You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2024/11/04 15:53:13 UTC
(maven-doxia-converter) 01/01: [DOXIATOOLS-89] Macros should not be resolved
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/keep-macros
in repository https://gitbox.apache.org/repos/asf/maven-doxia-converter.git
commit 50b7189fb51718c99b3ad1579f907321e2e80eb1
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Nov 4 16:53:03 2024 +0100
[DOXIATOOLS-89] Macros should not be resolved
Instead they should be converted to the destination format
---
pom.xml | 3 +-
.../org/apache/maven/doxia/DefaultConverter.java | 113 ++++++++++++++++++++-
.../maven/doxia/wrapper/InputReaderWrapper.java | 6 +-
.../maven/doxia/wrapper/OutputStreamWrapper.java | 10 +-
.../java/org/apache/maven/doxia/ConverterTest.java | 32 +++++-
.../apache/maven/doxia/DefaultConverterTest.java | 43 ++++++++
src/test/resources/unit/apt/macro.apt | 12 +++
src/test/resources/unit/markdown/macro.md | 12 +++
8 files changed, 212 insertions(+), 19 deletions(-)
diff --git a/pom.xml b/pom.xml
index 4b463d5..7c668c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,7 +55,7 @@ under the License.
</distributionManagement>
<properties>
- <doxiaVersion>2.0.0</doxiaVersion>
+ <doxiaVersion>2.1.0-SNAPSHOT</doxiaVersion>
<javaVersion>8</javaVersion>
<project.build.outputTimestamp>2023-01-09T21:24:22Z</project.build.outputTimestamp>
</properties>
@@ -175,6 +175,7 @@ under the License.
<configuration>
<excludes combine.children="append">
<exclude>src/test/resources/unit/**/test.*</exclude>
+ <exclude>src/test/resources/unit/**/macro.*</exclude>
<exclude>src/test/resources/book-1/section-*.apt</exclude>
</excludes>
</configuration>
diff --git a/src/main/java/org/apache/maven/doxia/DefaultConverter.java b/src/main/java/org/apache/maven/doxia/DefaultConverter.java
index 11a8783..55f22cf 100644
--- a/src/main/java/org/apache/maven/doxia/DefaultConverter.java
+++ b/src/main/java/org/apache/maven/doxia/DefaultConverter.java
@@ -32,15 +32,21 @@ import java.io.Reader;
import java.io.Writer;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import org.apache.commons.io.input.XmlStreamReader;
import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.doxia.macro.MacroExecutionException;
+import org.apache.maven.doxia.macro.MacroExecutor;
+import org.apache.maven.doxia.macro.MacroRequest;
+import org.apache.maven.doxia.macro.manager.MacroNotFoundException;
import org.apache.maven.doxia.parser.ParseException;
import org.apache.maven.doxia.parser.Parser;
import org.apache.maven.doxia.sink.Sink;
@@ -77,6 +83,73 @@ import static java.lang.String.format;
*/
@Named
public class DefaultConverter implements Converter {
+
+ /** Macro formatter for different Doxia formats.
+ * @see <a href="https://maven.apache.org/doxia/macros/index.html">Doxia Macros</a>
+ */
+ enum MacroFormatter {
+ APT("%{", "|", "=", "|", "}"),
+ FML("<macro name=\"", "\"", "<param name=\"", "\" value=\" />", "</macro>"),
+ XDOC("<macro name=\"", "\"", "<param name=\"", "\" value=\" />", "</macro>"),
+ XHTML("<!-- MACRO{", "|", "=", "|", "} -->"),
+ MARKDOWN("<!-- MACRO{", "|", "=", "|", "} -->");
+
+ private final String prefix;
+ private final String nameParameterDelimiter;
+ private final String parameterNameValueDelimiter;
+ private final String parameterDelimiter;
+ private final String suffix;
+
+ public static MacroFormatter forFormat(DoxiaFormat format) {
+ switch (format) {
+ case APT:
+ return APT;
+ case FML:
+ return FML;
+ case XDOC:
+ return XDOC;
+ case XHTML:
+ return XHTML;
+ case MARKDOWN:
+ return MARKDOWN;
+ default:
+ throw new IllegalArgumentException("Unsupported Doxia format: " + format);
+ }
+ }
+
+ MacroFormatter(
+ String prefix,
+ String nameParameterDelimiter,
+ String parameterNameValueDelimiter,
+ String parameterDelimiter,
+ String suffix) {
+ this.prefix = prefix;
+ this.nameParameterDelimiter = nameParameterDelimiter;
+ this.parameterNameValueDelimiter = parameterNameValueDelimiter;
+ this.parameterDelimiter = parameterDelimiter;
+ this.suffix = suffix;
+ }
+
+ /**
+ * Formats a macro with the given name and parameters for this format.
+ * @param name
+ * @param parameters
+ * @return the formatted macro string to be emitted in the output
+ */
+ public String format(String name, Map<String, Object> parameters) {
+ StringBuilder macro = new StringBuilder();
+ macro.append(prefix).append(name);
+ String parameterString = parameters.entrySet().stream()
+ .map(e -> e.getKey() + parameterNameValueDelimiter + e.getValue())
+ .collect(Collectors.joining(parameterDelimiter));
+ if (!parameters.isEmpty()) {
+ macro.append(nameParameterDelimiter).append(parameterString);
+ }
+ macro.append(suffix);
+ return macro.toString();
+ }
+ }
+
/**
* All supported Doxia formats (either only parser, only sink or both)
*/
@@ -133,19 +206,49 @@ public class DefaultConverter implements Converter {
return firstElement != null;
}
+ public String formatMacro(String name, Map<String, Object> parameters) {
+
+ return format("%{%s|%s}", name, parameters.toString());
+ }
/**
* @param plexus not null
- * @return an instance of <code>Parser</code> depending on the format.
+ * @param macroFormatter a formatter for macros in the target format
+ * @return an instance of <code>Parser</code> depending on the format which converts macros with the given {@link MacroFormatter}
* @throws ComponentLookupException if could not find the Parser for the given format.
* @throws IllegalArgumentException if any parameter is null
*/
- public Parser getParser(PlexusContainer plexus) throws ComponentLookupException {
+ public Parser getParser(PlexusContainer plexus, MacroFormatter macroFormatter) throws ComponentLookupException {
if (!hasParser) {
throw new IllegalStateException("The format " + this + " is not supported as parser!");
}
Objects.requireNonNull(plexus, "plexus is required");
+ Parser parser = plexus.lookup(Parser.class, roleHint);
+ parser.setMacroExecutor(new MacroConverterExecutor(macroFormatter));
+ return parser;
+ }
+
+ public static class MacroConverterExecutor implements MacroExecutor {
+ private final MacroFormatter macroFormatter;
- return plexus.lookup(Parser.class, roleHint);
+ public MacroConverterExecutor(MacroFormatter macroFormatter) {
+ super();
+ this.macroFormatter = macroFormatter;
+ }
+
+ @Override
+ public void executeMacro(String id, MacroRequest request, Sink sink)
+ throws MacroExecutionException, MacroNotFoundException {
+ // filter out internal parameters but keep original order
+ Map<String, Object> parameters = request.getParameters().entrySet().stream()
+ .filter(e -> !MacroRequest.isInternalParameter(e.getKey()))
+ .collect(Collectors.toMap(
+ Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
+
+ // the format of macros differs between the parser implementations
+ // (https://maven.apache.org/doxia/macros/index.html)
+ String macro = macroFormatter.format(id, parameters);
+ sink.rawText(macro);
+ }
}
/**
@@ -272,7 +375,7 @@ public class DefaultConverter implements Converter {
try {
Parser parser;
try {
- parser = input.getFormat().getParser(plexus);
+ parser = input.getFormat().getParser(plexus, MacroFormatter.forFormat(output.getFormat()));
} catch (ComponentLookupException e) {
throw new ConverterException("ComponentLookupException: " + e.getMessage(), e);
}
@@ -355,7 +458,7 @@ public class DefaultConverter implements Converter {
Parser parser;
try {
- parser = parserFormat.getParser(plexus);
+ parser = parserFormat.getParser(plexus, MacroFormatter.forFormat(output.getFormat()));
} catch (ComponentLookupException e) {
throw new ConverterException("ComponentLookupException: " + e.getMessage(), e);
}
diff --git a/src/main/java/org/apache/maven/doxia/wrapper/InputReaderWrapper.java b/src/main/java/org/apache/maven/doxia/wrapper/InputReaderWrapper.java
index 0d315b1..4b173d6 100644
--- a/src/main/java/org/apache/maven/doxia/wrapper/InputReaderWrapper.java
+++ b/src/main/java/org/apache/maven/doxia/wrapper/InputReaderWrapper.java
@@ -42,8 +42,8 @@ public class InputReaderWrapper {
* @param supportedFormat not null
* @throws IllegalArgumentException if the format equals AUTO_FORMAT.
*/
- private InputReaderWrapper(Reader reader, String format) {
- this.format = DefaultConverter.DoxiaFormat.valueOf(format.toUpperCase());
+ private InputReaderWrapper(Reader reader, DefaultConverter.DoxiaFormat format) {
+ this.format = format;
if (reader == null) {
throw new IllegalArgumentException("input reader is required");
@@ -66,7 +66,7 @@ public class InputReaderWrapper {
* @param format not null
* @return a type safe input reader
*/
- public static InputReaderWrapper valueOf(Reader reader, String format) {
+ public static InputReaderWrapper valueOf(Reader reader, DefaultConverter.DoxiaFormat format) {
return new InputReaderWrapper(reader, format);
}
}
diff --git a/src/main/java/org/apache/maven/doxia/wrapper/OutputStreamWrapper.java b/src/main/java/org/apache/maven/doxia/wrapper/OutputStreamWrapper.java
index 28e84ee..7790928 100644
--- a/src/main/java/org/apache/maven/doxia/wrapper/OutputStreamWrapper.java
+++ b/src/main/java/org/apache/maven/doxia/wrapper/OutputStreamWrapper.java
@@ -45,8 +45,8 @@ public class OutputStreamWrapper {
* @param supportedFormat not null
* @throws IllegalArgumentException if any.
*/
- private OutputStreamWrapper(OutputStream out, String format, String encoding) {
- this.format = DefaultConverter.DoxiaFormat.valueOf(format.toUpperCase());
+ private OutputStreamWrapper(OutputStream out, DefaultConverter.DoxiaFormat format, String encoding) {
+ this.format = format;
this.out = out;
this.encoding = encoding;
}
@@ -75,11 +75,9 @@ public class OutputStreamWrapper {
* @param encoding not null
* @return a type safe output stream wrapper
*/
- public static OutputStreamWrapper valueOf(OutputStream out, String format, String encoding) {
+ public static OutputStreamWrapper valueOf(OutputStream out, DefaultConverter.DoxiaFormat format, String encoding) {
Objects.requireNonNull(out, "output writer is required");
- if (format == null || format.isEmpty()) {
- throw new IllegalArgumentException("output format is required");
- }
+ Objects.requireNonNull(format, "output format is required");
return new OutputStreamWrapper(out, format, encoding);
}
diff --git a/src/test/java/org/apache/maven/doxia/ConverterTest.java b/src/test/java/org/apache/maven/doxia/ConverterTest.java
index 07ff85f..4695c2e 100644
--- a/src/test/java/org/apache/maven/doxia/ConverterTest.java
+++ b/src/test/java/org/apache/maven/doxia/ConverterTest.java
@@ -20,13 +20,20 @@ package org.apache.maven.doxia;
import javax.inject.Inject;
+import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
+import java.io.IOException;
import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
import org.apache.maven.doxia.DefaultConverter.DoxiaFormat;
import org.apache.maven.doxia.wrapper.InputFileWrapper;
@@ -43,6 +50,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertLinesMatch;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -263,9 +271,7 @@ class ConverterTest extends InjectedTest {
@Test
void aptWriterConverter() throws Exception {
String in = getBasedir() + "/src/test/resources/unit/apt/test.apt";
- String from = "apt";
String out = getBasedir() + "/target/unit/writer/apt/test.apt.xhtml";
- String to = "xhtml";
File inFile = new File(in);
File outFile = new File(out);
@@ -274,8 +280,8 @@ class ConverterTest extends InjectedTest {
try (OutputStream fo = new FileOutputStream(outFile)) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- InputReaderWrapper input = InputReaderWrapper.valueOf(new FileReader(inFile), from);
- OutputStreamWrapper output = OutputStreamWrapper.valueOf(outputStream, to, "UTF-8");
+ InputReaderWrapper input = InputReaderWrapper.valueOf(new FileReader(inFile), DoxiaFormat.APT);
+ OutputStreamWrapper output = OutputStreamWrapper.valueOf(outputStream, DoxiaFormat.XHTML, "UTF-8");
converter.setFormatOutput(formatOutput);
converter.convert(input, output);
@@ -429,4 +435,22 @@ class ConverterTest extends InjectedTest {
assertEquals(DoxiaFormat.FML, autoDetectFormat("fml/test.fml"));
assertEquals(DoxiaFormat.XHTML, autoDetectFormat("xhtml/test.xhtml"));
}
+
+ @Test
+ void testAptToMarkdownWithMacro() throws IOException, UnsupportedFormatException, ConverterException {
+ Path in = new File(getBasedir() + "/src/test/resources/unit/apt/macro.apt").toPath();
+ Path expectedOut = new File(getBasedir() + "//src/test/resources/unit/markdown/macro.md").toPath();
+
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Reader reader = Files.newBufferedReader(in, StandardCharsets.UTF_8); ) {
+ converter.convert(
+ InputReaderWrapper.valueOf(reader, DoxiaFormat.APT),
+ OutputStreamWrapper.valueOf(output, DoxiaFormat.MARKDOWN, StandardCharsets.UTF_8.name()));
+
+ try (BufferedReader outputReader =
+ new BufferedReader(new StringReader(new String(output.toByteArray(), StandardCharsets.UTF_8))); ) {
+ assertLinesMatch(Files.readAllLines(expectedOut).stream(), outputReader.lines());
+ }
+ }
+ }
}
diff --git a/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java b/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java
new file mode 100644
index 0000000..c2fccab
--- /dev/null
+++ b/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.doxia;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.doxia.DefaultConverter.MacroFormatter;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class DefaultConverterTest {
+
+ @Test
+ void testMacroFormatter() {
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("param1", "value1");
+ parameters.put("param2", "value2");
+ assertEquals("%{toc|param1=value1|param2=value2}", MacroFormatter.APT.format("toc", parameters));
+ assertEquals("%{toc}", MacroFormatter.APT.format("toc", Collections.emptyMap()));
+ assertEquals(
+ "<!-- MACRO{toc|param1=value1|param2=value2} -->", MacroFormatter.MARKDOWN.format("toc", parameters));
+ assertEquals("<!-- MACRO{toc} -->", MacroFormatter.MARKDOWN.format("toc", Collections.emptyMap()));
+ }
+}
diff --git a/src/test/resources/unit/apt/macro.apt b/src/test/resources/unit/apt/macro.apt
new file mode 100644
index 0000000..483d7c4
--- /dev/null
+++ b/src/test/resources/unit/apt/macro.apt
@@ -0,0 +1,12 @@
+ ------
+ Title
+ ------
+ Author
+ ------
+ Date
+
+%{toc|section=0|fromDepth=1|toDepth=3}
+
+{Introduction}
+
+ Section1 text
\ No newline at end of file
diff --git a/src/test/resources/unit/markdown/macro.md b/src/test/resources/unit/markdown/macro.md
new file mode 100644
index 0000000..47ea223
--- /dev/null
+++ b/src/test/resources/unit/markdown/macro.md
@@ -0,0 +1,12 @@
+---
+title: Title
+author:
+ - Author
+date: Date
+---
+
+<!-- MACRO{toc|section=0|fromDepth=1|toDepth=3} -->
+# Introduction
+
+Section1 text
+