@scalar/code-highlight 0.0.2

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/dist/code/highlight.d.ts +8 -0
  4. package/dist/code/highlight.d.ts.map +1 -0
  5. package/dist/code/highlight.js +61 -0
  6. package/dist/code/index.d.ts +2 -0
  7. package/dist/code/index.d.ts.map +1 -0
  8. package/dist/code/index.js +1 -0
  9. package/dist/code/line-numbers.d.ts +10 -0
  10. package/dist/code/line-numbers.d.ts.map +1 -0
  11. package/dist/code/line-numbers.js +102 -0
  12. package/dist/constants.d.ts +3 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +13 -0
  15. package/dist/css/code.css +202 -0
  16. package/dist/css/markdown.css +291 -0
  17. package/dist/index.d.ts +6 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +7 -0
  20. package/dist/languages/basic.d.ts +4 -0
  21. package/dist/languages/basic.d.ts.map +1 -0
  22. package/dist/languages/basic.js +32 -0
  23. package/dist/languages/index.d.ts +4 -0
  24. package/dist/languages/index.d.ts.map +1 -0
  25. package/dist/languages/index.js +3 -0
  26. package/dist/languages/json-yaml.d.ts +4 -0
  27. package/dist/languages/json-yaml.d.ts.map +1 -0
  28. package/dist/languages/json-yaml.js +11 -0
  29. package/dist/languages/standard.d.ts +4 -0
  30. package/dist/languages/standard.d.ts.map +1 -0
  31. package/dist/languages/standard.js +76 -0
  32. package/dist/markdown/index.d.ts +2 -0
  33. package/dist/markdown/index.d.ts.map +1 -0
  34. package/dist/markdown/index.js +1 -0
  35. package/dist/markdown/markdown.d.ts +6 -0
  36. package/dist/markdown/markdown.d.ts.map +1 -0
  37. package/dist/markdown/markdown.js +57 -0
  38. package/dist/rehype-highlight/index.d.ts +2 -0
  39. package/dist/rehype-highlight/index.d.ts.map +1 -0
  40. package/dist/rehype-highlight/index.js +1 -0
  41. package/dist/rehype-highlight/rehype-highlight.d.ts +27 -0
  42. package/dist/rehype-highlight/rehype-highlight.d.ts.map +1 -0
  43. package/dist/rehype-highlight/rehype-highlight.js +100 -0
  44. package/package.json +101 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # @scalar/code-highlight
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 8494349: Migrate to highlightjs based syntax highlighting
8
+ - 6fbb57e: feat: release all the packages
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Scalar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ import type { LanguageFn } from 'highlight.js';
2
+ export declare function syntaxHighlight(codeString: string, options: {
3
+ lang: string;
4
+ languages: Record<string, LanguageFn>;
5
+ lineNumbers?: boolean;
6
+ maskCredentials?: string | string[];
7
+ }): string;
8
+ //# sourceMappingURL=highlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../src/code/highlight.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAQ9C,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACrC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CACpC,UA+CF"}
@@ -0,0 +1,61 @@
1
+ import { lowlightLanguageMappings } from '../constants.js';
2
+ import rehypeParse from 'rehype-parse';
3
+ import rehypeStringify from 'rehype-stringify';
4
+ import { unified } from 'unified';
5
+ import { visit } from 'unist-util-visit';
6
+ import { codeBlockLinesPlugin } from './line-numbers.js';
7
+ import { rehypeHighlight } from '../rehype-highlight/rehype-highlight.js';
8
+
9
+ function syntaxHighlight(codeString, options) {
10
+ // Simple restriction on credentials to prevent unexpected behavior
11
+ const credentials = (typeof options?.maskCredentials === 'string'
12
+ ? [options.maskCredentials]
13
+ : options?.maskCredentials ?? []).filter((c) => {
14
+ if (c.length < 3) {
15
+ console.error(`Codeblock credentials must be at least 3 characters to mask. Will not mask "${c}"`);
16
+ return false;
17
+ }
18
+ return true;
19
+ });
20
+ // Classname is used by lowlight to select the language model
21
+ const className = `language-${lowlightLanguageMappings[options.lang] ?? options.lang}`;
22
+ const nullPlugin = (() => { });
23
+ const html = unified()
24
+ // Parses markdown
25
+ .use(rehypeParse, { fragment: true })
26
+ // Raw code string must be injected after initial hast parsing
27
+ // so that HTML code is not parsed into the hast tree
28
+ .use(injectRawCodeStringPlugin(codeString))
29
+ // Syntax highlighting
30
+ .use(rehypeHighlight, {
31
+ languages: options.languages,
32
+ })
33
+ .use(options?.lineNumbers ? codeBlockLinesPlugin : nullPlugin)
34
+ // Converts the HTML AST to a string
35
+ .use(rehypeStringify)
36
+ // Run the pipeline
37
+ .processSync(`<pre><code class="${className}"></code></pre>`);
38
+ const htmlString = html.toString();
39
+ // Replace any credentials with a wrapper element
40
+ return credentials.length
41
+ ? htmlString.replace(new RegExp(credentials.join('|'), 'g'), (m) => `<span class="credentials">${m}</span>`)
42
+ : htmlString;
43
+ }
44
+ /**
45
+ * To prevent unified from parsing any content of the code string we inject
46
+ * it as a raw text node into the AST tree as a child of the code element
47
+ */
48
+ function injectRawCodeStringPlugin(rawCodeString) {
49
+ return () => (tree) => {
50
+ visit(tree, 'element', (node) => {
51
+ if (node.tagName === 'code') {
52
+ node.children.push({
53
+ type: 'text',
54
+ value: rawCodeString,
55
+ });
56
+ }
57
+ });
58
+ };
59
+ }
60
+
61
+ export { syntaxHighlight };
@@ -0,0 +1,2 @@
1
+ export { syntaxHighlight } from './highlight.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1 @@
1
+ export { syntaxHighlight } from './highlight.js';
@@ -0,0 +1,10 @@
1
+ import type { Element, ElementContent, Root, Text } from 'hast';
2
+ export declare function isText(element?: ElementContent): element is Text;
3
+ export declare function isElement(node?: ElementContent): node is Element;
4
+ export declare function textElement(value: string): Text;
5
+ export declare function lineBreak(): Text;
6
+ /**
7
+ * Adds lines to code blocks
8
+ */
9
+ export declare function codeBlockLinesPlugin(): (tree: Root) => void;
10
+ //# sourceMappingURL=line-numbers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-numbers.d.ts","sourceRoot":"","sources":["../../src/code/line-numbers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAM/D,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,IAAI,IAAI,CAEhE;AAED,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,IAAI,OAAO,CAEhE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,WACpB,IAAI,UA0CnB"}
@@ -0,0 +1,102 @@
1
+ import { visit } from 'unist-util-visit';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Line Numbering plugin
5
+ function isText(element) {
6
+ return element?.type === 'text';
7
+ }
8
+ function isElement(node) {
9
+ return node?.type === 'element';
10
+ }
11
+ function textElement(value) {
12
+ return { type: 'text', value };
13
+ }
14
+ function lineBreak() {
15
+ return { type: 'text', value: '\n' };
16
+ }
17
+ /**
18
+ * Adds lines to code blocks
19
+ */
20
+ function codeBlockLinesPlugin() {
21
+ return (tree) => {
22
+ visit(tree, 'element', (node, _i, parent) => {
23
+ if (parent?.type === 'element' &&
24
+ parent.tagName === 'pre' &&
25
+ node.tagName === 'code') {
26
+ let numLines = 0;
27
+ // Wraps each line in a span
28
+ node.children = addLines(node);
29
+ // Adds a line break to the end of each line
30
+ node.children.forEach((child) => {
31
+ if (child.type === 'element' && child.tagName === 'span') {
32
+ const lastChild = child.children[child.children.length - 1];
33
+ if (!isText(lastChild) ||
34
+ (isText(lastChild) && !hasLineBreak(lastChild))) {
35
+ child.children.push(lineBreak());
36
+ numLines++;
37
+ }
38
+ }
39
+ });
40
+ // We need to maintain a count of the total lines to allow space for the labels
41
+ node.properties.style = [
42
+ `--line-count: ${numLines};`,
43
+ `--line-digits: ${numLines.toString().length};`,
44
+ ];
45
+ }
46
+ });
47
+ // console.log('NUMBER OF LINES IS: ', numLines)
48
+ };
49
+ }
50
+ /**
51
+ * Adds lines to a node recursively and returns them
52
+ *
53
+ * @param node - The node to add lines to
54
+ * @param lines - The current lines
55
+ * @param copyParent - Whether to copy the parent node to save the original node styles
56
+ */
57
+ function addLines(node, lines = [], copyParent) {
58
+ const line = () => lines[lines.length - 1] ??
59
+ (lines.push(createLine()) && lines[lines.length - 1]);
60
+ node.children.forEach((child) => {
61
+ if (isText(child) && hasLineBreak(child)) {
62
+ const split = child.value.split(/\n/);
63
+ split.forEach((content, i) => {
64
+ copyParent
65
+ ? line().children.push({ ...node, children: [textElement(content)] })
66
+ : line().children.push(textElement(content));
67
+ i !== split.length - 1 && lines.push(createLine());
68
+ });
69
+ }
70
+ else if (isElement(child) && child.children.some(hasLineBreak)) {
71
+ addLines(child, lines, true);
72
+ }
73
+ else {
74
+ line().children.push(child);
75
+ }
76
+ });
77
+ return lines;
78
+ }
79
+ /**
80
+ * Creates a new line element
81
+ *
82
+ * @param children - The children the line should have initially
83
+ */
84
+ function createLine(...children) {
85
+ return {
86
+ type: 'element',
87
+ tagName: 'span',
88
+ properties: { class: ['line'] },
89
+ children,
90
+ };
91
+ }
92
+ /**
93
+ * Checks if a node has a line break
94
+ *
95
+ * @param node - The node to check
96
+ */
97
+ function hasLineBreak(node) {
98
+ return ((isText(node) && /\r?\n/.test(node.value)) ||
99
+ (isElement(node) && node.children.some(hasLineBreak)));
100
+ }
101
+
102
+ export { codeBlockLinesPlugin, isElement, isText, lineBreak, textElement };
@@ -0,0 +1,3 @@
1
+ /** Map common markdown language shortcuts to lowlight languages */
2
+ export declare const lowlightLanguageMappings: Record<string, string>;
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ3D,CAAA"}
@@ -0,0 +1,13 @@
1
+ /** Map common markdown language shortcuts to lowlight languages */
2
+ const lowlightLanguageMappings = {
3
+ 'ts': 'typescript',
4
+ 'js': 'javascript',
5
+ 'py': 'python',
6
+ 'py3': 'python',
7
+ 'c#': 'csharp',
8
+ 'c++': 'cpp',
9
+ 'node': 'javascript',
10
+ };
11
+ //
12
+
13
+ export { lowlightLanguageMappings };
@@ -0,0 +1,202 @@
1
+ @layer scalar-base {
2
+ code.hljs * {
3
+ font-size: var(--scalar-small);
4
+ font-family: var(--scalar-font-code);
5
+ text-align: left;
6
+ white-space: pre;
7
+ word-spacing: normal;
8
+ word-break: normal;
9
+ word-wrap: normal;
10
+ line-height: 1.4;
11
+ tab-size: 4;
12
+ }
13
+ code.hljs {
14
+ font-size: var(--scalar-small);
15
+ font-family: var(--scalar-font-code);
16
+ display: inline-block;
17
+ counter-reset: linenumber;
18
+ }
19
+ .hljs {
20
+ background: transparent;
21
+ color: var(--scalar-color-2);
22
+ }
23
+
24
+ .hljs .line::before {
25
+ color: var(--scalar-color-3);
26
+ display: inline-block;
27
+ counter-increment: linenumber;
28
+ content: counter(linenumber);
29
+ margin-right: 0.7em;
30
+ /* Variable is set on the code element by the plugin when line numbers are used */
31
+ min-width: calc(var(--line-digits) * 1ch);
32
+ text-align: right;
33
+ }
34
+ /* ------------------------------------------------------------- */
35
+ /* Data types */
36
+ .hljs-comment,
37
+ .hljs-quote {
38
+ color: var(--scalar-color-3);
39
+ font-style: italic;
40
+ }
41
+
42
+ .hljs-number {
43
+ color: var(--scalar-color-orange);
44
+ }
45
+
46
+ .hljs-regexp,
47
+ .hljs-string {
48
+ color: var(--scalar-color-blue);
49
+ }
50
+
51
+ /** Globals such as `var()` and `!important` */
52
+ .hljs-built_in {
53
+ color: var(--scalar-color-blue);
54
+ }
55
+
56
+ /** Class initializers such as `Array` or `Date` */
57
+ /** Type declarations such as `Record` */
58
+ .hljs-title.class_ {
59
+ color: var(--scalar-color-1);
60
+ }
61
+
62
+ /** Language indicators such as `new`, `const`, or `function` in JS */
63
+ .hljs-keyword {
64
+ color: var(--scalar-color-purple);
65
+ }
66
+
67
+ /** Function names when declaring and calling */
68
+ .hljs-title.function_ {
69
+ color: var(--scalar-color-orange);
70
+ }
71
+
72
+ /** Template substitution */
73
+ .hljs-subst {
74
+ color: var(--scalar-color-blue);
75
+ }
76
+
77
+ /** HTML Tag name */
78
+ .hljs-name {
79
+ color: var(--scalar-color-blue);
80
+ }
81
+
82
+ /** Attribute name (ex. `class`, `id`) */
83
+ .hljs-attr,
84
+ .hljs-attribute {
85
+ color: var(--scalar-color-1);
86
+ }
87
+
88
+ .hljs-addition,
89
+ .hljs-literal,
90
+ .hljs-selector-tag,
91
+ .hljs-type {
92
+ color: var(--scalar-color-green);
93
+ }
94
+
95
+ .hljs-selector-attr,
96
+ .hljs-selector-pseudo {
97
+ color: var(--scalar-color-orange);
98
+ }
99
+ .hljs-doctag {
100
+ color: var(--scalar-color-blue);
101
+ }
102
+
103
+ .hljs-section,
104
+ .hljs-title {
105
+ color: var(--scalar-color-blue);
106
+ }
107
+
108
+ .hljs-selector-id,
109
+ .hljs-template-variable,
110
+ .hljs-variable {
111
+ color: var(--scalar-color-1);
112
+ }
113
+
114
+ .hljs-name,
115
+ .hljs-section,
116
+ .hljs-strong {
117
+ font-weight: var(--scalar-semibold);
118
+ }
119
+
120
+ .hljs-bullet,
121
+ .hljs-link,
122
+ .hljs-meta,
123
+ .hljs-symbol {
124
+ color: var(--scalar-color-blue);
125
+ }
126
+
127
+ .hljs-deletion {
128
+ color: var(--scalar-color-red);
129
+ }
130
+
131
+ .hljs-formula {
132
+ background: var(--scalar-color-1);
133
+ }
134
+
135
+ .hljs-emphasis {
136
+ font-style: italic;
137
+ }
138
+
139
+ /** Hide credentials */
140
+ .credentials {
141
+ font-size: 0 !important;
142
+ color: transparent;
143
+ }
144
+
145
+ /** Show a few dots instead */
146
+ .credentials::after {
147
+ content: '·····';
148
+ font-size: var(--scalar-small);
149
+ color: var(--scalar-color-3);
150
+ user-select: none;
151
+ }
152
+ }
153
+
154
+ /* -------------------------------------------------------------- */
155
+ /* Language specific overrides */
156
+
157
+ /** For HTML we leave the content strings brighter */
158
+ .hljs.language-html {
159
+ color: var(--scalar-color-1);
160
+ }
161
+
162
+ /** For HTML make the attr text different than the content */
163
+ .hljs.language-html .hljs-attr {
164
+ color: var(--scalar-color-2);
165
+ }
166
+
167
+ .hljs.language-curl .hljs-keyword {
168
+ color: var(--scalar-color-orange);
169
+ }
170
+
171
+ .hljs.language-curl .hljs-string {
172
+ color: var(--scalar-color-1);
173
+ }
174
+
175
+ .hljs.language-curl .hljs-literal {
176
+ color: var(--scalar-color-blue);
177
+ }
178
+
179
+ .hljs.language-curl .hljs-literal {
180
+ color: var(--scalar-color-blue);
181
+ }
182
+
183
+ /** Compromise here */
184
+ .hljs.language-cpp .hljs-built_in {
185
+ /* color: var(--scalar-color-1); */
186
+ }
187
+
188
+ .hljs.language-php .hljs-variable {
189
+ color: var(--scalar-color-blue);
190
+ }
191
+
192
+ .hljs.language-objectivec .hljs-meta {
193
+ color: var(--scalar-color-1);
194
+ }
195
+
196
+ .hljs.language-objectivec .hljs-built_in {
197
+ color: var(--scalar-color-orange);
198
+ }
199
+
200
+ .hljs-built_in {
201
+ color: var(--scalar-color-orange);
202
+ }
@@ -0,0 +1,291 @@
1
+ @import url('./code.css');
2
+
3
+ @layer scalar-base {
4
+ .markdown {
5
+ font-family: var(--scalar-font);
6
+ color: var(--scalar-color-1);
7
+ word-break: break-word;
8
+ }
9
+
10
+ /* Apply base padding for all block elements */
11
+ .markdown h1,
12
+ .markdown h2,
13
+ .markdown h3,
14
+ .markdown h4,
15
+ .markdown h5,
16
+ .markdown h6,
17
+ .markdown p,
18
+ .markdown div,
19
+ .markdown img,
20
+ .markdown details,
21
+ .markdown summary,
22
+ .markdown ul,
23
+ .markdown ol,
24
+ .markdown table,
25
+ .markdown blockquote,
26
+ .markdown code {
27
+ margin: 12px 0;
28
+ }
29
+
30
+ .markdown details {
31
+ margin: 12px 0;
32
+ color: var(--scalar-color-1);
33
+ }
34
+ .markdown summary {
35
+ display: block;
36
+ margin: 12px 0;
37
+ padding-left: 20px;
38
+ position: relative;
39
+ font-weight: var(--scalar-semibold);
40
+ cursor: pointer;
41
+ user-select: none;
42
+ }
43
+
44
+ .markdown summary::after {
45
+ display: block;
46
+ content: '';
47
+
48
+ position: absolute;
49
+ top: 1px;
50
+ left: 1px;
51
+
52
+ width: 16px;
53
+ height: 16px;
54
+
55
+ background-color: var(--scalar-color-3);
56
+ mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 19.5L15.75 12L8.25 4.5" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
57
+ }
58
+
59
+ .markdown summary:hover::after {
60
+ background-color: var(--scalar-color-1);
61
+ }
62
+
63
+ .markdown details[open] summary::after {
64
+ transform: rotate(90deg);
65
+ }
66
+
67
+ /* Fix for Safari displaying default caret next to `<summary>` */
68
+ .markdown summary::-webkit-details-marker {
69
+ display: none;
70
+ }
71
+
72
+ .markdown img {
73
+ overflow: hidden;
74
+ border-radius: var(--scalar-radius);
75
+ max-width: 100%;
76
+ }
77
+ /* Don't add margin to the first block */
78
+ .markdown > :first-child {
79
+ margin-top: 0;
80
+ }
81
+
82
+ .markdown h1 {
83
+ --font-size: 1.4em;
84
+ }
85
+
86
+ .markdown h2 {
87
+ --font-size: 1.25em;
88
+ }
89
+
90
+ .markdown h3 {
91
+ --font-size: 1.1em;
92
+ }
93
+
94
+ .markdown h4 {
95
+ --font-size: 1em;
96
+ }
97
+
98
+ .markdown h6 {
99
+ --font-size: 1em;
100
+ }
101
+ .markdown h1,
102
+ .markdown h2,
103
+ .markdown h3,
104
+ .markdown h4,
105
+ .markdown h5,
106
+ .markdown h6 {
107
+ font-size: var(--font-size);
108
+ margin: 18px 0 6px;
109
+ font-weight: var(--scalar-bold);
110
+ display: block;
111
+ line-height: 1.45;
112
+ }
113
+ .markdown b,
114
+ .markdown strong {
115
+ font-weight: var(--scalar-bold);
116
+ }
117
+ .markdown p {
118
+ color: var(--scalar-color-1);
119
+ font-weight: var(--font-weight, var(--scalar-regular));
120
+ line-height: 1.5;
121
+ margin-bottom: 0;
122
+ display: block;
123
+ }
124
+
125
+ .markdown ul,
126
+ .markdown ol {
127
+ padding-left: 24px;
128
+ line-height: 1.5;
129
+ margin: 12px 0;
130
+ display: block;
131
+ }
132
+
133
+ .markdown ul {
134
+ list-style: disc;
135
+ }
136
+
137
+ .markdown ol {
138
+ list-style: decimal;
139
+ }
140
+
141
+ .markdown ul.contains-task-list {
142
+ list-style: none;
143
+ padding-left: 0;
144
+ }
145
+
146
+ .markdown li {
147
+ margin: 6px 0;
148
+ display: list-item;
149
+ }
150
+ .markdown a {
151
+ color: var(--scalar-color-accent);
152
+ text-decoration: var(--scalar-text-decoration);
153
+ cursor: pointer;
154
+ }
155
+ .markdown a:hover {
156
+ text-decoration: var(--scalar-text-decoration-hover);
157
+ }
158
+ .markdown em {
159
+ font-style: italic;
160
+ }
161
+ .markdown sup {
162
+ font-size: var(--scalar-micro);
163
+ vertical-align: super;
164
+ font-weight: 450;
165
+ }
166
+ .markdown sub {
167
+ font-size: var(--scalar-micro);
168
+ vertical-align: sub;
169
+ font-weight: 450;
170
+ }
171
+ .markdown del {
172
+ text-decoration: line-through;
173
+ }
174
+ .markdown code {
175
+ font-family: var(--scalar-font-code);
176
+ background-color: var(--scalar-background-2);
177
+ box-shadow: 0 0 0 1px var(--scalar-border-color);
178
+ font-size: var(--scalar-micro);
179
+ border-radius: 2px;
180
+ padding: 0 3px;
181
+ }
182
+
183
+ .markdown pre code {
184
+ display: block;
185
+ white-space: pre;
186
+ padding: 12px;
187
+ line-height: 1.5;
188
+ margin: 12px 0;
189
+ -webkit-overflow-scrolling: touch;
190
+ overflow-x: auto;
191
+ max-width: 100%;
192
+ min-width: 100px;
193
+ }
194
+
195
+ .markdown hr {
196
+ border: none;
197
+ border-bottom: 1px solid var(--scalar-border-color);
198
+ }
199
+
200
+ .markdown img {
201
+ max-height: 150px;
202
+ border-radius: var(--scalar-radius);
203
+ }
204
+
205
+ .markdown blockquote {
206
+ border-left: 3px solid var(--scalar-border-color);
207
+ padding-left: 12px;
208
+ margin: 0;
209
+ display: block;
210
+ }
211
+
212
+ .markdown table {
213
+ display: block;
214
+ overflow-x: auto;
215
+ position: relative;
216
+ border-collapse: collapse;
217
+ width: max-content;
218
+ max-width: 100%;
219
+ margin: 1em 0;
220
+ box-shadow: 0 0 0 1px var(--scalar-border-color);
221
+ border-radius: var(--scalar-radius-lg);
222
+ }
223
+ .markdown tbody {
224
+ display: table-row-group;
225
+ vertical-align: middle;
226
+ }
227
+ .markdown thead {
228
+ display: table-header-group;
229
+ vertical-align: middle;
230
+ }
231
+
232
+ .markdown tr {
233
+ display: table-row;
234
+ border-color: inherit;
235
+ vertical-align: inherit;
236
+ }
237
+ .markdown td,
238
+ .markdown th {
239
+ display: table-cell;
240
+ vertical-align: inherit;
241
+ min-width: 1em;
242
+ padding: 6px 9px;
243
+ vertical-align: top;
244
+ line-height: 1.5;
245
+ position: relative;
246
+ word-break: initial;
247
+ font-size: var(--scalar-small);
248
+ color: var(--scalar-color-1);
249
+ font-weight: var(--font-weight, var(--scalar-regular));
250
+ border-right: 1px solid var(--scalar-border-color);
251
+ border-bottom: 1px solid var(--scalar-border-color);
252
+ }
253
+
254
+ .markdown td > *,
255
+ .markdown th > * {
256
+ margin-bottom: 0;
257
+ }
258
+ .markdown th:empty {
259
+ display: none;
260
+ }
261
+ .markdown td:first-of-type,
262
+ .markdown th:first-of-type {
263
+ border-left: none;
264
+ }
265
+
266
+ .markdown td:last-of-type,
267
+ .markdown th:last-of-type {
268
+ border-right: none;
269
+ }
270
+
271
+ .markdown tr:last-of-type td {
272
+ border-bottom: none;
273
+ }
274
+
275
+ .markdown th {
276
+ font-weight: var(--scalar-semibold) !important;
277
+ text-align: left;
278
+ border-left-color: transparent;
279
+ background: var(--scalar-background-2);
280
+ }
281
+
282
+ .markdown tr > [align='left'] {
283
+ text-align: left;
284
+ }
285
+ .markdown tr > [align='right'] {
286
+ text-align: right;
287
+ }
288
+ .markdown tr > [align='center'] {
289
+ text-align: center;
290
+ }
291
+ }
@@ -0,0 +1,6 @@
1
+ export { rehypeHighlight } from './rehype-highlight/index.js';
2
+ export { lowlightLanguageMappings } from './constants.js';
3
+ export { htmlFromMarkdown } from './markdown/index.js';
4
+ export { syntaxHighlight } from './code/index.js';
5
+ export * from './languages/index.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACxC,cAAc,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { lowlightLanguageMappings } from './constants.js';
2
+ export { rehypeHighlight } from './rehype-highlight/rehype-highlight.js';
3
+ export { htmlFromMarkdown } from './markdown/markdown.js';
4
+ export { syntaxHighlight } from './code/highlight.js';
5
+ export { jsonYamlLanguages } from './languages/json-yaml.js';
6
+ export { standardLanguages } from './languages/standard.js';
7
+ export { basicLanguages } from './languages/basic.js';
@@ -0,0 +1,4 @@
1
+ import type { LanguageFn } from 'highlight.js';
2
+ declare const basicLanguages: Record<string, LanguageFn>;
3
+ export { basicLanguages };
4
+ //# sourceMappingURL=basic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/languages/basic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAe9C,QAAA,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAe9C,CAAA;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}
@@ -0,0 +1,32 @@
1
+ import bash from 'highlight.js/lib/languages/bash';
2
+ import css from 'highlight.js/lib/languages/css';
3
+ import javascript from 'highlight.js/lib/languages/javascript';
4
+ import json from 'highlight.js/lib/languages/json';
5
+ import less from 'highlight.js/lib/languages/less';
6
+ import markdown from 'highlight.js/lib/languages/markdown';
7
+ import plaintext from 'highlight.js/lib/languages/plaintext';
8
+ import python from 'highlight.js/lib/languages/python';
9
+ import scss from 'highlight.js/lib/languages/scss';
10
+ import shell from 'highlight.js/lib/languages/shell';
11
+ import typescript from 'highlight.js/lib/languages/typescript';
12
+ import xml from 'highlight.js/lib/languages/xml';
13
+ import yaml from 'highlight.js/lib/languages/yaml';
14
+
15
+ const basicLanguages = {
16
+ bash,
17
+ css,
18
+ javascript,
19
+ json,
20
+ html: xml,
21
+ less,
22
+ markdown,
23
+ plaintext,
24
+ python,
25
+ scss,
26
+ shell,
27
+ typescript,
28
+ yaml,
29
+ xml,
30
+ };
31
+
32
+ export { basicLanguages };
@@ -0,0 +1,4 @@
1
+ export { jsonYamlLanguages } from './json-yaml.js';
2
+ export { standardLanguages } from './standard.js';
3
+ export { basicLanguages } from './basic.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/languages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { jsonYamlLanguages } from './json-yaml.js';
2
+ export { standardLanguages } from './standard.js';
3
+ export { basicLanguages } from './basic.js';
@@ -0,0 +1,4 @@
1
+ import type { LanguageFn } from 'highlight.js';
2
+ declare const jsonYamlLanguages: Record<string, LanguageFn>;
3
+ export { jsonYamlLanguages };
4
+ //# sourceMappingURL=json-yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-yaml.d.ts","sourceRoot":"","sources":["../../src/languages/json-yaml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAK9C,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAIjD,CAAA;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -0,0 +1,11 @@
1
+ import json from 'highlight.js/lib/languages/json';
2
+ import plaintext from 'highlight.js/lib/languages/plaintext';
3
+ import yaml from 'highlight.js/lib/languages/yaml';
4
+
5
+ const jsonYamlLanguages = {
6
+ json,
7
+ plaintext,
8
+ yaml,
9
+ };
10
+
11
+ export { jsonYamlLanguages };
@@ -0,0 +1,4 @@
1
+ import type { LanguageFn } from 'highlight.js';
2
+ declare const standardLanguages: Record<string, LanguageFn>;
3
+ export { standardLanguages };
4
+ //# sourceMappingURL=standard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.d.ts","sourceRoot":"","sources":["../../src/languages/standard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAsC9C,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAqCjD,CAAA;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -0,0 +1,76 @@
1
+ import bash from 'highlight.js/lib/languages/bash';
2
+ import c from 'highlight.js/lib/languages/c';
3
+ import clojure from 'highlight.js/lib/languages/clojure';
4
+ import cpp from 'highlight.js/lib/languages/cpp';
5
+ import csharp from 'highlight.js/lib/languages/csharp';
6
+ import css from 'highlight.js/lib/languages/css';
7
+ import elixir from 'highlight.js/lib/languages/elixir';
8
+ import go from 'highlight.js/lib/languages/go';
9
+ import graphql from 'highlight.js/lib/languages/graphql';
10
+ import java from 'highlight.js/lib/languages/java';
11
+ import javascript from 'highlight.js/lib/languages/javascript';
12
+ import json from 'highlight.js/lib/languages/json';
13
+ import kotlin from 'highlight.js/lib/languages/kotlin';
14
+ import less from 'highlight.js/lib/languages/less';
15
+ import makefile from 'highlight.js/lib/languages/makefile';
16
+ import markdown from 'highlight.js/lib/languages/markdown';
17
+ import matlab from 'highlight.js/lib/languages/matlab';
18
+ import nginx from 'highlight.js/lib/languages/nginx';
19
+ import objectivec from 'highlight.js/lib/languages/objectivec';
20
+ import ocaml from 'highlight.js/lib/languages/ocaml';
21
+ import php from 'highlight.js/lib/languages/php';
22
+ import plaintext from 'highlight.js/lib/languages/plaintext';
23
+ import powershell from 'highlight.js/lib/languages/powershell';
24
+ import python from 'highlight.js/lib/languages/python';
25
+ import r from 'highlight.js/lib/languages/r';
26
+ import ruby from 'highlight.js/lib/languages/ruby';
27
+ import rust from 'highlight.js/lib/languages/rust';
28
+ import scss from 'highlight.js/lib/languages/scss';
29
+ import shell from 'highlight.js/lib/languages/shell';
30
+ import sql from 'highlight.js/lib/languages/sql';
31
+ import swift from 'highlight.js/lib/languages/swift';
32
+ import typescript from 'highlight.js/lib/languages/typescript';
33
+ import xml from 'highlight.js/lib/languages/xml';
34
+ import yaml from 'highlight.js/lib/languages/yaml';
35
+ import curl from 'highlightjs-curl';
36
+
37
+ const standardLanguages = {
38
+ bash,
39
+ c,
40
+ clojure,
41
+ cpp,
42
+ css,
43
+ curl,
44
+ csharp,
45
+ elixir,
46
+ go,
47
+ graphql,
48
+ html: xml,
49
+ java,
50
+ javascript,
51
+ json,
52
+ kotlin,
53
+ less,
54
+ makefile,
55
+ markdown,
56
+ matlab,
57
+ nginx,
58
+ objectivec,
59
+ ocaml,
60
+ php,
61
+ plaintext,
62
+ powershell,
63
+ python,
64
+ r,
65
+ ruby,
66
+ rust,
67
+ scss,
68
+ shell,
69
+ sql,
70
+ swift,
71
+ typescript,
72
+ xml,
73
+ yaml,
74
+ };
75
+
76
+ export { standardLanguages };
@@ -0,0 +1,2 @@
1
+ export { htmlFromMarkdown } from './markdown.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/markdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1 @@
1
+ export { htmlFromMarkdown } from './markdown.js';
@@ -0,0 +1,6 @@
1
+ /** Take a markdown string and generate a raw HTML string */
2
+ export declare function htmlFromMarkdown(markdownString: string, options?: {
3
+ removeTags?: string[];
4
+ allowTags?: string[];
5
+ }): string;
6
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/markdown/markdown.ts"],"names":[],"mappings":"AAYA,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE;IACR,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB,UA4CF"}
@@ -0,0 +1,57 @@
1
+ import rehypeExternalLinks from 'rehype-external-links';
2
+ import rehypeFormat from 'rehype-format';
3
+ import rehypeRaw from 'rehype-raw';
4
+ import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
5
+ import rehypeStringify from 'rehype-stringify';
6
+ import remarkGfm from 'remark-gfm';
7
+ import remarkParse from 'remark-parse';
8
+ import remarkRehype from 'remark-rehype';
9
+ import { unified } from 'unified';
10
+ import { rehypeHighlight } from '../rehype-highlight/rehype-highlight.js';
11
+ import { standardLanguages } from '../languages/standard.js';
12
+
13
+ /** Take a markdown string and generate a raw HTML string */
14
+ function htmlFromMarkdown(markdownString, options) {
15
+ // Add permitted tags and remove stripped ones
16
+ const removeTags = options?.removeTags ?? [];
17
+ const tagNames = [
18
+ ...(defaultSchema.tagNames ?? []),
19
+ ...(options?.allowTags ?? []),
20
+ ].filter((t) => !removeTags.includes(t));
21
+ const html = unified()
22
+ // Parses markdown
23
+ .use(remarkParse)
24
+ // Support autolink literals, footnotes, strikethrough, tables and tasklists
25
+ .use(remarkGfm)
26
+ // Allows any HTML tags
27
+ .use(remarkRehype, { allowDangerousHtml: true })
28
+ // Creates a HTML AST
29
+ .use(rehypeRaw)
30
+ // Removes disallowed tags
31
+ .use(rehypeSanitize, {
32
+ ...defaultSchema,
33
+ // Makes it even more strict
34
+ tagNames,
35
+ attributes: {
36
+ ...defaultSchema.attributes,
37
+ abbr: ['title'],
38
+ },
39
+ })
40
+ // Syntax highlighting
41
+ .use(rehypeHighlight, {
42
+ languages: standardLanguages,
43
+ // Enable auto detection
44
+ detect: true,
45
+ })
46
+ // Adds target="_blank" to external links
47
+ .use(rehypeExternalLinks, { target: '_blank' })
48
+ // Formats the HTML
49
+ .use(rehypeFormat)
50
+ // Converts the HTML AST to a string
51
+ .use(rehypeStringify)
52
+ // Run the pipeline
53
+ .processSync(markdownString);
54
+ return html.toString();
55
+ }
56
+
57
+ export { htmlFromMarkdown };
@@ -0,0 +1,2 @@
1
+ export { rehypeHighlight } from './rehype-highlight.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rehype-highlight/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1 @@
1
+ export { rehypeHighlight } from './rehype-highlight.js';
@@ -0,0 +1,27 @@
1
+ import type { Root } from 'hast';
2
+ import { type LanguageFn, createLowlight } from 'lowlight';
3
+ import type { VFile } from 'vfile';
4
+ type HighlightOptions = {
5
+ /** Optional existing lowlight instance to use */
6
+ lowlight?: ReturnType<typeof createLowlight> | undefined;
7
+ /** Register more aliases (optional); passed to `lowlight.registerAlias` */
8
+ aliases?: Readonly<Record<string, ReadonlyArray<string> | string>> | null | undefined;
9
+ /** Register languages (default: `common`) passed to `lowlight.register` */
10
+ languages?: Readonly<Record<string, LanguageFn>> | null | undefined;
11
+ /** List of language names to not highlight (optional). Note: you can also add `no-highlight` classes. */
12
+ plainText?: ReadonlyArray<string> | null | undefined;
13
+ /** Class prefix (default: `'hljs-'`) */
14
+ prefix?: string | null | undefined;
15
+ /** Names of languages to check when detecting (default: all registered languages) */
16
+ subset?: ReadonlyArray<string> | null | undefined;
17
+ /** Option to autodetect languages */
18
+ detect?: boolean;
19
+ };
20
+ /**
21
+ * Lowlight syntax highlighting plugin for rehype pipelines
22
+ *
23
+ * Derived from: @url https://github.com/rehypejs/rehype-highlight/blob/main/lib/index.js
24
+ */
25
+ export declare function rehypeHighlight(options?: Readonly<HighlightOptions> | null | undefined): (tree: Root, file: VFile) => void;
26
+ export {};
27
+ //# sourceMappingURL=rehype-highlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehype-highlight.d.ts","sourceRoot":"","sources":["../../src/rehype-highlight/rehype-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,IAAI,EAAE,MAAM,MAAM,CAAA;AAEzD,OAAO,EAAE,KAAK,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAIlC,KAAK,gBAAgB,GAAG;IACtB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,GAAG,SAAS,CAAA;IACxD,2EAA2E;IAC3E,OAAO,CAAC,EACJ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GACxD,IAAI,GACJ,SAAS,CAAA;IACb,2EAA2E;IAC3E,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACnE,yGAAyG;IACzG,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACpD,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAClC,qFAAqF;IACrF,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACjD,qCAAqC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,GAAG,SAAS,UAsBhC,IAAI,QAAQ,KAAK,UAkEzC"}
@@ -0,0 +1,100 @@
1
+ import { toText } from 'hast-util-to-text';
2
+ import { createLowlight } from 'lowlight';
3
+ import { visit } from 'unist-util-visit';
4
+ import { lowlightLanguageMappings } from '../constants.js';
5
+
6
+ const emptyOptions = {};
7
+ /**
8
+ * Lowlight syntax highlighting plugin for rehype pipelines
9
+ *
10
+ * Derived from: @url https://github.com/rehypejs/rehype-highlight/blob/main/lib/index.js
11
+ */
12
+ function rehypeHighlight(options) {
13
+ const settings = options || emptyOptions;
14
+ const aliases = settings.aliases;
15
+ const detect = options?.detect ?? false;
16
+ const languages = settings.languages;
17
+ const plainText = settings.plainText;
18
+ const prefix = settings.prefix;
19
+ const subset = settings.subset;
20
+ let name = 'hljs';
21
+ // Create a lowlight instance if not provided
22
+ const lowlight = options?.lowlight ?? createLowlight(languages);
23
+ if (aliases)
24
+ lowlight.registerAlias(aliases);
25
+ if (prefix) {
26
+ const pos = prefix.indexOf('-');
27
+ name = pos > -1 ? prefix.slice(0, pos) : prefix;
28
+ }
29
+ /** Transform.*/
30
+ return function (tree, file) {
31
+ visit(tree, 'element', function (node, _, parent) {
32
+ if (node.tagName !== 'code' ||
33
+ !parent ||
34
+ parent.type !== 'element' ||
35
+ parent.tagName !== 'pre') {
36
+ return;
37
+ }
38
+ const lang = language(node);
39
+ if (lang === 'no-highlight' ||
40
+ (!lang && !detect) ||
41
+ (lang && plainText?.includes(lang))) {
42
+ return;
43
+ }
44
+ if (!Array.isArray(node.properties.className)) {
45
+ node.properties.className = [];
46
+ }
47
+ if (!node.properties.className.includes(name)) {
48
+ node.properties.className.unshift(name);
49
+ }
50
+ let result;
51
+ try {
52
+ result = lang
53
+ ? lowlight.highlight(lang, toText(parent), { prefix })
54
+ : lowlight.highlightAuto(toText(parent), { prefix, subset });
55
+ }
56
+ catch (error) {
57
+ const cause = error;
58
+ if (lang && /Unknown language/.test(cause.message)) {
59
+ file.message('Cannot highlight as `' + lang + '`, it’s not registered', {
60
+ ancestors: [parent, node],
61
+ cause,
62
+ place: node.position,
63
+ ruleId: 'missing-language',
64
+ source: 'rehype-highlight',
65
+ });
66
+ /* c8 ignore next 5 -- throw arbitrary hljs errors */
67
+ return;
68
+ }
69
+ throw cause;
70
+ }
71
+ if (!lang && result.data?.language) {
72
+ node.properties.className.push('language-' + result.data.language);
73
+ }
74
+ if (result.children.length > 0) {
75
+ node.children = result.children;
76
+ }
77
+ });
78
+ };
79
+ }
80
+ /** Get the programming language of `node` or an empty string */
81
+ function language(node) {
82
+ const list = node.properties.className;
83
+ if (!Array.isArray(list))
84
+ return '';
85
+ const name = list.reduce((result, _item) => {
86
+ if (result)
87
+ return result;
88
+ const item = String(_item);
89
+ if (item === 'no-highlight' || item === 'nohighlight')
90
+ return 'no-highlight';
91
+ if (item.slice(0, 5) === 'lang-')
92
+ return item.slice(5);
93
+ if (item.slice(0, 9) === 'language-')
94
+ return item.slice(9);
95
+ return result;
96
+ }, '');
97
+ return lowlightLanguageMappings[name || ''] || name;
98
+ }
99
+
100
+ export { rehypeHighlight };
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "@scalar/code-highlight",
3
+ "description": "Central methods and themes for code highlighting in Scalar projects",
4
+ "license": "MIT",
5
+ "author": "Scalar (https://github.com/scalar)",
6
+ "homepage": "https://github.com/scalar/scalar",
7
+ "bugs": "https://github.com/scalar/scalar/issues/new/choose",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/scalar/scalar.git",
11
+ "directory": "packages/code-highlight"
12
+ },
13
+ "keywords": [
14
+ "syntax",
15
+ "highlight",
16
+ "lowlight",
17
+ "highlightjs"
18
+ ],
19
+ "version": "0.0.2",
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "type": "module",
24
+ "main": "dist/index.js",
25
+ "exports": {
26
+ ".": {
27
+ "import": "./dist/index.js",
28
+ "types": "./dist/index.d.ts"
29
+ },
30
+ "./rehype-highlight": {
31
+ "import": "./dist/rehype-highlight/index.js",
32
+ "types": "./dist/rehype-highlight/index.d.ts"
33
+ },
34
+ "./markdown": {
35
+ "import": "./dist/markdown/index.js",
36
+ "types": "./dist/markdown/index.d.ts"
37
+ },
38
+ "./languages": {
39
+ "import": "./dist/languages/index.js",
40
+ "types": "./dist/languages/index.d.ts"
41
+ },
42
+ "./code": {
43
+ "import": "./dist/code/index.js",
44
+ "types": "./dist/code/index.d.ts"
45
+ },
46
+ "./css/*.css": {
47
+ "import": "./dist/css/*.css",
48
+ "require": "./dist/css/*.css"
49
+ },
50
+ "./*.css": {
51
+ "import": "./dist/*.css",
52
+ "require": "./dist/*.css"
53
+ }
54
+ },
55
+ "files": [
56
+ "dist",
57
+ "CHANGELOG.md"
58
+ ],
59
+ "module": "dist/index.js",
60
+ "sideEffects": false,
61
+ "dependencies": {
62
+ "hast-util-to-text": "^4.0.2",
63
+ "highlight.js": "^11.9.0",
64
+ "highlightjs-curl": "^1.3.0",
65
+ "highlightjs-vue": "^1.0.0",
66
+ "lowlight": "^3.1.0",
67
+ "rehype-external-links": "^3.0.0",
68
+ "rehype-format": "^5.0.0",
69
+ "rehype-highlight": "^7.0.0",
70
+ "rehype-parse": "^9.0.0",
71
+ "rehype-raw": "^7.0.0",
72
+ "rehype-sanitize": "^6.0.0",
73
+ "rehype-stringify": "^10.0.0",
74
+ "remark-gfm": "^4.0.0",
75
+ "remark-parse": "^11.0.0",
76
+ "remark-rehype": "^11.1.0",
77
+ "unified": "^11.0.4",
78
+ "unist-util-visit": "^5.0.0"
79
+ },
80
+ "devDependencies": {
81
+ "@rollup/plugin-typescript": "^11.1.6",
82
+ "@types/hast": "^3.0.4",
83
+ "rollup": "^4.16.4",
84
+ "tsc-alias": "^1.8.8",
85
+ "vfile": "^6.0.1",
86
+ "vite": "^5.2.10",
87
+ "vue": "^3.4.22",
88
+ "@scalar/themes": "0.9.0",
89
+ "@scalar/build-tooling": "0.1.5"
90
+ },
91
+ "scripts": {
92
+ "build": "scalar-build-rollup",
93
+ "dev": "vite",
94
+ "format": "scalar-format-js",
95
+ "lint:check": "eslint .",
96
+ "lint:fix": "eslint . --fix",
97
+ "test": "vitest",
98
+ "types:build": "scalar-types-build",
99
+ "types:check": "scalar-types-check"
100
+ }
101
+ }