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 074f7843 Support strikethrough for Markdown sink (#1033)
074f7843 is described below

commit 074f7843ed2fec3e9843f4bce29e3c36d959bf80
Author: Konrad Windszus <[email protected]>
AuthorDate: Tue Feb 24 10:41:54 2026 +0100

    Support strikethrough for Markdown sink (#1033)
    
    Properly support inline attributes not natively supported in Markdown.
    Add tests for strikethrough/del to all Sinks.
    Remove unused methods from Sink tests.
    
    This closes #872
---
 .../maven/doxia/sink/impl/AbstractSinkTest.java    | 32 +++++++++-
 .../apache/maven/doxia/module/apt/AptSinkTest.java | 12 +---
 .../doxia/module/markdown/MarkdownMarkup.java      |  6 ++
 .../maven/doxia/module/markdown/MarkdownSink.java  | 71 ++++++++++++++++------
 .../doxia/module/markdown/MarkdownParserTest.java  | 13 ++++
 .../doxia/module/markdown/MarkdownSinkTest.java    |  8 +--
 .../maven/doxia/module/xdoc/XdocSinkTest.java      |  4 ++
 .../maven/doxia/module/xhtml5/Xhtml5SinkTest.java  | 12 +---
 8 files changed, 114 insertions(+), 44 deletions(-)

diff --git 
a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/AbstractSinkTest.java
 
b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/AbstractSinkTest.java
index 5e5cc0c2..022f80d0 100644
--- 
a/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/AbstractSinkTest.java
+++ 
b/doxia-core/src/test/java/org/apache/maven/doxia/sink/impl/AbstractSinkTest.java
@@ -1009,7 +1009,7 @@ public abstract class AbstractSinkTest extends 
AbstractModuleTest {
     /**
      * Checks that the sequence <code>[inline(italic), text(text), 
inline_()]</code>,
      * invoked on the current sink, produces the same result as
-     * {@link #getInlineBoldBlock getInlineBoldBlock}(text).
+     * {@link #getInlineItalicBlock}.
      */
     @Test
     public void inlineItalic() {
@@ -1029,7 +1029,7 @@ public abstract class AbstractSinkTest extends 
AbstractModuleTest {
     /**
      * Checks that the sequence <code>[inline(code), text(text), 
inline_()]</code>,
      * invoked on the current sink, produces the same result as
-     * {@link #getInlineBoldBlock getInlineBoldBlock}(text).
+     * {@link #getInlineCodeBlock}.
      */
     @Test
     public void inlineCode() {
@@ -1046,6 +1046,26 @@ public abstract class AbstractSinkTest extends 
AbstractModuleTest {
         assertEquals(expected, actual, "Wrong inline code!");
     }
 
+    /**
+     * Checks that the sequence <code>[inline(code), text(text), 
inline_()]</code>,
+     * invoked on the current sink, produces the same result as
+     * {@link #getInlineDeleteBlock}.
+     */
+    @Test
+    public void inlineDelete() {
+        String text = "InlineDelete";
+        sink.inline(SinkEventAttributeSet.Semantics.DELETE);
+        sink.text(text);
+        sink.inline_();
+        sink.flush();
+        sink.close();
+
+        String actual = testWriter.toString();
+        String expected = getInlineDeleteBlock(text);
+
+        assertEquals(expected, actual, "Wrong inline code!");
+    }
+
     /**
      * Checks that the sequence <code>[lineBreak()]</code>,
      * invoked on the current sink, produces the same result as
@@ -1565,6 +1585,14 @@ public abstract class AbstractSinkTest extends 
AbstractModuleTest {
      */
     protected abstract String getInlineCodeBlock(String text);
 
+    /**
+     * Returns an Inline code block generated by this sink.
+     * @param text The text to use.
+     * @return The result of invoking a Inline cdldgd block on the current 
sink.
+     * @see #inlineBold()
+     */
+    protected abstract String getInlineDeleteBlock(String text);
+
     /**
      * Returns a LineBreak block generated by this sink.
      * @return The result of invoking a LineBreak block on the current sink.
diff --git 
a/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptSinkTest.java
 
b/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptSinkTest.java
index 2ff3b72b..bbad9639 100644
--- 
a/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptSinkTest.java
+++ 
b/doxia-modules/doxia-module-apt/src/test/java/org/apache/maven/doxia/module/apt/AptSinkTest.java
@@ -256,15 +256,9 @@ class AptSinkTest extends AbstractSinkTest {
         return AptMarkup.MONOSPACED_START_MARKUP + text + 
AptMarkup.MONOSPACED_END_MARKUP;
     }
 
-    protected String getItalicBlock(String text) {
-        return AptMarkup.ITALIC_START_MARKUP + text + 
AptMarkup.ITALIC_END_MARKUP;
-    }
-
-    protected String getBoldBlock(String text) {
-        return AptMarkup.BOLD_START_MARKUP + text + AptMarkup.BOLD_END_MARKUP;
-    }
-
-    protected String getMonospacedBlock(String text) {
+    @Override
+    protected String getInlineDeleteBlock(String text) {
+        // delete/strikethrough is not supported in APT, so we just return the 
text without any markup
         return text;
     }
 
diff --git 
a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownMarkup.java
 
b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownMarkup.java
index b7bbccd2..9d7b0f55 100644
--- 
a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownMarkup.java
+++ 
b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownMarkup.java
@@ -68,6 +68,12 @@ public interface MarkdownMarkup extends TextMarkup {
     /** Syntax for the italic style start: "_" */
     String ITALIC_START_MARKUP = "_";
 
+    /** Syntax for the strikethrough style end: "~~", 
https://github.github.com/gfm/#strikethrough-extension- */
+    String STRIKETHROUGH_END_MARKUP = "~~";
+
+    /** Syntax for the strikethrough style start: "~~", 
https://github.github.com/gfm/#strikethrough-extension- */
+    String STRIKETHROUGH_START_MARKUP = "~~";
+
     /** Syntax for the link end: ")" */
     String LINK_END_MARKUP = ")";
 
diff --git 
a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
 
b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
index e40d59dd..88c987a0 100644
--- 
a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
+++ 
b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
@@ -18,6 +18,9 @@
  */
 package org.apache.maven.doxia.module.markdown;
 
+import javax.swing.text.AttributeSet;
+import javax.swing.text.MutableAttributeSet;
+
 import java.io.PrintWriter;
 import java.io.Writer;
 import java.util.ArrayList;
@@ -88,7 +91,9 @@ public class MarkdownSink extends Xhtml5BaseSink implements 
MarkdownMarkup {
     /** A temporary writer used to buffer the last two lines */
     private final LastTwoLinesBufferingWriter bufferingWriter;
 
-    /** Keep track of end markup for inline events. */
+    private static final String USE_XHTML_SINK = "XhtmlSink";
+
+    /** Keep track of end markup for inline events. Special value  {@link 
#USE_XHTML_SINK} is used to indicate usage of the Xhtml5BaseSink.inline_()*/
     protected Queue<Queue<String>> inlineStack;
 
     /** The context of the surrounding elements as stack (LIFO) */
@@ -1074,19 +1079,19 @@ public class MarkdownSink extends Xhtml5BaseSink 
implements MarkdownMarkup {
 
     @Override
     public void inline(SinkEventAttributes attributes) {
+        Queue<String> endMarkups = Collections.asLifoQueue(new LinkedList<>());
         if (elementContextStack.element().isHtml()) {
             super.inline(attributes);
+            endMarkups.add(USE_XHTML_SINK);
         } else {
-            Queue<String> endMarkups = Collections.asLifoQueue(new 
LinkedList<>());
-
             boolean requiresHtml = elementContextStack.element() == 
ElementContext.HTML_BLOCK;
             if (attributes != null
                     && elementContextStack.element() != 
ElementContext.CODE_BLOCK
                     && elementContextStack.element() != 
ElementContext.CODE_SPAN) {
                 // code excludes other styles in markdown
-                if 
(attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "code")
-                        || 
attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "monospaced")
-                        || 
attributes.containsAttribute(SinkEventAttributes.STYLE, "monospaced")) {
+                if 
(attributes.containsAttributes(SinkEventAttributeSet.Semantics.CODE)
+                        || 
attributes.containsAttributes(SinkEventAttributeSet.Semantics.MONOSPACED)
+                        || 
attributes.containsAttributes(SinkEventAttributeSet.MONOSPACED)) {
                     if (requiresHtml) {
                         writeUnescaped("<code>");
                         endMarkups.add("</code>");
@@ -1096,10 +1101,13 @@ public class MarkdownSink extends Xhtml5BaseSink 
implements MarkdownMarkup {
                         endMarkups.add(MONOSPACED_END_MARKUP);
                     }
                 } else {
+                    SinkEventAttributeSet remainingAttributes = new 
SinkEventAttributeSet(attributes);
                     // in XHTML "<em>" is used, but some tests still rely on 
the outdated "<italic>"
-                    if 
(attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "emphasis")
-                            || 
attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "italic")
-                            || 
attributes.containsAttribute(SinkEventAttributes.STYLE, "italic")) {
+                    if (filterAttributes(
+                            remainingAttributes,
+                            SinkEventAttributeSet.Semantics.EMPHASIS,
+                            SinkEventAttributeSet.Semantics.ITALIC,
+                            SinkEventAttributeSet.ITALIC)) {
                         if (requiresHtml) {
                             writeUnescaped("<em>");
                             endMarkups.add("</em>");
@@ -1109,9 +1117,11 @@ public class MarkdownSink extends Xhtml5BaseSink 
implements MarkdownMarkup {
                         }
                     }
                     // in XHTML "<strong>" is used, but some tests still rely 
on the outdated "<bold>"
-                    if 
(attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "strong")
-                            || 
attributes.containsAttribute(SinkEventAttributes.SEMANTICS, "bold")
-                            || 
attributes.containsAttribute(SinkEventAttributes.STYLE, "bold")) {
+                    if (filterAttributes(
+                            remainingAttributes,
+                            SinkEventAttributeSet.Semantics.STRONG,
+                            SinkEventAttributeSet.Semantics.BOLD,
+                            SinkEventAttributeSet.BOLD)) {
                         if (requiresHtml) {
                             writeUnescaped("<strong>");
                             endMarkups.add("</strong>");
@@ -1120,18 +1130,45 @@ public class MarkdownSink extends Xhtml5BaseSink 
implements MarkdownMarkup {
                             endMarkups.add(BOLD_END_MARKUP);
                         }
                     }
+                    // <del> is supported via GFM strikethrough extension
+                    if (filterAttributes(remainingAttributes, 
SinkEventAttributeSet.Semantics.DELETE)) {
+                        if (requiresHtml) {
+                            writeUnescaped("<del>");
+                            endMarkups.add("</del>");
+                        } else {
+                            writeUnescaped(STRIKETHROUGH_START_MARKUP);
+                            endMarkups.add(STRIKETHROUGH_END_MARKUP);
+                        }
+                    }
+                    if (!remainingAttributes.isEmpty()) {
+                        // use HTML for other inline semantics which are not 
natively supported in Markdown (e.g.
+                        // subscript, superscript, small, etc.)
+                        super.inline(remainingAttributes);
+                        endMarkups.add(USE_XHTML_SINK);
+                    }
                 }
             }
-            inlineStack.add(endMarkups);
         }
+        inlineStack.add(endMarkups);
+    }
+
+    private static boolean filterAttributes(MutableAttributeSet attributes, 
AttributeSet... attributesToFilter) {
+        boolean hasAny = false;
+        for (AttributeSet attributeSet : attributesToFilter) {
+            if (attributes.containsAttributes(attributeSet)) {
+                hasAny = true;
+                attributes.removeAttributes(attributeSet);
+            }
+        }
+        return hasAny;
     }
 
     @Override
     public void inline_() {
-        if (elementContextStack.element().isHtml()) {
-            super.inline_();
-        } else {
-            for (String endMarkup : inlineStack.remove()) {
+        for (String endMarkup : inlineStack.remove()) {
+            if (USE_XHTML_SINK.equals(endMarkup)) {
+                super.inline_();
+            } else {
                 if (endMarkup.equals(MONOSPACED_END_MARKUP)) {
                     String buffer = getCurrentBuffer().toString();
                     endContext(ElementContext.CODE_SPAN);
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 1fad1a69..4b9b66e4 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
@@ -888,4 +888,17 @@ class MarkdownParserTest extends AbstractParserTest {
         assertSinkStartsWith(eventIterator, "paragraph", "anchor", "text", 
"anchor_", "paragraph_");
         assertEventSuffix(eventIterator);
     }
+
+    @Test
+    void strikeThrough() throws ParseException {
+        Iterator<SinkEventElement> eventIterator = 
parseSourceToEventTestingSink("~~strikethrough~~")
+                .getEventList()
+                .iterator();
+        assertEventPrefix(eventIterator);
+        assertSinkStartsWith(eventIterator, "paragraph");
+        // https://github.github.com/gfm/#strikethrough-extension- uses "del" 
element (not "s")
+        assertSinkEquals(eventIterator.next(), "inline", 
SinkEventAttributeSet.Semantics.DELETE);
+        assertSinkStartsWith(eventIterator, "text", "inline_", "paragraph_");
+        assertEventSuffix(eventIterator);
+    }
 }
diff --git 
a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
 
b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
index 81cd43dc..95c06f95 100644
--- 
a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
+++ 
b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
@@ -259,12 +259,8 @@ class MarkdownSinkTest extends AbstractSinkTest {
         return MarkdownMarkup.MONOSPACED_START_MARKUP + text + 
MarkdownMarkup.MONOSPACED_END_MARKUP;
     }
 
-    protected String getItalicBlock(String text) {
-        return MarkdownMarkup.ITALIC_START_MARKUP + text + 
MarkdownMarkup.ITALIC_END_MARKUP;
-    }
-
-    protected String getBoldBlock(String text) {
-        return MarkdownMarkup.BOLD_START_MARKUP + text + 
MarkdownMarkup.BOLD_END_MARKUP;
+    protected String getInlineDeleteBlock(String text) {
+        return MarkdownMarkup.STRIKETHROUGH_START_MARKUP + text + 
MarkdownMarkup.STRIKETHROUGH_END_MARKUP;
     }
 
     protected String getMonospacedBlock(String text) {
diff --git 
a/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocSinkTest.java
 
b/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocSinkTest.java
index ea39ea35..c664c872 100644
--- 
a/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocSinkTest.java
+++ 
b/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocSinkTest.java
@@ -261,6 +261,10 @@ public class XdocSinkTest extends AbstractSinkTest {
         return "<code>" + text + "</code>";
     }
 
+    protected String getInlineDeleteBlock(String text) {
+        return "<del>" + text + "</del>";
+    }
+
     protected String getLineBreakBlock() {
         return "<br />";
     }
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 d0e0c75c..87da4b18 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,16 +259,8 @@ public class Xhtml5SinkTest extends AbstractSinkTest {
         return "<code>" + text + "</code>";
     }
 
-    protected String getItalicBlock(String text) {
-        return "<i>" + text + "</i>";
-    }
-
-    protected String getBoldBlock(String text) {
-        return "<b>" + text + "</b>";
-    }
-
-    protected String getMonospacedBlock(String text) {
-        return "<code>" + text + "</code>";
+    protected String getInlineDeleteBlock(String text) {
+        return "<del>" + text + "</del>";
     }
 
     protected String getLineBreakBlock() {

Reply via email to