diff --git a/VERSION-TODO.md b/VERSION-TODO.md index d434ff587..6694b146f 100644 --- a/VERSION-TODO.md +++ b/VERSION-TODO.md @@ -219,6 +219,18 @@ Please give feedback on the upcoming changes if you have concerns about breaking ## 0.61.6 +* Add: `HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES` default `true` and + `HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES` default `true`. When `false` then + corresponding reference link text in heading text used for generating heading id is not + trimmed. +* Add: `HtmlRenderer.HEADER_ID_ADD_EMOJI_SHORTCUT` default `false` When `true` then emjoi nodes + add emoji shortcut to collected text for heading id. +* Fix: `ParserEmulationProfile.GITHUB` + * Set `HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES` to `false` because GitHub does + not trim trailing spaces for generating heading ids. + * `Emoji` node to generate text for heading id consisting of the emoji shortcut, for GitHub + compatibility. + * Fix: `ImageRef` not to add text to heading text for heading id generation * Fix: add more information to `MarkdownParagraph.resolveTrackedOffsetsEdit` assert failures to allow better diagnostics in reported stack traces. * Fix: disable wrapping of multiline URL image links @@ -227,11 +239,13 @@ Please give feedback on the upcoming changes if you have concerns about breaking parsing. * Fix: `TablesExtension` to accept non-indenting leading spaces on all table rows. This results in previously non-table text as valid table texts: - + ```markdown Abc|Def |---|--- ``` +* Fix: `LinkRef` and `ImageRef` changing spaces to ` ` for wrap formatting when not part of + a `Paragraph`, ie. in heading text. ## 0.61.4 diff --git a/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/ComboExtraSpec2Test.java b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/ComboExtraSpec2Test.java new file mode 100644 index 000000000..8475b54d0 --- /dev/null +++ b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/ComboExtraSpec2Test.java @@ -0,0 +1,29 @@ +package com.vladsch.flexmark.core.test.util.renderer; + +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.test.util.spec.ResourceLocation; +import com.vladsch.flexmark.test.util.spec.SpecExample; +import com.vladsch.flexmark.util.data.DataHolder; +import com.vladsch.flexmark.util.data.MutableDataSet; +import org.jetbrains.annotations.NotNull; +import org.junit.runners.Parameterized; + +import java.util.List; + +final public class ComboExtraSpec2Test extends CoreRendererSpecTest { + final private static String SPEC_RESOURCE = "/core_extra_ast_spec2.md"; + final public static @NotNull ResourceLocation RESOURCE_LOCATION = ResourceLocation.of(SPEC_RESOURCE); + + final private static DataHolder OPTIONS = new MutableDataSet() + .set(HtmlRenderer.PERCENT_ENCODE_URLS, true) + .toImmutable(); + + public ComboExtraSpec2Test(@NotNull SpecExample example) { + super(example, null, OPTIONS); + } + + @Parameterized.Parameters(name = "{0}") + public static List data() { + return getTestData(RESOURCE_LOCATION); + } +} diff --git a/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererSpecTest.java b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererSpecTest.java index 1cf50d9b8..b0a57c121 100644 --- a/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererSpecTest.java +++ b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererSpecTest.java @@ -24,6 +24,23 @@ public abstract class CoreRendererSpecTest extends RendererSpecTest { static { ArrayList userTags = new ArrayList<>(Parser.HTML_BLOCK_TAGS.get(null)); userTags.add("tag"); + optionsMap.put("heading-ids", new MutableDataSet().set(HtmlRenderer.RENDER_HEADER_ID, true)); + optionsMap.put("heading-ids-no-dupe-dashes", new MutableDataSet().set(HtmlRenderer.HEADER_ID_GENERATOR_NO_DUPED_DASHES, true)); + optionsMap.put("heading-ids-no-non-ascii-lowercase", new MutableDataSet().set(HtmlRenderer.HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE, false)); + optionsMap.put("heading-ids-no-trim-start", new MutableDataSet().set(HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES, false)); + optionsMap.put("heading-ids-no-trim-end", new MutableDataSet().set(HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES, false)); + optionsMap.put("heading-ids-emoji", new MutableDataSet().set(HtmlRenderer.HEADER_ID_ADD_EMOJI_SHORTCUT, true)); + optionsMap.put("heading-ids-github", new MutableDataSet() + .set(HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS, " -") + .set(HtmlRenderer.HEADER_ID_GENERATOR_NON_DASH_CHARS, "_") + .set(HtmlRenderer.HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE, false) + + // GitHub does not trim trailing spaces of Ref Links in Headings for ID generation + .set(HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES, false) + // GitHub adds emoji shortcut text to heading id + .set(HtmlRenderer.HEADER_ID_ADD_EMOJI_SHORTCUT, true) + ); + optionsMap.put("user-block-tags", new MutableDataSet().set(Parser.HTML_BLOCK_TAGS, userTags)); optionsMap.put("obfuscate-email", new MutableDataSet().set(HtmlRenderer.OBFUSCATE_EMAIL, true)); optionsMap.put("keep-blank-lines", new MutableDataSet().set(Parser.BLANK_LINES_IN_AST, true)); diff --git a/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererTestSuite.java b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererTestSuite.java index f546f8060..9e8fc72dc 100644 --- a/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererTestSuite.java +++ b/flexmark-core-test/src/test/java/com/vladsch/flexmark/core/test/util/renderer/CoreRendererTestSuite.java @@ -6,6 +6,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ ComboExtraSpecTest.class, + ComboExtraSpec2Test.class, CoreCompatibilityTestSuite.class, ComboIssuesSpecTest.class, FullOrigSpecCoreTest.class, diff --git a/flexmark-core-test/src/test/resources/core_extra_ast_spec2.md b/flexmark-core-test/src/test/resources/core_extra_ast_spec2.md new file mode 100644 index 000000000..09042ac30 --- /dev/null +++ b/flexmark-core-test/src/test/resources/core_extra_ast_spec2.md @@ -0,0 +1,636 @@ +--- +title: Extra Core Test Spec +author: Vladimir Schneider +version: 0.2 +date: '2016-06-06' +license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)' +... + +--- + +# Extra tests + +## Flexmark Spec + +## Heading ID + +### Default + +Heading ID option + +```````````````````````````````` example(Heading ID - Default: 1) options(heading-ids) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Default: 2) options(heading-ids) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Default: 3) options(heading-ids) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Default: 4) options(heading-ids) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### No Duped Dashes + +Heading ID option + +```````````````````````````````` example(Heading ID - No Duped Dashes: 1) options(heading-ids, heading-ids-no-dupe-dashes, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes: 2) options(heading-ids, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes: 3) options(heading-ids, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes: 4) options(heading-ids, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### No Lowercase + +Heading ID option + +```````````````````````````````` example(Heading ID - No Lowercase: 1) options(heading-ids, heading-ids-no-non-ascii-lowercase) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Lowercase: 2) options(heading-ids, heading-ids-no-non-ascii-lowercase) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Lowercase: 3) options(heading-ids, heading-ids-no-non-ascii-lowercase) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Lowercase: 4) options(heading-ids, heading-ids-no-non-ascii-lowercase) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### No Duped Dashes, No Lowercase + +Heading ID option + +```````````````````````````````` example(Heading ID - No Duped Dashes, No Lowercase: 1) options(heading-ids, heading-ids-no-non-ascii-lowercase, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes, No Lowercase: 2) options(heading-ids, heading-ids-no-non-ascii-lowercase, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes, No Lowercase: 3) options(heading-ids, heading-ids-no-non-ascii-lowercase, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Duped Dashes, No Lowercase: 4) options(heading-ids, heading-ids-no-non-ascii-lowercase, heading-ids-no-dupe-dashes) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### No Trim End + +Heading ID option + +```````````````````````````````` example(Heading ID - No Trim End: 1) options(heading-ids, heading-ids-no-trim-end) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim End: 2) options(heading-ids, heading-ids-no-trim-end) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim End: 3) options(heading-ids, heading-ids-no-trim-end) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim End: 4) options(heading-ids, heading-ids-no-trim-end) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### No Trim Start + +Heading ID option + +```````````````````````````````` example(Heading ID - No Trim Start: 1) options(heading-ids, heading-ids-no-trim-start) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 160] + Heading[0, 75] textOpen:[0, 2, "##"] text:[3, 75, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 75] referenceOpen:[19, 20, "["] reference:[21, 73, "There is a {} reference showing but is Нет copy-able"] referenceClose:[74, 75, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[77, 158] refOpen:[77, 78, "["] ref:[78, 130, "There is a {} reference showing but is Нет copy-able"] refClose:[130, 132, "]:"] url:[133, 158, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim Start: 2) options(heading-ids, heading-ids-no-trim-start) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 162] + Heading[0, 77] textOpen:[0, 2, "##"] text:[3, 77, "2.0. References [ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 77] referenceOpen:[19, 20, "["] reference:[22, 74, "There is a {} reference showing but is Нет copy-able"] referenceClose:[76, 77, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[79, 160] refOpen:[79, 80, "["] ref:[80, 132, "There is a {} reference showing but is Нет copy-able"] refClose:[132, 134, "]:"] url:[135, 160, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim Start: 3) options(heading-ids, heading-ids-no-trim-start) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 216] + Heading[0, 131] textOpen:[0, 2, "##"] text:[3, 131, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 131] textOpen:[19, 20, "["] text:[21, 73, "There is a {} reference showing but is Нет copy-able"] textClose:[74, 75, "]"] referenceOpen:[75, 76, "["] reference:[77, 129, "There is a {} reference showing but is Нет copy-able"] referenceClose:[130, 131, "]"] + Text[21, 73] chars:[21, 73, "There … -able"] + Reference[133, 214] refOpen:[133, 134, "["] ref:[134, 186, "There is a {} reference showing but is Нет copy-able"] refClose:[186, 188, "]:"] url:[189, 214, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - No Trim Start: 4) options(heading-ids, heading-ids-no-trim-start) +## 2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ] + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

