diff --git a/src/from-markdown.ts b/src/from-markdown.ts index 89c11140..33a36df4 100644 --- a/src/from-markdown.ts +++ b/src/from-markdown.ts @@ -227,6 +227,12 @@ function exitAttributes () { stackTop = stackTop.children[stackTop.children.length - 1] } + // Add attributes to last child of fragment + // Example: `[![Nuxt](https://nuxtjs.org/design-kit/colored-logo.svg){.nest}](https://nuxtjs.org)` + if (stackTop.type === 'fragment') { + stackTop = stackTop.children[stackTop.children.length - 1] + } + stackTop.attributes = cleaned } diff --git a/src/to-markdown.ts b/src/to-markdown.ts index 532dec05..240e6998 100644 --- a/src/to-markdown.ts +++ b/src/to-markdown.ts @@ -5,6 +5,8 @@ */ import { stringifyEntitiesLight } from 'stringify-entities' import type { Parent } from 'mdast-util-to-markdown/lib/types' +import { handle } from 'mdast-util-to-markdown/lib/handle' +import { Context, SafeOptions } from 'mdast-util-to-markdown' import { containerFlow, containerPhrasing, checkQuote } from './mdast-util-to-markdown' import { stringifyFrontMatter } from './frontmatter' @@ -34,7 +36,22 @@ export default { handlers: { containerComponent, textComponent, - componentContainerSection + componentContainerSection, + image: (node: Parent, _: any, context: Context, safeOptions: SafeOptions) => { + return handle.image(node as any, _, context, safeOptions) + attributes(node, context) + }, + link: (node: Parent, _: any, context: Context, safeOptions: SafeOptions) => { + return handle.link(node as any, _, context, safeOptions) + attributes(node, context) + }, + strong: (node: Parent, _: any, context: Context, safeOptions: SafeOptions) => { + return handle.strong(node as any, _, context, safeOptions) + attributes(node, context) + }, + inlineCode: (node: Parent, _: any, context: Context) => { + return handle.inlineCode(node as any, _, context) + attributes(node, context) + }, + emphasis: (node: Parent, _: any, context: Context, safeOptions: SafeOptions) => { + return handle.emphasis(node as any, _, context, safeOptions) + attributes(node, context) + } } } diff --git a/test/__snapshots__/attributes.test.ts.snap b/test/__snapshots__/attributes.test.ts.snap index ce3f8a40..467dedba 100644 --- a/test/__snapshots__/attributes.test.ts.snap +++ b/test/__snapshots__/attributes.test.ts.snap @@ -130,6 +130,217 @@ exports[`Attributes > class-suger 1`] = ` } `; +exports[`Attributes > code 1`] = ` +{ + "children": [ + { + "children": [ + { + "attributes": { + "class": "class", + "id": "id", + }, + "position": { + "end": { + "column": 7, + "line": 1, + "offset": 6, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "inlineCode", + "value": "code", + }, + ], + "position": { + "end": { + "column": 19, + "line": 1, + "offset": 18, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 19, + "line": 1, + "offset": 18, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + +exports[`Attributes > emphasis 1`] = ` +{ + "children": [ + { + "children": [ + { + "attributes": { + "class": "class", + "id": "id", + }, + "children": [ + { + "position": { + "end": { + "column": 10, + "line": 1, + "offset": 9, + }, + "start": { + "column": 2, + "line": 1, + "offset": 1, + }, + }, + "type": "text", + "value": "emphasis", + }, + ], + "position": { + "end": { + "column": 11, + "line": 1, + "offset": 10, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "emphasis", + }, + ], + "position": { + "end": { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + +exports[`Attributes > fragment-attribute 1`] = ` +{ + "children": [ + { + "children": [ + { + "attributes": { + "class": "cls", + }, + "children": [ + { + "alt": "Nuxt", + "attributes": { + "class": "nest", + }, + "position": { + "end": { + "column": 57, + "line": 1, + "offset": 56, + }, + "start": { + "column": 2, + "line": 1, + "offset": 1, + }, + }, + "title": null, + "type": "image", + "url": "https://nuxtjs.org/design-kit/colored-logo.svg", + }, + ], + "position": { + "end": { + "column": 77, + "line": 1, + "offset": 76, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "title": null, + "type": "link", + "url": "https:test", + }, + ], + "position": { + "end": { + "column": 83, + "line": 1, + "offset": 82, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 83, + "line": 1, + "offset": 82, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`Attributes > html-characters 1`] = ` { "children": [ @@ -322,6 +533,65 @@ exports[`Attributes > id-suger 1`] = ` } `; +exports[`Attributes > image 1`] = ` +{ + "children": [ + { + "children": [ + { + "alt": "Nuxt", + "attributes": { + "class": "class", + "id": "id", + }, + "position": { + "end": { + "column": 56, + "line": 1, + "offset": 55, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "title": null, + "type": "image", + "url": "https://nuxtjs.org/design-kit/colored-logo.svg", + }, + ], + "position": { + "end": { + "column": 68, + "line": 1, + "offset": 67, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 68, + "line": 1, + "offset": 67, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`Attributes > invlid-binding 1`] = ` { "children": [ @@ -398,6 +668,156 @@ exports[`Attributes > invlid-binding 1`] = ` } `; +exports[`Attributes > link 1`] = ` +{ + "children": [ + { + "children": [ + { + "attributes": { + "class": "class", + "id": "id", + }, + "children": [ + { + "position": { + "end": { + "column": 6, + "line": 1, + "offset": 5, + }, + "start": { + "column": 2, + "line": 1, + "offset": 1, + }, + }, + "type": "text", + "value": "Nuxt", + }, + ], + "position": { + "end": { + "column": 27, + "line": 1, + "offset": 26, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "title": null, + "type": "link", + "url": "https://nuxtjs.org", + }, + ], + "position": { + "end": { + "column": 39, + "line": 1, + "offset": 38, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 39, + "line": 1, + "offset": 38, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + +exports[`Attributes > strong 1`] = ` +{ + "children": [ + { + "children": [ + { + "attributes": { + "class": "class", + "id": "id", + }, + "children": [ + { + "position": { + "end": { + "column": 9, + "line": 1, + "offset": 8, + }, + "start": { + "column": 3, + "line": 1, + "offset": 2, + }, + }, + "type": "text", + "value": "strong", + }, + ], + "position": { + "end": { + "column": 11, + "line": 1, + "offset": 10, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "strong", + }, + ], + "position": { + "end": { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": { + "end": { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`Attributes > value-with-space 1`] = ` { "children": [ diff --git a/test/attributes.test.ts b/test/attributes.test.ts index 6bbab22a..4413dee4 100644 --- a/test/attributes.test.ts +++ b/test/attributes.test.ts @@ -29,6 +29,25 @@ describe('Attributes', () => { 'invlid-binding': { markdown: ':test{:}', expected: ':test{:}' + }, + 'fragment-attribute': { + markdown: '[![Nuxt](https://nuxtjs.org/design-kit/colored-logo.svg){.nest}](https:test){.cls}', + expected: '[![Nuxt](https://nuxtjs.org/design-kit/colored-logo.svg){.nest}](https\\:test){.cls}' + }, + image: { + markdown: '![Nuxt](https://nuxtjs.org/design-kit/colored-logo.svg){#id .class}' + }, + code: { + markdown: '`code`{#id .class}' + }, + strong: { + markdown: '**strong**{#id .class}' + }, + link: { + markdown: '[Nuxt](https://nuxtjs.org){#id .class}' + }, + emphasis: { + markdown: '*emphasis*{#id .class}' } }) }) diff --git a/test/utils/index.ts b/test/utils/index.ts index 244666de..418c5162 100644 --- a/test/utils/index.ts +++ b/test/utils/index.ts @@ -58,8 +58,8 @@ async function astToMarkdown (ast: any, plugins = [] as any[]) { } const stream = await unified() .use(jsonParser) - .use(mdc) .use(gfm) + .use(mdc) for (const plugin of plugins) { stream.use(plugin)