From abd96bda87667add2b32b3e5685d5f71d0a79896 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Fri, 27 May 2022 01:56:34 +0530 Subject: [PATCH] fix: modify `HTML_SEQUENCES` for better parsing --- src/node/markdown/plugins/component.ts | 109 ++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/src/node/markdown/plugins/component.ts b/src/node/markdown/plugins/component.ts index accacb8d..666177ee 100644 --- a/src/node/markdown/plugins/component.ts +++ b/src/node/markdown/plugins/component.ts @@ -3,6 +3,97 @@ import { RuleBlock } from 'markdown-it/lib/parser_block' import blockNames from 'markdown-it/lib/common/html_blocks' import { HTML_OPEN_CLOSE_TAG_RE } from 'markdown-it/lib/common/html_re' +/** + * Vue reserved tags + * + * @see https://vuejs.org/api/built-in-components.html + */ +const vueReservedTags = [ + 'template', + 'component', + 'transition', + 'transition-group', + 'keep-alive', + 'slot', + 'teleport' +] + +/** + * According to markdown spec, all non-block html tags are treated as "inline" + * tags (wrapped with

), including those "unknown" tags + * + * Therefore, markdown-it processes "inline" tags and "unknown" tags in the same + * way, and does not care if a tag is "inline" or "unknown" + * + * As we want to take those "unknown" tags as custom components, we should + * treat them as "block" tags + * + * So we have to distinguish between "inline" and "unknown" tags ourselves + * + * The inline tags list comes from MDN + * + * @see https://spec.commonmark.org/0.29/#raw-html + * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements + */ +const inlineTags = [ + 'a', + 'abbr', + 'acronym', + 'audio', + 'b', + 'bdi', + 'bdo', + 'big', + 'br', + 'button', + 'canvas', + 'cite', + 'code', + 'data', + 'datalist', + 'del', + 'dfn', + 'em', + 'embed', + 'i', + /* iframe is treated as HTML blocks in markdown spec */ + // 'iframe', + 'img', + 'input', + 'ins', + 'kbd', + 'label', + 'map', + 'mark', + 'meter', + 'noscript', + 'object', + 'output', + 'picture', + 'progress', + 'q', + 'ruby', + 's', + 'samp', + 'script', + 'select', + 'slot', + 'small', + 'span', + 'strong', + 'sub', + 'sup', + 'svg', + 'template', + 'textarea', + 'time', + 'u', + 'tt', + 'var', + 'video', + 'wbr' +] + // Replacing the default htmlBlock rule to allow using custom components at // root level @@ -14,10 +105,20 @@ const HTML_SEQUENCES: [RegExp, RegExp, boolean][] = [ [/^<\?/, /\?>/, true], [/^/, true], [/^/, true], - // PascalCase Components - [/^<[A-Z]/, />/, true], - // custom elements with hyphens - [/^<\w+\-/, />/, true], + // MODIFIED HERE: Treat vue reserved tags as block tags + [ + new RegExp('^|$))', 'i'), + /^$/, + true + ], + // MODIFIED HERE: Treat unknown tags as block tags (custom components), excluding known inline tags + [ + new RegExp( + '^]' + ), + /^$/, + true + ], [ new RegExp('^|$))', 'i'), /^$/,