@scalar/code-highlight 0.0.6 → 0.0.8
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/CHANGELOG.md +12 -0
- package/dist/css/markdown.css +0 -5
- package/dist/markdown/index.d.ts +1 -1
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/markdown.d.ts +17 -2
- package/dist/markdown/markdown.d.ts.map +1 -1
- package/dist/markdown/markdown.js +109 -4
- package/package.json +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @scalar/code-highlight
|
|
2
2
|
|
|
3
|
+
## 0.0.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b910fc1: feat: new Markdown helper methods splitContent and getHeadings
|
|
8
|
+
|
|
9
|
+
## 0.0.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- c2362ee: fix: don't constrain markdown image height
|
|
14
|
+
|
|
3
15
|
## 0.0.6
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/css/markdown.css
CHANGED
|
@@ -197,11 +197,6 @@
|
|
|
197
197
|
border-bottom: 1px solid var(--scalar-border-color);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
.markdown img {
|
|
201
|
-
max-height: 150px;
|
|
202
|
-
border-radius: var(--scalar-radius);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
200
|
.markdown blockquote {
|
|
206
201
|
border-left: 3px solid var(--scalar-border-color);
|
|
207
202
|
padding-left: 12px;
|
package/dist/markdown/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './markdown.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/markdown/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/markdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
|
package/dist/markdown/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { htmlFromMarkdown } from './markdown.js';
|
|
1
|
+
export { getHeadings, htmlFromMarkdown, splitContent } from './markdown.js';
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Take a Markdown string and generate HTML from it
|
|
3
|
+
*/
|
|
4
|
+
export declare function htmlFromMarkdown(markdown: string, options?: {
|
|
3
5
|
removeTags?: string[];
|
|
4
6
|
allowTags?: string[];
|
|
7
|
+
transform?: (node: Record<string, any>) => Record<string, any>;
|
|
8
|
+
transformType?: string;
|
|
5
9
|
}): string;
|
|
10
|
+
/**
|
|
11
|
+
* Find all headings of a specific type in a Markdown AST.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getHeadings(markdown: string, depth?: number): {
|
|
14
|
+
depth: number;
|
|
15
|
+
value: string;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* Return multiple Markdown documents. Every heading should be its own document.
|
|
19
|
+
*/
|
|
20
|
+
export declare function splitContent(markdown: string): string[];
|
|
6
21
|
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/markdown/markdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/markdown/markdown.ts"],"names":[],"mappings":"AA4CA;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACR,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,UAkDF;AASD;;GAEG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAU,GAChB;IACD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,EAAE,CAiBF;AAuBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,YAgC5C"}
|
|
@@ -6,12 +6,33 @@ import rehypeStringify from 'rehype-stringify';
|
|
|
6
6
|
import remarkGfm from 'remark-gfm';
|
|
7
7
|
import remarkParse from 'remark-parse';
|
|
8
8
|
import remarkRehype from 'remark-rehype';
|
|
9
|
+
import remarkStringify from 'remark-stringify';
|
|
9
10
|
import { unified } from 'unified';
|
|
11
|
+
import { visit, SKIP } from 'unist-util-visit';
|
|
10
12
|
import { rehypeHighlight } from '../rehype-highlight/rehype-highlight.js';
|
|
11
13
|
import { standardLanguages } from '../languages/standard.js';
|
|
12
14
|
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Plugin to transform nodes in a Markdown AST
|
|
17
|
+
*/
|
|
18
|
+
const transformNodes = function (options,
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
|
+
..._ignored) {
|
|
21
|
+
return (tree) => {
|
|
22
|
+
if (!options?.transform || !options?.type) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
visit(tree, options?.type, (node) => {
|
|
26
|
+
options?.transform ? options?.transform(node) : node;
|
|
27
|
+
return SKIP;
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Take a Markdown string and generate HTML from it
|
|
34
|
+
*/
|
|
35
|
+
function htmlFromMarkdown(markdown, options) {
|
|
15
36
|
// Add permitted tags and remove stripped ones
|
|
16
37
|
const removeTags = options?.removeTags ?? [];
|
|
17
38
|
const tagNames = [
|
|
@@ -23,6 +44,10 @@ function htmlFromMarkdown(markdownString, options) {
|
|
|
23
44
|
.use(remarkParse)
|
|
24
45
|
// Support autolink literals, footnotes, strikethrough, tables and tasklists
|
|
25
46
|
.use(remarkGfm)
|
|
47
|
+
.use(transformNodes, {
|
|
48
|
+
transform: options?.transform,
|
|
49
|
+
type: options?.transformType,
|
|
50
|
+
})
|
|
26
51
|
// Allows any HTML tags
|
|
27
52
|
.use(remarkRehype, { allowDangerousHtml: true })
|
|
28
53
|
// Creates a HTML AST
|
|
@@ -30,6 +55,8 @@ function htmlFromMarkdown(markdownString, options) {
|
|
|
30
55
|
// Removes disallowed tags
|
|
31
56
|
.use(rehypeSanitize, {
|
|
32
57
|
...defaultSchema,
|
|
58
|
+
// Don’t prefix the heading ids
|
|
59
|
+
clobberPrefix: '',
|
|
33
60
|
// Makes it even more strict
|
|
34
61
|
tagNames,
|
|
35
62
|
attributes: {
|
|
@@ -50,8 +77,86 @@ function htmlFromMarkdown(markdownString, options) {
|
|
|
50
77
|
// Converts the HTML AST to a string
|
|
51
78
|
.use(rehypeStringify)
|
|
52
79
|
// Run the pipeline
|
|
53
|
-
.processSync(
|
|
80
|
+
.processSync(markdown);
|
|
54
81
|
return html.toString();
|
|
55
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a Markdown AST from a string.
|
|
85
|
+
*/
|
|
86
|
+
function getMarkdownAst(markdown) {
|
|
87
|
+
return unified().use(remarkParse).use(remarkGfm).parse(markdown);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Find all headings of a specific type in a Markdown AST.
|
|
91
|
+
*/
|
|
92
|
+
function getHeadings(markdown, depth = 1) {
|
|
93
|
+
const tree = getMarkdownAst(markdown);
|
|
94
|
+
const nodes = [];
|
|
95
|
+
visit(tree, 'heading', (node) => {
|
|
96
|
+
const text = findTextInHeading(node);
|
|
97
|
+
if (text) {
|
|
98
|
+
nodes.push({ depth: node.depth ?? depth, value: text.value });
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return nodes;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Find the text in a Markdown node (recursively).
|
|
105
|
+
*/
|
|
106
|
+
function findTextInHeading(node) {
|
|
107
|
+
if (node.type === 'text') {
|
|
108
|
+
return node;
|
|
109
|
+
}
|
|
110
|
+
if ('children' in node && node.children) {
|
|
111
|
+
for (const child of node.children) {
|
|
112
|
+
const text = findTextInHeading(child);
|
|
113
|
+
if (text) {
|
|
114
|
+
return text;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Return multiple Markdown documents. Every heading should be its own document.
|
|
122
|
+
*/
|
|
123
|
+
function splitContent(markdown) {
|
|
124
|
+
const tree = getMarkdownAst(markdown);
|
|
125
|
+
/** Sections */
|
|
126
|
+
const sections = [];
|
|
127
|
+
/** Nodes inside a section */
|
|
128
|
+
let nodes = [];
|
|
129
|
+
tree.children?.forEach((node) => {
|
|
130
|
+
// If the node is a heading, start a new section
|
|
131
|
+
if (node.type === 'heading') {
|
|
132
|
+
if (nodes.length) {
|
|
133
|
+
sections.push(nodes);
|
|
134
|
+
}
|
|
135
|
+
sections.push([node]);
|
|
136
|
+
nodes = [];
|
|
137
|
+
}
|
|
138
|
+
// Otherwise, add the node to the current section
|
|
139
|
+
else {
|
|
140
|
+
nodes.push(node);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Add any remaining nodes
|
|
144
|
+
if (nodes.length) {
|
|
145
|
+
sections.push(nodes);
|
|
146
|
+
}
|
|
147
|
+
return sections.map((section) => createDocument(section));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Use remark to create a Markdown document from a list of nodes.
|
|
151
|
+
*/
|
|
152
|
+
function createDocument(nodes) {
|
|
153
|
+
// Create the Markdown string
|
|
154
|
+
const markdown = unified().use(remarkStringify).use(remarkGfm).stringify({
|
|
155
|
+
type: 'root',
|
|
156
|
+
children: nodes,
|
|
157
|
+
});
|
|
158
|
+
// Remove the whitespace
|
|
159
|
+
return markdown.trim();
|
|
160
|
+
}
|
|
56
161
|
|
|
57
|
-
export { htmlFromMarkdown };
|
|
162
|
+
export { getHeadings, htmlFromMarkdown, splitContent };
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"lowlight",
|
|
17
17
|
"highlightjs"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.0.
|
|
19
|
+
"version": "0.0.8",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
@@ -73,19 +73,21 @@
|
|
|
73
73
|
"remark-gfm": "^4.0.0",
|
|
74
74
|
"remark-parse": "^11.0.0",
|
|
75
75
|
"remark-rehype": "^11.1.0",
|
|
76
|
+
"remark-stringify": "^11.0.0",
|
|
76
77
|
"unified": "^11.0.4",
|
|
77
78
|
"unist-util-visit": "^5.0.0"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@rollup/plugin-typescript": "^11.1.6",
|
|
81
82
|
"@types/hast": "^3.0.4",
|
|
83
|
+
"@types/mdast": "^4.0.4",
|
|
84
|
+
"@types/unist": "^3.0.2",
|
|
82
85
|
"rollup": "^4.16.4",
|
|
83
|
-
"tsc-alias": "^1.8.8",
|
|
84
86
|
"vfile": "^6.0.1",
|
|
85
87
|
"vite": "^5.2.10",
|
|
86
|
-
"vue": "^3.4.
|
|
87
|
-
"@scalar/build-tooling": "0.1.
|
|
88
|
-
"@scalar/themes": "0.9.
|
|
88
|
+
"vue": "^3.4.29",
|
|
89
|
+
"@scalar/build-tooling": "0.1.10",
|
|
90
|
+
"@scalar/themes": "0.9.22"
|
|
89
91
|
},
|
|
90
92
|
"scripts": {
|
|
91
93
|
"build": "scalar-build-rollup",
|