From 372063d05a99e8293b9b4d8a20e89bf92fd8ba72 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Tue, 7 Jun 2022 15:22:28 +0200 Subject: [PATCH 1/7] fix(markdown): detect inline component followed by `.` and `,` --- .../micromark-extension/constants.ts | 76 ++++++++++--------- .../micromark-extension/tokenize-inline.ts | 2 +- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts b/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts index fe8d8e898..c168713c7 100644 --- a/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts +++ b/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts @@ -11,6 +11,10 @@ export const Codes = { * null */ EOF: null, + /** + * ' ' + */ + space: 32, /** * '"' */ @@ -24,13 +28,25 @@ export const Codes = { */ apostrophe: 39, /** - * '`' + * '(' */ - backTick: 96, + openingParentheses: 40, /** - * '\' + * ')' */ - backSlash: 92, + closingParentheses: 41, + /** + * ',' + **/ + comma: 44, + /** + * '-' + */ + dash: 45, + /** + * '.' + */ + dot: 46, /** * ':' */ @@ -40,59 +56,47 @@ export const Codes = { */ LessThan: 60, /** - * '=' - */ + * '=' + */ equals: 61, /** - * '>' - */ + * '>' + */ greaterThan: 62, /** - * '-' - */ - dash: 45, - /** - * '.' - */ - dot: 46, - /** - * ' ' + * 'X' */ - space: 32, + uppercaseX: 88, /** * '[' */ openingSquareBracket: 91, /** - * ']' - */ - closingSquareBracket: 93, - /** - * '{' + * '\' */ - openingCurlyBracket: 123, + backSlash: 92, /** - * '}' + * ']' */ - closingCurlyBracket: 125, + closingSquareBracket: 93, /** - * '(' + * '_' */ - openingParentheses: 40, + underscore: 95, /** - * ')' + * '`' */ - closingParentheses: 41, + backTick: 96, /** - * '_' + * 'x' */ - underscore: 95, + lowercaseX: 120, /** - * 'X' + * '{' */ - uppercaseX: 88, + openingCurlyBracket: 123, /** - * 'x' + * '}' */ - lowercaseX: 120 + closingCurlyBracket: 125 } diff --git a/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts b/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts index 216c95bb0..55ca93cce 100644 --- a/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts +++ b/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts @@ -78,7 +78,7 @@ function tokenize (this: TokenizeContext, effects: Effects, ok: State, nok: Stat } function exit (code: Code): void | State { - if (!markdownLineEndingOrSpace(code) && code !== null && ![Codes.closingSquareBracket].includes(code)) { + if (!markdownLineEndingOrSpace(code) && ![Codes.EOF, Codes.closingSquareBracket, Codes.dot, Codes.comma].includes(code)) { return nok(code) } effects.exit('componentText') From 928eb6365fb08f6c6d11b6154b0d59d8a2afa489 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Tue, 7 Jun 2022 15:22:38 +0200 Subject: [PATCH 2/7] test: add test --- test/features/parser-markdown.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/features/parser-markdown.ts b/test/features/parser-markdown.ts index 39bd03e32..fe34bc9c4 100644 --- a/test/features/parser-markdown.ts +++ b/test/features/parser-markdown.ts @@ -1,5 +1,6 @@ import { describe, test, expect, assert } from 'vitest' import { $fetch } from '@nuxt/test-utils' +import { visit } from 'unist-util-visit' export const testMarkdownParser = () => { describe('parser:markdown', () => { @@ -68,5 +69,21 @@ export const testMarkdownParser = () => { expect(parsed.body).toHaveProperty('children') expect(parsed.body.children.length).toEqual(0) }) + + test('inline component followed by dot or comma', async () => { + const parsed = await $fetch('/api/parse', { + method: 'POST', + body: { + id: 'content:index.md', + content: 'Inline component `:Comp` :Comp[works] beautifully, unless I put it before a :Comp[comma], or a :Comp[period].' + } + }) + + let compComponentCount = 0 + visit(parsed.body, node => (node as any).tag === 'comp', () => { + compComponentCount += 1 + }) + expect(compComponentCount).toEqual(3) + }) }) } From 1541ef7614d20540b1b4fae5cf9074ae0aca71d8 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Tue, 7 Jun 2022 15:28:12 +0200 Subject: [PATCH 3/7] chore: code style --- .../remark-mdc/micromark-extension/constants.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts b/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts index c168713c7..07a4371a6 100644 --- a/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts +++ b/src/runtime/markdown-parser/remark-mdc/micromark-extension/constants.ts @@ -44,8 +44,8 @@ export const Codes = { */ dash: 45, /** - * '.' - */ + * '.' + */ dot: 46, /** * ':' @@ -56,12 +56,12 @@ export const Codes = { */ LessThan: 60, /** - * '=' - */ + * '=' + */ equals: 61, /** - * '>' - */ + * '>' + */ greaterThan: 62, /** * 'X' From 6cafb88d8bf55c4f9dc823781cc647135362f0a7 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Wed, 8 Jun 2022 11:15:31 +0200 Subject: [PATCH 4/7] fix: detect inline component regardless of ending character --- .../remark-mdc/micromark-extension/tokenize-inline.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts b/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts index 55ca93cce..d82975da0 100644 --- a/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts +++ b/src/runtime/markdown-parser/remark-mdc/micromark-extension/tokenize-inline.ts @@ -78,9 +78,10 @@ function tokenize (this: TokenizeContext, effects: Effects, ok: State, nok: Stat } function exit (code: Code): void | State { - if (!markdownLineEndingOrSpace(code) && ![Codes.EOF, Codes.closingSquareBracket, Codes.dot, Codes.comma].includes(code)) { - return nok(code) - } + // Allow everything else to exit the componentText state + // if (!markdownLineEndingOrSpace(code) && ![Codes.EOF, Codes.closingSquareBracket, Codes.dot, Codes.comma].includes(code)) { + // return nok(code) + // } effects.exit('componentText') return ok(code) } From e8102b551c90a74edc3a5b5ba5d6ddc5bc560e87 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Wed, 8 Jun 2022 11:16:17 +0200 Subject: [PATCH 5/7] test: update tests --- test/features/parser-markdown.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/features/parser-markdown.ts b/test/features/parser-markdown.ts index fe34bc9c4..38f7cc4e3 100644 --- a/test/features/parser-markdown.ts +++ b/test/features/parser-markdown.ts @@ -70,20 +70,30 @@ export const testMarkdownParser = () => { expect(parsed.body.children.length).toEqual(0) }) - test('inline component followed by dot or comma', async () => { + test('inline component followed by non-space characters', async () => { const parsed = await $fetch('/api/parse', { method: 'POST', body: { id: 'content:index.md', - content: 'Inline component `:Comp` :Comp[works] beautifully, unless I put it before a :Comp[comma], or a :Comp[period].' + content: [ + ':hello', // valid + ':hello,', // valid + ':hello-world', // valid but with different name + ':hello{}-world', // valid + ':hello:', // invalid + ':rocket:' // emoji + ].join('\n') } }) let compComponentCount = 0 - visit(parsed.body, node => (node as any).tag === 'comp', () => { + visit(parsed.body, node => (node as any).tag === 'hello', () => { compComponentCount += 1 }) expect(compComponentCount).toEqual(3) + + // Check conflict between inline compoenent and emoji + expect(parsed.body.children[0].children.pop().value).toContain('🚀') }) }) } From 77d78f3d11b1b099f6adc524454bdeeb83b52426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Guilloux?= Date: Wed, 8 Jun 2022 13:42:58 +0200 Subject: [PATCH 6/7] docs(mdc): add example for inline ending chars --- docs/content/3.guide/1.writing/3.mdc.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/content/3.guide/1.writing/3.mdc.md b/docs/content/3.guide/1.writing/3.mdc.md index 320c7c2ac..28cc72b4e 100755 --- a/docs/content/3.guide/1.writing/3.mdc.md +++ b/docs/content/3.guide/1.writing/3.mdc.md @@ -164,6 +164,14 @@ They can be used with the `:` identifier. ``` :: +If you want to use an inline component followed by specific characters like `-`, `_` or `:`, you can use a dummy props specifier after it. + +```md +:hello{}-world +``` + +In this example, `:hello{}` will search for the `` component, and `-world` will be plain text. + ## Props There are two ways to pass props to components using MDC. From 750311ed4526053498fa36bdb271d942bd25f381 Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Thu, 9 Jun 2022 10:39:44 +0200 Subject: [PATCH 7/7] test: fix --- test/features/parser-markdown.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/features/parser-markdown.ts b/test/features/parser-markdown.ts index 5affeab3a..bf9aaec1e 100644 --- a/test/features/parser-markdown.ts +++ b/test/features/parser-markdown.ts @@ -74,6 +74,7 @@ export const testMarkdownParser = () => { const parsed = await $fetch('/api/parse', { method: 'POST', body: { + id: 'content:index.md', content: [ ':hello', // valid ':hello,', // valid