2.0. References There is a {} reference showing but is Нет copy-able

+. +Document[0, 220] + Heading[0, 135] textOpen:[0, 2, "##"] text:[3, 135, "2.0. References [ There is a {} reference showing but is Нет copy-able ][ There is a {} reference showing but is Нет copy-able ]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 135] textOpen:[19, 20, "["] text:[22, 74, "There is a {} reference showing but is Нет copy-able"] textClose:[76, 77, "]"] referenceOpen:[77, 78, "["] reference:[80, 132, "There is a {} reference showing but is Нет copy-able"] referenceClose:[134, 135, "]"] + Text[22, 74] chars:[22, 74, "There … -able"] + Reference[137, 218] refOpen:[137, 138, "["] ref:[138, 190, "There is a {} reference showing but is Нет copy-able"] refClose:[190, 192, "]:"] url:[193, 218, "https://www.example.com/0"] +```````````````````````````````` + + +### Emoji + +Heading ID with emoji + +```````````````````````````````` example(Heading ID - Emoji: 1) options(heading-ids, heading-ids-emoji) +## Heading with some_underscore + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with some_underscore

+. +Document[0, 116] + Heading[0, 31] textOpen:[0, 2, "##"] text:[3, 31, "Heading with some_underscore"] + Text[3, 31] chars:[3, 31, "Headi … score"] + Reference[33, 114] refOpen:[33, 34, "["] ref:[34, 86, "There is a {} reference showing but is Нет copy-able"] refClose:[86, 88, "]:"] url:[89, 114, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Emoji: 2) options(heading-ids, heading-ids-emoji) +## Heading with emoji :information_source: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :information_source:

+. +Document[0, 127] + Heading[0, 42] textOpen:[0, 2, "##"] text:[3, 42, "Heading with emoji :information_source:"] + Text[3, 42] chars:[3, 42, "Headi … urce:"] + Reference[44, 125] refOpen:[44, 45, "["] ref:[45, 97, "There is a {} reference showing but is Нет copy-able"] refClose:[97, 99, "]:"] url:[100, 125, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Emoji: 3) options(heading-ids, heading-ids-emoji) +## Heading with emoji :+1: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :+1:

+. +Document[0, 111] + Heading[0, 26] textOpen:[0, 2, "##"] text:[3, 26, "Heading with emoji :+1:"] + Text[3, 26] chars:[3, 26, "Headi … :+1:"] + Reference[28, 109] refOpen:[28, 29, "["] ref:[29, 81, "There is a {} reference showing but is Нет copy-able"] refClose:[81, 83, "]:"] url:[84, 109, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Emoji: 4) options(heading-ids, heading-ids-emoji) +## Heading with emoji :-1: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :-1:

+. +Document[0, 111] + Heading[0, 26] textOpen:[0, 2, "##"] text:[3, 26, "Heading with emoji :-1:"] + Text[3, 26] chars:[3, 26, "Headi … :-1:"] + Reference[28, 109] refOpen:[28, 29, "["] ref:[29, 81, "There is a {} reference showing but is Нет copy-able"] refClose:[81, 83, "]:"] url:[84, 109, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Emoji: 5) options(heading-ids, heading-ids-emoji) +## Heading with emoji :100: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :100:

+. +Document[0, 112] + Heading[0, 27] textOpen:[0, 2, "##"] text:[3, 27, "Heading with emoji :100:"] + Text[3, 27] chars:[3, 27, "Headi … :100:"] + Reference[29, 110] refOpen:[29, 30, "["] ref:[30, 82, "There is a {} reference showing but is Нет copy-able"] refClose:[82, 84, "]:"] url:[85, 110, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - Emoji: 6) options(heading-ids, heading-ids-emoji) +## Heading with emoji :u5272: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :u5272:

+. +Document[0, 114] + Heading[0, 29] textOpen:[0, 2, "##"] text:[3, 29, "Heading with emoji :u5272:"] + Text[3, 29] chars:[3, 29, "Headi … 5272:"] + Reference[31, 112] refOpen:[31, 32, "["] ref:[32, 84, "There is a {} reference showing but is Нет copy-able"] refClose:[84, 86, "]:"] url:[87, 112, "https://www.example.com/0"] +```````````````````````````````` + + +### GitHub + +Heading ID with emoji + +```````````````````````````````` example(Heading ID - GitHub: 1) options(heading-ids, heading-ids-github) +## Heading with some_underscore + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with some_underscore

+. +Document[0, 116] + Heading[0, 31] textOpen:[0, 2, "##"] text:[3, 31, "Heading with some_underscore"] + Text[3, 31] chars:[3, 31, "Headi … score"] + Reference[33, 114] refOpen:[33, 34, "["] ref:[34, 86, "There is a {} reference showing but is Нет copy-able"] refClose:[86, 88, "]:"] url:[89, 114, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - GitHub: 2) options(heading-ids, heading-ids-github) +## Heading with emoji :information_source: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :information_source:

+. +Document[0, 127] + Heading[0, 42] textOpen:[0, 2, "##"] text:[3, 42, "Heading with emoji :information_source:"] + Text[3, 42] chars:[3, 42, "Headi … urce:"] + Reference[44, 125] refOpen:[44, 45, "["] ref:[45, 97, "There is a {} reference showing but is Нет copy-able"] refClose:[97, 99, "]:"] url:[100, 125, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - GitHub: 3) options(heading-ids, heading-ids-github) +## Heading with emoji :+1: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :+1:

+. +Document[0, 111] + Heading[0, 26] textOpen:[0, 2, "##"] text:[3, 26, "Heading with emoji :+1:"] + Text[3, 26] chars:[3, 26, "Headi … :+1:"] + Reference[28, 109] refOpen:[28, 29, "["] ref:[29, 81, "There is a {} reference showing but is Нет copy-able"] refClose:[81, 83, "]:"] url:[84, 109, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - GitHub: 4) options(heading-ids, heading-ids-github) +## Heading with emoji :-1: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :-1:

+. +Document[0, 111] + Heading[0, 26] textOpen:[0, 2, "##"] text:[3, 26, "Heading with emoji :-1:"] + Text[3, 26] chars:[3, 26, "Headi … :-1:"] + Reference[28, 109] refOpen:[28, 29, "["] ref:[29, 81, "There is a {} reference showing but is Нет copy-able"] refClose:[81, 83, "]:"] url:[84, 109, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - GitHub: 5) options(heading-ids, heading-ids-github) +## Heading with emoji :100: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :100:

+. +Document[0, 112] + Heading[0, 27] textOpen:[0, 2, "##"] text:[3, 27, "Heading with emoji :100:"] + Text[3, 27] chars:[3, 27, "Headi … :100:"] + Reference[29, 110] refOpen:[29, 30, "["] ref:[30, 82, "There is a {} reference showing but is Нет copy-able"] refClose:[82, 84, "]:"] url:[85, 110, "https://www.example.com/0"] +```````````````````````````````` + + +```````````````````````````````` example(Heading ID - GitHub: 6) options(heading-ids, heading-ids-github) +## Heading with emoji :u5272: + +[There is a {} reference showing but is Нет copy-able]: https://www.example.com/0 + +. +

Heading with emoji :u5272:

+. +Document[0, 114] + Heading[0, 29] textOpen:[0, 2, "##"] text:[3, 29, "Heading with emoji :u5272:"] + Text[3, 29] chars:[3, 29, "Headi … 5272:"] + Reference[31, 112] refOpen:[31, 32, "["] ref:[32, 84, "There is a {} reference showing but is Нет copy-able"] refClose:[84, 86, "]:"] url:[87, 112, "https://www.example.com/0"] +```````````````````````````````` + + diff --git a/flexmark-docx-converter/src/test/resources/docx_converter_issues_ast_spec.md b/flexmark-docx-converter/src/test/resources/docx_converter_issues_ast_spec.md index dfe2fe862..a57d95d6a 100644 --- a/flexmark-docx-converter/src/test/resources/docx_converter_issues_ast_spec.md +++ b/flexmark-docx-converter/src/test/resources/docx_converter_issues_ast_spec.md @@ -2420,7 +2420,7 @@ TEXT :+1: TEXT . - + @@ -2470,7 +2470,7 @@ TEXT :+1: TEXT - + @@ -2520,7 +2520,7 @@ TEXT :+1: TEXT - + @@ -2570,7 +2570,7 @@ TEXT :+1: TEXT - + @@ -2620,7 +2620,7 @@ TEXT :+1: TEXT - + @@ -2670,7 +2670,7 @@ TEXT :+1: TEXT - + @@ -3514,7 +3514,7 @@ TEXT :basecamp: TEXT . - + @@ -3564,7 +3564,7 @@ TEXT :basecamp: TEXT - + @@ -3614,7 +3614,7 @@ TEXT :basecamp: TEXT - + @@ -3664,7 +3664,7 @@ TEXT :basecamp: TEXT - + @@ -3714,7 +3714,7 @@ TEXT :basecamp: TEXT - + @@ -3764,7 +3764,7 @@ TEXT :basecamp: TEXT - + @@ -3886,7 +3886,7 @@ TEXT :+1: TEXT . - + @@ -3899,7 +3899,7 @@ TEXT :+1: TEXT 👍 - + @@ -3912,7 +3912,7 @@ TEXT :+1: TEXT 👍 - + @@ -3925,7 +3925,7 @@ TEXT :+1: TEXT 👍 - + @@ -3938,7 +3938,7 @@ TEXT :+1: TEXT 👍 - + @@ -3951,7 +3951,7 @@ TEXT :+1: TEXT 👍 - + 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 f3ca765e2..9e76cdbed 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 @@ -23,7 +23,8 @@ The attributes is a space separated list of attribute syntax of one of the follo +--> + **NOTE**: Handling of multiple value assignment for attributes depends on its name: * `class` values are accumulated as a space (` `) separated list. @@ -1592,7 +1593,7 @@ Document[0, 15] Heading with emoji :+1: ======================= . -

Heading with emoji emoji people:+1

+

Heading with emoji emoji people:+1

. Document[0, 47] Heading[0, 47] text:[0, 23, "Heading with emoji :+1:"] textClose:[24, 47, "======================="] @@ -1602,7 +1603,21 @@ Document[0, 47] ```````````````````````````````` -```````````````````````````````` example(Headings Tests: 3) options(no-text-attributes) +```````````````````````````````` example Headings Tests: 3 +Heading with emoji :-1: +======================= +. +

Heading with emoji emoji people:-1

+. +Document[0, 47] + Heading[0, 47] text:[0, 23, "Heading with emoji :-1:"] textClose:[24, 47, "======================="] + Text[0, 19] chars:[0, 19, "Headi … moji "] + Emoji[19, 23] textOpen:[19, 20, ":"] text:[20, 22, "-1"] textClose:[22, 23, ":"] + Text[20, 22] chars:[20, 22, "-1"] +```````````````````````````````` + + +```````````````````````````````` example(Headings Tests: 4) options(no-text-attributes) Heading{#id1} with multiple{#id2} anchors{#id3} =============================================== . @@ -1622,7 +1637,7 @@ Document[0, 95] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 4 +```````````````````````````````` example Headings Tests: 5 Heading{#id1} with multiple{#id2} anchors{#id3} =============================================== . @@ -1645,7 +1660,7 @@ Document[0, 95] ```````````````````````````````` -```````````````````````````````` example(Headings Tests: 5) options(no-text-attributes) +```````````````````````````````` example(Headings Tests: 6) options(no-text-attributes) Heading{#id1} with multiple{#id2 style="color:red"} anchors{#id3} ================================================================= . @@ -1666,7 +1681,7 @@ Document[0, 131] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 6 +```````````````````````````````` example Headings Tests: 7 Heading{#id1} with multiple{#id2 style="color:red"} anchors{#id3} ================================================================= . @@ -1690,7 +1705,7 @@ Document[0, 131] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 7 +```````````````````````````````` example Headings Tests: 8 Heading{#id1} with multiple{#id2 style="color:red"} anchors{#id3} {#id4} ======================================================================== . @@ -1716,7 +1731,7 @@ Document[0, 145] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 8 +```````````````````````````````` example Headings Tests: 9 ### Heading with trailing { style='color:red' } More Text .

Heading with trailing More Text

@@ -1731,7 +1746,7 @@ Document[0, 57] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 9 +```````````````````````````````` example Headings Tests: 10 ### Heading with trailing{ style='color:red' } More Text .

Heading with trailing More Text

@@ -1746,7 +1761,7 @@ Document[0, 56] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 10 +```````````````````````````````` example Headings Tests: 11 ### Heading with trailing{ style='color:red' } .

Heading with trailing

@@ -1760,7 +1775,7 @@ Document[0, 46] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 11 +```````````````````````````````` example Headings Tests: 12 ### Heading {#explicit-id} .

Heading

@@ -1773,7 +1788,7 @@ Document[0, 26] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 12 +```````````````````````````````` example Headings Tests: 13 ### Heading{#explicit-id} .

Heading

@@ -1787,7 +1802,7 @@ Document[0, 25] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 13 +```````````````````````````````` example Headings Tests: 14 Heading {#explicit-id} ============== . @@ -1801,7 +1816,7 @@ Document[0, 37] ```````````````````````````````` -```````````````````````````````` example Headings Tests: 14 +```````````````````````````````` example Headings Tests: 15 Heading{#explicit-id} ============== . @@ -2860,12 +2875,13 @@ Document[0, 35]
. Document[0, 35] - FencedCodeBlock[0, 15] open:[0, 3, "```"] info:[3, 11, "plantuml"] lines[0] close:[12, 15, "```"] - Paragraph[16, 35] - AttributesNode[16, 35] textOpen:[16, 17, "{"] text:[17, 34, "caption=\"Caption\""] textClose:[34, 35, "}"] - AttributeNode[17, 34] name:[17, 24, "caption"] sep:[24, 25, "="] valueOpen:[25, 26, "\""] value:[26, 33, "Caption"] valueClose:[33, 34, "\""] +FencedCodeBlock[0, 15] open:[0, 3, "```"] info:[3, 11, "plantuml"] lines[0] close:[12, 15, "```"] +Paragraph[16, 35] +AttributesNode[16, 35] textOpen:[16, 17, "{"] text:[17, 34, "caption=\"Caption\""] textClose:[34, 35, "}"] +AttributeNode[17, 34] name:[17, 24, "caption"] sep:[24, 25, "="] valueOpen:[25, 26, "\""] value:[26, 33, "Caption"] valueClose:[33, 34, "\""] ```````````````````````````````` --> + ```````````````````````````````` example(Fenced Code: 20) options(info-attributes, fenced-code-to-code) ```plantuml ``` diff --git a/flexmark-ext-emoji/src/main/java/com/vladsch/flexmark/ext/emoji/Emoji.java b/flexmark-ext-emoji/src/main/java/com/vladsch/flexmark/ext/emoji/Emoji.java index dbf6413fd..06a9e10ee 100644 --- a/flexmark-ext-emoji/src/main/java/com/vladsch/flexmark/ext/emoji/Emoji.java +++ b/flexmark-ext-emoji/src/main/java/com/vladsch/flexmark/ext/emoji/Emoji.java @@ -1,15 +1,19 @@ package com.vladsch.flexmark.ext.emoji; +import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.util.ast.DelimitedNode; -import com.vladsch.flexmark.util.ast.DoNotCollectText; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; +import com.vladsch.flexmark.util.ast.TextContainer; +import com.vladsch.flexmark.util.misc.BitFieldSet; import com.vladsch.flexmark.util.sequence.BasedSequence; +import com.vladsch.flexmark.util.sequence.builder.ISequenceBuilder; import org.jetbrains.annotations.NotNull; /** * An emoji node containing emoji shortcut text */ -public class Emoji extends Node implements DelimitedNode, DoNotCollectText { +public class Emoji extends Node implements DelimitedNode, TextContainer { protected BasedSequence openingMarker = BasedSequence.NULL; protected BasedSequence text = BasedSequence.NULL; protected BasedSequence closingMarker = BasedSequence.NULL; @@ -62,4 +66,14 @@ public BasedSequence getClosingMarker() { public void setClosingMarker(BasedSequence closingMarker) { this.closingMarker = closingMarker; } + + @Override + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { + if (BitFieldSet.any(flags, F_FOR_HEADING_ID)) { + if (HtmlRenderer.HEADER_ID_ADD_EMOJI_SHORTCUT.get(getDocument())) { + out.append(text); + } + } + return false; + } } diff --git a/flexmark-ext-typographic/src/main/java/com/vladsch/flexmark/ext/typographic/TypographicSmarts.java b/flexmark-ext-typographic/src/main/java/com/vladsch/flexmark/ext/typographic/TypographicSmarts.java index 44e066522..1f0e42527 100644 --- a/flexmark-ext-typographic/src/main/java/com/vladsch/flexmark/ext/typographic/TypographicSmarts.java +++ b/flexmark-ext-typographic/src/main/java/com/vladsch/flexmark/ext/typographic/TypographicSmarts.java @@ -2,6 +2,7 @@ import com.vladsch.flexmark.util.ast.DoNotAttributeDecorate; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TypographicText; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; @@ -34,7 +35,7 @@ public TypographicSmarts(BasedSequence chars, String typographicText) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (any(flags, F_NODE_TEXT)) { out.append(getChars()); } else { diff --git a/flexmark-ext-wikilink/src/main/java/com/vladsch/flexmark/ext/wikilink/WikiNode.java b/flexmark-ext-wikilink/src/main/java/com/vladsch/flexmark/ext/wikilink/WikiNode.java index fe41c8410..fd579c1f7 100644 --- a/flexmark-ext-wikilink/src/main/java/com/vladsch/flexmark/ext/wikilink/WikiNode.java +++ b/flexmark-ext-wikilink/src/main/java/com/vladsch/flexmark/ext/wikilink/WikiNode.java @@ -2,6 +2,7 @@ import com.vladsch.flexmark.util.ast.DoNotDecorate; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.misc.CharPredicate; import com.vladsch.flexmark.util.sequence.BasedSequence; @@ -212,7 +213,7 @@ public void setLinkChars(BasedSequence linkChars, boolean allowAnchors, boolean } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { int urlType = flags & F_LINK_TEXT_TYPE; BasedSequence text; diff --git a/flexmark-formatter-test-suite/src/test/java/com/vladsch/flexmark/formatter/test/suite/ComboFormatterIssueSpecTest.java b/flexmark-formatter-test-suite/src/test/java/com/vladsch/flexmark/formatter/test/suite/ComboFormatterIssueSpecTest.java index 77ee83d08..5930cd79b 100644 --- a/flexmark-formatter-test-suite/src/test/java/com/vladsch/flexmark/formatter/test/suite/ComboFormatterIssueSpecTest.java +++ b/flexmark-formatter-test-suite/src/test/java/com/vladsch/flexmark/formatter/test/suite/ComboFormatterIssueSpecTest.java @@ -47,10 +47,7 @@ import org.jetbrains.annotations.Nullable; import org.junit.runners.Parameterized; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class ComboFormatterIssueSpecTest extends FormatterSpecTest { final private static String SPEC_RESOURCE = "/formatter_issue_test_suite_spec.md"; @@ -94,6 +91,7 @@ public class ComboFormatterIssueSpecTest extends FormatterSpecTest { optionsMap.put("use-builder", new MutableDataSet().set(USE_BUILDER, true)); optionsMap.put("spacer", new MutableDataSet().set(TocExtension.BLANK_LINE_SPACER, true)); optionsMap.put("text-only", new MutableDataSet().set(TocExtension.IS_TEXT_ONLY, true)); + optionsMap.put("no-anchor-links", new MutableDataSet().set(UNLOAD_EXTENSIONS, Collections.singletonList(AnchorLinkExtension.class))); optionsMap.put("no-append-references", new MutableDataSet().set(Formatter.APPEND_TRANSFERRED_REFERENCES, false) .set(TestUtils.INCLUDED_DOCUMENT, "" + diff --git a/flexmark-formatter-test-suite/src/test/resources/formatter_issue_test_suite_spec.md b/flexmark-formatter-test-suite/src/test/resources/formatter_issue_test_suite_spec.md index 997ba7f1e..5d55b926d 100644 --- a/flexmark-formatter-test-suite/src/test/resources/formatter_issue_test_suite_spec.md +++ b/flexmark-formatter-test-suite/src/test/resources/formatter_issue_test_suite_spec.md @@ -376,3 +376,45 @@ Text wrapping pipe `|` should be escaped when ```````````````````````````````` +### xxx-06 + +Make sure ` ` is not left in heading reference links + +```````````````````````````````` example(Issue - xxx-06: 1) options(margin[46], no-anchor-links) +## 2.0. References [There is a {} reference showing but is not copy-able] +[There is a {} reference showing but is not copy-able]: https://www.example.com/0 +. +## 2.0. References [There is a {} reference showing but is not copy-able] + +[There is a {} reference showing but is not copy-able]: https://www.example.com/0 + +. +Document[0, 155] + Heading[0, 73] textOpen:[0, 2, "##"] text:[3, 73, "2.0. References [There is a {} reference showing but is not copy-able]"] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 73] referenceOpen:[19, 20, "["] reference:[20, 72, "There is a {} reference showing but is not copy-able"] referenceClose:[72, 73, "]"] + Text[20, 72] chars:[20, 72, "There … -able"] + Reference[74, 155] refOpen:[74, 75, "["] ref:[75, 127, "There is a {} reference showing but is not copy-able"] refClose:[127, 129, "]:"] url:[130, 155, "https://www.example.com/0"] +```````````````````````````````` + +all is fine with anchor links + +```````````````````````````````` example(Issue - xxx-06: 2) options(margin[46]) +## 2.0. References [There is a {} reference showing but is not copy-able] +[There is a {} reference showing but is not copy-able]: https://www.example.com/0 +. +## 2.0. References [There is a {} reference showing but is not copy-able] + +[There is a {} reference showing but is not copy-able]: https://www.example.com/0 + +. +Document[0, 155] + Heading[0, 73] textOpen:[0, 2, "##"] text:[3, 73, "2.0. References [There is a {} reference showing but is not copy-able]"] + AnchorLink[3, 73] + Text[3, 19] chars:[3, 19, "2.0. … nces "] + LinkRef[19, 73] referenceOpen:[19, 20, "["] reference:[20, 72, "There is a {} reference showing but is not copy-able"] referenceClose:[72, 73, "]"] + Text[20, 72] chars:[20, 72, "There … -able"] + Reference[74, 155] refOpen:[74, 75, "["] ref:[75, 127, "There is a {} reference showing but is not copy-able"] refClose:[127, 129, "]:"] url:[130, 155, "https://www.example.com/0"] +```````````````````````````````` + + diff --git a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/DelimitedNode.java b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/DelimitedNode.java index 374c0f065..9cc4bad4c 100644 --- a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/DelimitedNode.java +++ b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/DelimitedNode.java @@ -21,7 +21,7 @@ public interface DelimitedNode extends TextContainer { void setClosingMarker(BasedSequence closingMarker); @Override - default boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + default boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (any(flags, F_NODE_TEXT)) { out.append(getText()); return false; diff --git a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextCollectingVisitor.java b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextCollectingVisitor.java index 3a990d81d..bff298aca 100644 --- a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextCollectingVisitor.java +++ b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextCollectingVisitor.java @@ -8,7 +8,7 @@ public class TextCollectingVisitor { final private NodeVisitor myVisitor; SpaceInsertingSequenceBuilder out; - int flags; + int flags; // flags defined by TextContainer public TextCollectingVisitor() { myVisitor = new NodeVisitor() { @@ -17,7 +17,7 @@ public void processNode(@NotNull Node node, boolean withChildren, @NotNull BiCon if (!node.isOrDescendantOfType(DoNotCollectText.class)) { if (node instanceof TextContainer) { out.setLastNode(node); - if (((TextContainer) node).collectText(out, flags)) { + if (((TextContainer) node).collectText(out, flags, myVisitor)) { if (node instanceof BlankLineBreakNode && out.isNotEmpty()) { out.appendEol(); } diff --git a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextContainer.java b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextContainer.java index fbf8c5cec..fc19f385e 100644 --- a/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextContainer.java +++ b/flexmark-util-ast/src/main/java/com/vladsch/flexmark/util/ast/TextContainer.java @@ -9,6 +9,9 @@ public interface TextContainer { enum Flags implements BitField { LINK_TEXT_TYPE(3), NODE_TEXT, // not unescaped and not percent decoded + FOR_HEADING_ID, // text for heading ID + NO_TRIM_REF_TEXT_START, // don't trim ref text start + NO_TRIM_REF_TEXT_END, // don't trim ref text end ; final int bits; @@ -28,20 +31,24 @@ public int getBits() { } int F_LINK_TEXT_TYPE = BitFieldSet.intMask(Flags.LINK_TEXT_TYPE); - int F_LINK_TEXT = 0; - int F_LINK_PAGE_REF = 1; - int F_LINK_ANCHOR = 2; - int F_LINK_URL = 3; - int F_LINK_NODE_TEXT = 4; + int F_LINK_TEXT = 0; // use link text + int F_LINK_PAGE_REF = 1; // use page ref + int F_LINK_ANCHOR = 2; // use link anchor + int F_LINK_URL = 3; // use link URL + int F_LINK_NODE_TEXT = 4; // use node text int F_NODE_TEXT = BitFieldSet.intMask(Flags.NODE_TEXT); + int F_FOR_HEADING_ID = BitFieldSet.intMask(Flags.FOR_HEADING_ID); + int F_NO_TRIM_REF_TEXT_START = BitFieldSet.intMask(Flags.NO_TRIM_REF_TEXT_START); + int F_NO_TRIM_REF_TEXT_END = BitFieldSet.intMask(Flags.NO_TRIM_REF_TEXT_END); /** * Append node's text * * @param out sequence build to which to append text * @param flags collection flags + * @param nodeVisitor node visitor to use to visit children * @return true if child nodes should be visited */ - boolean collectText(ISequenceBuilder, BasedSequence> out, int flags); + boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor); } diff --git a/flexmark-util-data/src/main/java/com/vladsch/flexmark/util/data/SharedDataKeys.java b/flexmark-util-data/src/main/java/com/vladsch/flexmark/util/data/SharedDataKeys.java index cbd8e5c5f..004f884ad 100644 --- a/flexmark-util-data/src/main/java/com/vladsch/flexmark/util/data/SharedDataKeys.java +++ b/flexmark-util-data/src/main/java/com/vladsch/flexmark/util/data/SharedDataKeys.java @@ -30,6 +30,9 @@ public class SharedDataKeys { final public static DataKey HEADER_ID_GENERATOR_NON_DASH_CHARS = new DataKey<>("HEADER_ID_GENERATOR_NON_DASH_CHARS", ""); final public static DataKey HEADER_ID_GENERATOR_NO_DUPED_DASHES = new DataKey<>("HEADER_ID_GENERATOR_NO_DUPED_DASHES", false); final public static DataKey HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE = new DataKey<>("HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE", true); + final public static DataKey HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES = new DataKey<>("HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES", true); + final public static DataKey HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES = new DataKey<>("HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES", true); + final public static DataKey HEADER_ID_ADD_EMOJI_SHORTCUT = new DataKey<>("HEADER_ID_ADD_EMOJI_SHORTCUT", false); final public static DataKey RENDER_HEADER_ID = new DataKey<>("RENDER_HEADER_ID", false); final public static DataKey GENERATE_HEADER_ID = new DataKey<>("GENERATE_HEADER_ID", true); final public static DataKey DO_NOT_RENDER_LINKS = new DataKey<>("DO_NOT_RENDER_LINKS", false); diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/Code.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/Code.java index c88b6854f..8f367c6aa 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/Code.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/Code.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ast; import com.vladsch.flexmark.util.ast.DoNotLinkDecorate; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.builder.ISequenceBuilder; import org.jetbrains.annotations.NotNull; @@ -23,7 +24,7 @@ public void getAstExtra(@NotNull StringBuilder out) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { out.append(getText()); return false; } diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/HardLineBreak.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/HardLineBreak.java index 9d410fc94..b3d4dfa7b 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/HardLineBreak.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/HardLineBreak.java @@ -2,6 +2,7 @@ import com.vladsch.flexmark.util.ast.DoNotTrim; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.builder.ISequenceBuilder; @@ -22,7 +23,7 @@ public HardLineBreak(BasedSequence chars) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { BasedSequence chars = getChars(); out.add(chars.subSequence(chars.length() - 1, chars.length())); return false; diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/Heading.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/Heading.java index dc97b5e4f..fcec361ba 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/Heading.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/Heading.java @@ -1,8 +1,10 @@ package com.vladsch.flexmark.ast; +import com.vladsch.flexmark.html.HtmlRenderer; import com.vladsch.flexmark.util.ast.Block; import com.vladsch.flexmark.util.ast.BlockContent; import com.vladsch.flexmark.util.ast.TextCollectingVisitor; +import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import org.jetbrains.annotations.NotNull; @@ -29,7 +31,10 @@ public BasedSequence[] getSegments() { @Override public String getAnchorRefText() { - return new TextCollectingVisitor().collectAndGetText(this).trim(); + boolean trimLeadingSpaces = HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES.get(getDocument()); + boolean trimTrailingSpaces = HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES.get(getDocument()); + + return new TextCollectingVisitor().collectAndGetText(this, TextContainer.F_FOR_HEADING_ID + (trimLeadingSpaces ? 0 : TextContainer.F_NO_TRIM_REF_TEXT_START) + (trimTrailingSpaces ? 0 : TextContainer.F_NO_TRIM_REF_TEXT_END)); } @Override diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/HtmlEntity.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/HtmlEntity.java index 45b53d68f..11c3ed392 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/HtmlEntity.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/HtmlEntity.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ast; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; @@ -36,7 +37,7 @@ public HtmlEntity(BasedSequence chars) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (any(flags, F_NODE_TEXT)) { out.append(getChars()); } else { diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/LinkNode.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/LinkNode.java index 631fe83ed..09cd8e263 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/LinkNode.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/LinkNode.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ast; import com.vladsch.flexmark.util.ast.DoNotLinkDecorate; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; @@ -17,7 +18,7 @@ public LinkNode(BasedSequence chars) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { int urlType = flags & F_LINK_TEXT_TYPE; BasedSequence url; diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/Paragraph.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/Paragraph.java index a6f6b4e55..d828bac0e 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/Paragraph.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/Paragraph.java @@ -2,6 +2,7 @@ import com.vladsch.flexmark.util.ast.Block; import com.vladsch.flexmark.util.ast.BlockContent; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.builder.ISequenceBuilder; @@ -133,7 +134,7 @@ public boolean hasTableSeparator() { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (!out.isEmpty()) { out.add("\n\n"); } diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/RefNode.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/RefNode.java index 241fd7f8d..9c22a947d 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/RefNode.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/RefNode.java @@ -3,6 +3,7 @@ import com.vladsch.flexmark.ast.util.ReferenceRepository; import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.*; +import com.vladsch.flexmark.util.misc.BitFieldSet; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; import com.vladsch.flexmark.util.sequence.ReplacedTextMapper; @@ -210,11 +211,24 @@ public void setReferenceClosingMarker(BasedSequence referenceClosingMarker) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { + // images no longer add alt text + int urlType = flags & F_LINK_TEXT_TYPE; if (urlType == F_LINK_TEXT) { - return true; + // To allow using leading/trailing spaces for generating heading ids, need to include stripped out spaces + if (BitFieldSet.any(flags, F_FOR_HEADING_ID) && this instanceof ImageRef) return false; + + if (BitFieldSet.any(flags, F_FOR_HEADING_ID) && BitFieldSet.any(flags, F_NO_TRIM_REF_TEXT_START | F_NO_TRIM_REF_TEXT_END)) { + BasedSequence[] segments = getSegments(); + if (BitFieldSet.any(flags, F_NO_TRIM_REF_TEXT_START)) out.append(getChars().baseSubSequence(segments[0].getEndOffset(), segments[1].getStartOffset())); + nodeVisitor.visitChildren(this); + if (BitFieldSet.any(flags, F_NO_TRIM_REF_TEXT_END)) out.append(getChars().baseSubSequence(segments[1].getEndOffset(), segments[2].getStartOffset())); + return false; + } else { + return true; + } } else { Reference reference = getReferenceNode(getDocument()); if (urlType == F_LINK_NODE_TEXT) { diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/SoftLineBreak.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/SoftLineBreak.java index 079ae08c4..dcfab2013 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/SoftLineBreak.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/SoftLineBreak.java @@ -1,9 +1,6 @@ package com.vladsch.flexmark.ast; -import com.vladsch.flexmark.util.ast.DoNotAttributeDecorate; -import com.vladsch.flexmark.util.ast.DoNotTrim; -import com.vladsch.flexmark.util.ast.Node; -import com.vladsch.flexmark.util.ast.TextContainer; +import com.vladsch.flexmark.util.ast.*; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.builder.ISequenceBuilder; import org.jetbrains.annotations.NotNull; @@ -47,7 +44,7 @@ public void setCharsFromSegments() { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { out.add(getChars()); return false; } diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/Text.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/Text.java index 583fa1bc6..bf3efff72 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/Text.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/Text.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ast; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; @@ -34,7 +35,7 @@ public BasedSequence[] getSegments() { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (any(flags, F_NODE_TEXT)) { out.append(getChars()); } else { diff --git a/flexmark/src/main/java/com/vladsch/flexmark/ast/TextBase.java b/flexmark/src/main/java/com/vladsch/flexmark/ast/TextBase.java index 7d802c2c5..99616ba98 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/ast/TextBase.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/ast/TextBase.java @@ -1,6 +1,7 @@ package com.vladsch.flexmark.ast; import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.ast.NodeVisitor; import com.vladsch.flexmark.util.ast.TextContainer; import com.vladsch.flexmark.util.sequence.BasedSequence; import com.vladsch.flexmark.util.sequence.Escaping; @@ -34,7 +35,7 @@ public void getAstExtra(@NotNull StringBuilder out) { } @Override - public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags) { + public boolean collectText(ISequenceBuilder, BasedSequence> out, int flags, NodeVisitor nodeVisitor) { if (any(flags, F_NODE_TEXT)) { out.append(getChars()); } else { diff --git a/flexmark/src/main/java/com/vladsch/flexmark/formatter/internal/CoreNodeFormatter.java b/flexmark/src/main/java/com/vladsch/flexmark/formatter/internal/CoreNodeFormatter.java index e409c94c6..4c56e9aa2 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/formatter/internal/CoreNodeFormatter.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/formatter/internal/CoreNodeFormatter.java @@ -910,13 +910,13 @@ private void render(Image node, NodeFormatterContext context, MarkdownWriter mar if (!node.getUrlContent().isEmpty()) { markdown.openPreFormatted(true); markdown.pushOptions().preserveSpaces(); - + if (!context.isTransformingText() && formatterOptions.rightMargin > 0) { CharSequence chars = node.getUrlContent(); int iMax = chars.length(); boolean hadEOL = true; markdown.append('\n'); - + for (int i = 0; i < iMax; i++) { char c = chars.charAt(i); @@ -1056,7 +1056,11 @@ private void render(ImageRef node, NodeFormatterContext context, MarkdownWriter } else { if (node.isReferenceTextCombined()) { markdown.append(node.getReferenceOpeningMarker()); - markdown.append(node.getReference().toMapped(SpaceMapper.toNonBreakSpace)); + if (node.isOrDescendantOfType(Paragraph.class)) { + markdown.append(node.getReference().toMapped(SpaceMapper.toNonBreakSpace)); + } else { + markdown.append(node.getReference()); + } markdown.append(node.getReferenceClosingMarker()); markdown.append(node.getTextOpeningMarker()); @@ -1104,7 +1108,11 @@ private void render(LinkRef node, NodeFormatterContext context, MarkdownWriter m } else { if (node.isReferenceTextCombined()) { markdown.append(node.getReferenceOpeningMarker()); - markdown.append(node.getReference().toMapped(SpaceMapper.toNonBreakSpace)); + if (node.isOrDescendantOfType(Paragraph.class)) { + markdown.append(node.getReference().toMapped(SpaceMapper.toNonBreakSpace)); + } else { + markdown.append(node.getReference()); + } markdown.append(node.getReferenceClosingMarker()); markdown.append(node.getTextOpeningMarker()); diff --git a/flexmark/src/main/java/com/vladsch/flexmark/html/HtmlRenderer.java b/flexmark/src/main/java/com/vladsch/flexmark/html/HtmlRenderer.java index 084b34001..a8be6a443 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/html/HtmlRenderer.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/html/HtmlRenderer.java @@ -61,6 +61,9 @@ public class HtmlRenderer implements IRender { final public static DataKey HEADER_ID_GENERATOR_NON_DASH_CHARS = SharedDataKeys.HEADER_ID_GENERATOR_NON_DASH_CHARS; final public static DataKey HEADER_ID_GENERATOR_NO_DUPED_DASHES = SharedDataKeys.HEADER_ID_GENERATOR_NO_DUPED_DASHES; final public static DataKey HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE = SharedDataKeys.HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE; + final public static DataKey HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES = SharedDataKeys.HEADER_ID_REF_TEXT_TRIM_LEADING_SPACES; + final public static DataKey HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES = SharedDataKeys.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES; + final public static DataKey HEADER_ID_ADD_EMOJI_SHORTCUT = SharedDataKeys.HEADER_ID_ADD_EMOJI_SHORTCUT; final public static DataKey RENDER_HEADER_ID = SharedDataKeys.RENDER_HEADER_ID; final public static DataKey GENERATE_HEADER_ID = SharedDataKeys.GENERATE_HEADER_ID; final public static DataKey DO_NOT_RENDER_LINKS = SharedDataKeys.DO_NOT_RENDER_LINKS; diff --git a/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java b/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java index be21c5c07..502762045 100644 --- a/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java +++ b/flexmark/src/main/java/com/vladsch/flexmark/parser/ParserEmulationProfile.java @@ -381,6 +381,11 @@ public MutableDataHolder setIn(@NotNull MutableDataHolder dataHolder) { .set(HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS, " -") .set(HtmlRenderer.HEADER_ID_GENERATOR_NON_DASH_CHARS, "_") .set(HtmlRenderer.HEADER_ID_GENERATOR_NON_ASCII_TO_LOWERCASE, false) + + // GitHub does not trim trailing spaces of Ref Links in Headings for ID generation + .set(HtmlRenderer.HEADER_ID_REF_TEXT_TRIM_TRAILING_SPACES, false) + // GitHub adds emoji shortcut text to heading id + .set(HtmlRenderer.HEADER_ID_ADD_EMOJI_SHORTCUT, true) ; } else if (this == MULTI_MARKDOWN) { getOptions(dataHolder).setIn(dataHolder);