diff --git a/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue b/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue index f0726ff3e6383c824bee48dbf20928ae046328bc..8caf12eac5f5b0314b578998872a1fde9d2524a6 100644 --- a/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue +++ b/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue @@ -10,6 +10,7 @@ import Code from '../../extensions/code'; import CodeBlockHighlight from '../../extensions/code_block_highlight'; import Diagram from '../../extensions/diagram'; import Frontmatter from '../../extensions/frontmatter'; +import ReferenceDefinition from '../../extensions/reference_definition'; import ToolbarButton from '../toolbar_button.vue'; export default { @@ -35,6 +36,7 @@ export default { Image.name, Audio.name, Video.name, + ReferenceDefinition.name, ]; return !exclude.some((type) => editor.isActive(type)); diff --git a/app/assets/javascripts/content_editor/extensions/reference_definition.js b/app/assets/javascripts/content_editor/extensions/reference_definition.js new file mode 100644 index 0000000000000000000000000000000000000000..e2762fe9fd905617ae4d430fa50966955e18e0e3 --- /dev/null +++ b/app/assets/javascripts/content_editor/extensions/reference_definition.js @@ -0,0 +1,29 @@ +import { Node } from '@tiptap/core'; + +export default Node.create({ + name: 'referenceDefinition', + + group: 'block', + + content: 'text*', + + marks: '', + + addAttributes() { + return { + identifier: { + default: null, + }, + url: { + default: null, + }, + title: { + default: null, + }, + }; + }, + + renderHTML() { + return ['pre', {}, 0]; + }, +}); diff --git a/app/assets/javascripts/content_editor/extensions/sourcemap.js b/app/assets/javascripts/content_editor/extensions/sourcemap.js index 618f17b1c5e7b8479ba3d5effc8d2c17d31b9e7d..fdac852e55c1db6f813cd8c85e1b363134060505 100644 --- a/app/assets/javascripts/content_editor/extensions/sourcemap.js +++ b/app/assets/javascripts/content_editor/extensions/sourcemap.js @@ -16,6 +16,7 @@ import Link from './link'; import ListItem from './list_item'; import OrderedList from './ordered_list'; import Paragraph from './paragraph'; +import ReferenceDefinition from './reference_definition'; import Strike from './strike'; import TaskList from './task_list'; import TaskItem from './task_item'; @@ -45,6 +46,7 @@ export default Extension.create({ ListItem.name, OrderedList.name, Paragraph.name, + ReferenceDefinition.name, Strike.name, TaskList.name, TaskItem.name, diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js index 795355abdab3a8d5090a98a887ba63a718e274d9..7a289df94eaea3285fc46e0fadd8508f1e3a11f2 100644 --- a/app/assets/javascripts/content_editor/services/create_content_editor.js +++ b/app/assets/javascripts/content_editor/services/create_content_editor.js @@ -42,6 +42,7 @@ import OrderedList from '../extensions/ordered_list'; import Paragraph from '../extensions/paragraph'; import PasteMarkdown from '../extensions/paste_markdown'; import Reference from '../extensions/reference'; +import ReferenceDefinition from '../extensions/reference_definition'; import Sourcemap from '../extensions/sourcemap'; import Strike from '../extensions/strike'; import Subscript from '../extensions/subscript'; @@ -128,6 +129,7 @@ export const createContentEditor = ({ Paragraph, PasteMarkdown, Reference, + ReferenceDefinition, Sourcemap, Strike, Subscript, diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js index c1c7af6b1afb65bb6da4ce6a7b87e90f7e3eb1cb..1511f122a15fee5a9af707c9772815c7231c0370 100644 --- a/app/assets/javascripts/content_editor/services/markdown_serializer.js +++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js @@ -33,6 +33,7 @@ import MathInline from '../extensions/math_inline'; import OrderedList from '../extensions/ordered_list'; import Paragraph from '../extensions/paragraph'; import Reference from '../extensions/reference'; +import ReferenceDefinition from '../extensions/reference_definition'; import Strike from '../extensions/strike'; import Subscript from '../extensions/subscript'; import Superscript from '../extensions/superscript'; @@ -177,6 +178,25 @@ const defaultSerializerConfig = { [Reference.name]: (state, node) => { state.write(node.attrs.originalText || node.attrs.text); }, + [ReferenceDefinition.name]: preserveUnchanged({ + render: (state, node, parent, index, same, sourceMarkdown) => { + const nextSibling = parent.maybeChild(index + 1); + + state.text(same ? sourceMarkdown : node.textContent, false); + + /** + * Do not insert a blank line between reference definitions + * because it isn’t necessary and a more compact text format + * is preferred. + */ + if (!nextSibling || nextSibling.type.name !== ReferenceDefinition.name) { + state.closeBlock(node); + } else { + state.ensureNewLine(); + } + }, + overwriteSourcePreservationStrategy: true, + }), [TableOfContents.name]: (state, node) => { state.write('[[_TOC_]]'); state.closeBlock(node); diff --git a/app/assets/javascripts/content_editor/services/remark_markdown_deserializer.js b/app/assets/javascripts/content_editor/services/remark_markdown_deserializer.js index 8e2c066e011e9c65c3973568eca8372888ccca6b..22cca4bd72f5f1e77ab7bb444607f745dd6c1cc7 100644 --- a/app/assets/javascripts/content_editor/services/remark_markdown_deserializer.js +++ b/app/assets/javascripts/content_editor/services/remark_markdown_deserializer.js @@ -170,6 +170,16 @@ const factorySpecs = { type: 'ignore', selector: (hastNode) => hastNode.type === 'comment', }, + + referenceDefinition: { + type: 'block', + selector: 'referencedefinition', + getAttrs: (node) => ({ + title: node.properties.title, + url: node.properties.url, + identifier: node.properties.identifier, + }), + }, }; export default () => { @@ -185,7 +195,7 @@ export default () => { wrappableTags, markdown, }), - skipRendering: ['footnoteReference', 'footnoteDefinition', 'code'], + skipRendering: ['footnoteReference', 'footnoteDefinition', 'code', 'definition'], }); return { document }; diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js index 7d5e718b41cfa613c2b3de3ac8608c285bdf72d3..97bad375aea1f2c6b2bdcedff7af9232cf0c17f9 100644 --- a/app/assets/javascripts/content_editor/services/serialization_helpers.js +++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js @@ -1,4 +1,4 @@ -import { uniq, isString, omit } from 'lodash'; +import { uniq, isString, omit, isFunction } from 'lodash'; const defaultAttrs = { td: { colspan: 1, rowspan: 1, colwidth: null }, @@ -327,16 +327,25 @@ export function renderCodeBlock(state, node) { state.closeBlock(node); } -export function preserveUnchanged(render) { +const expandPreserveUnchangedConfig = (configOrRender) => + isFunction(configOrRender) + ? { render: configOrRender, overwriteSourcePreservationStrategy: false } + : configOrRender; + +export function preserveUnchanged(configOrRender) { return (state, node, parent, index) => { + const { render, overwriteSourcePreservationStrategy } = expandPreserveUnchangedConfig( + configOrRender, + ); + const { sourceMarkdown } = node.attrs; const same = state.options.changeTracker.get(node); - if (same) { + if (same && !overwriteSourcePreservationStrategy) { state.write(sourceMarkdown); state.closeBlock(node); } else { - render(state, node, parent, index); + render(state, node, parent, index, same, sourceMarkdown); } }; } diff --git a/app/assets/javascripts/lib/gfm/index.js b/app/assets/javascripts/lib/gfm/index.js index 92118c8929f1be520613b6fff5fb574bc3bc20ef..05534401a2a27162f3d6c9b2723aa5136775e1f6 100644 --- a/app/assets/javascripts/lib/gfm/index.js +++ b/app/assets/javascripts/lib/gfm/index.js @@ -19,6 +19,16 @@ const skipRenderingHandlers = { h(node.position, 'codeBlock', { language: node.lang, meta: node.meta }, [ { type: 'text', value: node.value }, ]), + definition: (h, node) => { + const title = node.title ? ` "${node.title}"` : ''; + + return h( + node.position, + 'referenceDefinition', + { identifier: node.identifier, url: node.url, title: node.title }, + [{ type: 'text', value: `[${node.identifier}]: ${node.url}${title}` }], + ); + }, }; const createParser = ({ skipRendering = [] }) => { diff --git a/glfm_specification/example_snapshots/html.yml b/glfm_specification/example_snapshots/html.yml index 834dd49a93458db61b078256b74fa8bb59fd33c5..105a0d26409f9721cdb93052ae8ce6f3b54b3fcb 100644 --- a/glfm_specification/example_snapshots/html.yml +++ b/glfm_specification/example_snapshots/html.yml @@ -2144,6 +2144,7 @@ static: |- <p data-sourcepos="3:1-3:5" dir="auto"><a href="/url" title="title">foo</a></p> wysiwyg: |- + <pre>[foo]: /url "title"</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__002: canonical: | @@ -2151,6 +2152,7 @@ static: |- <p data-sourcepos="5:1-5:5" dir="auto"><a href="/url" title="the title">foo</a></p> wysiwyg: |- + <pre>[foo]: /url "the title"</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="the title">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__003: canonical: | @@ -2158,6 +2160,7 @@ static: |- <p data-sourcepos="3:1-3:11" dir="auto"><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p> wysiwyg: |- + <pre>[foo*bar\]]: my_(url) "title (with parens)"</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="my_(url)" title="title (with parens)">Foo*bar]</a></p> 04_07__leaf_blocks__link_reference_definitions__004: canonical: | @@ -2165,6 +2168,7 @@ static: |- <p data-sourcepos="5:1-5:9" dir="auto"><a href="my%20url" title="title">Foo bar</a></p> wysiwyg: |- + <pre>[foo bar]: my url "title"</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="my%20url" title="title">Foo bar</a></p> 04_07__leaf_blocks__link_reference_definitions__005: canonical: | @@ -2180,6 +2184,11 @@ line2 ">foo</a></p> wysiwyg: |- + <pre>[foo]: /url " + title + line1 + line2 + "</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title=" title line1 @@ -2204,6 +2213,7 @@ static: |- <p data-sourcepos="4:1-4:5" dir="auto"><a href="/url">foo</a></p> wysiwyg: |- + <pre>[foo]: /url</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__008: canonical: | @@ -2221,6 +2231,7 @@ static: |- <p data-sourcepos="3:1-3:5" dir="auto"><a href="">foo</a></p> wysiwyg: |- + <pre>[foo]: </pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__010: canonical: | @@ -2238,6 +2249,7 @@ static: |- <p data-sourcepos="3:1-3:5" dir="auto"><a href="/url%5Cbar*baz" title='foo"bar\baz'>foo</a></p> wysiwyg: |- + <pre>[foo]: /url\bar*baz "foo"bar\baz"</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url%5Cbar*baz" title="foo"bar\baz">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__012: canonical: | @@ -2246,6 +2258,7 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="url">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="url">foo</a></p> + <pre>[foo]: url</pre> 04_07__leaf_blocks__link_reference_definitions__013: canonical: | <p><a href="first">foo</a></p> @@ -2253,12 +2266,15 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="first">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="first">foo</a></p> + <pre>[foo]: first</pre> + <pre>[foo]: second</pre> 04_07__leaf_blocks__link_reference_definitions__014: canonical: | <p><a href="/url">Foo</a></p> static: |- <p data-sourcepos="3:1-3:5" dir="auto"><a href="/url">Foo</a></p> wysiwyg: |- + <pre>[foo]: /url</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">Foo</a></p> 04_07__leaf_blocks__link_reference_definitions__015: canonical: | @@ -2266,18 +2282,20 @@ static: |- <p data-sourcepos="3:1-3:8" dir="auto"><a href="/%CF%86%CE%BF%CF%85">αγω</a></p> wysiwyg: |- + <pre>[αγω]: /φου</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/%CF%86%CE%BF%CF%85">αγω</a></p> 04_07__leaf_blocks__link_reference_definitions__016: canonical: "" static: "" wysiwyg: |- - <p></p> + <pre>[foo]: /url</pre> 04_07__leaf_blocks__link_reference_definitions__017: canonical: | <p>bar</p> static: |- <p data-sourcepos="1:1-4:3" dir="auto">bar</p> wysiwyg: |- + <pre>[foo]: /url</pre> <p>bar</p> 04_07__leaf_blocks__link_reference_definitions__018: canonical: | @@ -2292,6 +2310,7 @@ static: |- <p data-sourcepos="1:1-2:10" dir="auto">"title" ok</p> wysiwyg: |- + <pre>[foo]: /url</pre> <p>"title" ok</p> 04_07__leaf_blocks__link_reference_definitions__020: canonical: | @@ -2349,6 +2368,7 @@ </blockquote> wysiwyg: |- <h1><a target="_blank" rel="noopener noreferrer nofollow" href="/url">Foo</a></h1> + <pre>[foo]: /url</pre> <blockquote multiline="false"><p>bar</p></blockquote> 04_07__leaf_blocks__link_reference_definitions__024: canonical: | @@ -2359,6 +2379,7 @@ <a id="user-content-bar" class="anchor" href="#bar" aria-hidden="true"></a>bar</h1> <p data-sourcepos="4:1-4:5" dir="auto"><a href="/url">foo</a></p> wysiwyg: |- + <pre>[foo]: /url</pre> <h1>bar</h1> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__025: @@ -2369,6 +2390,7 @@ <p data-sourcepos="1:1-3:5" dir="auto">=== <a href="/url">foo</a></p> wysiwyg: |- + <pre>[foo]: /url</pre> <p>=== <a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a></p> 04_07__leaf_blocks__link_reference_definitions__026: @@ -2381,6 +2403,9 @@ <a href="/bar-url" title="bar">bar</a>, <a href="/baz-url">baz</a></p> wysiwyg: |- + <pre>[foo]: /foo-url "foo"</pre> + <pre>[bar]: /bar-url "bar"</pre> + <pre>[baz]: /baz-url</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/foo-url" title="foo">foo</a>, <a target="_blank" rel="noopener noreferrer nofollow" href="/bar-url" title="bar">bar</a>, <a target="_blank" rel="noopener noreferrer nofollow" href="/baz-url">baz</a></p> @@ -2395,12 +2420,12 @@ </blockquote> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a></p> - <blockquote multiline="false"><p></p></blockquote> + <blockquote multiline="false"><pre>[foo]: /url</pre></blockquote> 04_07__leaf_blocks__link_reference_definitions__028: canonical: "" static: "" wysiwyg: |- - <p></p> + <pre>[foo]: /url</pre> 04_08__leaf_blocks__paragraphs__001: canonical: | <p>aaa</p> @@ -4543,7 +4568,7 @@ </li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>a</p></li><li><p>b</p></li><li><p>d</p></li></ul> + <ul bullet="*"><li><p>a</p></li><li><p>b</p><pre>[ref]: /url</pre></li><li><p>d</p></li></ul> 05_04__container_blocks__lists__018: canonical: | <ul> @@ -4880,6 +4905,7 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="/bar*" title="ti*tle">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/bar*" title="ti*tle">foo</a></p> + <pre>[foo]: /bar* "ti*tle"</pre> 06_02__inlines__backslash_escapes__013: canonical: | <pre><code class="language-foo+bar">foo @@ -4969,6 +4995,7 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/f%C3%B6%C3%B6" title="föö">foo</a></p> + <pre>[foo]: /föö "föö"</pre> 06_03__inlines__entity_and_numeric_character_references__010: canonical: | <pre><code class="language-föö">foo @@ -6475,6 +6502,7 @@ <p data-sourcepos="1:1-1:10" dir="auto"><a href="/url" title="title">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> + <pre>[bar]: /url "title"</pre> 06_07__inlines__links__044: canonical: | <p><a href="/uri">link [foo [bar]]</a></p> @@ -6482,6 +6510,7 @@ <p data-sourcepos="1:1-1:23" dir="auto"><a href="/uri">link [foo [bar]]</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">link [foo [bar]]</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__045: canonical: | <p><a href="/uri">link [bar</a></p> @@ -6489,6 +6518,7 @@ <p data-sourcepos="1:1-1:17" dir="auto"><a href="/uri">link [bar</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">link [bar</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__046: canonical: | <p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> @@ -6496,6 +6526,7 @@ <p data-sourcepos="1:1-1:29" dir="auto"><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">link <em>foo </em><strong><em>bar<code>#</code></em></strong></a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__047: canonical: | <p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> @@ -6503,6 +6534,7 @@ <p data-sourcepos="1:1-1:24" dir="auto"><a href="/uri"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="moon" decoding="async" class="lazy" data-src="moon.jpg"></a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri"><img src="moon.jpg" alt="moon"></a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__048: canonical: | <p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p> @@ -6510,6 +6542,7 @@ <p data-sourcepos="1:1-1:22" dir="auto">[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p> wysiwyg: |- <p>[foo <a target="_blank" rel="noopener noreferrer nofollow" href="/uri">bar</a>]<a target="_blank" rel="noopener noreferrer nofollow" href="/uri">ref</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__049: canonical: | <p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p> @@ -6517,6 +6550,7 @@ <p data-sourcepos="1:1-1:27" dir="auto">[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p> wysiwyg: |- <p>[foo <em>bar </em><a target="_blank" rel="noopener noreferrer nofollow" href="/uri"><em>baz</em></a>]<a target="_blank" rel="noopener noreferrer nofollow" href="/uri">ref</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__050: canonical: | <p>*<a href="/uri">foo*</a></p> @@ -6524,6 +6558,7 @@ <p data-sourcepos="1:1-1:12" dir="auto">*<a href="/uri">foo*</a></p> wysiwyg: |- <p>*<a target="_blank" rel="noopener noreferrer nofollow" href="/uri">foo*</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__051: canonical: | <p><a href="/uri">foo *bar</a></p> @@ -6531,6 +6566,7 @@ <p data-sourcepos="1:1-1:15" dir="auto"><a href="/uri">foo *bar</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">foo *bar</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__052: canonical: | <p>[foo <bar attr="][ref]"></p> @@ -6538,6 +6574,7 @@ <p data-sourcepos="1:1-1:24" dir="auto">[foo </p> wysiwyg: |- <p>[foo </p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__053: canonical: | <p>[foo<code>][ref]</code></p> @@ -6545,6 +6582,7 @@ <p data-sourcepos="1:1-1:12" dir="auto">[foo<code>][ref]</code></p> wysiwyg: |- <p>[foo<code>][ref]</code></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__054: canonical: | <p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p> @@ -6552,6 +6590,7 @@ <p data-sourcepos="1:1-1:39" dir="auto">[foo<a href="http://example.com/?search=%5D%5Bref%5D" rel="nofollow noreferrer noopener" target="_blank">http://example.com/?search=][ref]</a></p> wysiwyg: |- <p>[foo<a target="_blank" rel="noopener noreferrer nofollow" href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p> + <pre>[ref]: /uri</pre> 06_07__inlines__links__055: canonical: | <p><a href="/url" title="title">foo</a></p> @@ -6559,6 +6598,7 @@ <p data-sourcepos="1:1-1:10" dir="auto"><a href="/url" title="title">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> + <pre>[bar]: /url "title"</pre> 06_07__inlines__links__056: canonical: | <p><a href="/url">Толпой</a> is a Russian word.</p> @@ -6566,12 +6606,14 @@ <p data-sourcepos="1:1-1:47" dir="auto"><a href="/url">Толпой</a> is a Russian word.</p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">Толпой</a> is a Russian word.</p> + <pre>[толпой]: /url</pre> 06_07__inlines__links__057: canonical: | <p><a href="/url">Baz</a></p> static: |- <p data-sourcepos="4:1-4:14" dir="auto"><a href="/url">Baz</a></p> wysiwyg: |- + <pre>[foo bar]: /url</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">Baz</a></p> 06_07__inlines__links__058: canonical: | @@ -6580,6 +6622,7 @@ <p data-sourcepos="1:1-1:11" dir="auto">[foo] <a href="/url" title="title">bar</a></p> wysiwyg: |- <p>[foo] <a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">bar</a></p> + <pre>[bar]: /url "title"</pre> 06_07__inlines__links__059: canonical: | <p>[foo] @@ -6590,12 +6633,15 @@ wysiwyg: |- <p>[foo] <a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">bar</a></p> + <pre>[bar]: /url "title"</pre> 06_07__inlines__links__060: canonical: | <p><a href="/url1">bar</a></p> static: |- <p data-sourcepos="5:1-5:10" dir="auto"><a href="/url1">bar</a></p> wysiwyg: |- + <pre>[foo]: /url1</pre> + <pre>[foo]: /url2</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url1">bar</a></p> 06_07__inlines__links__061: canonical: | @@ -6604,6 +6650,7 @@ <p data-sourcepos="1:1-1:32" dir="auto">[bar][foo<span>!</span>]</p> wysiwyg: |- <p>[bar][foo!]</p> + <pre>[foo!]: /url</pre> 06_07__inlines__links__062: canonical: | <p>[foo][ref[]</p> @@ -6641,12 +6688,14 @@ <p data-sourcepos="1:1-1:12" dir="auto"><a href="/uri">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">foo</a></p> + <pre>[ref\[]: /uri</pre> 06_07__inlines__links__066: canonical: | <p><a href="/uri">bar\</a></p> static: |- <p data-sourcepos="3:1-3:7" dir="auto"><a href="/uri">bar\</a></p> wysiwyg: |- + <pre>[bar\\]: /uri</pre> <p><a target="_blank" rel="noopener noreferrer nofollow" href="/uri">bar\</a></p> 06_07__inlines__links__067: canonical: | @@ -6681,6 +6730,7 @@ <p data-sourcepos="1:1-1:7" dir="auto"><a href="/url" title="title">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__070: canonical: | <p><a href="/url" title="title"><em>foo</em> bar</a></p> @@ -6688,6 +6738,7 @@ <p data-sourcepos="1:1-1:13" dir="auto"><a href="/url" title="title"><em>foo</em> bar</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title"><em>foo</em> bar</a></p> + <pre>[*foo* bar]: /url "title"</pre> 06_07__inlines__links__071: canonical: | <p><a href="/url" title="title">Foo</a></p> @@ -6695,6 +6746,7 @@ <p data-sourcepos="1:1-1:7" dir="auto"><a href="/url" title="title">Foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">Foo</a></p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__072: canonical: | <p><a href="/url" title="title">foo</a> @@ -6705,6 +6757,7 @@ wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a> []</p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__073: canonical: | <p><a href="/url" title="title">foo</a></p> @@ -6712,6 +6765,7 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="/url" title="title">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__074: canonical: | <p><a href="/url" title="title"><em>foo</em> bar</a></p> @@ -6719,6 +6773,7 @@ <p data-sourcepos="1:1-1:11" dir="auto"><a href="/url" title="title"><em>foo</em> bar</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title"><em>foo</em> bar</a></p> + <pre>[*foo* bar]: /url "title"</pre> 06_07__inlines__links__075: canonical: | <p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p> @@ -6726,6 +6781,7 @@ <p data-sourcepos="1:1-1:13" dir="auto">[<a href="/url" title="title"><em>foo</em> bar</a>]</p> wysiwyg: |- <p>[<a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title"><em>foo</em> bar</a>]</p> + <pre>[*foo* bar]: /url "title"</pre> 06_07__inlines__links__076: canonical: | <p>[[bar <a href="/url">foo</a></p> @@ -6733,6 +6789,7 @@ <p data-sourcepos="1:1-1:11" dir="auto">[[bar <a href="/url">foo</a></p> wysiwyg: |- <p>[[bar <a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a></p> + <pre>[foo]: /url</pre> 06_07__inlines__links__077: canonical: | <p><a href="/url" title="title">Foo</a></p> @@ -6740,6 +6797,7 @@ <p data-sourcepos="1:1-1:5" dir="auto"><a href="/url" title="title">Foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">Foo</a></p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__078: canonical: | <p><a href="/url">foo</a> bar</p> @@ -6747,6 +6805,7 @@ <p data-sourcepos="1:1-1:9" dir="auto"><a href="/url">foo</a> bar</p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo</a> bar</p> + <pre>[foo]: /url</pre> 06_07__inlines__links__079: canonical: | <p>[foo]</p> @@ -6754,12 +6813,14 @@ <p data-sourcepos="1:1-1:6" dir="auto">[foo]</p> wysiwyg: |- <p>[foo]</p> + <pre>[foo]: /url "title"</pre> 06_07__inlines__links__080: canonical: | <p>*<a href="/url">foo*</a></p> static: |- <p data-sourcepos="3:1-3:7" dir="auto">*<a href="/url">foo*</a></p> wysiwyg: |- + <pre>[foo*]: /url</pre> <p>*<a target="_blank" rel="noopener noreferrer nofollow" href="/url">foo*</a></p> 06_07__inlines__links__081: canonical: | @@ -6768,6 +6829,8 @@ <p data-sourcepos="1:1-1:10" dir="auto"><a href="/url2">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url2">foo</a></p> + <pre>[foo]: /url1</pre> + <pre>[bar]: /url2</pre> 06_07__inlines__links__082: canonical: | <p><a href="/url1">foo</a></p> @@ -6775,6 +6838,7 @@ <p data-sourcepos="1:1-1:7" dir="auto"><a href="/url1">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url1">foo</a></p> + <pre>[foo]: /url1</pre> 06_07__inlines__links__083: canonical: | <p><a href="">foo</a></p> @@ -6782,6 +6846,7 @@ <p data-sourcepos="1:1-1:7" dir="auto"><a href="">foo</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="">foo</a></p> + <pre>[foo]: /url1</pre> 06_07__inlines__links__084: canonical: | <p><a href="/url1">foo</a>(not a link)</p> @@ -6789,6 +6854,7 @@ <p data-sourcepos="1:1-1:17" dir="auto"><a href="/url1">foo</a>(not a link)</p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url1">foo</a>(not a link)</p> + <pre>[foo]: /url1</pre> 06_07__inlines__links__085: canonical: | <p>[foo]<a href="/url">bar</a></p> @@ -6796,6 +6862,7 @@ <p data-sourcepos="1:1-1:15" dir="auto">[foo]<a href="/url">bar</a></p> wysiwyg: |- <p>[foo]<a target="_blank" rel="noopener noreferrer nofollow" href="/url">bar</a></p> + <pre>[baz]: /url</pre> 06_07__inlines__links__086: canonical: | <p><a href="/url2">foo</a><a href="/url1">baz</a></p> @@ -6803,6 +6870,8 @@ <p data-sourcepos="1:1-1:15" dir="auto"><a href="/url2">foo</a><a href="/url1">baz</a></p> wysiwyg: |- <p><a target="_blank" rel="noopener noreferrer nofollow" href="/url2">foo</a><a target="_blank" rel="noopener noreferrer nofollow" href="/url1">baz</a></p> + <pre>[baz]: /url1</pre> + <pre>[bar]: /url2</pre> 06_07__inlines__links__087: canonical: | <p>[foo]<a href="/url1">bar</a></p> @@ -6810,6 +6879,8 @@ <p data-sourcepos="1:1-1:15" dir="auto">[foo]<a href="/url1">bar</a></p> wysiwyg: |- <p>[foo]<a target="_blank" rel="noopener noreferrer nofollow" href="/url1">bar</a></p> + <pre>[baz]: /url1</pre> + <pre>[foo]: /url2</pre> 06_08__inlines__images__001: canonical: | <p><img src="/url" alt="foo" title="title" /></p> @@ -6824,6 +6895,7 @@ <p data-sourcepos="1:1-1:12" dir="auto"><a class="no-attachment-icon" href="train.jpg" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo bar" title="train & tracks" decoding="async" class="lazy" data-src="train.jpg"></a></p> wysiwyg: |- <p><img src="train.jpg" alt="foo bar" title="train & tracks"></p> + <pre>[foo *bar*]: train.jpg "train & tracks"</pre> 06_08__inlines__images__003: canonical: | <p><img src="/url2" alt="foo bar" /></p> @@ -6845,6 +6917,7 @@ <p data-sourcepos="1:1-1:14" dir="auto"><a class="no-attachment-icon" href="train.jpg" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo bar" title="train & tracks" decoding="async" class="lazy" data-src="train.jpg"></a></p> wysiwyg: |- <p><img src="train.jpg" alt="foo bar" title="train & tracks"></p> + <pre>[foo *bar*]: train.jpg "train & tracks"</pre> 06_08__inlines__images__006: canonical: | <p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> @@ -6852,6 +6925,7 @@ <p data-sourcepos="1:1-1:20" dir="auto"><a class="no-attachment-icon" href="train.jpg" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo bar" title="train & tracks" decoding="async" class="lazy" data-src="train.jpg"></a></p> wysiwyg: |- <p><img src="train.jpg" alt="foo bar" title="train & tracks"></p> + <pre>[foobar]: train.jpg "train & tracks"</pre> 06_08__inlines__images__007: canonical: | <p><img src="train.jpg" alt="foo" /></p> @@ -6887,6 +6961,7 @@ <p data-sourcepos="1:1-1:11" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo"></p> + <pre>[bar]: /url</pre> 06_08__inlines__images__012: canonical: | <p><img src="/url" alt="foo" /></p> @@ -6894,6 +6969,7 @@ <p data-sourcepos="1:1-1:11" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo"></p> + <pre>[bar]: /url</pre> 06_08__inlines__images__013: canonical: | <p><img src="/url" alt="foo" title="title" /></p> @@ -6901,6 +6977,7 @@ <p data-sourcepos="1:1-1:8" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo" title="title"></p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__014: canonical: | <p><img src="/url" alt="foo bar" title="title" /></p> @@ -6908,6 +6985,7 @@ <p data-sourcepos="1:1-1:14" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo bar" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo bar" title="title"></p> + <pre>[*foo* bar]: /url "title"</pre> 06_08__inlines__images__015: canonical: | <p><img src="/url" alt="Foo" title="title" /></p> @@ -6915,6 +6993,7 @@ <p data-sourcepos="1:1-1:8" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Foo" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="Foo" title="title"></p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__016: canonical: | <p><img src="/url" alt="foo" title="title" /> @@ -6925,6 +7004,7 @@ wysiwyg: |- <p><img src="/url" alt="foo" title="title"> []</p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__017: canonical: | <p><img src="/url" alt="foo" title="title" /></p> @@ -6932,6 +7012,7 @@ <p data-sourcepos="1:1-1:6" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo" title="title"></p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__018: canonical: | <p><img src="/url" alt="foo bar" title="title" /></p> @@ -6939,6 +7020,7 @@ <p data-sourcepos="1:1-1:12" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="foo bar" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="foo bar" title="title"></p> + <pre>[*foo* bar]: /url "title"</pre> 06_08__inlines__images__019: canonical: | <p>![[foo]]</p> @@ -6956,6 +7038,7 @@ <p data-sourcepos="1:1-1:6" dir="auto"><a class="no-attachment-icon" href="/url" target="_blank" rel="noopener noreferrer"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Foo" title="title" decoding="async" class="lazy" data-src="/url"></a></p> wysiwyg: |- <p><img src="/url" alt="Foo" title="title"></p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__021: canonical: | <p>![foo]</p> @@ -6963,6 +7046,7 @@ <p data-sourcepos="1:1-1:7" dir="auto">![foo]</p> wysiwyg: |- <p>![foo]</p> + <pre>[foo]: /url "title"</pre> 06_08__inlines__images__022: canonical: | <p>!<a href="/url" title="title">foo</a></p> @@ -6970,6 +7054,7 @@ <p data-sourcepos="1:1-1:27" dir="auto"><span>!</span><a href="/url" title="title">foo</a></p> wysiwyg: |- <p>!<a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> + <pre>[foo]: /url "title"</pre> 06_09__inlines__autolinks__001: canonical: | <p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p> diff --git a/glfm_specification/example_snapshots/prosemirror_json.yml b/glfm_specification/example_snapshots/prosemirror_json.yml index f770d341c426e80b3e0bdf995e684a991eb5ade7..7cb4757b368b9a630d3cb59e181dba0749bb9e44 100644 --- a/glfm_specification/example_snapshots/prosemirror_json.yml +++ b/glfm_specification/example_snapshots/prosemirror_json.yml @@ -3883,6 +3883,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -3910,6 +3924,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "the title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"the title\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -3937,6 +3965,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo*bar\\]", + "url": "my_(url)", + "title": "title (with parens)" + }, + "content": [ + { + "type": "text", + "text": "[foo*bar\\]]: my_(url) \"title (with parens)\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -3964,6 +4006,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo bar", + "url": "my url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo bar]: my url \"title\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -3991,6 +4047,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "\ntitle\nline1\nline2\n" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"\ntitle\nline1\nline2\n\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -4051,6 +4121,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4102,6 +4186,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: " + } + ] + }, { "type": "paragraph", "content": [ @@ -4153,6 +4251,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url\\bar*baz", + "title": "foo\"bar\\baz" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url\\bar*baz \"foo\"bar\\baz\"" + } + ] + }, { "type": "paragraph", "content": [ @@ -4200,6 +4312,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: url" + } + ] } ] } @@ -4227,6 +4353,34 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "first", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: first" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "second", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: second" + } + ] } ] } @@ -4234,6 +4388,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4261,6 +4429,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "αγω", + "url": "/φου", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[αγω]: /φου" + } + ] + }, { "type": "paragraph", "content": [ @@ -4289,7 +4471,18 @@ "type": "doc", "content": [ { - "type": "paragraph" + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] } ] } @@ -4297,6 +4490,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4327,6 +4534,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4446,6 +4667,20 @@ } ] }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "blockquote", "attrs": { @@ -4469,6 +4704,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "heading", "attrs": { @@ -4508,6 +4757,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4539,6 +4802,48 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/foo-url", + "title": "foo" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /foo-url \"foo\"" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/bar-url", + "title": "bar" + }, + "content": [ + { + "type": "text", + "text": "[bar]: /bar-url \"bar\"" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "baz", + "url": "/baz-url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[baz]: /baz-url" + } + ] + }, { "type": "paragraph", "content": [ @@ -4634,7 +4939,18 @@ }, "content": [ { - "type": "paragraph" + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] } ] } @@ -4645,7 +4961,18 @@ "type": "doc", "content": [ { - "type": "paragraph" + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] } ] } @@ -9572,6 +9899,20 @@ "text": "b" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /url" + } + ] } ] }, @@ -10416,6 +10757,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/bar*", + "title": "ti*tle" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /bar* \"ti*tle\"" + } + ] } ] } @@ -10588,6 +10943,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/föö", + "title": "föö" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /föö \"föö\"" + } + ] } ] } @@ -15592,11 +15961,25 @@ "text": "foo" } ] - } - ] - } -06_07__inlines__links__044: |- - { + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url \"title\"" + } + ] + } + ] + } +06_07__inlines__links__044: |- + { "type": "doc", "content": [ { @@ -15619,6 +16002,20 @@ "text": "link [foo [bar]]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15646,6 +16043,20 @@ "text": "link [bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15739,6 +16150,20 @@ "text": "#" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15772,6 +16197,20 @@ ] } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15823,6 +16262,20 @@ "text": "ref" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15886,6 +16339,20 @@ "text": "ref" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15917,6 +16384,20 @@ "text": "foo*" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15944,6 +16425,20 @@ "text": "foo *bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15959,6 +16454,20 @@ "text": "[foo " } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -15983,6 +16492,20 @@ "text": "][ref]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -16014,6 +16537,20 @@ "text": "http://example.com/?search=][ref]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref]: /uri" + } + ] } ] } @@ -16041,6 +16578,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url \"title\"" + } + ] } ] } @@ -16072,6 +16623,20 @@ "text": " is a Russian word." } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "толпой", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[толпой]: /url" + } + ] } ] } @@ -16079,6 +16644,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo bar", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo bar]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -16130,6 +16709,20 @@ "text": "bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url \"title\"" + } + ] } ] } @@ -16161,6 +16754,20 @@ "text": "bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url \"title\"" + } + ] } ] } @@ -16168,6 +16775,34 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url1" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url2", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url2" + } + ] + }, { "type": "paragraph", "content": [ @@ -16203,6 +16838,20 @@ "text": "[bar][foo!]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo!", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo!]: /url" + } + ] } ] } @@ -16302,6 +16951,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "ref\\[", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[ref\\[]: /uri" + } + ] } ] } @@ -16309,6 +16972,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar\\\\", + "url": "/uri", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[bar\\\\]: /uri" + } + ] + }, { "type": "paragraph", "content": [ @@ -16404,6 +17081,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16450,6 +17141,20 @@ "text": " bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "*foo* bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[*foo* bar]: /url \"title\"" + } + ] } ] } @@ -16477,6 +17182,20 @@ "text": "Foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16508,6 +17227,20 @@ "text": "\n[]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16535,6 +17268,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16581,10 +17328,24 @@ "text": " bar" } ] - } - ] - } -06_07__inlines__links__075: |- + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "*foo* bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[*foo* bar]: /url \"title\"" + } + ] + } + ] + } +06_07__inlines__links__075: |- { "type": "doc", "content": [ @@ -16635,6 +17396,20 @@ "text": "]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "*foo* bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[*foo* bar]: /url \"title\"" + } + ] } ] } @@ -16666,6 +17441,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] } ] } @@ -16693,6 +17482,20 @@ "text": "Foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16724,6 +17527,20 @@ "text": " bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url" + } + ] } ] } @@ -16739,6 +17556,20 @@ "text": "[foo]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -16746,6 +17577,20 @@ { "type": "doc", "content": [ + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo*", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo*]: /url" + } + ] + }, { "type": "paragraph", "content": [ @@ -16797,6 +17642,34 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url1" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url2", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url2" + } + ] } ] } @@ -16824,6 +17697,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url1" + } + ] } ] } @@ -16851,6 +17738,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url1" + } + ] } ] } @@ -16882,6 +17783,20 @@ "text": "(not a link)" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url1" + } + ] } ] } @@ -16913,6 +17828,20 @@ "text": "bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "baz", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[baz]: /url" + } + ] } ] } @@ -16956,6 +17885,34 @@ "text": "baz" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "baz", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[baz]: /url1" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url2", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url2" + } + ] } ] } @@ -16987,6 +17944,34 @@ "text": "bar" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "baz", + "url": "/url1", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[baz]: /url1" + } + ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url2", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url2" + } + ] } ] } @@ -17029,6 +18014,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo *bar*", + "url": "train.jpg", + "title": "train & tracks" + }, + "content": [ + { + "type": "text", + "text": "[foo *bar*]: train.jpg \"train & tracks\"" + } + ] } ] } @@ -17092,6 +18091,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo *bar*", + "url": "train.jpg", + "title": "train & tracks" + }, + "content": [ + { + "type": "text", + "text": "[foo *bar*]: train.jpg \"train & tracks\"" + } + ] } ] } @@ -17113,6 +18126,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foobar", + "url": "train.jpg", + "title": "train & tracks" + }, + "content": [ + { + "type": "text", + "text": "[foobar]: train.jpg \"train & tracks\"" + } + ] } ] } @@ -17222,6 +18249,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url" + } + ] } ] } @@ -17243,6 +18284,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "bar", + "url": "/url", + "title": null + }, + "content": [ + { + "type": "text", + "text": "[bar]: /url" + } + ] } ] } @@ -17264,6 +18319,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17285,6 +18354,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "*foo* bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[*foo* bar]: /url \"title\"" + } + ] } ] } @@ -17306,6 +18389,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17331,6 +18428,20 @@ "text": "\n[]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17352,6 +18463,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17373,6 +18498,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "*foo* bar", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[*foo* bar]: /url \"title\"" + } + ] } ] } @@ -17418,6 +18557,20 @@ } } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17433,6 +18586,20 @@ "text": "![foo]" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } @@ -17464,6 +18631,20 @@ "text": "foo" } ] + }, + { + "type": "referenceDefinition", + "attrs": { + "identifier": "foo", + "url": "/url", + "title": "title" + }, + "content": [ + { + "type": "text", + "text": "[foo]: /url \"title\"" + } + ] } ] } diff --git a/spec/frontend/content_editor/remark_markdown_processing_spec.js b/spec/frontend/content_editor/remark_markdown_processing_spec.js index 48adceaab58e373cbf15da521ee1c8d446e15f81..ddf49a4c18eb1756b47c437a484394bc016530e8 100644 --- a/spec/frontend/content_editor/remark_markdown_processing_spec.js +++ b/spec/frontend/content_editor/remark_markdown_processing_spec.js @@ -15,6 +15,7 @@ import Link from '~/content_editor/extensions/link'; import ListItem from '~/content_editor/extensions/list_item'; import OrderedList from '~/content_editor/extensions/ordered_list'; import Paragraph from '~/content_editor/extensions/paragraph'; +import ReferenceDefinition from '~/content_editor/extensions/reference_definition'; import Sourcemap from '~/content_editor/extensions/sourcemap'; import Strike from '~/content_editor/extensions/strike'; import Table from '~/content_editor/extensions/table'; @@ -45,6 +46,7 @@ const tiptapEditor = createTestEditor({ Link, ListItem, OrderedList, + ReferenceDefinition, Sourcemap, Strike, Table, @@ -78,6 +80,7 @@ const { listItem, orderedList, pre, + referenceDefinition, strike, table, tableRow, @@ -105,6 +108,7 @@ const { listItem: { nodeType: ListItem.name }, orderedList: { nodeType: OrderedList.name }, paragraph: { nodeType: Paragraph.name }, + referenceDefinition: { nodeType: ReferenceDefinition.name }, strike: { nodeType: Strike.name }, table: { nodeType: Table.name }, tableCell: { nodeType: TableCell.name }, @@ -1079,6 +1083,32 @@ _world_. ), ), }, + { + markdown: ` +[GitLab][gitlab-url] + +[gitlab-url]: https://gitlab.com "GitLab" + + `, + expectedDoc: doc( + paragraph( + source('[GitLab][gitlab-url]'), + link( + { ...source('[GitLab][gitlab-url]'), href: 'https://gitlab.com', title: 'GitLab' }, + 'GitLab', + ), + ), + referenceDefinition( + { + ...source('[gitlab-url]: https://gitlab.com "GitLab"'), + identifier: 'gitlab-url', + url: 'https://gitlab.com', + title: 'GitLab', + }, + '[gitlab-url]: https://gitlab.com "GitLab"', + ), + ), + }, ]; const runOnly = examples.find((example) => example.only === true); diff --git a/spec/frontend/content_editor/render_html_and_json_for_all_examples.js b/spec/frontend/content_editor/render_html_and_json_for_all_examples.js index 116a26cf7d55baae95f8a53635153eb2eef0c140..782158810dd2688d44b6825b8c13ad0086132fb0 100644 --- a/spec/frontend/content_editor/render_html_and_json_for_all_examples.js +++ b/spec/frontend/content_editor/render_html_and_json_for_all_examples.js @@ -26,6 +26,7 @@ import Italic from '~/content_editor/extensions/italic'; import Link from '~/content_editor/extensions/link'; import ListItem from '~/content_editor/extensions/list_item'; import OrderedList from '~/content_editor/extensions/ordered_list'; +import ReferenceDefinition from '~/content_editor/extensions/reference_definition'; import Strike from '~/content_editor/extensions/strike'; import Table from '~/content_editor/extensions/table'; import TableCell from '~/content_editor/extensions/table_cell'; @@ -63,6 +64,7 @@ const tiptapEditor = createTestEditor({ Link, ListItem, OrderedList, + ReferenceDefinition, Strike, Table, TableCell, diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js index 29f1f219971ede75f16e0443cbb95fca561cec48..422eb3f311b2fb40836cf6320d150c635803cf1c 100644 --- a/spec/frontend/content_editor/services/markdown_serializer_spec.js +++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js @@ -24,6 +24,7 @@ import Link from '~/content_editor/extensions/link'; import ListItem from '~/content_editor/extensions/list_item'; import OrderedList from '~/content_editor/extensions/ordered_list'; import Paragraph from '~/content_editor/extensions/paragraph'; +import ReferenceDefinition from '~/content_editor/extensions/reference_definition'; import Sourcemap from '~/content_editor/extensions/sourcemap'; import Strike from '~/content_editor/extensions/strike'; import Table from '~/content_editor/extensions/table'; @@ -63,6 +64,7 @@ const tiptapEditor = createTestEditor({ Link, ListItem, OrderedList, + ReferenceDefinition, Sourcemap, Strike, Table, @@ -104,6 +106,7 @@ const { listItem, orderedList, paragraph, + referenceDefinition, strike, table, tableCell, @@ -139,6 +142,7 @@ const { listItem: { nodeType: ListItem.name }, orderedList: { nodeType: OrderedList.name }, paragraph: { nodeType: Paragraph.name }, + referenceDefinition: { nodeType: ReferenceDefinition.name }, strike: { markType: Strike.name }, table: { nodeType: Table.name }, tableCell: { nodeType: TableCell.name }, @@ -1163,6 +1167,38 @@ Oranges are orange [^1] ); }); + it('correctly serializes reference definition', () => { + expect( + serialize( + referenceDefinition('[gitlab]: https://gitlab.com'), + referenceDefinition('[foobar]: foobar.com'), + ), + ).toBe( + ` +[gitlab]: https://gitlab.com +[foobar]: foobar.com`.trimLeft(), + ); + }); + + it('correctly adds a space between a reference definition and a block content', () => { + expect( + serialize( + paragraph('paragraph'), + referenceDefinition('[gitlab]: https://gitlab.com'), + referenceDefinition('[foobar]: foobar.com'), + heading({ level: 2 }, 'heading'), + ), + ).toBe( + ` +paragraph + +[gitlab]: https://gitlab.com +[foobar]: foobar.com + +## heading`.trimLeft(), + ); + }); + const defaultEditAction = (initialContent) => { tiptapEditor.chain().setContent(initialContent.toJSON()).insertContent(' modified').run(); }; diff --git a/spec/frontend/lib/gfm/index_spec.js b/spec/frontend/lib/gfm/index_spec.js index b722315d63a971c9dbc77dd6b962d50ca4cde83e..624744b9a920889851e24d95b0049fe11bc547de 100644 --- a/spec/frontend/lib/gfm/index_spec.js +++ b/spec/frontend/lib/gfm/index_spec.js @@ -96,28 +96,60 @@ describe('gfm', () => { ); }); }); - }); - describe('when skipping the rendering of code blocks', () => { - it('transforms code nodes into codeblock html tags', async () => { - const result = await markdownToAST( - ` + describe('when skipping the rendering of code blocks', () => { + it('transforms code nodes into codeblock html tags', async () => { + const result = await markdownToAST( + ` \`\`\`javascript console.log('Hola'); \`\`\`\ `, - ['code'], - ); + ['code'], + ); - expectInRoot( - result, - expect.objectContaining({ - tagName: 'codeblock', - properties: { - language: 'javascript', - }, - }), - ); + expectInRoot( + result, + expect.objectContaining({ + tagName: 'codeblock', + properties: { + language: 'javascript', + }, + }), + ); + }); + }); + + describe('when skipping the rendering of reference definitions', () => { + it('transforms code nodes into codeblock html tags', async () => { + const result = await markdownToAST( + ` +[gitlab][gitlab] + +[gitlab]: https://gitlab.com "GitLab" + `, + ['definition'], + ); + + expectInRoot( + result, + expect.objectContaining({ + type: 'element', + tagName: 'referencedefinition', + properties: { + identifier: 'gitlab', + title: 'GitLab', + url: 'https://gitlab.com', + }, + children: [ + { + type: 'text', + value: '[gitlab]: https://gitlab.com "GitLab"', + }, + ], + }), + ); + }); }); }); }); diff --git a/spec/frontend_integration/content_editor/content_editor_integration_spec.js b/spec/frontend_integration/content_editor/content_editor_integration_spec.js index 89b8d8d6d94d6210e0ad30ec09485eea1465094c..4d400a383e32be93294b47256a7cb8a9f12c07db 100644 --- a/spec/frontend_integration/content_editor/content_editor_integration_spec.js +++ b/spec/frontend_integration/content_editor/content_editor_integration_spec.js @@ -61,29 +61,38 @@ describe('content_editor', () => { }); }); - it('renders footnote ids alongside the footnote definition', async () => { - buildWrapper(); - - renderMarkdown.mockResolvedValue(` - <p data-sourcepos="3:1-3:56" dir="auto"> - This reference tag is a mix of letters and numbers. <sup class="footnote-ref"><a href="#fn-footnote-2717" id="fnref-footnote-2717" data-footnote-ref="">2</a></sup> - </p> - <section class="footnotes" data-footnotes> - <ol> - <li id="fn-footnote-2717"> - <p data-sourcepos="6:7-6:31">This is another footnote. <a href="#fnref-footnote-2717" aria-label="Back to content" class="footnote-backref" data-footnote-backref=""><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p> - </li> - </ol> - </section> - `); + describe('when preserveUnchangedMarkdown feature flag is enabled', () => { + beforeEach(() => { + gon.features = { preserveUnchangedMarkdown: true }; + }); + afterEach(() => { + gon.features = { preserveUnchangedMarkdown: false }; + }); - await contentEditorService.setSerializedContent(` - This reference tag is a mix of letters and numbers [^footnote]. + it('processes and renders footnote ids alongside the footnote definition', async () => { + buildWrapper(); - [^footnote]: This is another footnote. + await contentEditorService.setSerializedContent(` +This reference tag is a mix of letters and numbers [^footnote]. + +[^footnote]: This is another footnote. `); - await nextTick(); + await nextTick(); + + expect(wrapper.text()).toContain('footnote: This is another footnote'); + }); + + it('processes and displays reference definitions', async () => { + buildWrapper(); + + await contentEditorService.setSerializedContent(` +[GitLab][gitlab] - expect(wrapper.text()).toContain('footnote: This is another footnote'); +[gitlab]: https://gitlab.com + `); + await nextTick(); + + expect(wrapper.find('pre').text()).toContain('[gitlab]: https://gitlab.com'); + }); }); });