diff --git a/.idea/markdown-exported-files.xml b/.idea/markdown-exported-files.xml index a404d7591..9319bc56a 100644 --- a/.idea/markdown-exported-files.xml +++ b/.idea/markdown-exported-files.xml @@ -2,52 +2,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + diff --git a/.idea/markdown-navigator/COPY_HTML_MIME.xml b/.idea/markdown-navigator/COPY_HTML_MIME.xml index bc8aaad07..b53f944f9 100644 --- a/.idea/markdown-navigator/COPY_HTML_MIME.xml +++ b/.idea/markdown-navigator/COPY_HTML_MIME.xml @@ -1,6 +1,6 @@ - diff --git a/flexmark-ext-admonition/pom.xml b/flexmark-ext-admonition/pom.xml index e22050089..fa6b7ba01 100644 --- a/flexmark-ext-admonition/pom.xml +++ b/flexmark-ext-admonition/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-admonition diff --git a/flexmark-ext-anchorlink/pom.xml b/flexmark-ext-anchorlink/pom.xml index 2edb4690d..95a352085 100644 --- a/flexmark-ext-anchorlink/pom.xml +++ b/flexmark-ext-anchorlink/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-anchorlink @@ -28,7 +28,7 @@ com.vladsch.flexmark flexmark-jira-converter - 0.35.6 + 0.35.10 test diff --git a/flexmark-ext-aside/pom.xml b/flexmark-ext-aside/pom.xml index 084b79237..eb3c718bc 100644 --- a/flexmark-ext-aside/pom.xml +++ b/flexmark-ext-aside/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-aside diff --git a/flexmark-ext-attributes/flexmark-ext-attributes.iml b/flexmark-ext-attributes/flexmark-ext-attributes.iml index 64600b4f4..2754ba46a 100644 --- a/flexmark-ext-attributes/flexmark-ext-attributes.iml +++ b/flexmark-ext-attributes/flexmark-ext-attributes.iml @@ -36,5 +36,7 @@ + + \ No newline at end of file diff --git a/flexmark-ext-attributes/pom.xml b/flexmark-ext-attributes/pom.xml index 6e629cdba..5e2aa1081 100644 --- a/flexmark-ext-attributes/pom.xml +++ b/flexmark-ext-attributes/pom.xml @@ -1,58 +1,138 @@ - 4.0.0 - - com.vladsch.flexmark - flexmark-java - 0.35.6 - - - flexmark-ext-attributes - flexmark-java extension for attributes - flexmark-java extension for attributes - - - - com.vladsch.flexmark - flexmark-util - - - com.vladsch.flexmark - flexmark - - - com.vladsch.flexmark - flexmark-test-util - test - - - com.vladsch.flexmark - flexmark-ext-anchorlink - test - - - com.vladsch.flexmark - flexmark-ext-toc - test - - - com.vladsch.flexmark - flexmark-ext-definition - test - - - com.vladsch.flexmark - flexmark-ext-tables - test - - - com.vladsch.flexmark - flexmark-ext-emoji - test - - - com.vladsch.flexmark - flexmark-formatter - - + + 4.0.0 + + + + com.vladsch.flexmark + + + flexmark-java + + 0.35.10 + + + flexmark-ext-attributes + + + flexmark-java extension for attributes + + + flexmark-java extension for attributes + + + + + com.vladsch.flexmark + + + flexmark-util + + + + + com.vladsch.flexmark + + + flexmark + + + + + com.vladsch.flexmark + + + flexmark-test-util + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-anchorlink + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-toc + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-definition + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-escaped-character + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-tables + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-typographic + + + test + + + + + com.vladsch.flexmark + + + flexmark-ext-emoji + + + test + + + + + com.vladsch.flexmark + + + flexmark-formatter + + + diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributeNode.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributeNode.java index cd2591bd2..db7dee5a7 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributeNode.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributeNode.java @@ -1,6 +1,6 @@ package com.vladsch.flexmark.ext.attributes; -import com.vladsch.flexmark.ast.CustomNode; +import com.vladsch.flexmark.ast.Node; import com.vladsch.flexmark.ast.DoNotDecorate; import com.vladsch.flexmark.util.html.Attribute; import com.vladsch.flexmark.util.sequence.BasedSequence; @@ -8,7 +8,7 @@ /** * An Attribute node representing a single attribute name and value in attributes node */ -public class AttributeNode extends CustomNode implements DoNotDecorate { +public class AttributeNode extends Node implements DoNotDecorate { protected BasedSequence name = BasedSequence.NULL; protected BasedSequence attributeSeparator = BasedSequence.NULL; protected BasedSequence openingMarker = BasedSequence.NULL; diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesDelimiter.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesDelimiter.java new file mode 100644 index 000000000..2bbd1c0a4 --- /dev/null +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesDelimiter.java @@ -0,0 +1,27 @@ +package com.vladsch.flexmark.ext.attributes; + +import com.vladsch.flexmark.ast.DelimitedNode; +import com.vladsch.flexmark.ast.Node; +import com.vladsch.flexmark.ast.DoNotDecorate; +import com.vladsch.flexmark.ast.NonRenderingInline; +import com.vladsch.flexmark.util.sequence.BasedSequence; + +/** + * A empty implicit AttributesNode used to mark attribute span start + */ +public class AttributesDelimiter extends AttributesNode { + public AttributesDelimiter() { + } + + public AttributesDelimiter(final BasedSequence chars) { + super(chars); + } + + public AttributesDelimiter(final BasedSequence openingMarker, final BasedSequence text, final BasedSequence closingMarker) { + super(openingMarker, text, closingMarker); + } + + public AttributesDelimiter(final BasedSequence chars, final String attributesBlockText) { + super(chars, attributesBlockText); + } +} diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesExtension.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesExtension.java index 75c7d2704..a55a5abd5 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesExtension.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesExtension.java @@ -36,6 +36,8 @@ public class AttributesExtension implements Parser.ParserExtension }); public static final DataKey ATTRIBUTES_KEEP = new DataKey<>("ATTRIBUTES_KEEP", KeepType.FIRST); // standard option to allow control over how to handle duplicates public static final DataKey ASSIGN_TEXT_ATTRIBUTES = new DataKey<>("ASSIGN_TEXT_ATTRIBUTES", true); // assign attributes to text if previous is not a space + public static final DataKey WRAP_NON_ATTRIBUTE_TEXT = new DataKey<>("WRAP_NON_ATTRIBUTE_TEXT", true); + public static final DataKey USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER = new DataKey<>("USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER", false); private AttributesExtension() { } diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesNode.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesNode.java index c486c4fe8..d341c47d0 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesNode.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/AttributesNode.java @@ -1,6 +1,6 @@ package com.vladsch.flexmark.ext.attributes; -import com.vladsch.flexmark.ast.CustomNode; +import com.vladsch.flexmark.ast.Node; import com.vladsch.flexmark.ast.DelimitedNode; import com.vladsch.flexmark.ast.DoNotDecorate; import com.vladsch.flexmark.ast.NonRenderingInline; @@ -9,7 +9,7 @@ /** * A AttributesNode node */ -public class AttributesNode extends CustomNode implements DelimitedNode, DoNotDecorate, NonRenderingInline { +public class AttributesNode extends Node implements DelimitedNode, DoNotDecorate, NonRenderingInline { protected BasedSequence openingMarker = BasedSequence.NULL; protected BasedSequence text = BasedSequence.NULL; protected BasedSequence closingMarker = BasedSequence.NULL; diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributeParsing.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributeParsing.java index a0ddba1f0..50fa2f91b 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributeParsing.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributeParsing.java @@ -4,6 +4,8 @@ import java.util.regex.Pattern; +import static com.vladsch.flexmark.ext.attributes.AttributesExtension.USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER; + class AttributeParsing { final Parsing myParsing; final Pattern ATTRIBUTES_TAG; @@ -13,7 +15,17 @@ public AttributeParsing(Parsing parsing) { this.myParsing = parsing; String unquotedValue = myParsing.UNQUOTEDVALUE;//.replace("]+","}{"); // exclude braces this.ATTRIBUTE = Pattern.compile("\\s*([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?"); - this.ATTRIBUTES_TAG = Pattern.compile("\\{((?:" + "\\s*([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")" + - "(?:" + "\\s+([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")*" + ")\\s*\\}"); + + if (USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER.getFrom(parsing.options)) { + this.ATTRIBUTES_TAG = Pattern.compile( + "^\\{((?:[#.])|(?:" + "\\s*([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")" + + "(?:" + "\\s+([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")*" + "\\s*)\\}" + ); + } else { + this.ATTRIBUTES_TAG = Pattern.compile( + "^\\{((?:" + "\\s*([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")" + + "(?:" + "\\s+([#.]" + unquotedValue + "|" + myParsing.ATTRIBUTENAME + ")\\s*(?:=\\s*(" + myParsing.ATTRIBUTEVALUE + ")?" + ")?" + ")*" + "\\s*)\\}" + ); + } } } diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesInlineParserExtension.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesInlineParserExtension.java index 56d5d5ef4..ac544f0cc 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesInlineParserExtension.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesInlineParserExtension.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ext.attributes.internal; import com.vladsch.flexmark.ext.attributes.AttributeNode; +import com.vladsch.flexmark.ext.attributes.AttributesDelimiter; import com.vladsch.flexmark.ext.attributes.AttributesNode; import com.vladsch.flexmark.parser.InlineParser; import com.vladsch.flexmark.parser.InlineParserExtension; @@ -38,13 +39,15 @@ public boolean parse(final InlineParser inlineParser) { // see what we have // open, see if open/close BasedSequence attributesText = input.subSequence(matcher.start(1), matcher.end(1)); - AttributesNode attributes = new AttributesNode(attributesOpen.subSequence(0, 1), attributesText, attributesOpen.endSequence(1)); + AttributesNode attributes = attributesText.equals("#") || attributesText.equals(".") ? new AttributesDelimiter(attributesOpen.subSequence(0, 1), attributesText, attributesOpen.endSequence(1)) + : new AttributesNode(attributesOpen.subSequence(0, 1), attributesText, attributesOpen.endSequence(1)); + attributes.setCharsFromContent(); int leadingSpaces = attributesText.countLeading(" \t"); // give it to the text node if (leadingSpaces > 0) { - inlineParser.appendText(attributesText,0,leadingSpaces); + inlineParser.appendText(attributesText, 0, leadingSpaces); attributesText = attributesText.subSequence(leadingSpaces); } @@ -52,7 +55,7 @@ public boolean parse(final InlineParser inlineParser) { inlineParser.getBlock().appendChild(attributes); BasedSequence attributeText = attributesText.trim(); - if (!attributeText.isEmpty()) { + if (!attributeText.isEmpty() && attributes instanceof AttributesNode) { // have some attribute text // parse attributes Matcher attributeMatcher = parsing.ATTRIBUTE.matcher(attributeText); diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodeFormatter.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodeFormatter.java index 8aa0f9622..43eb856a6 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodeFormatter.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodeFormatter.java @@ -1,5 +1,6 @@ package com.vladsch.flexmark.ext.attributes.internal; +import com.vladsch.flexmark.ext.attributes.AttributesDelimiter; import com.vladsch.flexmark.ast.Document; import com.vladsch.flexmark.ast.Node; import com.vladsch.flexmark.ext.attributes.AttributeNode; @@ -67,6 +68,12 @@ public void render(AttributesNode node, NodeFormatterContext context, MarkdownWr AttributesNodeFormatter.this.render(node, context, markdown); } })); + set.add(new NodeFormattingHandler(AttributesDelimiter.class, new CustomNodeFormatter() { + @Override + public void render(AttributesDelimiter node, NodeFormatterContext context, MarkdownWriter markdown) { + AttributesNodeFormatter.this.render(node, context, markdown); + } + })); return set; } diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodePostProcessor.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodePostProcessor.java index bac671627..e00623c6f 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodePostProcessor.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesNodePostProcessor.java @@ -2,12 +2,15 @@ import com.vladsch.flexmark.ast.*; import com.vladsch.flexmark.ext.attributes.AttributeNode; +import com.vladsch.flexmark.ext.attributes.AttributesDelimiter; import com.vladsch.flexmark.ext.attributes.AttributesExtension; import com.vladsch.flexmark.ext.attributes.AttributesNode; import com.vladsch.flexmark.parser.block.NodePostProcessor; import com.vladsch.flexmark.parser.block.NodePostProcessorFactory; import com.vladsch.flexmark.util.NodeTracker; +import java.util.ArrayList; + public class AttributesNodePostProcessor extends NodePostProcessor { private final NodeAttributeRepository nodeAttributeRepository; private final AttributesOptions myOptions; @@ -18,7 +21,7 @@ public AttributesNodePostProcessor(Document document) { } public Node getAttributeOwner(NodeTracker state, AttributesNode attributesNode) { - Node previous = attributesNode.getPreviousAnyNot(BlankLine.class); + Node previous = attributesNode.getPreviousAnyNot(BlankLine.class, DoNotAttributeDecorate.class); Node next = attributesNode.getNext(); Node attributeOwner; Node parent = attributesNode.getParent(); @@ -81,14 +84,50 @@ public Node getAttributeOwner(NodeTracker state, AttributesNode attributesNode) } else { if ((!myOptions.assignTextAttributes && (previous instanceof Text || previous instanceof TextBase)) || previous.getChars().getEndOffset() < attributesNode.getStartOffset()) { // either previous is text and no text attributes or not attached to the previous node - // then attributes go to parent - if (parent instanceof Paragraph && parent.getParent() instanceof ParagraphItemContainer) { + // then attributes go to parent unless overridden by delimited attribute spans + + if (myOptions.useEmptyImplicitAsSpanDelimiter) { + // find first previous not delimited by unmatched attribute + previous = matchDelimitedSpans(state, attributesNode, previous); + } + + if (previous instanceof TextBase) { + // use delimited span + attributeOwner = previous; + } else if (parent instanceof Paragraph && parent.getParent() instanceof ParagraphItemContainer) { attributeOwner = parent.getParent(); } else { attributeOwner = parent; } } else { - // attached, attributes go to previous node + // attached, attributes go to previous node, but may need to wrap spans containing DoNotAttributeDecorate in TextBase + if (myOptions.wrapNonAttributeText) { + // find first previous not delimited by attribute + Node first = attributesNode.getPrevious(); + Node lastNonAttributesNode = null; + boolean hadDoNotDecorate = false; + + while (first != null && (first instanceof Text || first instanceof DoNotAttributeDecorate)) { + if (first instanceof DoNotAttributeDecorate) { + hadDoNotDecorate = true; + } + lastNonAttributesNode = first; + first = first.getPrevious(); + } + + if (hadDoNotDecorate) { + // need to wrap in text base from first to attribute node + TextBase textBase = new TextBase(); + textBaseWrap(state, lastNonAttributesNode, attributesNode, textBase); + previous = textBase; + } + } + + if (myOptions.useEmptyImplicitAsSpanDelimiter) { + // find first previous not delimited by unmatched attribute + previous = matchDelimitedSpans(state, attributesNode, previous); + } + if (previous instanceof Text) { // insert text base where text was TextBase textBase = new TextBase(previous.getChars()); @@ -99,6 +138,9 @@ public Node getAttributeOwner(NodeTracker state, AttributesNode attributesNode) textBase.appendChild(previous); state.nodeAddedWithChildren(textBase); attributeOwner = textBase; + } else if (previous instanceof AttributesDelimiter) { + // no owner, attributes go into aether + attributeOwner = null; } else { if (previous instanceof AttributesNode) { // we are spliced right up against previous attributes, give our attributes to the owner of previous attributes @@ -112,6 +154,72 @@ public Node getAttributeOwner(NodeTracker state, AttributesNode attributesNode) return attributeOwner; } + static Node matchDelimitedSpans(NodeTracker state, AttributesNode attributesNode, Node previous) { + Node first = attributesNode.getPrevious(); + Node lastNonAttributesNode = null; + ArrayList unmatchedAttributes = new ArrayList<>(); + + while (first != null) { + if (first instanceof AttributesDelimiter) { + if (!unmatchedAttributes.isEmpty()) { + // match it and wrap in text + Node lastNode = unmatchedAttributes.remove(unmatchedAttributes.size() - 1); + lastNonAttributesNode = first.getNext(); + if (lastNode != lastNonAttributesNode) { + TextBase textBase = new TextBase(); + + textBaseWrap(state, lastNonAttributesNode, lastNode, textBase); + lastNonAttributesNode = textBase; + } else { + previous = first; + } + } else { + // unmatched delimiter is our start span + TextBase textBase = new TextBase(); + lastNonAttributesNode = first.getNext(); + + if (lastNonAttributesNode != attributesNode) { + textBaseWrap(state, lastNonAttributesNode, attributesNode, textBase); + previous = textBase; + } else { + previous = first; + } + break; + } + } else if (first instanceof AttributesNode) { + unmatchedAttributes.add(first); + } else { + lastNonAttributesNode = first; + } + + first = first.getPrevious(); + } + + if (!unmatchedAttributes.isEmpty()) { + // use the first unmatched as our end of attribute span + previous = unmatchedAttributes.get(0); + Node previousNext = previous.getNext(); + if (previousNext != null && previousNext != attributesNode) { + previous = previousNext; + } + } + + return previous; + } + + static void textBaseWrap(final NodeTracker state, Node lastNonAttributesNode, final Node lastNode, final TextBase textBase) { + while (lastNonAttributesNode != lastNode) { + Node nextNode = lastNonAttributesNode.getNext(); + lastNonAttributesNode.unlink(); + state.nodeRemoved(lastNonAttributesNode); + textBase.appendChild(lastNonAttributesNode); + lastNonAttributesNode = nextNode; + } + textBase.setCharsFromContent(); + lastNode.insertBefore(textBase); + state.nodeAddedWithDescendants(textBase); + } + @Override public void process(NodeTracker state, Node node) { if (node instanceof AttributesNode) { @@ -154,15 +262,17 @@ public void process(NodeTracker state, Node node) { } Node attributeOwner = getAttributeOwner(state, attributesNode); - nodeAttributeRepository.put(attributeOwner, attributesNode); - - // set the heading id for this node so the correct id will be used - if (attributeOwner instanceof AnchorRefTarget) { - for (Node attributeNode : attributesNode.getReversedChildren()) { - if (attributeNode instanceof AttributeNode) { - if (((AttributeNode) attributeNode).isId()) { - ((AnchorRefTarget) attributeOwner).setAnchorRefId(((AttributeNode) attributeNode).getValue().toString()); - break; + if (attributeOwner != null) { + nodeAttributeRepository.put(attributeOwner, attributesNode); + + // set the heading id for this node so the correct id will be used + if (attributeOwner instanceof AnchorRefTarget) { + for (Node attributeNode : attributesNode.getReversedChildren()) { + if (attributeNode instanceof AttributeNode) { + if (((AttributeNode) attributeNode).isId()) { + ((AnchorRefTarget) attributeOwner).setAnchorRefId(((AttributeNode) attributeNode).getValue().toString()); + break; + } } } } diff --git a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesOptions.java b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesOptions.java index ff85020e6..154ba965c 100644 --- a/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesOptions.java +++ b/flexmark-ext-attributes/src/main/java/com/vladsch/flexmark/ext/attributes/internal/AttributesOptions.java @@ -7,14 +7,20 @@ class AttributesOptions implements MutableDataSetter { public final boolean assignTextAttributes; + public final boolean wrapNonAttributeText; + public final boolean useEmptyImplicitAsSpanDelimiter; public AttributesOptions(DataHolder options) { assignTextAttributes = AttributesExtension.ASSIGN_TEXT_ATTRIBUTES.getFrom(options); + wrapNonAttributeText = AttributesExtension.WRAP_NON_ATTRIBUTE_TEXT.getFrom(options); + useEmptyImplicitAsSpanDelimiter = AttributesExtension.USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER.getFrom(options); } @Override public MutableDataHolder setIn(final MutableDataHolder dataHolder) { dataHolder.set(AttributesExtension.ASSIGN_TEXT_ATTRIBUTES, assignTextAttributes); + dataHolder.set(AttributesExtension.WRAP_NON_ATTRIBUTE_TEXT, wrapNonAttributeText); + dataHolder.set(AttributesExtension.USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER, useEmptyImplicitAsSpanDelimiter); return dataHolder; } } diff --git a/flexmark-ext-attributes/src/main/javadoc/overview.md b/flexmark-ext-attributes/src/main/javadoc/overview.md index bb6518a29..527be484e 100644 --- a/flexmark-ext-attributes/src/main/javadoc/overview.md +++ b/flexmark-ext-attributes/src/main/javadoc/overview.md @@ -41,3 +41,6 @@ Attribute which starts with `#` such as `#id-string` is equivalent to `id="id-st * `style` values are accumulated as a semicolon (`;`) separated list. * all others override any previous values of the same name. +Setting `USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER` to `true`, will treat `{.}` or `{#}` as markers +for start of closest matching attributes node to give greater control of where attributes are +attached in text. diff --git a/flexmark-ext-attributes/src/test/java/com/vladsch/flexmark/ext/attributes/ComboExtAttributesSpecTest.java b/flexmark-ext-attributes/src/test/java/com/vladsch/flexmark/ext/attributes/ComboExtAttributesSpecTest.java index 1b7ec9f8b..6eb1e1d76 100644 --- a/flexmark-ext-attributes/src/test/java/com/vladsch/flexmark/ext/attributes/ComboExtAttributesSpecTest.java +++ b/flexmark-ext-attributes/src/test/java/com/vladsch/flexmark/ext/attributes/ComboExtAttributesSpecTest.java @@ -3,8 +3,10 @@ import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension; import com.vladsch.flexmark.ext.definition.DefinitionExtension; import com.vladsch.flexmark.ext.emoji.EmojiExtension; +import com.vladsch.flexmark.ext.escaped.character.EscapedCharacterExtension; import com.vladsch.flexmark.ext.tables.TablesExtension; import com.vladsch.flexmark.ext.toc.TocExtension; +import com.vladsch.flexmark.ext.typographic.TypographicExtension; import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.spec.SpecExample; @@ -28,6 +30,8 @@ public class ComboExtAttributesSpecTest extends ComboSpecTestCase { TocExtension.create(), EmojiExtension.create(), DefinitionExtension.create(), + EscapedCharacterExtension.create(), + TypographicExtension.create(), TablesExtension.create() )); @@ -40,6 +44,8 @@ public class ComboExtAttributesSpecTest extends ComboSpecTestCase { ); optionsMap.put("text-attributes", new MutableDataSet().set(AttributesExtension.ASSIGN_TEXT_ATTRIBUTES, true)); optionsMap.put("no-text-attributes", new MutableDataSet().set(AttributesExtension.ASSIGN_TEXT_ATTRIBUTES, false)); + optionsMap.put("dont-wrap-non-attributes", new MutableDataSet().set(AttributesExtension.WRAP_NON_ATTRIBUTE_TEXT, false)); + optionsMap.put("empty-implicit-delimiters", new MutableDataSet().set(AttributesExtension.USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER, true)); optionsMap.put("src-pos", new MutableDataSet().set(HtmlRenderer.SOURCE_POSITION_ATTRIBUTE, "md-pos")); } diff --git a/flexmark-ext-attributes/src/test/resources/ext_attributes_ast_spec.md b/flexmark-ext-attributes/src/test/resources/ext_attributes_ast_spec.md index 250910f69..ecbac9483 100644 --- a/flexmark-ext-attributes/src/test/resources/ext_attributes_ast_spec.md +++ b/flexmark-ext-attributes/src/test/resources/ext_attributes_ast_spec.md @@ -95,6 +95,14 @@ For the rest of the specification the `options` following the example will conta * else * Cond 1.3 attributes are assigned to the text element +To allow greater control of attribute assignment it is possible to set +`USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER` to `true`, will treat `{.}` or `{#}` as markers for start +of closest matching attributes node to give greater control of where attributes are attached in +text. + +**NOTE**: If `ASSIGN_TEXT_ATTRIBUTES` is set to `false` then +`USE_EMPTY_IMPLICIT_AS_SPAN_DELIMITER` option is ignored. + attributes assigned to paragraph ```````````````````````````````` example(Text Node Previous Sibling: 1) options(no-text-attributes) @@ -1774,9 +1782,595 @@ Document[0, 162] ```````````````````````````````` -## Trailing Spaces +## Non-Attributes + +wrap non-attributes by default + +```````````````````````````````` example Non-Attributes: 1 +This is a test. It works fine until a word like don't appears.{.style} Another style might follow.{.style2} +. +

