rehype-highlight-code-lines 0.0.3 → 0.0.5
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 +129 -3
- package/dist/esm/index.js +25 -11
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +39 -10
package/README.md
CHANGED
|
@@ -158,7 +158,21 @@ use(rehypeHighlightLines, {
|
|
|
158
158
|
});
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
Now, all code blocks will become numbered by line.
|
|
161
|
+
Now, all code blocks will become numbered by line. If you want to exclude a specific code block not to be numbered, use `noLineNumbers`.
|
|
162
|
+
|
|
163
|
+
**\`\`\`[language] noLineNumbers {2}**
|
|
164
|
+
|
|
165
|
+
**\`\`\`[language] noLineNumbers**
|
|
166
|
+
|
|
167
|
+
**\`\`\`noLineNumbers**
|
|
168
|
+
|
|
169
|
+
Sometimes you may want to start the line numbering from a specific number. In that cases, use `showLineNumbers=[number]` in code blocks. For example, below, the code block's line numbering will start from number `8`.
|
|
170
|
+
|
|
171
|
+
**\`\`\`[language] {2} showLineNumbers=8**
|
|
172
|
+
|
|
173
|
+
**\`\`\`[language] showLineNumbers=8**
|
|
174
|
+
|
|
175
|
+
**\`\`\`showLineNumbers=8**
|
|
162
176
|
|
|
163
177
|
#### `lineContainerTagName`
|
|
164
178
|
|
|
@@ -177,10 +191,122 @@ Now, the code line container's tag name will be `div`.
|
|
|
177
191
|
### Examples:
|
|
178
192
|
|
|
179
193
|
```typescript
|
|
194
|
+
// line numbering will occur as per directive "showLineNumber" and code-line containers will be <span> inline element
|
|
180
195
|
use(rehypeHighlightLines);
|
|
181
196
|
|
|
182
|
-
// all code blocks will be numbered
|
|
183
|
-
use(rehypeHighlightLines, {
|
|
197
|
+
// all code blocks will be numbered and code-line containers will be <div> block element
|
|
198
|
+
use(rehypeHighlightLines, {
|
|
199
|
+
showLineNumbers: true,
|
|
200
|
+
lineContainerTagName: "div",
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Copying Code Block's Content Issue
|
|
205
|
+
|
|
206
|
+
When the line containers are "div" block element, the end of line character (eol) at the end of each line causes unwanted extra blank lines. In order to fix the issue, I've removed the eol when they are "div", but kept it when they are "span".
|
|
207
|
+
|
|
208
|
+
But, the lack of eol when "div" causes another issue. If you implement a button for copying code block content, it doesn't work as expected as all code are printed in a single line. In order to work around the issue, you can implement an `onClick` like below:
|
|
209
|
+
|
|
210
|
+
*I assume you use a `useRef` for `<pre>` element.*
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
const onClick = () => {
|
|
214
|
+
if (!preRef.current) return;
|
|
215
|
+
|
|
216
|
+
// clone the <code> element in order not to cause any change in actual DOM
|
|
217
|
+
const code = preRef.current.getElementsByTagName("code")[0].cloneNode(true);
|
|
218
|
+
|
|
219
|
+
// add eol to each code-line since there is no eol at the end when they are div
|
|
220
|
+
Array.from((code as HTMLElement).querySelectorAll("div.code-line")).forEach(
|
|
221
|
+
(line) => {
|
|
222
|
+
line.innerHTML = line.innerHTML + "\r";
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
void navigator.clipboard.writeText(code.textContent ?? "");
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Styling
|
|
231
|
+
|
|
232
|
+
The following styles can be added for **line highlighting** and **line numbering** to work correctly:
|
|
233
|
+
|
|
234
|
+
*Choose the colors as you wish!*
|
|
235
|
+
|
|
236
|
+
```css
|
|
237
|
+
.parent-container-of-pre {
|
|
238
|
+
display: grid; /* in order { overflow-x: auto; } works in child <pre> */
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
pre,
|
|
242
|
+
pre code {
|
|
243
|
+
background-color: var(--color-code-background);
|
|
244
|
+
|
|
245
|
+
direction: ltr;
|
|
246
|
+
text-align: left;
|
|
247
|
+
white-space: pre;
|
|
248
|
+
word-spacing: normal;
|
|
249
|
+
word-break: normal;
|
|
250
|
+
line-height: 1.2;
|
|
251
|
+
tab-size: 2;
|
|
252
|
+
hyphens: none;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
pre {
|
|
256
|
+
padding: 0.5rem 1rem;
|
|
257
|
+
border: 1px solid var(--color-text-weak);
|
|
258
|
+
border-radius: 5px;
|
|
259
|
+
|
|
260
|
+
overflow-x: auto;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
pre > code {
|
|
264
|
+
float: left;
|
|
265
|
+
min-width: 100%;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.code-line {
|
|
269
|
+
padding-left: 12px;
|
|
270
|
+
padding-right: 12px;
|
|
271
|
+
margin-left: -12px;
|
|
272
|
+
margin-right: -12px;
|
|
273
|
+
border-left: 4px solid transparent; /* prepare for highlighted code-lines */
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
div.code-line:empty {
|
|
277
|
+
/* it is necessary because there is no even eol character in div code-lines */
|
|
278
|
+
height: 15.5938px; /* calculated height */
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
span.code-line {
|
|
282
|
+
min-width: 100%;
|
|
283
|
+
display: inline-block;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.code-line.inserted {
|
|
287
|
+
background-color: var(--color-inserted-line); /* inserted code-line (+) color */
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.code-line.deleted {
|
|
291
|
+
background-color: var(--color-deleted-line); /* deleted code-line (-) color */
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.highlighted-code-line {
|
|
295
|
+
background-color: var(--color-highlighted-line);
|
|
296
|
+
border-left: 4px solid var(--color-highlighted-line-indicator);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.numbered-code-line::before {
|
|
300
|
+
content: attr(data-line-number);
|
|
301
|
+
|
|
302
|
+
margin-left: -8px;
|
|
303
|
+
margin-right: 16px;
|
|
304
|
+
width: 1rem;
|
|
305
|
+
color: var(--color-text-weak);
|
|
306
|
+
text-align: right;
|
|
307
|
+
|
|
308
|
+
display: inline-block;
|
|
309
|
+
}
|
|
184
310
|
```
|
|
185
311
|
|
|
186
312
|
## Syntax tree
|
package/dist/esm/index.js
CHANGED
|
@@ -17,7 +17,8 @@ const plugin = (options) => {
|
|
|
17
17
|
const settings = Object.assign({}, DEFAULT_SETTINGS, options);
|
|
18
18
|
/**
|
|
19
19
|
*
|
|
20
|
-
* flatten
|
|
20
|
+
* flatten code element children
|
|
21
|
+
* inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js
|
|
21
22
|
*
|
|
22
23
|
*/
|
|
23
24
|
function flattenCodeTree(children, className = [], newTree = []) {
|
|
@@ -46,7 +47,7 @@ const plugin = (options) => {
|
|
|
46
47
|
* constructs the line element
|
|
47
48
|
*
|
|
48
49
|
*/
|
|
49
|
-
const createLine = (children, lineNumber, showLineNumbers, linesToBeHighlighted) => {
|
|
50
|
+
const createLine = (children, lineNumber, startingNumber, showLineNumbers, linesToBeHighlighted) => {
|
|
50
51
|
return {
|
|
51
52
|
type: "element",
|
|
52
53
|
tagName: settings.lineContainerTagName,
|
|
@@ -57,13 +58,13 @@ const plugin = (options) => {
|
|
|
57
58
|
showLineNumbers && "numbered-code-line",
|
|
58
59
|
linesToBeHighlighted.includes(lineNumber) && "highlighted-code-line",
|
|
59
60
|
]),
|
|
60
|
-
dataLineNumber: showLineNumbers ? lineNumber : undefined,
|
|
61
|
+
dataLineNumber: showLineNumbers ? startingNumber - 1 + lineNumber : undefined,
|
|
61
62
|
},
|
|
62
63
|
};
|
|
63
64
|
};
|
|
64
65
|
// match all common types of line breaks
|
|
65
66
|
const RE = /\r?\n|\r/g;
|
|
66
|
-
function gutter(tree, showLineNumbers, linesToBeHighlighted) {
|
|
67
|
+
function gutter(tree, showLineNumbers, startingNumber, linesToBeHighlighted) {
|
|
67
68
|
const replacement = [];
|
|
68
69
|
let index = -1;
|
|
69
70
|
let start = 0;
|
|
@@ -91,7 +92,7 @@ const plugin = (options) => {
|
|
|
91
92
|
}
|
|
92
93
|
// Add a line
|
|
93
94
|
lineNumber += 1;
|
|
94
|
-
replacement.push(createLine(line, lineNumber, showLineNumbers, linesToBeHighlighted));
|
|
95
|
+
replacement.push(createLine(line, lineNumber, startingNumber, showLineNumbers, linesToBeHighlighted));
|
|
95
96
|
// Add eol if the tag name is "span"
|
|
96
97
|
if (settings.lineContainerTagName === "span") {
|
|
97
98
|
replacement.push({ type: "text", value: match[0] });
|
|
@@ -115,7 +116,7 @@ const plugin = (options) => {
|
|
|
115
116
|
}
|
|
116
117
|
if (line.length > 0) {
|
|
117
118
|
lineNumber += 1;
|
|
118
|
-
replacement.push(createLine(line, lineNumber, showLineNumbers, linesToBeHighlighted));
|
|
119
|
+
replacement.push(createLine(line, lineNumber, startingNumber, showLineNumbers, linesToBeHighlighted));
|
|
119
120
|
}
|
|
120
121
|
/* v8 ignore end */
|
|
121
122
|
// Replace children with new array.
|
|
@@ -147,7 +148,9 @@ const plugin = (options) => {
|
|
|
147
148
|
const className = code.properties.className.find(testingFunction);
|
|
148
149
|
if (className) {
|
|
149
150
|
const language = className.slice(9).toLowerCase();
|
|
150
|
-
if (language.startsWith("{") ||
|
|
151
|
+
if (language.startsWith("{") ||
|
|
152
|
+
language.startsWith("showlinenumbers") ||
|
|
153
|
+
language.startsWith("nolinenumbers")) {
|
|
151
154
|
meta = meta ? language + meta : language;
|
|
152
155
|
const idx = code.properties.className.findIndex(testingFunction);
|
|
153
156
|
if (idx > -1) {
|
|
@@ -166,17 +169,28 @@ const plugin = (options) => {
|
|
|
166
169
|
}
|
|
167
170
|
if (!meta)
|
|
168
171
|
return;
|
|
169
|
-
const showLineNumbers = meta.includes("
|
|
172
|
+
const showLineNumbers = meta.includes("nolinenumbers")
|
|
173
|
+
? false
|
|
174
|
+
: meta.includes("showlinenumbers");
|
|
175
|
+
let startingNumber = 1;
|
|
176
|
+
if (showLineNumbers) {
|
|
177
|
+
const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
|
|
178
|
+
const start = REGEX1.exec(meta)?.groups?.start;
|
|
179
|
+
if (start && !isNaN(Number(start)))
|
|
180
|
+
startingNumber = Number(start);
|
|
181
|
+
}
|
|
182
|
+
console.log({ startingNumber });
|
|
170
183
|
// find number range string within curly braces and parse it
|
|
171
|
-
const
|
|
172
|
-
const strLineNumbers =
|
|
184
|
+
const REGEX2 = /{(?<lines>[\d\s,-]+)}/g;
|
|
185
|
+
const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\s/g, "");
|
|
173
186
|
const linesToBeHighlighted = strLineNumbers ? rangeParser(strLineNumbers) : [];
|
|
187
|
+
console.log({ linesToBeHighlighted });
|
|
174
188
|
if (!showLineNumbers && linesToBeHighlighted.length === 0)
|
|
175
189
|
return;
|
|
176
190
|
// flatten deeper nodes into first level <span>s an texts
|
|
177
191
|
code.children = flattenCodeTree(code.children);
|
|
178
192
|
// add wrapper for each line mutating the code element
|
|
179
|
-
gutter(code, showLineNumbers, linesToBeHighlighted);
|
|
193
|
+
gutter(code, showLineNumbers, startingNumber, linesToBeHighlighted);
|
|
180
194
|
});
|
|
181
195
|
};
|
|
182
196
|
};
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,WAAW,MAAM,qBAAqB,CAAC;AAa9C,MAAM,gBAAgB,GAA0B;IAC9C,eAAe,EAAE,KAAK;IACtB,oBAAoB,EAAE,MAAM;CAC7B,CAAC;AAUF,oDAAoD;AACpD,MAAM,UAAU,IAAI,CAAC,GAA8C;IACjE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,MAAM,GAA2C,CAAC,OAAO,EAAE,EAAE;IACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC5B,EAAE,EACF,gBAAgB,EAChB,OAAO,CACkC,CAAC;IAE5C
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -46,7 +46,8 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
*
|
|
49
|
-
* flatten
|
|
49
|
+
* flatten code element children
|
|
50
|
+
* inspired from https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/highlight.js
|
|
50
51
|
*
|
|
51
52
|
*/
|
|
52
53
|
function flattenCodeTree(
|
|
@@ -82,6 +83,7 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
82
83
|
const createLine = (
|
|
83
84
|
children: ElementContent[],
|
|
84
85
|
lineNumber: number,
|
|
86
|
+
startingNumber: number,
|
|
85
87
|
showLineNumbers: boolean,
|
|
86
88
|
linesToBeHighlighted: number[],
|
|
87
89
|
): Element => {
|
|
@@ -95,7 +97,7 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
95
97
|
showLineNumbers && "numbered-code-line",
|
|
96
98
|
linesToBeHighlighted.includes(lineNumber) && "highlighted-code-line",
|
|
97
99
|
]),
|
|
98
|
-
dataLineNumber: showLineNumbers ? lineNumber : undefined,
|
|
100
|
+
dataLineNumber: showLineNumbers ? startingNumber - 1 + lineNumber : undefined,
|
|
99
101
|
},
|
|
100
102
|
};
|
|
101
103
|
};
|
|
@@ -103,7 +105,12 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
103
105
|
// match all common types of line breaks
|
|
104
106
|
const RE = /\r?\n|\r/g;
|
|
105
107
|
|
|
106
|
-
function gutter(
|
|
108
|
+
function gutter(
|
|
109
|
+
tree: Element,
|
|
110
|
+
showLineNumbers: boolean,
|
|
111
|
+
startingNumber: number,
|
|
112
|
+
linesToBeHighlighted: number[],
|
|
113
|
+
) {
|
|
107
114
|
const replacement: Array<ElementContent> = [];
|
|
108
115
|
|
|
109
116
|
let index = -1;
|
|
@@ -140,7 +147,9 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
140
147
|
|
|
141
148
|
// Add a line
|
|
142
149
|
lineNumber += 1;
|
|
143
|
-
replacement.push(
|
|
150
|
+
replacement.push(
|
|
151
|
+
createLine(line, lineNumber, startingNumber, showLineNumbers, linesToBeHighlighted),
|
|
152
|
+
);
|
|
144
153
|
|
|
145
154
|
// Add eol if the tag name is "span"
|
|
146
155
|
if (settings.lineContainerTagName === "span") {
|
|
@@ -171,7 +180,9 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
171
180
|
|
|
172
181
|
if (line.length > 0) {
|
|
173
182
|
lineNumber += 1;
|
|
174
|
-
replacement.push(
|
|
183
|
+
replacement.push(
|
|
184
|
+
createLine(line, lineNumber, startingNumber, showLineNumbers, linesToBeHighlighted),
|
|
185
|
+
);
|
|
175
186
|
}
|
|
176
187
|
|
|
177
188
|
/* v8 ignore end */
|
|
@@ -212,7 +223,11 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
212
223
|
if (className) {
|
|
213
224
|
const language = className.slice(9).toLowerCase();
|
|
214
225
|
|
|
215
|
-
if (
|
|
226
|
+
if (
|
|
227
|
+
language.startsWith("{") ||
|
|
228
|
+
language.startsWith("showlinenumbers") ||
|
|
229
|
+
language.startsWith("nolinenumbers")
|
|
230
|
+
) {
|
|
216
231
|
meta = meta ? language + meta : language;
|
|
217
232
|
|
|
218
233
|
const idx = code.properties.className.findIndex(testingFunction);
|
|
@@ -234,20 +249,34 @@ const plugin: Plugin<[HighlightLinesOptions?], Root> = (options) => {
|
|
|
234
249
|
|
|
235
250
|
if (!meta) return;
|
|
236
251
|
|
|
237
|
-
const showLineNumbers = meta.includes("
|
|
252
|
+
const showLineNumbers = meta.includes("nolinenumbers")
|
|
253
|
+
? false
|
|
254
|
+
: meta.includes("showlinenumbers");
|
|
255
|
+
|
|
256
|
+
let startingNumber = 1;
|
|
257
|
+
|
|
258
|
+
if (showLineNumbers) {
|
|
259
|
+
const REGEX1 = /showlinenumbers=(?<start>\d+)/i;
|
|
260
|
+
const start = REGEX1.exec(meta)?.groups?.start;
|
|
261
|
+
if (start && !isNaN(Number(start))) startingNumber = Number(start);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log({ startingNumber });
|
|
238
265
|
|
|
239
266
|
// find number range string within curly braces and parse it
|
|
240
|
-
const
|
|
241
|
-
const strLineNumbers =
|
|
267
|
+
const REGEX2 = /{(?<lines>[\d\s,-]+)}/g;
|
|
268
|
+
const strLineNumbers = REGEX2.exec(meta)?.groups?.lines?.replace(/\s/g, "");
|
|
242
269
|
const linesToBeHighlighted = strLineNumbers ? rangeParser(strLineNumbers) : [];
|
|
243
270
|
|
|
271
|
+
console.log({ linesToBeHighlighted });
|
|
272
|
+
|
|
244
273
|
if (!showLineNumbers && linesToBeHighlighted.length === 0) return;
|
|
245
274
|
|
|
246
275
|
// flatten deeper nodes into first level <span>s an texts
|
|
247
276
|
code.children = flattenCodeTree(code.children);
|
|
248
277
|
|
|
249
278
|
// add wrapper for each line mutating the code element
|
|
250
|
-
gutter(code, showLineNumbers, linesToBeHighlighted);
|
|
279
|
+
gutter(code, showLineNumbers, startingNumber, linesToBeHighlighted);
|
|
251
280
|
});
|
|
252
281
|
};
|
|
253
282
|
};
|