Skip to content

Commit ac3e23a

Browse files
authored
Ignore unknown lang with shiki plugin (#130)
1 parent 22b016b commit ac3e23a

4 files changed

Lines changed: 48 additions & 17 deletions

File tree

fixtures/code.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ module MyModule {
6060
declare magicNumber number;
6161
myArray.forEach(() => { }); // fat arrow syntax
6262
```
63+
64+
```unknown
65+
unknown lang
66+
```

src/__snapshots__/index.spec.ts.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3307,7 +3307,9 @@ exports[`e2e > code 1`] = `
33073307
w:val="false"
33083308
/><w:color w:val="6A9955" /></w:rPr><w:t
33093309
xml:space="preserve"
3310-
>// fat arrow syntax</w:t></w:r></w:p><w:sectPr><w:pgSz
3310+
>// fat arrow syntax</w:t></w:r></w:p><w:r><w:t
3311+
xml:space="preserve"
3312+
>unknown lang</w:t></w:r><w:sectPr><w:pgSz
33113313
w:w="11906"
33123314
w:h="16838"
33133315
w:orient="portrait"

src/mdast-util-to-docx.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,31 @@ const createNumberingRegistry = (): NumberingRegistry => {
156156
};
157157
};
158158

159+
const composeBuilders = (
160+
pluginsBuilders: readonly NodeBuilders[],
161+
defaultBuilders: NodeBuilders,
162+
): NodeBuilders => {
163+
return pluginsBuilders.reduceRight<NodeBuilders>((acc, p) => {
164+
type Key = keyof typeof p;
165+
for (const k of Object.keys(p)) {
166+
const cur = p[k as Key]!;
167+
const prev = acc[k as Key];
168+
acc[k as Key] = (
169+
prev
170+
? (n, c) => {
171+
const r = cur(n as any, c);
172+
if (r) {
173+
return r;
174+
}
175+
return prev(n as any, c);
176+
}
177+
: cur
178+
) as NodeBuilder<any>;
179+
}
180+
return acc;
181+
}, defaultBuilders);
182+
};
183+
159184
export interface DocxOptions extends Pick<
160185
IPropertiesOptions,
161186
| "title"
@@ -192,16 +217,8 @@ export const mdastToDocx = async (
192217

193218
const pluginCtx = { root: node, definition };
194219

195-
const builders = (
196-
await Promise.all(plugins.map((p) => p(pluginCtx)))
197-
).reduceRight<NodeBuilders>(
198-
(acc, p) => {
199-
type Key = keyof typeof p;
200-
for (const k of Object.keys(p)) {
201-
acc[k as Key] = p[k as Key] as any;
202-
}
203-
return acc;
204-
},
220+
const builders = composeBuilders(
221+
await Promise.all(plugins.map((p) => p(pluginCtx))),
205222
{
206223
paragraph: buildParagraph,
207224
heading: buildHeading,

src/plugins/shiki/index.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "shiki";
88
import { visit } from "unist-util-visit";
99
import type { FontStyle } from "shiki/textmate";
10+
import { warnOnce } from "../../utils";
1011

1112
/**
1213
* Format to 6 disit hex
@@ -41,6 +42,7 @@ export const shikiPlugin = ({
4142
}: ShikiPluginOptions): RemarkDocxPlugin => {
4243
let highlighter: Awaited<ReturnType<typeof createHighlighter>> | undefined;
4344
const langs = new Set<string>();
45+
const failedLangs = new Set<string>();
4446

4547
return async ({ root }) => {
4648
const newLangs: string[] = [];
@@ -57,17 +59,23 @@ export const shikiPlugin = ({
5759
if (!highlighter) {
5860
highlighter = await createHighlighter({
5961
themes: [theme],
60-
langs: [...langs],
62+
langs: [],
6163
});
62-
} else {
63-
await Promise.all(
64-
newLangs.map((l) => highlighter!.loadLanguage(l as BundledLanguage)),
65-
);
6664
}
65+
await Promise.all(
66+
newLangs.map(async (l) => {
67+
try {
68+
await highlighter!.loadLanguage(l as BundledLanguage);
69+
} catch (e) {
70+
failedLangs.add(l);
71+
warnOnce(String(e));
72+
}
73+
}),
74+
);
6775

6876
return {
6977
code: ({ value, lang }) => {
70-
if (!lang) {
78+
if (!lang || failedLangs.has(lang)) {
7179
return null;
7280
}
7381
const res = highlighter!.codeToTokens(value, {

0 commit comments

Comments
 (0)