This is a test. It works fine until a word like don’t appears. Another style might follow.

+. +Document[0, 108] + Paragraph[0, 108] + Text[0, 51] chars:[0, 51, "This … e don"] + TypographicSmarts[51, 52] typographic: ’ + TextBase[52, 62] chars:[52, 62, "t appears."] + Text[52, 62] chars:[52, 62, "t appears."] + AttributesNode[62, 70] textOpen:[62, 63, "{"] text:[63, 69, ".style"] textClose:[69, 70, "}"] + AttributeNode[63, 69] name:[63, 64, "."] value:[64, 69, "style"] isImplicit isClass + TextBase[70, 98] chars:[70, 98, " Anot … llow."] + Text[70, 98] chars:[70, 98, " Anot … llow."] + AttributesNode[98, 107] textOpen:[98, 99, "{"] text:[99, 106, ".style2"] textClose:[106, 107, "}"] + AttributeNode[99, 106] name:[99, 100, "."] value:[100, 106, "style2"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example Non-Attributes: 2 +This is a test. It works fine until a word like 'don't' appears.{.style} Another style might +follow.{.style2} +. +

This is a test. It works fine until a word like ‘don’t’ appears. Another style might +follow.

+. +Document[0, 110] + Paragraph[0, 110] + Text[0, 48] chars:[0, 48, "This … like "] + TypographicQuotes[48, 55] typographicOpening: ‘ typographicClosing: ’ textOpen:[48, 49, "'"] text:[49, 54, "don't"] textClose:[54, 55, "'"] + Text[49, 52] chars:[49, 52, "don"] + TypographicSmarts[52, 53] typographic: ’ + Text[53, 54] chars:[53, 54, "t"] + TextBase[55, 64] chars:[55, 64, " appears."] + Text[55, 64] chars:[55, 64, " appears."] + AttributesNode[64, 72] textOpen:[64, 65, "{"] text:[65, 71, ".style"] textClose:[71, 72, "}"] + AttributeNode[65, 71] name:[65, 66, "."] value:[66, 71, "style"] isImplicit isClass + Text[72, 92] chars:[72, 92, " Anot … might"] + SoftLineBreak[92, 93] + TextBase[93, 100] chars:[93, 100, "follow."] + Text[93, 100] chars:[93, 100, "follow."] + AttributesNode[100, 109] textOpen:[100, 101, "{"] text:[101, 108, ".style2"] textClose:[108, 109, "}"] + AttributeNode[101, 108] name:[101, 102, "."] value:[102, 108, "style2"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example Non-Attributes: 3 +This is a test. It works fine until a word like don\'t appears.{.style} Another style might +follow.{.style2} +. +

This is a test. It works fine until a word like don't appears. Another style might +follow.

+. +Document[0, 109] + Paragraph[0, 109] + TextBase[0, 63] chars:[0, 63, "This … ears."] + Text[0, 51] chars:[0, 51, "This … e don"] + EscapedCharacter[51, 53] textOpen:[51, 52, "\"] text:[52, 53, "'"] + Text[53, 63] chars:[53, 63, "t appears."] + AttributesNode[63, 71] textOpen:[63, 64, "{"] text:[64, 70, ".style"] textClose:[70, 71, "}"] + AttributeNode[64, 70] name:[64, 65, "."] value:[65, 70, "style"] isImplicit isClass + Text[71, 91] chars:[71, 91, " Anot … might"] + SoftLineBreak[91, 92] + TextBase[92, 99] chars:[92, 99, "follow."] + Text[92, 99] chars:[92, 99, "follow."] + AttributesNode[99, 108] textOpen:[99, 100, "{"] text:[100, 107, ".style2"] textClose:[107, 108, "}"] + AttributeNode[100, 107] name:[100, 101, "."] value:[101, 107, "style2"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Non-Attributes: 4) options(dont-wrap-non-attributes) +This is a test. It works fine until a word like don't appears.{.style} Another style might follow.{.style2} +. +

This is a test. It works fine until a word like don’t appears. Another style might follow.

+. +Document[0, 107] + Paragraph[0, 107] + Text[0, 51] chars:[0, 51, "This … e don"] + TypographicSmarts[51, 52] typographic: ’ + TextBase[52, 62] chars:[52, 62, "t appears."] + Text[52, 62] chars:[52, 62, "t appears."] + AttributesNode[62, 70] textOpen:[62, 63, "{"] text:[63, 69, ".style"] textClose:[69, 70, "}"] + AttributeNode[63, 69] name:[63, 64, "."] value:[64, 69, "style"] isImplicit isClass + TextBase[70, 98] chars:[70, 98, " Anot … llow."] + Text[70, 98] chars:[70, 98, " Anot … llow."] + AttributesNode[98, 107] textOpen:[98, 99, "{"] text:[99, 106, ".style2"] textClose:[106, 107, "}"] + AttributeNode[99, 106] name:[99, 100, "."] value:[100, 106, "style2"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Non-Attributes: 5) options(dont-wrap-non-attributes) +This is a test. It works fine until a word like 'don't' appears.{.style} Another style might follow.{.style2} +. +

This is a test. It works fine until a word like ‘don’t’ appears. Another style might follow.

+. +Document[0, 109] + Paragraph[0, 109] + Text[0, 48] chars:[0, 48, "This … like "] + TypographicQuotes[48, 55] typographicOpening: ‘ typographicClosing: ’ textOpen:[48, 49, "'"] text:[49, 54, "don't"] textClose:[54, 55, "'"] + Text[49, 52] chars:[49, 52, "don"] + TypographicSmarts[52, 53] typographic: ’ + Text[53, 54] chars:[53, 54, "t"] + TextBase[55, 64] chars:[55, 64, " appears."] + Text[55, 64] chars:[55, 64, " appears."] + AttributesNode[64, 72] textOpen:[64, 65, "{"] text:[65, 71, ".style"] textClose:[71, 72, "}"] + AttributeNode[65, 71] name:[65, 66, "."] value:[66, 71, "style"] isImplicit isClass + TextBase[72, 100] chars:[72, 100, " Anot … llow."] + Text[72, 100] chars:[72, 100, " Anot … llow."] + AttributesNode[100, 109] textOpen:[100, 101, "{"] text:[101, 108, ".style2"] textClose:[108, 109, "}"] + AttributeNode[101, 108] name:[101, 102, "."] value:[102, 108, "style2"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Non-Attributes: 6) options(dont-wrap-non-attributes) +This is a test. It works fine until a word like don\'t appears.{.style} Another style might +follow.{.style2} +. +

This is a test. It works fine until a word like don't appears. Another style might +follow.

+. +Document[0, 108] + Paragraph[0, 108] + TextBase[0, 63] chars:[0, 63, "This … ears."] + Text[0, 51] chars:[0, 51, "This … e don"] + EscapedCharacter[51, 53] textOpen:[51, 52, "\"] text:[52, 53, "'"] + Text[53, 63] chars:[53, 63, "t appears."] + AttributesNode[63, 71] textOpen:[63, 64, "{"] text:[64, 70, ".style"] textClose:[70, 71, "}"] + AttributeNode[64, 70] name:[64, 65, "."] value:[65, 70, "style"] isImplicit isClass + Text[71, 91] chars:[71, 91, " Anot … might"] + SoftLineBreak[91, 92] + TextBase[92, 99] chars:[92, 99, "follow."] + Text[92, 99] chars:[92, 99, "follow."] + AttributesNode[99, 108] textOpen:[99, 100, "{"] text:[100, 107, ".style2"] textClose:[107, 108, "}"] + AttributeNode[100, 107] name:[100, 101, "."] value:[101, 107, "style2"] isImplicit isClass +```````````````````````````````` + + +## Attribute Span + +```````````````````````````````` example Attribute Span: 1 +Cond 1.2 text node{.red} +. +

Cond 1.2 text node

+. +Document[0, 25] + Paragraph[0, 25] + TextBase[0, 18] chars:[0, 18, "Cond … node"] + Text[0, 18] chars:[0, 18, "Cond … node"] + AttributesNode[18, 24] textOpen:[18, 19, "{"] text:[19, 23, ".red"] textClose:[23, 24, "}"] + AttributeNode[19, 23] name:[19, 20, "."] value:[20, 23, "red"] isImplicit isClass +```````````````````````````````` + + +can use empty for braces + +```````````````````````````````` example Attribute Span: 2 +Cond 1.2 text {}node +. +

Cond 1.2 text {}node

+. +Document[0, 21] + Paragraph[0, 21] + Text[0, 20] chars:[0, 20, "Cond … }node"] +```````````````````````````````` + + +empty attributes are just text + +```````````````````````````````` example Attribute Span: 3 +Cond 1.2 text {}node{.red} +. +

Cond 1.2 text {}node

+. +Document[0, 27] + Paragraph[0, 27] + TextBase[0, 20] chars:[0, 20, "Cond … }node"] + Text[0, 20] chars:[0, 20, "Cond … }node"] + AttributesNode[20, 26] textOpen:[20, 21, "{"] text:[21, 25, ".red"] textClose:[25, 26, "}"] + AttributeNode[21, 25] name:[21, 22, "."] value:[22, 25, "red"] isImplicit isClass +```````````````````````````````` + + +empty attributes are just text + +```````````````````````````````` example Attribute Span: 4 +Cond 1.2 text { }node{.red} +. +

Cond 1.2 text { }node

+. +Document[0, 28] + Paragraph[0, 28] + TextBase[0, 21] chars:[0, 21, "Cond … }node"] + Text[0, 21] chars:[0, 21, "Cond … }node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +can use empty class is just text + +```````````````````````````````` example Attribute Span: 5 +Cond 1.2 text {.}node{.red} +. +

Cond 1.2 text {.}node

+. +Document[0, 28] + Paragraph[0, 28] + TextBase[0, 21] chars:[0, 21, "Cond … }node"] + Text[0, 21] chars:[0, 21, "Cond … }node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +spaces in empty id is just text + +```````````````````````````````` example Attribute Span: 6 +Cond 1.2 text { #}node{.red} +. +

Cond 1.2 text { #}node

+. +Document[0, 29] + Paragraph[0, 29] + TextBase[0, 22] chars:[0, 22, "Cond … }node"] + Text[0, 22] chars:[0, 22, "Cond … }node"] + AttributesNode[22, 28] textOpen:[22, 23, "{"] text:[23, 27, ".red"] textClose:[27, 28, "}"] + AttributeNode[23, 27] name:[23, 24, "."] value:[24, 27, "red"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example Attribute Span: 7 +Cond 1.2 text {# }node{.red} +. +

Cond 1.2 text {# }node

+. +Document[0, 29] + Paragraph[0, 29] + TextBase[0, 22] chars:[0, 22, "Cond … }node"] + Text[0, 22] chars:[0, 22, "Cond … }node"] + AttributesNode[22, 28] textOpen:[22, 23, "{"] text:[23, 27, ".red"] textClose:[27, 28, "}"] + AttributeNode[23, 27] name:[23, 24, "."] value:[24, 27, "red"] isImplicit isClass +```````````````````````````````` + + +spaces in empty class is just text + +```````````````````````````````` example(Attribute Span: 8) options(empty-implicit-delimiters) +Cond 1.2 text { .}node{.red} +. +

Cond 1.2 text { .}node

+. +Document[0, 28] + Paragraph[0, 28] + TextBase[0, 22] chars:[0, 22, "Cond … }node"] + Text[0, 22] chars:[0, 22, "Cond … }node"] + AttributesNode[22, 28] textOpen:[22, 23, "{"] text:[23, 27, ".red"] textClose:[27, 28, "}"] + AttributeNode[23, 27] name:[23, 24, "."] value:[24, 27, "red"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 9) options(empty-implicit-delimiters) +Cond 1.2 text {. }node{.red} +. +

Cond 1.2 text {. }node

+. +Document[0, 28] + Paragraph[0, 28] + TextBase[0, 22] chars:[0, 22, "Cond … }node"] + Text[0, 22] chars:[0, 22, "Cond … }node"] + AttributesNode[22, 28] textOpen:[22, 23, "{"] text:[23, 27, ".red"] textClose:[27, 28, "}"] + AttributeNode[23, 27] name:[23, 24, "."] value:[24, 27, "red"] isImplicit isClass +```````````````````````````````` + + +can use empty id is just text + +```````````````````````````````` example Attribute Span: 10 +Cond 1.2 text {#}node{.red} +. +

Cond 1.2 text {#}node

+. +Document[0, 28] + Paragraph[0, 28] + TextBase[0, 21] chars:[0, 21, "Cond … }node"] + Text[0, 21] chars:[0, 21, "Cond … }node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +can use empty class as delimiter + +```````````````````````````````` example(Attribute Span: 11) options(empty-implicit-delimiters) +Cond 1.2 text {.}node{.red} +. +

Cond 1.2 text node

+. +Document[0, 27] + Paragraph[0, 27] + Text[0, 14] chars:[0, 14, "Cond … text "] + AttributesDelimiter[14, 17] textOpen:[14, 15, "{"] text:[15, 16, "."] textClose:[16, 17, "}"] + TextBase[17, 21] chars:[17, 21, "node"] + Text[17, 21] chars:[17, 21, "node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 12) options(empty-implicit-delimiters) +Cond 1.2 {.}text node{.red} +. +

Cond 1.2 text node

+. +Document[0, 27] + Paragraph[0, 27] + Text[0, 9] chars:[0, 9, "Cond 1.2 "] + AttributesDelimiter[9, 12] textOpen:[9, 10, "{"] text:[10, 11, "."] textClose:[11, 12, "}"] + TextBase[12, 21] chars:[12, 21, "text node"] + Text[12, 21] chars:[12, 21, "text node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +can use empty id as delimiter + +```````````````````````````````` example(Attribute Span: 13) options(empty-implicit-delimiters) +Cond 1.2 {#}text node{.red} +. +

Cond 1.2 text node

+. +Document[0, 27] + Paragraph[0, 27] + Text[0, 9] chars:[0, 9, "Cond 1.2 "] + AttributesDelimiter[9, 12] textOpen:[9, 10, "{"] text:[10, 11, "#"] textClose:[11, 12, "}"] + TextBase[12, 21] chars:[12, 21, "text node"] + Text[12, 21] chars:[12, 21, "text node"] + AttributesNode[21, 27] textOpen:[21, 22, "{"] text:[22, 26, ".red"] textClose:[26, 27, "}"] + AttributeNode[22, 26] name:[22, 23, "."] value:[23, 26, "red"] isImplicit isClass +```````````````````````````````` + + +nesting is allowed + +```````````````````````````````` example(Attribute Span: 14) options(empty-implicit-delimiters) +Cond {.}1.2 {#}text node{.red}{.green} +. +

Cond 1.2 text node

+. +Document[0, 38] + Paragraph[0, 38] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 30] chars:[8, 30, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "#"] textClose:[14, 15, "}"] + TextBase[15, 24] chars:[15, 24, "text node"] + TextBase[15, 24] chars:[15, 24, "text node"] + Text[15, 24] chars:[15, 24, "text node"] + AttributesNode[24, 30] textOpen:[24, 25, "{"] text:[25, 29, ".red"] textClose:[29, 30, "}"] + AttributeNode[25, 29] name:[25, 26, "."] value:[26, 29, "red"] isImplicit isClass + AttributesNode[30, 38] textOpen:[30, 31, "{"] text:[31, 37, ".green"] textClose:[37, 38, "}"] + AttributeNode[31, 37] name:[31, 32, "."] value:[32, 37, "green"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 15) options(empty-implicit-delimiters) +Cond {#}1.2 {.}text node{.red}{.green} +. +

Cond 1.2 text node

+. +Document[0, 38] + Paragraph[0, 38] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "#"] textClose:[7, 8, "}"] + TextBase[8, 30] chars:[8, 30, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "."] textClose:[14, 15, "}"] + TextBase[15, 24] chars:[15, 24, "text node"] + TextBase[15, 24] chars:[15, 24, "text node"] + Text[15, 24] chars:[15, 24, "text node"] + AttributesNode[24, 30] textOpen:[24, 25, "{"] text:[25, 29, ".red"] textClose:[29, 30, "}"] + AttributeNode[25, 29] name:[25, 26, "."] value:[26, 29, "red"] isImplicit isClass + AttributesNode[30, 38] textOpen:[30, 31, "{"] text:[31, 37, ".green"] textClose:[37, 38, "}"] + AttributeNode[31, 37] name:[31, 32, "."] value:[32, 37, "green"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 16) options(empty-implicit-delimiters) +Cond {#}1.2 {#}text node{.red}{.green} +. +

Cond 1.2 text node

+. +Document[0, 38] + Paragraph[0, 38] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "#"] textClose:[7, 8, "}"] + TextBase[8, 30] chars:[8, 30, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "#"] textClose:[14, 15, "}"] + TextBase[15, 24] chars:[15, 24, "text node"] + TextBase[15, 24] chars:[15, 24, "text node"] + Text[15, 24] chars:[15, 24, "text node"] + AttributesNode[24, 30] textOpen:[24, 25, "{"] text:[25, 29, ".red"] textClose:[29, 30, "}"] + AttributeNode[25, 29] name:[25, 26, "."] value:[26, 29, "red"] isImplicit isClass + AttributesNode[30, 38] textOpen:[30, 31, "{"] text:[31, 37, ".green"] textClose:[37, 38, "}"] + AttributeNode[31, 37] name:[31, 32, "."] value:[32, 37, "green"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 17) options(empty-implicit-delimiters) +Cond {.}1.2 {.}text node{.red}{.green} +. +

Cond 1.2 text node

+. +Document[0, 38] + Paragraph[0, 38] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 30] chars:[8, 30, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "."] textClose:[14, 15, "}"] + TextBase[15, 24] chars:[15, 24, "text node"] + TextBase[15, 24] chars:[15, 24, "text node"] + Text[15, 24] chars:[15, 24, "text node"] + AttributesNode[24, 30] textOpen:[24, 25, "{"] text:[25, 29, ".red"] textClose:[29, 30, "}"] + AttributeNode[25, 29] name:[25, 26, "."] value:[26, 29, "red"] isImplicit isClass + AttributesNode[30, 38] textOpen:[30, 31, "{"] text:[31, 37, ".green"] textClose:[37, 38, "}"] + AttributeNode[31, 37] name:[31, 32, "."] value:[32, 37, "green"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 18) options(empty-implicit-delimiters) +Cond {.}1.2 {.}text node{.red}{.green} +. +

Cond 1.2 text node

+. +Document[0, 38] + Paragraph[0, 38] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 30] chars:[8, 30, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "."] textClose:[14, 15, "}"] + TextBase[15, 24] chars:[15, 24, "text node"] + TextBase[15, 24] chars:[15, 24, "text node"] + Text[15, 24] chars:[15, 24, "text node"] + AttributesNode[24, 30] textOpen:[24, 25, "{"] text:[25, 29, ".red"] textClose:[29, 30, "}"] + AttributeNode[25, 29] name:[25, 26, "."] value:[26, 29, "red"] isImplicit isClass + AttributesNode[30, 38] textOpen:[30, 31, "{"] text:[31, 37, ".green"] textClose:[37, 38, "}"] + AttributeNode[31, 37] name:[31, 32, "."] value:[32, 37, "green"] isImplicit isClass +```````````````````````````````` + + +delimiters override assignment to parent + +```````````````````````````````` example(Attribute Span: 19) options(empty-implicit-delimiters) +Cond {.}1.2 {.}decorated text {.red} {.green} +. +

Cond 1.2 decorated text

+. +Document[0, 45] + Paragraph[0, 45] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 36] chars:[8, 36, "1.2 { … .red}"] + Text[8, 12] chars:[8, 12, "1.2 "] + AttributesDelimiter[12, 15] textOpen:[12, 13, "{"] text:[13, 14, "."] textClose:[14, 15, "}"] + TextBase[15, 30] chars:[15, 30, "decor … text "] + TextBase[15, 30] chars:[15, 30, "decor … text "] + Text[15, 30] chars:[15, 30, "decor … text "] + AttributesNode[30, 36] textOpen:[30, 31, "{"] text:[31, 35, ".red"] textClose:[35, 36, "}"] + AttributeNode[31, 35] name:[31, 32, "."] value:[32, 35, "red"] isImplicit isClass + AttributesNode[37, 45] textOpen:[37, 38, "{"] text:[38, 44, ".green"] textClose:[44, 45, "}"] + AttributeNode[38, 44] name:[38, 39, "."] value:[39, 44, "green"] isImplicit isClass +```````````````````````````````` -```````````````````````````````` example Trailing Spaces: 1 + +unmatched goes to parent + +```````````````````````````````` example(Attribute Span: 20) options(empty-implicit-delimiters) +Cond 1.2 {.}decorated text {.red} {.green} +. +

Cond 1.2 decorated text

+. +Document[0, 42] + Paragraph[0, 42] + Text[0, 9] chars:[0, 9, "Cond 1.2 "] + AttributesDelimiter[9, 12] textOpen:[9, 10, "{"] text:[10, 11, "."] textClose:[11, 12, "}"] + TextBase[12, 27] chars:[12, 27, "decor … text "] + TextBase[12, 27] chars:[12, 27, "decor … text "] + Text[12, 27] chars:[12, 27, "decor … text "] + AttributesNode[27, 33] textOpen:[27, 28, "{"] text:[28, 32, ".red"] textClose:[32, 33, "}"] + AttributeNode[28, 32] name:[28, 29, "."] value:[29, 32, "red"] isImplicit isClass + AttributesNode[34, 42] textOpen:[34, 35, "{"] text:[35, 41, ".green"] textClose:[41, 42, "}"] + AttributeNode[35, 41] name:[35, 36, "."] value:[36, 41, "green"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 21) options(empty-implicit-delimiters) +Cond {.}blue {.}green {.}red{.red}{.green}{.blue}{.rgb} +. +

Cond blue green red

+. +Document[0, 55] + Paragraph[0, 55] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 42] chars:[8, 42, "blue … reen}"] + TextBase[8, 42] chars:[8, 42, "blue … reen}"] + TextBase[8, 42] chars:[8, 42, "blue … reen}"] + Text[8, 13] chars:[8, 13, "blue "] + AttributesDelimiter[13, 16] textOpen:[13, 14, "{"] text:[14, 15, "."] textClose:[15, 16, "}"] + TextBase[16, 34] chars:[16, 34, "green … .red}"] + TextBase[16, 34] chars:[16, 34, "green … .red}"] + Text[16, 22] chars:[16, 22, "green "] + AttributesDelimiter[22, 25] textOpen:[22, 23, "{"] text:[23, 24, "."] textClose:[24, 25, "}"] + TextBase[25, 28] chars:[25, 28, "red"] + TextBase[25, 28] chars:[25, 28, "red"] + Text[25, 28] chars:[25, 28, "red"] + AttributesNode[28, 34] textOpen:[28, 29, "{"] text:[29, 33, ".red"] textClose:[33, 34, "}"] + AttributeNode[29, 33] name:[29, 30, "."] value:[30, 33, "red"] isImplicit isClass + AttributesNode[34, 42] textOpen:[34, 35, "{"] text:[35, 41, ".green"] textClose:[41, 42, "}"] + AttributeNode[35, 41] name:[35, 36, "."] value:[36, 41, "green"] isImplicit isClass + AttributesNode[42, 49] textOpen:[42, 43, "{"] text:[43, 48, ".blue"] textClose:[48, 49, "}"] + AttributeNode[43, 48] name:[43, 44, "."] value:[44, 48, "blue"] isImplicit isClass + AttributesNode[49, 55] textOpen:[49, 50, "{"] text:[50, 54, ".rgb"] textClose:[54, 55, "}"] + AttributeNode[50, 54] name:[50, 51, "."] value:[51, 54, "rgb"] isImplicit isClass +```````````````````````````````` + + +```````````````````````````````` example(Attribute Span: 22) options(empty-implicit-delimiters) +Cond {.}blue {.}green {.}red{.red}{.green}{.blue} rgb{.rgb} +. +

Cond blue green red rgb

+. +Document[0, 59] + Paragraph[0, 59] + Text[0, 5] chars:[0, 5, "Cond "] + AttributesDelimiter[5, 8] textOpen:[5, 6, "{"] text:[6, 7, "."] textClose:[7, 8, "}"] + TextBase[8, 42] chars:[8, 42, "blue … reen}"] + TextBase[8, 42] chars:[8, 42, "blue … reen}"] + Text[8, 13] chars:[8, 13, "blue "] + AttributesDelimiter[13, 16] textOpen:[13, 14, "{"] text:[14, 15, "."] textClose:[15, 16, "}"] + TextBase[16, 34] chars:[16, 34, "green … .red}"] + TextBase[16, 34] chars:[16, 34, "green … .red}"] + Text[16, 22] chars:[16, 22, "green "] + AttributesDelimiter[22, 25] textOpen:[22, 23, "{"] text:[23, 24, "."] textClose:[24, 25, "}"] + TextBase[25, 28] chars:[25, 28, "red"] + TextBase[25, 28] chars:[25, 28, "red"] + Text[25, 28] chars:[25, 28, "red"] + AttributesNode[28, 34] textOpen:[28, 29, "{"] text:[29, 33, ".red"] textClose:[33, 34, "}"] + AttributeNode[29, 33] name:[29, 30, "."] value:[30, 33, "red"] isImplicit isClass + AttributesNode[34, 42] textOpen:[34, 35, "{"] text:[35, 41, ".green"] textClose:[41, 42, "}"] + AttributeNode[35, 41] name:[35, 36, "."] value:[36, 41, "green"] isImplicit isClass + AttributesNode[42, 49] textOpen:[42, 43, "{"] text:[43, 48, ".blue"] textClose:[48, 49, "}"] + AttributeNode[43, 48] name:[43, 44, "."] value:[44, 48, "blue"] isImplicit isClass + TextBase[49, 53] chars:[49, 53, " rgb"] + Text[49, 53] chars:[49, 53, " rgb"] + AttributesNode[53, 59] textOpen:[53, 54, "{"] text:[54, 58, ".rgb"] textClose:[58, 59, "}"] + AttributeNode[54, 58] name:[54, 55, "."] value:[55, 58, "rgb"] isImplicit isClass +```````````````````````````````` + + +## Embedded Spaces + +leading spaces + +```````````````````````````````` example Embedded Spaces: 1 +text { attribute=value} +. +

text

+. +Document[0, 26] + Paragraph[0, 26] + Text[0, 4] chars:[0, 4, "text"] + AttributesNode[5, 25] textOpen:[5, 6, "{"] text:[6, 24, " attribute=value"] textClose:[24, 25, "}"] + AttributeNode[9, 24] name:[9, 18, "attribute"] sep:[18, 19, "="] value:[19, 24, "value"] +```````````````````````````````` + + +trailing spaces + +```````````````````````````````` example Embedded Spaces: 2 text {attribute=value } .

text

@@ -1784,11 +2378,95 @@ text {attribute=value } Document[0, 26] Paragraph[0, 26] Text[0, 4] chars:[0, 4, "text"] - AttributesNode[5, 25] textOpen:[5, 6, "{"] text:[6, 21, "attribute=value"] textClose:[24, 25, "}"] + AttributesNode[5, 25] textOpen:[5, 6, "{"] text:[6, 24, "attribute=value "] textClose:[24, 25, "}"] AttributeNode[6, 21] name:[6, 15, "attribute"] sep:[15, 16, "="] value:[16, 21, "value"] ```````````````````````````````` +Attributes go to link or element + +```````````````````````````````` example Embedded Spaces: 3 +Work with +[Markdown]{style="color:[[LINK]]"} files like you do with other languages in the IDE: + +[Markdown]: https://example.com +. +

Work with +Markdown files like you do with other languages in the IDE:

+. +Document[0, 129] + Paragraph[0, 96] isTrailingBlankLine + Text[0, 9] chars:[0, 9, "Work with"] + SoftLineBreak[9, 10] + LinkRef[10, 20] referenceOpen:[10, 11, "["] reference:[11, 19, "Markdown"] referenceClose:[19, 20, "]"] + Text[11, 19] chars:[11, 19, "Markdown"] + AttributesNode[20, 44] textOpen:[20, 21, "{"] text:[21, 43, "style=\"color:[[LINK]]\""] textClose:[43, 44, "}"] + AttributeNode[21, 43] name:[21, 26, "style"] sep:[26, 27, "="] valueOpen:[27, 28, "\""] value:[28, 42, "color:[[LINK]]"] valueClose:[42, 43, "\""] + Text[44, 95] chars:[44, 95, " file … IDE:"] + Reference[97, 128] refOpen:[97, 98, "["] ref:[98, 106, "Markdown"] refClose:[106, 108, "]:"] url:[109, 128, "https://example.com"] +```````````````````````````````` + + +```````````````````````````````` example Embedded Spaces: 4 +Work with +![Markdown]{style="color:[[LINK]]"} files like you do with other languages in the IDE: + +[Markdown]: https://example.com/image.png +. +

Work with +Markdown files like you do with other languages in the IDE:

+. +Document[0, 140] + Paragraph[0, 97] isTrailingBlankLine + Text[0, 9] chars:[0, 9, "Work with"] + SoftLineBreak[9, 10] + ImageRef[10, 21] referenceOpen:[10, 12, "!["] reference:[12, 20, "Markdown"] referenceClose:[20, 21, "]"] + Text[12, 20] chars:[12, 20, "Markdown"] + AttributesNode[21, 45] textOpen:[21, 22, "{"] text:[22, 44, "style=\"color:[[LINK]]\""] textClose:[44, 45, "}"] + AttributeNode[22, 44] name:[22, 27, "style"] sep:[27, 28, "="] valueOpen:[28, 29, "\""] value:[29, 43, "color:[[LINK]]"] valueClose:[43, 44, "\""] + Text[45, 96] chars:[45, 96, " file … IDE:"] + Reference[98, 139] refOpen:[98, 99, "["] ref:[99, 107, "Markdown"] refClose:[107, 109, "]:"] url:[110, 139, "https://example.com/image.png"] +```````````````````````````````` + + +```````````````````````````````` example Embedded Spaces: 5 +Work with +[Markdown](https://example.com){style="color:[[LINK]]"} files like you do with other languages in the IDE: +. +

Work with +Markdown files like you do with other languages in the IDE:

+. +Document[0, 117] + Paragraph[0, 117] + Text[0, 9] chars:[0, 9, "Work with"] + SoftLineBreak[9, 10] + Link[10, 41] textOpen:[10, 11, "["] text:[11, 19, "Markdown"] textClose:[19, 20, "]"] linkOpen:[20, 21, "("] url:[21, 40, "https://example.com"] pageRef:[21, 40, "https://example.com"] linkClose:[40, 41, ")"] + Text[11, 19] chars:[11, 19, "Markdown"] + AttributesNode[41, 65] textOpen:[41, 42, "{"] text:[42, 64, "style=\"color:[[LINK]]\""] textClose:[64, 65, "}"] + AttributeNode[42, 64] name:[42, 47, "style"] sep:[47, 48, "="] valueOpen:[48, 49, "\""] value:[49, 63, "color:[[LINK]]"] valueClose:[63, 64, "\""] + Text[65, 116] chars:[65, 116, " file … IDE:"] +```````````````````````````````` + + +```````````````````````````````` example Embedded Spaces: 6 +Work with +![Markdown](https://example.com/image.png){style="color:[[LINK]]"} files like you do with other languages in the IDE: +. +

Work with +Markdown files like you do with other languages in the IDE:

+. +Document[0, 128] + Paragraph[0, 128] + Text[0, 9] chars:[0, 9, "Work with"] + SoftLineBreak[9, 10] + Image[10, 52] textOpen:[10, 12, "!["] text:[12, 20, "Markdown"] textClose:[20, 21, "]"] linkOpen:[21, 22, "("] url:[22, 51, "https://example.com/image.png"] pageRef:[22, 51, "https://example.com/image.png"] linkClose:[51, 52, ")"] + Text[12, 20] chars:[12, 20, "Markdown"] + AttributesNode[52, 76] textOpen:[52, 53, "{"] text:[53, 75, "style=\"color:[[LINK]]\""] textClose:[75, 76, "}"] + AttributeNode[53, 75] name:[53, 58, "style"] sep:[58, 59, "="] valueOpen:[59, 60, "\""] value:[60, 74, "color:[[LINK]]"] valueClose:[74, 75, "\""] + Text[76, 127] chars:[76, 127, " file … IDE:"] +```````````````````````````````` + + ## Translator Encoding ```````````````````````````````` example Translator Encoding: 1 @@ -1836,3 +2514,5 @@ Document[0, 28] ```````````````````````````````` +[Markdown]: https://daringfireball.net/projects/markdown + diff --git a/flexmark-ext-autolink/pom.xml b/flexmark-ext-autolink/pom.xml index 575cdc97e..07e9b4e0b 100644 --- a/flexmark-ext-autolink/pom.xml +++ b/flexmark-ext-autolink/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-autolink diff --git a/flexmark-ext-definition/pom.xml b/flexmark-ext-definition/pom.xml index 07b473de4..6385963fa 100644 --- a/flexmark-ext-definition/pom.xml +++ b/flexmark-ext-definition/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-definition diff --git a/flexmark-ext-emoji/pom.xml b/flexmark-ext-emoji/pom.xml index 71baad924..7512b406b 100644 --- a/flexmark-ext-emoji/pom.xml +++ b/flexmark-ext-emoji/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-emoji diff --git a/flexmark-ext-enumerated-reference/pom.xml b/flexmark-ext-enumerated-reference/pom.xml index c81eb7db6..f150dc14e 100644 --- a/flexmark-ext-enumerated-reference/pom.xml +++ b/flexmark-ext-enumerated-reference/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-enumerated-reference diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedOrdinalRenderer.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedOrdinalRenderer.java new file mode 100644 index 000000000..995b8e35b --- /dev/null +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedOrdinalRenderer.java @@ -0,0 +1,25 @@ +package com.vladsch.flexmark.ext.enumerated.reference; + +public interface EnumeratedOrdinalRenderer { + /** + * Start of rendering for all renderings + * + * @param renderings renderings which will be rendered + */ + void startRendering(EnumeratedReferenceRendering[] renderings); + + /** + * Render final reference format + * + * @param referenceOrdinal ordinal for the reference + * @param referenceFormat reference format or null + * @param defaultText default text to use if referenceFormat is null or not being used + * @param needSeparator true if need to add separator character before adding text or rendering reference format + */ + void render(final int referenceOrdinal, EnumeratedReferenceBlock referenceFormat, final String defaultText, final boolean needSeparator); + + /** + * After Rendering is complete + */ + void endRendering(); +} diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBase.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBase.java index f5c110e32..961d1aeb8 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBase.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBase.java @@ -7,7 +7,7 @@ /** * A EnumeratedReference node */ -public class EnumeratedReferenceBase extends CustomNode implements DelimitedNode, DoNotDecorate, ReferencingNode { +public class EnumeratedReferenceBase extends Node implements DelimitedNode, DoNotDecorate, ReferencingNode { protected BasedSequence openingMarker = BasedSequence.NULL; protected BasedSequence text = BasedSequence.NULL; protected BasedSequence closingMarker = BasedSequence.NULL; diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBlock.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBlock.java index 7bfffe71c..d728fe930 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBlock.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceBlock.java @@ -9,7 +9,7 @@ /** * A EnumeratedReference block node */ -public class EnumeratedReferenceBlock extends CustomBlock implements ReferenceNode, ParagraphItemContainer { +public class EnumeratedReferenceBlock extends Block implements ReferenceNode, ParagraphItemContainer { protected BasedSequence openingMarker = BasedSequence.NULL; protected BasedSequence text = BasedSequence.NULL; protected BasedSequence closingMarker = BasedSequence.NULL; diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceRendering.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceRendering.java new file mode 100644 index 000000000..67e7bbda6 --- /dev/null +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/EnumeratedReferenceRendering.java @@ -0,0 +1,13 @@ +package com.vladsch.flexmark.ext.enumerated.reference; + +public class EnumeratedReferenceRendering { + public final EnumeratedReferenceBlock referenceFormat; + public final String referenceType; + public final int referenceOrdinal; + + public EnumeratedReferenceRendering(final EnumeratedReferenceBlock referenceFormat, final String referenceType, final int referenceOrdinal) { + this.referenceFormat = referenceFormat; + this.referenceType = referenceType; + this.referenceOrdinal = referenceOrdinal; + } +} diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumRefTextCollectingVisitor.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumRefTextCollectingVisitor.java index 6f498cf95..a77705259 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumRefTextCollectingVisitor.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumRefTextCollectingVisitor.java @@ -1,8 +1,7 @@ package com.vladsch.flexmark.ext.enumerated.reference.internal; import com.vladsch.flexmark.ast.*; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceLink; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceText; +import com.vladsch.flexmark.ext.enumerated.reference.*; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.SegmentedSequenceBuilder; @@ -10,9 +9,15 @@ public class EnumRefTextCollectingVisitor { private SegmentedSequenceBuilder out; private final NodeVisitor myVisitor; - private final int ordinal; + private int myOrdinal; + + public EnumRefTextCollectingVisitor() { + this(0); + } public EnumRefTextCollectingVisitor(int ordinal) { + myOrdinal = ordinal; + myVisitor = new NodeVisitor( new VisitHandler(Text.class, new Visitor() { @Override @@ -57,39 +62,102 @@ public void visit(EnumeratedReferenceLink node) { } }) ); - this.ordinal = ordinal; } public String getText() { return out.toString(); } + /** + * @param node format node + * @deprecated use {@link #collect(BasedSequence, EnumeratedReferenceRendering[], String)} + */ + @Deprecated public void collect(Node node) { out = new SegmentedSequenceBuilder(node.getChars()); myVisitor.visit(node); } + /** + * @param node format node + * @deprecated use {@link #collectAndGetText(BasedSequence, EnumeratedReferenceRendering[], String)} + */ + @Deprecated public String collectAndGetText(Node node) { collect(node); return out.toString(); } + /** + * @param node format node + * @deprecated use {@link #collectAndGetSegments(BasedSequence, EnumeratedReferenceRendering[], String)} + */ + @Deprecated public BasedSequence[] collectAndGetSegments(Node node) { collect(node); return out.toSegments(); } + /** + * @param node format node + * @deprecated use {@link #collectAndGetSequence(BasedSequence, EnumeratedReferenceRendering[], String)} + */ + @Deprecated public BasedSequence collectAndGetSequence(Node node) { collect(node); return out.toBasedSequence(); } + public void collect(BasedSequence basedSequence, final EnumeratedReferenceRendering[] renderings, final String defaultFormat) { + out = new SegmentedSequenceBuilder(basedSequence); + + EnumeratedReferences.renderReferenceOrdinals(renderings, defaultFormat, new EnumeratedOrdinalRenderer() { + @Override + public void startRendering(final EnumeratedReferenceRendering[] renderings) { + + } + + @Override + public void render(final int referenceOrdinal, final EnumeratedReferenceBlock referenceFormat, final String defaultText, final boolean needSeparator) { + if (needSeparator) out.append("."); + + if (referenceFormat != null) { + myOrdinal = referenceOrdinal; + collect(referenceFormat); + } else { + // use default text + out.append(defaultText); + } + } + + @Override + public void endRendering() { + + } + }); + } + + public String collectAndGetText(BasedSequence basedSequence, EnumeratedReferenceRendering[] renderings, final String defaultFormat) { + collect(basedSequence, renderings, defaultFormat); + return out.toString(); + } + + public BasedSequence[] collectAndGetSegments(BasedSequence basedSequence, EnumeratedReferenceRendering[] renderings, final String defaultFormat) { + collect(basedSequence, renderings, defaultFormat); + return out.toSegments(); + } + + public BasedSequence collectAndGetSequence(BasedSequence basedSequence, EnumeratedReferenceRendering[] renderings, final String defaultFormat) { + collect(basedSequence, renderings, defaultFormat); + return out.toBasedSequence(); + } + private void visit(EnumeratedReferenceText node) { final String text = node.getText().toString(); if (text.isEmpty()) { // placeholder for ordinal - out.append(String.valueOf(ordinal)); + out.append(String.valueOf(myOrdinal)); } } @@ -98,7 +166,7 @@ private void visit(EnumeratedReferenceLink node) { if (text.isEmpty()) { // placeholder for ordinal - out.append(String.valueOf(ordinal)); + out.append(String.valueOf(myOrdinal)); } } @@ -108,7 +176,7 @@ private void visit(SoftLineBreak node) { private void visit(HardLineBreak node) { final BasedSequence chars = node.getChars(); - out.append(chars.subSequence(chars.length()-1, chars.length())); + out.append(chars.subSequence(chars.length() - 1, chars.length())); } private void visit(HtmlEntity node) { diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceBlockParser.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceBlockParser.java index 7a53378ec..26f81007a 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceBlockParser.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceBlockParser.java @@ -13,7 +13,7 @@ import java.util.regex.Pattern; public class EnumeratedReferenceBlockParser extends AbstractBlockParser { - static String ENUM_REF_ID = ".*"; + static String ENUM_REF_ID = "(?:[^0-9].*)?"; static Pattern ENUM_REF_ID_PATTERN = Pattern.compile("\\[[\\@|#]\\s*(" + ENUM_REF_ID + ")\\s*\\]"); static Pattern ENUM_REF_DEF_PATTERN = Pattern.compile("^\\[[\\@]\\s*(" + ENUM_REF_ID + ")\\s*\\]:"); diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceLinkRefProcessor.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceLinkRefProcessor.java index 1f9813e89..6077f7607 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceLinkRefProcessor.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceLinkRefProcessor.java @@ -30,7 +30,7 @@ public int getBracketNestingLevel() { @Override public boolean isMatch(BasedSequence nodeChars) { - return nodeChars.length() >= 3 && nodeChars.charAt(0) == '[' && (nodeChars.charAt(1) == '@' || nodeChars.charAt(1) == '#') && nodeChars.endCharAt(1) == ']'; + return nodeChars.length() >= 3 && nodeChars.charAt(0) == '[' && (nodeChars.charAt(1) == '@' || nodeChars.charAt(1) == '#') && nodeChars.endCharAt(1) == ']' && (nodeChars.length() == 3 || !Character.isDigit(nodeChars.charAt(2))); } @Override diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodePostProcessor.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodePostProcessor.java index c8f6f1ddc..ab6880821 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodePostProcessor.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodePostProcessor.java @@ -1,19 +1,27 @@ package com.vladsch.flexmark.ext.enumerated.reference.internal; import com.vladsch.flexmark.ast.Document; +import com.vladsch.flexmark.ast.Heading; import com.vladsch.flexmark.ast.Node; import com.vladsch.flexmark.ext.attributes.AttributeNode; import com.vladsch.flexmark.ext.attributes.AttributesNode; import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceExtension; +import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceText; +import com.vladsch.flexmark.html.renderer.HeaderIdGenerator; +import com.vladsch.flexmark.html.renderer.HtmlIdGenerator; import com.vladsch.flexmark.parser.block.NodePostProcessor; import com.vladsch.flexmark.parser.block.NodePostProcessorFactory; import com.vladsch.flexmark.util.NodeTracker; +import com.vladsch.flexmark.util.sequence.BasedSequence; public class EnumeratedReferenceNodePostProcessor extends NodePostProcessor { private final EnumeratedReferences enumeratedReferences; + private final HtmlIdGenerator headerIdGenerator; public EnumeratedReferenceNodePostProcessor(Document document) { enumeratedReferences = EnumeratedReferenceExtension.ENUMERATED_REFERENCE_ORDINALS.getFrom(document); + headerIdGenerator = new HeaderIdGenerator.Factory().create(); + headerIdGenerator.generateIds(document); } @Override @@ -26,6 +34,19 @@ public void process(NodeTracker state, Node node) { if (((AttributeNode) attributeNode).isId()) { final String text = ((AttributeNode) attributeNode).getValue().toString(); enumeratedReferences.add(text); + break; + } + } + } + } else if (node instanceof Heading) { + // see if it has bare enum reference text + for (Node child : node.getChildren()) { + if (child instanceof EnumeratedReferenceText) { + BasedSequence text = ((EnumeratedReferenceText) child).getText(); + String type = EnumeratedReferenceRepository.getType(text.toString()); + if (type.isEmpty() || text.equals(type + ":")) { + String id = (type.isEmpty() ? text : type) + ":" + headerIdGenerator.getId(node); + enumeratedReferences.add(id); } } } @@ -35,7 +56,7 @@ public void process(NodeTracker state, Node node) { public static class Factory extends NodePostProcessorFactory { public Factory() { super(false); - addNodes(AttributesNode.class); + addNodes(AttributesNode.class, Heading.class); } @Override diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodeRenderer.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodeRenderer.java index c8091bc47..e2824b49d 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodeRenderer.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceNodeRenderer.java @@ -1,11 +1,9 @@ package com.vladsch.flexmark.ext.enumerated.reference.internal; import com.vladsch.flexmark.ast.Document; +import com.vladsch.flexmark.ast.Heading; import com.vladsch.flexmark.ast.Node; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceBlock; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceExtension; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceLink; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceText; +import com.vladsch.flexmark.ext.enumerated.reference.*; import com.vladsch.flexmark.html.CustomNodeRenderer; import com.vladsch.flexmark.html.HtmlWriter; import com.vladsch.flexmark.html.renderer.*; @@ -15,30 +13,33 @@ import java.util.LinkedHashSet; import java.util.Set; -import static com.vladsch.flexmark.html.renderer.RenderingPhase.BODY_TOP; - public class EnumeratedReferenceNodeRenderer implements PhasedNodeRenderer // , PhasedNodeRenderer { private final EnumeratedReferenceOptions options; private EnumeratedReferences enumeratedOrdinals; private int ordinal; + private final HtmlIdGenerator headerIdGenerator; // used for enumerated text reference public EnumeratedReferenceNodeRenderer(DataHolder options) { this.options = new EnumeratedReferenceOptions(options); ordinal = 0; + headerIdGenerator = new HeaderIdGenerator.Factory().create(); } @Override public Set getRenderingPhases() { LinkedHashSet phaseSet = new LinkedHashSet<>(); - phaseSet.add(BODY_TOP); + phaseSet.add(RenderingPhase.HEAD_TOP); + phaseSet.add(RenderingPhase.BODY_TOP); return phaseSet; } @Override public void renderDocument(final NodeRendererContext context, final HtmlWriter html, final Document document, final RenderingPhase phase) { - if (phase == BODY_TOP) { + if (phase == RenderingPhase.HEAD_TOP) { + headerIdGenerator.generateIds(document); + } else if (phase == RenderingPhase.BODY_TOP) { enumeratedOrdinals = EnumeratedReferenceExtension.ENUMERATED_REFERENCE_ORDINALS.getFrom(document); } } @@ -54,52 +55,82 @@ public Set> getNodeRenderingHandlers() { return set; } - private void render(EnumeratedReferenceLink node, NodeRendererContext context, HtmlWriter html) { + private void render(final EnumeratedReferenceLink node, final NodeRendererContext context, final HtmlWriter html) { final String text = node.getText().toString(); if (text.isEmpty()) { // placeholder for ordinal html.text(String.valueOf(ordinal)); } else { - Node referenceFormat = enumeratedOrdinals.getFormatNode(text); - int wasOrdinal = ordinal; - ordinal = enumeratedOrdinals.getOrdinal(text); - if (referenceFormat != null) { - String title = new EnumRefTextCollectingVisitor(ordinal).collectAndGetText(referenceFormat); - html.withAttr().attr("href", "#" + text).attr("title", title).tag("a"); - context.renderChildren(referenceFormat); - html.tag("/a"); - } else { - // no format, just output type space ordinal - final String defaultText = String.format("%s %d", EnumeratedReferenceRepository.getType(text), ordinal); - html.withAttr().attr("href", "#" + text).attr("title", defaultText).tag("a"); - html.text(defaultText); - html.tag("/a"); - } - ordinal = wasOrdinal; + enumeratedOrdinals.renderReferenceOrdinals(text, null, new EnumeratedOrdinalRenderer() { + @Override + public void startRendering(final EnumeratedReferenceRendering[] renderings) { + String title = new EnumRefTextCollectingVisitor().collectAndGetText(node.getChars().getBaseSequence(), renderings, null); + html.withAttr().attr("href", "#" + text).attr("title", title).tag("a"); + } + + @Override + public void render(final int referenceOrdinal, final EnumeratedReferenceBlock referenceFormat, final String defaultText, final boolean needSeparator) { + EnumeratedReferenceNodeRenderer.this.ordinal = referenceOrdinal; + if (needSeparator) { + html.text("."); + } + + if (referenceFormat != null) { + context.renderChildren(referenceFormat); + } else { + html.text(defaultText); + } + } + + @Override + public void endRendering() { + html.tag("/a"); + } + }); } } - private void render(EnumeratedReferenceText node, NodeRendererContext context, HtmlWriter html) { - final String text = node.getText().toString(); + private void render(EnumeratedReferenceText node, final NodeRendererContext context, final HtmlWriter html) { + String text = node.getText().toString(); if (text.isEmpty()) { // placeholder for ordinal html.text(String.valueOf(ordinal)); } else { - Node referenceFormat = enumeratedOrdinals.getFormatNode(text); - int wasOrdinal = ordinal; - ordinal = enumeratedOrdinals.getOrdinal(text); - - final String defaultText = String.format("%s %d", EnumeratedReferenceRepository.getType(text), ordinal); - - if (referenceFormat != null) { - context.renderChildren(referenceFormat); - } else { - // no format, just output ordinal - html.text(defaultText); + String type = EnumeratedReferenceRepository.getType(text.toString()); + + if (type.isEmpty() || text.equals(type + ":")) { + Node parent = node.getAncestorOfType(Heading.class); + + if (parent instanceof Heading) { + text = (type.isEmpty() ? text : type) + ":" + headerIdGenerator.getId(parent); + } } - ordinal = wasOrdinal; + + enumeratedOrdinals.renderReferenceOrdinals(text, null, new EnumeratedOrdinalRenderer() { + @Override + public void startRendering(final EnumeratedReferenceRendering[] renderings) { + + } + + @Override + public void render(final int referenceOrdinal, final EnumeratedReferenceBlock referenceFormat, final String defaultText, final boolean needSeparator) { + if (needSeparator) html.text("."); + + if (referenceFormat != null) { + EnumeratedReferenceNodeRenderer.this.ordinal = referenceOrdinal; + context.renderChildren(referenceFormat); + } else { + html.text(defaultText); + } + } + + @Override + public void endRendering() { + + } + }); } } diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceRepository.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceRepository.java index e781cce84..3130915fe 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceRepository.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferenceRepository.java @@ -18,7 +18,7 @@ public class EnumeratedReferenceRepository extends NodeRepository referencedEnumeratedReferenceBlocks = new ArrayList(); public static String getType(final String text) { - int pos = text.indexOf(':'); + int pos = text.lastIndexOf(':'); if (pos > 0) { return text.subSequence(0, pos).toString(); } else { diff --git a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferences.java b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferences.java index 18535a5e3..9992a3067 100644 --- a/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferences.java +++ b/flexmark-ext-enumerated-reference/src/main/java/com/vladsch/flexmark/ext/enumerated/reference/internal/EnumeratedReferences.java @@ -1,16 +1,18 @@ package com.vladsch.flexmark.ext.enumerated.reference.internal; import com.vladsch.flexmark.ast.Node; -import com.vladsch.flexmark.ext.enumerated.reference.EnumeratedReferenceExtension; +import com.vladsch.flexmark.ext.enumerated.reference.*; import com.vladsch.flexmark.util.options.DataHolder; import java.util.HashMap; public class EnumeratedReferences { public static final String EMPTY_TYPE = ""; + public static final int[] EMPTY_ORDINALS = new int[0]; + private final EnumeratedReferenceRepository referenceRepository; private final HashMap enumerationCounters; - private final HashMap enumeratedReferenceOrdinals; + private final HashMap enumeratedReferenceOrdinals; public EnumeratedReferences(DataHolder options) { referenceRepository = EnumeratedReferenceExtension.ENUMERATED_REFERENCES.getFrom(options); @@ -20,22 +22,56 @@ public EnumeratedReferences(DataHolder options) { public void add(final String text) { String type = EnumeratedReferenceRepository.getType(text); - int ordinal; - if (!enumerationCounters.containsKey(type)) { - enumerationCounters.put(type, 2); - ordinal = 1; - } else { - ordinal = enumerationCounters.get(type); - enumerationCounters.put(type, ordinal + 1); + + String[] types = type.split(":"); + int[] ordinals = new int[types.length]; + + // replace all types but the last with ordinal of that type + StringBuilder nestedType = new StringBuilder(); + + int iMax = types.length; + for (int i = 0; i < iMax; i++) { + String typeText = types[i]; + nestedType.append(typeText); + + String nestedTypeKey = nestedType.toString(); + + if (i < iMax - 1) { + Integer ordinalInt = enumerationCounters.get(nestedTypeKey); + int typeOrdinal = ordinalInt == null ? 0 : ordinalInt; + + nestedType.append(':').append(typeOrdinal).append(':'); + ordinals[i] = typeOrdinal; + } else { + // last type gets defined if it does not exist + int ordinal; + + if (!enumerationCounters.containsKey(nestedTypeKey)) { + enumerationCounters.put(nestedTypeKey, 1); + ordinal = 1; + } else { + ordinal = enumerationCounters.get(nestedTypeKey) + 1; + enumerationCounters.put(nestedTypeKey, ordinal); + } + + ordinals[i] = ordinal; + } } // save the ordinal for this reference and type - enumeratedReferenceOrdinals.put(text, ordinal); + enumeratedReferenceOrdinals.put(text, ordinals); } + /** + * @param text anchor id with type reference + * @return ordinal or 0 for anchor id + * @deprecated only returns the last ordinal for the text, does not support compound ordinal numbering + * use {@link #getEnumeratedReferenceOrdinals(String)} to get compound ordinals + */ + @Deprecated public int getOrdinal(final String text) { - final Integer ordinal = enumeratedReferenceOrdinals.get(text); - return ordinal == null ? 0 : ordinal; + final int[] ordinals = enumeratedReferenceOrdinals.get(text); + return ordinals == null ? 0 : ordinals[ordinals.length - 1]; } /** @@ -43,9 +79,69 @@ public int getOrdinal(final String text) { * * @param text reference text * @return enumerated reference block or null if not defined + * @deprecated use {@link #getEnumeratedReferenceOrdinals(String)} instead which supports compound enumerated ordinals */ + @Deprecated public Node getFormatNode(final String text) { String type = EnumeratedReferenceRepository.getType(text); return referenceRepository.get(type); } + + public EnumeratedReferenceRendering[] getEnumeratedReferenceOrdinals(final String text) { + String type = EnumeratedReferenceRepository.getType(text); + + String[] types = type.split(":"); + EnumeratedReferenceRendering[] renderings = new EnumeratedReferenceRendering[types.length]; + + int[] ordinals = enumeratedReferenceOrdinals.get(text); + + if (ordinals == null) { + ordinals = EMPTY_ORDINALS; + } + + int iMax = types.length; + for (int i = 0; i < iMax; i++) { + String typeText = types[i]; + EnumeratedReferenceBlock referenceFormat = referenceRepository.get(typeText); + int ordinal = i < ordinals.length ? ordinals[i] : 0; + renderings[i] = new EnumeratedReferenceRendering(referenceFormat, typeText, ordinal); + } + + return renderings; + } + + public void renderReferenceOrdinals(final String text, final String defaultFormat, EnumeratedOrdinalRenderer renderer) { + EnumeratedReferenceRendering[] renderings = getEnumeratedReferenceOrdinals(text); + renderReferenceOrdinals(renderings, defaultFormat, renderer); + } + + public static void renderReferenceOrdinals(EnumeratedReferenceRendering[] renderings, final String defaultFormat, EnumeratedOrdinalRenderer renderer) { + boolean needSeparator = false; + + String useDefaultFormat = defaultFormat == null ? "%s %d" : defaultFormat; + + renderer.startRendering(renderings); + + for (EnumeratedReferenceRendering rendering : renderings) { + int ordinal = rendering.referenceOrdinal; + + String defaultText = String.format(useDefaultFormat, rendering.referenceType, rendering.referenceOrdinal); + + renderer.render(ordinal, rendering.referenceFormat, defaultText, needSeparator); + + if (rendering.referenceFormat != null) { + Node lastChild = rendering.referenceFormat.getLastChild(); + while (lastChild != null && !(lastChild instanceof EnumeratedReferenceBase)) { + lastChild = lastChild.getLastChild(); + } + + needSeparator = lastChild instanceof EnumeratedReferenceBase && ((EnumeratedReferenceBase) lastChild).getText().isEmpty(); + } else { + char c = defaultText.charAt(defaultText.length() - 1); + needSeparator = Character.isUnicodeIdentifierPart(c); + } + } + + renderer.endRendering(); + } } diff --git a/flexmark-ext-enumerated-reference/src/main/javadoc/information_source.png b/flexmark-ext-enumerated-reference/src/main/javadoc/information_source.png new file mode 100644 index 000000000..e1e8ede6e Binary files /dev/null and b/flexmark-ext-enumerated-reference/src/main/javadoc/information_source.png differ diff --git a/flexmark-ext-enumerated-reference/src/main/javadoc/overview.html b/flexmark-ext-enumerated-reference/src/main/javadoc/overview.html index 70898e6e2..c45d9712a 100644 --- a/flexmark-ext-enumerated-reference/src/main/javadoc/overview.html +++ b/flexmark-ext-enumerated-reference/src/main/javadoc/overview.html @@ -9,6 +9,7 @@ the category and reference is used to uniquely identify an element in the category. The anchor id of the element will be type:reference and this must be used by the enumerated reference label or link.

+

emoji symbols:information_source type must not start with a digit.

To refer to the element in the document use the enumerated reference elements:

  1. @@ -34,10 +35,10 @@

For example:

-
![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test}   
+
![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test}
 [#fig:test]
 
-![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2}   
+![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2}
 [#fig:test2]
 
 | heading | heading | heading |
@@ -58,10 +59,10 @@
 

is equivalent to the following without having to manually keep track of numbering of individual elements:

-
![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test}  
+
![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test}
 Figure 1.
 
-![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2}  
+![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2}
 Figure 2.
 
 | table |
@@ -96,5 +97,71 @@
 <p>See <a href="#fig:test"><span>Figure 1.</span></a></p>
 <p>See <a href="#tbl:test"><span>Table 1.</span></a></p>
 
+

Enumerated Reference Text in Headings

+

Because headings contain their own anchor id an enumerated reference with only a type is +allowed in headings and has the effect of adding an incremented counter to heading text.

+
# [#hd1] Heading 1
+
+# [#hd1] Heading 2
+
+# [#hd1] Heading 3
+
+[@hd1]: [#].
+
+

Will render as:

+
<h1>1. Heading 1</h1>
+<h1>2. Heading 2</h1>
+<h1>3. Heading 3</h1>
+
+

Compound Types

+

Compound enumerated reference types are created by including more than one type reference with +: separating each type.

+

The effect of compound reference is that all child reference counters are reset to 1 for change +in parent type’s ordinal allowing creation of legal numbering using enumerated references.

+

emoji symbols:information_source When combining enumerated type ordinal strings for compound enumerated +reference if the last element of the enumerated format definition is an empty enumerated +reference text [#] or empty enumerated reference link [@] then a . will be added after the +parent enumerated ordinal text.

+

emoji symbols:information_source For compound type for headings without an element id, a trailing : is +needed to prevent the last type from being interpreted as the element id.

+
# [#hd1] Heading 1
+
+## [#hd1:hd2:] Heading 1.1
+
+### [#hd1:hd2:hd3:] Heading 1.1.1
+
+### [#hd1:hd2:hd3:] Heading 1.1.2
+
+## [#hd1:hd2:] Heading 1.2
+
+### [#hd1:hd2:hd3:] Heading 1.2.1
+
+### [#hd1:hd2:hd3:] Heading 1.2.2
+
+# [#hd1] Heading 2
+
+## [#hd1:hd2:] Heading 2.1
+
+### [#hd1:hd2:hd3:] Heading 2.1.1
+
+### [#hd1:hd2:hd3:] Heading 2.1.2
+
+[@hd1]: [#].
+[@hd2]: [#].
+[@hd2]: [#].
+
+

Will render as:

+
<h1>1. Heading 1</h1>
+<h2>1.1. Heading 1.1</h2>
+<h3>1.1.1. Heading 1.1.1</h3>
+<h3>1.1.2. Heading 1.1.2</h3>
+<h2>1.2. Heading 1.2</h2>
+<h3>1.2.1. Heading 1.2.1</h3>
+<h3>1.2.2. Heading 1.2.2</h3>
+<h1>2. Heading 2</h1>
+<h2>2.1. Heading 2.1</h2>
+<h3>2.1.1. Heading 2.1.1</h3>
+<h3>2.1.2. Heading 2.1.2</h3>
+
diff --git a/flexmark-ext-enumerated-reference/src/main/javadoc/overview.md b/flexmark-ext-enumerated-reference/src/main/javadoc/overview.md index 28e16285e..91017e219 100644 --- a/flexmark-ext-enumerated-reference/src/main/javadoc/overview.md +++ b/flexmark-ext-enumerated-reference/src/main/javadoc/overview.md @@ -6,6 +6,8 @@ the category and `reference` is used to uniquely identify an element in the cate id of the element will be `type:reference` and this must be used by the enumerated reference label or link. +:information_source: `type` must not start with a digit. + To refer to the element in the document use the enumerated reference elements: 1. A reference link syntax `[@type:reference]` converts to a link based on type pattern defined @@ -32,10 +34,10 @@ To refer to the element in the document use the enumerated reference elements: For example: ``` -![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test} +![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test} [#fig:test] -![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2} +![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2} [#fig:test2] | heading | heading | heading | @@ -59,10 +61,10 @@ is equivalent to the following without having to manually keep track of numberin elements: ``` -![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test} +![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test} Figure 1. -![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2} +![Flexmark Icon Logo](https://github.com/vsch/flexmark-java/raw/master/assets/images/flexmark-icon-logo%402x.png){#fig:test2} Figure 2. | table | @@ -101,3 +103,85 @@ Will render as:

See Table 1.

``` +## Enumerated Reference Text in Headings + +Because headings contain their own anchor id an enumerated reference with only a `type` is +allowed in headings and has the effect of adding an incremented counter to heading text. + +```markdown +# [#hd1] Heading 1 + +# [#hd1] Heading 2 + +# [#hd1] Heading 3 + +[@hd1]: [#]. +``` + +Will render as: + +```html +

1. Heading 1

+

2. Heading 2

+

3. Heading 3

+``` + +## Compound Types + +Compound enumerated reference types are created by including more than one type reference with +`:` separating each type. + +The effect of compound reference is that all child reference counters are reset to 1 for change +in parent type's ordinal allowing creation of legal numbering using enumerated references. + +:information_source: When combining enumerated type ordinal strings for compound enumerated +reference if the last element of the enumerated format definition is an empty enumerated +reference text `[#]` or empty enumerated reference link `[@]` then a `.` will be added after the +parent enumerated ordinal text. + +:information_source: For compound type for headings without an element id, a trailing `:` is +needed to prevent the last `type` from being interpreted as the element id. + +```markdown +# [#hd1] Heading 1 + +## [#hd1:hd2:] Heading 1.1 + +### [#hd1:hd2:hd3:] Heading 1.1.1 + +### [#hd1:hd2:hd3:] Heading 1.1.2 + +## [#hd1:hd2:] Heading 1.2 + +### [#hd1:hd2:hd3:] Heading 1.2.1 + +### [#hd1:hd2:hd3:] Heading 1.2.2 + +# [#hd1] Heading 2 + +## [#hd1:hd2:] Heading 2.1 + +### [#hd1:hd2:hd3:] Heading 2.1.1 + +### [#hd1:hd2:hd3:] Heading 2.1.2 + +[@hd1]: [#]. +[@hd2]: [#]. +[@hd2]: [#]. +``` + +Will render as: + +```html +

1. Heading 1

+

1.1. Heading 1.1

+

1.1.1. Heading 1.1.1

+

1.1.2. Heading 1.1.2

+

1.2. Heading 1.2

+

1.2.1. Heading 1.2.1

+

1.2.2. Heading 1.2.2

+

2. Heading 2

+

2.1. Heading 2.1

+

2.1.1. Heading 2.1.1

+

2.1.2. Heading 2.1.2

+``` diff --git a/flexmark-ext-enumerated-reference/src/test/resources/ext_enumerated_reference_ast_spec.md b/flexmark-ext-enumerated-reference/src/test/resources/ext_enumerated_reference_ast_spec.md index d06a0d52f..578bbf9ce 100644 --- a/flexmark-ext-enumerated-reference/src/test/resources/ext_enumerated_reference_ast_spec.md +++ b/flexmark-ext-enumerated-reference/src/test/resources/ext_enumerated_reference_ast_spec.md @@ -19,6 +19,8 @@ Where [#] is replaced by the ordinal for the actual reference in the document. [ to [@] when there is no id. It is treated as a placeholder for the ordinal number for the given type. Outside of a enumerated reference definition it will render `0` +:information_source: `reference` must not start with a digit. + no spaces between brackets ```````````````````````````````` example Enumerated Reference: 1 @@ -154,3 +156,307 @@ Document[0, 42] ```````````````````````````````` +starting with digit is not a reference + +```````````````````````````````` example Enumerated Reference: 3 +[#123, GitHub Issue] + +[#123, GitHub Issue]: https://github.com/vsch/flexmark-java/issues/123 + +. +

#123, GitHub Issue

+. +Document[0, 94] + Paragraph[0, 21] isTrailingBlankLine + LinkRef[0, 20] referenceOpen:[0, 1, "["] reference:[1, 19, "#123, GitHub Issue"] referenceClose:[19, 20, "]"] + Text[1, 19] chars:[1, 19, "#123, … Issue"] + Reference[22, 92] refOpen:[22, 23, "["] ref:[23, 41, "#123, GitHub Issue"] refClose:[41, 43, "]:"] url:[44, 92, "https://github.com/vsch/flexmark-java/issues/123"] +```````````````````````````````` + + +## Heading + +Allow using empty format ref in heading + +```````````````````````````````` example Heading: 1 +# [#hdr] Numbered Heading + +[@hdr]: [#]. + +. +

1. Numbered Heading

+. +Document[0, 45] + Heading[0, 25] textOpen:[0, 1, "#"] text:[2, 25, "[#hdr] Numbered Heading"] + EnumeratedReferenceText[2, 8] textOpen:[2, 4, "[#"] text:[4, 7, "hdr"] textClose:[7, 8, "]"] + Text[4, 7] chars:[4, 7, "hdr"] + Text[8, 25] chars:[8, 25, " Numb … ading"] + EnumeratedReferenceBlock[31, 44] open:[31, 33] text:[33, 36] close:[36, 38] enumeratedReference:[39, 44] + Paragraph[39, 44] isTrailingBlankLine + EnumeratedReferenceText[39, 42] textOpen:[39, 41, "[#"] text:[41, 41] textClose:[41, 42, "]"] + Text[42, 43] chars:[42, 43, "."] +```````````````````````````````` + + +```````````````````````````````` example Heading: 2 +# [#hdr] Numbered Heading + +# [#hdr] Numbered Heading + +[@hdr]: [#]. + +. +

1. Numbered Heading

+

2. Numbered Heading

+. +Document[0, 76] + Heading[0, 25] textOpen:[0, 1, "#"] text:[2, 25, "[#hdr] Numbered Heading"] + EnumeratedReferenceText[2, 8] textOpen:[2, 4, "[#"] text:[4, 7, "hdr"] textClose:[7, 8, "]"] + Text[4, 7] chars:[4, 7, "hdr"] + Text[8, 25] chars:[8, 25, " Numb … ading"] + Heading[31, 56] textOpen:[31, 32, "#"] text:[33, 56, "[#hdr] Numbered Heading"] + EnumeratedReferenceText[33, 39] textOpen:[33, 35, "[#"] text:[35, 38, "hdr"] textClose:[38, 39, "]"] + Text[35, 38] chars:[35, 38, "hdr"] + Text[39, 56] chars:[39, 56, " Numb … ading"] + EnumeratedReferenceBlock[62, 75] open:[62, 64] text:[64, 67] close:[67, 69] enumeratedReference:[70, 75] + Paragraph[70, 75] isTrailingBlankLine + EnumeratedReferenceText[70, 73] textOpen:[70, 72, "[#"] text:[72, 72] textClose:[72, 73, "]"] + Text[73, 74] chars:[73, 74, "."] +```````````````````````````````` + + +Compound numbering + +```````````````````````````````` example Heading: 3 +## [#hdr1:hdr2:] Numbered Heading 0.1 + +# [#hdr1] Numbered Heading 1 + +## [#hdr1:hdr2:] Numbered Heading 1.1 + +# [#hdr1] Numbered Heading 2 + +## [#hdr1:hdr2:] Numbered Heading 2.1 + +[@hdr1]: [#]. + +[@hdr2]: [#]. + +. +

0.1. Numbered Heading 0.1

+

1. Numbered Heading 1

+

1.1. Numbered Heading 1.1

+

2. Numbered Heading 2

+

2.1. Numbered Heading 2.1

+. +Document[0, 231] + Heading[0, 37] textOpen:[0, 2, "##"] text:[3, 37, "[#hdr1:hdr2:] Numbered Heading 0.1"] + EnumeratedReferenceText[3, 16] textOpen:[3, 5, "[#"] text:[5, 15, "hdr1:hdr2:"] textClose:[15, 16, "]"] + Text[5, 15] chars:[5, 15, "hdr1:hdr2:"] + Text[16, 37] chars:[16, 37, " Numb … g 0.1"] + Heading[43, 71] textOpen:[43, 44, "#"] text:[45, 71, "[#hdr1] Numbered Heading 1"] + EnumeratedReferenceText[45, 52] textOpen:[45, 47, "[#"] text:[47, 51, "hdr1"] textClose:[51, 52, "]"] + Text[47, 51] chars:[47, 51, "hdr1"] + Text[52, 71] chars:[52, 71, " Numb … ing 1"] + Heading[77, 114] textOpen:[77, 79, "##"] text:[80, 114, "[#hdr1:hdr2:] Numbered Heading 1.1"] + EnumeratedReferenceText[80, 93] textOpen:[80, 82, "[#"] text:[82, 92, "hdr1:hdr2:"] textClose:[92, 93, "]"] + Text[82, 92] chars:[82, 92, "hdr1:hdr2:"] + Text[93, 114] chars:[93, 114, " Numb … g 1.1"] + Heading[120, 148] textOpen:[120, 121, "#"] text:[122, 148, "[#hdr1] Numbered Heading 2"] + EnumeratedReferenceText[122, 129] textOpen:[122, 124, "[#"] text:[124, 128, "hdr1"] textClose:[128, 129, "]"] + Text[124, 128] chars:[124, 128, "hdr1"] + Text[129, 148] chars:[129, 148, " Numb … ing 2"] + Heading[154, 191] textOpen:[154, 156, "##"] text:[157, 191, "[#hdr1:hdr2:] Numbered Heading 2.1"] + EnumeratedReferenceText[157, 170] textOpen:[157, 159, "[#"] text:[159, 169, "hdr1:hdr2:"] textClose:[169, 170, "]"] + Text[159, 169] chars:[159, 169, "hdr1:hdr2:"] + Text[170, 191] chars:[170, 191, " Numb … g 2.1"] + EnumeratedReferenceBlock[197, 211] open:[197, 199] text:[199, 203] close:[203, 205] enumeratedReference:[206, 211] + Paragraph[206, 211] isTrailingBlankLine + EnumeratedReferenceText[206, 209] textOpen:[206, 208, "[#"] text:[208, 208] textClose:[208, 209, "]"] + Text[209, 210] chars:[209, 210, "."] + EnumeratedReferenceBlock[216, 230] open:[216, 218] text:[218, 222] close:[222, 224] enumeratedReference:[225, 230] + Paragraph[225, 230] isTrailingBlankLine + EnumeratedReferenceText[225, 228] textOpen:[225, 227, "[#"] text:[227, 227] textClose:[227, 228, "]"] + Text[228, 229] chars:[228, 229, "."] +```````````````````````````````` + + +`.` appended by default if last element for format is empty Enumerated Reference Text or Link + +```````````````````````````````` example Heading: 4 +# [#hdr1] Numbered Heading 1 + +## [#hdr1:hdr2:] Numbered Heading 1.1 + +# [#hdr1] Numbered Heading 2 + +## [#hdr1:hdr2:] Numbered Heading 2.1 + +[@hdr1]: [#] + +[@hdr2]: [#] + +. +

1 Numbered Heading 1

+

1.1 Numbered Heading 1.1

+

2 Numbered Heading 2

+

2.1 Numbered Heading 2.1

+. +Document[0, 186] + Heading[0, 28] textOpen:[0, 1, "#"] text:[2, 28, "[#hdr1] Numbered Heading 1"] + EnumeratedReferenceText[2, 9] textOpen:[2, 4, "[#"] text:[4, 8, "hdr1"] textClose:[8, 9, "]"] + Text[4, 8] chars:[4, 8, "hdr1"] + Text[9, 28] chars:[9, 28, " Numb … ing 1"] + Heading[34, 71] textOpen:[34, 36, "##"] text:[37, 71, "[#hdr1:hdr2:] Numbered Heading 1.1"] + EnumeratedReferenceText[37, 50] textOpen:[37, 39, "[#"] text:[39, 49, "hdr1:hdr2:"] textClose:[49, 50, "]"] + Text[39, 49] chars:[39, 49, "hdr1:hdr2:"] + Text[50, 71] chars:[50, 71, " Numb … g 1.1"] + Heading[77, 105] textOpen:[77, 78, "#"] text:[79, 105, "[#hdr1] Numbered Heading 2"] + EnumeratedReferenceText[79, 86] textOpen:[79, 81, "[#"] text:[81, 85, "hdr1"] textClose:[85, 86, "]"] + Text[81, 85] chars:[81, 85, "hdr1"] + Text[86, 105] chars:[86, 105, " Numb … ing 2"] + Heading[111, 148] textOpen:[111, 113, "##"] text:[114, 148, "[#hdr1:hdr2:] Numbered Heading 2.1"] + EnumeratedReferenceText[114, 127] textOpen:[114, 116, "[#"] text:[116, 126, "hdr1:hdr2:"] textClose:[126, 127, "]"] + Text[116, 126] chars:[116, 126, "hdr1:hdr2:"] + Text[127, 148] chars:[127, 148, " Numb … g 2.1"] + EnumeratedReferenceBlock[154, 167] open:[154, 156] text:[156, 160] close:[160, 162] enumeratedReference:[163, 167] + Paragraph[163, 167] isTrailingBlankLine + EnumeratedReferenceText[163, 166] textOpen:[163, 165, "[#"] text:[165, 165] textClose:[165, 166, "]"] + EnumeratedReferenceBlock[172, 185] open:[172, 174] text:[174, 178] close:[178, 180] enumeratedReference:[181, 185] + Paragraph[181, 185] isTrailingBlankLine + EnumeratedReferenceText[181, 184] textOpen:[181, 183, "[#"] text:[183, 183] textClose:[183, 184, "]"] +```````````````````````````````` + + +```````````````````````````````` example Heading: 5 +# [#hd1] Heading 1 + +# [#hd1] Heading 2 + +# [#hd1] Heading 3 + +[@hd1]: [#]. +. +

1. Heading 1

+

2. Heading 2

+

3. Heading 3

+. +Document[0, 73] + Heading[0, 18] textOpen:[0, 1, "#"] text:[2, 18, "[#hd1] Heading 1"] + EnumeratedReferenceText[2, 8] textOpen:[2, 4, "[#"] text:[4, 7, "hd1"] textClose:[7, 8, "]"] + Text[4, 7] chars:[4, 7, "hd1"] + Text[8, 18] chars:[8, 18, " Heading 1"] + Heading[20, 38] textOpen:[20, 21, "#"] text:[22, 38, "[#hd1] Heading 2"] + EnumeratedReferenceText[22, 28] textOpen:[22, 24, "[#"] text:[24, 27, "hd1"] textClose:[27, 28, "]"] + Text[24, 27] chars:[24, 27, "hd1"] + Text[28, 38] chars:[28, 38, " Heading 2"] + Heading[40, 58] textOpen:[40, 41, "#"] text:[42, 58, "[#hd1] Heading 3"] + EnumeratedReferenceText[42, 48] textOpen:[42, 44, "[#"] text:[44, 47, "hd1"] textClose:[47, 48, "]"] + Text[44, 47] chars:[44, 47, "hd1"] + Text[48, 58] chars:[48, 58, " Heading 3"] + EnumeratedReferenceBlock[60, 73] open:[60, 62] text:[62, 65] close:[65, 67] enumeratedReference:[68, 73] + Paragraph[68, 73] + EnumeratedReferenceText[68, 71] textOpen:[68, 70, "[#"] text:[70, 70] textClose:[70, 71, "]"] + Text[71, 72] chars:[71, 72, "."] +```````````````````````````````` + + +```````````````````````````````` example Heading: 6 +# [#hd1] Heading 1 + +## [#hd1:hd2:] Heading 1.1 + +### [#hd1:hd2:hd3:] Heading 1.1.1 + +### [#hd1:hd2:hd3:] Heading 1.1.2 + +## [#hd1:hd2:] Heading 1.2 + +### [#hd1:hd2:hd3:] Heading 1.2.1 + +### [#hd1:hd2:hd3:] Heading 1.2.2 + +# [#hd1] Heading 2 + +## [#hd1:hd2:] Heading 2.1 + +### [#hd1:hd2:hd3:] Heading 2.1.1 + +### [#hd1:hd2:hd3:] Heading 2.1.2 + +[@hd1]: [#]. +[@hd2]: [#]. +[@hd3]: [#]. +. +

1. Heading 1

+

1.1. Heading 1.1

+

1.1.1. Heading 1.1.1

+

1.1.2. Heading 1.1.2

+

1.2. Heading 1.2

+

1.2.1. Heading 1.2.1

+

1.2.2. Heading 1.2.2

+

2. Heading 2

+

2.1. Heading 2.1

+

2.1.1. Heading 2.1.1

+

2.1.2. Heading 2.1.2

+. +Document[0, 373] + Heading[0, 18] textOpen:[0, 1, "#"] text:[2, 18, "[#hd1] Heading 1"] + EnumeratedReferenceText[2, 8] textOpen:[2, 4, "[#"] text:[4, 7, "hd1"] textClose:[7, 8, "]"] + Text[4, 7] chars:[4, 7, "hd1"] + Text[8, 18] chars:[8, 18, " Heading 1"] + Heading[20, 46] textOpen:[20, 22, "##"] text:[23, 46, "[#hd1:hd2:] Heading 1.1"] + EnumeratedReferenceText[23, 34] textOpen:[23, 25, "[#"] text:[25, 33, "hd1:hd2:"] textClose:[33, 34, "]"] + Text[25, 33] chars:[25, 33, "hd1:hd2:"] + Text[34, 46] chars:[34, 46, " Head … g 1.1"] + Heading[48, 81] textOpen:[48, 51, "###"] text:[52, 81, "[#hd1:hd2:hd3:] Heading 1.1.1"] + EnumeratedReferenceText[52, 67] textOpen:[52, 54, "[#"] text:[54, 66, "hd1:hd2:hd3:"] textClose:[66, 67, "]"] + Text[54, 66] chars:[54, 66, "hd1:h … :hd3:"] + Text[67, 81] chars:[67, 81, " Head … 1.1.1"] + Heading[83, 116] textOpen:[83, 86, "###"] text:[87, 116, "[#hd1:hd2:hd3:] Heading 1.1.2"] + EnumeratedReferenceText[87, 102] textOpen:[87, 89, "[#"] text:[89, 101, "hd1:hd2:hd3:"] textClose:[101, 102, "]"] + Text[89, 101] chars:[89, 101, "hd1:h … :hd3:"] + Text[102, 116] chars:[102, 116, " Head … 1.1.2"] + Heading[118, 144] textOpen:[118, 120, "##"] text:[121, 144, "[#hd1:hd2:] Heading 1.2"] + EnumeratedReferenceText[121, 132] textOpen:[121, 123, "[#"] text:[123, 131, "hd1:hd2:"] textClose:[131, 132, "]"] + Text[123, 131] chars:[123, 131, "hd1:hd2:"] + Text[132, 144] chars:[132, 144, " Head … g 1.2"] + Heading[146, 179] textOpen:[146, 149, "###"] text:[150, 179, "[#hd1:hd2:hd3:] Heading 1.2.1"] + EnumeratedReferenceText[150, 165] textOpen:[150, 152, "[#"] text:[152, 164, "hd1:hd2:hd3:"] textClose:[164, 165, "]"] + Text[152, 164] chars:[152, 164, "hd1:h … :hd3:"] + Text[165, 179] chars:[165, 179, " Head … 1.2.1"] + Heading[181, 214] textOpen:[181, 184, "###"] text:[185, 214, "[#hd1:hd2:hd3:] Heading 1.2.2"] + EnumeratedReferenceText[185, 200] textOpen:[185, 187, "[#"] text:[187, 199, "hd1:hd2:hd3:"] textClose:[199, 200, "]"] + Text[187, 199] chars:[187, 199, "hd1:h … :hd3:"] + Text[200, 214] chars:[200, 214, " Head … 1.2.2"] + Heading[216, 234] textOpen:[216, 217, "#"] text:[218, 234, "[#hd1] Heading 2"] + EnumeratedReferenceText[218, 224] textOpen:[218, 220, "[#"] text:[220, 223, "hd1"] textClose:[223, 224, "]"] + Text[220, 223] chars:[220, 223, "hd1"] + Text[224, 234] chars:[224, 234, " Heading 2"] + Heading[236, 262] textOpen:[236, 238, "##"] text:[239, 262, "[#hd1:hd2:] Heading 2.1"] + EnumeratedReferenceText[239, 250] textOpen:[239, 241, "[#"] text:[241, 249, "hd1:hd2:"] textClose:[249, 250, "]"] + Text[241, 249] chars:[241, 249, "hd1:hd2:"] + Text[250, 262] chars:[250, 262, " Head … g 2.1"] + Heading[264, 297] textOpen:[264, 267, "###"] text:[268, 297, "[#hd1:hd2:hd3:] Heading 2.1.1"] + EnumeratedReferenceText[268, 283] textOpen:[268, 270, "[#"] text:[270, 282, "hd1:hd2:hd3:"] textClose:[282, 283, "]"] + Text[270, 282] chars:[270, 282, "hd1:h … :hd3:"] + Text[283, 297] chars:[283, 297, " Head … 2.1.1"] + Heading[299, 332] textOpen:[299, 302, "###"] text:[303, 332, "[#hd1:hd2:hd3:] Heading 2.1.2"] + EnumeratedReferenceText[303, 318] textOpen:[303, 305, "[#"] text:[305, 317, "hd1:hd2:hd3:"] textClose:[317, 318, "]"] + Text[305, 317] chars:[305, 317, "hd1:h … :hd3:"] + Text[318, 332] chars:[318, 332, " Head … 2.1.2"] + EnumeratedReferenceBlock[334, 347] open:[334, 336] text:[336, 339] close:[339, 341] enumeratedReference:[342, 347] + Paragraph[342, 347] + EnumeratedReferenceText[342, 345] textOpen:[342, 344, "[#"] text:[344, 344] textClose:[344, 345, "]"] + Text[345, 346] chars:[345, 346, "."] + EnumeratedReferenceBlock[347, 360] open:[347, 349] text:[349, 352] close:[352, 354] enumeratedReference:[355, 360] + Paragraph[355, 360] + EnumeratedReferenceText[355, 358] textOpen:[355, 357, "[#"] text:[357, 357] textClose:[357, 358, "]"] + Text[358, 359] chars:[358, 359, "."] + EnumeratedReferenceBlock[360, 373] open:[360, 362] text:[362, 365] close:[365, 367] enumeratedReference:[368, 373] + Paragraph[368, 373] + EnumeratedReferenceText[368, 371] textOpen:[368, 370, "[#"] text:[370, 370] textClose:[370, 371, "]"] + Text[371, 372] chars:[371, 372, "."] +```````````````````````````````` + + diff --git a/flexmark-ext-escaped-character/pom.xml b/flexmark-ext-escaped-character/pom.xml index bdce52b82..b87a6be72 100644 --- a/flexmark-ext-escaped-character/pom.xml +++ b/flexmark-ext-escaped-character/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-escaped-character diff --git a/flexmark-ext-footnotes/pom.xml b/flexmark-ext-footnotes/pom.xml index 24364b135..2a2a65700 100644 --- a/flexmark-ext-footnotes/pom.xml +++ b/flexmark-ext-footnotes/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-footnotes diff --git a/flexmark-ext-gfm-issues/pom.xml b/flexmark-ext-gfm-issues/pom.xml index 734b3b0e8..3edb13794 100644 --- a/flexmark-ext-gfm-issues/pom.xml +++ b/flexmark-ext-gfm-issues/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gfm-issues diff --git a/flexmark-ext-gfm-strikethrough/pom.xml b/flexmark-ext-gfm-strikethrough/pom.xml index c786703fe..05ffee01a 100644 --- a/flexmark-ext-gfm-strikethrough/pom.xml +++ b/flexmark-ext-gfm-strikethrough/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gfm-strikethrough diff --git a/flexmark-ext-gfm-tables/pom.xml b/flexmark-ext-gfm-tables/pom.xml index e3b75522a..f36d6eb42 100644 --- a/flexmark-ext-gfm-tables/pom.xml +++ b/flexmark-ext-gfm-tables/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gfm-tables diff --git a/flexmark-ext-gfm-tasklist/pom.xml b/flexmark-ext-gfm-tasklist/pom.xml index 00c66b926..5c5f7e290 100644 --- a/flexmark-ext-gfm-tasklist/pom.xml +++ b/flexmark-ext-gfm-tasklist/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gfm-tasklist diff --git a/flexmark-ext-gfm-users/pom.xml b/flexmark-ext-gfm-users/pom.xml index 8d9d9fbb1..0e4b3e9b0 100644 --- a/flexmark-ext-gfm-users/pom.xml +++ b/flexmark-ext-gfm-users/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gfm-users diff --git a/flexmark-ext-gitlab/pom.xml b/flexmark-ext-gitlab/pom.xml index 9036de37f..680819589 100644 --- a/flexmark-ext-gitlab/pom.xml +++ b/flexmark-ext-gitlab/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-gitlab diff --git a/flexmark-ext-ins/pom.xml b/flexmark-ext-ins/pom.xml index faac494af..b82b83f5f 100644 --- a/flexmark-ext-ins/pom.xml +++ b/flexmark-ext-ins/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-ins diff --git a/flexmark-ext-jekyll-front-matter/pom.xml b/flexmark-ext-jekyll-front-matter/pom.xml index b48abf45f..518d42cc6 100644 --- a/flexmark-ext-jekyll-front-matter/pom.xml +++ b/flexmark-ext-jekyll-front-matter/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-jekyll-front-matter diff --git a/flexmark-ext-jekyll-tag/pom.xml b/flexmark-ext-jekyll-tag/pom.xml index a785c2694..6e94da5d2 100644 --- a/flexmark-ext-jekyll-tag/pom.xml +++ b/flexmark-ext-jekyll-tag/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-jekyll-tag diff --git a/flexmark-ext-macros/pom.xml b/flexmark-ext-macros/pom.xml index 98dc8c04e..2909d0e96 100644 --- a/flexmark-ext-macros/pom.xml +++ b/flexmark-ext-macros/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-macros diff --git a/flexmark-ext-media-tags/pom.xml b/flexmark-ext-media-tags/pom.xml index 1029d0808..dc2e2f489 100644 --- a/flexmark-ext-media-tags/pom.xml +++ b/flexmark-ext-media-tags/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-media-tags @@ -19,6 +19,7 @@ com.vladsch.flexmark flexmark-test-util + test diff --git a/flexmark-ext-spec-example/pom.xml b/flexmark-ext-spec-example/pom.xml index 4bcc61b4d..ebbf4e63c 100644 --- a/flexmark-ext-spec-example/pom.xml +++ b/flexmark-ext-spec-example/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-spec-example diff --git a/flexmark-ext-superscript/pom.xml b/flexmark-ext-superscript/pom.xml index 42e5017b4..948bca762 100644 --- a/flexmark-ext-superscript/pom.xml +++ b/flexmark-ext-superscript/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-superscript diff --git a/flexmark-ext-tables/pom.xml b/flexmark-ext-tables/pom.xml index 71469d3ae..873297af3 100644 --- a/flexmark-ext-tables/pom.xml +++ b/flexmark-ext-tables/pom.xml @@ -5,7 +5,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-tables diff --git a/flexmark-ext-tables/src/main/javadoc/overview.html b/flexmark-ext-tables/src/main/javadoc/overview.html index b0a8c1d68..84e989718 100644 --- a/flexmark-ext-tables/src/main/javadoc/overview.html +++ b/flexmark-ext-tables/src/main/javadoc/overview.html @@ -19,6 +19,6 @@

Additionally, missing columns may be either left as is or filled in with empty elements.

When column span syntax is enabled, empty table cells must have at least one space. Otherwise they will be interpreted as column spans for the previous cell.

-

emoji places:warning Table elements must be preceded by a blank line to be processed by this extension.

+

emoji places:warning Table elements must be preceded by a blank line to be processed by this extension.

diff --git a/flexmark-ext-toc/pom.xml b/flexmark-ext-toc/pom.xml index aab25690f..6e8602c25 100644 --- a/flexmark-ext-toc/pom.xml +++ b/flexmark-ext-toc/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-toc diff --git a/flexmark-ext-typographic/pom.xml b/flexmark-ext-typographic/pom.xml index 8108ee2ab..64b609698 100644 --- a/flexmark-ext-typographic/pom.xml +++ b/flexmark-ext-typographic/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-typographic diff --git a/flexmark-ext-wikilink/pom.xml b/flexmark-ext-wikilink/pom.xml index 3d5d1a4e0..5a15e57ea 100644 --- a/flexmark-ext-wikilink/pom.xml +++ b/flexmark-ext-wikilink/pom.xml @@ -5,7 +5,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-wikilink diff --git a/flexmark-ext-xwiki-macros/pom.xml b/flexmark-ext-xwiki-macros/pom.xml index aa6782af8..366e2f80b 100644 --- a/flexmark-ext-xwiki-macros/pom.xml +++ b/flexmark-ext-xwiki-macros/pom.xml @@ -4,7 +4,7 @@ com.vladsch.flexmark flexmark-java - 0.35.6 + 0.35.10 flexmark-ext-xwiki-macros diff --git a/flexmark-ext-xwiki-macros/src/main/javadoc/overview.html b/flexmark-ext-xwiki-macros/src/main/javadoc/overview.html index d9dad9d70..34572c4d5 100644 --- a/flexmark-ext-xwiki-macros/src/main/javadoc/overview.html +++ b/flexmark-ext-xwiki-macros/src/main/javadoc/overview.html @@ -37,7 +37,7 @@

Block Macros

Inline Macros:

A non-indenting space should be included before the opening and closing inline macro to prevent it from being interpreted as a block macro.

-

emoji symbols:information_source Non-indenting space below is replaced with

+

emoji symbols:information_source Non-indenting space below is replaced with

․{{macroName attribute4='another format'}} 
 possibly containing other lines, but no blank lines 
 ․{{/macroName}}
diff --git a/flexmark-ext-yaml-front-matter/pom.xml b/flexmark-ext-yaml-front-matter/pom.xml
index ac67959cf..f594351ea 100644
--- a/flexmark-ext-yaml-front-matter/pom.xml
+++ b/flexmark-ext-yaml-front-matter/pom.xml
@@ -4,7 +4,7 @@
     
         flexmark-java
         com.vladsch.flexmark
-        0.35.6
+        0.35.10
     
 
     flexmark-ext-yaml-front-matter
diff --git a/flexmark-ext-youtube-embedded/pom.xml b/flexmark-ext-youtube-embedded/pom.xml
index 2610f4b80..9e5b38de3 100644
--- a/flexmark-ext-youtube-embedded/pom.xml
+++ b/flexmark-ext-youtube-embedded/pom.xml
@@ -4,7 +4,7 @@
     
         flexmark-java
         com.vladsch.flexmark
-        0.35.6
+        0.35.10
     
     4.0.0
 
diff --git a/flexmark-ext-zzzzzz/pom.xml b/flexmark-ext-zzzzzz/pom.xml
index d0fde10f3..9c297aa45 100644
--- a/flexmark-ext-zzzzzz/pom.xml
+++ b/flexmark-ext-zzzzzz/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-ext-zzzzzz
diff --git a/flexmark-formatter/pom.xml b/flexmark-formatter/pom.xml
index 2df915450..53c4177e7 100644
--- a/flexmark-formatter/pom.xml
+++ b/flexmark-formatter/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-formatter
diff --git a/flexmark-html-parser/pom.xml b/flexmark-html-parser/pom.xml
index 3805bb73e..5ac5def86 100644
--- a/flexmark-html-parser/pom.xml
+++ b/flexmark-html-parser/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-html-parser
diff --git a/flexmark-integration-test/pom.xml b/flexmark-integration-test/pom.xml
index b6f72fea1..1393fc862 100644
--- a/flexmark-integration-test/pom.xml
+++ b/flexmark-integration-test/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-integration-test
diff --git a/flexmark-jira-converter/pom.xml b/flexmark-jira-converter/pom.xml
index 97e4005f4..36aeca7a6 100644
--- a/flexmark-jira-converter/pom.xml
+++ b/flexmark-jira-converter/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-jira-converter
diff --git a/flexmark-osgi/pom.xml b/flexmark-osgi/pom.xml
index c0d565c08..267e312e7 100644
--- a/flexmark-osgi/pom.xml
+++ b/flexmark-osgi/pom.xml
@@ -7,7 +7,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-osgi
diff --git a/flexmark-pdf-converter/pom.xml b/flexmark-pdf-converter/pom.xml
index 217953ca6..31f39a84c 100644
--- a/flexmark-pdf-converter/pom.xml
+++ b/flexmark-pdf-converter/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-pdf-converter
diff --git a/flexmark-profile-pegdown/pom.xml b/flexmark-profile-pegdown/pom.xml
index 0f2edfb77..8c40096eb 100644
--- a/flexmark-profile-pegdown/pom.xml
+++ b/flexmark-profile-pegdown/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-profile-pegdown
diff --git a/flexmark-test-util/pom.xml b/flexmark-test-util/pom.xml
index 04114e394..43518185b 100644
--- a/flexmark-test-util/pom.xml
+++ b/flexmark-test-util/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-test-util
diff --git a/flexmark-util/pom.xml b/flexmark-util/pom.xml
index af9690553..8f07dd1a2 100644
--- a/flexmark-util/pom.xml
+++ b/flexmark-util/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-util
diff --git a/flexmark-util/src/main/java/com/vladsch/flexmark/ast/DoNotAttributeDecorate.java b/flexmark-util/src/main/java/com/vladsch/flexmark/ast/DoNotAttributeDecorate.java
new file mode 100644
index 000000000..1bcfaf9bb
--- /dev/null
+++ b/flexmark-util/src/main/java/com/vladsch/flexmark/ast/DoNotAttributeDecorate.java
@@ -0,0 +1,7 @@
+package com.vladsch.flexmark.ast;
+
+/**
+ * To be implemented by nodes marking their text as not for attachment by attributes
+ */
+public interface DoNotAttributeDecorate {
+}
diff --git a/flexmark-youtrack-converter/pom.xml b/flexmark-youtrack-converter/pom.xml
index 17dbc3f50..539253f58 100644
--- a/flexmark-youtrack-converter/pom.xml
+++ b/flexmark-youtrack-converter/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark-youtrack-converter
diff --git a/flexmark/pom.xml b/flexmark/pom.xml
index a5688b473..1a8da9355 100644
--- a/flexmark/pom.xml
+++ b/flexmark/pom.xml
@@ -4,7 +4,7 @@
     
         com.vladsch.flexmark
         flexmark-java
-        0.35.6
+        0.35.10
     
 
     flexmark
@@ -15,6 +15,7 @@
         
             com.vladsch.flexmark
             flexmark-test-util
+            test
         
         
             com.vladsch.flexmark
diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/util/Parsing.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/util/Parsing.java
index 9c3e214c7..8b7c542ab 100644
--- a/flexmark/src/main/java/com/vladsch/flexmark/ast/util/Parsing.java
+++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/util/Parsing.java
@@ -13,6 +13,9 @@ public class Parsing {
     public static final char INTELLIJ_DUMMY_IDENTIFIER_CHAR = TableFormatOptions.INTELLIJ_DUMMY_IDENTIFIER_CHAR;
     public static final String INTELLIJ_DUMMY_IDENTIFIER = TableFormatOptions.INTELLIJ_DUMMY_IDENTIFIER;
 
+    // save options for others to use when only parsing instance is available
+    public final DataHolder options;
+    
     public final String ADDITIONAL_CHARS;
     public final String EXCLUDED_0_TO_SPACE;
 
@@ -52,6 +55,7 @@ public class Parsing {
     public final Pattern TICKS_HERE;
     public final Pattern EMAIL_AUTOLINK;
     public final Pattern AUTOLINK;
+    public final Pattern WWW_AUTOLINK;
     public final Pattern SPNL;
     public final Pattern SPNL_URL;
     public final Pattern SPNI;
@@ -88,6 +92,7 @@ public class Parsing {
     public final String REG_CHAR_SP_PARENS;
 
     public Parsing(DataHolder options) {
+        this.options = options;
         this.intellijDummyIdentifier = Parser.INTELLIJ_DUMMY_IDENTIFIER.getFrom(options);
         this.htmlForTranslator = Parser.HTML_FOR_TRANSLATOR.getFrom(options);
         this.translationHtmlInlineTagPattern = Parser.TRANSLATION_HTML_INLINE_TAG_PATTERN.getFrom(options);
@@ -156,6 +161,10 @@ public Parsing(DataHolder options) {
                 "^<([a-zA-Z0-9" + ADDITIONAL_CHARS + ".!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9" + ADDITIONAL_CHARS + "](?:[a-zA-Z0-9" + ADDITIONAL_CHARS + "-]{0,61}[a-zA-Z0-9" + ADDITIONAL_CHARS + "])?(?:\\.[a-zA-Z0-9" + ADDITIONAL_CHARS + "](?:[a-zA-Z0-9" + ADDITIONAL_CHARS + "-]{0,61}[a-zA-Z0-9" + ADDITIONAL_CHARS + "])?)*)>");
         this.AUTOLINK = Pattern.compile(
                 "^<[a-zA-Z][a-zA-Z0-9" + ADDITIONAL_CHARS + ".+-]{1,31}:[^<>" + EXCLUDED_0_TO_SPACE + "]*>");
+        
+        this.WWW_AUTOLINK = Pattern.compile(
+                "^<(?:w" + ADDITIONAL_CHARS + "?){3,3}\\.[^<>" + EXCLUDED_0_TO_SPACE + "]*>");
+        
         this.SPNL = Pattern.compile("^(?:[ \t])*(?:" + EOL + "(?:[ \t])*)?");
         this.SPNL_URL = Pattern.compile("^(?:[ \t])*" + EOL);
         this.SPNI = Pattern.compile("^ {0,3}");
diff --git a/flexmark/src/main/java/com/vladsch/flexmark/internal/DocumentParser.java b/flexmark/src/main/java/com/vladsch/flexmark/internal/DocumentParser.java
index 8e83c540a..ad8cc9a81 100644
--- a/flexmark/src/main/java/com/vladsch/flexmark/internal/DocumentParser.java
+++ b/flexmark/src/main/java/com/vladsch/flexmark/internal/DocumentParser.java
@@ -1,12 +1,6 @@
 package com.vladsch.flexmark.internal;
 
-import com.vladsch.flexmark.ast.BlankLine;
-import com.vladsch.flexmark.ast.BlankLineContainer;
-import com.vladsch.flexmark.ast.Block;
-import com.vladsch.flexmark.ast.Document;
-import com.vladsch.flexmark.ast.KeepTrailingBlankLineContainer;
-import com.vladsch.flexmark.ast.Node;
-import com.vladsch.flexmark.ast.Paragraph;
+import com.vladsch.flexmark.ast.*;
 import com.vladsch.flexmark.ast.util.ClassifyingBlockTracker;
 import com.vladsch.flexmark.ast.util.Parsing;
 import com.vladsch.flexmark.parser.InlineParser;
@@ -15,7 +9,6 @@
 import com.vladsch.flexmark.parser.Parser;
 import com.vladsch.flexmark.parser.block.*;
 import com.vladsch.flexmark.parser.delimiter.DelimiterProcessor;
-import com.vladsch.flexmark.test.AstCollectingVisitor;
 import com.vladsch.flexmark.util.Computable;
 import com.vladsch.flexmark.util.collection.ItemFactoryMap;
 import com.vladsch.flexmark.util.collection.iteration.ReversibleIterable;
@@ -28,18 +21,11 @@
 import com.vladsch.flexmark.util.sequence.CharSubSequence;
 import com.vladsch.flexmark.util.sequence.PrefixedSubSequence;
 import com.vladsch.flexmark.util.sequence.SubSequence;
-import org.apache.log4j.Logger;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.Reader;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import static com.vladsch.flexmark.parser.Parser.BLANK_LINES_IN_AST;
 import static com.vladsch.flexmark.parser.Parser.TRACK_DOCUMENT_LINES;
@@ -1145,37 +1131,37 @@ private void preProcessBlocks() {
         }
     }
 
-    private static Logger LOG = Logger.getLogger(DocumentParser.class);
+    //private static Logger LOG = Logger.getLogger(DocumentParser.class);
 
     private Document finalizeAndProcess() {
         finalizeBlocks(this.activeBlockParsers);
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Parsed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
-        }
+        //if (LOG.isDebugEnabled()) {
+        //    LOG.debug("Parsed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
+        //}
 
         // need to run block pre-processors at this point, before inline processing
         currentPhase = ParserPhase.PRE_PROCESS_PARAGRAPHS;
         this.preProcessParagraphs();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Paragraphs PreProcessed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
-        }
+        //if (LOG.isDebugEnabled()) {
+        //    LOG.debug("Paragraphs PreProcessed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
+        //}
 
         currentPhase = ParserPhase.PRE_PROCESS_BLOCKS;
         this.preProcessBlocks();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Blocks PreProcessed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
-        }
+        //if (LOG.isDebugEnabled()) {
+        //    LOG.debug("Blocks PreProcessed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
+        //}
 
         // can naw run inline processing
         currentPhase = ParserPhase.PARSE_INLINES;
         this.processInlines();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Inline Processed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
-        }
+        //if (LOG.isDebugEnabled()) {
+        //    LOG.debug("Inline Processed\n" + new AstCollectingVisitor().collectAndGetAstText(documentBlockParser.getBlock()));
+        //}
 
         currentPhase = ParserPhase.DONE;
         Document document = this.documentBlockParser.getBlock();
diff --git a/pom.xml b/pom.xml
index 5fc3ef8bc..96ae7df3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
 
     com.vladsch.flexmark
     flexmark-java
-    0.35.6
+    0.35.10
     flexmark-java
     
         Java re-implementation of commonmark-java based parser, with AST reflecting source elements, full source position tracking, greater parser extensibility.
@@ -217,217 +217,217 @@
             
                 com.vladsch.flexmark
                 flexmark
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-docx-converter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-abbreviation
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-anchorlink
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-admonition
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-aside
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-attributes
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-autolink
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-definition
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-emoji
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-enumerated-reference
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-escaped-character
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-footnotes
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gfm-issues
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gfm-strikethrough
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gfm-tables
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gfm-tasklist
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gfm-users
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-gitlab
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-ins
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-jekyll-front-matter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-jekyll-tag
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-macros
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-media-tags
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-xwiki-macros
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-spec-example
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-superscript
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-tables
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-toc
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-typographic
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-wikilink
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-yaml-front-matter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-youtube-embedded
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-ext-zzzzzz
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-formatter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-html-parser
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-jira-converter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-pdf-converter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-profile-pegdown
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-test-util
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-util
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-youtrack-converter
-                0.35.6
+                0.35.10
             
             
                 com.vladsch.flexmark
                 flexmark-all
-                0.35.6
+                0.35.10