@expressive-code/plugin-text-markers
Advanced tools
+4
-3
@@ -500,4 +500,4 @@ "use strict"; | ||
| const textColors = annotations.filter( | ||
| (annotation) => annotation instanceof import_core4.InlineStyleAnnotation && // Only consider annotations for the current style variant | ||
| annotation.styleVariantIndex === styleVariantIndex && annotation.color | ||
| (annotation) => annotation instanceof import_core4.InlineStyleAnnotation && annotation.color && // Only consider annotations that apply to the current style variant | ||
| (annotation.styleVariantIndex === void 0 || annotation.styleVariantIndex === styleVariantIndex) | ||
| ); | ||
@@ -527,3 +527,4 @@ textColors.forEach((textColor) => { | ||
| }, | ||
| color: readableTextColor | ||
| color: readableTextColor, | ||
| renderPhase: "earlier" | ||
| }) | ||
@@ -530,0 +531,0 @@ ); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../../../node_modules/.pnpm/parse-numeric-range@1.3.0/node_modules/parse-numeric-range/index.js","../src/index.ts","../src/marker-types.ts","../src/styles.ts","../src/inline-markers.ts","../src/annotations.ts"],"sourcesContent":["/**\n * @param {string} string The string to parse\n * @returns {Array<number>} Returns an energetic array.\n */\nfunction parsePart(string) {\n let res = [];\n let m;\n\n for (let str of string.split(\",\").map((str) => str.trim())) {\n // just a number\n if (/^-?\\d+$/.test(str)) {\n res.push(parseInt(str, 10));\n } else if (\n (m = str.match(/^(-?\\d+)(-|\\.\\.\\.?|\\u2025|\\u2026|\\u22EF)(-?\\d+)$/))\n ) {\n // 1-5 or 1..5 (equivalent) or 1...5 (doesn't include 5)\n let [_, lhs, sep, rhs] = m;\n\n if (lhs && rhs) {\n lhs = parseInt(lhs);\n rhs = parseInt(rhs);\n const incr = lhs < rhs ? 1 : -1;\n\n // Make it inclusive by moving the right 'stop-point' away by one.\n if (sep === \"-\" || sep === \"..\" || sep === \"\\u2025\") rhs += incr;\n\n for (let i = lhs; i !== rhs; i += incr) res.push(i);\n }\n }\n }\n\n return res;\n}\n\nexports.default = parsePart;\nmodule.exports = parsePart;\n","import {\n\tAnnotationRenderPhaseOrder,\n\tAttachedPluginData,\n\tExpressiveCodePlugin,\n\tInlineStyleAnnotation,\n\tensureColorContrastOnBackground,\n\tonBackground,\n\treplaceDelimitedValues,\n} from '@expressive-code/core'\nimport rangeParser from 'parse-numeric-range'\nimport { MarkerType, MarkerTypeOrder, markerTypeFromString } from './marker-types'\nimport { getTextMarkersBaseStyles, markerBgColorPaths, textMarkersStyleSettings } from './styles'\nimport { flattenInlineMarkerRanges, getInlineSearchTermMatches } from './inline-markers'\nimport { TextMarkerAnnotation } from './annotations'\nexport { TextMarkersStyleSettings } from './styles'\n\nexport function pluginTextMarkers(): ExpressiveCodePlugin {\n\treturn {\n\t\tname: 'TextMarkers',\n\t\tstyleSettings: textMarkersStyleSettings,\n\t\tbaseStyles: (context) => getTextMarkersBaseStyles(context),\n\t\thooks: {\n\t\t\tpreprocessMetadata: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.meta = replaceDelimitedValues(\n\t\t\t\t\tcodeBlock.meta,\n\t\t\t\t\t({ fullMatch, key, value, valueStartDelimiter }) => {\n\t\t\t\t\t\t// If we found a \"lang\" key and the code block's language is \"diff\",\n\t\t\t\t\t\t// use the \"lang\" value as the new syntax highlighting language instead\n\t\t\t\t\t\tif (key === 'lang' && codeBlock.language === 'diff') {\n\t\t\t\t\t\t\tcodeBlock.language = value\n\t\t\t\t\t\t\tblockData.originalLanguage = 'diff'\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Try to identify the marker type from the key\n\t\t\t\t\t\tconst markerType = markerTypeFromString(key || 'mark')\n\n\t\t\t\t\t\t// If an unknown key was encountered, leave this meta string part untouched\n\t\t\t\t\t\tif (!markerType) return fullMatch\n\n\t\t\t\t\t\t// Handle full-line highlighting definitions\n\t\t\t\t\t\tif (valueStartDelimiter === '{') {\n\t\t\t\t\t\t\tconst lineNumbers = rangeParser(value)\n\t\t\t\t\t\t\tlineNumbers.forEach((lineNumber) => {\n\t\t\t\t\t\t\t\tconst lineIndex = lineNumber - 1\n\t\t\t\t\t\t\t\tcodeBlock.getLine(lineIndex)?.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle regular expression search terms\n\t\t\t\t\t\tif (valueStartDelimiter === '/') {\n\t\t\t\t\t\t\t// Remember the term for highlighting in a later hook\n\t\t\t\t\t\t\tlet regExp: RegExp | undefined\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Try to use regular expressions with capture group indices\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'gd')\n\t\t\t\t\t\t\t\t/* c8 ignore start */\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t// Use fallback if unsupported\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'g')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/* c8 ignore stop */\n\t\t\t\t\t\t\tblockData.regExpTerms.push({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tregExp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Treat everything else as a plaintext search term and\n\t\t\t\t\t\t// remember it for highlighting in a later hook\n\t\t\t\t\t\tblockData.plaintextTerms.push({\n\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalueDelimiters: ['\"', \"'\", '/', '{...}'],\n\t\t\t\t\t\tkeyValueSeparator: '=',\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t},\n\t\t\tpreprocessCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\t// Perform special handling of code marked with the language \"diff\":\n\t\t\t\t// - This language is often used as a widely supported format for highlighting\n\t\t\t\t// changes to code. In this case, the code is not actually a diff,\n\t\t\t\t// but another language with some lines prefixed by `+` or `-`.\n\t\t\t\t// - We try to detect this case and convert the prefixed lines to annotations\n\t\t\t\t// - To prevent modifying actual diff files (which would make them invalid),\n\t\t\t\t// we ensure that the code does not begin like a real diff:\n\t\t\t\t// - The first lines must not start with `*** `, `+++ `, `--- `, `@@ `,\n\t\t\t\t// or the default mode location syntax (e.g. `0a1`, `1,2c1,2`, `1,2d1`).\n\t\t\t\tif ((blockData.originalLanguage ?? codeBlock.language) === 'diff') {\n\t\t\t\t\tconst lines = codeBlock.getLines()\n\n\t\t\t\t\t// Ensure that the first lines do not look like actual diff output\n\t\t\t\t\tconst couldBeRealDiffFile = lines.slice(0, 4).some((line) => line.text.match(/^([*+-]{3}\\s|@@\\s|[0-9,]+[acd][0-9,]+\\s*$)/))\n\t\t\t\t\tif (!couldBeRealDiffFile) {\n\t\t\t\t\t\tlet minIndentation = Infinity\n\t\t\t\t\t\tconst parsedLines = lines.map((line) => {\n\t\t\t\t\t\t\tconst [, indentation, marker, content] = line.text.match(/^(([+-](?![+-]))?\\s*)(.*)$/) || []\n\t\t\t\t\t\t\tconst markerType: MarkerType | undefined = marker === '+' ? 'ins' : marker === '-' ? 'del' : undefined\n\n\t\t\t\t\t\t\t// As it's common to indent unchanged lines to match the indentation\n\t\t\t\t\t\t\t// of changed lines, and we don't want extra whitespace in the output,\n\t\t\t\t\t\t\t// we remember the minimum indentation of all non-empty lines\n\t\t\t\t\t\t\tif (content.trim().length > 0 && indentation.length < minIndentation) minIndentation = indentation.length\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tparsedLines.forEach(({ line, markerType }) => {\n\t\t\t\t\t\t\t// Remove line prefixes:\n\t\t\t\t\t\t\t// - If minIndentation is > 0, we remove minIndentation\n\t\t\t\t\t\t\t// - Otherwise, if the current line starts with a marker character,\n\t\t\t\t\t\t\t// we remove this single character\n\t\t\t\t\t\t\tconst colsToRemove = minIndentation || (markerType ? 1 : 0)\n\t\t\t\t\t\t\tif (colsToRemove > 0) line.editText(0, colsToRemove, '')\n\n\t\t\t\t\t\t\t// If we found a diff marker, add a line annotation\n\t\t\t\t\t\t\tif (markerType) {\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tannotateCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\t// Check the line text for search term matches and collect their ranges\n\t\t\t\t\tconst markerRanges = getInlineSearchTermMatches(line.text, blockData)\n\t\t\t\t\tif (!markerRanges.length) return\n\n\t\t\t\t\t// Flatten marked ranges to prevent any overlaps\n\t\t\t\t\tconst flattenedRanges = flattenInlineMarkerRanges(markerRanges)\n\n\t\t\t\t\t// Add annotations for all flattened ranges\n\t\t\t\t\tflattenedRanges.forEach(({ markerType, start, end }) => {\n\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\tcolumnStart: start,\n\t\t\t\t\t\t\t\t\tcolumnEnd: end,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t\tpostprocessAnnotations: ({ codeBlock, styleVariants, config }) => {\n\t\t\t\tif (config.minSyntaxHighlightingColorContrast <= 0) return\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\tconst annotations = line.getAnnotations()\n\t\t\t\t\t// Determine the highest-priority full line marker\n\t\t\t\t\t// and collect all inline markers\n\t\t\t\t\tconst markers: TextMarkerAnnotation[] = []\n\t\t\t\t\tlet fullLineMarker: TextMarkerAnnotation | undefined = undefined\n\t\t\t\t\tfor (const annotation of annotations) {\n\t\t\t\t\t\tif (!(annotation instanceof TextMarkerAnnotation)) continue\n\t\t\t\t\t\tif (annotation.inlineRange) {\n\t\t\t\t\t\t\tmarkers.push(annotation)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fullLineMarker) {\n\t\t\t\t\t\t\tif (MarkerTypeOrder.indexOf(annotation.markerType) < MarkerTypeOrder.indexOf(fullLineMarker.markerType)) continue\n\t\t\t\t\t\t\tif (AnnotationRenderPhaseOrder.indexOf(annotation.renderPhase) < AnnotationRenderPhaseOrder.indexOf(fullLineMarker.renderPhase)) continue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfullLineMarker = annotation\n\t\t\t\t\t}\n\t\t\t\t\t// Prepend the highest-priority full line marker to the inline markers\n\t\t\t\t\tif (fullLineMarker) markers.unshift(fullLineMarker)\n\t\t\t\t\t// Ensure color contrast for all style variants\n\t\t\t\t\tstyleVariants.forEach((styleVariant, styleVariantIndex) => {\n\t\t\t\t\t\tconst fullLineMarkerBgColor = (fullLineMarker && styleVariant.resolvedStyleSettings.get(markerBgColorPaths[fullLineMarker.markerType])) || 'transparent'\n\t\t\t\t\t\tconst lineBgColor = onBackground(fullLineMarkerBgColor, styleVariant.resolvedStyleSettings.get('codeBackground') || styleVariant.theme.bg)\n\t\t\t\t\t\t// Collect inline style annotations that change the text color\n\t\t\t\t\t\tconst textColors = annotations.filter(\n\t\t\t\t\t\t\t(annotation) =>\n\t\t\t\t\t\t\t\tannotation instanceof InlineStyleAnnotation &&\n\t\t\t\t\t\t\t\t// Only consider annotations for the current style variant\n\t\t\t\t\t\t\t\tannotation.styleVariantIndex === styleVariantIndex &&\n\t\t\t\t\t\t\t\tannotation.color\n\t\t\t\t\t\t) as InlineStyleAnnotation[]\n\t\t\t\t\t\t// Go through all text color annotations\n\t\t\t\t\t\ttextColors.forEach((textColor) => {\n\t\t\t\t\t\t\tconst textFgColor = textColor.color\n\t\t\t\t\t\t\tconst textStart = textColor.inlineRange?.columnStart\n\t\t\t\t\t\t\tconst textEnd = textColor.inlineRange?.columnEnd\n\t\t\t\t\t\t\tif (textFgColor === undefined || textStart === undefined || textEnd === undefined) return\n\t\t\t\t\t\t\t// Go through all markers\n\t\t\t\t\t\t\tmarkers.forEach((marker) => {\n\t\t\t\t\t\t\t\tconst markerStart = marker.inlineRange?.columnStart ?? 0\n\t\t\t\t\t\t\t\tconst markerEnd = marker.inlineRange?.columnEnd ?? line.text.length\n\t\t\t\t\t\t\t\tif (markerStart > textEnd || markerEnd < textStart) return\n\t\t\t\t\t\t\t\t// As the marker overlaps with the text color annotation,\n\t\t\t\t\t\t\t\t// determine the combined background color of this range\n\t\t\t\t\t\t\t\tconst markerBgColor = styleVariant.resolvedStyleSettings.get(markerBgColorPaths[marker.markerType]) ?? ''\n\t\t\t\t\t\t\t\tconst combinedBgColor = onBackground(markerBgColor, lineBgColor)\n\t\t\t\t\t\t\t\t// Now ensure a good contrast ratio of the text\n\t\t\t\t\t\t\t\tconst readableTextColor = ensureColorContrastOnBackground(textFgColor, combinedBgColor, config.minSyntaxHighlightingColorContrast)\n\t\t\t\t\t\t\t\tif (readableTextColor.toLowerCase() === textFgColor.toLowerCase()) return\n\t\t\t\t\t\t\t\t// If the text color is not readable enough, add an annotation\n\t\t\t\t\t\t\t\t// with better contrast for the overlapping range\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew InlineStyleAnnotation({\n\t\t\t\t\t\t\t\t\t\tstyleVariantIndex,\n\t\t\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\t\t\tcolumnStart: Math.max(textStart, markerStart),\n\t\t\t\t\t\t\t\t\t\t\tcolumnEnd: Math.min(textEnd, markerEnd),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tcolor: readableTextColor,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface PluginTextMarkersData {\n\tplaintextTerms: { markerType: MarkerType; text: string }[]\n\tregExpTerms: { markerType: MarkerType; regExp: RegExp }[]\n\toriginalLanguage?: string | undefined\n}\n\nexport const pluginTextMarkersData = new AttachedPluginData<PluginTextMarkersData>(() => ({ plaintextTerms: [], regExpTerms: [] }))\n","export type MarkerType = 'mark' | 'ins' | 'del'\n\n/** When markers overlap, those with higher indices override lower ones. */\nexport const MarkerTypeOrder: MarkerType[] = ['mark', 'del', 'ins']\n\n/**\n * If the given input string represents a valid marker type,\n * converts it to a {@link MarkerType} and returns it.\n *\n * Otherwise, returns `undefined`.\n */\nexport function markerTypeFromString(input: string) {\n\t// Fix common marker type mistakes\n\tif (input === 'add') input = 'ins'\n\tif (input === 'rem') input = 'del'\n\n\t// Return either the converted type or undefined\n\tconst markerType = input as MarkerType\n\treturn MarkerTypeOrder.includes(markerType) ? markerType : undefined\n}\n","import { PluginStyleSettings, codeLineClass, toHexColor, StyleSettingPath, ResolverContext, StyleResolverFn } from '@expressive-code/core'\nimport { MarkerType } from './marker-types'\n\nexport interface TextMarkersStyleSettings {\n\t/**\n\t * The margin between the code block border and the line marker accent bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0rem'\n\t */\n\tlineMarkerAccentMargin: string\n\t/**\n\t * The width of the line marker accent bar. This is the vertical border-like bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.15rem'\n\t */\n\tlineMarkerAccentWidth: string\n\t/**\n\t * The margin between the code block border and the diff indicator (e.g. `+` or `-`)\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.5rem'\n\t */\n\tlineDiffIndicatorMarginLeft: string\n\t/**\n\t * The width of the border around inline text markers, rendered in a way\n\t * that does not cause marked code to shift.\n\t * @default '1.5px'\n\t */\n\tinlineMarkerBorderWidth: string\n\t/**\n\t * The border radius of inline text markers.\n\t * @default '0.2rem'\n\t */\n\tinlineMarkerBorderRadius: string\n\t/**\n\t * The inline padding of inline text markers. Keep this low to prevent marked code\n\t * from shifting too much compared to the original text.\n\t * @default '0.15rem'\n\t */\n\tinlineMarkerPadding: string\n\t/**\n\t * The LCH hue to be used for marked text (text marker type `mark`).\n\t * @default '284' (a blue hue)\n\t */\n\tmarkHue: string\n\t/**\n\t * The LCH hue to be used for inserted text (text marker type `ins`).\n\t * @default '136' (a green hue)\n\t */\n\tinsHue: string\n\t/**\n\t * The LCH hue to be used for deleted text (text marker type `del`).\n\t * @default '33' (a red hue)\n\t */\n\tdelHue: string\n\t/**\n\t * The LCH chroma to be used for all text marker types.\n\t *\n\t * The chroma value defines the saturation of the color. Higher values lead to\n\t * more saturated colors, lower values lead to less saturated colors.\n\t *\n\t * @default '40'\n\t */\n\tdefaultChroma: string\n\t/**\n\t * The LCH luminance to be used for all text marker types.\n\t * @default\n\t * ['32%', '75%'] // 32% for dark themes, 75% for light themes\n\t */\n\tdefaultLuminance: string\n\t/**\n\t * The opacity of the background color of all text marker types.\n\t * @default '50%'\n\t */\n\tbackgroundOpacity: string\n\t/**\n\t * The LCH luminance to be used for the border color of all text marker types.\n\t * @default '48%'\n\t */\n\tborderLuminance: string\n\t/**\n\t * The opacity of the border color of all text marker types.\n\t * @default '81.6%'\n\t */\n\tborderOpacity: string\n\t/**\n\t * The LCH luminance to be used for the diff indicator (e.g. `+` or `-`).\n\t * @default\n\t * ['67%', '40%'] // 67% for dark themes, 40% for light themes\n\t */\n\tindicatorLuminance: string\n\t/**\n\t * The opacity of the diff indicator (e.g. `+` or `-`).\n\t * @default '81.6%'\n\t */\n\tindicatorOpacity: string\n\t/**\n\t * The content to be displayed inside the diff indicator of inserted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'+'\"\n\t */\n\tinsDiffIndicatorContent: string\n\t/**\n\t * The content to be displayed inside the diff indicator of deleted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'-'\"\n\t */\n\tdelDiffIndicatorContent: string\n\t/**\n\t * The background color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <markHue> / <backgroundOpacity>)\n\t */\n\tmarkBackground: string\n\t/**\n\t * The border color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <markHue> / <borderOpacity>)\n\t */\n\tmarkBorderColor: string\n\t/**\n\t * The background color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <insHue> / <backgroundOpacity>)\n\t */\n\tinsBackground: string\n\t/**\n\t * The border color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <insHue> / <borderOpacity>)\n\t */\n\tinsBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of inserted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <insHue> / <indicatorOpacity>)\n\t */\n\tinsDiffIndicatorColor: string\n\t/**\n\t * The background color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <delHue> / <backgroundOpacity>)\n\t */\n\tdelBackground: string\n\t/**\n\t * The border color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <delHue> / <borderOpacity>)\n\t */\n\tdelBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of deleted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <delHue> / <indicatorOpacity>)\n\t */\n\tdelDiffIndicatorColor: string\n}\n\ndeclare module '@expressive-code/core' {\n\texport interface StyleSettings {\n\t\ttextMarkers: TextMarkersStyleSettings\n\t}\n}\n\nexport const textMarkersStyleSettings = new PluginStyleSettings({\n\tdefaultValues: {\n\t\ttextMarkers: {\n\t\t\tlineMarkerAccentMargin: '0rem',\n\t\t\tlineMarkerAccentWidth: '0.15rem',\n\t\t\tlineDiffIndicatorMarginLeft: '0.5rem',\n\t\t\tinlineMarkerBorderWidth: '1.5px',\n\t\t\tinlineMarkerBorderRadius: '0.2rem',\n\t\t\tinlineMarkerPadding: '0.15rem',\n\t\t\t// Define base colors for all markers in the LCH color space,\n\t\t\t// which leads to consistent perceived brightness independent of hue\n\t\t\tmarkHue: '284',\n\t\t\tinsHue: '136',\n\t\t\tdelHue: '33',\n\t\t\tdefaultChroma: '40',\n\t\t\tdefaultLuminance: ['32%', '75%'],\n\t\t\tbackgroundOpacity: '50%',\n\t\t\tborderLuminance: '48%',\n\t\t\tborderOpacity: '81.6%',\n\t\t\tindicatorLuminance: ['67%', '40%'],\n\t\t\tindicatorOpacity: '81.6%',\n\t\t\t// You can use these to override the diff indicator content\n\t\t\tinsDiffIndicatorContent: \"'+'\",\n\t\t\tdelDiffIndicatorContent: \"'-'\",\n\t\t\t// The settings below will be calculated based on the settings above\n\t\t\tmarkBackground: (context) => resolveBg(context, 'textMarkers.markHue'),\n\t\t\tmarkBorderColor: (context) => resolveBorder(context, 'textMarkers.markHue'),\n\t\t\tinsBackground: (context) => resolveBg(context, 'textMarkers.insHue'),\n\t\t\tinsBorderColor: (context) => resolveBorder(context, 'textMarkers.insHue'),\n\t\t\tinsDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.insHue'),\n\t\t\tdelBackground: (context) => resolveBg(context, 'textMarkers.delHue'),\n\t\t\tdelBorderColor: (context) => resolveBorder(context, 'textMarkers.delHue'),\n\t\t\tdelDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.delHue'),\n\t\t},\n\t},\n\tcssVarExclusions: [\n\t\t// Exclude all settings from CSS variable output that will not be used directly in styles,\n\t\t// but instead be used to calculate other settings\n\t\t'textMarkers.markHue',\n\t\t'textMarkers.insHue',\n\t\t'textMarkers.delHue',\n\t\t'textMarkers.defaultChroma',\n\t\t'textMarkers.defaultLuminance',\n\t\t'textMarkers.backgroundOpacity',\n\t\t'textMarkers.borderLuminance',\n\t\t'textMarkers.borderOpacity',\n\t\t'textMarkers.indicatorLuminance',\n\t\t'textMarkers.indicatorOpacity',\n\t],\n})\n\nexport function getTextMarkersBaseStyles({ cssVar }: ResolverContext) {\n\tconst result = `\n\t\t.${codeLineClass} {\n\t\t\t/* Support line-level mark/ins/del */\n\t\t\t&.mark {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t&.ins {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.insDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.insDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.del {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.delDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.delDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.mark,\n\t\t\t&.ins,\n\t\t\t&.del {\n\t\t\t\tposition: relative;\n\t\t\t\tbackground: var(--tmLineBgCol);\n\t\t\t\tmin-width: calc(100% - ${cssVar('textMarkers.lineMarkerAccentMargin')});\n\t\t\t\tmargin-inline-start: ${cssVar('textMarkers.lineMarkerAccentMargin')};\n\t\t\t\tborder-inline-start: ${cssVar('textMarkers.lineMarkerAccentWidth')} solid var(--tmLineBrdCol);\n\t\t\t\tpadding-inline-start: calc(${cssVar('codePaddingInline')} - ${cssVar('textMarkers.lineMarkerAccentMargin')} - ${cssVar('textMarkers.lineMarkerAccentWidth')}) !important;\n\t\t\t\t&::before {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tleft: ${cssVar('textMarkers.lineDiffIndicatorMarginLeft')};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Support inline mark/ins/del */\n\t\t\t& mark {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t& ins {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t}\n\t\t\t& del {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t}\n\t\t\t& mark,\n\t\t\t& ins,\n\t\t\t& del {\n\t\t\t\tall: unset;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tposition: relative;\n\t\t\t\t--tmBrdL: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmBrdR: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmRadL: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\t--tmRadR: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\tmargin-inline: 0.025rem;\n\t\t\t\tpadding-inline: ${cssVar('textMarkers.inlineMarkerPadding')};\n\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\tbackground: var(--tmInlineBgCol);\n\t\t\t\tbackground-clip: padding-box;\n\n\t\t\t\t&.open-start {\n\t\t\t\t\tmargin-inline-start: 0;\n\t\t\t\t\tpadding-inline-start: 0;\n\t\t\t\t\t--tmBrdL: 0px;\n\t\t\t\t\t--tmRadL: 0;\n\t\t\t\t}\n\t\t\t\t&.open-end {\n\t\t\t\t\tmargin-inline-end: 0;\n\t\t\t\t\tpadding-inline-end: 0;\n\t\t\t\t\t--tmBrdR: 0px;\n\t\t\t\t\t--tmRadR: 0;\n\t\t\t\t}\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: '';\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tinset: 0;\n\t\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\t\tborder: ${cssVar('textMarkers.inlineMarkerBorderWidth')} solid var(--tmInlineBrdCol);\n\t\t\t\t\tborder-inline-width: var(--tmBrdL) var(--tmBrdR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`\n\n\treturn result\n}\n\nexport const markerBgColorPaths: { [K in MarkerType]: StyleSettingPath } = {\n\tmark: 'textMarkers.markBackground',\n\tins: 'textMarkers.insBackground',\n\tdel: 'textMarkers.delBackground',\n}\n\nfunction resolveBg({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.defaultLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.backgroundOpacity')})`)\n}\n\nfunction resolveBorder({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.borderLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.borderOpacity')})`)\n}\n\nfunction resolveIndicator({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.indicatorLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.indicatorOpacity')})`)\n}\n","import { getGroupIndicesFromRegExpMatch } from '@expressive-code/core'\nimport { MarkerType, MarkerTypeOrder } from './marker-types'\nimport { PluginTextMarkersData } from '.'\n\nexport type InlineMarkerRange = { markerType: MarkerType; start: number; end: number }\n\n/**\n * Goes through all search terms in the given block data and returns an array of\n * inline marker ranges that match the given line text.\n */\nexport function getInlineSearchTermMatches(lineText: string, blockData: PluginTextMarkersData) {\n\tconst markerMatches: InlineMarkerRange[] = []\n\n\t// Collect all plaintext term matches\n\tblockData.plaintextTerms.forEach(({ markerType, text }) => {\n\t\tlet idx = lineText.indexOf(text, 0)\n\t\twhile (idx > -1) {\n\t\t\tmarkerMatches.push({\n\t\t\t\tmarkerType,\n\t\t\t\tstart: idx,\n\t\t\t\tend: idx + text.length,\n\t\t\t})\n\t\t\tidx = lineText.indexOf(text, idx + text.length)\n\t\t}\n\t})\n\n\t// Collect all regular expression matches\n\tblockData.regExpTerms.forEach(({ markerType, regExp }) => {\n\t\tconst matches = lineText.matchAll(regExp)\n\t\tfor (const match of matches) {\n\t\t\tconst rawGroupIndices = getGroupIndicesFromRegExpMatch(match)\n\t\t\t// Remove null group indices\n\t\t\tlet groupIndices = rawGroupIndices.flatMap((range) => (range ? [range] : []))\n\t\t\t// If there are no non-null indices, use the full match instead\n\t\t\t// (capture group feature fallback, impossible to cover in tests)\n\t\t\t/* c8 ignore start */\n\t\t\tif (!groupIndices.length) {\n\t\t\t\tconst fullMatchIndex = match.index as number\n\t\t\t\tgroupIndices = [[fullMatchIndex, fullMatchIndex + match[0].length]]\n\t\t\t}\n\t\t\t/* c8 ignore end */\n\t\t\t// If there are multiple non-null indices, remove the first one\n\t\t\t// as it is the full match and we only want to mark capture groups\n\t\t\tif (groupIndices.length > 1) {\n\t\t\t\tgroupIndices.shift()\n\t\t\t}\n\t\t\t// Create marked ranges from all remaining group indices\n\t\t\tgroupIndices.forEach((range) => {\n\t\t\t\tmarkerMatches.push({\n\t\t\t\t\tmarkerType,\n\t\t\t\t\tstart: range[0],\n\t\t\t\t\tend: range[1],\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t})\n\n\treturn markerMatches\n}\n\n/**\n * Takes an array of inline marker ranges and returns a new array without overlapping ranges,\n * either by merging them into a combined range (if their marker types are the same),\n * or by overriding lower-priority markers with higher-priority ones (if their types differ).\n */\nexport function flattenInlineMarkerRanges(markerRanges: InlineMarkerRange[]): InlineMarkerRange[] {\n\tconst flattenedRanges: InlineMarkerRange[] = []\n\tconst addRange = (newRange: InlineMarkerRange) => {\n\t\tfor (let idx = flattenedRanges.length - 1; idx >= 0; idx--) {\n\t\t\tconst curRange = flattenedRanges[idx]\n\t\t\t// No overlap: The new range ends before the current one starts,\n\t\t\t// or it starts after the current one ends\n\t\t\tif (newRange.end <= curRange.start || newRange.start >= curRange.end) continue\n\n\t\t\t// Full overlap: The new range fully covers the current one\n\t\t\tif (newRange.start <= curRange.start && newRange.end >= curRange.end) {\n\t\t\t\t// Remove current range\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Partial overlap with same marker type\n\t\t\tif (newRange.markerType === curRange.markerType) {\n\t\t\t\t// Remove current range and extend the new one to cover it\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tnewRange = {\n\t\t\t\t\t...newRange,\n\t\t\t\t\tstart: Math.min(newRange.start, curRange.start),\n\t\t\t\t\tend: Math.max(newRange.end, curRange.end),\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range leaves both the start and the end of the current range\n\t\t\t// uncovered, we need to split the current range into two parts\n\t\t\tif (newRange.start > curRange.start && newRange.end < curRange.end) {\n\t\t\t\t// Replace the current range with two partial ranges\n\t\t\t\tflattenedRanges.splice(idx, 1, { ...curRange, end: newRange.start }, { ...curRange, start: newRange.end })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range starts after the current one starts, shorten the current range\n\t\t\tif (newRange.start > curRange.start) {\n\t\t\t\tcurRange.end = newRange.start\n\t\t\t}\n\n\t\t\t// If the new range ends before the current one ends, shorten the current range\n\t\t\tif (newRange.end < curRange.end) {\n\t\t\t\tcurRange.start = newRange.end\n\t\t\t}\n\t\t}\n\t\t// Finally add the new range to the flattened ranges and sort them by start position\n\t\tflattenedRanges.push(newRange)\n\t\tflattenedRanges.sort((a, b) => a.start - b.start)\n\t}\n\n\tMarkerTypeOrder.forEach((markerType) => {\n\t\tmarkerRanges.filter((range) => range.markerType === markerType).forEach(addRange)\n\t})\n\n\treturn flattenedRanges\n}\n","import { addClassName, ExpressiveCodeAnnotation, AnnotationBaseOptions, AnnotationRenderOptions } from '@expressive-code/core'\nimport { h } from 'hastscript'\nimport { Element } from 'hast-util-select/lib/types'\nimport { MarkerType } from './marker-types'\n\nexport class TextMarkerAnnotation extends ExpressiveCodeAnnotation {\n\tmarkerType: MarkerType\n\tbackgroundColor: string\n\n\tconstructor({ markerType, backgroundColor, ...baseOptions }: { markerType: MarkerType; backgroundColor: string } & AnnotationBaseOptions) {\n\t\tsuper(baseOptions)\n\t\tthis.markerType = markerType\n\t\tthis.backgroundColor = backgroundColor\n\t}\n\n\trender(options: AnnotationRenderOptions) {\n\t\tif (!this.inlineRange) return this.renderFullLineMarker(options)\n\t\treturn this.renderInlineMarker(options)\n\t}\n\n\tprivate renderFullLineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node) => {\n\t\t\taddClassName(node as Element, this.markerType)\n\t\t\treturn node\n\t\t})\n\t}\n\n\tprivate renderInlineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node, idx) => {\n\t\t\tconst transformedNode = h(this.markerType, node)\n\n\t\t\tif (nodesToTransform.length > 0 && idx > 0) {\n\t\t\t\taddClassName(transformedNode, 'open-start')\n\t\t\t}\n\t\t\tif (nodesToTransform.length > 0 && idx < nodesToTransform.length - 1) {\n\t\t\t\taddClassName(transformedNode, 'open-end')\n\t\t\t}\n\t\t\treturn transformedNode\n\t\t})\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,6GAAAA,SAAA;AAAA;AAIA,aAAS,UAAU,QAAQ;AACzB,UAAI,MAAM,CAAC;AACX,UAAI;AAEJ,eAAS,OAAO,OAAO,MAAM,GAAG,EAAE,IAAI,CAACC,SAAQA,KAAI,KAAK,CAAC,GAAG;AAE1D,YAAI,UAAU,KAAK,GAAG,GAAG;AACvB,cAAI,KAAK,SAAS,KAAK,EAAE,CAAC;AAAA,QAC5B,WACG,IAAI,IAAI,MAAM,kDAAkD,GACjE;AAEA,cAAI,CAAC,GAAG,KAAK,KAAK,GAAG,IAAI;AAEzB,cAAI,OAAO,KAAK;AACd,kBAAM,SAAS,GAAG;AAClB,kBAAM,SAAS,GAAG;AAClB,kBAAM,OAAO,MAAM,MAAM,IAAI;AAG7B,gBAAI,QAAQ,OAAO,QAAQ,QAAQ,QAAQ;AAAU,qBAAO;AAE5D,qBAAS,IAAI,KAAK,MAAM,KAAK,KAAK;AAAM,kBAAI,KAAK,CAAC;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,YAAQ,UAAU;AAClB,IAAAD,QAAO,UAAU;AAAA;AAAA;;;ACnCjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAE,eAQO;AACP,iCAAwB;;;ACNjB,IAAM,kBAAgC,CAAC,QAAQ,OAAO,KAAK;AAQ3D,SAAS,qBAAqB,OAAe;AAEnD,MAAI,UAAU;AAAO,YAAQ;AAC7B,MAAI,UAAU;AAAO,YAAQ;AAG7B,QAAM,aAAa;AACnB,SAAO,gBAAgB,SAAS,UAAU,IAAI,aAAa;AAC5D;;;ACnBA,kBAAmH;AAyK5G,IAAM,2BAA2B,IAAI,gCAAoB;AAAA,EAC/D,eAAe;AAAA,IACd,aAAa;AAAA,MACZ,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,6BAA6B;AAAA,MAC7B,yBAAyB;AAAA,MACzB,0BAA0B;AAAA,MAC1B,qBAAqB;AAAA;AAAA;AAAA,MAGrB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,kBAAkB,CAAC,OAAO,KAAK;AAAA,MAC/B,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,oBAAoB,CAAC,OAAO,KAAK;AAAA,MACjC,kBAAkB;AAAA;AAAA,MAElB,yBAAyB;AAAA,MACzB,yBAAyB;AAAA;AAAA,MAEzB,gBAAgB,CAAC,YAAY,UAAU,SAAS,qBAAqB;AAAA,MACrE,iBAAiB,CAAC,YAAY,cAAc,SAAS,qBAAqB;AAAA,MAC1E,eAAe,CAAC,YAAY,UAAU,SAAS,oBAAoB;AAAA,MACnE,gBAAgB,CAAC,YAAY,cAAc,SAAS,oBAAoB;AAAA,MACxE,uBAAuB,CAAC,YAAY,iBAAiB,SAAS,oBAAoB;AAAA,MAClF,eAAe,CAAC,YAAY,UAAU,SAAS,oBAAoB;AAAA,MACnE,gBAAgB,CAAC,YAAY,cAAc,SAAS,oBAAoB;AAAA,MACxE,uBAAuB,CAAC,YAAY,iBAAiB,SAAS,oBAAoB;AAAA,IACnF;AAAA,EACD;AAAA,EACA,kBAAkB;AAAA;AAAA;AAAA,IAGjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD,CAAC;AAEM,SAAS,yBAAyB,EAAE,OAAO,GAAoB;AACrE,QAAM,SAAS;AAAA,KACX,yBAAa;AAAA;AAAA;AAAA,qBAGG,OAAO,4BAA4B,CAAC;AAAA,sBACnC,OAAO,6BAA6B,CAAC;AAAA;AAAA;AAAA,qBAGtC,OAAO,2BAA2B,CAAC;AAAA,sBAClC,OAAO,4BAA4B,CAAC;AAAA;AAAA,gBAE1C,OAAO,qCAAqC,CAAC;AAAA,cAC/C,OAAO,mCAAmC,CAAC;AAAA;AAAA;AAAA;AAAA,qBAIpC,OAAO,2BAA2B,CAAC;AAAA,sBAClC,OAAO,4BAA4B,CAAC;AAAA;AAAA,gBAE1C,OAAO,qCAAqC,CAAC;AAAA,cAC/C,OAAO,mCAAmC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAQ5B,OAAO,oCAAoC,CAAC;AAAA,2BAC9C,OAAO,oCAAoC,CAAC;AAAA,2BAC5C,OAAO,mCAAmC,CAAC;AAAA,iCACrC,OAAO,mBAAmB,CAAC,MAAM,OAAO,oCAAoC,CAAC,MAAM,OAAO,mCAAmC,CAAC;AAAA;AAAA;AAAA,aAGlJ,OAAO,yCAAyC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAMvC,OAAO,4BAA4B,CAAC;AAAA,wBACnC,OAAO,6BAA6B,CAAC;AAAA;AAAA;AAAA,uBAGtC,OAAO,2BAA2B,CAAC;AAAA,wBAClC,OAAO,4BAA4B,CAAC;AAAA;AAAA;AAAA,uBAGrC,OAAO,2BAA2B,CAAC;AAAA,wBAClC,OAAO,4BAA4B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAQ5C,OAAO,qCAAqC,CAAC;AAAA,gBAC7C,OAAO,qCAAqC,CAAC;AAAA,gBAC7C,OAAO,sCAAsC,CAAC;AAAA,gBAC9C,OAAO,sCAAsC,CAAC;AAAA;AAAA,sBAExC,OAAO,iCAAiC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAwBhD,OAAO,qCAAqC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAO3D,SAAO;AACR;AAEO,IAAM,qBAA8D;AAAA,EAC1E,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AACN;AAEA,SAAS,UAAU,EAAE,gBAAgB,EAAE,GAAmC,KAAuB;AAChG,aAAO,wBAAW,OAAO,EAAE,8BAA8B,CAAC,IAAI,EAAE,2BAA2B,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,+BAA+B,CAAC,GAAG;AAClJ;AAEA,SAAS,cAAc,EAAE,gBAAgB,EAAE,GAAmC,KAAuB;AACpG,aAAO,wBAAW,OAAO,EAAE,6BAA6B,CAAC,IAAI,EAAE,2BAA2B,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,2BAA2B,CAAC,GAAG;AAC7I;AAEA,SAAS,iBAAiB,EAAE,gBAAgB,EAAE,GAAmC,KAAuB;AACvG,aAAO,wBAAW,OAAO,EAAE,gCAAgC,CAAC,IAAI,EAAE,2BAA2B,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,8BAA8B,CAAC,GAAG;AACnJ;;;AC7UA,IAAAC,eAA+C;AAUxC,SAAS,2BAA2B,UAAkB,WAAkC;AAC9F,QAAM,gBAAqC,CAAC;AAG5C,YAAU,eAAe,QAAQ,CAAC,EAAE,YAAY,KAAK,MAAM;AAC1D,QAAI,MAAM,SAAS,QAAQ,MAAM,CAAC;AAClC,WAAO,MAAM,IAAI;AAChB,oBAAc,KAAK;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,QACP,KAAK,MAAM,KAAK;AAAA,MACjB,CAAC;AACD,YAAM,SAAS,QAAQ,MAAM,MAAM,KAAK,MAAM;AAAA,IAC/C;AAAA,EACD,CAAC;AAGD,YAAU,YAAY,QAAQ,CAAC,EAAE,YAAY,OAAO,MAAM;AACzD,UAAM,UAAU,SAAS,SAAS,MAAM;AACxC,eAAW,SAAS,SAAS;AAC5B,YAAM,sBAAkB,6CAA+B,KAAK;AAE5D,UAAI,eAAe,gBAAgB,QAAQ,CAAC,UAAW,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAE;AAI5E,UAAI,CAAC,aAAa,QAAQ;AACzB,cAAM,iBAAiB,MAAM;AAC7B,uBAAe,CAAC,CAAC,gBAAgB,iBAAiB,MAAM,CAAC,EAAE,MAAM,CAAC;AAAA,MACnE;AAIA,UAAI,aAAa,SAAS,GAAG;AAC5B,qBAAa,MAAM;AAAA,MACpB;AAEA,mBAAa,QAAQ,CAAC,UAAU;AAC/B,sBAAc,KAAK;AAAA,UAClB;AAAA,UACA,OAAO,MAAM,CAAC;AAAA,UACd,KAAK,MAAM,CAAC;AAAA,QACb,CAAC;AAAA,MACF,CAAC;AAAA,IACF;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAOO,SAAS,0BAA0B,cAAwD;AACjG,QAAM,kBAAuC,CAAC;AAC9C,QAAM,WAAW,CAAC,aAAgC;AACjD,aAAS,MAAM,gBAAgB,SAAS,GAAG,OAAO,GAAG,OAAO;AAC3D,YAAM,WAAW,gBAAgB,GAAG;AAGpC,UAAI,SAAS,OAAO,SAAS,SAAS,SAAS,SAAS,SAAS;AAAK;AAGtE,UAAI,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO,SAAS,KAAK;AAErE,wBAAgB,OAAO,KAAK,CAAC;AAC7B;AAAA,MACD;AAGA,UAAI,SAAS,eAAe,SAAS,YAAY;AAEhD,wBAAgB,OAAO,KAAK,CAAC;AAC7B,mBAAW;AAAA,UACV,GAAG;AAAA,UACH,OAAO,KAAK,IAAI,SAAS,OAAO,SAAS,KAAK;AAAA,UAC9C,KAAK,KAAK,IAAI,SAAS,KAAK,SAAS,GAAG;AAAA,QACzC;AACA;AAAA,MACD;AAIA,UAAI,SAAS,QAAQ,SAAS,SAAS,SAAS,MAAM,SAAS,KAAK;AAEnE,wBAAgB,OAAO,KAAK,GAAG,EAAE,GAAG,UAAU,KAAK,SAAS,MAAM,GAAG,EAAE,GAAG,UAAU,OAAO,SAAS,IAAI,CAAC;AACzG;AAAA,MACD;AAGA,UAAI,SAAS,QAAQ,SAAS,OAAO;AACpC,iBAAS,MAAM,SAAS;AAAA,MACzB;AAGA,UAAI,SAAS,MAAM,SAAS,KAAK;AAChC,iBAAS,QAAQ,SAAS;AAAA,MAC3B;AAAA,IACD;AAEA,oBAAgB,KAAK,QAAQ;AAC7B,oBAAgB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA,EACjD;AAEA,kBAAgB,QAAQ,CAAC,eAAe;AACvC,iBAAa,OAAO,CAAC,UAAU,MAAM,eAAe,UAAU,EAAE,QAAQ,QAAQ;AAAA,EACjF,CAAC;AAED,SAAO;AACR;;;ACzHA,IAAAC,eAAuG;AACvG,wBAAkB;AAIX,IAAM,uBAAN,cAAmC,sCAAyB;AAAA,EAClE;AAAA,EACA;AAAA,EAEA,YAAY,EAAE,YAAY,iBAAiB,GAAG,YAAY,GAAgF;AACzI,UAAM,WAAW;AACjB,SAAK,aAAa;AAClB,SAAK,kBAAkB;AAAA,EACxB;AAAA,EAEA,OAAO,SAAkC;AACxC,QAAI,CAAC,KAAK;AAAa,aAAO,KAAK,qBAAqB,OAAO;AAC/D,WAAO,KAAK,mBAAmB,OAAO;AAAA,EACvC;AAAA,EAEQ,qBAAqB,EAAE,iBAAiB,GAA4B;AAC3E,WAAO,iBAAiB,IAAI,CAAC,SAAS;AACrC,qCAAa,MAAiB,KAAK,UAAU;AAC7C,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAEQ,mBAAmB,EAAE,iBAAiB,GAA4B;AACzE,WAAO,iBAAiB,IAAI,CAAC,MAAM,QAAQ;AAC1C,YAAM,sBAAkB,qBAAE,KAAK,YAAY,IAAI;AAE/C,UAAI,iBAAiB,SAAS,KAAK,MAAM,GAAG;AAC3C,uCAAa,iBAAiB,YAAY;AAAA,MAC3C;AACA,UAAI,iBAAiB,SAAS,KAAK,MAAM,iBAAiB,SAAS,GAAG;AACrE,uCAAa,iBAAiB,UAAU;AAAA,MACzC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AACD;;;AJxBO,SAAS,oBAA0C;AACzD,SAAO;AAAA,IACN,MAAM;AAAA,IACN,eAAe;AAAA,IACf,YAAY,CAAC,YAAY,yBAAyB,OAAO;AAAA,IACzD,OAAO;AAAA,MACN,oBAAoB,CAAC,EAAE,WAAW,OAAO,MAAM;AAC9C,cAAM,YAAY,sBAAsB,eAAe,SAAS;AAEhE,kBAAU,WAAO;AAAA,UAChB,UAAU;AAAA,UACV,CAAC,EAAE,WAAW,KAAK,OAAO,oBAAoB,MAAM;AAGnD,gBAAI,QAAQ,UAAU,UAAU,aAAa,QAAQ;AACpD,wBAAU,WAAW;AACrB,wBAAU,mBAAmB;AAC7B,qBAAO;AAAA,YACR;AAGA,kBAAM,aAAa,qBAAqB,OAAO,MAAM;AAGrD,gBAAI,CAAC;AAAY,qBAAO;AAGxB,gBAAI,wBAAwB,KAAK;AAChC,oBAAM,kBAAc,2BAAAC,SAAY,KAAK;AACrC,0BAAY,QAAQ,CAAC,eAAe;AACnC,sBAAM,YAAY,aAAa;AAC/B,0BAAU,QAAQ,SAAS,GAAG;AAAA,kBAC7B,IAAI,qBAAqB;AAAA,oBACxB;AAAA,oBACA,iBAAiB,OAAO,mBAAmB,UAAU,CAAC;AAAA,kBACvD,CAAC;AAAA,gBACF;AAAA,cACD,CAAC;AACD,qBAAO;AAAA,YACR;AAGA,gBAAI,wBAAwB,KAAK;AAEhC,kBAAI;AACJ,kBAAI;AAEH,yBAAS,IAAI,OAAO,OAAO,IAAI;AAAA,cAEhC,SAAS,OAAO;AAEf,yBAAS,IAAI,OAAO,OAAO,GAAG;AAAA,cAC/B;AAEA,wBAAU,YAAY,KAAK;AAAA,gBAC1B;AAAA,gBACA;AAAA,cACD,CAAC;AACD,qBAAO;AAAA,YACR;AAIA,sBAAU,eAAe,KAAK;AAAA,cAC7B;AAAA,cACA,MAAM;AAAA,YACP,CAAC;AACD,mBAAO;AAAA,UACR;AAAA,UACA;AAAA,YACC,iBAAiB,CAAC,KAAK,KAAK,KAAK,OAAO;AAAA,YACxC,mBAAmB;AAAA,UACpB;AAAA,QACD;AAAA,MACD;AAAA,MACA,gBAAgB,CAAC,EAAE,WAAW,OAAO,MAAM;AAC1C,cAAM,YAAY,sBAAsB,eAAe,SAAS;AAWhE,aAAK,UAAU,oBAAoB,UAAU,cAAc,QAAQ;AAClE,gBAAM,QAAQ,UAAU,SAAS;AAGjC,gBAAM,sBAAsB,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,4CAA4C,CAAC;AAC1H,cAAI,CAAC,qBAAqB;AACzB,gBAAI,iBAAiB;AACrB,kBAAM,cAAc,MAAM,IAAI,CAAC,SAAS;AACvC,oBAAM,CAAC,EAAE,aAAa,QAAQ,OAAO,IAAI,KAAK,KAAK,MAAM,4BAA4B,KAAK,CAAC;AAC3F,oBAAM,aAAqC,WAAW,MAAM,QAAQ,WAAW,MAAM,QAAQ;AAK7F,kBAAI,QAAQ,KAAK,EAAE,SAAS,KAAK,YAAY,SAAS;AAAgB,iCAAiB,YAAY;AAEnG,qBAAO;AAAA,gBACN;AAAA,gBACA;AAAA,cACD;AAAA,YACD,CAAC;AAED,wBAAY,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM;AAK7C,oBAAM,eAAe,mBAAmB,aAAa,IAAI;AACzD,kBAAI,eAAe;AAAG,qBAAK,SAAS,GAAG,cAAc,EAAE;AAGvD,kBAAI,YAAY;AACf,qBAAK;AAAA,kBACJ,IAAI,qBAAqB;AAAA,oBACxB;AAAA,oBACA,iBAAiB,OAAO,mBAAmB,UAAU,CAAC;AAAA,kBACvD,CAAC;AAAA,gBACF;AAAA,cACD;AAAA,YACD,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD;AAAA,MACA,cAAc,CAAC,EAAE,WAAW,OAAO,MAAM;AACxC,cAAM,YAAY,sBAAsB,eAAe,SAAS;AAEhE,kBAAU,SAAS,EAAE,QAAQ,CAAC,SAAS;AAEtC,gBAAM,eAAe,2BAA2B,KAAK,MAAM,SAAS;AACpE,cAAI,CAAC,aAAa;AAAQ;AAG1B,gBAAM,kBAAkB,0BAA0B,YAAY;AAG9D,0BAAgB,QAAQ,CAAC,EAAE,YAAY,OAAO,IAAI,MAAM;AACvD,iBAAK;AAAA,cACJ,IAAI,qBAAqB;AAAA,gBACxB;AAAA,gBACA,iBAAiB,OAAO,mBAAmB,UAAU,CAAC;AAAA,gBACtD,aAAa;AAAA,kBACZ,aAAa;AAAA,kBACb,WAAW;AAAA,gBACZ;AAAA,cACD,CAAC;AAAA,YACF;AAAA,UACD,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,MACA,wBAAwB,CAAC,EAAE,WAAW,eAAe,OAAO,MAAM;AACjE,YAAI,OAAO,sCAAsC;AAAG;AACpD,kBAAU,SAAS,EAAE,QAAQ,CAAC,SAAS;AACtC,gBAAM,cAAc,KAAK,eAAe;AAGxC,gBAAM,UAAkC,CAAC;AACzC,cAAI,iBAAmD;AACvD,qBAAW,cAAc,aAAa;AACrC,gBAAI,EAAE,sBAAsB;AAAuB;AACnD,gBAAI,WAAW,aAAa;AAC3B,sBAAQ,KAAK,UAAU;AACvB;AAAA,YACD;AACA,gBAAI,gBAAgB;AACnB,kBAAI,gBAAgB,QAAQ,WAAW,UAAU,IAAI,gBAAgB,QAAQ,eAAe,UAAU;AAAG;AACzG,kBAAI,wCAA2B,QAAQ,WAAW,WAAW,IAAI,wCAA2B,QAAQ,eAAe,WAAW;AAAG;AAAA,YAClI;AACA,6BAAiB;AAAA,UAClB;AAEA,cAAI;AAAgB,oBAAQ,QAAQ,cAAc;AAElD,wBAAc,QAAQ,CAAC,cAAc,sBAAsB;AAC1D,kBAAM,wBAAyB,kBAAkB,aAAa,sBAAsB,IAAI,mBAAmB,eAAe,UAAU,CAAC,KAAM;AAC3I,kBAAM,kBAAc,2BAAa,uBAAuB,aAAa,sBAAsB,IAAI,gBAAgB,KAAK,aAAa,MAAM,EAAE;AAEzI,kBAAM,aAAa,YAAY;AAAA,cAC9B,CAAC,eACA,sBAAsB;AAAA,cAEtB,WAAW,sBAAsB,qBACjC,WAAW;AAAA,YACb;AAEA,uBAAW,QAAQ,CAAC,cAAc;AACjC,oBAAM,cAAc,UAAU;AAC9B,oBAAM,YAAY,UAAU,aAAa;AACzC,oBAAM,UAAU,UAAU,aAAa;AACvC,kBAAI,gBAAgB,UAAa,cAAc,UAAa,YAAY;AAAW;AAEnF,sBAAQ,QAAQ,CAAC,WAAW;AAC3B,sBAAM,cAAc,OAAO,aAAa,eAAe;AACvD,sBAAM,YAAY,OAAO,aAAa,aAAa,KAAK,KAAK;AAC7D,oBAAI,cAAc,WAAW,YAAY;AAAW;AAGpD,sBAAM,gBAAgB,aAAa,sBAAsB,IAAI,mBAAmB,OAAO,UAAU,CAAC,KAAK;AACvG,sBAAM,sBAAkB,2BAAa,eAAe,WAAW;AAE/D,sBAAM,wBAAoB,8CAAgC,aAAa,iBAAiB,OAAO,kCAAkC;AACjI,oBAAI,kBAAkB,YAAY,MAAM,YAAY,YAAY;AAAG;AAGnE,qBAAK;AAAA,kBACJ,IAAI,mCAAsB;AAAA,oBACzB;AAAA,oBACA,aAAa;AAAA,sBACZ,aAAa,KAAK,IAAI,WAAW,WAAW;AAAA,sBAC5C,WAAW,KAAK,IAAI,SAAS,SAAS;AAAA,oBACvC;AAAA,oBACA,OAAO;AAAA,kBACR,CAAC;AAAA,gBACF;AAAA,cACD,CAAC;AAAA,YACF,CAAC;AAAA,UACF,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AACD;AAQO,IAAM,wBAAwB,IAAI,gCAA0C,OAAO,EAAE,gBAAgB,CAAC,GAAG,aAAa,CAAC,EAAE,EAAE;","names":["module","str","import_core","import_core","import_core","rangeParser"]} | ||
| {"version":3,"sources":["../../../../node_modules/.pnpm/parse-numeric-range@1.3.0/node_modules/parse-numeric-range/index.js","../src/index.ts","../src/marker-types.ts","../src/styles.ts","../src/inline-markers.ts","../src/annotations.ts"],"sourcesContent":["/**\n * @param {string} string The string to parse\n * @returns {Array<number>} Returns an energetic array.\n */\nfunction parsePart(string) {\n let res = [];\n let m;\n\n for (let str of string.split(\",\").map((str) => str.trim())) {\n // just a number\n if (/^-?\\d+$/.test(str)) {\n res.push(parseInt(str, 10));\n } else if (\n (m = str.match(/^(-?\\d+)(-|\\.\\.\\.?|\\u2025|\\u2026|\\u22EF)(-?\\d+)$/))\n ) {\n // 1-5 or 1..5 (equivalent) or 1...5 (doesn't include 5)\n let [_, lhs, sep, rhs] = m;\n\n if (lhs && rhs) {\n lhs = parseInt(lhs);\n rhs = parseInt(rhs);\n const incr = lhs < rhs ? 1 : -1;\n\n // Make it inclusive by moving the right 'stop-point' away by one.\n if (sep === \"-\" || sep === \"..\" || sep === \"\\u2025\") rhs += incr;\n\n for (let i = lhs; i !== rhs; i += incr) res.push(i);\n }\n }\n }\n\n return res;\n}\n\nexports.default = parsePart;\nmodule.exports = parsePart;\n","import {\n\tAnnotationRenderPhaseOrder,\n\tAttachedPluginData,\n\tExpressiveCodePlugin,\n\tInlineStyleAnnotation,\n\tensureColorContrastOnBackground,\n\tonBackground,\n\treplaceDelimitedValues,\n} from '@expressive-code/core'\nimport rangeParser from 'parse-numeric-range'\nimport { MarkerType, MarkerTypeOrder, markerTypeFromString } from './marker-types'\nimport { getTextMarkersBaseStyles, markerBgColorPaths, textMarkersStyleSettings } from './styles'\nimport { flattenInlineMarkerRanges, getInlineSearchTermMatches } from './inline-markers'\nimport { TextMarkerAnnotation } from './annotations'\nexport { TextMarkersStyleSettings } from './styles'\n\nexport function pluginTextMarkers(): ExpressiveCodePlugin {\n\treturn {\n\t\tname: 'TextMarkers',\n\t\tstyleSettings: textMarkersStyleSettings,\n\t\tbaseStyles: (context) => getTextMarkersBaseStyles(context),\n\t\thooks: {\n\t\t\tpreprocessMetadata: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.meta = replaceDelimitedValues(\n\t\t\t\t\tcodeBlock.meta,\n\t\t\t\t\t({ fullMatch, key, value, valueStartDelimiter }) => {\n\t\t\t\t\t\t// If we found a \"lang\" key and the code block's language is \"diff\",\n\t\t\t\t\t\t// use the \"lang\" value as the new syntax highlighting language instead\n\t\t\t\t\t\tif (key === 'lang' && codeBlock.language === 'diff') {\n\t\t\t\t\t\t\tcodeBlock.language = value\n\t\t\t\t\t\t\tblockData.originalLanguage = 'diff'\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Try to identify the marker type from the key\n\t\t\t\t\t\tconst markerType = markerTypeFromString(key || 'mark')\n\n\t\t\t\t\t\t// If an unknown key was encountered, leave this meta string part untouched\n\t\t\t\t\t\tif (!markerType) return fullMatch\n\n\t\t\t\t\t\t// Handle full-line highlighting definitions\n\t\t\t\t\t\tif (valueStartDelimiter === '{') {\n\t\t\t\t\t\t\tconst lineNumbers = rangeParser(value)\n\t\t\t\t\t\t\tlineNumbers.forEach((lineNumber) => {\n\t\t\t\t\t\t\t\tconst lineIndex = lineNumber - 1\n\t\t\t\t\t\t\t\tcodeBlock.getLine(lineIndex)?.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle regular expression search terms\n\t\t\t\t\t\tif (valueStartDelimiter === '/') {\n\t\t\t\t\t\t\t// Remember the term for highlighting in a later hook\n\t\t\t\t\t\t\tlet regExp: RegExp | undefined\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Try to use regular expressions with capture group indices\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'gd')\n\t\t\t\t\t\t\t\t/* c8 ignore start */\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t// Use fallback if unsupported\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'g')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/* c8 ignore stop */\n\t\t\t\t\t\t\tblockData.regExpTerms.push({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tregExp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Treat everything else as a plaintext search term and\n\t\t\t\t\t\t// remember it for highlighting in a later hook\n\t\t\t\t\t\tblockData.plaintextTerms.push({\n\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalueDelimiters: ['\"', \"'\", '/', '{...}'],\n\t\t\t\t\t\tkeyValueSeparator: '=',\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t},\n\t\t\tpreprocessCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\t// Perform special handling of code marked with the language \"diff\":\n\t\t\t\t// - This language is often used as a widely supported format for highlighting\n\t\t\t\t// changes to code. In this case, the code is not actually a diff,\n\t\t\t\t// but another language with some lines prefixed by `+` or `-`.\n\t\t\t\t// - We try to detect this case and convert the prefixed lines to annotations\n\t\t\t\t// - To prevent modifying actual diff files (which would make them invalid),\n\t\t\t\t// we ensure that the code does not begin like a real diff:\n\t\t\t\t// - The first lines must not start with `*** `, `+++ `, `--- `, `@@ `,\n\t\t\t\t// or the default mode location syntax (e.g. `0a1`, `1,2c1,2`, `1,2d1`).\n\t\t\t\tif ((blockData.originalLanguage ?? codeBlock.language) === 'diff') {\n\t\t\t\t\tconst lines = codeBlock.getLines()\n\n\t\t\t\t\t// Ensure that the first lines do not look like actual diff output\n\t\t\t\t\tconst couldBeRealDiffFile = lines.slice(0, 4).some((line) => line.text.match(/^([*+-]{3}\\s|@@\\s|[0-9,]+[acd][0-9,]+\\s*$)/))\n\t\t\t\t\tif (!couldBeRealDiffFile) {\n\t\t\t\t\t\tlet minIndentation = Infinity\n\t\t\t\t\t\tconst parsedLines = lines.map((line) => {\n\t\t\t\t\t\t\tconst [, indentation, marker, content] = line.text.match(/^(([+-](?![+-]))?\\s*)(.*)$/) || []\n\t\t\t\t\t\t\tconst markerType: MarkerType | undefined = marker === '+' ? 'ins' : marker === '-' ? 'del' : undefined\n\n\t\t\t\t\t\t\t// As it's common to indent unchanged lines to match the indentation\n\t\t\t\t\t\t\t// of changed lines, and we don't want extra whitespace in the output,\n\t\t\t\t\t\t\t// we remember the minimum indentation of all non-empty lines\n\t\t\t\t\t\t\tif (content.trim().length > 0 && indentation.length < minIndentation) minIndentation = indentation.length\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tparsedLines.forEach(({ line, markerType }) => {\n\t\t\t\t\t\t\t// Remove line prefixes:\n\t\t\t\t\t\t\t// - If minIndentation is > 0, we remove minIndentation\n\t\t\t\t\t\t\t// - Otherwise, if the current line starts with a marker character,\n\t\t\t\t\t\t\t// we remove this single character\n\t\t\t\t\t\t\tconst colsToRemove = minIndentation || (markerType ? 1 : 0)\n\t\t\t\t\t\t\tif (colsToRemove > 0) line.editText(0, colsToRemove, '')\n\n\t\t\t\t\t\t\t// If we found a diff marker, add a line annotation\n\t\t\t\t\t\t\tif (markerType) {\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tannotateCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\t// Check the line text for search term matches and collect their ranges\n\t\t\t\t\tconst markerRanges = getInlineSearchTermMatches(line.text, blockData)\n\t\t\t\t\tif (!markerRanges.length) return\n\n\t\t\t\t\t// Flatten marked ranges to prevent any overlaps\n\t\t\t\t\tconst flattenedRanges = flattenInlineMarkerRanges(markerRanges)\n\n\t\t\t\t\t// Add annotations for all flattened ranges\n\t\t\t\t\tflattenedRanges.forEach(({ markerType, start, end }) => {\n\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\tcolumnStart: start,\n\t\t\t\t\t\t\t\t\tcolumnEnd: end,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t\tpostprocessAnnotations: ({ codeBlock, styleVariants, config }) => {\n\t\t\t\tif (config.minSyntaxHighlightingColorContrast <= 0) return\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\tconst annotations = line.getAnnotations()\n\t\t\t\t\t// Determine the highest-priority full line marker\n\t\t\t\t\t// and collect all inline markers\n\t\t\t\t\tconst markers: TextMarkerAnnotation[] = []\n\t\t\t\t\tlet fullLineMarker: TextMarkerAnnotation | undefined = undefined\n\t\t\t\t\tfor (const annotation of annotations) {\n\t\t\t\t\t\tif (!(annotation instanceof TextMarkerAnnotation)) continue\n\t\t\t\t\t\tif (annotation.inlineRange) {\n\t\t\t\t\t\t\tmarkers.push(annotation)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fullLineMarker) {\n\t\t\t\t\t\t\tif (MarkerTypeOrder.indexOf(annotation.markerType) < MarkerTypeOrder.indexOf(fullLineMarker.markerType)) continue\n\t\t\t\t\t\t\tif (AnnotationRenderPhaseOrder.indexOf(annotation.renderPhase) < AnnotationRenderPhaseOrder.indexOf(fullLineMarker.renderPhase)) continue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfullLineMarker = annotation\n\t\t\t\t\t}\n\t\t\t\t\t// Prepend the highest-priority full line marker to the inline markers\n\t\t\t\t\tif (fullLineMarker) markers.unshift(fullLineMarker)\n\t\t\t\t\t// Ensure color contrast for all style variants\n\t\t\t\t\tstyleVariants.forEach((styleVariant, styleVariantIndex) => {\n\t\t\t\t\t\tconst fullLineMarkerBgColor = (fullLineMarker && styleVariant.resolvedStyleSettings.get(markerBgColorPaths[fullLineMarker.markerType])) || 'transparent'\n\t\t\t\t\t\tconst lineBgColor = onBackground(fullLineMarkerBgColor, styleVariant.resolvedStyleSettings.get('codeBackground') || styleVariant.theme.bg)\n\t\t\t\t\t\t// Collect inline style annotations that change the text color\n\t\t\t\t\t\tconst textColors = annotations.filter(\n\t\t\t\t\t\t\t(annotation) =>\n\t\t\t\t\t\t\t\tannotation instanceof InlineStyleAnnotation &&\n\t\t\t\t\t\t\t\tannotation.color &&\n\t\t\t\t\t\t\t\t// Only consider annotations that apply to the current style variant\n\t\t\t\t\t\t\t\t(annotation.styleVariantIndex === undefined || annotation.styleVariantIndex === styleVariantIndex)\n\t\t\t\t\t\t) as InlineStyleAnnotation[]\n\t\t\t\t\t\t// Go through all text color annotations\n\t\t\t\t\t\ttextColors.forEach((textColor) => {\n\t\t\t\t\t\t\tconst textFgColor = textColor.color\n\t\t\t\t\t\t\tconst textStart = textColor.inlineRange?.columnStart\n\t\t\t\t\t\t\tconst textEnd = textColor.inlineRange?.columnEnd\n\t\t\t\t\t\t\tif (textFgColor === undefined || textStart === undefined || textEnd === undefined) return\n\t\t\t\t\t\t\t// Go through all markers\n\t\t\t\t\t\t\tmarkers.forEach((marker) => {\n\t\t\t\t\t\t\t\tconst markerStart = marker.inlineRange?.columnStart ?? 0\n\t\t\t\t\t\t\t\tconst markerEnd = marker.inlineRange?.columnEnd ?? line.text.length\n\t\t\t\t\t\t\t\tif (markerStart > textEnd || markerEnd < textStart) return\n\t\t\t\t\t\t\t\t// As the marker overlaps with the text color annotation,\n\t\t\t\t\t\t\t\t// determine the combined background color of this range\n\t\t\t\t\t\t\t\tconst markerBgColor = styleVariant.resolvedStyleSettings.get(markerBgColorPaths[marker.markerType]) ?? ''\n\t\t\t\t\t\t\t\tconst combinedBgColor = onBackground(markerBgColor, lineBgColor)\n\t\t\t\t\t\t\t\t// Now ensure a good contrast ratio of the text\n\t\t\t\t\t\t\t\tconst readableTextColor = ensureColorContrastOnBackground(textFgColor, combinedBgColor, config.minSyntaxHighlightingColorContrast)\n\t\t\t\t\t\t\t\tif (readableTextColor.toLowerCase() === textFgColor.toLowerCase()) return\n\t\t\t\t\t\t\t\t// If the text color is not readable enough, add an annotation\n\t\t\t\t\t\t\t\t// with better contrast for the overlapping range\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew InlineStyleAnnotation({\n\t\t\t\t\t\t\t\t\t\tstyleVariantIndex,\n\t\t\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\t\t\tcolumnStart: Math.max(textStart, markerStart),\n\t\t\t\t\t\t\t\t\t\t\tcolumnEnd: Math.min(textEnd, markerEnd),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tcolor: readableTextColor,\n\t\t\t\t\t\t\t\t\t\trenderPhase: 'earlier',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface PluginTextMarkersData {\n\tplaintextTerms: { markerType: MarkerType; text: string }[]\n\tregExpTerms: { markerType: MarkerType; regExp: RegExp }[]\n\toriginalLanguage?: string | undefined\n}\n\nexport const pluginTextMarkersData = new AttachedPluginData<PluginTextMarkersData>(() => ({ plaintextTerms: [], regExpTerms: [] }))\n","export type MarkerType = 'mark' | 'ins' | 'del'\n\n/** When markers overlap, those with higher indices override lower ones. */\nexport const MarkerTypeOrder: MarkerType[] = ['mark', 'del', 'ins']\n\n/**\n * If the given input string represents a valid marker type,\n * converts it to a {@link MarkerType} and returns it.\n *\n * Otherwise, returns `undefined`.\n */\nexport function markerTypeFromString(input: string) {\n\t// Fix common marker type mistakes\n\tif (input === 'add') input = 'ins'\n\tif (input === 'rem') input = 'del'\n\n\t// Return either the converted type or undefined\n\tconst markerType = input as MarkerType\n\treturn MarkerTypeOrder.includes(markerType) ? markerType : undefined\n}\n","import { PluginStyleSettings, codeLineClass, toHexColor, StyleSettingPath, ResolverContext, StyleResolverFn } from '@expressive-code/core'\nimport { MarkerType } from './marker-types'\n\nexport interface TextMarkersStyleSettings {\n\t/**\n\t * The margin between the code block border and the line marker accent bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0rem'\n\t */\n\tlineMarkerAccentMargin: string\n\t/**\n\t * The width of the line marker accent bar. This is the vertical border-like bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.15rem'\n\t */\n\tlineMarkerAccentWidth: string\n\t/**\n\t * The margin between the code block border and the diff indicator (e.g. `+` or `-`)\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.5rem'\n\t */\n\tlineDiffIndicatorMarginLeft: string\n\t/**\n\t * The width of the border around inline text markers, rendered in a way\n\t * that does not cause marked code to shift.\n\t * @default '1.5px'\n\t */\n\tinlineMarkerBorderWidth: string\n\t/**\n\t * The border radius of inline text markers.\n\t * @default '0.2rem'\n\t */\n\tinlineMarkerBorderRadius: string\n\t/**\n\t * The inline padding of inline text markers. Keep this low to prevent marked code\n\t * from shifting too much compared to the original text.\n\t * @default '0.15rem'\n\t */\n\tinlineMarkerPadding: string\n\t/**\n\t * The LCH hue to be used for marked text (text marker type `mark`).\n\t * @default '284' (a blue hue)\n\t */\n\tmarkHue: string\n\t/**\n\t * The LCH hue to be used for inserted text (text marker type `ins`).\n\t * @default '136' (a green hue)\n\t */\n\tinsHue: string\n\t/**\n\t * The LCH hue to be used for deleted text (text marker type `del`).\n\t * @default '33' (a red hue)\n\t */\n\tdelHue: string\n\t/**\n\t * The LCH chroma to be used for all text marker types.\n\t *\n\t * The chroma value defines the saturation of the color. Higher values lead to\n\t * more saturated colors, lower values lead to less saturated colors.\n\t *\n\t * @default '40'\n\t */\n\tdefaultChroma: string\n\t/**\n\t * The LCH luminance to be used for all text marker types.\n\t * @default\n\t * ['32%', '75%'] // 32% for dark themes, 75% for light themes\n\t */\n\tdefaultLuminance: string\n\t/**\n\t * The opacity of the background color of all text marker types.\n\t * @default '50%'\n\t */\n\tbackgroundOpacity: string\n\t/**\n\t * The LCH luminance to be used for the border color of all text marker types.\n\t * @default '48%'\n\t */\n\tborderLuminance: string\n\t/**\n\t * The opacity of the border color of all text marker types.\n\t * @default '81.6%'\n\t */\n\tborderOpacity: string\n\t/**\n\t * The LCH luminance to be used for the diff indicator (e.g. `+` or `-`).\n\t * @default\n\t * ['67%', '40%'] // 67% for dark themes, 40% for light themes\n\t */\n\tindicatorLuminance: string\n\t/**\n\t * The opacity of the diff indicator (e.g. `+` or `-`).\n\t * @default '81.6%'\n\t */\n\tindicatorOpacity: string\n\t/**\n\t * The content to be displayed inside the diff indicator of inserted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'+'\"\n\t */\n\tinsDiffIndicatorContent: string\n\t/**\n\t * The content to be displayed inside the diff indicator of deleted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'-'\"\n\t */\n\tdelDiffIndicatorContent: string\n\t/**\n\t * The background color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <markHue> / <backgroundOpacity>)\n\t */\n\tmarkBackground: string\n\t/**\n\t * The border color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <markHue> / <borderOpacity>)\n\t */\n\tmarkBorderColor: string\n\t/**\n\t * The background color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <insHue> / <backgroundOpacity>)\n\t */\n\tinsBackground: string\n\t/**\n\t * The border color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <insHue> / <borderOpacity>)\n\t */\n\tinsBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of inserted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <insHue> / <indicatorOpacity>)\n\t */\n\tinsDiffIndicatorColor: string\n\t/**\n\t * The background color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <delHue> / <backgroundOpacity>)\n\t */\n\tdelBackground: string\n\t/**\n\t * The border color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <delHue> / <borderOpacity>)\n\t */\n\tdelBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of deleted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <delHue> / <indicatorOpacity>)\n\t */\n\tdelDiffIndicatorColor: string\n}\n\ndeclare module '@expressive-code/core' {\n\texport interface StyleSettings {\n\t\ttextMarkers: TextMarkersStyleSettings\n\t}\n}\n\nexport const textMarkersStyleSettings = new PluginStyleSettings({\n\tdefaultValues: {\n\t\ttextMarkers: {\n\t\t\tlineMarkerAccentMargin: '0rem',\n\t\t\tlineMarkerAccentWidth: '0.15rem',\n\t\t\tlineDiffIndicatorMarginLeft: '0.5rem',\n\t\t\tinlineMarkerBorderWidth: '1.5px',\n\t\t\tinlineMarkerBorderRadius: '0.2rem',\n\t\t\tinlineMarkerPadding: '0.15rem',\n\t\t\t// Define base colors for all markers in the LCH color space,\n\t\t\t// which leads to consistent perceived brightness independent of hue\n\t\t\tmarkHue: '284',\n\t\t\tinsHue: '136',\n\t\t\tdelHue: '33',\n\t\t\tdefaultChroma: '40',\n\t\t\tdefaultLuminance: ['32%', '75%'],\n\t\t\tbackgroundOpacity: '50%',\n\t\t\tborderLuminance: '48%',\n\t\t\tborderOpacity: '81.6%',\n\t\t\tindicatorLuminance: ['67%', '40%'],\n\t\t\tindicatorOpacity: '81.6%',\n\t\t\t// You can use these to override the diff indicator content\n\t\t\tinsDiffIndicatorContent: \"'+'\",\n\t\t\tdelDiffIndicatorContent: \"'-'\",\n\t\t\t// The settings below will be calculated based on the settings above\n\t\t\tmarkBackground: (context) => resolveBg(context, 'textMarkers.markHue'),\n\t\t\tmarkBorderColor: (context) => resolveBorder(context, 'textMarkers.markHue'),\n\t\t\tinsBackground: (context) => resolveBg(context, 'textMarkers.insHue'),\n\t\t\tinsBorderColor: (context) => resolveBorder(context, 'textMarkers.insHue'),\n\t\t\tinsDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.insHue'),\n\t\t\tdelBackground: (context) => resolveBg(context, 'textMarkers.delHue'),\n\t\t\tdelBorderColor: (context) => resolveBorder(context, 'textMarkers.delHue'),\n\t\t\tdelDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.delHue'),\n\t\t},\n\t},\n\tcssVarExclusions: [\n\t\t// Exclude all settings from CSS variable output that will not be used directly in styles,\n\t\t// but instead be used to calculate other settings\n\t\t'textMarkers.markHue',\n\t\t'textMarkers.insHue',\n\t\t'textMarkers.delHue',\n\t\t'textMarkers.defaultChroma',\n\t\t'textMarkers.defaultLuminance',\n\t\t'textMarkers.backgroundOpacity',\n\t\t'textMarkers.borderLuminance',\n\t\t'textMarkers.borderOpacity',\n\t\t'textMarkers.indicatorLuminance',\n\t\t'textMarkers.indicatorOpacity',\n\t],\n})\n\nexport function getTextMarkersBaseStyles({ cssVar }: ResolverContext) {\n\tconst result = `\n\t\t.${codeLineClass} {\n\t\t\t/* Support line-level mark/ins/del */\n\t\t\t&.mark {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t&.ins {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.insDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.insDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.del {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.delDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.delDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.mark,\n\t\t\t&.ins,\n\t\t\t&.del {\n\t\t\t\tposition: relative;\n\t\t\t\tbackground: var(--tmLineBgCol);\n\t\t\t\tmin-width: calc(100% - ${cssVar('textMarkers.lineMarkerAccentMargin')});\n\t\t\t\tmargin-inline-start: ${cssVar('textMarkers.lineMarkerAccentMargin')};\n\t\t\t\tborder-inline-start: ${cssVar('textMarkers.lineMarkerAccentWidth')} solid var(--tmLineBrdCol);\n\t\t\t\tpadding-inline-start: calc(${cssVar('codePaddingInline')} - ${cssVar('textMarkers.lineMarkerAccentMargin')} - ${cssVar('textMarkers.lineMarkerAccentWidth')}) !important;\n\t\t\t\t&::before {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tleft: ${cssVar('textMarkers.lineDiffIndicatorMarginLeft')};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Support inline mark/ins/del */\n\t\t\t& mark {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t& ins {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t}\n\t\t\t& del {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t}\n\t\t\t& mark,\n\t\t\t& ins,\n\t\t\t& del {\n\t\t\t\tall: unset;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tposition: relative;\n\t\t\t\t--tmBrdL: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmBrdR: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmRadL: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\t--tmRadR: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\tmargin-inline: 0.025rem;\n\t\t\t\tpadding-inline: ${cssVar('textMarkers.inlineMarkerPadding')};\n\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\tbackground: var(--tmInlineBgCol);\n\t\t\t\tbackground-clip: padding-box;\n\n\t\t\t\t&.open-start {\n\t\t\t\t\tmargin-inline-start: 0;\n\t\t\t\t\tpadding-inline-start: 0;\n\t\t\t\t\t--tmBrdL: 0px;\n\t\t\t\t\t--tmRadL: 0;\n\t\t\t\t}\n\t\t\t\t&.open-end {\n\t\t\t\t\tmargin-inline-end: 0;\n\t\t\t\t\tpadding-inline-end: 0;\n\t\t\t\t\t--tmBrdR: 0px;\n\t\t\t\t\t--tmRadR: 0;\n\t\t\t\t}\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: '';\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tinset: 0;\n\t\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\t\tborder: ${cssVar('textMarkers.inlineMarkerBorderWidth')} solid var(--tmInlineBrdCol);\n\t\t\t\t\tborder-inline-width: var(--tmBrdL) var(--tmBrdR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`\n\n\treturn result\n}\n\nexport const markerBgColorPaths: { [K in MarkerType]: StyleSettingPath } = {\n\tmark: 'textMarkers.markBackground',\n\tins: 'textMarkers.insBackground',\n\tdel: 'textMarkers.delBackground',\n}\n\nfunction resolveBg({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.defaultLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.backgroundOpacity')})`)\n}\n\nfunction resolveBorder({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.borderLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.borderOpacity')})`)\n}\n\nfunction resolveIndicator({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.indicatorLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.indicatorOpacity')})`)\n}\n","import { getGroupIndicesFromRegExpMatch } from '@expressive-code/core'\nimport { MarkerType, MarkerTypeOrder } from './marker-types'\nimport { PluginTextMarkersData } from '.'\n\nexport type InlineMarkerRange = { markerType: MarkerType; start: number; end: number }\n\n/**\n * Goes through all search terms in the given block data and returns an array of\n * inline marker ranges that match the given line text.\n */\nexport function getInlineSearchTermMatches(lineText: string, blockData: PluginTextMarkersData) {\n\tconst markerMatches: InlineMarkerRange[] = []\n\n\t// Collect all plaintext term matches\n\tblockData.plaintextTerms.forEach(({ markerType, text }) => {\n\t\tlet idx = lineText.indexOf(text, 0)\n\t\twhile (idx > -1) {\n\t\t\tmarkerMatches.push({\n\t\t\t\tmarkerType,\n\t\t\t\tstart: idx,\n\t\t\t\tend: idx + text.length,\n\t\t\t})\n\t\t\tidx = lineText.indexOf(text, idx + text.length)\n\t\t}\n\t})\n\n\t// Collect all regular expression matches\n\tblockData.regExpTerms.forEach(({ markerType, regExp }) => {\n\t\tconst matches = lineText.matchAll(regExp)\n\t\tfor (const match of matches) {\n\t\t\tconst rawGroupIndices = getGroupIndicesFromRegExpMatch(match)\n\t\t\t// Remove null group indices\n\t\t\tlet groupIndices = rawGroupIndices.flatMap((range) => (range ? [range] : []))\n\t\t\t// If there are no non-null indices, use the full match instead\n\t\t\t// (capture group feature fallback, impossible to cover in tests)\n\t\t\t/* c8 ignore start */\n\t\t\tif (!groupIndices.length) {\n\t\t\t\tconst fullMatchIndex = match.index as number\n\t\t\t\tgroupIndices = [[fullMatchIndex, fullMatchIndex + match[0].length]]\n\t\t\t}\n\t\t\t/* c8 ignore end */\n\t\t\t// If there are multiple non-null indices, remove the first one\n\t\t\t// as it is the full match and we only want to mark capture groups\n\t\t\tif (groupIndices.length > 1) {\n\t\t\t\tgroupIndices.shift()\n\t\t\t}\n\t\t\t// Create marked ranges from all remaining group indices\n\t\t\tgroupIndices.forEach((range) => {\n\t\t\t\tmarkerMatches.push({\n\t\t\t\t\tmarkerType,\n\t\t\t\t\tstart: range[0],\n\t\t\t\t\tend: range[1],\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t})\n\n\treturn markerMatches\n}\n\n/**\n * Takes an array of inline marker ranges and returns a new array without overlapping ranges,\n * either by merging them into a combined range (if their marker types are the same),\n * or by overriding lower-priority markers with higher-priority ones (if their types differ).\n */\nexport function flattenInlineMarkerRanges(markerRanges: InlineMarkerRange[]): InlineMarkerRange[] {\n\tconst flattenedRanges: InlineMarkerRange[] = []\n\tconst addRange = (newRange: InlineMarkerRange) => {\n\t\tfor (let idx = flattenedRanges.length - 1; idx >= 0; idx--) {\n\t\t\tconst curRange = flattenedRanges[idx]\n\t\t\t// No overlap: The new range ends before the current one starts,\n\t\t\t// or it starts after the current one ends\n\t\t\tif (newRange.end <= curRange.start || newRange.start >= curRange.end) continue\n\n\t\t\t// Full overlap: The new range fully covers the current one\n\t\t\tif (newRange.start <= curRange.start && newRange.end >= curRange.end) {\n\t\t\t\t// Remove current range\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Partial overlap with same marker type\n\t\t\tif (newRange.markerType === curRange.markerType) {\n\t\t\t\t// Remove current range and extend the new one to cover it\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tnewRange = {\n\t\t\t\t\t...newRange,\n\t\t\t\t\tstart: Math.min(newRange.start, curRange.start),\n\t\t\t\t\tend: Math.max(newRange.end, curRange.end),\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range leaves both the start and the end of the current range\n\t\t\t// uncovered, we need to split the current range into two parts\n\t\t\tif (newRange.start > curRange.start && newRange.end < curRange.end) {\n\t\t\t\t// Replace the current range with two partial ranges\n\t\t\t\tflattenedRanges.splice(idx, 1, { ...curRange, end: newRange.start }, { ...curRange, start: newRange.end })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range starts after the current one starts, shorten the current range\n\t\t\tif (newRange.start > curRange.start) {\n\t\t\t\tcurRange.end = newRange.start\n\t\t\t}\n\n\t\t\t// If the new range ends before the current one ends, shorten the current range\n\t\t\tif (newRange.end < curRange.end) {\n\t\t\t\tcurRange.start = newRange.end\n\t\t\t}\n\t\t}\n\t\t// Finally add the new range to the flattened ranges and sort them by start position\n\t\tflattenedRanges.push(newRange)\n\t\tflattenedRanges.sort((a, b) => a.start - b.start)\n\t}\n\n\tMarkerTypeOrder.forEach((markerType) => {\n\t\tmarkerRanges.filter((range) => range.markerType === markerType).forEach(addRange)\n\t})\n\n\treturn flattenedRanges\n}\n","import { addClassName, ExpressiveCodeAnnotation, AnnotationBaseOptions, AnnotationRenderOptions } from '@expressive-code/core'\nimport { h } from 'hastscript'\nimport { Element } from 'hast-util-select/lib/types'\nimport { MarkerType } from './marker-types'\n\nexport class TextMarkerAnnotation extends ExpressiveCodeAnnotation {\n\tmarkerType: MarkerType\n\tbackgroundColor: string\n\n\tconstructor({ markerType, backgroundColor, ...baseOptions }: { markerType: MarkerType; backgroundColor: string } & AnnotationBaseOptions) {\n\t\tsuper(baseOptions)\n\t\tthis.markerType = markerType\n\t\tthis.backgroundColor = backgroundColor\n\t}\n\n\trender(options: AnnotationRenderOptions) {\n\t\tif (!this.inlineRange) return this.renderFullLineMarker(options)\n\t\treturn this.renderInlineMarker(options)\n\t}\n\n\tprivate renderFullLineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node) => {\n\t\t\taddClassName(node as Element, this.markerType)\n\t\t\treturn node\n\t\t})\n\t}\n\n\tprivate renderInlineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node, idx) => {\n\t\t\tconst transformedNode = h(this.markerType, node)\n\n\t\t\tif (nodesToTransform.length > 0 && idx > 0) {\n\t\t\t\taddClassName(transformedNode, 'open-start')\n\t\t\t}\n\t\t\tif (nodesToTransform.length > 0 && idx < nodesToTransform.length - 1) {\n\t\t\t\taddClassName(transformedNode, 'open-end')\n\t\t\t}\n\t\t\treturn transformedNode\n\t\t})\n\t}\n}\n"],"mappings":"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","names":["module","str","import_core","import_core","import_core","rangeParser"]} |
+4
-3
@@ -495,4 +495,4 @@ var __create = Object.create; | ||
| const textColors = annotations.filter( | ||
| (annotation) => annotation instanceof InlineStyleAnnotation && // Only consider annotations for the current style variant | ||
| annotation.styleVariantIndex === styleVariantIndex && annotation.color | ||
| (annotation) => annotation instanceof InlineStyleAnnotation && annotation.color && // Only consider annotations that apply to the current style variant | ||
| (annotation.styleVariantIndex === void 0 || annotation.styleVariantIndex === styleVariantIndex) | ||
| ); | ||
@@ -522,3 +522,4 @@ textColors.forEach((textColor) => { | ||
| }, | ||
| color: readableTextColor | ||
| color: readableTextColor, | ||
| renderPhase: "earlier" | ||
| }) | ||
@@ -525,0 +526,0 @@ ); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../../../node_modules/.pnpm/parse-numeric-range@1.3.0/node_modules/parse-numeric-range/index.js","../src/index.ts","../src/marker-types.ts","../src/styles.ts","../src/inline-markers.ts","../src/annotations.ts"],"sourcesContent":["/**\n * @param {string} string The string to parse\n * @returns {Array<number>} Returns an energetic array.\n */\nfunction parsePart(string) {\n let res = [];\n let m;\n\n for (let str of string.split(\",\").map((str) => str.trim())) {\n // just a number\n if (/^-?\\d+$/.test(str)) {\n res.push(parseInt(str, 10));\n } else if (\n (m = str.match(/^(-?\\d+)(-|\\.\\.\\.?|\\u2025|\\u2026|\\u22EF)(-?\\d+)$/))\n ) {\n // 1-5 or 1..5 (equivalent) or 1...5 (doesn't include 5)\n let [_, lhs, sep, rhs] = m;\n\n if (lhs && rhs) {\n lhs = parseInt(lhs);\n rhs = parseInt(rhs);\n const incr = lhs < rhs ? 1 : -1;\n\n // Make it inclusive by moving the right 'stop-point' away by one.\n if (sep === \"-\" || sep === \"..\" || sep === \"\\u2025\") rhs += incr;\n\n for (let i = lhs; i !== rhs; i += incr) res.push(i);\n }\n }\n }\n\n return res;\n}\n\nexports.default = parsePart;\nmodule.exports = parsePart;\n","import {\n\tAnnotationRenderPhaseOrder,\n\tAttachedPluginData,\n\tExpressiveCodePlugin,\n\tInlineStyleAnnotation,\n\tensureColorContrastOnBackground,\n\tonBackground,\n\treplaceDelimitedValues,\n} from '@expressive-code/core'\nimport rangeParser from 'parse-numeric-range'\nimport { MarkerType, MarkerTypeOrder, markerTypeFromString } from './marker-types'\nimport { getTextMarkersBaseStyles, markerBgColorPaths, textMarkersStyleSettings } from './styles'\nimport { flattenInlineMarkerRanges, getInlineSearchTermMatches } from './inline-markers'\nimport { TextMarkerAnnotation } from './annotations'\nexport { TextMarkersStyleSettings } from './styles'\n\nexport function pluginTextMarkers(): ExpressiveCodePlugin {\n\treturn {\n\t\tname: 'TextMarkers',\n\t\tstyleSettings: textMarkersStyleSettings,\n\t\tbaseStyles: (context) => getTextMarkersBaseStyles(context),\n\t\thooks: {\n\t\t\tpreprocessMetadata: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.meta = replaceDelimitedValues(\n\t\t\t\t\tcodeBlock.meta,\n\t\t\t\t\t({ fullMatch, key, value, valueStartDelimiter }) => {\n\t\t\t\t\t\t// If we found a \"lang\" key and the code block's language is \"diff\",\n\t\t\t\t\t\t// use the \"lang\" value as the new syntax highlighting language instead\n\t\t\t\t\t\tif (key === 'lang' && codeBlock.language === 'diff') {\n\t\t\t\t\t\t\tcodeBlock.language = value\n\t\t\t\t\t\t\tblockData.originalLanguage = 'diff'\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Try to identify the marker type from the key\n\t\t\t\t\t\tconst markerType = markerTypeFromString(key || 'mark')\n\n\t\t\t\t\t\t// If an unknown key was encountered, leave this meta string part untouched\n\t\t\t\t\t\tif (!markerType) return fullMatch\n\n\t\t\t\t\t\t// Handle full-line highlighting definitions\n\t\t\t\t\t\tif (valueStartDelimiter === '{') {\n\t\t\t\t\t\t\tconst lineNumbers = rangeParser(value)\n\t\t\t\t\t\t\tlineNumbers.forEach((lineNumber) => {\n\t\t\t\t\t\t\t\tconst lineIndex = lineNumber - 1\n\t\t\t\t\t\t\t\tcodeBlock.getLine(lineIndex)?.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle regular expression search terms\n\t\t\t\t\t\tif (valueStartDelimiter === '/') {\n\t\t\t\t\t\t\t// Remember the term for highlighting in a later hook\n\t\t\t\t\t\t\tlet regExp: RegExp | undefined\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Try to use regular expressions with capture group indices\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'gd')\n\t\t\t\t\t\t\t\t/* c8 ignore start */\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t// Use fallback if unsupported\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'g')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/* c8 ignore stop */\n\t\t\t\t\t\t\tblockData.regExpTerms.push({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tregExp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Treat everything else as a plaintext search term and\n\t\t\t\t\t\t// remember it for highlighting in a later hook\n\t\t\t\t\t\tblockData.plaintextTerms.push({\n\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalueDelimiters: ['\"', \"'\", '/', '{...}'],\n\t\t\t\t\t\tkeyValueSeparator: '=',\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t},\n\t\t\tpreprocessCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\t// Perform special handling of code marked with the language \"diff\":\n\t\t\t\t// - This language is often used as a widely supported format for highlighting\n\t\t\t\t// changes to code. In this case, the code is not actually a diff,\n\t\t\t\t// but another language with some lines prefixed by `+` or `-`.\n\t\t\t\t// - We try to detect this case and convert the prefixed lines to annotations\n\t\t\t\t// - To prevent modifying actual diff files (which would make them invalid),\n\t\t\t\t// we ensure that the code does not begin like a real diff:\n\t\t\t\t// - The first lines must not start with `*** `, `+++ `, `--- `, `@@ `,\n\t\t\t\t// or the default mode location syntax (e.g. `0a1`, `1,2c1,2`, `1,2d1`).\n\t\t\t\tif ((blockData.originalLanguage ?? codeBlock.language) === 'diff') {\n\t\t\t\t\tconst lines = codeBlock.getLines()\n\n\t\t\t\t\t// Ensure that the first lines do not look like actual diff output\n\t\t\t\t\tconst couldBeRealDiffFile = lines.slice(0, 4).some((line) => line.text.match(/^([*+-]{3}\\s|@@\\s|[0-9,]+[acd][0-9,]+\\s*$)/))\n\t\t\t\t\tif (!couldBeRealDiffFile) {\n\t\t\t\t\t\tlet minIndentation = Infinity\n\t\t\t\t\t\tconst parsedLines = lines.map((line) => {\n\t\t\t\t\t\t\tconst [, indentation, marker, content] = line.text.match(/^(([+-](?![+-]))?\\s*)(.*)$/) || []\n\t\t\t\t\t\t\tconst markerType: MarkerType | undefined = marker === '+' ? 'ins' : marker === '-' ? 'del' : undefined\n\n\t\t\t\t\t\t\t// As it's common to indent unchanged lines to match the indentation\n\t\t\t\t\t\t\t// of changed lines, and we don't want extra whitespace in the output,\n\t\t\t\t\t\t\t// we remember the minimum indentation of all non-empty lines\n\t\t\t\t\t\t\tif (content.trim().length > 0 && indentation.length < minIndentation) minIndentation = indentation.length\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tparsedLines.forEach(({ line, markerType }) => {\n\t\t\t\t\t\t\t// Remove line prefixes:\n\t\t\t\t\t\t\t// - If minIndentation is > 0, we remove minIndentation\n\t\t\t\t\t\t\t// - Otherwise, if the current line starts with a marker character,\n\t\t\t\t\t\t\t// we remove this single character\n\t\t\t\t\t\t\tconst colsToRemove = minIndentation || (markerType ? 1 : 0)\n\t\t\t\t\t\t\tif (colsToRemove > 0) line.editText(0, colsToRemove, '')\n\n\t\t\t\t\t\t\t// If we found a diff marker, add a line annotation\n\t\t\t\t\t\t\tif (markerType) {\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tannotateCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\t// Check the line text for search term matches and collect their ranges\n\t\t\t\t\tconst markerRanges = getInlineSearchTermMatches(line.text, blockData)\n\t\t\t\t\tif (!markerRanges.length) return\n\n\t\t\t\t\t// Flatten marked ranges to prevent any overlaps\n\t\t\t\t\tconst flattenedRanges = flattenInlineMarkerRanges(markerRanges)\n\n\t\t\t\t\t// Add annotations for all flattened ranges\n\t\t\t\t\tflattenedRanges.forEach(({ markerType, start, end }) => {\n\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\tcolumnStart: start,\n\t\t\t\t\t\t\t\t\tcolumnEnd: end,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t\tpostprocessAnnotations: ({ codeBlock, styleVariants, config }) => {\n\t\t\t\tif (config.minSyntaxHighlightingColorContrast <= 0) return\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\tconst annotations = line.getAnnotations()\n\t\t\t\t\t// Determine the highest-priority full line marker\n\t\t\t\t\t// and collect all inline markers\n\t\t\t\t\tconst markers: TextMarkerAnnotation[] = []\n\t\t\t\t\tlet fullLineMarker: TextMarkerAnnotation | undefined = undefined\n\t\t\t\t\tfor (const annotation of annotations) {\n\t\t\t\t\t\tif (!(annotation instanceof TextMarkerAnnotation)) continue\n\t\t\t\t\t\tif (annotation.inlineRange) {\n\t\t\t\t\t\t\tmarkers.push(annotation)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fullLineMarker) {\n\t\t\t\t\t\t\tif (MarkerTypeOrder.indexOf(annotation.markerType) < MarkerTypeOrder.indexOf(fullLineMarker.markerType)) continue\n\t\t\t\t\t\t\tif (AnnotationRenderPhaseOrder.indexOf(annotation.renderPhase) < AnnotationRenderPhaseOrder.indexOf(fullLineMarker.renderPhase)) continue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfullLineMarker = annotation\n\t\t\t\t\t}\n\t\t\t\t\t// Prepend the highest-priority full line marker to the inline markers\n\t\t\t\t\tif (fullLineMarker) markers.unshift(fullLineMarker)\n\t\t\t\t\t// Ensure color contrast for all style variants\n\t\t\t\t\tstyleVariants.forEach((styleVariant, styleVariantIndex) => {\n\t\t\t\t\t\tconst fullLineMarkerBgColor = (fullLineMarker && styleVariant.resolvedStyleSettings.get(markerBgColorPaths[fullLineMarker.markerType])) || 'transparent'\n\t\t\t\t\t\tconst lineBgColor = onBackground(fullLineMarkerBgColor, styleVariant.resolvedStyleSettings.get('codeBackground') || styleVariant.theme.bg)\n\t\t\t\t\t\t// Collect inline style annotations that change the text color\n\t\t\t\t\t\tconst textColors = annotations.filter(\n\t\t\t\t\t\t\t(annotation) =>\n\t\t\t\t\t\t\t\tannotation instanceof InlineStyleAnnotation &&\n\t\t\t\t\t\t\t\t// Only consider annotations for the current style variant\n\t\t\t\t\t\t\t\tannotation.styleVariantIndex === styleVariantIndex &&\n\t\t\t\t\t\t\t\tannotation.color\n\t\t\t\t\t\t) as InlineStyleAnnotation[]\n\t\t\t\t\t\t// Go through all text color annotations\n\t\t\t\t\t\ttextColors.forEach((textColor) => {\n\t\t\t\t\t\t\tconst textFgColor = textColor.color\n\t\t\t\t\t\t\tconst textStart = textColor.inlineRange?.columnStart\n\t\t\t\t\t\t\tconst textEnd = textColor.inlineRange?.columnEnd\n\t\t\t\t\t\t\tif (textFgColor === undefined || textStart === undefined || textEnd === undefined) return\n\t\t\t\t\t\t\t// Go through all markers\n\t\t\t\t\t\t\tmarkers.forEach((marker) => {\n\t\t\t\t\t\t\t\tconst markerStart = marker.inlineRange?.columnStart ?? 0\n\t\t\t\t\t\t\t\tconst markerEnd = marker.inlineRange?.columnEnd ?? line.text.length\n\t\t\t\t\t\t\t\tif (markerStart > textEnd || markerEnd < textStart) return\n\t\t\t\t\t\t\t\t// As the marker overlaps with the text color annotation,\n\t\t\t\t\t\t\t\t// determine the combined background color of this range\n\t\t\t\t\t\t\t\tconst markerBgColor = styleVariant.resolvedStyleSettings.get(markerBgColorPaths[marker.markerType]) ?? ''\n\t\t\t\t\t\t\t\tconst combinedBgColor = onBackground(markerBgColor, lineBgColor)\n\t\t\t\t\t\t\t\t// Now ensure a good contrast ratio of the text\n\t\t\t\t\t\t\t\tconst readableTextColor = ensureColorContrastOnBackground(textFgColor, combinedBgColor, config.minSyntaxHighlightingColorContrast)\n\t\t\t\t\t\t\t\tif (readableTextColor.toLowerCase() === textFgColor.toLowerCase()) return\n\t\t\t\t\t\t\t\t// If the text color is not readable enough, add an annotation\n\t\t\t\t\t\t\t\t// with better contrast for the overlapping range\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew InlineStyleAnnotation({\n\t\t\t\t\t\t\t\t\t\tstyleVariantIndex,\n\t\t\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\t\t\tcolumnStart: Math.max(textStart, markerStart),\n\t\t\t\t\t\t\t\t\t\t\tcolumnEnd: Math.min(textEnd, markerEnd),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tcolor: readableTextColor,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface PluginTextMarkersData {\n\tplaintextTerms: { markerType: MarkerType; text: string }[]\n\tregExpTerms: { markerType: MarkerType; regExp: RegExp }[]\n\toriginalLanguage?: string | undefined\n}\n\nexport const pluginTextMarkersData = new AttachedPluginData<PluginTextMarkersData>(() => ({ plaintextTerms: [], regExpTerms: [] }))\n","export type MarkerType = 'mark' | 'ins' | 'del'\n\n/** When markers overlap, those with higher indices override lower ones. */\nexport const MarkerTypeOrder: MarkerType[] = ['mark', 'del', 'ins']\n\n/**\n * If the given input string represents a valid marker type,\n * converts it to a {@link MarkerType} and returns it.\n *\n * Otherwise, returns `undefined`.\n */\nexport function markerTypeFromString(input: string) {\n\t// Fix common marker type mistakes\n\tif (input === 'add') input = 'ins'\n\tif (input === 'rem') input = 'del'\n\n\t// Return either the converted type or undefined\n\tconst markerType = input as MarkerType\n\treturn MarkerTypeOrder.includes(markerType) ? markerType : undefined\n}\n","import { PluginStyleSettings, codeLineClass, toHexColor, StyleSettingPath, ResolverContext, StyleResolverFn } from '@expressive-code/core'\nimport { MarkerType } from './marker-types'\n\nexport interface TextMarkersStyleSettings {\n\t/**\n\t * The margin between the code block border and the line marker accent bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0rem'\n\t */\n\tlineMarkerAccentMargin: string\n\t/**\n\t * The width of the line marker accent bar. This is the vertical border-like bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.15rem'\n\t */\n\tlineMarkerAccentWidth: string\n\t/**\n\t * The margin between the code block border and the diff indicator (e.g. `+` or `-`)\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.5rem'\n\t */\n\tlineDiffIndicatorMarginLeft: string\n\t/**\n\t * The width of the border around inline text markers, rendered in a way\n\t * that does not cause marked code to shift.\n\t * @default '1.5px'\n\t */\n\tinlineMarkerBorderWidth: string\n\t/**\n\t * The border radius of inline text markers.\n\t * @default '0.2rem'\n\t */\n\tinlineMarkerBorderRadius: string\n\t/**\n\t * The inline padding of inline text markers. Keep this low to prevent marked code\n\t * from shifting too much compared to the original text.\n\t * @default '0.15rem'\n\t */\n\tinlineMarkerPadding: string\n\t/**\n\t * The LCH hue to be used for marked text (text marker type `mark`).\n\t * @default '284' (a blue hue)\n\t */\n\tmarkHue: string\n\t/**\n\t * The LCH hue to be used for inserted text (text marker type `ins`).\n\t * @default '136' (a green hue)\n\t */\n\tinsHue: string\n\t/**\n\t * The LCH hue to be used for deleted text (text marker type `del`).\n\t * @default '33' (a red hue)\n\t */\n\tdelHue: string\n\t/**\n\t * The LCH chroma to be used for all text marker types.\n\t *\n\t * The chroma value defines the saturation of the color. Higher values lead to\n\t * more saturated colors, lower values lead to less saturated colors.\n\t *\n\t * @default '40'\n\t */\n\tdefaultChroma: string\n\t/**\n\t * The LCH luminance to be used for all text marker types.\n\t * @default\n\t * ['32%', '75%'] // 32% for dark themes, 75% for light themes\n\t */\n\tdefaultLuminance: string\n\t/**\n\t * The opacity of the background color of all text marker types.\n\t * @default '50%'\n\t */\n\tbackgroundOpacity: string\n\t/**\n\t * The LCH luminance to be used for the border color of all text marker types.\n\t * @default '48%'\n\t */\n\tborderLuminance: string\n\t/**\n\t * The opacity of the border color of all text marker types.\n\t * @default '81.6%'\n\t */\n\tborderOpacity: string\n\t/**\n\t * The LCH luminance to be used for the diff indicator (e.g. `+` or `-`).\n\t * @default\n\t * ['67%', '40%'] // 67% for dark themes, 40% for light themes\n\t */\n\tindicatorLuminance: string\n\t/**\n\t * The opacity of the diff indicator (e.g. `+` or `-`).\n\t * @default '81.6%'\n\t */\n\tindicatorOpacity: string\n\t/**\n\t * The content to be displayed inside the diff indicator of inserted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'+'\"\n\t */\n\tinsDiffIndicatorContent: string\n\t/**\n\t * The content to be displayed inside the diff indicator of deleted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'-'\"\n\t */\n\tdelDiffIndicatorContent: string\n\t/**\n\t * The background color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <markHue> / <backgroundOpacity>)\n\t */\n\tmarkBackground: string\n\t/**\n\t * The border color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <markHue> / <borderOpacity>)\n\t */\n\tmarkBorderColor: string\n\t/**\n\t * The background color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <insHue> / <backgroundOpacity>)\n\t */\n\tinsBackground: string\n\t/**\n\t * The border color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <insHue> / <borderOpacity>)\n\t */\n\tinsBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of inserted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <insHue> / <indicatorOpacity>)\n\t */\n\tinsDiffIndicatorColor: string\n\t/**\n\t * The background color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <delHue> / <backgroundOpacity>)\n\t */\n\tdelBackground: string\n\t/**\n\t * The border color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <delHue> / <borderOpacity>)\n\t */\n\tdelBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of deleted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <delHue> / <indicatorOpacity>)\n\t */\n\tdelDiffIndicatorColor: string\n}\n\ndeclare module '@expressive-code/core' {\n\texport interface StyleSettings {\n\t\ttextMarkers: TextMarkersStyleSettings\n\t}\n}\n\nexport const textMarkersStyleSettings = new PluginStyleSettings({\n\tdefaultValues: {\n\t\ttextMarkers: {\n\t\t\tlineMarkerAccentMargin: '0rem',\n\t\t\tlineMarkerAccentWidth: '0.15rem',\n\t\t\tlineDiffIndicatorMarginLeft: '0.5rem',\n\t\t\tinlineMarkerBorderWidth: '1.5px',\n\t\t\tinlineMarkerBorderRadius: '0.2rem',\n\t\t\tinlineMarkerPadding: '0.15rem',\n\t\t\t// Define base colors for all markers in the LCH color space,\n\t\t\t// which leads to consistent perceived brightness independent of hue\n\t\t\tmarkHue: '284',\n\t\t\tinsHue: '136',\n\t\t\tdelHue: '33',\n\t\t\tdefaultChroma: '40',\n\t\t\tdefaultLuminance: ['32%', '75%'],\n\t\t\tbackgroundOpacity: '50%',\n\t\t\tborderLuminance: '48%',\n\t\t\tborderOpacity: '81.6%',\n\t\t\tindicatorLuminance: ['67%', '40%'],\n\t\t\tindicatorOpacity: '81.6%',\n\t\t\t// You can use these to override the diff indicator content\n\t\t\tinsDiffIndicatorContent: \"'+'\",\n\t\t\tdelDiffIndicatorContent: \"'-'\",\n\t\t\t// The settings below will be calculated based on the settings above\n\t\t\tmarkBackground: (context) => resolveBg(context, 'textMarkers.markHue'),\n\t\t\tmarkBorderColor: (context) => resolveBorder(context, 'textMarkers.markHue'),\n\t\t\tinsBackground: (context) => resolveBg(context, 'textMarkers.insHue'),\n\t\t\tinsBorderColor: (context) => resolveBorder(context, 'textMarkers.insHue'),\n\t\t\tinsDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.insHue'),\n\t\t\tdelBackground: (context) => resolveBg(context, 'textMarkers.delHue'),\n\t\t\tdelBorderColor: (context) => resolveBorder(context, 'textMarkers.delHue'),\n\t\t\tdelDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.delHue'),\n\t\t},\n\t},\n\tcssVarExclusions: [\n\t\t// Exclude all settings from CSS variable output that will not be used directly in styles,\n\t\t// but instead be used to calculate other settings\n\t\t'textMarkers.markHue',\n\t\t'textMarkers.insHue',\n\t\t'textMarkers.delHue',\n\t\t'textMarkers.defaultChroma',\n\t\t'textMarkers.defaultLuminance',\n\t\t'textMarkers.backgroundOpacity',\n\t\t'textMarkers.borderLuminance',\n\t\t'textMarkers.borderOpacity',\n\t\t'textMarkers.indicatorLuminance',\n\t\t'textMarkers.indicatorOpacity',\n\t],\n})\n\nexport function getTextMarkersBaseStyles({ cssVar }: ResolverContext) {\n\tconst result = `\n\t\t.${codeLineClass} {\n\t\t\t/* Support line-level mark/ins/del */\n\t\t\t&.mark {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t&.ins {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.insDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.insDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.del {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.delDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.delDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.mark,\n\t\t\t&.ins,\n\t\t\t&.del {\n\t\t\t\tposition: relative;\n\t\t\t\tbackground: var(--tmLineBgCol);\n\t\t\t\tmin-width: calc(100% - ${cssVar('textMarkers.lineMarkerAccentMargin')});\n\t\t\t\tmargin-inline-start: ${cssVar('textMarkers.lineMarkerAccentMargin')};\n\t\t\t\tborder-inline-start: ${cssVar('textMarkers.lineMarkerAccentWidth')} solid var(--tmLineBrdCol);\n\t\t\t\tpadding-inline-start: calc(${cssVar('codePaddingInline')} - ${cssVar('textMarkers.lineMarkerAccentMargin')} - ${cssVar('textMarkers.lineMarkerAccentWidth')}) !important;\n\t\t\t\t&::before {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tleft: ${cssVar('textMarkers.lineDiffIndicatorMarginLeft')};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Support inline mark/ins/del */\n\t\t\t& mark {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t& ins {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t}\n\t\t\t& del {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t}\n\t\t\t& mark,\n\t\t\t& ins,\n\t\t\t& del {\n\t\t\t\tall: unset;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tposition: relative;\n\t\t\t\t--tmBrdL: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmBrdR: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmRadL: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\t--tmRadR: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\tmargin-inline: 0.025rem;\n\t\t\t\tpadding-inline: ${cssVar('textMarkers.inlineMarkerPadding')};\n\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\tbackground: var(--tmInlineBgCol);\n\t\t\t\tbackground-clip: padding-box;\n\n\t\t\t\t&.open-start {\n\t\t\t\t\tmargin-inline-start: 0;\n\t\t\t\t\tpadding-inline-start: 0;\n\t\t\t\t\t--tmBrdL: 0px;\n\t\t\t\t\t--tmRadL: 0;\n\t\t\t\t}\n\t\t\t\t&.open-end {\n\t\t\t\t\tmargin-inline-end: 0;\n\t\t\t\t\tpadding-inline-end: 0;\n\t\t\t\t\t--tmBrdR: 0px;\n\t\t\t\t\t--tmRadR: 0;\n\t\t\t\t}\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: '';\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tinset: 0;\n\t\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\t\tborder: ${cssVar('textMarkers.inlineMarkerBorderWidth')} solid var(--tmInlineBrdCol);\n\t\t\t\t\tborder-inline-width: var(--tmBrdL) var(--tmBrdR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`\n\n\treturn result\n}\n\nexport const markerBgColorPaths: { [K in MarkerType]: StyleSettingPath } = {\n\tmark: 'textMarkers.markBackground',\n\tins: 'textMarkers.insBackground',\n\tdel: 'textMarkers.delBackground',\n}\n\nfunction resolveBg({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.defaultLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.backgroundOpacity')})`)\n}\n\nfunction resolveBorder({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.borderLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.borderOpacity')})`)\n}\n\nfunction resolveIndicator({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.indicatorLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.indicatorOpacity')})`)\n}\n","import { getGroupIndicesFromRegExpMatch } from '@expressive-code/core'\nimport { MarkerType, MarkerTypeOrder } from './marker-types'\nimport { PluginTextMarkersData } from '.'\n\nexport type InlineMarkerRange = { markerType: MarkerType; start: number; end: number }\n\n/**\n * Goes through all search terms in the given block data and returns an array of\n * inline marker ranges that match the given line text.\n */\nexport function getInlineSearchTermMatches(lineText: string, blockData: PluginTextMarkersData) {\n\tconst markerMatches: InlineMarkerRange[] = []\n\n\t// Collect all plaintext term matches\n\tblockData.plaintextTerms.forEach(({ markerType, text }) => {\n\t\tlet idx = lineText.indexOf(text, 0)\n\t\twhile (idx > -1) {\n\t\t\tmarkerMatches.push({\n\t\t\t\tmarkerType,\n\t\t\t\tstart: idx,\n\t\t\t\tend: idx + text.length,\n\t\t\t})\n\t\t\tidx = lineText.indexOf(text, idx + text.length)\n\t\t}\n\t})\n\n\t// Collect all regular expression matches\n\tblockData.regExpTerms.forEach(({ markerType, regExp }) => {\n\t\tconst matches = lineText.matchAll(regExp)\n\t\tfor (const match of matches) {\n\t\t\tconst rawGroupIndices = getGroupIndicesFromRegExpMatch(match)\n\t\t\t// Remove null group indices\n\t\t\tlet groupIndices = rawGroupIndices.flatMap((range) => (range ? [range] : []))\n\t\t\t// If there are no non-null indices, use the full match instead\n\t\t\t// (capture group feature fallback, impossible to cover in tests)\n\t\t\t/* c8 ignore start */\n\t\t\tif (!groupIndices.length) {\n\t\t\t\tconst fullMatchIndex = match.index as number\n\t\t\t\tgroupIndices = [[fullMatchIndex, fullMatchIndex + match[0].length]]\n\t\t\t}\n\t\t\t/* c8 ignore end */\n\t\t\t// If there are multiple non-null indices, remove the first one\n\t\t\t// as it is the full match and we only want to mark capture groups\n\t\t\tif (groupIndices.length > 1) {\n\t\t\t\tgroupIndices.shift()\n\t\t\t}\n\t\t\t// Create marked ranges from all remaining group indices\n\t\t\tgroupIndices.forEach((range) => {\n\t\t\t\tmarkerMatches.push({\n\t\t\t\t\tmarkerType,\n\t\t\t\t\tstart: range[0],\n\t\t\t\t\tend: range[1],\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t})\n\n\treturn markerMatches\n}\n\n/**\n * Takes an array of inline marker ranges and returns a new array without overlapping ranges,\n * either by merging them into a combined range (if their marker types are the same),\n * or by overriding lower-priority markers with higher-priority ones (if their types differ).\n */\nexport function flattenInlineMarkerRanges(markerRanges: InlineMarkerRange[]): InlineMarkerRange[] {\n\tconst flattenedRanges: InlineMarkerRange[] = []\n\tconst addRange = (newRange: InlineMarkerRange) => {\n\t\tfor (let idx = flattenedRanges.length - 1; idx >= 0; idx--) {\n\t\t\tconst curRange = flattenedRanges[idx]\n\t\t\t// No overlap: The new range ends before the current one starts,\n\t\t\t// or it starts after the current one ends\n\t\t\tif (newRange.end <= curRange.start || newRange.start >= curRange.end) continue\n\n\t\t\t// Full overlap: The new range fully covers the current one\n\t\t\tif (newRange.start <= curRange.start && newRange.end >= curRange.end) {\n\t\t\t\t// Remove current range\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Partial overlap with same marker type\n\t\t\tif (newRange.markerType === curRange.markerType) {\n\t\t\t\t// Remove current range and extend the new one to cover it\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tnewRange = {\n\t\t\t\t\t...newRange,\n\t\t\t\t\tstart: Math.min(newRange.start, curRange.start),\n\t\t\t\t\tend: Math.max(newRange.end, curRange.end),\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range leaves both the start and the end of the current range\n\t\t\t// uncovered, we need to split the current range into two parts\n\t\t\tif (newRange.start > curRange.start && newRange.end < curRange.end) {\n\t\t\t\t// Replace the current range with two partial ranges\n\t\t\t\tflattenedRanges.splice(idx, 1, { ...curRange, end: newRange.start }, { ...curRange, start: newRange.end })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range starts after the current one starts, shorten the current range\n\t\t\tif (newRange.start > curRange.start) {\n\t\t\t\tcurRange.end = newRange.start\n\t\t\t}\n\n\t\t\t// If the new range ends before the current one ends, shorten the current range\n\t\t\tif (newRange.end < curRange.end) {\n\t\t\t\tcurRange.start = newRange.end\n\t\t\t}\n\t\t}\n\t\t// Finally add the new range to the flattened ranges and sort them by start position\n\t\tflattenedRanges.push(newRange)\n\t\tflattenedRanges.sort((a, b) => a.start - b.start)\n\t}\n\n\tMarkerTypeOrder.forEach((markerType) => {\n\t\tmarkerRanges.filter((range) => range.markerType === markerType).forEach(addRange)\n\t})\n\n\treturn flattenedRanges\n}\n","import { addClassName, ExpressiveCodeAnnotation, AnnotationBaseOptions, AnnotationRenderOptions } from '@expressive-code/core'\nimport { h } from 'hastscript'\nimport { Element } from 'hast-util-select/lib/types'\nimport { MarkerType } from './marker-types'\n\nexport class TextMarkerAnnotation extends ExpressiveCodeAnnotation {\n\tmarkerType: MarkerType\n\tbackgroundColor: string\n\n\tconstructor({ markerType, backgroundColor, ...baseOptions }: { markerType: MarkerType; backgroundColor: string } & AnnotationBaseOptions) {\n\t\tsuper(baseOptions)\n\t\tthis.markerType = markerType\n\t\tthis.backgroundColor = backgroundColor\n\t}\n\n\trender(options: AnnotationRenderOptions) {\n\t\tif (!this.inlineRange) return this.renderFullLineMarker(options)\n\t\treturn this.renderInlineMarker(options)\n\t}\n\n\tprivate renderFullLineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node) => {\n\t\t\taddClassName(node as Element, this.markerType)\n\t\t\treturn node\n\t\t})\n\t}\n\n\tprivate renderInlineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node, idx) => {\n\t\t\tconst transformedNode = h(this.markerType, node)\n\n\t\t\tif (nodesToTransform.length > 0 && idx > 0) {\n\t\t\t\taddClassName(transformedNode, 'open-start')\n\t\t\t}\n\t\t\tif (nodesToTransform.length > 0 && idx < nodesToTransform.length - 1) {\n\t\t\t\taddClassName(transformedNode, 'open-end')\n\t\t\t}\n\t\t\treturn transformedNode\n\t\t})\n\t}\n}\n"],"mappings":"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","names":["str","rangeParser"]} | ||
| {"version":3,"sources":["../../../../node_modules/.pnpm/parse-numeric-range@1.3.0/node_modules/parse-numeric-range/index.js","../src/index.ts","../src/marker-types.ts","../src/styles.ts","../src/inline-markers.ts","../src/annotations.ts"],"sourcesContent":["/**\n * @param {string} string The string to parse\n * @returns {Array<number>} Returns an energetic array.\n */\nfunction parsePart(string) {\n let res = [];\n let m;\n\n for (let str of string.split(\",\").map((str) => str.trim())) {\n // just a number\n if (/^-?\\d+$/.test(str)) {\n res.push(parseInt(str, 10));\n } else if (\n (m = str.match(/^(-?\\d+)(-|\\.\\.\\.?|\\u2025|\\u2026|\\u22EF)(-?\\d+)$/))\n ) {\n // 1-5 or 1..5 (equivalent) or 1...5 (doesn't include 5)\n let [_, lhs, sep, rhs] = m;\n\n if (lhs && rhs) {\n lhs = parseInt(lhs);\n rhs = parseInt(rhs);\n const incr = lhs < rhs ? 1 : -1;\n\n // Make it inclusive by moving the right 'stop-point' away by one.\n if (sep === \"-\" || sep === \"..\" || sep === \"\\u2025\") rhs += incr;\n\n for (let i = lhs; i !== rhs; i += incr) res.push(i);\n }\n }\n }\n\n return res;\n}\n\nexports.default = parsePart;\nmodule.exports = parsePart;\n","import {\n\tAnnotationRenderPhaseOrder,\n\tAttachedPluginData,\n\tExpressiveCodePlugin,\n\tInlineStyleAnnotation,\n\tensureColorContrastOnBackground,\n\tonBackground,\n\treplaceDelimitedValues,\n} from '@expressive-code/core'\nimport rangeParser from 'parse-numeric-range'\nimport { MarkerType, MarkerTypeOrder, markerTypeFromString } from './marker-types'\nimport { getTextMarkersBaseStyles, markerBgColorPaths, textMarkersStyleSettings } from './styles'\nimport { flattenInlineMarkerRanges, getInlineSearchTermMatches } from './inline-markers'\nimport { TextMarkerAnnotation } from './annotations'\nexport { TextMarkersStyleSettings } from './styles'\n\nexport function pluginTextMarkers(): ExpressiveCodePlugin {\n\treturn {\n\t\tname: 'TextMarkers',\n\t\tstyleSettings: textMarkersStyleSettings,\n\t\tbaseStyles: (context) => getTextMarkersBaseStyles(context),\n\t\thooks: {\n\t\t\tpreprocessMetadata: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.meta = replaceDelimitedValues(\n\t\t\t\t\tcodeBlock.meta,\n\t\t\t\t\t({ fullMatch, key, value, valueStartDelimiter }) => {\n\t\t\t\t\t\t// If we found a \"lang\" key and the code block's language is \"diff\",\n\t\t\t\t\t\t// use the \"lang\" value as the new syntax highlighting language instead\n\t\t\t\t\t\tif (key === 'lang' && codeBlock.language === 'diff') {\n\t\t\t\t\t\t\tcodeBlock.language = value\n\t\t\t\t\t\t\tblockData.originalLanguage = 'diff'\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Try to identify the marker type from the key\n\t\t\t\t\t\tconst markerType = markerTypeFromString(key || 'mark')\n\n\t\t\t\t\t\t// If an unknown key was encountered, leave this meta string part untouched\n\t\t\t\t\t\tif (!markerType) return fullMatch\n\n\t\t\t\t\t\t// Handle full-line highlighting definitions\n\t\t\t\t\t\tif (valueStartDelimiter === '{') {\n\t\t\t\t\t\t\tconst lineNumbers = rangeParser(value)\n\t\t\t\t\t\t\tlineNumbers.forEach((lineNumber) => {\n\t\t\t\t\t\t\t\tconst lineIndex = lineNumber - 1\n\t\t\t\t\t\t\t\tcodeBlock.getLine(lineIndex)?.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle regular expression search terms\n\t\t\t\t\t\tif (valueStartDelimiter === '/') {\n\t\t\t\t\t\t\t// Remember the term for highlighting in a later hook\n\t\t\t\t\t\t\tlet regExp: RegExp | undefined\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Try to use regular expressions with capture group indices\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'gd')\n\t\t\t\t\t\t\t\t/* c8 ignore start */\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t// Use fallback if unsupported\n\t\t\t\t\t\t\t\tregExp = new RegExp(value, 'g')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/* c8 ignore stop */\n\t\t\t\t\t\t\tblockData.regExpTerms.push({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tregExp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Treat everything else as a plaintext search term and\n\t\t\t\t\t\t// remember it for highlighting in a later hook\n\t\t\t\t\t\tblockData.plaintextTerms.push({\n\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalueDelimiters: ['\"', \"'\", '/', '{...}'],\n\t\t\t\t\t\tkeyValueSeparator: '=',\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t},\n\t\t\tpreprocessCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\t// Perform special handling of code marked with the language \"diff\":\n\t\t\t\t// - This language is often used as a widely supported format for highlighting\n\t\t\t\t// changes to code. In this case, the code is not actually a diff,\n\t\t\t\t// but another language with some lines prefixed by `+` or `-`.\n\t\t\t\t// - We try to detect this case and convert the prefixed lines to annotations\n\t\t\t\t// - To prevent modifying actual diff files (which would make them invalid),\n\t\t\t\t// we ensure that the code does not begin like a real diff:\n\t\t\t\t// - The first lines must not start with `*** `, `+++ `, `--- `, `@@ `,\n\t\t\t\t// or the default mode location syntax (e.g. `0a1`, `1,2c1,2`, `1,2d1`).\n\t\t\t\tif ((blockData.originalLanguage ?? codeBlock.language) === 'diff') {\n\t\t\t\t\tconst lines = codeBlock.getLines()\n\n\t\t\t\t\t// Ensure that the first lines do not look like actual diff output\n\t\t\t\t\tconst couldBeRealDiffFile = lines.slice(0, 4).some((line) => line.text.match(/^([*+-]{3}\\s|@@\\s|[0-9,]+[acd][0-9,]+\\s*$)/))\n\t\t\t\t\tif (!couldBeRealDiffFile) {\n\t\t\t\t\t\tlet minIndentation = Infinity\n\t\t\t\t\t\tconst parsedLines = lines.map((line) => {\n\t\t\t\t\t\t\tconst [, indentation, marker, content] = line.text.match(/^(([+-](?![+-]))?\\s*)(.*)$/) || []\n\t\t\t\t\t\t\tconst markerType: MarkerType | undefined = marker === '+' ? 'ins' : marker === '-' ? 'del' : undefined\n\n\t\t\t\t\t\t\t// As it's common to indent unchanged lines to match the indentation\n\t\t\t\t\t\t\t// of changed lines, and we don't want extra whitespace in the output,\n\t\t\t\t\t\t\t// we remember the minimum indentation of all non-empty lines\n\t\t\t\t\t\t\tif (content.trim().length > 0 && indentation.length < minIndentation) minIndentation = indentation.length\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tparsedLines.forEach(({ line, markerType }) => {\n\t\t\t\t\t\t\t// Remove line prefixes:\n\t\t\t\t\t\t\t// - If minIndentation is > 0, we remove minIndentation\n\t\t\t\t\t\t\t// - Otherwise, if the current line starts with a marker character,\n\t\t\t\t\t\t\t// we remove this single character\n\t\t\t\t\t\t\tconst colsToRemove = minIndentation || (markerType ? 1 : 0)\n\t\t\t\t\t\t\tif (colsToRemove > 0) line.editText(0, colsToRemove, '')\n\n\t\t\t\t\t\t\t// If we found a diff marker, add a line annotation\n\t\t\t\t\t\t\tif (markerType) {\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tannotateCode: ({ codeBlock, cssVar }) => {\n\t\t\t\tconst blockData = pluginTextMarkersData.getOrCreateFor(codeBlock)\n\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\t// Check the line text for search term matches and collect their ranges\n\t\t\t\t\tconst markerRanges = getInlineSearchTermMatches(line.text, blockData)\n\t\t\t\t\tif (!markerRanges.length) return\n\n\t\t\t\t\t// Flatten marked ranges to prevent any overlaps\n\t\t\t\t\tconst flattenedRanges = flattenInlineMarkerRanges(markerRanges)\n\n\t\t\t\t\t// Add annotations for all flattened ranges\n\t\t\t\t\tflattenedRanges.forEach(({ markerType, start, end }) => {\n\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\tnew TextMarkerAnnotation({\n\t\t\t\t\t\t\t\tmarkerType,\n\t\t\t\t\t\t\t\tbackgroundColor: cssVar(markerBgColorPaths[markerType]),\n\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\tcolumnStart: start,\n\t\t\t\t\t\t\t\t\tcolumnEnd: end,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t\tpostprocessAnnotations: ({ codeBlock, styleVariants, config }) => {\n\t\t\t\tif (config.minSyntaxHighlightingColorContrast <= 0) return\n\t\t\t\tcodeBlock.getLines().forEach((line) => {\n\t\t\t\t\tconst annotations = line.getAnnotations()\n\t\t\t\t\t// Determine the highest-priority full line marker\n\t\t\t\t\t// and collect all inline markers\n\t\t\t\t\tconst markers: TextMarkerAnnotation[] = []\n\t\t\t\t\tlet fullLineMarker: TextMarkerAnnotation | undefined = undefined\n\t\t\t\t\tfor (const annotation of annotations) {\n\t\t\t\t\t\tif (!(annotation instanceof TextMarkerAnnotation)) continue\n\t\t\t\t\t\tif (annotation.inlineRange) {\n\t\t\t\t\t\t\tmarkers.push(annotation)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fullLineMarker) {\n\t\t\t\t\t\t\tif (MarkerTypeOrder.indexOf(annotation.markerType) < MarkerTypeOrder.indexOf(fullLineMarker.markerType)) continue\n\t\t\t\t\t\t\tif (AnnotationRenderPhaseOrder.indexOf(annotation.renderPhase) < AnnotationRenderPhaseOrder.indexOf(fullLineMarker.renderPhase)) continue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfullLineMarker = annotation\n\t\t\t\t\t}\n\t\t\t\t\t// Prepend the highest-priority full line marker to the inline markers\n\t\t\t\t\tif (fullLineMarker) markers.unshift(fullLineMarker)\n\t\t\t\t\t// Ensure color contrast for all style variants\n\t\t\t\t\tstyleVariants.forEach((styleVariant, styleVariantIndex) => {\n\t\t\t\t\t\tconst fullLineMarkerBgColor = (fullLineMarker && styleVariant.resolvedStyleSettings.get(markerBgColorPaths[fullLineMarker.markerType])) || 'transparent'\n\t\t\t\t\t\tconst lineBgColor = onBackground(fullLineMarkerBgColor, styleVariant.resolvedStyleSettings.get('codeBackground') || styleVariant.theme.bg)\n\t\t\t\t\t\t// Collect inline style annotations that change the text color\n\t\t\t\t\t\tconst textColors = annotations.filter(\n\t\t\t\t\t\t\t(annotation) =>\n\t\t\t\t\t\t\t\tannotation instanceof InlineStyleAnnotation &&\n\t\t\t\t\t\t\t\tannotation.color &&\n\t\t\t\t\t\t\t\t// Only consider annotations that apply to the current style variant\n\t\t\t\t\t\t\t\t(annotation.styleVariantIndex === undefined || annotation.styleVariantIndex === styleVariantIndex)\n\t\t\t\t\t\t) as InlineStyleAnnotation[]\n\t\t\t\t\t\t// Go through all text color annotations\n\t\t\t\t\t\ttextColors.forEach((textColor) => {\n\t\t\t\t\t\t\tconst textFgColor = textColor.color\n\t\t\t\t\t\t\tconst textStart = textColor.inlineRange?.columnStart\n\t\t\t\t\t\t\tconst textEnd = textColor.inlineRange?.columnEnd\n\t\t\t\t\t\t\tif (textFgColor === undefined || textStart === undefined || textEnd === undefined) return\n\t\t\t\t\t\t\t// Go through all markers\n\t\t\t\t\t\t\tmarkers.forEach((marker) => {\n\t\t\t\t\t\t\t\tconst markerStart = marker.inlineRange?.columnStart ?? 0\n\t\t\t\t\t\t\t\tconst markerEnd = marker.inlineRange?.columnEnd ?? line.text.length\n\t\t\t\t\t\t\t\tif (markerStart > textEnd || markerEnd < textStart) return\n\t\t\t\t\t\t\t\t// As the marker overlaps with the text color annotation,\n\t\t\t\t\t\t\t\t// determine the combined background color of this range\n\t\t\t\t\t\t\t\tconst markerBgColor = styleVariant.resolvedStyleSettings.get(markerBgColorPaths[marker.markerType]) ?? ''\n\t\t\t\t\t\t\t\tconst combinedBgColor = onBackground(markerBgColor, lineBgColor)\n\t\t\t\t\t\t\t\t// Now ensure a good contrast ratio of the text\n\t\t\t\t\t\t\t\tconst readableTextColor = ensureColorContrastOnBackground(textFgColor, combinedBgColor, config.minSyntaxHighlightingColorContrast)\n\t\t\t\t\t\t\t\tif (readableTextColor.toLowerCase() === textFgColor.toLowerCase()) return\n\t\t\t\t\t\t\t\t// If the text color is not readable enough, add an annotation\n\t\t\t\t\t\t\t\t// with better contrast for the overlapping range\n\t\t\t\t\t\t\t\tline.addAnnotation(\n\t\t\t\t\t\t\t\t\tnew InlineStyleAnnotation({\n\t\t\t\t\t\t\t\t\t\tstyleVariantIndex,\n\t\t\t\t\t\t\t\t\t\tinlineRange: {\n\t\t\t\t\t\t\t\t\t\t\tcolumnStart: Math.max(textStart, markerStart),\n\t\t\t\t\t\t\t\t\t\t\tcolumnEnd: Math.min(textEnd, markerEnd),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tcolor: readableTextColor,\n\t\t\t\t\t\t\t\t\t\trenderPhase: 'earlier',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface PluginTextMarkersData {\n\tplaintextTerms: { markerType: MarkerType; text: string }[]\n\tregExpTerms: { markerType: MarkerType; regExp: RegExp }[]\n\toriginalLanguage?: string | undefined\n}\n\nexport const pluginTextMarkersData = new AttachedPluginData<PluginTextMarkersData>(() => ({ plaintextTerms: [], regExpTerms: [] }))\n","export type MarkerType = 'mark' | 'ins' | 'del'\n\n/** When markers overlap, those with higher indices override lower ones. */\nexport const MarkerTypeOrder: MarkerType[] = ['mark', 'del', 'ins']\n\n/**\n * If the given input string represents a valid marker type,\n * converts it to a {@link MarkerType} and returns it.\n *\n * Otherwise, returns `undefined`.\n */\nexport function markerTypeFromString(input: string) {\n\t// Fix common marker type mistakes\n\tif (input === 'add') input = 'ins'\n\tif (input === 'rem') input = 'del'\n\n\t// Return either the converted type or undefined\n\tconst markerType = input as MarkerType\n\treturn MarkerTypeOrder.includes(markerType) ? markerType : undefined\n}\n","import { PluginStyleSettings, codeLineClass, toHexColor, StyleSettingPath, ResolverContext, StyleResolverFn } from '@expressive-code/core'\nimport { MarkerType } from './marker-types'\n\nexport interface TextMarkersStyleSettings {\n\t/**\n\t * The margin between the code block border and the line marker accent bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0rem'\n\t */\n\tlineMarkerAccentMargin: string\n\t/**\n\t * The width of the line marker accent bar. This is the vertical border-like bar\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.15rem'\n\t */\n\tlineMarkerAccentWidth: string\n\t/**\n\t * The margin between the code block border and the diff indicator (e.g. `+` or `-`)\n\t * displayed on the left side of a full-line text marker.\n\t * @default '0.5rem'\n\t */\n\tlineDiffIndicatorMarginLeft: string\n\t/**\n\t * The width of the border around inline text markers, rendered in a way\n\t * that does not cause marked code to shift.\n\t * @default '1.5px'\n\t */\n\tinlineMarkerBorderWidth: string\n\t/**\n\t * The border radius of inline text markers.\n\t * @default '0.2rem'\n\t */\n\tinlineMarkerBorderRadius: string\n\t/**\n\t * The inline padding of inline text markers. Keep this low to prevent marked code\n\t * from shifting too much compared to the original text.\n\t * @default '0.15rem'\n\t */\n\tinlineMarkerPadding: string\n\t/**\n\t * The LCH hue to be used for marked text (text marker type `mark`).\n\t * @default '284' (a blue hue)\n\t */\n\tmarkHue: string\n\t/**\n\t * The LCH hue to be used for inserted text (text marker type `ins`).\n\t * @default '136' (a green hue)\n\t */\n\tinsHue: string\n\t/**\n\t * The LCH hue to be used for deleted text (text marker type `del`).\n\t * @default '33' (a red hue)\n\t */\n\tdelHue: string\n\t/**\n\t * The LCH chroma to be used for all text marker types.\n\t *\n\t * The chroma value defines the saturation of the color. Higher values lead to\n\t * more saturated colors, lower values lead to less saturated colors.\n\t *\n\t * @default '40'\n\t */\n\tdefaultChroma: string\n\t/**\n\t * The LCH luminance to be used for all text marker types.\n\t * @default\n\t * ['32%', '75%'] // 32% for dark themes, 75% for light themes\n\t */\n\tdefaultLuminance: string\n\t/**\n\t * The opacity of the background color of all text marker types.\n\t * @default '50%'\n\t */\n\tbackgroundOpacity: string\n\t/**\n\t * The LCH luminance to be used for the border color of all text marker types.\n\t * @default '48%'\n\t */\n\tborderLuminance: string\n\t/**\n\t * The opacity of the border color of all text marker types.\n\t * @default '81.6%'\n\t */\n\tborderOpacity: string\n\t/**\n\t * The LCH luminance to be used for the diff indicator (e.g. `+` or `-`).\n\t * @default\n\t * ['67%', '40%'] // 67% for dark themes, 40% for light themes\n\t */\n\tindicatorLuminance: string\n\t/**\n\t * The opacity of the diff indicator (e.g. `+` or `-`).\n\t * @default '81.6%'\n\t */\n\tindicatorOpacity: string\n\t/**\n\t * The content to be displayed inside the diff indicator of inserted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'+'\"\n\t */\n\tinsDiffIndicatorContent: string\n\t/**\n\t * The content to be displayed inside the diff indicator of deleted lines.\n\t *\n\t * Note that this is used as the `content` value in a CSS pseudo-element,\n\t * so you need to wrap any text in additional quotes.\n\t *\n\t * @default \"'-'\"\n\t */\n\tdelDiffIndicatorContent: string\n\t/**\n\t * The background color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <markHue> / <backgroundOpacity>)\n\t */\n\tmarkBackground: string\n\t/**\n\t * The border color of marked text (text marker type `mark`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <markHue> / <borderOpacity>)\n\t */\n\tmarkBorderColor: string\n\t/**\n\t * The background color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <insHue> / <backgroundOpacity>)\n\t */\n\tinsBackground: string\n\t/**\n\t * The border color of inserted text (text marker type `ins`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <insHue> / <borderOpacity>)\n\t */\n\tinsBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of inserted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <insHue> / <indicatorOpacity>)\n\t */\n\tinsDiffIndicatorColor: string\n\t/**\n\t * The background color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<defaultLuminance> <defaultChroma> <delHue> / <backgroundOpacity>)\n\t */\n\tdelBackground: string\n\t/**\n\t * The border color of deleted text (text marker type `del`).\n\t * @default\n\t * lch(<borderLuminance> <defaultChroma> <delHue> / <borderOpacity>)\n\t */\n\tdelBorderColor: string\n\t/**\n\t * The color of the diff indicator (e.g. `+` or `-`) of deleted lines.\n\t * @default\n\t * lch(<indicatorLuminance> <defaultChroma> <delHue> / <indicatorOpacity>)\n\t */\n\tdelDiffIndicatorColor: string\n}\n\ndeclare module '@expressive-code/core' {\n\texport interface StyleSettings {\n\t\ttextMarkers: TextMarkersStyleSettings\n\t}\n}\n\nexport const textMarkersStyleSettings = new PluginStyleSettings({\n\tdefaultValues: {\n\t\ttextMarkers: {\n\t\t\tlineMarkerAccentMargin: '0rem',\n\t\t\tlineMarkerAccentWidth: '0.15rem',\n\t\t\tlineDiffIndicatorMarginLeft: '0.5rem',\n\t\t\tinlineMarkerBorderWidth: '1.5px',\n\t\t\tinlineMarkerBorderRadius: '0.2rem',\n\t\t\tinlineMarkerPadding: '0.15rem',\n\t\t\t// Define base colors for all markers in the LCH color space,\n\t\t\t// which leads to consistent perceived brightness independent of hue\n\t\t\tmarkHue: '284',\n\t\t\tinsHue: '136',\n\t\t\tdelHue: '33',\n\t\t\tdefaultChroma: '40',\n\t\t\tdefaultLuminance: ['32%', '75%'],\n\t\t\tbackgroundOpacity: '50%',\n\t\t\tborderLuminance: '48%',\n\t\t\tborderOpacity: '81.6%',\n\t\t\tindicatorLuminance: ['67%', '40%'],\n\t\t\tindicatorOpacity: '81.6%',\n\t\t\t// You can use these to override the diff indicator content\n\t\t\tinsDiffIndicatorContent: \"'+'\",\n\t\t\tdelDiffIndicatorContent: \"'-'\",\n\t\t\t// The settings below will be calculated based on the settings above\n\t\t\tmarkBackground: (context) => resolveBg(context, 'textMarkers.markHue'),\n\t\t\tmarkBorderColor: (context) => resolveBorder(context, 'textMarkers.markHue'),\n\t\t\tinsBackground: (context) => resolveBg(context, 'textMarkers.insHue'),\n\t\t\tinsBorderColor: (context) => resolveBorder(context, 'textMarkers.insHue'),\n\t\t\tinsDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.insHue'),\n\t\t\tdelBackground: (context) => resolveBg(context, 'textMarkers.delHue'),\n\t\t\tdelBorderColor: (context) => resolveBorder(context, 'textMarkers.delHue'),\n\t\t\tdelDiffIndicatorColor: (context) => resolveIndicator(context, 'textMarkers.delHue'),\n\t\t},\n\t},\n\tcssVarExclusions: [\n\t\t// Exclude all settings from CSS variable output that will not be used directly in styles,\n\t\t// but instead be used to calculate other settings\n\t\t'textMarkers.markHue',\n\t\t'textMarkers.insHue',\n\t\t'textMarkers.delHue',\n\t\t'textMarkers.defaultChroma',\n\t\t'textMarkers.defaultLuminance',\n\t\t'textMarkers.backgroundOpacity',\n\t\t'textMarkers.borderLuminance',\n\t\t'textMarkers.borderOpacity',\n\t\t'textMarkers.indicatorLuminance',\n\t\t'textMarkers.indicatorOpacity',\n\t],\n})\n\nexport function getTextMarkersBaseStyles({ cssVar }: ResolverContext) {\n\tconst result = `\n\t\t.${codeLineClass} {\n\t\t\t/* Support line-level mark/ins/del */\n\t\t\t&.mark {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t&.ins {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.insDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.insDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.del {\n\t\t\t\t--tmLineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmLineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: ${cssVar('textMarkers.delDiffIndicatorContent')};\n\t\t\t\t\tcolor: ${cssVar('textMarkers.delDiffIndicatorColor')};\n\t\t\t\t}\n\t\t\t}\n\t\t\t&.mark,\n\t\t\t&.ins,\n\t\t\t&.del {\n\t\t\t\tposition: relative;\n\t\t\t\tbackground: var(--tmLineBgCol);\n\t\t\t\tmin-width: calc(100% - ${cssVar('textMarkers.lineMarkerAccentMargin')});\n\t\t\t\tmargin-inline-start: ${cssVar('textMarkers.lineMarkerAccentMargin')};\n\t\t\t\tborder-inline-start: ${cssVar('textMarkers.lineMarkerAccentWidth')} solid var(--tmLineBrdCol);\n\t\t\t\tpadding-inline-start: calc(${cssVar('codePaddingInline')} - ${cssVar('textMarkers.lineMarkerAccentMargin')} - ${cssVar('textMarkers.lineMarkerAccentWidth')}) !important;\n\t\t\t\t&::before {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tleft: ${cssVar('textMarkers.lineDiffIndicatorMarginLeft')};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Support inline mark/ins/del */\n\t\t\t& mark {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.markBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.markBorderColor')};\n\t\t\t}\n\t\t\t& ins {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.insBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.insBorderColor')};\n\t\t\t}\n\t\t\t& del {\n\t\t\t\t--tmInlineBgCol: ${cssVar('textMarkers.delBackground')};\n\t\t\t\t--tmInlineBrdCol: ${cssVar('textMarkers.delBorderColor')};\n\t\t\t}\n\t\t\t& mark,\n\t\t\t& ins,\n\t\t\t& del {\n\t\t\t\tall: unset;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tposition: relative;\n\t\t\t\t--tmBrdL: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmBrdR: ${cssVar('textMarkers.inlineMarkerBorderWidth')};\n\t\t\t\t--tmRadL: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\t--tmRadR: ${cssVar('textMarkers.inlineMarkerBorderRadius')};\n\t\t\t\tmargin-inline: 0.025rem;\n\t\t\t\tpadding-inline: ${cssVar('textMarkers.inlineMarkerPadding')};\n\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\tbackground: var(--tmInlineBgCol);\n\t\t\t\tbackground-clip: padding-box;\n\n\t\t\t\t&.open-start {\n\t\t\t\t\tmargin-inline-start: 0;\n\t\t\t\t\tpadding-inline-start: 0;\n\t\t\t\t\t--tmBrdL: 0px;\n\t\t\t\t\t--tmRadL: 0;\n\t\t\t\t}\n\t\t\t\t&.open-end {\n\t\t\t\t\tmargin-inline-end: 0;\n\t\t\t\t\tpadding-inline-end: 0;\n\t\t\t\t\t--tmBrdR: 0px;\n\t\t\t\t\t--tmRadR: 0;\n\t\t\t\t}\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: '';\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tinset: 0;\n\t\t\t\t\tborder-radius: var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);\n\t\t\t\t\tborder: ${cssVar('textMarkers.inlineMarkerBorderWidth')} solid var(--tmInlineBrdCol);\n\t\t\t\t\tborder-inline-width: var(--tmBrdL) var(--tmBrdR);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`\n\n\treturn result\n}\n\nexport const markerBgColorPaths: { [K in MarkerType]: StyleSettingPath } = {\n\tmark: 'textMarkers.markBackground',\n\tins: 'textMarkers.insBackground',\n\tdel: 'textMarkers.delBackground',\n}\n\nfunction resolveBg({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.defaultLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.backgroundOpacity')})`)\n}\n\nfunction resolveBorder({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.borderLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.borderOpacity')})`)\n}\n\nfunction resolveIndicator({ resolveSetting: r }: Parameters<StyleResolverFn>[0], hue: StyleSettingPath) {\n\treturn toHexColor(`lch(${r('textMarkers.indicatorLuminance')} ${r('textMarkers.defaultChroma')} ${r(hue)} / ${r('textMarkers.indicatorOpacity')})`)\n}\n","import { getGroupIndicesFromRegExpMatch } from '@expressive-code/core'\nimport { MarkerType, MarkerTypeOrder } from './marker-types'\nimport { PluginTextMarkersData } from '.'\n\nexport type InlineMarkerRange = { markerType: MarkerType; start: number; end: number }\n\n/**\n * Goes through all search terms in the given block data and returns an array of\n * inline marker ranges that match the given line text.\n */\nexport function getInlineSearchTermMatches(lineText: string, blockData: PluginTextMarkersData) {\n\tconst markerMatches: InlineMarkerRange[] = []\n\n\t// Collect all plaintext term matches\n\tblockData.plaintextTerms.forEach(({ markerType, text }) => {\n\t\tlet idx = lineText.indexOf(text, 0)\n\t\twhile (idx > -1) {\n\t\t\tmarkerMatches.push({\n\t\t\t\tmarkerType,\n\t\t\t\tstart: idx,\n\t\t\t\tend: idx + text.length,\n\t\t\t})\n\t\t\tidx = lineText.indexOf(text, idx + text.length)\n\t\t}\n\t})\n\n\t// Collect all regular expression matches\n\tblockData.regExpTerms.forEach(({ markerType, regExp }) => {\n\t\tconst matches = lineText.matchAll(regExp)\n\t\tfor (const match of matches) {\n\t\t\tconst rawGroupIndices = getGroupIndicesFromRegExpMatch(match)\n\t\t\t// Remove null group indices\n\t\t\tlet groupIndices = rawGroupIndices.flatMap((range) => (range ? [range] : []))\n\t\t\t// If there are no non-null indices, use the full match instead\n\t\t\t// (capture group feature fallback, impossible to cover in tests)\n\t\t\t/* c8 ignore start */\n\t\t\tif (!groupIndices.length) {\n\t\t\t\tconst fullMatchIndex = match.index as number\n\t\t\t\tgroupIndices = [[fullMatchIndex, fullMatchIndex + match[0].length]]\n\t\t\t}\n\t\t\t/* c8 ignore end */\n\t\t\t// If there are multiple non-null indices, remove the first one\n\t\t\t// as it is the full match and we only want to mark capture groups\n\t\t\tif (groupIndices.length > 1) {\n\t\t\t\tgroupIndices.shift()\n\t\t\t}\n\t\t\t// Create marked ranges from all remaining group indices\n\t\t\tgroupIndices.forEach((range) => {\n\t\t\t\tmarkerMatches.push({\n\t\t\t\t\tmarkerType,\n\t\t\t\t\tstart: range[0],\n\t\t\t\t\tend: range[1],\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t})\n\n\treturn markerMatches\n}\n\n/**\n * Takes an array of inline marker ranges and returns a new array without overlapping ranges,\n * either by merging them into a combined range (if their marker types are the same),\n * or by overriding lower-priority markers with higher-priority ones (if their types differ).\n */\nexport function flattenInlineMarkerRanges(markerRanges: InlineMarkerRange[]): InlineMarkerRange[] {\n\tconst flattenedRanges: InlineMarkerRange[] = []\n\tconst addRange = (newRange: InlineMarkerRange) => {\n\t\tfor (let idx = flattenedRanges.length - 1; idx >= 0; idx--) {\n\t\t\tconst curRange = flattenedRanges[idx]\n\t\t\t// No overlap: The new range ends before the current one starts,\n\t\t\t// or it starts after the current one ends\n\t\t\tif (newRange.end <= curRange.start || newRange.start >= curRange.end) continue\n\n\t\t\t// Full overlap: The new range fully covers the current one\n\t\t\tif (newRange.start <= curRange.start && newRange.end >= curRange.end) {\n\t\t\t\t// Remove current range\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Partial overlap with same marker type\n\t\t\tif (newRange.markerType === curRange.markerType) {\n\t\t\t\t// Remove current range and extend the new one to cover it\n\t\t\t\tflattenedRanges.splice(idx, 1)\n\t\t\t\tnewRange = {\n\t\t\t\t\t...newRange,\n\t\t\t\t\tstart: Math.min(newRange.start, curRange.start),\n\t\t\t\t\tend: Math.max(newRange.end, curRange.end),\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range leaves both the start and the end of the current range\n\t\t\t// uncovered, we need to split the current range into two parts\n\t\t\tif (newRange.start > curRange.start && newRange.end < curRange.end) {\n\t\t\t\t// Replace the current range with two partial ranges\n\t\t\t\tflattenedRanges.splice(idx, 1, { ...curRange, end: newRange.start }, { ...curRange, start: newRange.end })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the new range starts after the current one starts, shorten the current range\n\t\t\tif (newRange.start > curRange.start) {\n\t\t\t\tcurRange.end = newRange.start\n\t\t\t}\n\n\t\t\t// If the new range ends before the current one ends, shorten the current range\n\t\t\tif (newRange.end < curRange.end) {\n\t\t\t\tcurRange.start = newRange.end\n\t\t\t}\n\t\t}\n\t\t// Finally add the new range to the flattened ranges and sort them by start position\n\t\tflattenedRanges.push(newRange)\n\t\tflattenedRanges.sort((a, b) => a.start - b.start)\n\t}\n\n\tMarkerTypeOrder.forEach((markerType) => {\n\t\tmarkerRanges.filter((range) => range.markerType === markerType).forEach(addRange)\n\t})\n\n\treturn flattenedRanges\n}\n","import { addClassName, ExpressiveCodeAnnotation, AnnotationBaseOptions, AnnotationRenderOptions } from '@expressive-code/core'\nimport { h } from 'hastscript'\nimport { Element } from 'hast-util-select/lib/types'\nimport { MarkerType } from './marker-types'\n\nexport class TextMarkerAnnotation extends ExpressiveCodeAnnotation {\n\tmarkerType: MarkerType\n\tbackgroundColor: string\n\n\tconstructor({ markerType, backgroundColor, ...baseOptions }: { markerType: MarkerType; backgroundColor: string } & AnnotationBaseOptions) {\n\t\tsuper(baseOptions)\n\t\tthis.markerType = markerType\n\t\tthis.backgroundColor = backgroundColor\n\t}\n\n\trender(options: AnnotationRenderOptions) {\n\t\tif (!this.inlineRange) return this.renderFullLineMarker(options)\n\t\treturn this.renderInlineMarker(options)\n\t}\n\n\tprivate renderFullLineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node) => {\n\t\t\taddClassName(node as Element, this.markerType)\n\t\t\treturn node\n\t\t})\n\t}\n\n\tprivate renderInlineMarker({ nodesToTransform }: AnnotationRenderOptions) {\n\t\treturn nodesToTransform.map((node, idx) => {\n\t\t\tconst transformedNode = h(this.markerType, node)\n\n\t\t\tif (nodesToTransform.length > 0 && idx > 0) {\n\t\t\t\taddClassName(transformedNode, 'open-start')\n\t\t\t}\n\t\t\tif (nodesToTransform.length > 0 && idx < nodesToTransform.length - 1) {\n\t\t\t\taddClassName(transformedNode, 'open-end')\n\t\t\t}\n\t\t\treturn transformedNode\n\t\t})\n\t}\n}\n"],"mappings":"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","names":["str","rangeParser"]} |
+3
-3
| { | ||
| "name": "@expressive-code/plugin-text-markers", | ||
| "version": "0.30.1", | ||
| "version": "0.30.2", | ||
| "description": "Text marker plugin for Expressive Code, a text marking & annotation engine for presenting source code on the web.", | ||
@@ -26,3 +26,3 @@ "keywords": [], | ||
| "dependencies": { | ||
| "@expressive-code/core": "^0.30.1", | ||
| "@expressive-code/core": "^0.30.2", | ||
| "hastscript": "^7.2.0", | ||
@@ -32,3 +32,3 @@ "unist-util-visit-parents": "^5.1.3" | ||
| "devDependencies": { | ||
| "@expressive-code/plugin-shiki": "^0.30.1", | ||
| "@expressive-code/plugin-shiki": "^0.30.2", | ||
| "hast-util-select": "^5.0.5", | ||
@@ -35,0 +35,0 @@ "hast-util-to-html": "^8.0.4", |
+2
-279
| # @expressive-code/plugin-text-markers | ||
| ## Contents | ||
| - [What is this?](#what-is-this) | ||
| - [When should I use this?](#when-should-i-use-this) | ||
| - [Installation (not required)](#installation-not-required) | ||
| - [Usage in markdown / MDX documents](#usage-in-markdown--mdx-documents) | ||
| - [Marking entire lines & line ranges](#marking-entire-lines--line-ranges) | ||
| - [Marking individual text inside lines](#marking-individual-text-inside-lines) | ||
| - [Plaintext search strings](#plaintext-search-strings) | ||
| - [Regular expressions](#regular-expressions) | ||
| - [Selecting marker types (`mark`, `ins`, `del`)](#selecting-marker-types-mark-ins-del) | ||
| - [Support for `diff`-like syntax](#support-for-diff-like-syntax) | ||
| - [Configuration](#configuration) | ||
| - [Astro configuration example](#astro-configuration-example) | ||
| - [Next.js configuration example using `@next/mdx`](#nextjs-configuration-example-using-nextmdx) | ||
| - [Available plugin options](#available-plugin-options) | ||
| - [Advanced use cases](#advanced-use-cases) | ||
| - [Manual installation](#manual-installation) | ||
| - [Manual usage from the core package](#manual-usage-from-the-core-package) | ||
| ## What is this? | ||
| A default plugin of Expressive Code, an engine for presenting source code on the web. | ||
@@ -31,263 +9,8 @@ | ||
| Please see the [usage examples](#usage-in-markdown--mdx-documents) below for more information. | ||
| ## Documentation | ||
| ## When should I use this? | ||
| [Read this plugin's documentation](https://expressive-code.com/key-features/text-markers/) on the Expressive Code website to learn more about its features. | ||
| This plugin is **installed by default** by our higher-level packages like `remark-expressive-code`, so text markers are always available when rendering code blocks in your markdown / MDX documents. | ||
| ## Installation (not required) | ||
| No installation is required. This package is **installed by default** by our higher-level packages. | ||
| If you are using the core package directly (e.g. because you are writing an integration), see the [Advanced use cases](#advanced-use-cases) section for more information. | ||
| ## Usage in markdown / MDX documents | ||
| To use text markers, you need to add them to the **meta information** of your code blocks. This is the string following the language identifier of your opening code fence: | ||
| ````md | ||
| ```js {4, 12-15} "this will be marked" /ye[sp]/ | ||
| // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| // This is the meta information of this code | ||
| // block. It contains 3 text markers: | ||
| // - Line range: {4, 12-15} | ||
| // - Plaintext search: "this will be marked" | ||
| // - Regular expression search: /ye[sp]/ | ||
| ``` | ||
| ```` | ||
| ### Marking entire lines & line ranges | ||
| Lines can be marked by adding their **line numbers inside curly brackets** to a code block's meta information. Line numbers start at 1, just like in VS Code and other popular editors. | ||
| You can either mark a single line, or a range of lines, and you can combine multiple line markers by separating them with commas: | ||
| - Single line: `{4}` | ||
| - Multiple lines: `{4, 8, 12}` | ||
| - Range of lines: `{4-8}` | ||
| - Different types combined: `{4, 6, 12-15}` | ||
| ### Marking individual text inside lines | ||
| #### Plaintext search strings | ||
| To match a string of text inside your code block's lines, simply **wrap it in quotes**. You can use either double or single quotes: | ||
| - `"this will be marked"` | ||
| - `'this will be marked'` | ||
| If the text you want to match contains quotes itself, you can use the other quote type to wrap it without having to escape the nested quotes: | ||
| - `"these 'single' quotes need no escaping"` | ||
| - `'these "double" quotes need no escaping'` | ||
| If you cannot avoid nested quotes of the same type, you can escape them using a backslash: | ||
| - `"this contains both \"double\" and 'single' quotes"` | ||
| - `'this contains both "double" and \'single\' quotes'` | ||
| #### Regular expressions | ||
| To match a regular expression inside your code block's lines, **wrap it in forward slashes**: | ||
| - `/ye[sp]/` will mark both `yes` and `yep` | ||
| To match a forward slash inside your regular expression, you can escape it using a backslash: | ||
| - `/\/home\//` will mark `/home/` | ||
| If you only want to mark certain parts matched by your regular expression, you can use capture groups: | ||
| - `/ye(s|p)/` will match `yes` and `yep`, but only mark the character `s` or `p` | ||
| To prevent capture groups from being marked, you can use non-capturing groups: | ||
| - `/ye(?:s|p)/` will mark `yes` and `yep` | ||
| ### Selecting marker types (`mark`, `ins`, `del`) | ||
| All of the above examples will use the default marker type `mark`, unless you specify a different type like `ins` (inserted) or `del` (deleted). | ||
| You can add your desired marker type in front of the marker definition, followed by an equals sign. For example, to mark a line as inserted, you would use `ins={4}`. | ||
| You can also combine many different markers in a single code block: | ||
| ````md | ||
| ```js del={4-6} ins={12} ins="this was inserted" del=/ye[sp]/ | ||
| // ^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ | ||
| // deleted inserted inserted deleted | ||
| // lines line text text | ||
| ``` | ||
| ```` | ||
| ### Support for `diff`-like syntax | ||
| Instead of adding line numbers to the opening code fence as shown above, you can also use the `diff` language, which is supported on many platforms (e.g. GitHub). Set the language in the opening code fence to `diff` and add a `+` or `-` marker to the first column of any line: | ||
| ````md | ||
| ```diff | ||
| +this line will be marked as inserted | ||
| -this line will be marked as deleted | ||
| this is a regular line | ||
| ``` | ||
| ```` | ||
| To make the raw contents in your markdown / MDX document more readable, you can add whitespace after the `+` or `-` marker (not before), and align unchanged lines with the changed ones. This additional whitespace will be automatically detected and removed from the rendered code block: | ||
| ````md | ||
| ```diff | ||
| + this line will be marked as inserted | ||
| - this line will be marked as deleted | ||
| this is a regular line | ||
| ``` | ||
| ```` | ||
| To avoid unexpected modifications of actual diff files (which would make them unusable), this plugin will automatically detect diff content based on its common metadata lines. It will detect unified and context mode diff syntax like `***`, `+++`, `---`, `@@`, as well as the default mode location syntax (e.g. `0a1`, `1,2c1,2`, `1,2d1`): | ||
| ````md | ||
| ```diff | ||
| --- a/README.md | ||
| +++ b/README.md | ||
| @@ -1,3 +1,4 @@ | ||
| +this is an actual diff file | ||
| -all contents will remain unmodified | ||
| no whitespace will be removed either | ||
| ``` | ||
| ```` | ||
| #### Combining syntax highlighting with `diff`-like syntax | ||
| Usually, a downside of using the `diff` language is that you lose syntax highlighting of the actual code's language. To work around this, this plugin allows you to specify a second language identifier by adding a `lang="..."` attribute to the opening code fence. The value of this attribute will then be used for syntax highlighting, while the `diff`-like syntax can be used for marking lines: | ||
| ````md | ||
| ```diff lang="js" | ||
| function thisIsJavaScript() { | ||
| // This entire block gets highlighted as JavaScript, | ||
| // and we can still add diff markers to it! | ||
| - console.log('Old code to be removed') | ||
| + console.log('New and shiny code!') | ||
| } | ||
| ``` | ||
| ```` | ||
| ## Configuration | ||
| When using this plugin through higher-level integration packages, you can configure it by passing options to the higher-level package. | ||
| Here are configuration examples for some popular site generators: | ||
| ### Astro configuration example | ||
| We assume that you're using our Astro integration [`astro-expressive-code`](https://www.npmjs.com/package/astro-expressive-code). | ||
| In your Astro config file, you can pass options to the plugin like this: | ||
| ```js | ||
| // astro.config.mjs | ||
| import { defineConfig } from 'astro/config' | ||
| import astroExpressiveCode from 'astro-expressive-code' | ||
| /** @type {import('astro-expressive-code').AstroExpressiveCodeOptions} */ | ||
| const astroExpressiveCodeOptions = { | ||
| styleOverrides: { | ||
| // You can optionally override the plugin's default styles here | ||
| textMarkers: { | ||
| // Make default marker color slightly purple | ||
| markHue: '310', | ||
| // Reduce marker border opacity | ||
| borderOpacity: '50%', | ||
| }, | ||
| }, | ||
| } | ||
| export default defineConfig({ | ||
| integrations: [ | ||
| astroExpressiveCode(astroExpressiveCodeOptions), | ||
| ], | ||
| }) | ||
| ``` | ||
| ### Next.js configuration example using `@next/mdx` | ||
| ```js | ||
| // next.config.mjs | ||
| import createMDX from '@next/mdx' | ||
| import remarkExpressiveCode from 'remark-expressive-code' | ||
| /** @type {import('remark-expressive-code').RemarkExpressiveCodeOptions} */ | ||
| const remarkExpressiveCodeOptions = { | ||
| styleOverrides: { | ||
| // You can optionally override the plugin's default styles here | ||
| textMarkers: { | ||
| // Make default marker color slightly purple | ||
| markHue: '310', | ||
| // Reduce marker border opacity | ||
| borderOpacity: '50%', | ||
| }, | ||
| }, | ||
| } | ||
| /** @type {import('next').NextConfig} */ | ||
| const nextConfig = { | ||
| reactStrictMode: true, | ||
| pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"], | ||
| } | ||
| const withMDX = createMDX({ | ||
| extension: /\.mdx?$/, | ||
| options: { | ||
| remarkPlugins: [ | ||
| // The nested array structure is required to pass options | ||
| // to a remark plugin | ||
| [remarkExpressiveCode, remarkExpressiveCodeOptions], | ||
| ], | ||
| rehypePlugins: [], | ||
| }, | ||
| }) | ||
| export default withMDX(nextConfig) | ||
| ``` | ||
| ### Available plugin options | ||
| This plugin does not provide any configuration options that can be passed to its initialization function. | ||
| However, you can override its default styles inside the `styleOverrides` engine config option. See the [configuration examples](#configuration) above for more information. | ||
| ## Advanced use cases | ||
| ### Manual installation | ||
| You only need to install this plugin if you are using the core package `@expressive-code/core` directly. In this case, you can install the plugin like this: | ||
| ```bash | ||
| # Note: This is an advanced usage example! | ||
| # You normally don't need to install this package manually, | ||
| # it is installed by default by our higher-level packages. | ||
| npm install @expressive-code/plugin-text-markers | ||
| ``` | ||
| ### Manual usage from the core package | ||
| > **Warning**: | ||
| > **This is an advanced usage example!** You normally don't need to use the core package directly, or manually add this plugin to the configuration. | ||
| ```js | ||
| import { ExpressiveCodeEngine } from '@expressive-code/core' | ||
| import { pluginTextMarkers } from '@expressive-code/plugin-text-markers' | ||
| const ec = new ExpressiveCodeEngine({ | ||
| plugins: [ | ||
| pluginTextMarkers(), | ||
| ], | ||
| }) | ||
| const renderResult = await ec.render({ | ||
| code: `const hello = 'World!'`, | ||
| language: 'js', | ||
| meta: `"hello"`, | ||
| }) | ||
| // If you were to render the returned AST to HTML now, | ||
| // the word "hello" would be marked. | ||
| ``` |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1242
0.16%143517
-6.21%16
-94.54%