rehype-highlight-code-lines 1.0.5 → 1.0.7

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.
@@ -1,5 +1,10 @@
1
1
  import type { Plugin } from "unified";
2
2
  import type { Root } from "hast";
3
+ declare module "hast" {
4
+ interface Data {
5
+ meta?: string | undefined;
6
+ }
7
+ }
3
8
  export type HighlightLinesOptions = {
4
9
  showLineNumbers?: boolean;
5
10
  /**
package/dist/esm/index.js CHANGED
@@ -8,6 +8,24 @@ const DEFAULT_SETTINGS = {
8
8
  export function clsx(arr) {
9
9
  return arr.filter((item) => !!item);
10
10
  }
11
+ // check if it is string array
12
+ function isStringArray(value) {
13
+ return (
14
+ // type-coverage:ignore-next-line
15
+ Array.isArray(value) && value.every((item) => typeof item === "string"));
16
+ }
17
+ // check if it is Element which first child is text
18
+ function isElementWithTextNode(node) {
19
+ return (node?.type === "element" && node.children[0]?.type === "text" && "value" in node.children[0]);
20
+ }
21
+ function hasClassName(node, className) {
22
+ return (node?.type === "element" &&
23
+ isStringArray(node.properties.className) &&
24
+ node.properties.className.some((cls) => cls.includes(className)));
25
+ }
26
+ // match all common types of line breaks
27
+ const REGEX_LINE_BREAKS = /\r?\n|\r/g;
28
+ const REGEX_LINE_BREAKS_IN_THE_BEGINNING = /^(\r?\n|\r)/;
11
29
  /**
12
30
  *
13
31
  * add line numbers to code blocks and allow highlighting of desired code lines
@@ -20,19 +38,20 @@ const plugin = (options) => {
20
38
  * check code element children need flattening or not
21
39
  *
22
40
  */
23
- function checkCodeTreeForFlatteningNeed(code) {
41
+ function hasFlatteningNeed(code) {
24
42
  const elementContents = code.children;
25
43
  // type ElementContent = Comment | Element | Text
26
44
  for (const elemenContent of elementContents) {
27
- if (elemenContent.type === "element")
28
- if (elemenContent.children.length >= 1 && elemenContent.children[0].type === "element")
45
+ if (elemenContent.type === "element" && Boolean(elemenContent.children.length))
46
+ if (elemenContent.children.some((ec) => ec.type === "element"))
29
47
  return true;
30
48
  }
31
49
  return false;
32
50
  }
33
51
  /**
34
52
  *
35
- * flatten code element children, recursively
53
+ * flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx
54
+ * mutates the code, recursively
36
55
  * inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js
37
56
  *
38
57
  */
@@ -65,14 +84,10 @@ const plugin = (options) => {
65
84
  * construct the line element
66
85
  *
67
86
  */
68
- const createLine = (children, lineNumber, startingNumber, directiveShowLineNumbers, linesToBeHighlighted) => {
87
+ const createLine = (children, lineNumber, directiveShowLineNumbers, directiveHighlightLines) => {
69
88
  const firstChild = children[0];
70
- const isAddition = firstChild?.type === "element" &&
71
- Array.isArray(firstChild.properties.className) &&
72
- firstChild.properties.className.some((cls) => typeof cls === "string" && cls.includes("addition"));
73
- const isDeletion = firstChild?.type === "element" &&
74
- Array.isArray(firstChild.properties.className) &&
75
- firstChild.properties.className.some((cls) => typeof cls === "string" && cls.includes("deletion"));
89
+ const isAddition = hasClassName(firstChild, "addition");
90
+ const isDeletion = hasClassName(firstChild, "deletion");
76
91
  return {
77
92
  type: "element",
78
93
  tagName: "span", // now it is always "span"
@@ -81,16 +96,76 @@ const plugin = (options) => {
81
96
  className: clsx([
82
97
  "code-line",
83
98
  directiveShowLineNumbers && "numbered-code-line",
84
- linesToBeHighlighted.includes(lineNumber) && "highlighted-code-line",
99
+ directiveHighlightLines.includes(lineNumber) && "highlighted-code-line",
85
100
  isAddition && "inserted",
86
101
  isDeletion && "deleted",
87
102
  ]),
88
- dataLineNumber: directiveShowLineNumbers ? startingNumber - 1 + lineNumber : undefined,
103
+ dataLineNumber: typeof directiveShowLineNumbers === "number"
104
+ ? directiveShowLineNumbers - 1 + lineNumber
105
+ : directiveShowLineNumbers
106
+ ? lineNumber
107
+ : undefined,
89
108
  },
90
109
  };
91
110
  };
92
- // match all common types of line breaks
93
- const REGEX_LINE_BREAKS = /\r?\n|\r/g;
111
+ /**
112
+ *
113
+ * handle elements which is multi line comment in code
114
+ * mutates the code
115
+ *
116
+ */
117
+ function handleMultiLineComments(code) {
118
+ for (let index = 0; index < code.children.length; index++) {
119
+ const replacement = [];
120
+ const child = code.children[index];
121
+ if (!isElementWithTextNode(child))
122
+ continue;
123
+ if (!hasClassName(child, "comment"))
124
+ continue;
125
+ const textNode = child.children[0];
126
+ if (!REGEX_LINE_BREAKS.test(textNode.value))
127
+ continue;
128
+ const comments = textNode.value.split(REGEX_LINE_BREAKS);
129
+ for (let i = 0; i < comments.length; i++) {
130
+ const newChild = structuredClone(child);
131
+ newChild.children[0].value = comments[i];
132
+ replacement.push(newChild);
133
+ if (i < comments.length - 1) {
134
+ replacement.push({ type: "text", value: "\n" }); // eol
135
+ }
136
+ }
137
+ code.children = [
138
+ ...code.children.slice(0, index),
139
+ ...replacement,
140
+ ...code.children.slice(index + 1),
141
+ ];
142
+ }
143
+ }
144
+ /**
145
+ *
146
+ * handle eol characters in the beginning of the only first element
147
+ * (because gutter function does not check the first element in the HAST whether contain eol at the beginning)
148
+ * mutates the code
149
+ *
150
+ */
151
+ function handleFirstElementContent(code) {
152
+ const replacement = [];
153
+ const elementNode = code.children[0];
154
+ if (!isElementWithTextNode(elementNode))
155
+ return;
156
+ const textNode = elementNode.children[0];
157
+ if (!REGEX_LINE_BREAKS_IN_THE_BEGINNING.test(textNode.value))
158
+ return;
159
+ let match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
160
+ while (match !== null) {
161
+ replacement.push({ type: "text", value: match[0] });
162
+ // Update the child value
163
+ textNode.value = textNode.value.slice(1);
164
+ // iterate the match
165
+ match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
166
+ }
167
+ code.children.unshift(...replacement);
168
+ }
94
169
  /**
95
170
  *
96
171
  * check the code line is empty or with value only spaces
@@ -100,21 +175,33 @@ const plugin = (options) => {
100
175
  return (line.length === 0 ||
101
176
  (line.length === 1 && line[0].type === "text" && line[0].value.trim() === ""));
102
177
  }
103
- function gutter(tree, directiveShowLineNumbers, startingNumber, linesToBeHighlighted) {
178
+ /**
179
+ *
180
+ * extract the lines from HAST of code element
181
+ * mutates the code
182
+ *
183
+ */
184
+ function gutter(code, { directiveShowLineNumbers, directiveHighlightLines, }) {
185
+ hasFlatteningNeed(code) && flattenCodeTree(code); // mutates the code
186
+ handleMultiLineComments(code); // mutates the code
187
+ handleFirstElementContent(code); // mutates the code
104
188
  const replacement = [];
105
- let index = -1;
106
189
  let start = 0;
107
190
  let startTextRemainder = "";
108
191
  let lineNumber = 0;
109
- while (++index < tree.children.length) {
110
- const child = tree.children[index];
192
+ for (let index = 0; index < code.children.length; index++) {
193
+ const child = code.children[index];
194
+ // if (index === 0 && /^[\n][\s]*$/.test(child.value)) {
195
+ // console.log(child.value, index);
196
+ // }
111
197
  if (child.type !== "text")
112
198
  continue;
113
199
  let textStart = 0;
114
200
  let match = REGEX_LINE_BREAKS.exec(child.value);
115
201
  while (match !== null) {
116
202
  // Nodes in this line. (current child is exclusive)
117
- const line = tree.children.slice(start, index);
203
+ // Array.prototype.slice() start to end (end not included)
204
+ const line = code.children.slice(start, index);
118
205
  // Prepend text from a partial matched earlier text.
119
206
  if (startTextRemainder) {
120
207
  line.unshift({ type: "text", value: startTextRemainder });
@@ -125,12 +212,8 @@ const plugin = (options) => {
125
212
  const value = child.value.slice(textStart, match.index);
126
213
  line.push({ type: "text", value });
127
214
  }
128
- if (!isEmptyLine(line)) {
129
- lineNumber += 1;
130
- replacement.push(createLine(line, lineNumber, startingNumber, directiveShowLineNumbers, linesToBeHighlighted));
131
- }
132
- // Add eol
133
- replacement.push({ type: "text", value: match[0] });
215
+ lineNumber += 1;
216
+ replacement.push(createLine(line, lineNumber, directiveShowLineNumbers, directiveHighlightLines), { type: "text", value: match[0] });
134
217
  start = index + 1;
135
218
  textStart = match.index + match[0].length;
136
219
  // iterate the match
@@ -141,20 +224,23 @@ const plugin = (options) => {
141
224
  startTextRemainder = child.value.slice(textStart);
142
225
  }
143
226
  }
144
- const line = tree.children.slice(start);
227
+ const line = code.children.slice(start);
145
228
  // Prepend text from a partial matched earlier text.
146
229
  if (startTextRemainder) {
147
230
  line.unshift({ type: "text", value: startTextRemainder });
148
231
  startTextRemainder = "";
149
232
  }
150
- if (!isEmptyLine(line)) {
151
- if (line.length > 0) {
233
+ if (line.length > 0) {
234
+ if (isEmptyLine(line)) {
235
+ replacement.push(...line);
236
+ }
237
+ else {
152
238
  lineNumber += 1;
153
- replacement.push(createLine(line, lineNumber, startingNumber, directiveShowLineNumbers, linesToBeHighlighted));
239
+ replacement.push(createLine(line, lineNumber, directiveShowLineNumbers, directiveHighlightLines));
154
240
  }
155
241
  }
156
242
  // Replace children with new array.
157
- tree.children = replacement;
243
+ code.children = replacement;
158
244
  }
159
245
  /**
160
246
  *
@@ -183,53 +269,51 @@ const plugin = (options) => {
183
269
  * Nothing.
184
270
  */
185
271
  return (tree) => {
186
- visit(tree, "element", function (node, index, parent) {
187
- if (!parent || index === undefined || node.tagName !== "code") {
272
+ visit(tree, "element", function (code, index, parent) {
273
+ if (!parent || index === undefined || code.tagName !== "code") {
188
274
  return;
189
275
  }
190
276
  if (parent.type !== "element" || parent.tagName !== "pre") {
191
277
  return;
192
278
  }
193
- const code = node;
194
279
  const classNames = code.properties.className;
195
280
  // only for type narrowing
196
281
  /* v8 ignore next */
197
- if (!Array.isArray(classNames) && classNames !== undefined)
282
+ if (!isStringArray(classNames) && classNames !== undefined)
198
283
  return;
199
- let meta = code.data?.meta?.toLowerCase().trim() || "";
284
+ let meta = code.data?.meta?.toLowerCase().trim() ?? "";
200
285
  const language = getLanguage(classNames);
201
286
  if (language?.startsWith("{") ||
202
287
  language?.startsWith("showlinenumbers") ||
203
288
  language?.startsWith("nolinenumbers")) {
204
289
  // add specifiers to meta
205
290
  meta = (language + " " + meta).trim();
206
- // remove all classnames like hljs, lang-x, language-x, because of false positive
291
+ // correct the code's meta
292
+ code.data && (code.data.meta = meta);
293
+ // remove all classnames like hljs, lang-{1,3}, language-showLineNumbers, because of false positive
207
294
  code.properties.className = undefined;
208
295
  }
209
- const directiveShowLineNumbers = meta.includes("nolinenumbers")
296
+ let directiveShowLineNumbers = meta.includes("nolinenumbers")
210
297
  ? false
211
298
  : settings.showLineNumbers || meta.includes("showlinenumbers");
212
- let startingNumber = 1;
213
299
  // find the number where the line number starts, if exists
214
- if (directiveShowLineNumbers) {
215
- const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
216
- const start = REGEX1.exec(meta)?.groups?.start;
217
- if (start && !isNaN(Number(start)))
218
- startingNumber = Number(start);
219
- }
300
+ const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
301
+ const start = REGEX1.exec(meta)?.groups?.start;
302
+ if (start && !isNaN(Number(start)))
303
+ directiveShowLineNumbers = Number(start);
220
304
  // find number range string within curly braces and parse it
221
305
  const REGEX2 = /{(?<lines>[\d\s,-]+)}/g;
222
306
  const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\s/g, "");
223
- const linesToBeHighlighted = strLineNumbers ? rangeParser(strLineNumbers) : [];
224
- // if nothing to do for numbering and highlihting, just return
225
- if (!directiveShowLineNumbers && linesToBeHighlighted.length === 0)
307
+ const directiveHighlightLines = strLineNumbers ? rangeParser(strLineNumbers) : [];
308
+ // if nothing to do for numbering, highlihting or trimming blank lines, just return;
309
+ if (directiveShowLineNumbers === false && directiveHighlightLines.length === 0) {
226
310
  return;
227
- // flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx
228
- if (checkCodeTreeForFlatteningNeed(code)) {
229
- flattenCodeTree(code);
230
311
  }
231
312
  // add container for each line mutating the code element
232
- gutter(code, directiveShowLineNumbers, startingNumber, linesToBeHighlighted);
313
+ gutter(code, {
314
+ directiveShowLineNumbers,
315
+ directiveHighlightLines,
316
+ });
233
317
  });
234
318
  };
235
319
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rehype-highlight-code-lines",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Rehype plugin to add line numbers to code blocks and allow highlighting of desired code lines",
5
5
  "type": "module",
6
6
  "exports": "./dist/esm/index.js",
@@ -13,7 +13,8 @@
13
13
  "lint": "eslint .",
14
14
  "test": "vitest --watch=false",
15
15
  "test:watch": "vitest",
16
- "test:file": "vitest test.html.spec.ts",
16
+ "test:file1": "vitest test.markdown.spec.ts",
17
+ "test:file2": "vitest test.cases.spec.ts",
17
18
  "prepack": "npm run build",
18
19
  "prepublishOnly": "npm run test && npm run format && npm run test-coverage",
19
20
  "test-coverage": "vitest run --coverage"
@@ -51,16 +52,16 @@
51
52
  "url": "https://github.com/ipikuka/rehype-highlight-code-lines/issues"
52
53
  },
53
54
  "devDependencies": {
54
- "@eslint/js": "^9.19.0",
55
+ "@eslint/js": "^9.20.0",
55
56
  "@types/dedent": "^0.7.2",
56
57
  "@types/node": "^22.13.1",
57
58
  "@vitest/coverage-v8": "^3.0.5",
58
- "@vitest/eslint-plugin": "^1.1.25",
59
+ "@vitest/eslint-plugin": "^1.1.27",
59
60
  "dedent": "^1.5.3",
60
- "eslint": "^9.19.0",
61
+ "eslint": "^9.20.0",
61
62
  "eslint-config-prettier": "^10.0.1",
62
63
  "eslint-plugin-prettier": "^5.2.3",
63
- "prettier": "^3.4.2",
64
+ "prettier": "^3.5.0",
64
65
  "rehype": "^13.0.2",
65
66
  "rehype-highlight": "^7.0.2",
66
67
  "rehype-parse": "^9.0.1",
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Plugin } from "unified";
2
- import type { Root, Element, ElementContent, ElementData } from "hast";
2
+ import type { Root, Element, Text, ElementContent } from "hast";
3
3
  import { visit, type VisitorResult } from "unist-util-visit";
4
4
  import rangeParser from "parse-numeric-range";
5
5
 
@@ -7,6 +7,16 @@ type Prettify<T> = { [K in keyof T]: T[K] } & {};
7
7
 
8
8
  type PartiallyRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
9
9
 
10
+ declare module "hast" {
11
+ interface Data {
12
+ meta?: string | undefined;
13
+ }
14
+ }
15
+
16
+ type ElementWithTextNode = Element & {
17
+ children: [Text, ...ElementContent[]];
18
+ };
19
+
10
20
  export type HighlightLinesOptions = {
11
21
  showLineNumbers?: boolean;
12
22
  /**
@@ -25,15 +35,38 @@ type PartiallyRequiredHighlightLinesOptions = Prettify<
25
35
  PartiallyRequired<HighlightLinesOptions, "showLineNumbers" | "lineContainerTagName">
26
36
  >;
27
37
 
28
- type CodeData = ElementData & {
29
- meta?: string;
30
- };
31
-
32
38
  // a simple util for our use case, like clsx package
33
39
  export function clsx(arr: (string | false | null | undefined | 0)[]): string[] {
34
40
  return arr.filter((item): item is string => !!item);
35
41
  }
36
42
 
43
+ // check if it is string array
44
+ function isStringArray(value: unknown): value is string[] {
45
+ return (
46
+ // type-coverage:ignore-next-line
47
+ Array.isArray(value) && value.every((item) => typeof item === "string")
48
+ );
49
+ }
50
+
51
+ // check if it is Element which first child is text
52
+ function isElementWithTextNode(node: ElementContent | undefined): node is ElementWithTextNode {
53
+ return (
54
+ node?.type === "element" && node.children[0]?.type === "text" && "value" in node.children[0]
55
+ );
56
+ }
57
+
58
+ function hasClassName(node: ElementContent | undefined, className: string): boolean {
59
+ return (
60
+ node?.type === "element" &&
61
+ isStringArray(node.properties.className) &&
62
+ node.properties.className.some((cls) => cls.includes(className))
63
+ );
64
+ }
65
+
66
+ // match all common types of line breaks
67
+ const REGEX_LINE_BREAKS = /\r?\n|\r/g;
68
+ const REGEX_LINE_BREAKS_IN_THE_BEGINNING = /^(\r?\n|\r)/;
69
+
37
70
  /**
38
71
  *
39
72
  * add line numbers to code blocks and allow highlighting of desired code lines
@@ -51,14 +84,13 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
51
84
  * check code element children need flattening or not
52
85
  *
53
86
  */
54
- function checkCodeTreeForFlatteningNeed(code: Element): boolean {
87
+ function hasFlatteningNeed(code: Element): boolean {
55
88
  const elementContents = code.children;
56
89
 
57
90
  // type ElementContent = Comment | Element | Text
58
91
  for (const elemenContent of elementContents) {
59
- if (elemenContent.type === "element")
60
- if (elemenContent.children.length >= 1 && elemenContent.children[0].type === "element")
61
- return true;
92
+ if (elemenContent.type === "element" && Boolean(elemenContent.children.length))
93
+ if (elemenContent.children.some((ec) => ec.type === "element")) return true;
62
94
  }
63
95
 
64
96
  return false;
@@ -66,7 +98,8 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
66
98
 
67
99
  /**
68
100
  *
69
- * flatten code element children, recursively
101
+ * flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx
102
+ * mutates the code, recursively
70
103
  * inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js
71
104
  *
72
105
  */
@@ -106,25 +139,12 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
106
139
  const createLine = (
107
140
  children: ElementContent[],
108
141
  lineNumber: number,
109
- startingNumber: number,
110
- directiveShowLineNumbers: boolean,
111
- linesToBeHighlighted: number[],
142
+ directiveShowLineNumbers: boolean | number,
143
+ directiveHighlightLines: number[],
112
144
  ): Element => {
113
145
  const firstChild = children[0];
114
-
115
- const isAddition =
116
- firstChild?.type === "element" &&
117
- Array.isArray(firstChild.properties.className) &&
118
- firstChild.properties.className.some(
119
- (cls) => typeof cls === "string" && cls.includes("addition"),
120
- );
121
-
122
- const isDeletion =
123
- firstChild?.type === "element" &&
124
- Array.isArray(firstChild.properties.className) &&
125
- firstChild.properties.className.some(
126
- (cls) => typeof cls === "string" && cls.includes("deletion"),
127
- );
146
+ const isAddition = hasClassName(firstChild, "addition");
147
+ const isDeletion = hasClassName(firstChild, "deletion");
128
148
 
129
149
  return {
130
150
  type: "element",
@@ -134,17 +154,87 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
134
154
  className: clsx([
135
155
  "code-line",
136
156
  directiveShowLineNumbers && "numbered-code-line",
137
- linesToBeHighlighted.includes(lineNumber) && "highlighted-code-line",
157
+ directiveHighlightLines.includes(lineNumber) && "highlighted-code-line",
138
158
  isAddition && "inserted",
139
159
  isDeletion && "deleted",
140
160
  ]),
141
- dataLineNumber: directiveShowLineNumbers ? startingNumber - 1 + lineNumber : undefined,
161
+ dataLineNumber:
162
+ typeof directiveShowLineNumbers === "number"
163
+ ? directiveShowLineNumbers - 1 + lineNumber
164
+ : directiveShowLineNumbers
165
+ ? lineNumber
166
+ : undefined,
142
167
  },
143
168
  };
144
169
  };
145
170
 
146
- // match all common types of line breaks
147
- const REGEX_LINE_BREAKS = /\r?\n|\r/g;
171
+ /**
172
+ *
173
+ * handle elements which is multi line comment in code
174
+ * mutates the code
175
+ *
176
+ */
177
+ function handleMultiLineComments(code: Element): undefined {
178
+ for (let index = 0; index < code.children.length; index++) {
179
+ const replacement: ElementContent[] = [];
180
+
181
+ const child = code.children[index];
182
+
183
+ if (!isElementWithTextNode(child)) continue;
184
+ if (!hasClassName(child, "comment")) continue;
185
+
186
+ const textNode = child.children[0];
187
+ if (!REGEX_LINE_BREAKS.test(textNode.value)) continue;
188
+ const comments = textNode.value.split(REGEX_LINE_BREAKS);
189
+
190
+ for (let i = 0; i < comments.length; i++) {
191
+ const newChild = structuredClone(child);
192
+ newChild.children[0].value = comments[i];
193
+ replacement.push(newChild);
194
+
195
+ if (i < comments.length - 1) {
196
+ replacement.push({ type: "text", value: "\n" }); // eol
197
+ }
198
+ }
199
+
200
+ code.children = [
201
+ ...code.children.slice(0, index),
202
+ ...replacement,
203
+ ...code.children.slice(index + 1),
204
+ ];
205
+ }
206
+ }
207
+
208
+ /**
209
+ *
210
+ * handle eol characters in the beginning of the only first element
211
+ * (because gutter function does not check the first element in the HAST whether contain eol at the beginning)
212
+ * mutates the code
213
+ *
214
+ */
215
+ function handleFirstElementContent(code: Element): undefined {
216
+ const replacement: ElementContent[] = [];
217
+
218
+ const elementNode = code.children[0];
219
+ if (!isElementWithTextNode(elementNode)) return;
220
+
221
+ const textNode = elementNode.children[0];
222
+ if (!REGEX_LINE_BREAKS_IN_THE_BEGINNING.test(textNode.value)) return;
223
+
224
+ let match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
225
+
226
+ while (match !== null) {
227
+ replacement.push({ type: "text", value: match[0] });
228
+
229
+ // Update the child value
230
+ textNode.value = textNode.value.slice(1);
231
+
232
+ // iterate the match
233
+ match = REGEX_LINE_BREAKS_IN_THE_BEGINNING.exec(textNode.value);
234
+ }
235
+
236
+ code.children.unshift(...replacement);
237
+ }
148
238
 
149
239
  /**
150
240
  *
@@ -158,21 +248,40 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
158
248
  );
159
249
  }
160
250
 
251
+ /**
252
+ *
253
+ * extract the lines from HAST of code element
254
+ * mutates the code
255
+ *
256
+ */
161
257
  function gutter(
162
- tree: Element,
163
- directiveShowLineNumbers: boolean,
164
- startingNumber: number,
165
- linesToBeHighlighted: number[],
258
+ code: Element,
259
+ {
260
+ directiveShowLineNumbers,
261
+ directiveHighlightLines,
262
+ }: {
263
+ directiveShowLineNumbers: boolean | number;
264
+ directiveHighlightLines: number[];
265
+ },
166
266
  ) {
267
+ hasFlatteningNeed(code) && flattenCodeTree(code); // mutates the code
268
+
269
+ handleMultiLineComments(code); // mutates the code
270
+
271
+ handleFirstElementContent(code); // mutates the code
272
+
167
273
  const replacement: ElementContent[] = [];
168
274
 
169
- let index = -1;
170
275
  let start = 0;
171
276
  let startTextRemainder = "";
172
277
  let lineNumber = 0;
173
278
 
174
- while (++index < tree.children.length) {
175
- const child = tree.children[index];
279
+ for (let index = 0; index < code.children.length; index++) {
280
+ const child = code.children[index];
281
+
282
+ // if (index === 0 && /^[\n][\s]*$/.test(child.value)) {
283
+ // console.log(child.value, index);
284
+ // }
176
285
 
177
286
  if (child.type !== "text") continue;
178
287
 
@@ -181,7 +290,8 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
181
290
 
182
291
  while (match !== null) {
183
292
  // Nodes in this line. (current child is exclusive)
184
- const line = tree.children.slice(start, index);
293
+ // Array.prototype.slice() start to end (end not included)
294
+ const line = code.children.slice(start, index);
185
295
 
186
296
  // Prepend text from a partial matched earlier text.
187
297
  if (startTextRemainder) {
@@ -195,21 +305,11 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
195
305
  line.push({ type: "text", value });
196
306
  }
197
307
 
198
- if (!isEmptyLine(line)) {
199
- lineNumber += 1;
200
- replacement.push(
201
- createLine(
202
- line,
203
- lineNumber,
204
- startingNumber,
205
- directiveShowLineNumbers,
206
- linesToBeHighlighted,
207
- ),
208
- );
209
- }
210
-
211
- // Add eol
212
- replacement.push({ type: "text", value: match[0] });
308
+ lineNumber += 1;
309
+ replacement.push(
310
+ createLine(line, lineNumber, directiveShowLineNumbers, directiveHighlightLines),
311
+ { type: "text", value: match[0] }, // eol
312
+ );
213
313
 
214
314
  start = index + 1;
215
315
  textStart = match.index + match[0].length;
@@ -224,7 +324,7 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
224
324
  }
225
325
  }
226
326
 
227
- const line = tree.children.slice(start);
327
+ const line = code.children.slice(start);
228
328
 
229
329
  // Prepend text from a partial matched earlier text.
230
330
  if (startTextRemainder) {
@@ -232,23 +332,19 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
232
332
  startTextRemainder = "";
233
333
  }
234
334
 
235
- if (!isEmptyLine(line)) {
236
- if (line.length > 0) {
335
+ if (line.length > 0) {
336
+ if (isEmptyLine(line)) {
337
+ replacement.push(...line);
338
+ } else {
237
339
  lineNumber += 1;
238
340
  replacement.push(
239
- createLine(
240
- line,
241
- lineNumber,
242
- startingNumber,
243
- directiveShowLineNumbers,
244
- linesToBeHighlighted,
245
- ),
341
+ createLine(line, lineNumber, directiveShowLineNumbers, directiveHighlightLines),
246
342
  );
247
343
  }
248
344
  }
249
345
 
250
346
  // Replace children with new array.
251
- tree.children = replacement;
347
+ code.children = replacement;
252
348
  }
253
349
 
254
350
  /**
@@ -283,8 +379,8 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
283
379
  * Nothing.
284
380
  */
285
381
  return (tree: Root): undefined => {
286
- visit(tree, "element", function (node, index, parent): VisitorResult {
287
- if (!parent || index === undefined || node.tagName !== "code") {
382
+ visit(tree, "element", function (code, index, parent): VisitorResult {
383
+ if (!parent || index === undefined || code.tagName !== "code") {
288
384
  return;
289
385
  }
290
386
 
@@ -292,15 +388,13 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
292
388
  return;
293
389
  }
294
390
 
295
- const code = node;
296
-
297
391
  const classNames = code.properties.className;
298
392
 
299
393
  // only for type narrowing
300
394
  /* v8 ignore next */
301
- if (!Array.isArray(classNames) && classNames !== undefined) return;
395
+ if (!isStringArray(classNames) && classNames !== undefined) return;
302
396
 
303
- let meta = (code.data as CodeData)?.meta?.toLowerCase().trim() || "";
397
+ let meta = code.data?.meta?.toLowerCase().trim() ?? "";
304
398
 
305
399
  const language = getLanguage(classNames);
306
400
 
@@ -312,38 +406,37 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
312
406
  // add specifiers to meta
313
407
  meta = (language + " " + meta).trim();
314
408
 
315
- // remove all classnames like hljs, lang-x, language-x, because of false positive
409
+ // correct the code's meta
410
+ code.data && (code.data.meta = meta);
411
+
412
+ // remove all classnames like hljs, lang-{1,3}, language-showLineNumbers, because of false positive
316
413
  code.properties.className = undefined;
317
414
  }
318
415
 
319
- const directiveShowLineNumbers = meta.includes("nolinenumbers")
416
+ let directiveShowLineNumbers: boolean | number = meta.includes("nolinenumbers")
320
417
  ? false
321
418
  : settings.showLineNumbers || meta.includes("showlinenumbers");
322
419
 
323
- let startingNumber = 1;
324
-
325
420
  // find the number where the line number starts, if exists
326
- if (directiveShowLineNumbers) {
327
- const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
328
- const start = REGEX1.exec(meta)?.groups?.start;
329
- if (start && !isNaN(Number(start))) startingNumber = Number(start);
330
- }
421
+ const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
422
+ const start = REGEX1.exec(meta)?.groups?.start;
423
+ if (start && !isNaN(Number(start))) directiveShowLineNumbers = Number(start);
331
424
 
332
425
  // find number range string within curly braces and parse it
333
426
  const REGEX2 = /{(?<lines>[\d\s,-]+)}/g;
334
427
  const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\s/g, "");
335
- const linesToBeHighlighted = strLineNumbers ? rangeParser(strLineNumbers) : [];
428
+ const directiveHighlightLines = strLineNumbers ? rangeParser(strLineNumbers) : [];
336
429
 
337
- // if nothing to do for numbering and highlihting, just return
338
- if (!directiveShowLineNumbers && linesToBeHighlighted.length === 0) return;
339
-
340
- // flatten deeper nodes into first level <span> and text, especially for languages like jsx, tsx
341
- if (checkCodeTreeForFlatteningNeed(code)) {
342
- flattenCodeTree(code);
430
+ // if nothing to do for numbering, highlihting or trimming blank lines, just return;
431
+ if (directiveShowLineNumbers === false && directiveHighlightLines.length === 0) {
432
+ return;
343
433
  }
344
434
 
345
435
  // add container for each line mutating the code element
346
- gutter(code, directiveShowLineNumbers, startingNumber, linesToBeHighlighted);
436
+ gutter(code, {
437
+ directiveShowLineNumbers,
438
+ directiveHighlightLines,
439
+ });
347
440
  });
348
441
  };
349
442
  };