rehype-pretty-code
Advanced tools
Comparing version 0.12.0 to 0.12.1
@@ -10,3 +10,3 @@ import { visit } from 'unist-util-visit'; | ||
function isJSONTheme(value) { | ||
return value ? hasOwnProperty(value, 'tokenColors') : false; | ||
return value ? Object.hasOwn(value, 'tokenColors') : false; | ||
} | ||
@@ -19,5 +19,2 @@ function isElement(value) { | ||
} | ||
function hasOwnProperty(object, string) { | ||
return {}.hasOwnProperty.call(object, string); | ||
} | ||
function isInlineCode(element, parent) { | ||
@@ -71,2 +68,16 @@ return element.tagName === 'code' && isElement(parent) && parent.tagName !== 'pre' || element.tagName === 'inlineCode'; | ||
} | ||
function getLineId(lineNumber, meta) { | ||
const segments = meta.match(/\{[^}]+\}#[a-zA-Z0-9]+/g); | ||
if (!segments) return null; | ||
for (const segment of segments) { | ||
const [range, id] = segment.split('#'); | ||
if (!range || !id) continue; | ||
const match = range.match(/\{(.*?)\}/); | ||
const capture = match?.[1]; | ||
if (capture && rangeParser(capture).includes(lineNumber)) { | ||
return id; | ||
} | ||
} | ||
return null; | ||
} | ||
@@ -192,3 +203,3 @@ function splitElement({ | ||
// ignore any previously matched chars within | ||
hasOwnProperty(maybeElement.properties ?? {}, 'rehype-pretty-code-visited')) { | ||
Object.hasOwn(maybeElement.properties ?? {}, 'rehype-pretty-code-visited')) { | ||
continue; | ||
@@ -390,3 +401,3 @@ } | ||
const props = isElement(childNode) ? childNode.properties : {}; | ||
if (props && !hasOwnProperty(props, 'rehype-pretty-code-visited') && !Object.hasOwn(props, 'data-highlighted-chars-mark')) { | ||
if (props && !Object.hasOwn(props, 'rehype-pretty-code-visited') && !Object.hasOwn(props, 'data-highlighted-chars-mark')) { | ||
return toString(childNode); | ||
@@ -397,13 +408,9 @@ } | ||
} | ||
element.children.forEach(childNode => { | ||
if (!isElement(childNode)) { | ||
return; | ||
} | ||
if (hasOwnProperty(childNode.properties ?? {}, 'rehype-pretty-code-visited')) { | ||
if (childNode.properties) { | ||
delete childNode.properties['rehype-pretty-code-visited']; | ||
} | ||
} | ||
}); | ||
}); | ||
element.children.forEach(childNode => { | ||
if (!isElement(childNode)) return; | ||
if (Object.hasOwn(childNode.properties, 'rehype-pretty-code-visited')) { | ||
delete childNode.properties['rehype-pretty-code-visited']; | ||
} | ||
}); | ||
} | ||
@@ -466,3 +473,3 @@ | ||
} | ||
if (hasOwnProperty(code.properties, 'data-line-numbers')) { | ||
if (Object.hasOwn(code.properties, 'data-line-numbers')) { | ||
code.properties['data-line-numbers-max-digits'] = lineNumbersMaxDigits.toString().length; | ||
@@ -641,16 +648,31 @@ } | ||
} = parseBlockMetaString(codeElement, filterMetaString, defaultCodeBlockLang); | ||
const lineNumbers = meta ? rangeParser(meta.match(/(?:^|\s){(.*?)}/)?.[1] ?? '') : []; | ||
const lineNumbers = []; | ||
if (meta) { | ||
const matches = meta.matchAll(/\{(.*?)\}/g); | ||
for (const match of matches) { | ||
if (match[1]) { | ||
lineNumbers.push(...rangeParser(match[1])); | ||
} | ||
} | ||
} | ||
let lineNumbersMaxDigits = 0; | ||
const lineIdMap = new Map(); | ||
const charsList = []; | ||
const charsListNumbers = []; | ||
const charsListIdMap = new Map(); | ||
const charsMatches = meta ? [...meta.matchAll(/\/(.*?)\/(\S*)/g)] : undefined; | ||
const charsMatches = meta ? [...meta.matchAll(/(?<delimiter>["/])(?<chars>.*?)\k<delimiter>(?<charsIdAndOrRange>\S*)/g)] : undefined; | ||
lineNumbers.forEach(lineNumber => { | ||
const id = getLineId(lineNumber, meta); | ||
id && lineIdMap.set(lineNumber, id); | ||
}); | ||
if (Array.isArray(charsMatches)) { | ||
charsMatches.forEach((_, index) => { | ||
const word = charsMatches[index][1]; | ||
const charsIdOrRange = charsMatches[index][2]; | ||
const [range, id] = charsIdOrRange.split('#'); | ||
charsList.push(word); | ||
charsMatches.forEach(name => { | ||
const { | ||
chars, | ||
charsIdAndOrRange | ||
} = name.groups; | ||
const [range, id] = charsIdAndOrRange.split('#'); | ||
charsList.push(chars); | ||
range && charsListNumbers.push(rangeParser(range)); | ||
id && charsListIdMap.set(word, id); | ||
id && charsListIdMap.set(chars, id); | ||
}); | ||
@@ -696,5 +718,10 @@ } | ||
onVisitLine?.(element); | ||
if (lineNumbers.includes(++lineCounter)) { | ||
lineCounter++; | ||
if (lineNumbers.includes(lineCounter)) { | ||
element.properties['data-highlighted-line'] = ''; | ||
onVisitHighlightedLine?.(element); | ||
const lineId = lineIdMap.get(lineCounter); | ||
if (lineId) { | ||
element.properties['data-highlighted-line-id'] = lineId; | ||
} | ||
onVisitHighlightedLine?.(element, lineId); | ||
} | ||
@@ -701,0 +728,0 @@ charsHighlighter(element, charsList, charsHighlighterOptions, onVisitHighlightedChars); |
@@ -32,3 +32,3 @@ import type { | ||
onVisitLine?(element: LineElement): void; | ||
onVisitHighlightedLine?(element: LineElement): void; | ||
onVisitHighlightedLine?(element: LineElement, id: string | undefined): void; | ||
onVisitHighlightedChars?(element: CharsElement, id: string | undefined): void; | ||
@@ -35,0 +35,0 @@ onVisitTitle?(element: Element): void; |
{ | ||
"name": "rehype-pretty-code", | ||
"version": "0.12.0", | ||
"version": "0.12.1", | ||
"description": "Beautiful code for your MD/MDX docs.", | ||
@@ -46,3 +46,3 @@ "main": "./dist/rehype-pretty-code.js", | ||
"peerDependencies": { | ||
"shikiji": "0.7.x" | ||
"shikiji": "^0.7.0 || ^0.8.0" | ||
}, | ||
@@ -49,0 +49,0 @@ "devDependencies": { |
30279
757