diff --git a/README.jrf b/README.jrf index 972bcd4e..7ec47b8d 100644 --- a/README.jrf +++ b/README.jrf @@ -1,5 +1,5 @@ # This is a Jamal reference file containing serialized base64 encoded macros -# Created: 2024-12-10 17:58:05 +0100 +# Created: 2024-12-11 13:19:58 +0100 # id|openStr|closeStr|verbatim|tailParameter|pure|content|parameters # TOC VE9D|eyU=|JX0=|0|0|0|Ci4gPDxJbnN0YWxsYXRpb24+PgouIDw8R1M+PgouIDw8Q29uZmlndXJhdGlvbj4+Ci4gPDxGZWF0dXJlcz4+Ci4gPDxDb250cmlidXRpbmc+PgouIDw8RG9jdW1lbnRhdGlvbj4+Ci4gPDxMaWNlbnNlPj4KLiA8PENoYW5nZWxvZz4+Ci4gPDxSb2FkbWFwPj4KLiA8PFN1cHBvcnQ+PgouIDw8RkFRPj4KLiA8PE1haW50ZW5hbmNlPj4=| diff --git a/jamal-api/src/main/java/javax0/jamal/api/BadSyntaxAt.java b/jamal-api/src/main/java/javax0/jamal/api/BadSyntaxAt.java index c5038750..9ad55ec9 100644 --- a/jamal-api/src/main/java/javax0/jamal/api/BadSyntaxAt.java +++ b/jamal-api/src/main/java/javax0/jamal/api/BadSyntaxAt.java @@ -58,20 +58,12 @@ public BadSyntaxAt(String message, Position pos, Throwable cause) { this.pos = pos; } - public static String posFormat(Position pos) { - if (pos == null) { - return ""; - } else { - return pos.file + "/" + pos.line + ":" + pos.column; - } - } - @Override public String getMessage() { if (pos == null) { return super.getMessage(); } else { - return super.getMessage() + " at " + posFormat(pos); + return super.getMessage() + " at " + pos.posFormat(); } } diff --git a/jamal-api/src/main/java/javax0/jamal/api/Input.java b/jamal-api/src/main/java/javax0/jamal/api/Input.java index c0ff827e..5ce31e5d 100644 --- a/jamal-api/src/main/java/javax0/jamal/api/Input.java +++ b/jamal-api/src/main/java/javax0/jamal/api/Input.java @@ -20,7 +20,7 @@ public interface Input extends CharSequence { *
  • either perform the operation as described here to support the default implementations, or *
  • implement the methods in a way that they do not use this method. * - * + *

    * Get the {@link StringBuilder} that contains the characters of the input. The processing many times works directly * on the {@link StringBuilder} deleting characters from the start of it as the processing progresses, thus * essentially modifying/mutating the {@code Input} object. @@ -38,7 +38,6 @@ public interface Input extends CharSequence { */ Position getPosition(); - /** * @return the reference file name that the input was read from */ diff --git a/jamal-api/src/main/java/javax0/jamal/api/Position.java b/jamal-api/src/main/java/javax0/jamal/api/Position.java index 7556dfc0..d8772e13 100644 --- a/jamal-api/src/main/java/javax0/jamal/api/Position.java +++ b/jamal-api/src/main/java/javax0/jamal/api/Position.java @@ -1,5 +1,7 @@ package javax0.jamal.api; +import java.util.ArrayList; + /** * The {@code Position} contains the name of a file, a line number and the column number. This serves as a parameter * when an error happens. The exception {@link BadSyntaxAt} gets an object of this type as a parameter, and later it is @@ -10,19 +12,30 @@ */ public class Position { public final String file; + public final ArrayList segment = new ArrayList<>(); public int line; public int column; public int charpos = 0; public final Position parent; + /** + * This is the position that this position is a clone of. This is needed when segments are to be added to or + * removed from a position. The method {@link Input#getPosition()} returns a clone of the position but in the case + * when we want to add a segment we need the original position as we want to modify it. + */ + public final Position cloneOf; + public Position(String file, int line, int column, Position parent) { this.file = file; this.line = line; this.column = column; this.parent = parent; + this.cloneOf = this; } + public Position(Position clone) { + cloneOf = clone; if (clone == null) { file = null; line = 1; @@ -60,6 +73,14 @@ public Position clone() { return new Position(this); } + public void pushSegment(String segment) { + this.segment.add(segment); + } + + public void popSegment() { + this.segment.remove(this.segment.size() - 1); + } + /** * @return return the position, which is the same as the position of the input, but references the position of the * input as parent. This means that we will have two positions, with the same file/line:column information, but @@ -83,12 +104,20 @@ public Position fork() { */ public Position top() { var top = this; - while ( top.parent != null) { + while (top.parent != null) { top = top.parent; } return top; } + public String posFormat() { + if (segment.isEmpty()) { + return file + "/" + line + ":" + column; + } else { + return file + "[" + String.join(">", segment) + "]" + line + ":" + column; + } + } + @Override public String toString() { return file + ":" + line + ":" + column; diff --git a/jamal-cmd/src/main/java/javax0/jamal/cmd/JamalMain.java b/jamal-cmd/src/main/java/javax0/jamal/cmd/JamalMain.java index 1db44c90..5039059c 100644 --- a/jamal-cmd/src/main/java/javax0/jamal/cmd/JamalMain.java +++ b/jamal-cmd/src/main/java/javax0/jamal/cmd/JamalMain.java @@ -137,7 +137,7 @@ public static void main(String[] args) { private static final System.Logger LOGGER = System.getLogger("JAMAL"); private static void log(final System.Logger.Level level, final Position pos, final String format, final String... params) { - final var msg = String.format(format, (Object[]) params) + (pos == null ? "" : " at ") + BadSyntaxAt.posFormat(pos); + final var msg = String.format(format, (Object[]) params) + (pos == null ? "" : " at " + pos.posFormat()); LOGGER.log(level, msg); } diff --git a/jamal-engine/src/main/java/javax0/jamal/engine/Processor.java b/jamal-engine/src/main/java/javax0/jamal/engine/Processor.java index fcbd5be0..7efe41ca 100644 --- a/jamal-engine/src/main/java/javax0/jamal/engine/Processor.java +++ b/jamal-engine/src/main/java/javax0/jamal/engine/Processor.java @@ -200,7 +200,7 @@ public String process(final Input input) throws BadSyntax { skipWhiteSpaces(input); try { processMacro(input, output); - }catch(LinkageError le){ + } catch (LinkageError le) { throw new BadSyntax("Linkage error", le); } } else { @@ -215,7 +215,7 @@ public String process(final Input input) throws BadSyntax { } processingException = badSyntax; throw badSyntax; - }finally { + } finally { closeProcessWithExceptionHandling(output, processingException); } traceRecordFactory.dump(null); @@ -511,7 +511,14 @@ private void pushBadSyntax(BadSyntax bs, final Position ref) throws BadSyntaxAt private String evaluateBuiltinMacro(final Input input, final Position ref, final MacroQualifier qualifier) throws BadSyntaxAt { try { lastInvokedBuiltInMacro = qualifier.macroId; - return qualifier.macro.evaluate(input, this); + input.getPosition().cloneOf.pushSegment(qualifier.macro.getId()); + final String s; + try { + s = qualifier.macro.evaluate(input, this); + } finally { + input.getPosition().cloneOf.popSegment(); + } + return s; } catch (BadSyntax bs) { pushBadSyntax(bs, ref); return ""; diff --git a/jamal-maven-plugin/src/main/java/com/javax0/jamal/maven/JamalLogger.java b/jamal-maven-plugin/src/main/java/com/javax0/jamal/maven/JamalLogger.java index bd62ee81..4680a65d 100644 --- a/jamal-maven-plugin/src/main/java/com/javax0/jamal/maven/JamalLogger.java +++ b/jamal-maven-plugin/src/main/java/com/javax0/jamal/maven/JamalLogger.java @@ -7,7 +7,7 @@ public class JamalLogger { public static void log(final System.Logger.Level level, final Position pos, final String format, final String... params) { org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("jamal"); - final var msg = String.format(format, (Object[]) params) + (pos == null ? "" : " at ") + BadSyntaxAt.posFormat(pos); + final var msg = String.format(format, (Object[]) params) + (pos == null ? "" : " at " + pos.posFormat()); switch (level) { case DEBUG: log.debug(msg); diff --git a/jamal-snippet/README.adoc b/jamal-snippet/README.adoc index b16a677c..ba7f8cef 100644 --- a/jamal-snippet/README.adoc +++ b/jamal-snippet/README.adoc @@ -3816,7 +3816,7 @@ will result in the output .output [source] ---- -2024-12-10 17:58:06 +2024-12-11 13:19:58 ---- diff --git a/jamal-sql/demodb.mv.db b/jamal-sql/demodb.mv.db index 5e88ffee..46535c89 100644 Binary files a/jamal-sql/demodb.mv.db and b/jamal-sql/demodb.mv.db differ diff --git a/jamal-testsupport/src/main/java/javax0/jamal/testsupport/TestThat.java b/jamal-testsupport/src/main/java/javax0/jamal/testsupport/TestThat.java index 5e077bfd..f6bf6b4a 100644 --- a/jamal-testsupport/src/main/java/javax0/jamal/testsupport/TestThat.java +++ b/jamal-testsupport/src/main/java/javax0/jamal/testsupport/TestThat.java @@ -69,7 +69,7 @@ private TestThat(Class klass) { private final List logItems = new ArrayList<>(); private void log(final System.Logger.Level level, final Position pos, final String format, final String... params) { - logItems.add("[" + level.getName() + "] " + String.format(format, (Object[]) params) + (pos == null ? "" : " at ") + BadSyntaxAt.posFormat(pos)); + logItems.add("[" + level.getName() + "] " + String.format(format, (Object[]) params) + (pos == null ? "" : " at " + pos.posFormat())); } public List getLogs() { diff --git a/jamal-tools/src/main/java/javax0/jamal/tools/Input.java b/jamal-tools/src/main/java/javax0/jamal/tools/Input.java index 665d60f7..fd28a156 100644 --- a/jamal-tools/src/main/java/javax0/jamal/tools/Input.java +++ b/jamal-tools/src/main/java/javax0/jamal/tools/Input.java @@ -7,8 +7,11 @@ */ public class Input implements javax0.jamal.api.Input { private final StringBuilder input; - private final Position pos; + private Position pos; + Position getPos() { + return pos; + } /** * Create an empty input, which may also serve as an output where the characters are collected. @@ -147,7 +150,6 @@ public void stepColumn() { pos.charpos++; } - @Override public StringBuilder getSB() { return input; diff --git a/jamal-word/src/test/resources/demoConverted.docx b/jamal-word/src/test/resources/demoConverted.docx index b281023a..98f89ff6 100644 Binary files a/jamal-word/src/test/resources/demoConverted.docx and b/jamal-word/src/test/resources/demoConverted.docx differ diff --git a/jamal-word/src/test/resources/includetestConverted.docx b/jamal-word/src/test/resources/includetestConverted.docx index 53f0a886..723905c4 100644 Binary files a/jamal-word/src/test/resources/includetestConverted.docx and b/jamal-word/src/test/resources/includetestConverted.docx differ diff --git a/jamal-word/src/test/resources/pictureConverted.docx b/jamal-word/src/test/resources/pictureConverted.docx index aa73805c..ad5d1ede 100644 Binary files a/jamal-word/src/test/resources/pictureConverted.docx and b/jamal-word/src/test/resources/pictureConverted.docx differ diff --git a/jamal-word/src/test/resources/sampleConverted.docx b/jamal-word/src/test/resources/sampleConverted.docx index a9d117f2..902cf96b 100644 Binary files a/jamal-word/src/test/resources/sampleConverted.docx and b/jamal-word/src/test/resources/sampleConverted.docx differ