rehype-highlight-code-lines 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,17 @@
1
+ **A robust Next.js newsletter `Next.js Weekly` is sponsoring me** 💖
2
+ [![NextjsWeekly banner](./assets/next-js-weekly.png)](https://nextjsweekly.com/)
3
+
4
+ ### [Become a sponsor](https://github.com/sponsors/ipikuka) 🚀
5
+
6
+ If you find **`rehype-highlight-code-lines`** useful in your projects, consider supporting my work.
7
+ Your sponsorship means a lot 💖
8
+
9
+ My sponsors are going to be featured here and on [my sponsor wall](https://github.com/sponsors/ipikuka).
10
+
11
+ A warm thanks 🙌 to [@ErfanEbrahimnia](https://github.com/ErfanEbrahimnia), [@recepkyk](https://github.com/recepkyk), and [@LSeaburg](https://github.com/LSeaburg) for the support!
12
+
13
+ Thank you for supporting open source! 🙌
14
+
1
15
  # rehype-highlight-code-lines
2
16
 
3
17
  [![npm version][badge-npm-version]][url-npm-package]
@@ -18,7 +32,7 @@ This package is a **[unified][unified]** (**[rehype][rehype]**) plugin that **wr
18
32
 
19
33
  **`rehype-highlight-code-lines`** is ideal for adding line numbers to code blocks and highlighting specific lines.
20
34
 
21
- **`rehype-highlight-code-lines`** is **NOT** code highlighter and **does NOT** provide code highlighting! You can use a code highlighter for example **[rehype-highlight][rehype-highlight]** to highlight the code, then use the `rehype-highlight-code-lines` **after**.
35
+ **`rehype-highlight-code-lines`** is **NOT** code highlighter and **does NOT** provide code highlighting! You can use a code highlighter for example **[rehype-highlight][rehype-highlight]** to highlight the code, then use **`rehype-highlight-code-lines`** **after**.
22
36
 
23
37
  > [!IMPORTANT]
24
38
  > If your code highlighter already provides numbering and highlighting code lines, don't use **`rehype-highlight-code-lines`**!
@@ -320,8 +334,8 @@ use(rehypeHighlightLines, {
320
334
  ![markdown code block result](https://github.com/rehypejs/rehype-highlight/assets/30029208/908449d6-8028-4ecd-8536-3e747c725da7)
321
335
 
322
336
  **Here you can find some demo applications below which the `rehype-highlight` and `rehype-highlight-code-lines` are used together:**
323
- + [demo blog application](https://next-mdx-remote-client-in-app-router.vercel.app/) using `next-mdx-remote-client` within `Next.js app router`
324
- + [demo blog application](https://next-mdx-remote-client-in-pages-router.vercel.app/) using `next-mdx-remote-client` within `Next.js pages router`
337
+ + [demo blog application](https://nmrc-in-app-router.vercel.app) using `next-mdx-remote-client` within `Next.js app router`
338
+ + [demo blog application](https://nmrc-in-pages-router.vercel.app) using `next-mdx-remote-client` within `Next.js pages router`
325
339
 
326
340
  ## Styling
327
341
 
@@ -414,7 +428,7 @@ This plugin works with `rehype-parse` version 1+, `rehype-stringify` version 1+,
414
428
 
415
429
  ## Security
416
430
 
417
- Use of `rehype-highlight-code-lines` involves rehype (hast), but doesn't lead to cross-site scripting (XSS) attacks.
431
+ Use of **`rehype-highlight-code-lines`** involves rehype (hast), but doesn't lead to cross-site scripting (XSS) attacks.
418
432
 
419
433
  ## My Plugins
420
434
 
@@ -436,6 +450,8 @@ I like to contribute the Unified / Remark / MDX ecosystem, so I recommend you to
436
450
  – Remark plugin to expose the table of contents via `vfile.data` or via an option reference
437
451
  - [`remark-mdx-remove-esm`](https://www.npmjs.com/package/remark-mdx-remove-esm)
438
452
  – Remark plugin to remove import and/or export statements (mdxjsEsm)
453
+ - [`remark-mdx-remove-expressions`](https://www.npmjs.com/package/remark-mdx-remove-expressions)
454
+ – Remark plugin to remove MDX expressions within curlybraces {} in MDX content
439
455
 
440
456
  ### My Rehype Plugins
441
457
 
@@ -22,3 +22,4 @@ export declare function clsx(arr: (string | false | null | undefined | 0)[]): st
22
22
  */
23
23
  declare const plugin: Plugin<[HighlightLinesOptions?], Root>;
24
24
  export default plugin;
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAiC,MAAM,MAAM,CAAC;AAQhE,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,IAAI;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IACD,UAAU,UAAU;QAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;KACxC;CACF;AAMD,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAkBF,wBAAgB,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAE7E;AAgCD;;;;GAIG;AACH,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAyalD,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -65,8 +65,8 @@ const plugin = (options) => {
65
65
  newTree.push(elementContent);
66
66
  }
67
67
  else {
68
+ /* v8 ignore next -- @preserve */
68
69
  // @ts-expect-error className is different from other key of properties, and expected to be an array or undefined
69
- // /* v8 ignore next */
70
70
  const classNames = className.concat(elementContent.properties.className || []);
71
71
  if (elementContent.children.length === 1 &&
72
72
  elementContent.children[0].type !== "element") {
@@ -157,6 +157,8 @@ const plugin = (options) => {
157
157
  if (!REGEX_LINE_BREAKS_IN_THE_BEGINNING.test(textNode.value))
158
158
  return;
159
159
  const match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
160
+ // classic V8 coverage false negative
161
+ /* v8 ignore next -- @preserve */
160
162
  if (match) {
161
163
  code.children.unshift({ type: "text", value: match[0] });
162
164
  textNode.value = textNode.value.replace(REGEX_LINE_BREAKS_IN_THE_BEGINNING, "");
@@ -207,7 +209,8 @@ const plugin = (options) => {
207
209
  // this happens always in code fence if there is extra blank line at the end
208
210
  }
209
211
  else {
210
- replacement.push(createLine(line, ++lineNumber, directiveLineNumbering, directiveLineHighlighting), { type: "text", value: match[0] });
212
+ lineNumber++;
213
+ replacement.push(createLine(line, lineNumber, directiveLineNumbering, directiveLineHighlighting), { type: "text", value: match[0] });
211
214
  }
212
215
  start = index + 1;
213
216
  textStart = match.index + match[0].length;
@@ -227,7 +230,8 @@ const plugin = (options) => {
227
230
  replacement.push(...remainingLine);
228
231
  }
229
232
  else {
230
- replacement.push(createLine(remainingLine, ++lineNumber, directiveLineNumbering, directiveLineHighlighting));
233
+ lineNumber++;
234
+ replacement.push(createLine(remainingLine, lineNumber, directiveLineNumbering, directiveLineHighlighting));
231
235
  }
232
236
  }
233
237
  // Replace children with new array.
@@ -265,10 +269,9 @@ const plugin = (options) => {
265
269
  return;
266
270
  }
267
271
  // for type narrowing
272
+ /* v8 ignore if -- @preserve */
268
273
  if (!isStringArray(code.properties.className) &&
269
- code.properties.className !== undefined
270
- /* v8 ignore next 3 */
271
- ) {
274
+ code.properties.className !== undefined) {
272
275
  return;
273
276
  }
274
277
  /** the part of correcting language and meta */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin } from \"unified\";\nimport type { Root, Element, Text, ElementContent } from \"hast\";\nimport { visit, type VisitorResult } from \"unist-util-visit\";\nimport rangeParser from \"parse-numeric-range\";\n\ntype Prettify<T> = { [K in keyof T]: T[K] } & {};\n\ntype PartiallyRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;\n\ndeclare module \"hast\" {\n interface Data {\n meta?: string;\n }\n interface Properties {\n dataStartNumbering?: string;\n dataHighlightLines?: string;\n metastring?: string | null | undefined;\n }\n}\n\ntype ElementWithTextNode = Element & {\n children: [Text];\n};\n\nexport type HighlightLinesOptions = {\n showLineNumbers?: boolean;\n keepOuterBlankLine?: boolean;\n};\n\nconst DEFAULT_SETTINGS: HighlightLinesOptions = {\n showLineNumbers: false,\n keepOuterBlankLine: false,\n};\n\ntype PartiallyRequiredHighlightLinesOptions = Prettify<\n PartiallyRequired<HighlightLinesOptions, \"showLineNumbers\">\n>;\n\ntype GutterOptions = {\n directiveLineNumbering: boolean | number;\n directiveLineHighlighting: number[];\n directiveKeepOuterBlankLine: boolean;\n};\n\n// a simple util for our use case, like clsx package\nexport function clsx(arr: (string | false | null | undefined | 0)[]): string[] {\n return arr.filter((item): item is string => !!item);\n}\n\n// check if it is a string array\nfunction isStringArray(value: unknown): value is string[] {\n return (\n // type-coverage:ignore-next-line\n Array.isArray(value) && value.every((item) => typeof item === \"string\")\n );\n}\n\n// check if it is Element which first child is text\nfunction isElementWithTextNode(node: ElementContent | undefined): node is ElementWithTextNode {\n return (\n node?.type === \"element\" &&\n node.children.length === 1 &&\n node.children[0].type === \"text\" &&\n \"value\" in node.children[0]\n );\n}\n\nfunction hasClassName(node: ElementContent | undefined, className: string): boolean {\n return (\n node?.type === \"element\" &&\n isStringArray(node.properties.className) &&\n node.properties.className.some((cls) => cls.includes(className))\n );\n}\n\n// match all common types of line breaks\nconst REGEX_LINE_BREAKS = /\\r?\\n|\\r/g;\nconst REGEX_LINE_BREAKS_IN_THE_BEGINNING = /^(\\r?\\n|\\r)+/;\n\n/**\n *\n * add line numbers to code blocks and allow highlighting of desired code lines\n *\n */\nconst plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {\n const settings = Object.assign(\n {},\n DEFAULT_SETTINGS,\n options,\n ) as PartiallyRequiredHighlightLinesOptions;\n\n /**\n *\n * check code element children need flattening or not\n *\n */\n function hasFlatteningNeed(code: Element): boolean {\n const elementContents = code.children;\n\n // type ElementContent = Comment | Element | Text\n for (const elemenContent of elementContents) {\n if (elemenContent.type === \"element\" && Boolean(elemenContent.children.length))\n if (elemenContent.children.some((ec) => ec.type === \"element\")) return true;\n }\n\n return false;\n }\n\n /**\n *\n * flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx\n * mutates the code, recursively\n * inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js\n *\n */\n function flattenCodeTree(code: Element, className: string[] = []): ElementContent[] {\n const newTree: ElementContent[] = [];\n\n for (const elementContent of code.children) {\n if (elementContent.type === \"comment\" || elementContent.type === \"text\") {\n newTree.push(elementContent);\n } else {\n /* v8 ignore next -- @preserve */\n // @ts-expect-error className is different from other key of properties, and expected to be an array or undefined\n const classNames = className.concat(elementContent.properties.className || []);\n\n if (\n elementContent.children.length === 1 &&\n elementContent.children[0].type !== \"element\"\n ) {\n elementContent.properties.className = classNames;\n newTree.push(elementContent);\n } else {\n newTree.push(...flattenCodeTree(elementContent, classNames));\n }\n }\n }\n\n // Mutate the original code object\n code.children = newTree;\n return newTree;\n }\n\n /**\n *\n * construct the line element\n *\n */\n const createLine = (\n children: ElementContent[],\n lineNumber: number,\n directiveLineNumbering: boolean | number,\n directiveLineHighlighting: number[],\n ): Element => {\n const firstChild = children[0];\n const isAddition = hasClassName(firstChild, \"addition\");\n const isDeletion = hasClassName(firstChild, \"deletion\");\n\n return {\n type: \"element\",\n tagName: \"span\", // now it is always \"span\"\n children,\n properties: {\n className: clsx([\n \"code-line\",\n (directiveLineNumbering || directiveLineNumbering === 0) && \"numbered-code-line\",\n directiveLineHighlighting.includes(lineNumber) && \"highlighted-code-line\",\n isAddition && \"inserted\",\n isDeletion && \"deleted\",\n ]),\n dataLineNumber:\n typeof directiveLineNumbering === \"number\"\n ? directiveLineNumbering - 1 + lineNumber\n : directiveLineNumbering\n ? lineNumber\n : undefined,\n },\n };\n };\n\n /**\n *\n * handle elements which is multi line comment in code\n * mutates the code\n *\n */\n function handleMultiLineComments(code: Element): undefined {\n for (let index = 0; index < code.children.length; index++) {\n const replacement: ElementContent[] = [];\n\n const child = code.children[index];\n\n if (!isElementWithTextNode(child)) continue;\n\n const textNode = child.children[0];\n if (!REGEX_LINE_BREAKS.test(textNode.value)) continue;\n const comments = textNode.value.split(REGEX_LINE_BREAKS);\n\n for (let i = 0; i < comments.length; i++) {\n const newChild = structuredClone(child);\n newChild.children[0].value = comments[i];\n replacement.push(newChild);\n\n if (i < comments.length - 1) {\n replacement.push({ type: \"text\", value: \"\\n\" }); // eol\n }\n }\n\n code.children = [\n ...code.children.slice(0, index),\n ...replacement,\n ...code.children.slice(index + 1),\n ];\n }\n }\n\n /**\n *\n * handle eol characters in the beginning of the only first element\n * (because gutter function does not check the first element in the HAST whether contain eol at the beginning)\n * mutates the code\n *\n */\n function handleFirstElementContent(code: Element): undefined {\n const elementNode = code.children[0];\n if (!isElementWithTextNode(elementNode)) return;\n\n const textNode = elementNode.children[0];\n if (!REGEX_LINE_BREAKS_IN_THE_BEGINNING.test(textNode.value)) return;\n\n const match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);\n\n // classic V8 coverage false negative\n /* v8 ignore next -- @preserve */\n if (match) {\n code.children.unshift({ type: \"text\", value: match[0] });\n\n textNode.value = textNode.value.replace(REGEX_LINE_BREAKS_IN_THE_BEGINNING, \"\");\n }\n }\n\n /**\n *\n * finds the code lines from HAST of code element and costructs the lines\n * mutates the code\n *\n */\n function gutter(\n code: Element,\n {\n directiveLineNumbering,\n directiveLineHighlighting,\n directiveKeepOuterBlankLine,\n }: GutterOptions,\n ) {\n hasFlatteningNeed(code) && flattenCodeTree(code);\n\n handleFirstElementContent(code);\n handleMultiLineComments(code);\n\n const replacement: ElementContent[] = [];\n let start = 0;\n let startTextRemainder = \"\";\n let lineNumber = 0;\n\n for (let index = 0; index < code.children.length; index++) {\n const child = code.children[index];\n if (child.type !== \"text\") continue;\n\n let textStart = 0;\n const matches = Array.from(child.value.matchAll(REGEX_LINE_BREAKS));\n\n for (const [iteration, match] of matches.entries()) {\n // Nodes in this line. (current child (index) is exclusive)\n const line = code.children.slice(start, index);\n\n // Prepend text from a partial matched earlier text.\n if (startTextRemainder) {\n line.unshift({ type: \"text\", value: startTextRemainder });\n startTextRemainder = \"\";\n }\n\n // Append text from this text.\n if (match.index > textStart) {\n line.push({ type: \"text\", value: child.value.slice(textStart, match.index) });\n }\n\n const isFirstIteration = index === 0 && iteration === 0;\n const isLastIteration =\n index === code.children.length - 1 && iteration === matches.length - 1;\n\n if (isFirstIteration && !directiveKeepOuterBlankLine && line.length === 0) {\n // do nothing, intentionally\n // this happens in code fence if there is extra blank line at the beginning or\n // this happens in code html if there is eol right after <code> opening tag\n // replacement.push({ type: \"text\", value: match[0] }); // cancelled\n } else if (isLastIteration && !directiveKeepOuterBlankLine && line.length === 0) {\n // do nothing, intentionally\n // this happens always in code fence if there is extra blank line at the end\n } else {\n lineNumber++;\n\n replacement.push(\n createLine(line, lineNumber, directiveLineNumbering, directiveLineHighlighting),\n { type: \"text\", value: match[0] },\n );\n }\n\n start = index + 1;\n textStart = match.index + match[0].length;\n }\n\n // If we matched, make sure to not drop the text after the last line ending.\n if (start === index + 1) {\n startTextRemainder = child.value.slice(textStart);\n }\n }\n\n const remainingLine = code.children.slice(start);\n\n // Prepend text from a partial matched earlier text.\n if (startTextRemainder) {\n remainingLine.unshift({ type: \"text\", value: startTextRemainder });\n }\n\n if (remainingLine.length > 0) {\n if (remainingLine[0].type === \"text\" && remainingLine[0].value.trim() === \"\") {\n replacement.push(...remainingLine);\n } else {\n lineNumber++;\n\n replacement.push(\n createLine(\n remainingLine,\n lineNumber,\n directiveLineNumbering,\n directiveLineHighlighting,\n ),\n );\n }\n }\n\n // Replace children with new array.\n code.children = replacement;\n }\n\n /**\n *\n * get the programming language analyzing the classNames\n *\n */\n function getLanguage(classNames: string[] | undefined): string | undefined {\n if (!classNames) return;\n\n const isLanguageString = (element: string): boolean =>\n element.startsWith(\"language-\") || element.startsWith(\"lang-\");\n\n const languageString = classNames.find(isLanguageString);\n\n if (!languageString) return;\n\n const language = languageString.slice(languageString.indexOf(\"-\") + 1).toLowerCase();\n\n return language;\n }\n\n /**\n * Transform.\n *\n * @param {Root} tree\n * Tree.\n * @returns {undefined}\n * Nothing.\n */\n return (tree: Root): undefined => {\n visit(tree, \"element\", function (code, index, parent): VisitorResult {\n if (!parent || index === undefined || code.tagName !== \"code\") {\n return;\n }\n\n if (parent.type !== \"element\" || parent.tagName !== \"pre\") {\n return;\n }\n\n // for type narrowing\n /* v8 ignore if -- @preserve */\n if (\n !isStringArray(code.properties.className) &&\n code.properties.className !== undefined\n ) {\n return;\n }\n\n /** the part of correcting language and meta */\n\n let meta = (code.data?.meta || code.properties?.metastring || \"\").toLowerCase().trim();\n\n const language = getLanguage(code.properties.className);\n\n if (\n language &&\n (language.startsWith(\"{\") ||\n language.startsWith(\"showlinenumbers\") ||\n language.startsWith(\"nolinenumbers\") ||\n language.startsWith(\"keepouterblankline\"))\n ) {\n // add directives to meta\n meta = (language + \" \" + meta).trim();\n\n // remove classnames like hljs, lang-{1,3}, language-showLineNumbers, because of false positive\n code.properties.className = undefined;\n }\n\n /** the part of getting directives from code.properties.className */\n\n const keywords = [\"showlinenumbers\", \"nolinenumbers\", \"keepouterblankline\"];\n\n const directives = code.properties.className\n ?.map((cls) => cls.toLowerCase().replaceAll(\"-\", \"\"))\n .filter((cls) => keywords.includes(cls));\n\n /** the part of defining the line numbering directive */\n\n const directiveNoLineNumbers =\n meta.includes(\"nolinenumbers\") || Boolean(directives?.includes(\"nolinenumbers\"));\n\n const directiveShowLineNumbers =\n settings.showLineNumbers ||\n meta.includes(\"showlinenumbers\") ||\n Boolean(directives?.includes(\"showlinenumbers\"));\n\n let directiveLineNumbering: boolean | number = directiveNoLineNumbers\n ? false\n : directiveShowLineNumbers;\n\n // find the number where the line number starts, if exists\n const REGEX1 = /showlinenumbers=(?<start>\\d+)/;\n const start = REGEX1.exec(meta)?.groups?.start;\n\n if (!directiveNoLineNumbers && !isNaN(Number(start))) {\n directiveLineNumbering = Number(start);\n }\n\n // get the number where the line number starts, if exists\n const { dataStartNumbering } = code.properties;\n\n if (\n !directiveNoLineNumbers &&\n dataStartNumbering !== \"\" &&\n !isNaN(Number(dataStartNumbering))\n ) {\n directiveLineNumbering = Number(dataStartNumbering);\n }\n\n /** the part of defining the line highlighting directive */\n\n // find number range string within curly braces and parse it\n const directiveLineHighlighting: number[] = [];\n const REGEX2 = /{(?<lines>[\\d\\s,-]+)}/;\n const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\\s/g, \"\");\n\n if (strLineNumbers) {\n const range = rangeParser(strLineNumbers);\n directiveLineHighlighting.push(...range);\n }\n\n // get number range string within properties and parse it\n const { dataHighlightLines } = code.properties;\n\n if (dataHighlightLines) {\n const range = rangeParser(dataHighlightLines.replace(/\\s/g, \"\"));\n directiveLineHighlighting.push(...range);\n }\n\n /** the part of defining the directive for outer blank lines */\n\n // find the directive for trimming blank lines\n const directiveKeepOuterBlankLine =\n settings.keepOuterBlankLine ||\n /keepouterblankline/.test(meta) ||\n Boolean(directives?.includes(\"keepouterblankline\"));\n\n /** the part of cleaning the code properties */\n\n const classnamesFiltered = code.properties.className?.filter(\n (cls) => !keywords.includes(cls.toLowerCase().replaceAll(\"-\", \"\")),\n );\n\n code.properties.className = classnamesFiltered?.length ? classnamesFiltered : undefined;\n\n [\"dataStartNumbering\", \"dataHighlightLines\", \"metastring\"].forEach((property) => {\n if (property in code.properties) code.properties[property] = undefined;\n });\n\n /** the part of main logic */\n\n // if nothing to do for line numbering or line highlihting, just return;\n if (directiveLineNumbering === false && directiveLineHighlighting.length === 0) {\n return;\n }\n\n // add container for each line mutating the code element\n gutter(code, {\n directiveLineNumbering,\n directiveLineHighlighting,\n directiveKeepOuterBlankLine,\n });\n });\n };\n};\n\nexport default plugin;\n"]}
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,17 +1,23 @@
1
1
  {
2
2
  "name": "rehype-highlight-code-lines",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Rehype plugin to add line numbers to code blocks and allow highlighting of desired code lines",
5
5
  "type": "module",
6
- "exports": "./dist/esm/index.js",
7
- "main": "./dist/esm/index.js",
8
- "types": "./dist/esm/index.d.ts",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
9
15
  "scripts": {
10
16
  "build": "rimraf dist && tsc --build && type-coverage",
11
17
  "format": "npm run prettier && npm run lint",
12
18
  "prettier": "prettier --write .",
13
19
  "lint": "eslint .",
14
- "test": "vitest --watch=false",
20
+ "test": "vitest run",
15
21
  "test:watch": "vitest",
16
22
  "test:file1": "vitest test.md.spec.ts",
17
23
  "test:file2": "vitest test.html.spec.ts",
@@ -19,13 +25,12 @@
19
25
  "test:file4": "vitest from-rehype-highlight/test.rhcl2.spec.ts",
20
26
  "test:file5": "vitest test.raw.spec.ts",
21
27
  "test:file6": "vitest test.debug.spec.ts",
28
+ "test-coverage": "vitest run --coverage",
22
29
  "prepack": "npm run build",
23
- "prepublishOnly": "npm run test && npm run format && npm run test-coverage",
24
- "test-coverage": "vitest run --coverage"
30
+ "prepublishOnly": "npm run format && npm run test-coverage"
25
31
  },
26
32
  "files": [
27
33
  "dist/",
28
- "src/",
29
34
  "LICENSE",
30
35
  "README.md"
31
36
  ],
@@ -56,16 +61,17 @@
56
61
  "url": "https://github.com/ipikuka/rehype-highlight-code-lines/issues"
57
62
  },
58
63
  "devDependencies": {
59
- "@eslint/js": "^9.35.0",
64
+ "@eslint/js": "^10.0.1",
60
65
  "@types/dedent": "^0.7.2",
61
- "@types/node": "^24.3.1",
62
- "@vitest/coverage-v8": "^3.2.4",
63
- "@vitest/eslint-plugin": "^1.3.9",
64
- "dedent": "^1.7.0",
65
- "eslint": "^9.35.0",
66
+ "@types/node": "^24.10.13",
67
+ "@vitest/coverage-v8": "^4.0.18",
68
+ "@vitest/eslint-plugin": "^1.6.9",
69
+ "dedent": "^1.7.1",
70
+ "eslint": "^10.0.0",
66
71
  "eslint-config-prettier": "^10.1.8",
67
- "eslint-plugin-prettier": "^5.5.4",
68
- "prettier": "^3.6.2",
72
+ "eslint-plugin-prettier": "^5.5.5",
73
+ "globals": "^17.3.0",
74
+ "prettier": "^3.8.1",
69
75
  "rehype": "^13.0.2",
70
76
  "rehype-highlight": "^7.0.2",
71
77
  "rehype-parse": "^9.0.1",
@@ -74,19 +80,19 @@
74
80
  "remark-gfm": "^4.0.1",
75
81
  "remark-parse": "^11.0.0",
76
82
  "remark-rehype": "^11.1.2",
77
- "rimraf": "^6.0.1",
83
+ "rimraf": "^6.1.3",
78
84
  "type-coverage": "^2.29.7",
79
- "typescript": "^5.9.2",
80
- "typescript-eslint": "^8.43.0",
85
+ "typescript": "^5.9.3",
86
+ "typescript-eslint": "^8.56.0",
81
87
  "unified": "^11.0.5",
82
88
  "unist-util-remove-position": "^5.0.0",
83
89
  "vfile": "^6.0.3",
84
- "vitest": "^3.2.4"
90
+ "vitest": "^4.0.18"
85
91
  },
86
92
  "dependencies": {
87
93
  "@types/hast": "^3.0.4",
88
94
  "parse-numeric-range": "^1.3.0",
89
- "unist-util-visit": "^5.0.0"
95
+ "unist-util-visit": "^5.1.0"
90
96
  },
91
97
  "peerDependencies": {
92
98
  "unified": "^11"
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"root":["../../src/index.ts"],"version":"5.9.2"}
package/src/index.ts DELETED
@@ -1,506 +0,0 @@
1
- import type { Plugin } from "unified";
2
- import type { Root, Element, Text, ElementContent } from "hast";
3
- import { visit, type VisitorResult } from "unist-util-visit";
4
- import rangeParser from "parse-numeric-range";
5
-
6
- type Prettify<T> = { [K in keyof T]: T[K] } & {};
7
-
8
- type PartiallyRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
9
-
10
- declare module "hast" {
11
- interface Data {
12
- meta?: string;
13
- }
14
- interface Properties {
15
- dataStartNumbering?: string;
16
- dataHighlightLines?: string;
17
- metastring?: string | null | undefined;
18
- }
19
- }
20
-
21
- type ElementWithTextNode = Element & {
22
- children: [Text];
23
- };
24
-
25
- export type HighlightLinesOptions = {
26
- showLineNumbers?: boolean;
27
- keepOuterBlankLine?: boolean;
28
- };
29
-
30
- const DEFAULT_SETTINGS: HighlightLinesOptions = {
31
- showLineNumbers: false,
32
- keepOuterBlankLine: false,
33
- };
34
-
35
- type PartiallyRequiredHighlightLinesOptions = Prettify<
36
- PartiallyRequired<HighlightLinesOptions, "showLineNumbers">
37
- >;
38
-
39
- type GutterOptions = {
40
- directiveLineNumbering: boolean | number;
41
- directiveLineHighlighting: number[];
42
- directiveKeepOuterBlankLine: boolean;
43
- };
44
-
45
- // a simple util for our use case, like clsx package
46
- export function clsx(arr: (string | false | null | undefined | 0)[]): string[] {
47
- return arr.filter((item): item is string => !!item);
48
- }
49
-
50
- // check if it is a string array
51
- function isStringArray(value: unknown): value is string[] {
52
- return (
53
- // type-coverage:ignore-next-line
54
- Array.isArray(value) && value.every((item) => typeof item === "string")
55
- );
56
- }
57
-
58
- // check if it is Element which first child is text
59
- function isElementWithTextNode(node: ElementContent | undefined): node is ElementWithTextNode {
60
- return (
61
- node?.type === "element" &&
62
- node.children.length === 1 &&
63
- node.children[0].type === "text" &&
64
- "value" in node.children[0]
65
- );
66
- }
67
-
68
- function hasClassName(node: ElementContent | undefined, className: string): boolean {
69
- return (
70
- node?.type === "element" &&
71
- isStringArray(node.properties.className) &&
72
- node.properties.className.some((cls) => cls.includes(className))
73
- );
74
- }
75
-
76
- // match all common types of line breaks
77
- const REGEX_LINE_BREAKS = /\r?\n|\r/g;
78
- const REGEX_LINE_BREAKS_IN_THE_BEGINNING = /^(\r?\n|\r)+/;
79
-
80
- /**
81
- *
82
- * add line numbers to code blocks and allow highlighting of desired code lines
83
- *
84
- */
85
- const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
86
- const settings = Object.assign(
87
- {},
88
- DEFAULT_SETTINGS,
89
- options,
90
- ) as PartiallyRequiredHighlightLinesOptions;
91
-
92
- /**
93
- *
94
- * check code element children need flattening or not
95
- *
96
- */
97
- function hasFlatteningNeed(code: Element): boolean {
98
- const elementContents = code.children;
99
-
100
- // type ElementContent = Comment | Element | Text
101
- for (const elemenContent of elementContents) {
102
- if (elemenContent.type === "element" && Boolean(elemenContent.children.length))
103
- if (elemenContent.children.some((ec) => ec.type === "element")) return true;
104
- }
105
-
106
- return false;
107
- }
108
-
109
- /**
110
- *
111
- * flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx
112
- * mutates the code, recursively
113
- * inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js
114
- *
115
- */
116
- function flattenCodeTree(code: Element, className: string[] = []): ElementContent[] {
117
- const newTree: ElementContent[] = [];
118
-
119
- for (const elementContent of code.children) {
120
- if (elementContent.type === "comment" || elementContent.type === "text") {
121
- newTree.push(elementContent);
122
- } else {
123
- // @ts-expect-error className is different from other key of properties, and expected to be an array or undefined
124
- // /* v8 ignore next */
125
- const classNames = className.concat(elementContent.properties.className || []);
126
-
127
- if (
128
- elementContent.children.length === 1 &&
129
- elementContent.children[0].type !== "element"
130
- ) {
131
- elementContent.properties.className = classNames;
132
- newTree.push(elementContent);
133
- } else {
134
- newTree.push(...flattenCodeTree(elementContent, classNames));
135
- }
136
- }
137
- }
138
-
139
- // Mutate the original code object
140
- code.children = newTree;
141
- return newTree;
142
- }
143
-
144
- /**
145
- *
146
- * construct the line element
147
- *
148
- */
149
- const createLine = (
150
- children: ElementContent[],
151
- lineNumber: number,
152
- directiveLineNumbering: boolean | number,
153
- directiveLineHighlighting: number[],
154
- ): Element => {
155
- const firstChild = children[0];
156
- const isAddition = hasClassName(firstChild, "addition");
157
- const isDeletion = hasClassName(firstChild, "deletion");
158
-
159
- return {
160
- type: "element",
161
- tagName: "span", // now it is always "span"
162
- children,
163
- properties: {
164
- className: clsx([
165
- "code-line",
166
- (directiveLineNumbering || directiveLineNumbering === 0) && "numbered-code-line",
167
- directiveLineHighlighting.includes(lineNumber) && "highlighted-code-line",
168
- isAddition && "inserted",
169
- isDeletion && "deleted",
170
- ]),
171
- dataLineNumber:
172
- typeof directiveLineNumbering === "number"
173
- ? directiveLineNumbering - 1 + lineNumber
174
- : directiveLineNumbering
175
- ? lineNumber
176
- : undefined,
177
- },
178
- };
179
- };
180
-
181
- /**
182
- *
183
- * handle elements which is multi line comment in code
184
- * mutates the code
185
- *
186
- */
187
- function handleMultiLineComments(code: Element): undefined {
188
- for (let index = 0; index < code.children.length; index++) {
189
- const replacement: ElementContent[] = [];
190
-
191
- const child = code.children[index];
192
-
193
- if (!isElementWithTextNode(child)) continue;
194
-
195
- const textNode = child.children[0];
196
- if (!REGEX_LINE_BREAKS.test(textNode.value)) continue;
197
- const comments = textNode.value.split(REGEX_LINE_BREAKS);
198
-
199
- for (let i = 0; i < comments.length; i++) {
200
- const newChild = structuredClone(child);
201
- newChild.children[0].value = comments[i];
202
- replacement.push(newChild);
203
-
204
- if (i < comments.length - 1) {
205
- replacement.push({ type: "text", value: "\n" }); // eol
206
- }
207
- }
208
-
209
- code.children = [
210
- ...code.children.slice(0, index),
211
- ...replacement,
212
- ...code.children.slice(index + 1),
213
- ];
214
- }
215
- }
216
-
217
- /**
218
- *
219
- * handle eol characters in the beginning of the only first element
220
- * (because gutter function does not check the first element in the HAST whether contain eol at the beginning)
221
- * mutates the code
222
- *
223
- */
224
- function handleFirstElementContent(code: Element): undefined {
225
- const elementNode = code.children[0];
226
- if (!isElementWithTextNode(elementNode)) return;
227
-
228
- const textNode = elementNode.children[0];
229
- if (!REGEX_LINE_BREAKS_IN_THE_BEGINNING.test(textNode.value)) return;
230
-
231
- const match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
232
-
233
- if (match) {
234
- code.children.unshift({ type: "text", value: match[0] });
235
-
236
- textNode.value = textNode.value.replace(REGEX_LINE_BREAKS_IN_THE_BEGINNING, "");
237
- }
238
- }
239
-
240
- /**
241
- *
242
- * finds the code lines from HAST of code element and costructs the lines
243
- * mutates the code
244
- *
245
- */
246
- function gutter(
247
- code: Element,
248
- {
249
- directiveLineNumbering,
250
- directiveLineHighlighting,
251
- directiveKeepOuterBlankLine,
252
- }: GutterOptions,
253
- ) {
254
- hasFlatteningNeed(code) && flattenCodeTree(code);
255
-
256
- handleFirstElementContent(code);
257
- handleMultiLineComments(code);
258
-
259
- const replacement: ElementContent[] = [];
260
- let start = 0;
261
- let startTextRemainder = "";
262
- let lineNumber = 0;
263
-
264
- for (let index = 0; index < code.children.length; index++) {
265
- const child = code.children[index];
266
- if (child.type !== "text") continue;
267
-
268
- let textStart = 0;
269
- const matches = Array.from(child.value.matchAll(REGEX_LINE_BREAKS));
270
-
271
- for (const [iteration, match] of matches.entries()) {
272
- // Nodes in this line. (current child (index) is exclusive)
273
- const line = code.children.slice(start, index);
274
-
275
- // Prepend text from a partial matched earlier text.
276
- if (startTextRemainder) {
277
- line.unshift({ type: "text", value: startTextRemainder });
278
- startTextRemainder = "";
279
- }
280
-
281
- // Append text from this text.
282
- if (match.index > textStart) {
283
- line.push({ type: "text", value: child.value.slice(textStart, match.index) });
284
- }
285
-
286
- const isFirstIteration = index === 0 && iteration === 0;
287
- const isLastIteration =
288
- index === code.children.length - 1 && iteration === matches.length - 1;
289
-
290
- if (isFirstIteration && !directiveKeepOuterBlankLine && line.length === 0) {
291
- // do nothing, intentionally
292
- // this happens in code fence if there is extra blank line at the beginning or
293
- // this happens in code html if there is eol right after <code> opening tag
294
- // replacement.push({ type: "text", value: match[0] }); // cancelled
295
- } else if (isLastIteration && !directiveKeepOuterBlankLine && line.length === 0) {
296
- // do nothing, intentionally
297
- // this happens always in code fence if there is extra blank line at the end
298
- } else {
299
- replacement.push(
300
- createLine(line, ++lineNumber, directiveLineNumbering, directiveLineHighlighting),
301
- { type: "text", value: match[0] },
302
- );
303
- }
304
-
305
- start = index + 1;
306
- textStart = match.index + match[0].length;
307
- }
308
-
309
- // If we matched, make sure to not drop the text after the last line ending.
310
- if (start === index + 1) {
311
- startTextRemainder = child.value.slice(textStart);
312
- }
313
- }
314
-
315
- const remainingLine = code.children.slice(start);
316
-
317
- // Prepend text from a partial matched earlier text.
318
- if (startTextRemainder) {
319
- remainingLine.unshift({ type: "text", value: startTextRemainder });
320
- }
321
-
322
- if (remainingLine.length > 0) {
323
- if (remainingLine[0].type === "text" && remainingLine[0].value.trim() === "") {
324
- replacement.push(...remainingLine);
325
- } else {
326
- replacement.push(
327
- createLine(
328
- remainingLine,
329
- ++lineNumber,
330
- directiveLineNumbering,
331
- directiveLineHighlighting,
332
- ),
333
- );
334
- }
335
- }
336
-
337
- // Replace children with new array.
338
- code.children = replacement;
339
- }
340
-
341
- /**
342
- *
343
- * get the programming language analyzing the classNames
344
- *
345
- */
346
- function getLanguage(classNames: string[] | undefined): string | undefined {
347
- if (!classNames) return;
348
-
349
- const isLanguageString = (element: string): boolean =>
350
- element.startsWith("language-") || element.startsWith("lang-");
351
-
352
- const languageString = classNames.find(isLanguageString);
353
-
354
- if (!languageString) return;
355
-
356
- const language = languageString.slice(languageString.indexOf("-") + 1).toLowerCase();
357
-
358
- return language;
359
- }
360
-
361
- /**
362
- * Transform.
363
- *
364
- * @param {Root} tree
365
- * Tree.
366
- * @returns {undefined}
367
- * Nothing.
368
- */
369
- return (tree: Root): undefined => {
370
- visit(tree, "element", function (code, index, parent): VisitorResult {
371
- if (!parent || index === undefined || code.tagName !== "code") {
372
- return;
373
- }
374
-
375
- if (parent.type !== "element" || parent.tagName !== "pre") {
376
- return;
377
- }
378
-
379
- // for type narrowing
380
- if (
381
- !isStringArray(code.properties.className) &&
382
- code.properties.className !== undefined
383
- /* v8 ignore next 3 */
384
- ) {
385
- return;
386
- }
387
-
388
- /** the part of correcting language and meta */
389
-
390
- let meta = (code.data?.meta || code.properties?.metastring || "").toLowerCase().trim();
391
-
392
- const language = getLanguage(code.properties.className);
393
-
394
- if (
395
- language &&
396
- (language.startsWith("{") ||
397
- language.startsWith("showlinenumbers") ||
398
- language.startsWith("nolinenumbers") ||
399
- language.startsWith("keepouterblankline"))
400
- ) {
401
- // add directives to meta
402
- meta = (language + " " + meta).trim();
403
-
404
- // remove classnames like hljs, lang-{1,3}, language-showLineNumbers, because of false positive
405
- code.properties.className = undefined;
406
- }
407
-
408
- /** the part of getting directives from code.properties.className */
409
-
410
- const keywords = ["showlinenumbers", "nolinenumbers", "keepouterblankline"];
411
-
412
- const directives = code.properties.className
413
- ?.map((cls) => cls.toLowerCase().replaceAll("-", ""))
414
- .filter((cls) => keywords.includes(cls));
415
-
416
- /** the part of defining the line numbering directive */
417
-
418
- const directiveNoLineNumbers =
419
- meta.includes("nolinenumbers") || Boolean(directives?.includes("nolinenumbers"));
420
-
421
- const directiveShowLineNumbers =
422
- settings.showLineNumbers ||
423
- meta.includes("showlinenumbers") ||
424
- Boolean(directives?.includes("showlinenumbers"));
425
-
426
- let directiveLineNumbering: boolean | number = directiveNoLineNumbers
427
- ? false
428
- : directiveShowLineNumbers;
429
-
430
- // find the number where the line number starts, if exists
431
- const REGEX1 = /showlinenumbers=(?<start>\d+)/;
432
- const start = REGEX1.exec(meta)?.groups?.start;
433
-
434
- if (!directiveNoLineNumbers && !isNaN(Number(start))) {
435
- directiveLineNumbering = Number(start);
436
- }
437
-
438
- // get the number where the line number starts, if exists
439
- const { dataStartNumbering } = code.properties;
440
-
441
- if (
442
- !directiveNoLineNumbers &&
443
- dataStartNumbering !== "" &&
444
- !isNaN(Number(dataStartNumbering))
445
- ) {
446
- directiveLineNumbering = Number(dataStartNumbering);
447
- }
448
-
449
- /** the part of defining the line highlighting directive */
450
-
451
- // find number range string within curly braces and parse it
452
- const directiveLineHighlighting: number[] = [];
453
- const REGEX2 = /{(?<lines>[\d\s,-]+)}/;
454
- const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\s/g, "");
455
-
456
- if (strLineNumbers) {
457
- const range = rangeParser(strLineNumbers);
458
- directiveLineHighlighting.push(...range);
459
- }
460
-
461
- // get number range string within properties and parse it
462
- const { dataHighlightLines } = code.properties;
463
-
464
- if (dataHighlightLines) {
465
- const range = rangeParser(dataHighlightLines.replace(/\s/g, ""));
466
- directiveLineHighlighting.push(...range);
467
- }
468
-
469
- /** the part of defining the directive for outer blank lines */
470
-
471
- // find the directive for trimming blank lines
472
- const directiveKeepOuterBlankLine =
473
- settings.keepOuterBlankLine ||
474
- /keepouterblankline/.test(meta) ||
475
- Boolean(directives?.includes("keepouterblankline"));
476
-
477
- /** the part of cleaning the code properties */
478
-
479
- const classnamesFiltered = code.properties.className?.filter(
480
- (cls) => !keywords.includes(cls.toLowerCase().replaceAll("-", "")),
481
- );
482
-
483
- code.properties.className = classnamesFiltered?.length ? classnamesFiltered : undefined;
484
-
485
- ["dataStartNumbering", "dataHighlightLines", "metastring"].forEach((property) => {
486
- if (property in code.properties) code.properties[property] = undefined;
487
- });
488
-
489
- /** the part of main logic */
490
-
491
- // if nothing to do for line numbering or line highlihting, just return;
492
- if (directiveLineNumbering === false && directiveLineHighlighting.length === 0) {
493
- return;
494
- }
495
-
496
- // add container for each line mutating the code element
497
- gutter(code, {
498
- directiveLineNumbering,
499
- directiveLineHighlighting,
500
- directiveKeepOuterBlankLine,
501
- });
502
- });
503
- };
504
- };
505
-
506
- export default plugin;