This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch bugfix/accept-anchor-with-name-even-in-xhtml5
in repository https://gitbox.apache.org/repos/asf/maven-doxia.git

commit 3487243ff584f440d049cfabeae74aac403f0bc6
Author: Konrad Windszus <[email protected]>
AuthorDate: Tue Feb 10 20:27:20 2026 +0100

    Support "name" attribute in "a" element still in XHTML5
    
    This is also suggested by
    https://www.w3.org/TR/html5-diff/#obsolete-attributes:
    
    "The following attributes are allowed...:
    ... The name attribute on a."
    
    This closes #1020
---
 .../maven/doxia/parser/Xhtml1BaseParser.java       |  2 ++
 .../maven/doxia/parser/Xhtml5BaseParser.java       |  5 ++++
 .../maven/doxia/parser/AbstractParserTest.java     | 31 ++++++++++++++++++++++
 .../maven/doxia/parser/Xhtml5BaseParserTest.java   | 12 +++++++++
 .../doxia/module/markdown/MarkdownParserTest.java  | 29 +++++++-------------
 5 files changed, 60 insertions(+), 19 deletions(-)

diff --git 
a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml1BaseParser.java 
b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml1BaseParser.java
index a915c812..860f96f4 100644
--- 
a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml1BaseParser.java
+++ 
b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml1BaseParser.java
@@ -118,6 +118,8 @@ public class Xhtml1BaseParser extends Xhtml5BaseParser {
     private static final Map<String, String> ELEMENT_MAPPING_TABLE = new 
HashMap<>();
 
     static {
+        // although obsolete attribute "name" is still allowed, however 
strongly recommended to be replaced by "id"
+        // (https://www.w3.org/TR/html5-diff/#obsolete-attributes)
         ATTRIBUTE_MAPPING_TABLE.put(
                 "a", Collections.singleton(new AttributeMapping("name", "id", 
AttributeMapping.MergeSemantics.IGNORE)));
 
diff --git 
a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml5BaseParser.java 
b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml5BaseParser.java
index 31232f9f..dbfed392 100644
--- 
a/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml5BaseParser.java
+++ 
b/doxia-core/src/main/java/org/apache/maven/doxia/parser/Xhtml5BaseParser.java
@@ -826,6 +826,11 @@ public class Xhtml5BaseParser extends AbstractXmlParser 
implements HtmlMarkup {
             isLink = true;
         } else {
             String id = (String) attribs.getAttribute(Attribute.ID.toString());
+            if (id == null) {
+                // although the "name" attribute is obsolete in HTML5, it is 
still allowed
+                // (https://www.w3.org/TR/html5-diff/#obsolete-attributes)
+                id = (String) attribs.getAttribute(Attribute.NAME.toString());
+            }
             if (id != null) {
                 sink.anchor(validAnchor(id), attribs);
                 isAnchor = true;
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 d90ee119..26bfa9c5 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
@@ -249,6 +249,37 @@ public abstract class AbstractParserTest extends 
AbstractModuleTest {
         assertEventSuffix(it);
     }
 
+    /**
+     * Parse the file and return a {@link SinkEventTestingSink}.
+     *
+     * @param file the file to parse with {@link #parser}
+     * @return a sink to test parsing events
+     * @throws ParseException if the document parsing failed
+     * @throws IOException if an I/O error occurs while closing test reader
+     */
+    protected SinkEventTestingSink parseFileToEventTestingSink(String file) 
throws ParseException, IOException {
+        SinkEventTestingSink sink;
+        try (Reader reader = getTestReader(file)) {
+            sink = new SinkEventTestingSink();
+            createParser().parse(reader, sink);
+        }
+        return sink;
+    }
+
+    /**
+     * Parse the text and return a {@link SinkEventTestingSink}.
+     *
+     * @param file the file to parse with {@link #parser}
+     * @return a sink to test parsing events
+     * @throws ParseException if the document parsing failed
+     */
+    protected SinkEventTestingSink parseSourceToEventTestingSink(String text) 
throws ParseException {
+        SinkEventTestingSink sink;
+        sink = new SinkEventTestingSink();
+        createParser().parse(text, sink);
+        return sink;
+    }
+
     public static void assertSinkEquals(SinkEventElement element, String name, 
Object... args) {
         assertEquals(name, element.getName(), "Name of element doesn't match");
         assertArrayEquals(args, element.getArgs(), "Arguments don't match");
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 5ea893a6..1777e648 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
@@ -942,4 +942,16 @@ class Xhtml5BaseParserTest extends AbstractParserTest {
     protected String getVerbatimCodeSource() {
         return "<pre><code>&lt;&gt;{}=#*</code></pre>";
     }
+
+    @Test
+    void anchorWithName() throws ParseException {
+        String text = "<a name=\"test\"></a>";
+
+        parser.parse(text, sink);
+
+        Iterator<SinkEventElement> it = sink.getEventList().iterator();
+        // first attribute is the id, second is all given attributes
+        assertSinkEquals(it.next(), "anchor", "test", new 
SinkEventAttributeSet("name", "test"));
+        assertSinkEquals(it, "anchor_");
+    }
 }
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 5d644616..1fad1a69 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
@@ -32,7 +32,6 @@ import org.apache.maven.doxia.parser.ParseException;
 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.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -651,24 +650,6 @@ class MarkdownParserTest extends AbstractParserTest {
         assertFalse(it.hasNext());
     }
 
-    /**
-     * Parse the file and return a {@link SinkEventTestingSink}.
-     *
-     * @param file the file to parse with {@link #parser}
-     * @return a sink to test parsing events
-     * @throws ParseException if the document parsing failed
-     * @throws IOException if an I/O error occurs while closing test reader
-     */
-    protected SinkEventTestingSink parseFileToEventTestingSink(String file) 
throws ParseException, IOException {
-        SinkEventTestingSink sink;
-        try (Reader reader = getTestReader(file)) {
-            sink = new SinkEventTestingSink();
-            parser.parse(reader, sink);
-        }
-
-        return sink;
-    }
-
     protected String parseFileToHtml(String file) throws ParseException, 
IOException {
         try (Reader reader = getTestReader(file)) {
             return parser.toXhtml(reader).toString();
@@ -897,4 +878,14 @@ class MarkdownParserTest extends AbstractParserTest {
     protected String getVerbatimCodeSource() {
         return "```" + EOL + "<>{}=#*" + EOL + "```";
     }
+
+    @Test
+    void anchorWithName() throws ParseException {
+        Iterator<SinkEventElement> eventIterator = 
parseSourceToEventTestingSink("<a name=\"my-anchor\">test</a>")
+                .getEventList()
+                .iterator();
+        assertEventPrefix(eventIterator);
+        assertSinkStartsWith(eventIterator, "paragraph", "anchor", "text", 
"anchor_", "paragraph_");
+        assertEventSuffix(eventIterator);
+    }
 }

Reply via email to