diff --git a/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java b/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
index aed398ba2..c426898ed 100644
--- a/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
+++ b/doxia-modules/doxia-module-apt/src/main/java/org/apache/maven/doxia/module/apt/AptParser.java
@@ -2371,7 +2371,10 @@ public void traverse() throws AptParseException {
}
final int start = text.indexOf('{');
- final int end = text.indexOf('}');
+ // the macro block always ends with the closing brace, so look for the last one:
+ // parameter values may contain braces themselves (e.g. unresolved Velocity references
+ // such as ${project.build.directory} when the raw source of a *.apt.vm file is parsed)
+ final int end = text.lastIndexOf('}');
String s = text.substring(start + 1, end);
diff --git a/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptParserTest.java b/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptParserTest.java
index fbf0620f2..ff07b266e 100644
--- a/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptParserTest.java
+++ b/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptParserTest.java
@@ -25,6 +25,8 @@
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
import org.apache.maven.doxia.parser.AbstractParser;
import org.apache.maven.doxia.parser.AbstractParserTest;
@@ -75,6 +77,29 @@ void snippetMacro() throws Exception {
assertTrue(macro.contains("4.0.0\\"));
}
+ /**
+ * A macro parameter value may contain braces itself, for example an unresolved Velocity
+ * reference when the raw source of a {@code *.apt.vm} file is parsed. The macro block ends
+ * with the last brace on the line, not the first one.
+ */
+ @Test
+ void macroWithBracesInParameterValue() throws Exception {
+ Map parameters = new LinkedHashMap<>();
+
+ AbstractParser parser = createParser();
+ parser.setMacroExecutor((id, request, sink) -> {
+ assertEquals("snippet", id);
+ parameters.putAll(request.getParameters());
+ });
+
+ try (Reader reader = getTestReader("test/macro-braces-in-parameter")) {
+ parser.parse(reader, new SinkEventTestingSink());
+ }
+
+ assertEquals("superpom", parameters.get("id"));
+ assertEquals("${project.build.directory}/test-classes/pom-4.0.0.xml", parameters.get("file"));
+ }
+
@Test
void commentsBeforeTitle() throws Exception {
String comments = parseFileToAptSink("test/comments");
diff --git a/doxia-modules/doxia-module-apt/src/test/resources/test/macro-braces-in-parameter.apt b/doxia-modules/doxia-module-apt/src/test/resources/test/macro-braces-in-parameter.apt
new file mode 100644
index 000000000..a3a0e24bf
--- /dev/null
+++ b/doxia-modules/doxia-module-apt/src/test/resources/test/macro-braces-in-parameter.apt
@@ -0,0 +1,7 @@
+ -----
+ Braces in macro parameters
+ -----
+
+Braces in macro parameters
+
+%{snippet|id=superpom|file=${project.build.directory}/test-classes/pom-4.0.0.xml}