From 34e291e4afca7eac3f302e41e1e483e3f1c09201 Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Wed, 19 Jun 2024 20:26:57 +0800 Subject: [PATCH] feat(markdown): support single line code import syntax (close #1355) --- .../createImportCodeBlockRule.ts | 21 ++++++++++++++----- .../tests/plugins/importCodePlugin.spec.ts | 10 +++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/packages/markdown/src/plugins/importCodePlugin/createImportCodeBlockRule.ts b/packages/markdown/src/plugins/importCodePlugin/createImportCodeBlockRule.ts index 6e6a69a449..c658f2ee73 100644 --- a/packages/markdown/src/plugins/importCodePlugin/createImportCodeBlockRule.ts +++ b/packages/markdown/src/plugins/importCodePlugin/createImportCodeBlockRule.ts @@ -10,7 +10,14 @@ const MIN_LENGTH = 9 const START_CODES = [64, 91, 99, 111, 100, 101] // regexp to match the import syntax -const SYNTAX_RE = /^@\[code(?:{(?:(\d+)?-(\d+)?)})?(?: ([^\]]+))?\]\(([^)]*)\)/ +const SYNTAX_RE = + /^@\[code(?:{(?:(?:(?\d+)?-(?\d+)?)|(?\d+))})?(?: (?[^\]]+))?\]\((?[^)]*)\)/ + +/** + * Utility function to parse line number from line string that matched by SYNTAX_RE + */ +const parseLineNumber = (line: string | undefined): number | undefined => + line ? Number.parseInt(line, 10) : undefined export const createImportCodeBlockRule = ({ handleImportPath = (str) => str }: ImportCodePluginOptions): RuleBlock => @@ -36,17 +43,21 @@ export const createImportCodeBlockRule = // check if it's matched the syntax const match = state.src.slice(pos, max).match(SYNTAX_RE) - if (!match) return false + if (!match?.groups) return false // return true as we have matched the syntax if (silent) return true - const [, lineStart, lineEnd, info, importPath] = match + const { info, importPath } = match.groups + + const lineSingle = parseLineNumber(match.groups.lineSingle) + const lineStart = lineSingle ?? parseLineNumber(match.groups.lineStart) ?? 0 + const lineEnd = lineSingle ?? parseLineNumber(match.groups.lineEnd) const meta: ImportCodeTokenMeta = { importPath: handleImportPath(importPath), - lineStart: lineStart ? Number.parseInt(lineStart, 10) : 0, - lineEnd: lineEnd ? Number.parseInt(lineEnd, 10) : undefined, + lineStart, + lineEnd, } // create a import_code token diff --git a/packages/markdown/tests/plugins/importCodePlugin.spec.ts b/packages/markdown/tests/plugins/importCodePlugin.spec.ts index 157c6a6fef..7bd5cc3f38 100644 --- a/packages/markdown/tests/plugins/importCodePlugin.spec.ts +++ b/packages/markdown/tests/plugins/importCodePlugin.spec.ts @@ -87,8 +87,10 @@ ${mdFixtureContent}\ const source = `\ @[code{1-2}](${jsFixturePathRelative}) @[code{1-}](${jsFixturePathRelative}) +@[code{2}](${jsFixturePathRelative}) @[code{4-5}](${mdFixturePathRelative}) @[code{-5}](${mdFixturePathRelative}) +@[code{5}](${mdFixturePathRelative}) ` const expected = `\ @@ -98,12 +100,18 @@ ${jsFixtureContent.split('\n').slice(0, 2).join('\n').replace(/\n?$/, '\n')}\
\
 ${jsFixtureContent.split('\n').slice(0).join('\n').replace(/\n?$/, '\n')}\
 
+
\
+${jsFixtureContent.split('\n').slice(1, 1).join('\n').replace(/\n?$/, '\n')}\
+
\
 ${mdFixtureContent.split('\n').slice(3, 5).join('\n').replace(/\n?$/, '\n')}\
 
\
 ${mdFixtureContent.split('\n').slice(0, 5).join('\n').replace(/\n?$/, '\n')}\
 
+
\
+${mdFixtureContent.split('\n').slice(4, 5).join('\n').replace(/\n?$/, '\n')}\
+
` const md = MarkdownIt().use(importCodePlugin) @@ -116,6 +124,8 @@ ${mdFixtureContent.split('\n').slice(0, 5).join('\n').replace(/\n?$/, '\n')}\ expect(env.importedFiles).toEqual([ jsFixturePath, jsFixturePath, + jsFixturePath, + mdFixturePath, mdFixturePath, mdFixturePath, ])