This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-doxia.git
The following commit(s) were added to refs/heads/master by this push: new 356a0fe6 [DOXIA-731] Simplify HTML markup emitted from Sink.verbatim (#202) 356a0fe6 is described below commit 356a0fe63fe6789f001518455514e513c1a40647 Author: Konrad Windszus <k...@apache.org> AuthorDate: Sat Mar 16 12:33:33 2024 +0100 [DOXIA-731] Simplify HTML markup emitted from Sink.verbatim (#202) Emit either <pre> or <pre><code>. Add parser tests for verbatim text/code (for all parsers) --- .../maven/doxia/sink/impl/Xhtml5BaseSink.java | 82 +++++++------ .../maven/doxia/parser/AbstractParserTest.java | 127 ++++++++++++++++++++- .../maven/doxia/parser/Xhtml5BaseParserTest.java | 12 +- .../maven/doxia/sink/impl/SinkTestDocument.java | 8 +- .../maven/doxia/sink/impl/Xhtml5BaseSinkTest.java | 15 ++- .../maven/doxia/module/apt/AptParserTest.java | 25 +++- .../maven/doxia/module/fml/FmlParserTest.java | 63 +++++++++- .../doxia/module/markdown/MarkdownParserTest.java | 36 +++++- .../apache/maven/doxia/module/xdoc/XdocSink.java | 21 ++-- .../maven/doxia/module/xdoc/XdocParserTest.java | 14 ++- .../doxia/module/xhtml5/Xhtml5ParserTest.java | 14 ++- .../maven/doxia/module/xhtml5/Xhtml5SinkTest.java | 2 +- 12 files changed, 344 insertions(+), 75 deletions(-) diff --git a/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSink.java b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSink.java index cdb7d7b8..bbe3107e 100644 --- a/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSink.java +++ b/doxia-core/src/main/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSink.java @@ -40,6 +40,7 @@ import org.apache.maven.doxia.markup.HtmlMarkup; import org.apache.maven.doxia.markup.Markup; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkEventAttributes; +import org.apache.maven.doxia.sink.impl.Xhtml5BaseSink.VerbatimMode; import org.apache.maven.doxia.util.DoxiaUtils; import org.apache.maven.doxia.util.HtmlTools; import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; @@ -77,8 +78,16 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { /** An indication on if we're inside a paragraph flag. */ private boolean paragraphFlag; - /** An indication on if we're in verbatim mode. */ - private boolean verbatimFlag; + protected enum VerbatimMode { + /** not in verbatim mode */ + OFF, + /** Inside {@code <pre>} */ + ON, + /** Inside {@code <pre><code>} */ + ON_WITH_CODE + } + /** An indication on if we're in verbatim mode and if so, surrounded by which tags. */ + private VerbatimMode verbatimMode; /** Stack of alignment int[] of table cells. */ private final LinkedList<int[]> cellJustifStack; @@ -160,21 +169,28 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { } /** - * <p>Setter for the field <code>verbatimFlag</code>.</p> * - * @param verb a verbatim flag. + * @return the current verbatim mode. + */ + protected VerbatimMode getVerbatimMode() { + return this.verbatimMode; + } + + /** + * <p>Setter for the field <code>verbatimMode</code>.</p> + * + * @param mode a verbatim mode. */ - protected void setVerbatimFlag(boolean verb) { - this.verbatimFlag = verb; + protected void setVerbatimMode(VerbatimMode mode) { + this.verbatimMode = mode; } /** - * <p>isVerbatimFlag.</p> * - * @return the current verbatim flag. + * @return {@code true} if inside verbatim section, {@code false} otherwise */ - protected boolean isVerbatimFlag() { - return this.verbatimFlag; + protected boolean isVerbatim() { + return this.verbatimMode != VerbatimMode.OFF; } /** @@ -232,7 +248,7 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { this.headFlag = false; this.paragraphFlag = false; - this.verbatimFlag = false; + this.verbatimMode = VerbatimMode.OFF; this.evenTableRow = true; this.tableAttributes = null; @@ -825,11 +841,13 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { } /** - * The default class style is <code>verbatim</code>, for source is {@code verbatim source}. + * Depending on whether the decoration attribute is "source" or not, this leads + * to either emitting {@code <pre><code>} or just {@code <pre>}. + * No default classes are emitted but the given attributes are always added to the {@code pre} element only. * * {@inheritDoc} - * @see javax.swing.text.html.HTML.Tag#DIV * @see javax.swing.text.html.HTML.Tag#PRE + * @see javax.swing.text.html.HTML.Tag#CODE */ @Override public void verbatim(SinkEventAttributes attributes) { @@ -840,47 +858,41 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { paragraph_(); } - verbatimFlag = true; - MutableAttributeSet atts = SinkUtils.filterAttributes(attributes, SinkUtils.SINK_VERBATIM_ATTRIBUTES); if (atts == null) { atts = new SinkEventAttributeSet(); } - boolean source = false; - + verbatimMode = VerbatimMode.ON; if (atts.isDefined(SinkEventAttributes.DECORATION)) { - source = "source" - .equals(atts.getAttribute(SinkEventAttributes.DECORATION).toString()); - } - - SinkEventAttributes divAtts = null; - String divClass = "verbatim"; - - if (source) { - divClass += " source"; + if ("source" + .equals(atts.getAttribute(SinkEventAttributes.DECORATION).toString())) { + verbatimMode = VerbatimMode.ON_WITH_CODE; + } } - divAtts = new SinkEventAttributeSet(SinkEventAttributes.CLASS.toString(), divClass); - atts.removeAttribute(SinkEventAttributes.DECORATION); - writeStartTag(HtmlMarkup.DIV, divAtts); writeStartTag(HtmlMarkup.PRE, atts); + if (verbatimMode == VerbatimMode.ON_WITH_CODE) { + writeStartTag(HtmlMarkup.CODE); + } } /** * {@inheritDoc} - * @see javax.swing.text.html.HTML.Tag#DIV + * @see javax.swing.text.html.HTML.Tag#CODE * @see javax.swing.text.html.HTML.Tag#PRE */ @Override public void verbatim_() { + if (verbatimMode == VerbatimMode.ON_WITH_CODE) { + writeEndTag(HtmlMarkup.CODE); + } writeEndTag(HtmlMarkup.PRE); - writeEndTag(HtmlMarkup.DIV); - verbatimFlag = false; + verbatimMode = VerbatimMode.OFF; } /** @@ -1369,7 +1381,7 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { */ @Override public void lineBreak(SinkEventAttributes attributes) { - if (headFlag || isVerbatimFlag()) { + if (headFlag || isVerbatim()) { getTextBuffer().append(EOL); } else { MutableAttributeSet atts = SinkUtils.filterAttributes(attributes, SinkUtils.SINK_BR_ATTRIBUTES); @@ -1381,7 +1393,7 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { /** {@inheritDoc} */ @Override public void lineBreakOpportunity(SinkEventAttributes attributes) { - if (!headFlag && !isVerbatimFlag()) { + if (!headFlag && !isVerbatim()) { MutableAttributeSet atts = SinkUtils.filterAttributes(attributes, SinkUtils.SINK_BR_ATTRIBUTES); writeSimpleTag(HtmlMarkup.WBR, atts); @@ -1412,7 +1424,7 @@ public class Xhtml5BaseSink extends AbstractXmlSink implements HtmlMarkup { } if (headFlag) { getTextBuffer().append(text); - } else if (verbatimFlag) { + } else if (isVerbatim()) { verbatimContent(text); } else { content(text); diff --git a/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java b/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java index 59e0e9c3..285d9c0a 100644 --- a/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java +++ b/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java @@ -23,12 +23,14 @@ import java.io.Reader; import java.io.StringWriter; import java.io.Writer; import java.util.Iterator; +import java.util.ListIterator; import org.apache.maven.doxia.AbstractModuleTest; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkEventAttributes; import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.apache.maven.doxia.sink.impl.SinkEventElement; +import org.apache.maven.doxia.sink.impl.SinkEventTestingSink; import org.apache.maven.doxia.sink.impl.SinkWrapper; import org.apache.maven.doxia.sink.impl.SinkWrapperFactory; import org.apache.maven.doxia.sink.impl.TextSink; @@ -36,7 +38,10 @@ import org.apache.maven.doxia.sink.impl.WellformednessCheckingSink; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Test the parsing of sample input files. @@ -46,12 +51,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; * @since 1.0 */ public abstract class AbstractParserTest extends AbstractModuleTest { + /** + * Example text which usually requires escaping in different markup languages as they have special meaning there + */ + public static final String TEXT_WITH_SPECIAL_CHARS = "<>{}=#*"; + /** * Create a new instance of the parser to test. * * @return the parser to test. */ - protected abstract Parser createParser(); + protected abstract AbstractParser createParser(); /** * Returns the directory where all parser test output will go. @@ -146,6 +156,91 @@ public abstract class AbstractParserTest extends AbstractModuleTest { } } + /** + * Override this method if the parser always emits some static prefix for incomplete documents + * and consume the prefix related events from the given {@link Iterator}. + * @param eventIterator the iterator + */ + protected void assertEventPrefix(Iterator<SinkEventElement> eventIterator) { + // do nothing by default, i.e. assume no prefix + } + + /** + * Override this method if the parser always emits some static suffix for incomplete documents + * and consume the suffix related events from the given {@link Iterator}. + * @param eventIterator the iterator + */ + protected void assertEventSuffix(Iterator<SinkEventElement> eventIterator) { + assertFalse(eventIterator.hasNext(), "didn't expect any further events but got at least one"); + } + + /** + * @return markup representing the verbatim text {@value #TEXT_WITH_SPECIAL_CHARS} (needs to be properly escaped). + * {@code null} can be returned to skip the test for a particular parser. + */ + protected abstract String getVerbatimSource(); + + /** + * Test a verbatim block (no code) given through {@link #getVerbatimSource()} + * @throws ParseException + */ + @Test + public void testVerbatim() throws ParseException { + String source = getVerbatimSource(); + assumeTrue(source != null, "parser does not support simple verbatim text"); + AbstractParser parser = createParser(); + SinkEventTestingSink sink = new SinkEventTestingSink(); + + parser.parse(source, sink); + ListIterator<SinkEventElement> it = sink.getEventList().listIterator(); + assertEventPrefix(it); + assertEquals("verbatim", it.next().getName()); + assertConcatenatedTextEquals(it, TEXT_WITH_SPECIAL_CHARS, true); + assertEquals("verbatim_", it.next().getName()); + assertEventSuffix(it); + } + + /** + * @return markup representing the verbatim code block {@value #TEXT_WITH_SPECIAL_CHARS} (needs to be properly escaped). + * {@code null} can be returned to skip the test for a particular parser. + */ + protected abstract String getVerbatimCodeSource(); + + /** + * Test a verbatim code block given through {@link #getVerbatimCodeSource()} + * @throws ParseException + */ + @Test + public void testVerbatimCode() throws ParseException { + String source = getVerbatimCodeSource(); + assumeTrue(source != null, "parser does not support verbatim code"); + AbstractParser parser = createParser(); + SinkEventTestingSink sink = new SinkEventTestingSink(); + + parser.parse(source, sink); + ListIterator<SinkEventElement> it = sink.getEventList().listIterator(); + assertEventPrefix(it); + SinkEventElement verbatimEvt = it.next(); + assertEquals("verbatim", verbatimEvt.getName()); + SinkEventAttributeSet atts = (SinkEventAttributeSet) verbatimEvt.getArgs()[0]; + + // either verbatim event has attribute "source" or additional "inline" event + boolean isInlineCode; + if (atts.isEmpty()) { + isInlineCode = true; + assertSinkAttributesEqual(it.next(), "inline", SinkEventAttributeSet.Semantics.CODE); + } else { + isInlineCode = false; + assertEquals(SinkEventAttributeSet.SOURCE, atts); + } + assertConcatenatedTextEquals(it, TEXT_WITH_SPECIAL_CHARS, true); + if (isInlineCode) { + assertEquals("inline_", it.next().getName()); + } + assertEquals("verbatim_", it.next().getName()); + assertEventSuffix(it); + } + public static void assertSinkEquals(SinkEventElement element, String name, Object... args) { Assertions.assertEquals(name, element.getName(), "Name of element doesn't match"); Assertions.assertArrayEquals(args, element.getArgs(), "Arguments don't match"); @@ -157,6 +252,36 @@ public abstract class AbstractParserTest extends AbstractModuleTest { Assertions.assertEquals(value, atts.getAttribute(attr)); } + public static void assertSinkAttributesEqual( + SinkEventElement element, String name, SinkEventAttributes expectedAttributes) { + Assertions.assertEquals(name, element.getName()); + SinkEventAttributeSet atts = (SinkEventAttributeSet) element.getArgs()[0]; + Assertions.assertEquals(expectedAttributes, atts); + } + + /** + * Consumes all consecutive text events from the given {@link ListIterator} and compares the concatenated text with the expected text + * @param it the iterator to traverse, is positioned to the last text event once this method finishes + * @param expectedText the expected text which is compared with the concatenated text of all text events + * @param trimText {@code true} to trim the actual text before comparing with the expected one, otherwise compare without trimming + */ + void assertConcatenatedTextEquals(ListIterator<SinkEventElement> it, String expectedText, boolean trimText) { + StringBuilder builder = new StringBuilder(); + while (it.hasNext()) { + SinkEventElement currentEvent = it.next(); + if (currentEvent.getName() != "text") { + it.previous(); + break; + } + builder.append(currentEvent.getArgs()[0]); + } + String actualValue = builder.toString(); + if (trimText) { + actualValue = actualValue.trim(); + } + assertEquals(expectedText, actualValue); + } + public static void assertSinkEquals(Iterator<SinkEventElement> it, String... names) { StringBuilder expected = new StringBuilder(); StringBuilder actual = new StringBuilder(); diff --git a/doxia-core/src/test/java/org/apache/maven/doxia/parser/Xhtml5BaseParserTest.java b/doxia-core/src/test/java/org/apache/maven/doxia/parser/Xhtml5BaseParserTest.java index dadc9122..084b03f6 100644 --- a/doxia-core/src/test/java/org/apache/maven/doxia/parser/Xhtml5BaseParserTest.java +++ b/doxia-core/src/test/java/org/apache/maven/doxia/parser/Xhtml5BaseParserTest.java @@ -36,7 +36,7 @@ public class Xhtml5BaseParserTest extends AbstractParserTest { private final SinkEventTestingSink sink = new SinkEventTestingSink(); @Override - protected Parser createParser() { + protected AbstractParser createParser() { parser = new Xhtml5BaseParser(); return parser; } @@ -931,4 +931,14 @@ public class Xhtml5BaseParserTest extends AbstractParserTest { "definitionListItem_", "definitionList_"); } + + @Override + protected String getVerbatimSource() { + return "<pre><>{}=#*</pre>"; + } + + @Override + protected String getVerbatimCodeSource() { + return "<pre><code><>{}=#*</code></pre>"; + } } diff --git a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/SinkTestDocument.java b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/SinkTestDocument.java index c4d5d676..35220f2a 100644 --- a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/SinkTestDocument.java +++ b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/SinkTestDocument.java @@ -81,8 +81,10 @@ public class SinkTestDocument { generateList(sink); - sink.verbatim(SinkEventAttributeSet.SOURCE); + sink.verbatim(); + sink.inline(SinkEventAttributeSet.Semantics.CODE); sink.text("Verbatim source text not contained in list item 3"); + sink.inline_(); sink.verbatim_(); generateNumberedList(sink); @@ -258,8 +260,10 @@ public class SinkTestDocument { sink.definedTerm_(); sink.definition(); sink.text("of definition list."); - sink.verbatim(SinkEventAttributeSet.SOURCE); + sink.verbatim(); + sink.inline(SinkEventAttributeSet.Semantics.CODE); sink.text("Verbatim source text" + eol + " in a box "); + sink.inline_(); sink.verbatim_(); sink.definition_(); sink.definitionListItem_(); diff --git a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSinkTest.java b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSinkTest.java index 43b6af06..63c6e436 100644 --- a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSinkTest.java +++ b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/Xhtml5BaseSinkTest.java @@ -651,28 +651,27 @@ public class Xhtml5BaseSinkTest { * Test of verbatim method, of class Xhtml5BaseSink. */ @Test - public void testVerbatimSource() { + public void testVerbatim() { try (Xhtml5BaseSink sink = new Xhtml5BaseSink(writer)) { sink.verbatim(SinkEventAttributeSet.SOURCE); sink.verbatim_(); } - assertEquals("<div class=\"verbatim source\">" + LS + "<pre></pre></div>", writer.toString()); + assertEquals("<pre><code></code></pre>", writer.toString()); - checkVerbatimAttributes(attributes, "<div class=\"verbatim\">" + LS + "<pre style=\"bold\"></pre></div>"); + checkVerbatimAttributes(attributes, "<pre style=\"bold\"></pre>"); final SinkEventAttributes att = new SinkEventAttributeSet(SinkEventAttributes.ID, "id"); - checkVerbatimAttributes(att, "<div class=\"verbatim\">" + LS + "<pre id=\"id\"></pre></div>"); + checkVerbatimAttributes(att, "<pre id=\"id\"></pre>"); att.addAttribute(Attribute.CLASS, "class"); - checkVerbatimAttributes(att, "<div class=\"verbatim\">" + LS + "<pre id=\"id\" class=\"class\"></pre></div>"); + checkVerbatimAttributes(att, "<pre id=\"id\" class=\"class\"></pre>"); att.addAttribute(SinkEventAttributes.DECORATION, "source"); - checkVerbatimAttributes( - att, "<div class=\"verbatim source\">" + LS + "<pre id=\"id\" class=\"class\"></pre></div>"); + checkVerbatimAttributes(att, "<pre id=\"id\" class=\"class\"><code></code></pre>"); att.removeAttribute(Attribute.CLASS.toString()); - checkVerbatimAttributes(att, "<div class=\"verbatim source\">" + LS + "<pre id=\"id\"></pre></div>"); + checkVerbatimAttributes(att, "<pre id=\"id\"><code></code></pre>"); } private void checkVerbatimAttributes(final SinkEventAttributes att, final String expected) { 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 b4a69df2..c6a6a501 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 @@ -26,9 +26,9 @@ import java.io.StringWriter; import java.io.Writer; import java.util.Iterator; +import org.apache.maven.doxia.parser.AbstractParser; import org.apache.maven.doxia.parser.AbstractParserTest; import org.apache.maven.doxia.parser.ParseException; -import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.apache.maven.doxia.sink.impl.SinkEventElement; @@ -47,7 +47,7 @@ public class AptParserTest extends AbstractParserTest { @Inject private AptParser parser; - protected Parser createParser() { + protected AbstractParser createParser() { return parser; } @@ -522,7 +522,28 @@ public class AptParserTest extends AbstractParserTest { assertSinkEquals(sink.getEventList().get(8), "text", "Another author", null); } + @Override protected String outputExtension() { return "apt"; } + + @Override + protected void assertEventPrefix(Iterator<SinkEventElement> eventIterator) { + assertSinkStartsWith(eventIterator, "head", "head_", "body"); + } + + @Override + protected void assertEventSuffix(Iterator<SinkEventElement> eventIterator) { + assertSinkEquals(eventIterator, "body_"); + } + + @Override + protected String getVerbatimSource() { + return "---" + EOL + "<>{}=#*" + EOL + "---" + EOL; + } + + @Override + protected String getVerbatimCodeSource() { + return "+--" + EOL + "<>{}=#*" + EOL + "+--" + EOL; + } } diff --git a/doxia-modules/doxia-module-fml/src/test/java/org/apache/maven/doxia/module/fml/FmlParserTest.java b/doxia-modules/doxia-module-fml/src/test/java/org/apache/maven/doxia/module/fml/FmlParserTest.java index 7eaad969..fb89d26b 100644 --- a/doxia-modules/doxia-module-fml/src/test/java/org/apache/maven/doxia/module/fml/FmlParserTest.java +++ b/doxia-modules/doxia-module-fml/src/test/java/org/apache/maven/doxia/module/fml/FmlParserTest.java @@ -29,8 +29,8 @@ import java.util.Iterator; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; +import org.apache.maven.doxia.parser.AbstractParser; import org.apache.maven.doxia.parser.AbstractParserTest; -import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.impl.SinkEventElement; import org.apache.maven.doxia.sink.impl.SinkEventTestingSink; @@ -73,7 +73,7 @@ public class FmlParserTest extends AbstractParserTest { } /** {@inheritDoc} */ - protected Parser createParser() { + protected AbstractParser createParser() { return parser; } @@ -272,6 +272,65 @@ public class FmlParserTest extends AbstractParserTest { assertTrue(content.contains("<a id=\"macro-definition\"></a>" + EOL + "<dt>Macro Question</dt>")); } + @Override + protected void assertEventPrefix(Iterator<SinkEventElement> eventIterator) { + assertSinkStartsWith( + eventIterator, + "head", + "title", + "text", + "title_", + "head_", + "body", + "section1", + "anchor", + "anchor_", + "sectionTitle1", + "text", + "sectionTitle1_", + "numberedList", + "numberedListItem", + "link", + "link_", + "numberedListItem_", + "numberedList_", + "section1_", + "definitionList", + "anchor", + "anchor_", + "definedTerm", + "definedTerm_", + "definition"); + } + + @Override + protected void assertEventSuffix(Iterator<SinkEventElement> eventIterator) { + assertSinkEquals( + eventIterator, + "paragraph", + "link", + "text", + "link_", + "paragraph_", + "definition_", + "definitionList_", + "body_"); + } + + @Override + protected String getVerbatimSource() { + return "<faqs title=\"title\"><part id=\"general\"><faq id=\"first\"><question></question><answer>" + + "<pre><>{}=#*</pre>" + + "</answer></faq></part></faqs>"; + } + + @Override + protected String getVerbatimCodeSource() { + return "<faqs title=\"title\"><part id=\"general\"><faq id=\"first\"><question></question><answer>" + + "<source><>{}=#*</source>" + + "</answer></faq></part></faqs>"; + } + private void assertTextEvent(SinkEventElement textEvt, String string) { assertEquals("text", textEvt.getName()); assertEquals(string, textEvt.getArgs()[0]); diff --git a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java index 9d716de0..4308f051 100644 --- a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java +++ b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java @@ -25,9 +25,9 @@ import java.io.Reader; import java.util.Iterator; import java.util.List; +import org.apache.maven.doxia.parser.AbstractParser; import org.apache.maven.doxia.parser.AbstractParserTest; import org.apache.maven.doxia.parser.ParseException; -import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.SinkEventAttributes; import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.apache.maven.doxia.sink.impl.SinkEventElement; @@ -56,7 +56,7 @@ public class MarkdownParserTest extends AbstractParserTest { * {@inheritDoc} */ @Override - protected Parser createParser() { + protected AbstractParser createParser() { return parser; } @@ -205,12 +205,12 @@ public class MarkdownParserTest extends AbstractParserTest { assertFalse(it.hasNext()); - // PRE element must be a "verbatim" Sink event that specifies - // SOURCE = true + // PRE element must be a "verbatim" Sink event SinkEventElement pre = eventList.get(7); assertEquals("verbatim", pre.getName()); SinkEventAttributeSet preAtts = (SinkEventAttributeSet) pre.getArgs()[0]; - assertFalse(preAtts.containsAttribute(SinkEventAttributes.DECORATION, "source")); + // instead of using a decoration tag on the verbatim event and additional inline event is used + assertTrue(preAtts.isEmpty()); // * CODE element must be an "inline" Sink event that specifies: // * SEMANTICS = "code" and CLASS = "language-java" @@ -778,12 +778,14 @@ public class MarkdownParserTest extends AbstractParserTest { } // test fix for https://github.com/vsch/flexmark-java/issues/384 + @Test public void testFlexIssue384() throws Exception { parseFileToEventTestingSink("flex-384"); } // Apostrophe versus single quotes // Simple apostrophes (like in Sophie's Choice) must not be replaced with a single quote + @Test public void testQuoteVsApostrophe() throws Exception { List<SinkEventElement> eventList = parseFileToEventTestingSink("quote-vs-apostrophe").getEventList(); @@ -798,4 +800,28 @@ public class MarkdownParserTest extends AbstractParserTest { "This apostrophe isn't a quote." + "This \u2018quoted text\u2019 isn't surrounded by apostrophes.", content.toString()); } + + @Override + protected void assertEventPrefix(Iterator<SinkEventElement> eventIterator) { + assertSinkStartsWith(eventIterator, "head", "head_", "body"); + } + + @Override + protected void assertEventSuffix(Iterator<SinkEventElement> eventIterator) { + assertSinkEquals(eventIterator, "body_"); + } + + @Override + protected String getVerbatimSource() { + /** + * Markdown doesn't support verbatim text which is not code: + * https://spec.commonmark.org/0.31.2/#fenced-code-blocks and https://spec.commonmark.org/0.31.2/#indented-code-blocks + */ + return null; + } + + @Override + protected String getVerbatimCodeSource() { + return "```" + EOL + "<>{}=#*" + EOL + "```"; + } } diff --git a/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocSink.java b/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocSink.java index f4e55b96..c90e9024 100644 --- a/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocSink.java +++ b/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocSink.java @@ -44,9 +44,6 @@ public class XdocSink extends Xhtml5BaseSink implements XdocMarkup { // Instance fields // ---------------------------------------------------------------------- - /** An indication on if we're inside verbatim source. */ - private boolean sourceFlag; - private String encoding; private String languageId; @@ -104,8 +101,6 @@ public class XdocSink extends Xhtml5BaseSink implements XdocMarkup { */ protected void init() { super.init(); - - sourceFlag = false; } /** @@ -340,7 +335,6 @@ public class XdocSink extends Xhtml5BaseSink implements XdocMarkup { * @param attributes a {@link org.apache.maven.doxia.sink.SinkEventAttributes} object. */ public void verbatim(SinkEventAttributes attributes) { - setVerbatimFlag(true); MutableAttributeSet atts = SinkUtils.filterAttributes(attributes, SinkUtils.SINK_VERBATIM_ATTRIBUTES); @@ -348,15 +342,16 @@ public class XdocSink extends Xhtml5BaseSink implements XdocMarkup { atts = new SinkEventAttributeSet(); } - boolean source = false; - + this.setVerbatimMode(VerbatimMode.ON); if (atts.isDefined(SinkEventAttributes.DECORATION)) { - sourceFlag = source = "source".equals(atts.getAttribute(SinkEventAttributes.DECORATION)); + if ("source".equals(atts.getAttribute(SinkEventAttributes.DECORATION))) { + this.setVerbatimMode(VerbatimMode.ON_WITH_CODE); + } } atts.removeAttribute(SinkEventAttributes.DECORATION); - if (source) { + if (getVerbatimMode() == VerbatimMode.ON_WITH_CODE) { writeStartTag(SOURCE_TAG, atts); } else { writeStartTag(PRE, atts); @@ -370,15 +365,13 @@ public class XdocSink extends Xhtml5BaseSink implements XdocMarkup { * @see javax.swing.text.html.HTML.Tag#PRE */ public void verbatim_() { - if (sourceFlag) { + if (getVerbatimMode() == VerbatimMode.ON_WITH_CODE) { writeEndTag(SOURCE_TAG); } else { writeEndTag(PRE); } - setVerbatimFlag(false); - - sourceFlag = false; + this.setVerbatimMode(VerbatimMode.OFF); } /** diff --git a/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java b/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java index 2fb5c5d4..eb953355 100644 --- a/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java +++ b/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java @@ -29,9 +29,9 @@ import java.util.Iterator; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; +import org.apache.maven.doxia.parser.AbstractParser; import org.apache.maven.doxia.parser.AbstractParserTest; import org.apache.maven.doxia.parser.ParseException; -import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.apache.maven.doxia.sink.impl.SinkEventElement; @@ -91,7 +91,7 @@ public class XdocParserTest extends AbstractParserTest { } /** {@inheritDoc} */ - protected Parser createParser() { + protected AbstractParser createParser() { return parser; } @@ -430,4 +430,14 @@ public class XdocParserTest extends AbstractParserTest { assertEquals("style", styleElm_.getArgs()[0]); assertFalse(it.hasNext()); } + + @Override + protected String getVerbatimSource() { + return "<pre><![CDATA[<>{}=#*]]></pre>"; + } + + @Override + protected String getVerbatimCodeSource() { + return "<source><![CDATA[<>{}=#*]]></source>"; + } } diff --git a/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5ParserTest.java b/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5ParserTest.java index 60cfc9f6..b939f3d5 100644 --- a/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5ParserTest.java +++ b/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5ParserTest.java @@ -25,8 +25,8 @@ import java.io.FileFilter; import java.util.Iterator; import java.util.regex.Pattern; +import org.apache.maven.doxia.parser.AbstractParser; import org.apache.maven.doxia.parser.AbstractParserTest; -import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.impl.SinkEventElement; import org.apache.maven.doxia.sink.impl.SinkEventTestingSink; import org.junit.jupiter.api.BeforeEach; @@ -63,7 +63,7 @@ public class Xhtml5ParserTest extends AbstractParserTest { } /** {@inheritDoc} */ - protected Parser createParser() { + protected AbstractParser createParser() { return parser; } @@ -181,4 +181,14 @@ public class Xhtml5ParserTest extends AbstractParserTest { assertEquals("listItem_", it.next().getName()); assertEquals("list_", it.next().getName()); } + + @Override + protected String getVerbatimSource() { + return null; // already tested in Xhtml5BaseParserTest + } + + @Override + protected String getVerbatimCodeSource() { + return null; // already tested in Xhtml5BaseParserTest + } } diff --git a/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5SinkTest.java b/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5SinkTest.java index 8d262e0a..875c246a 100644 --- a/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5SinkTest.java +++ b/doxia-modules/doxia-module-xhtml5/src/test/java/org/apache/maven/doxia/module/xhtml5/Xhtml5SinkTest.java @@ -259,7 +259,7 @@ public class Xhtml5SinkTest extends AbstractSinkTest { /** {@inheritDoc} */ protected String getVerbatimSourceBlock(String text) { - return "<div class=\"verbatim source\">\n<pre>" + text + "</pre></div>"; + return "<pre><code>" + text + "</code></pre>"; } /** {@inheritDoc} */