@pierre/diffs 1.5.2 → 1.6.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +6 -5
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +11 -6
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +12 -7
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts +6 -4
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +49 -36
- package/dist/components/FileStream.js.map +1 -1
- package/dist/constants.d.ts +3 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/editor.d.ts +2 -1
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +5 -1
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/tokenizer.d.ts +6 -4
- package/dist/editor/tokenizer.d.ts.map +1 -1
- package/dist/editor/tokenizer.js +25 -470
- package/dist/editor/tokenizer.js.map +1 -1
- package/dist/highlighter/DiffsEditorTokenizer.d.ts +16 -0
- package/dist/highlighter/DiffsEditorTokenizer.d.ts.map +1 -0
- package/dist/highlighter/DiffsEditorTokenizer.js +0 -0
- package/dist/highlighter/DiffsHighlighter.d.ts +41 -0
- package/dist/highlighter/DiffsHighlighter.d.ts.map +1 -0
- package/dist/highlighter/DiffsHighlighter.js +39 -0
- package/dist/highlighter/DiffsHighlighter.js.map +1 -0
- package/dist/highlighter/backends/highlights.d.ts +26 -0
- package/dist/highlighter/backends/highlights.d.ts.map +1 -0
- package/dist/highlighter/backends/highlights.js +71 -0
- package/dist/highlighter/backends/highlights.js.map +1 -0
- package/dist/highlighter/backends/shiki.d.ts +27 -0
- package/dist/highlighter/backends/shiki.d.ts.map +1 -0
- package/dist/highlighter/backends/shiki.js +107 -0
- package/dist/highlighter/backends/shiki.js.map +1 -0
- package/dist/highlighter/highlighterType.d.ts +13 -0
- package/dist/highlighter/highlighterType.d.ts.map +1 -0
- package/dist/highlighter/highlighterType.js +32 -0
- package/dist/highlighter/highlighterType.js.map +1 -0
- package/dist/highlighter/highlights-editor.d.ts +24 -0
- package/dist/highlighter/highlights-editor.d.ts.map +1 -0
- package/dist/highlighter/highlights-editor.js +166 -0
- package/dist/highlighter/highlights-editor.js.map +1 -0
- package/dist/highlighter/highlights-stream.d.ts +20 -0
- package/dist/highlighter/highlights-stream.d.ts.map +1 -0
- package/dist/highlighter/highlights-stream.js +93 -0
- package/dist/highlighter/highlights-stream.js.map +1 -0
- package/dist/highlighter/languages/areLanguagesAttached.d.ts +2 -1
- package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
- package/dist/highlighter/languages/areLanguagesAttached.js +4 -6
- package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts +6 -1
- package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
- package/dist/highlighter/languages/attachResolvedLanguages.js +6 -11
- package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
- package/dist/highlighter/languages/constants.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedLanguages.d.ts +1 -1
- package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
- package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
- package/dist/highlighter/languages/resolveLanguage.js +19 -16
- package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
- package/dist/highlighter/languages/resolveLanguages.d.ts +1 -1
- package/dist/highlighter/shared_highlighter.d.ts +23 -9
- package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
- package/dist/highlighter/shared_highlighter.js +59 -47
- package/dist/highlighter/shared_highlighter.js.map +1 -1
- package/dist/highlighter/shiki-editor.d.ts +25 -0
- package/dist/highlighter/shiki-editor.d.ts.map +1 -0
- package/dist/highlighter/shiki-editor.js +483 -0
- package/dist/highlighter/shiki-editor.js.map +1 -0
- package/dist/highlighter/shiki-stream.d.ts +20 -0
- package/dist/highlighter/shiki-stream.d.ts.map +1 -0
- package/dist/highlighter/shiki-stream.js +60 -0
- package/dist/highlighter/shiki-stream.js.map +1 -0
- package/dist/highlighter/stream-tokenizer.d.ts +40 -0
- package/dist/highlighter/stream-tokenizer.d.ts.map +1 -0
- package/dist/highlighter/stream-tokenizer.js +70 -0
- package/dist/highlighter/stream-tokenizer.js.map +1 -0
- package/dist/highlighter/themes/areThemesAttached.d.ts +3 -2
- package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
- package/dist/highlighter/themes/areThemesAttached.js +5 -4
- package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.d.ts +5 -2
- package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/attachResolvedThemes.js +4 -16
- package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts +3 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/cleanUpResolvedThemes.js +8 -5
- package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts +7 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.d.ts.map +1 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js +89 -0
- package/dist/highlighter/themes/createCSSVariablesTheme.js.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts +5 -0
- package/dist/highlighter/themes/createCachedLoader.d.ts.map +1 -0
- package/dist/highlighter/themes/createCachedLoader.js +15 -0
- package/dist/highlighter/themes/createCachedLoader.js.map +1 -0
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js +4 -4
- package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.d.ts +3 -2
- package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/getResolvedThemes.js +4 -3
- package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.d.ts +2 -2
- package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/hasResolvedThemes.js +4 -3
- package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +3 -3
- package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.d.ts +9 -4
- package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/registerCustomTheme.js +8 -16
- package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveTheme.d.ts +3 -2
- package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveTheme.js +4 -7
- package/dist/highlighter/themes/resolveTheme.js.map +1 -1
- package/dist/highlighter/themes/resolveThemes.d.ts +3 -2
- package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
- package/dist/highlighter/themes/resolveThemes.js +4 -7
- package/dist/highlighter/themes/resolveThemes.js.map +1 -1
- package/dist/highlighter/themes/themeResolver.d.ts +10 -4
- package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
- package/dist/highlighter/themes/themeResolver.js +141 -2
- package/dist/highlighter/themes/themeResolver.js.map +1 -1
- package/dist/highlighter/themes/types.d.ts +23 -0
- package/dist/highlighter/themes/types.d.ts.map +1 -0
- package/dist/highlighter/themes/types.js +0 -0
- package/dist/highlighter/tokenizer-types.d.ts +35 -0
- package/dist/highlighter/tokenizer-types.d.ts.map +1 -0
- package/dist/highlighter/tokenizer-types.js +0 -0
- package/dist/highlighter/types.d.ts +55 -0
- package/dist/highlighter/types.d.ts.map +1 -0
- package/dist/highlighter/types.js +0 -0
- package/dist/index.d.ts +14 -10
- package/dist/index.js +16 -18
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +2 -2
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +9 -1
- package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -1
- package/dist/react/CodeView.js +1 -1
- package/dist/react/index.d.ts +8 -3
- package/dist/renderers/DiffHunksRenderer.d.ts +2 -1
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +31 -22
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +2 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +33 -24
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/shiki-stream/index.d.ts +3 -3
- package/dist/shiki-stream/index.js +1 -2
- package/dist/shiki-stream/stream.d.ts +4 -4
- package/dist/shiki-stream/stream.d.ts.map +1 -1
- package/dist/shiki-stream/stream.js +20 -9
- package/dist/shiki-stream/stream.js.map +1 -1
- package/dist/shiki-stream/types.d.ts +7 -38
- package/dist/shiki-stream/types.d.ts.map +1 -1
- package/dist/ssr/FileDiffReact.js +1 -1
- package/dist/ssr/index.d.ts +7 -2
- package/dist/ssr/renderHTML.js +2 -2
- package/dist/ssr/renderHTML.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +10 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/createSpanNodeFromToken.d.ts +3 -2
- package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
- package/dist/utils/createSpanNodeFromToken.js +4 -5
- package/dist/utils/createSpanNodeFromToken.js.map +1 -1
- package/dist/utils/cssWrappers.d.ts.map +1 -1
- package/dist/utils/cssWrappers.js +12 -0
- package/dist/utils/cssWrappers.js.map +1 -1
- package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
- package/dist/utils/getHighlighterOptions.js +3 -2
- package/dist/utils/getHighlighterOptions.js.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts +2 -1
- package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
- package/dist/utils/getHighlighterThemeStyles.js +13 -3
- package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
- package/dist/utils/getTokenOptions.d.ts +7 -0
- package/dist/utils/getTokenOptions.d.ts.map +1 -0
- package/dist/utils/getTokenOptions.js +16 -0
- package/dist/utils/getTokenOptions.js.map +1 -0
- package/dist/utils/hastToHtml.d.ts +10 -0
- package/dist/utils/hastToHtml.d.ts.map +1 -0
- package/dist/utils/hastToHtml.js +125 -0
- package/dist/utils/hastToHtml.js.map +1 -0
- package/dist/utils/parseDiffDecorations.d.ts +2 -1
- package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.d.ts +3 -2
- package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +33 -48
- package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts +3 -2
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +10 -26
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/renderTokenLines.d.ts +17 -0
- package/dist/utils/renderTokenLines.d.ts.map +1 -0
- package/dist/utils/renderTokenLines.js +246 -0
- package/dist/utils/renderTokenLines.js.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts +13 -0
- package/dist/utils/resolvePreferredHighlighter.d.ts.map +1 -0
- package/dist/utils/resolvePreferredHighlighter.js +11 -0
- package/dist/utils/resolvePreferredHighlighter.js.map +1 -0
- package/dist/utils/setDeferredArrayItem.d.ts +5 -0
- package/dist/utils/setDeferredArrayItem.d.ts.map +1 -0
- package/dist/utils/setDeferredArrayItem.js +39 -0
- package/dist/utils/setDeferredArrayItem.js.map +1 -0
- package/dist/utils/tokenStyle.d.ts +7 -0
- package/dist/utils/tokenStyle.d.ts.map +1 -0
- package/dist/utils/tokenStyle.js +28 -0
- package/dist/utils/tokenStyle.js.map +1 -0
- package/dist/utils/tokensToHtml.d.ts +8 -0
- package/dist/utils/tokensToHtml.d.ts.map +1 -0
- package/dist/utils/tokensToHtml.js +45 -0
- package/dist/utils/tokensToHtml.js.map +1 -0
- package/dist/utils/wrapTokenFragments.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +2 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +56 -46
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/hastLinesTransport.d.ts +14 -0
- package/dist/worker/hastLinesTransport.d.ts.map +1 -0
- package/dist/worker/hastLinesTransport.js +156 -0
- package/dist/worker/hastLinesTransport.js.map +1 -0
- package/dist/worker/highlights-sAHlxqlf.js +317 -0
- package/dist/worker/highlights-sAHlxqlf.js.map +1 -0
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/shiki-Bx2JpdqZ.js +697 -0
- package/dist/worker/shiki-Bx2JpdqZ.js.map +1 -0
- package/dist/worker/stream-tokenizer-YZ6M1qSx.js +424 -0
- package/dist/worker/stream-tokenizer-YZ6M1qSx.js.map +1 -0
- package/dist/worker/types.d.ts +5 -3
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +41 -13337
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +672 -349
- package/dist/worker/worker.js.map +1 -1
- package/dist/worker/workerMessage.d.ts +24 -0
- package/dist/worker/workerMessage.d.ts.map +1 -0
- package/dist/worker/workerMessage.js +0 -0
- package/package.json +33 -29
- package/dist/highlighter/themes/constants.d.ts +0 -5
- package/dist/highlighter/themes/constants.d.ts.map +0 -1
- package/dist/highlighter/themes/constants.js +0 -6
- package/dist/highlighter/themes/constants.js.map +0 -1
- package/dist/highlighter/themes/themeResolution.d.ts +0 -7
- package/dist/highlighter/themes/themeResolution.d.ts.map +0 -1
- package/dist/highlighter/themes/themeResolution.js +0 -21
- package/dist/highlighter/themes/themeResolution.js.map +0 -1
- package/dist/shiki-stream/tokenizer.d.ts +0 -23
- package/dist/shiki-stream/tokenizer.d.ts.map +0 -1
- package/dist/shiki-stream/tokenizer.js +0 -72
- package/dist/shiki-stream/tokenizer.js.map +0 -1
- package/dist/utils/createTransformerWithState.d.ts +0 -12
- package/dist/utils/createTransformerWithState.d.ts.map +0 -1
- package/dist/utils/createTransformerWithState.js +0 -89
- package/dist/utils/createTransformerWithState.js.map +0 -1
- package/dist/worker/wasm-B9ZqxnKj.js +0 -8
- package/dist/worker/wasm-B9ZqxnKj.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderFileWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderFileWithHighlighter.d.ts","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"mappings":";;;iBAmBgB,0BACd,MAAM,cACN,aAAa,oBACX,OAAO,uBAAuB,uBAAuB,qBAErD,gBACA,aACA,cACA,YACA,UACC,4BACF"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { linesFromFileContents } from "./computeFileOffsets.js";
|
|
2
2
|
import { getFiletypeFromFileName } from "./getFiletypeFromFileName.js";
|
|
3
3
|
import { appendItems } from "./appendItems.js";
|
|
4
|
-
import { createTransformerWithState } from "./createTransformerWithState.js";
|
|
5
|
-
import { formatCSSVariablePrefix } from "./formatCSSVariablePrefix.js";
|
|
6
4
|
import { getHighlighterThemeStyles } from "./getHighlighterThemeStyles.js";
|
|
7
|
-
import {
|
|
5
|
+
import { getTokenOptions } from "./getTokenOptions.js";
|
|
6
|
+
import { renderTokenLines } from "./renderTokenLines.js";
|
|
8
7
|
//#region src/utils/renderFileWithHighlighter.ts
|
|
9
8
|
const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
|
|
10
|
-
function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }, { forcePlainText, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
9
|
+
function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLength, useTokenTransformer }, { forcePlainText, lazyLineAST = false, startingLine, totalLines, lines } = DEFAULT_PLAIN_TEXT_OPTIONS) {
|
|
11
10
|
if (forcePlainText) {
|
|
12
11
|
startingLine ??= 0;
|
|
13
12
|
totalLines ??= Infinity;
|
|
@@ -16,7 +15,7 @@ function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLe
|
|
|
16
15
|
totalLines = Infinity;
|
|
17
16
|
}
|
|
18
17
|
const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
|
|
19
|
-
const {
|
|
18
|
+
const state = { lineInfo: [] };
|
|
20
19
|
const lang = forcePlainText ? "text" : file.lang ?? getFiletypeFromFileName(file.name);
|
|
21
20
|
const baseThemeType = typeof theme === "string" ? highlighter.getTheme(theme).type : void 0;
|
|
22
21
|
const themeStyles = getHighlighterThemeStyles({
|
|
@@ -28,27 +27,12 @@ function renderFileWithHighlighter(file, highlighter, { theme, tokenizeMaxLineLe
|
|
|
28
27
|
lineIndex: shikiLineNumber - 1 + startingLine,
|
|
29
28
|
lineNumber: shikiLineNumber + startingLine
|
|
30
29
|
});
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
38
|
-
tokenizeMaxLineLength,
|
|
39
|
-
tokenizeTimeLimit: 0
|
|
40
|
-
};
|
|
41
|
-
return {
|
|
42
|
-
lang,
|
|
43
|
-
themes: theme,
|
|
44
|
-
transformers,
|
|
45
|
-
defaultColor: false,
|
|
46
|
-
cssVariablePrefix: formatCSSVariablePrefix("token"),
|
|
47
|
-
tokenizeMaxLineLength,
|
|
48
|
-
tokenizeTimeLimit: 0
|
|
49
|
-
};
|
|
50
|
-
})();
|
|
51
|
-
const highlightedLines = getLineNodes(highlighter.codeToHast(normalizeHighlightLineEndings(isWindowedHighlight ? extractWindowedFileContent(lines ?? linesFromFileContents(file.contents), startingLine, totalLines) : file.contents), hastConfig));
|
|
30
|
+
const highlightedLines = renderTokenLines(highlighter.codeToTokens(normalizeHighlightLineEndings(isWindowedHighlight ? extractWindowedFileContent(lines ?? linesFromFileContents(file.contents), startingLine, totalLines) : file.contents), getTokenOptions(lang, theme, tokenizeMaxLineLength)).tokens, {
|
|
31
|
+
state,
|
|
32
|
+
useTokenTransformer,
|
|
33
|
+
lazyLineAST: lazyLineAST && !forcePlainText && !useTokenTransformer,
|
|
34
|
+
cacheHtmlStyles: highlighter.name === "highlights"
|
|
35
|
+
});
|
|
52
36
|
const code = isWindowedHighlight ? new Array(startingLine) : highlightedLines;
|
|
53
37
|
if (isWindowedHighlight) appendItems(code, highlightedLines);
|
|
54
38
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderFileWithHighlighter.js","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"sourcesContent":["import type {\n
|
|
1
|
+
{"version":3,"file":"renderFileWithHighlighter.js","names":[],"sources":["../../src/utils/renderFileWithHighlighter.ts"],"sourcesContent":["import type {\n DiffsHighlighter,\n FileContents,\n ForceFilePlainTextOptions,\n RenderFileOptions,\n SharedRenderState,\n ThemedFileResult,\n} from '../types';\nimport { appendItems } from './appendItems';\nimport { linesFromFileContents } from './computeFileOffsets';\nimport { getFiletypeFromFileName } from './getFiletypeFromFileName';\nimport { getHighlighterThemeStyles } from './getHighlighterThemeStyles';\nimport { getTokenOptions } from './getTokenOptions';\nimport { renderTokenLines } from './renderTokenLines';\n\nconst DEFAULT_PLAIN_TEXT_OPTIONS: ForceFilePlainTextOptions = {\n forcePlainText: false,\n};\n\nexport function renderFileWithHighlighter(\n file: FileContents,\n highlighter: DiffsHighlighter,\n { theme, tokenizeMaxLineLength, useTokenTransformer }: RenderFileOptions,\n {\n forcePlainText,\n lazyLineAST = false,\n startingLine,\n totalLines,\n lines,\n }: ForceFilePlainTextOptions = DEFAULT_PLAIN_TEXT_OPTIONS\n): ThemedFileResult {\n if (forcePlainText) {\n startingLine ??= 0;\n totalLines ??= Infinity;\n } else {\n // Tokenization must include preceding lines to preserve lexical state.\n startingLine = 0;\n totalLines = Infinity;\n }\n const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;\n const state: SharedRenderState = { lineInfo: [] };\n const lang = forcePlainText\n ? 'text'\n : (file.lang ?? getFiletypeFromFileName(file.name));\n const baseThemeType =\n typeof theme === 'string' ? highlighter.getTheme(theme).type : undefined;\n const themeStyles = getHighlighterThemeStyles({\n theme,\n highlighter,\n });\n state.lineInfo = (shikiLineNumber: number) => ({\n type: 'context',\n lineIndex: shikiLineNumber - 1 + startingLine,\n lineNumber: shikiLineNumber + startingLine,\n });\n const highlightedLines = renderTokenLines(\n highlighter.codeToTokens(\n normalizeHighlightLineEndings(\n isWindowedHighlight\n ? extractWindowedFileContent(\n lines ?? linesFromFileContents(file.contents),\n startingLine,\n totalLines\n )\n : file.contents\n ),\n getTokenOptions(lang, theme, tokenizeMaxLineLength)\n ).tokens,\n {\n state,\n useTokenTransformer,\n lazyLineAST: lazyLineAST && !forcePlainText && !useTokenTransformer,\n cacheHtmlStyles: highlighter.name === 'highlights',\n }\n );\n\n // Create sparse array for windowed rendering\n const code = isWindowedHighlight ? new Array(startingLine) : highlightedLines;\n if (isWindowedHighlight) {\n appendItems(code, highlightedLines);\n }\n\n return { code, themeStyles, baseThemeType };\n}\n\n// Shiki does not treat a lone carriage return as a line break. Normalize only\n// the text sent to the highlighter so its output stays aligned with the file\n// model while the original document retains its line endings.\nfunction normalizeHighlightLineEndings(contents: string): string {\n return contents.replace(/\\r(?!\\n)/g, '\\n');\n}\n\nfunction extractWindowedFileContent(\n lines: string[],\n startingLine: number,\n totalLines: number\n): string {\n if (lines.length === 0) {\n return '';\n }\n const endLine = Math.min(startingLine + totalLines, lines.length);\n return lines.slice(startingLine, endLine).join('');\n}\n"],"mappings":";;;;;;;AAeA,MAAM,6BAAwD,EAC5D,gBAAgB,MAClB;AAEA,SAAgB,0BACd,MACA,aACA,EAAE,OAAO,uBAAuB,uBAChC,EACE,gBACA,cAAc,OACd,cACA,YACA,UAC6B,4BACb;CAClB,IAAI,gBAAgB;EAClB,iBAAiB;EACjB,eAAe;CACjB,OAAO;EAEL,eAAe;EACf,aAAa;CACf;CACA,MAAM,sBAAsB,eAAe,KAAK,aAAa;CAC7D,MAAM,QAA2B,EAAE,UAAU,CAAC,EAAE;CAChD,MAAM,OAAO,iBACT,SACC,KAAK,QAAQ,wBAAwB,KAAK,IAAI;CACnD,MAAM,gBACJ,OAAO,UAAU,WAAW,YAAY,SAAS,KAAK,CAAC,CAAC,OAAO,KAAA;CACjE,MAAM,cAAc,0BAA0B;EAC5C;EACA;CACF,CAAC;CACD,MAAM,YAAY,qBAA6B;EAC7C,MAAM;EACN,WAAW,kBAAkB,IAAI;EACjC,YAAY,kBAAkB;CAChC;CACA,MAAM,mBAAmB,iBACvB,YAAY,aACV,8BACE,sBACI,2BACE,SAAS,sBAAsB,KAAK,QAAQ,GAC5C,cACA,UACF,IACA,KAAK,QACX,GACA,gBAAgB,MAAM,OAAO,qBAAqB,CACpD,CAAC,CAAC,QACF;EACE;EACA;EACA,aAAa,eAAe,CAAC,kBAAkB,CAAC;EAChD,iBAAiB,YAAY,SAAS;CACxC,CACF;CAGA,MAAM,OAAO,sBAAsB,IAAI,MAAM,YAAY,IAAI;CAC7D,IAAI,qBACF,YAAY,MAAM,gBAAgB;CAGpC,OAAO;EAAE;EAAM;EAAa;CAAc;AAC5C;AAKA,SAAS,8BAA8B,UAA0B;CAC/D,OAAO,SAAS,QAAQ,aAAa,IAAI;AAC3C;AAEA,SAAS,2BACP,OACA,cACA,YACQ;CACR,IAAI,MAAM,WAAW,GACnB,OAAO;CAET,MAAM,UAAU,KAAK,IAAI,eAAe,YAAY,MAAM,MAAM;CAChE,OAAO,MAAM,MAAM,cAAc,OAAO,CAAC,CAAC,KAAK,EAAE;AACnD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ElementContent } from "../node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.js";
|
|
2
|
+
import { DecorationItem, ThemedToken } from "../highlighter/types.js";
|
|
3
|
+
import { SharedRenderState } from "../types.js";
|
|
4
|
+
//#region src/utils/renderTokenLines.d.ts
|
|
5
|
+
interface RenderTokenLinesOptions {
|
|
6
|
+
lazyLineAST?: boolean;
|
|
7
|
+
cacheHtmlStyles?: boolean;
|
|
8
|
+
state?: SharedRenderState;
|
|
9
|
+
useTokenTransformer?: boolean;
|
|
10
|
+
mergeWhitespaces?: 'never' | 'always';
|
|
11
|
+
decorations?: DecorationItem[];
|
|
12
|
+
lineOffsets?: number[];
|
|
13
|
+
}
|
|
14
|
+
declare function renderTokenLines(lines: ThemedToken[][], { state, lazyLineAST, cacheHtmlStyles, useTokenTransformer, mergeWhitespaces, decorations, lineOffsets }: RenderTokenLinesOptions): ElementContent[];
|
|
15
|
+
//#endregion
|
|
16
|
+
export { renderTokenLines };
|
|
17
|
+
//# sourceMappingURL=renderTokenLines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderTokenLines.d.ts","names":[],"sources":["../../src/utils/renderTokenLines.ts"],"mappings":";;;;UAQU;EACR;EACA;EACA,QAAQ;EACR;EACA;EACA,cAAc;EACd;;iBAsBc,iBACd,OAAO,mBAEL,OACA,aACA,iBACA,qBACA,kBACA,aACA,eACC,0BACF"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { processLine } from "./processLine.js";
|
|
2
|
+
import { setDeferredArrayItem } from "./setDeferredArrayItem.js";
|
|
3
|
+
import { tokenStyle } from "./tokenStyle.js";
|
|
4
|
+
import { wrapTokenFragments } from "./wrapTokenFragments.js";
|
|
5
|
+
//#region src/utils/renderTokenLines.ts
|
|
6
|
+
function renderTokenLines(lines, { state, lazyLineAST = false, cacheHtmlStyles = false, useTokenTransformer = false, mergeWhitespaces = "always", decorations = [], lineOffsets = [] }) {
|
|
7
|
+
let decorationsByLine;
|
|
8
|
+
for (const decoration of decorations) {
|
|
9
|
+
const byLine = decorationsByLine ??= /* @__PURE__ */ new Map();
|
|
10
|
+
const normalized = {
|
|
11
|
+
...decoration,
|
|
12
|
+
start: getDecorationPosition(decoration.start, lineOffsets),
|
|
13
|
+
end: getDecorationPosition(decoration.end, lineOffsets)
|
|
14
|
+
};
|
|
15
|
+
const lastLine = Math.min(normalized.end.line, lines.length - 1);
|
|
16
|
+
for (let line = normalized.start.line; line <= lastLine; line++) {
|
|
17
|
+
let spans = byLine.get(line);
|
|
18
|
+
if (spans == null) byLine.set(line, spans = []);
|
|
19
|
+
spans.push(normalized);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const renderLine = (tokens, lineIndex) => {
|
|
23
|
+
let normalized;
|
|
24
|
+
if (useTokenTransformer || mergeWhitespaces !== "never") {
|
|
25
|
+
let pendingWhitespace = "";
|
|
26
|
+
let whitespaceOffset = 0;
|
|
27
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
28
|
+
let token = tokens[i];
|
|
29
|
+
if (useTokenTransformer) {
|
|
30
|
+
const content = token.content.trim();
|
|
31
|
+
if (content !== "" && content !== token.content) {
|
|
32
|
+
normalized ??= tokens.slice(0, i);
|
|
33
|
+
const start = token.content.indexOf(content);
|
|
34
|
+
if (start > 0) normalized.push({
|
|
35
|
+
content: token.content.slice(0, start),
|
|
36
|
+
offset: token.offset
|
|
37
|
+
});
|
|
38
|
+
normalized.push({
|
|
39
|
+
...token,
|
|
40
|
+
content,
|
|
41
|
+
offset: token.offset + start
|
|
42
|
+
});
|
|
43
|
+
const end = start + content.length;
|
|
44
|
+
if (end < token.content.length) normalized.push({
|
|
45
|
+
content: token.content.slice(end),
|
|
46
|
+
offset: token.offset + end
|
|
47
|
+
});
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
const decoratedWhitespace = ((token.fontStyle ?? 0) & 12) !== 0;
|
|
52
|
+
if (!decoratedWhitespace && /^\s+$/.test(token.content) && i < tokens.length - 1) {
|
|
53
|
+
normalized ??= tokens.slice(0, i);
|
|
54
|
+
if (pendingWhitespace === "") whitespaceOffset = token.offset;
|
|
55
|
+
pendingWhitespace += token.content;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (pendingWhitespace !== "" && normalized != null) {
|
|
59
|
+
if (decoratedWhitespace) normalized.push({
|
|
60
|
+
content: pendingWhitespace,
|
|
61
|
+
offset: whitespaceOffset
|
|
62
|
+
});
|
|
63
|
+
else token = {
|
|
64
|
+
...token,
|
|
65
|
+
content: pendingWhitespace + token.content,
|
|
66
|
+
offset: whitespaceOffset
|
|
67
|
+
};
|
|
68
|
+
pendingWhitespace = "";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
normalized?.push(token);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
normalized ??= tokens;
|
|
75
|
+
const line = {
|
|
76
|
+
type: "element",
|
|
77
|
+
tagName: state == null ? "span" : "div",
|
|
78
|
+
properties: state == null ? { class: "line" } : {},
|
|
79
|
+
children: []
|
|
80
|
+
};
|
|
81
|
+
const spans = decorationsByLine?.get(lineIndex);
|
|
82
|
+
const column = spans == null ? appendTokens(line, normalized, useTokenTransformer, cacheHtmlStyles) : appendDecoratedTokens(line, normalized, spans, lineIndex, useTokenTransformer, cacheHtmlStyles);
|
|
83
|
+
if (useTokenTransformer && column === 0) line.children.push({
|
|
84
|
+
type: "element",
|
|
85
|
+
tagName: "br",
|
|
86
|
+
properties: {},
|
|
87
|
+
children: []
|
|
88
|
+
});
|
|
89
|
+
if (useTokenTransformer && spans != null) wrapTokenFragments(line);
|
|
90
|
+
return state == null ? line : processLine(line, lineIndex + 1, state);
|
|
91
|
+
};
|
|
92
|
+
if (!lazyLineAST) return lines.map(renderLine);
|
|
93
|
+
const rows = new Array(lines.length);
|
|
94
|
+
for (let index = 0; index < lines.length; index++) {
|
|
95
|
+
const tokens = lines[index];
|
|
96
|
+
setDeferredArrayItem(rows, index, () => renderLine(tokens, index));
|
|
97
|
+
}
|
|
98
|
+
return rows;
|
|
99
|
+
}
|
|
100
|
+
function appendTokens(line, tokens, useTokenTransformer, cacheHtmlStyles) {
|
|
101
|
+
let column = 0;
|
|
102
|
+
for (const token of tokens) {
|
|
103
|
+
if (token.content === "") continue;
|
|
104
|
+
line.children.push(createTokenSpan(token, tokenStyle(token, cacheHtmlStyles), token.content, column, useTokenTransformer));
|
|
105
|
+
column += token.content.length;
|
|
106
|
+
}
|
|
107
|
+
return column;
|
|
108
|
+
}
|
|
109
|
+
function appendDecoratedTokens(line, tokens, spans, lineIndex, useTokenTransformer, cacheHtmlStyles) {
|
|
110
|
+
if (spans.length > 1) spans.sort((a, b) => {
|
|
111
|
+
if (a.start.line !== b.start.line) return a.start.line - b.start.line;
|
|
112
|
+
if (a.start.character !== b.start.character) return a.start.character - b.start.character;
|
|
113
|
+
if (a.end.line !== b.end.line) return b.end.line - a.end.line;
|
|
114
|
+
return b.end.character - a.end.character;
|
|
115
|
+
});
|
|
116
|
+
const lineLength = tokens.reduce((length, token) => length + token.content.length, 0);
|
|
117
|
+
const boundaries = [];
|
|
118
|
+
for (let order = 0; order < spans.length; order++) {
|
|
119
|
+
const decoration = spans[order];
|
|
120
|
+
const range = {
|
|
121
|
+
decoration,
|
|
122
|
+
order,
|
|
123
|
+
from: decoration.start.line === lineIndex ? decoration.start.character : 0,
|
|
124
|
+
to: decoration.end.line === lineIndex ? decoration.end.character : lineLength
|
|
125
|
+
};
|
|
126
|
+
boundaries.push({
|
|
127
|
+
position: Math.max(0, Math.min(range.from, lineLength)),
|
|
128
|
+
range,
|
|
129
|
+
start: true
|
|
130
|
+
}, {
|
|
131
|
+
position: Math.max(0, Math.min(range.to, lineLength)),
|
|
132
|
+
range,
|
|
133
|
+
start: false
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
boundaries.sort((a, b) => a.position - b.position);
|
|
137
|
+
const active = [];
|
|
138
|
+
const decorationStack = [];
|
|
139
|
+
let boundaryIndex = 0;
|
|
140
|
+
const updateActive = (range, add) => {
|
|
141
|
+
let low = 0;
|
|
142
|
+
let high = active.length;
|
|
143
|
+
while (low < high) {
|
|
144
|
+
const middle = low + high >>> 1;
|
|
145
|
+
if (active[middle].order < range.order) low = middle + 1;
|
|
146
|
+
else high = middle;
|
|
147
|
+
}
|
|
148
|
+
if (add) active.splice(low, 0, range);
|
|
149
|
+
else if (active[low] === range) active.splice(low, 1);
|
|
150
|
+
};
|
|
151
|
+
const getParent = () => {
|
|
152
|
+
let parent = line;
|
|
153
|
+
let depth = 0;
|
|
154
|
+
for (const range of active) {
|
|
155
|
+
if (decorationStack[depth]?.range !== range) {
|
|
156
|
+
decorationStack.length = depth;
|
|
157
|
+
const wrapper = {
|
|
158
|
+
type: "element",
|
|
159
|
+
tagName: "span",
|
|
160
|
+
properties: { ...range.decoration.properties },
|
|
161
|
+
children: []
|
|
162
|
+
};
|
|
163
|
+
parent.children.push(wrapper);
|
|
164
|
+
decorationStack.push({
|
|
165
|
+
range,
|
|
166
|
+
node: wrapper
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
parent = decorationStack[depth++].node;
|
|
170
|
+
}
|
|
171
|
+
decorationStack.length = depth;
|
|
172
|
+
return parent;
|
|
173
|
+
};
|
|
174
|
+
let parent = line;
|
|
175
|
+
const advanceBoundary = (position) => {
|
|
176
|
+
const first = boundaryIndex;
|
|
177
|
+
while (boundaries[boundaryIndex]?.position === position) boundaryIndex++;
|
|
178
|
+
let hasMarker = false;
|
|
179
|
+
for (let i = first; i < boundaryIndex; i++) {
|
|
180
|
+
const { range, start } = boundaries[i];
|
|
181
|
+
if (!start && range.from !== range.to && position < lineLength) updateActive(range, false);
|
|
182
|
+
}
|
|
183
|
+
for (let i = first; i < boundaryIndex; i++) {
|
|
184
|
+
const { range, start } = boundaries[i];
|
|
185
|
+
if (start && range.from <= position && range.to >= position && (range.to > position || range.from === position || position === lineLength)) {
|
|
186
|
+
updateActive(range, true);
|
|
187
|
+
if (range.from === range.to) hasMarker = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (hasMarker) {
|
|
191
|
+
getParent();
|
|
192
|
+
for (let i = first; i < boundaryIndex; i++) {
|
|
193
|
+
const { range, start } = boundaries[i];
|
|
194
|
+
if (start && range.from === range.to) updateActive(range, false);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (position < lineLength) parent = getParent();
|
|
198
|
+
};
|
|
199
|
+
let column = 0;
|
|
200
|
+
for (const token of tokens) {
|
|
201
|
+
if (token.content === "") continue;
|
|
202
|
+
const start = column;
|
|
203
|
+
const end = start + token.content.length;
|
|
204
|
+
const style = tokenStyle(token, cacheHtmlStyles);
|
|
205
|
+
while (column < end) {
|
|
206
|
+
if (boundaries[boundaryIndex]?.position === column) advanceBoundary(column);
|
|
207
|
+
const to = Math.min(end, boundaries[boundaryIndex]?.position ?? end);
|
|
208
|
+
parent.children.push(createTokenSpan(token, style, column === start && to === end ? token.content : token.content.slice(column - start, to - start), start, useTokenTransformer));
|
|
209
|
+
column = to;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (boundaries[boundaryIndex]?.position === column) advanceBoundary(column);
|
|
213
|
+
return column;
|
|
214
|
+
}
|
|
215
|
+
function createTokenSpan(token, style, text, start, useTokenTransformer) {
|
|
216
|
+
const properties = token.htmlAttrs != null ? { ...token.htmlAttrs } : {};
|
|
217
|
+
if (style !== "") properties.style = style;
|
|
218
|
+
if (useTokenTransformer) properties["data-char"] = start;
|
|
219
|
+
return {
|
|
220
|
+
type: "element",
|
|
221
|
+
tagName: "span",
|
|
222
|
+
properties,
|
|
223
|
+
children: [{
|
|
224
|
+
type: "text",
|
|
225
|
+
value: text
|
|
226
|
+
}]
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function getDecorationPosition(position, lineOffsets) {
|
|
230
|
+
if (typeof position !== "number") return position;
|
|
231
|
+
let low = 0;
|
|
232
|
+
let high = lineOffsets.length;
|
|
233
|
+
while (low + 1 < high) {
|
|
234
|
+
const middle = low + high >>> 1;
|
|
235
|
+
if (lineOffsets[middle] <= position) low = middle;
|
|
236
|
+
else high = middle;
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
line: low,
|
|
240
|
+
character: position - (lineOffsets[low] ?? 0)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
export { renderTokenLines };
|
|
245
|
+
|
|
246
|
+
//# sourceMappingURL=renderTokenLines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderTokenLines.js","names":[],"sources":["../../src/utils/renderTokenLines.ts"],"sourcesContent":["import type { Element, ElementContent, Properties } from 'hast';\n\nimport type { DecorationItem, SharedRenderState, ThemedToken } from '../types';\nimport { processLine } from './processLine';\nimport { setDeferredArrayItem } from './setDeferredArrayItem';\nimport { tokenStyle } from './tokenStyle';\nimport { wrapTokenFragments } from './wrapTokenFragments';\n\ninterface RenderTokenLinesOptions {\n lazyLineAST?: boolean;\n cacheHtmlStyles?: boolean;\n state?: SharedRenderState;\n useTokenTransformer?: boolean;\n mergeWhitespaces?: 'never' | 'always';\n decorations?: DecorationItem[];\n lineOffsets?: number[];\n}\n\ninterface LineDecoration extends Omit<DecorationItem, 'start' | 'end'> {\n start: { line: number; character: number };\n end: { line: number; character: number };\n}\n\n// from/to are columns within this line; order preserves outer-to-inner nesting.\ninterface LineDecorationRange {\n decoration: LineDecoration;\n order: number;\n from: number;\n to: number;\n}\n\ninterface DecorationBoundary {\n position: number;\n range: LineDecorationRange;\n start: boolean;\n}\n\nexport function renderTokenLines(\n lines: ThemedToken[][],\n {\n state,\n lazyLineAST = false,\n cacheHtmlStyles = false,\n useTokenTransformer = false,\n mergeWhitespaces = 'always',\n decorations = [],\n lineOffsets = [],\n }: RenderTokenLinesOptions\n): ElementContent[] {\n let decorationsByLine: Map<number, LineDecoration[]> | undefined;\n for (const decoration of decorations) {\n const byLine = (decorationsByLine ??= new Map());\n const normalized: LineDecoration = {\n ...decoration,\n start: getDecorationPosition(decoration.start, lineOffsets),\n end: getDecorationPosition(decoration.end, lineOffsets),\n };\n const lastLine = Math.min(normalized.end.line, lines.length - 1);\n for (let line = normalized.start.line; line <= lastLine; line++) {\n let spans = byLine.get(line);\n if (spans == null) byLine.set(line, (spans = []));\n spans.push(normalized);\n }\n }\n const renderLine = (tokens: ThemedToken[], lineIndex: number) => {\n let normalized: ThemedToken[] | undefined;\n if (useTokenTransformer || mergeWhitespaces !== 'never') {\n let pendingWhitespace = '';\n let whitespaceOffset = 0;\n for (let i = 0; i < tokens.length; i++) {\n let token = tokens[i];\n if (useTokenTransformer) {\n const content = token.content.trim();\n if (content !== '' && content !== token.content) {\n normalized ??= tokens.slice(0, i);\n const start = token.content.indexOf(content);\n if (start > 0)\n normalized.push({\n content: token.content.slice(0, start),\n offset: token.offset,\n });\n normalized.push({\n ...token,\n content,\n offset: token.offset + start,\n });\n const end = start + content.length;\n if (end < token.content.length)\n normalized.push({\n content: token.content.slice(end),\n offset: token.offset + end,\n });\n continue;\n }\n } else {\n const decoratedWhitespace = ((token.fontStyle ?? 0) & 12) !== 0;\n if (\n !decoratedWhitespace &&\n /^\\s+$/.test(token.content) &&\n i < tokens.length - 1\n ) {\n normalized ??= tokens.slice(0, i);\n if (pendingWhitespace === '') whitespaceOffset = token.offset;\n pendingWhitespace += token.content;\n continue;\n }\n if (pendingWhitespace !== '' && normalized != null) {\n if (decoratedWhitespace)\n normalized.push({\n content: pendingWhitespace,\n offset: whitespaceOffset,\n });\n else\n token = {\n ...token,\n content: pendingWhitespace + token.content,\n offset: whitespaceOffset,\n };\n pendingWhitespace = '';\n }\n }\n normalized?.push(token);\n }\n }\n normalized ??= tokens;\n const line: Element = {\n type: 'element',\n tagName: state == null ? 'span' : 'div',\n properties: state == null ? { class: 'line' } : {},\n children: [],\n };\n const spans = decorationsByLine?.get(lineIndex);\n const column =\n spans == null\n ? appendTokens(line, normalized, useTokenTransformer, cacheHtmlStyles)\n : appendDecoratedTokens(\n line,\n normalized,\n spans,\n lineIndex,\n useTokenTransformer,\n cacheHtmlStyles\n );\n if (useTokenTransformer && column === 0) {\n line.children.push({\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n });\n }\n // Undecorated tokens already have one span per editor position.\n if (useTokenTransformer && spans != null) wrapTokenFragments(line);\n return state == null ? line : processLine(line, lineIndex + 1, state);\n };\n if (!lazyLineAST) return lines.map(renderLine);\n const rows: ElementContent[] = new Array(lines.length);\n for (let index = 0; index < lines.length; index++) {\n // Warning: capture one line, not `lines`; unbuilt rows would keep every\n // line's tokens alive.\n const tokens = lines[index];\n setDeferredArrayItem(rows, index, () => renderLine(tokens, index));\n }\n return rows;\n}\n\n// Returns the line length in UTF-16 code units.\nfunction appendTokens(\n line: Element,\n tokens: ThemedToken[],\n useTokenTransformer: boolean,\n cacheHtmlStyles: boolean\n): number {\n let column = 0;\n for (const token of tokens) {\n if (token.content === '') continue;\n line.children.push(\n createTokenSpan(\n token,\n tokenStyle(token, cacheHtmlStyles),\n token.content,\n column,\n useTokenTransformer\n )\n );\n column += token.content.length;\n }\n return column;\n}\n\n// Visit sorted boundaries once to avoid scanning every decoration per token.\n// Emit empty ranges before text at the same position.\nfunction appendDecoratedTokens(\n line: Element,\n tokens: ThemedToken[],\n spans: LineDecoration[],\n lineIndex: number,\n useTokenTransformer: boolean,\n cacheHtmlStyles: boolean\n): number {\n // Open outer ranges first, regardless of their order in the input.\n if (spans.length > 1)\n spans.sort((a, b) => {\n if (a.start.line !== b.start.line) return a.start.line - b.start.line;\n if (a.start.character !== b.start.character)\n return a.start.character - b.start.character;\n if (a.end.line !== b.end.line) return b.end.line - a.end.line;\n return b.end.character - a.end.character;\n });\n const lineLength = tokens.reduce(\n (length, token) => length + token.content.length,\n 0\n );\n const boundaries: DecorationBoundary[] = [];\n for (let order = 0; order < spans.length; order++) {\n const decoration = spans[order];\n const range: LineDecorationRange = {\n decoration,\n order,\n from:\n decoration.start.line === lineIndex ? decoration.start.character : 0,\n to:\n decoration.end.line === lineIndex\n ? decoration.end.character\n : lineLength,\n };\n boundaries.push(\n {\n position: Math.max(0, Math.min(range.from, lineLength)),\n range,\n start: true,\n },\n {\n position: Math.max(0, Math.min(range.to, lineLength)),\n range,\n start: false,\n }\n );\n }\n boundaries.sort((a, b) => a.position - b.position);\n const active: LineDecorationRange[] = [];\n const decorationStack: { range: LineDecorationRange; node: Element }[] = [];\n let boundaryIndex = 0;\n\n // Keep the same outer-to-inner order even when decorations cross each other.\n const updateActive = (range: LineDecorationRange, add: boolean): void => {\n let low = 0;\n let high = active.length;\n while (low < high) {\n const middle = (low + high) >>> 1;\n if (active[middle].order < range.order) low = middle + 1;\n else high = middle;\n }\n if (add) active.splice(low, 0, range);\n else if (active[low] === range) active.splice(low, 1);\n };\n\n // Reuse wrappers across tokens so a continuous range stays in one element.\n const getParent = (): Element => {\n let parent = line;\n let depth = 0;\n for (const range of active) {\n if (decorationStack[depth]?.range !== range) {\n decorationStack.length = depth;\n const wrapper: Element = {\n type: 'element',\n tagName: 'span',\n properties: { ...range.decoration.properties },\n children: [],\n };\n parent.children.push(wrapper);\n decorationStack.push({ range, node: wrapper });\n }\n parent = decorationStack[depth++].node;\n }\n decorationStack.length = depth;\n return parent;\n };\n\n let parent = line;\n\n // Markers belong inside ranges starting here, except at the line end,\n // where they belong inside ranges ending here.\n const advanceBoundary = (position: number): void => {\n const first = boundaryIndex;\n while (boundaries[boundaryIndex]?.position === position) boundaryIndex++;\n let hasMarker = false;\n for (let i = first; i < boundaryIndex; i++) {\n const { range, start } = boundaries[i];\n if (!start && range.from !== range.to && position < lineLength)\n updateActive(range, false);\n }\n for (let i = first; i < boundaryIndex; i++) {\n const { range, start } = boundaries[i];\n if (\n start &&\n range.from <= position &&\n range.to >= position &&\n (range.to > position ||\n range.from === position ||\n position === lineLength)\n ) {\n updateActive(range, true);\n if (range.from === range.to) hasMarker = true;\n }\n }\n if (hasMarker) {\n getParent();\n for (let i = first; i < boundaryIndex; i++) {\n const { range, start } = boundaries[i];\n if (start && range.from === range.to) updateActive(range, false);\n }\n }\n if (position < lineLength) parent = getParent();\n };\n\n let column = 0;\n for (const token of tokens) {\n if (token.content === '') continue;\n const start = column;\n const end = start + token.content.length;\n const style = tokenStyle(token, cacheHtmlStyles);\n while (column < end) {\n if (boundaries[boundaryIndex]?.position === column)\n advanceBoundary(column);\n const to = Math.min(end, boundaries[boundaryIndex]?.position ?? end);\n parent.children.push(\n createTokenSpan(\n token,\n style,\n column === start && to === end\n ? token.content\n : token.content.slice(column - start, to - start),\n start,\n useTokenTransformer\n )\n );\n column = to;\n }\n }\n if (boundaries[boundaryIndex]?.position === column) advanceBoundary(column);\n return column;\n}\n\n// data-char must retain the original token column when decorations split it.\nfunction createTokenSpan(\n token: ThemedToken,\n style: string,\n text: string,\n start: number,\n useTokenTransformer: boolean\n): Element {\n const properties: Properties =\n token.htmlAttrs != null ? { ...token.htmlAttrs } : {};\n if (style !== '') properties.style = style;\n if (useTokenTransformer) properties['data-char'] = start;\n return {\n type: 'element',\n tagName: 'span',\n properties,\n children: [{ type: 'text', value: text }],\n };\n}\n\n// Convert absolute UTF-16 offsets to the line coordinates used by decorations.\nfunction getDecorationPosition(\n position: DecorationItem['start'],\n lineOffsets: number[]\n): { line: number; character: number } {\n if (typeof position !== 'number') return position;\n let low = 0;\n let high = lineOffsets.length;\n while (low + 1 < high) {\n const middle = (low + high) >>> 1;\n if (lineOffsets[middle] <= position) low = middle;\n else high = middle;\n }\n return { line: low, character: position - (lineOffsets[low] ?? 0) };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HighlighterTypes } from "../types.js";
|
|
2
|
+
//#region src/utils/resolvePreferredHighlighter.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Undefined lets the caller use the active type or the default.
|
|
5
|
+
*/
|
|
6
|
+
declare function resolvePreferredHighlighter(workerManager: {
|
|
7
|
+
getPreferredHighlighter(): HighlighterTypes;
|
|
8
|
+
} | undefined, options: {
|
|
9
|
+
preferredHighlighter?: HighlighterTypes | undefined;
|
|
10
|
+
}): HighlighterTypes | undefined;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { resolvePreferredHighlighter };
|
|
13
|
+
//# sourceMappingURL=resolvePreferredHighlighter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvePreferredHighlighter.d.ts","names":[],"sources":["../../src/utils/resolvePreferredHighlighter.ts"],"mappings":";;;;;iBAKgB,4BACd;EAAiB,2BAA2B;eAC5C;EAAW,uBAAuB;IACjC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/utils/resolvePreferredHighlighter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Undefined lets the caller use the active type or the default.
|
|
4
|
+
*/
|
|
5
|
+
function resolvePreferredHighlighter(workerManager, options) {
|
|
6
|
+
return workerManager?.getPreferredHighlighter() ?? options.preferredHighlighter;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { resolvePreferredHighlighter };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=resolvePreferredHighlighter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvePreferredHighlighter.js","names":[],"sources":["../../src/utils/resolvePreferredHighlighter.ts"],"sourcesContent":["import type { HighlighterTypes } from '../types';\n\n/**\n * Undefined lets the caller use the active type or the default.\n */\nexport function resolvePreferredHighlighter(\n workerManager: { getPreferredHighlighter(): HighlighterTypes } | undefined,\n options: { preferredHighlighter?: HighlighterTypes | undefined }\n): HighlighterTypes | undefined {\n return (\n workerManager?.getPreferredHighlighter() ?? options.preferredHighlighter\n );\n}\n"],"mappings":";;;;AAKA,SAAgB,4BACd,eACA,SAC8B;CAC9B,OACE,eAAe,wBAAwB,KAAK,QAAQ;AAExD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setDeferredArrayItem.d.ts","names":[],"sources":["../../src/utils/setDeferredArrayItem.ts"],"mappings":";iBAAgB,qBAAqB,GACnC,OAAO,KACP,eACA,cAAc"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/utils/setDeferredArrayItem.ts
|
|
2
|
+
function setDeferredArrayItem(array, index, create) {
|
|
3
|
+
let initialized = false;
|
|
4
|
+
let cached;
|
|
5
|
+
Object.defineProperty(array, index, {
|
|
6
|
+
configurable: true,
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get() {
|
|
9
|
+
if (!initialized) {
|
|
10
|
+
cached = create();
|
|
11
|
+
initialized = true;
|
|
12
|
+
}
|
|
13
|
+
if (Object.getOwnPropertyDescriptor(array, index)?.configurable === true) Object.defineProperty(array, index, {
|
|
14
|
+
configurable: true,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: cached
|
|
18
|
+
});
|
|
19
|
+
return cached;
|
|
20
|
+
},
|
|
21
|
+
set(value) {
|
|
22
|
+
if (Object.getOwnPropertyDescriptor(array, index)?.configurable === true) Object.defineProperty(array, index, {
|
|
23
|
+
configurable: true,
|
|
24
|
+
enumerable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value
|
|
27
|
+
});
|
|
28
|
+
else if (Object.isFrozen(array)) throw new TypeError(`Cannot assign to read only array index '${index}'`);
|
|
29
|
+
else {
|
|
30
|
+
cached = value;
|
|
31
|
+
initialized = true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { setDeferredArrayItem };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=setDeferredArrayItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setDeferredArrayItem.js","names":[],"sources":["../../src/utils/setDeferredArrayItem.ts"],"sourcesContent":["export function setDeferredArrayItem<T>(\n array: T[],\n index: number,\n create: () => T\n): void {\n let initialized = false;\n let cached: T;\n Object.defineProperty(array, index, {\n configurable: true,\n enumerable: true,\n get() {\n if (!initialized) {\n cached = create();\n initialized = true;\n }\n if (\n Object.getOwnPropertyDescriptor(array, index)?.configurable === true\n ) {\n Object.defineProperty(array, index, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: cached,\n });\n }\n return cached;\n },\n set(value: T) {\n if (\n Object.getOwnPropertyDescriptor(array, index)?.configurable === true\n ) {\n Object.defineProperty(array, index, {\n configurable: true,\n enumerable: true,\n writable: true,\n value,\n });\n } else if (Object.isFrozen(array)) {\n throw new TypeError(\n `Cannot assign to read only array index '${index}'`\n );\n } else {\n cached = value;\n initialized = true;\n }\n },\n });\n}\n"],"mappings":";AAAA,SAAgB,qBACd,OACA,OACA,QACM;CACN,IAAI,cAAc;CAClB,IAAI;CACJ,OAAO,eAAe,OAAO,OAAO;EAClC,cAAc;EACd,YAAY;EACZ,MAAM;GACJ,IAAI,CAAC,aAAa;IAChB,SAAS,OAAO;IAChB,cAAc;GAChB;GACA,IACE,OAAO,yBAAyB,OAAO,KAAK,CAAC,EAAE,iBAAiB,MAEhE,OAAO,eAAe,OAAO,OAAO;IAClC,cAAc;IACd,YAAY;IACZ,UAAU;IACV,OAAO;GACT,CAAC;GAEH,OAAO;EACT;EACA,IAAI,OAAU;GACZ,IACE,OAAO,yBAAyB,OAAO,KAAK,CAAC,EAAE,iBAAiB,MAEhE,OAAO,eAAe,OAAO,OAAO;IAClC,cAAc;IACd,YAAY;IACZ,UAAU;IACV;GACF,CAAC;QACI,IAAI,OAAO,SAAS,KAAK,GAC9B,MAAM,IAAI,UACR,2CAA2C,MAAM,EACnD;QACK;IACL,SAAS;IACT,cAAc;GAChB;EACF;CACF,CAAC;AACH"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ThemedToken } from "../highlighter/types.js";
|
|
2
|
+
import "../types.js";
|
|
3
|
+
//#region src/utils/tokenStyle.d.ts
|
|
4
|
+
declare function tokenStyle(token: ThemedToken, cacheHtmlStyle: boolean): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { tokenStyle };
|
|
7
|
+
//# sourceMappingURL=tokenStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenStyle.d.ts","names":[],"sources":["../../src/utils/tokenStyle.ts"],"mappings":";;;iBAMgB,WACd,OAAO,aACP"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/utils/tokenStyle.ts
|
|
2
|
+
const htmlStyleCache = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function tokenStyle(token, cacheHtmlStyle) {
|
|
4
|
+
const { htmlStyle } = token;
|
|
5
|
+
if (htmlStyle != null) {
|
|
6
|
+
let style = cacheHtmlStyle ? htmlStyleCache.get(htmlStyle) : void 0;
|
|
7
|
+
if (style == null) {
|
|
8
|
+
style = "";
|
|
9
|
+
for (const name in htmlStyle) style += `${style === "" ? "" : ";"}${name}:${htmlStyle[name]}`;
|
|
10
|
+
if (cacheHtmlStyle) htmlStyleCache.set(htmlStyle, style);
|
|
11
|
+
}
|
|
12
|
+
return style;
|
|
13
|
+
}
|
|
14
|
+
let style = token.color != null ? `color:${token.color}` : "";
|
|
15
|
+
if (token.bgColor != null) style += `;background-color:${token.bgColor}`;
|
|
16
|
+
if (token.fontStyle != null) {
|
|
17
|
+
if ((token.fontStyle & 1) !== 0) style += ";font-style:italic";
|
|
18
|
+
if ((token.fontStyle & 2) !== 0) style += ";font-weight:bold";
|
|
19
|
+
const underline = (token.fontStyle & 4) !== 0;
|
|
20
|
+
const strikethrough = (token.fontStyle & 8) !== 0;
|
|
21
|
+
if (underline || strikethrough) style += `;text-decoration:${underline ? "underline" : ""}${underline && strikethrough ? " " : ""}${strikethrough ? "line-through" : ""}`;
|
|
22
|
+
}
|
|
23
|
+
return style.replace(/^;/, "");
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { tokenStyle };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=tokenStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenStyle.js","names":[],"sources":["../../src/utils/tokenStyle.ts"],"sourcesContent":["import type { ThemedToken } from '../types';\n\n// Warning: cache only tokens from Highlights, which reuses htmlStyle objects.\n// Shiki creates one per token, so caching them adds a WeakMap entry per token.\nconst htmlStyleCache = new WeakMap<Record<string, string>, string>();\n\nexport function tokenStyle(\n token: ThemedToken,\n cacheHtmlStyle: boolean\n): string {\n const { htmlStyle } = token;\n if (htmlStyle != null) {\n let style = cacheHtmlStyle ? htmlStyleCache.get(htmlStyle) : undefined;\n if (style == null) {\n style = '';\n for (const name in htmlStyle) {\n style += `${style === '' ? '' : ';'}${name}:${htmlStyle[name]}`;\n }\n if (cacheHtmlStyle) htmlStyleCache.set(htmlStyle, style);\n }\n return style;\n }\n let style = token.color != null ? `color:${token.color}` : '';\n if (token.bgColor != null) style += `;background-color:${token.bgColor}`;\n if (token.fontStyle != null) {\n if ((token.fontStyle & 1) !== 0) style += ';font-style:italic';\n if ((token.fontStyle & 2) !== 0) style += ';font-weight:bold';\n const underline = (token.fontStyle & 4) !== 0;\n const strikethrough = (token.fontStyle & 8) !== 0;\n if (underline || strikethrough)\n style += `;text-decoration:${underline ? 'underline' : ''}${underline && strikethrough ? ' ' : ''}${strikethrough ? 'line-through' : ''}`;\n }\n return style.replace(/^;/, '');\n}\n"],"mappings":";AAIA,MAAM,iCAAiB,IAAI,QAAwC;AAEnE,SAAgB,WACd,OACA,gBACQ;CACR,MAAM,EAAE,cAAc;CACtB,IAAI,aAAa,MAAM;EACrB,IAAI,QAAQ,iBAAiB,eAAe,IAAI,SAAS,IAAI,KAAA;EAC7D,IAAI,SAAS,MAAM;GACjB,QAAQ;GACR,KAAK,MAAM,QAAQ,WACjB,SAAS,GAAG,UAAU,KAAK,KAAK,MAAM,KAAK,GAAG,UAAU;GAE1D,IAAI,gBAAgB,eAAe,IAAI,WAAW,KAAK;EACzD;EACA,OAAO;CACT;CACA,IAAI,QAAQ,MAAM,SAAS,OAAO,SAAS,MAAM,UAAU;CAC3D,IAAI,MAAM,WAAW,MAAM,SAAS,qBAAqB,MAAM;CAC/D,IAAI,MAAM,aAAa,MAAM;EAC3B,KAAK,MAAM,YAAY,OAAO,GAAG,SAAS;EAC1C,KAAK,MAAM,YAAY,OAAO,GAAG,SAAS;EAC1C,MAAM,aAAa,MAAM,YAAY,OAAO;EAC5C,MAAM,iBAAiB,MAAM,YAAY,OAAO;EAChD,IAAI,aAAa,eACf,SAAS,oBAAoB,YAAY,cAAc,KAAK,aAAa,gBAAgB,MAAM,KAAK,gBAAgB,iBAAiB;CACzI;CACA,OAAO,MAAM,QAAQ,MAAM,EAAE;AAC/B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CodeToHtmlOptions, TokensResult } from "../highlighter/types.js";
|
|
2
|
+
import "../types.js";
|
|
3
|
+
//#region src/utils/tokensToHtml.d.ts
|
|
4
|
+
/** Serialize highlighted tokens without loading a backend's HTML renderer. */
|
|
5
|
+
declare function tokensToHtml(source: string, result: TokensResult, options: CodeToHtmlOptions, cacheHtmlStyles: boolean): string;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { tokensToHtml };
|
|
8
|
+
//# sourceMappingURL=tokensToHtml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokensToHtml.d.ts","names":[],"sources":["../../src/utils/tokensToHtml.ts"],"mappings":";;;;iBAOgB,aACd,gBACA,QAAQ,cACR,SAAS,mBACT"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { hastToHtml } from "./hastToHtml.js";
|
|
2
|
+
import { renderTokenLines } from "./renderTokenLines.js";
|
|
3
|
+
//#region src/utils/tokensToHtml.ts
|
|
4
|
+
/** Serialize highlighted tokens without loading a backend's HTML renderer. */
|
|
5
|
+
function tokensToHtml(source, result, options, cacheHtmlStyles) {
|
|
6
|
+
const lineOffsets = [0];
|
|
7
|
+
if (options.decorations?.some((item) => typeof item.start === "number" || typeof item.end === "number") === true) for (let index = source.indexOf("\n"); index !== -1; index = source.indexOf("\n", index + 1)) lineOffsets.push(index + 1);
|
|
8
|
+
const code = {
|
|
9
|
+
type: "element",
|
|
10
|
+
tagName: "code",
|
|
11
|
+
properties: {},
|
|
12
|
+
children: []
|
|
13
|
+
};
|
|
14
|
+
const lines = renderTokenLines(result.tokens, {
|
|
15
|
+
decorations: options.decorations,
|
|
16
|
+
mergeWhitespaces: options.mergeWhitespaces,
|
|
17
|
+
lineOffsets,
|
|
18
|
+
cacheHtmlStyles
|
|
19
|
+
});
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
if (i > 0) code.children.push({
|
|
22
|
+
type: "text",
|
|
23
|
+
value: "\n"
|
|
24
|
+
});
|
|
25
|
+
code.children.push(lines[i]);
|
|
26
|
+
}
|
|
27
|
+
const root = {
|
|
28
|
+
type: "root",
|
|
29
|
+
children: [{
|
|
30
|
+
type: "element",
|
|
31
|
+
tagName: "pre",
|
|
32
|
+
properties: {
|
|
33
|
+
class: "diffs",
|
|
34
|
+
style: result.rootStyle === false ? void 0 : result.rootStyle ?? [result.fg != null ? `color:${result.fg}` : "", result.bg != null ? `background-color:${result.bg}` : ""].filter(Boolean).join(";"),
|
|
35
|
+
tabIndex: 0
|
|
36
|
+
},
|
|
37
|
+
children: [code]
|
|
38
|
+
}]
|
|
39
|
+
};
|
|
40
|
+
return hastToHtml(root);
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { tokensToHtml };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=tokensToHtml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokensToHtml.js","names":[],"sources":["../../src/utils/tokensToHtml.ts"],"sourcesContent":["import type { Element, Root } from 'hast';\n\nimport type { CodeToHtmlOptions, TokensResult } from '../types';\nimport { hastToHtml } from './hastToHtml';\nimport { renderTokenLines } from './renderTokenLines';\n\n/** Serialize highlighted tokens without loading a backend's HTML renderer. */\nexport function tokensToHtml(\n source: string,\n result: TokensResult,\n options: CodeToHtmlOptions,\n cacheHtmlStyles: boolean\n): string {\n const lineOffsets = [0];\n if (\n options.decorations?.some(\n (item) => typeof item.start === 'number' || typeof item.end === 'number'\n ) === true\n ) {\n for (\n let index = source.indexOf('\\n');\n index !== -1;\n index = source.indexOf('\\n', index + 1)\n )\n lineOffsets.push(index + 1);\n }\n const code: Element = {\n type: 'element',\n tagName: 'code',\n properties: {},\n children: [],\n };\n const lines = renderTokenLines(result.tokens, {\n decorations: options.decorations,\n mergeWhitespaces: options.mergeWhitespaces,\n lineOffsets,\n cacheHtmlStyles,\n });\n for (let i = 0; i < lines.length; i++) {\n if (i > 0) code.children.push({ type: 'text', value: '\\n' });\n code.children.push(lines[i]);\n }\n const root: Root = {\n type: 'root',\n children: [\n {\n type: 'element',\n tagName: 'pre',\n properties: {\n class: 'diffs',\n style:\n result.rootStyle === false\n ? undefined\n : (result.rootStyle ??\n [\n result.fg != null ? `color:${result.fg}` : '',\n result.bg != null ? `background-color:${result.bg}` : '',\n ]\n .filter(Boolean)\n .join(';')),\n tabIndex: 0,\n },\n children: [code],\n },\n ],\n };\n return hastToHtml(root);\n}\n"],"mappings":";;;;AAOA,SAAgB,aACd,QACA,QACA,SACA,iBACQ;CACR,MAAM,cAAc,CAAC,CAAC;CACtB,IACE,QAAQ,aAAa,MAClB,SAAS,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,QAAQ,QAClE,MAAM,MAEN,KACE,IAAI,QAAQ,OAAO,QAAQ,IAAI,GAC/B,UAAU,IACV,QAAQ,OAAO,QAAQ,MAAM,QAAQ,CAAC,GAEtC,YAAY,KAAK,QAAQ,CAAC;CAE9B,MAAM,OAAgB;EACpB,MAAM;EACN,SAAS;EACT,YAAY,CAAC;EACb,UAAU,CAAC;CACb;CACA,MAAM,QAAQ,iBAAiB,OAAO,QAAQ;EAC5C,aAAa,QAAQ;EACrB,kBAAkB,QAAQ;EAC1B;EACA;CACF,CAAC;CACD,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,IAAI,IAAI,GAAG,KAAK,SAAS,KAAK;GAAE,MAAM;GAAQ,OAAO;EAAK,CAAC;EAC3D,KAAK,SAAS,KAAK,MAAM,EAAE;CAC7B;CACA,MAAM,OAAa;EACjB,MAAM;EACN,UAAU,CACR;GACE,MAAM;GACN,SAAS;GACT,YAAY;IACV,OAAO;IACP,OACE,OAAO,cAAc,QACjB,KAAA,IACC,OAAO,aACR,CACE,OAAO,MAAM,OAAO,SAAS,OAAO,OAAO,IAC3C,OAAO,MAAM,OAAO,oBAAoB,OAAO,OAAO,EACxD,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;IACjB,UAAU;GACZ;GACA,UAAU,CAAC,IAAI;EACjB,CACF;CACF;CACA,OAAO,WAAW,IAAI;AACxB"}
|