Skip to content

Commit 82efe61

Browse files
feat: mdx double formatting (#631)
* feat: advanced mdx * chore: changeset * feat: double formatting for mdx
1 parent 313f8c3 commit 82efe61

4 files changed

Lines changed: 145 additions & 56 deletions

File tree

.changeset/olive-otters-rule.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@lingo.dev/_spec": minor
3+
"lingo.dev": minor
4+
---
5+
6+
double formatting for mdx

.changeset/tasty-swans-explode.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@lingo.dev/_spec": minor
3+
"lingo.dev": minor
4+
---
5+
6+
advanced mdx support (shout out to @ZYJLiu!)

packages/cli/src/cli/loaders/index.ts

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import createAndroidLoader from "./android";
1212
import createCsvLoader from "./csv";
1313
import createHtmlLoader from "./html";
1414
import createMarkdownLoader from "./markdown";
15-
import { createMdxFormatLoader, createMdxStructureLoader } from "./mdx";
15+
import {
16+
createDoubleSerializationLoader,
17+
createMdxFormatLoader,
18+
createMdxStructureLoader,
19+
} from "./mdx";
1620
import createPropertiesLoader from "./properties";
1721
import createXcodeStringsLoader from "./xcode-strings";
1822
import createXcodeStringsdictLoader from "./xcode-stringsdict";
@@ -55,23 +59,32 @@ export default function createBucketLoader(
5559
createAndroidLoader(),
5660
createFlatLoader(),
5761
createSyncLoader(),
58-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
62+
createUnlocalizableLoader(
63+
options.isCacheRestore,
64+
options.returnUnlocalizedKeys,
65+
),
5966
);
6067
case "csv":
6168
return composeLoaders(
6269
createTextFileLoader(bucketPathPattern),
6370
createCsvLoader(),
6471
createFlatLoader(),
6572
createSyncLoader(),
66-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
73+
createUnlocalizableLoader(
74+
options.isCacheRestore,
75+
options.returnUnlocalizedKeys,
76+
),
6777
);
6878
case "html":
6979
return composeLoaders(
7080
createTextFileLoader(bucketPathPattern),
7181
createPrettierLoader({ parser: "html", bucketPathPattern }),
7282
createHtmlLoader(),
7383
createSyncLoader(),
74-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
84+
createUnlocalizableLoader(
85+
options.isCacheRestore,
86+
options.returnUnlocalizedKeys,
87+
),
7588
);
7689
case "json":
7790
return composeLoaders(
@@ -82,15 +95,35 @@ export default function createBucketLoader(
8295
createFlatLoader(),
8396
createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
8497
createSyncLoader(),
85-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
98+
createUnlocalizableLoader(
99+
options.isCacheRestore,
100+
options.returnUnlocalizedKeys,
101+
),
86102
);
87103
case "markdown":
88104
return composeLoaders(
89105
createTextFileLoader(bucketPathPattern),
90106
createPrettierLoader({ parser: "markdown", bucketPathPattern }),
91107
createMarkdownLoader(),
92108
createSyncLoader(),
93-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
109+
createUnlocalizableLoader(
110+
options.isCacheRestore,
111+
options.returnUnlocalizedKeys,
112+
),
113+
);
114+
case "mdx":
115+
return composeLoaders(
116+
createTextFileLoader(bucketPathPattern),
117+
createDoubleSerializationLoader(),
118+
createPrettierLoader({ parser: "mdx", bucketPathPattern }),
119+
createMdxFormatLoader(),
120+
createFlatLoader(),
121+
createMdxStructureLoader(),
122+
createSyncLoader(),
123+
createUnlocalizableLoader(
124+
options.isCacheRestore,
125+
options.returnUnlocalizedKeys,
126+
),
94127
);
95128
case "mdx":
96129
return composeLoaders(
@@ -109,29 +142,41 @@ export default function createBucketLoader(
109142
createFlatLoader(),
110143
createSyncLoader(),
111144
createVariableLoader({ type: "python" }),
112-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
145+
createUnlocalizableLoader(
146+
options.isCacheRestore,
147+
options.returnUnlocalizedKeys,
148+
),
113149
);
114150
case "properties":
115151
return composeLoaders(
116152
createTextFileLoader(bucketPathPattern),
117153
createPropertiesLoader(),
118154
createSyncLoader(),
119-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
155+
createUnlocalizableLoader(
156+
options.isCacheRestore,
157+
options.returnUnlocalizedKeys,
158+
),
120159
);
121160
case "xcode-strings":
122161
return composeLoaders(
123162
createTextFileLoader(bucketPathPattern),
124163
createXcodeStringsLoader(),
125164
createSyncLoader(),
126-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
165+
createUnlocalizableLoader(
166+
options.isCacheRestore,
167+
options.returnUnlocalizedKeys,
168+
),
127169
);
128170
case "xcode-stringsdict":
129171
return composeLoaders(
130172
createTextFileLoader(bucketPathPattern),
131173
createXcodeStringsdictLoader(),
132174
createFlatLoader(),
133175
createSyncLoader(),
134-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
176+
createUnlocalizableLoader(
177+
options.isCacheRestore,
178+
options.returnUnlocalizedKeys,
179+
),
135180
);
136181
case "xcode-xcstrings":
137182
return composeLoaders(
@@ -142,7 +187,10 @@ export default function createBucketLoader(
142187
createFlatLoader(),
143188
createSyncLoader(),
144189
createVariableLoader({ type: "ieee" }),
145-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
190+
createUnlocalizableLoader(
191+
options.isCacheRestore,
192+
options.returnUnlocalizedKeys,
193+
),
146194
);
147195
case "yaml":
148196
return composeLoaders(
@@ -152,7 +200,10 @@ export default function createBucketLoader(
152200
createFlatLoader(),
153201
createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
154202
createSyncLoader(),
155-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
203+
createUnlocalizableLoader(
204+
options.isCacheRestore,
205+
options.returnUnlocalizedKeys,
206+
),
156207
);
157208
case "yaml-root-key":
158209
return composeLoaders(
@@ -162,7 +213,10 @@ export default function createBucketLoader(
162213
createRootKeyLoader(true),
163214
createFlatLoader(),
164215
createSyncLoader(),
165-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
216+
createUnlocalizableLoader(
217+
options.isCacheRestore,
218+
options.returnUnlocalizedKeys,
219+
),
166220
);
167221
case "flutter":
168222
return composeLoaders(
@@ -172,60 +226,84 @@ export default function createBucketLoader(
172226
createFlutterLoader(),
173227
createFlatLoader(),
174228
createSyncLoader(),
175-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
229+
createUnlocalizableLoader(
230+
options.isCacheRestore,
231+
options.returnUnlocalizedKeys,
232+
),
176233
);
177234
case "xliff":
178235
return composeLoaders(
179236
createTextFileLoader(bucketPathPattern),
180237
createXliffLoader(),
181238
createFlatLoader(),
182239
createSyncLoader(),
183-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
240+
createUnlocalizableLoader(
241+
options.isCacheRestore,
242+
options.returnUnlocalizedKeys,
243+
),
184244
);
185245
case "xml":
186246
return composeLoaders(
187247
createTextFileLoader(bucketPathPattern),
188248
createXmlLoader(),
189249
createFlatLoader(),
190250
createSyncLoader(),
191-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
251+
createUnlocalizableLoader(
252+
options.isCacheRestore,
253+
options.returnUnlocalizedKeys,
254+
),
192255
);
193256
case "srt":
194257
return composeLoaders(
195258
createTextFileLoader(bucketPathPattern),
196259
createSrtLoader(),
197260
createSyncLoader(),
198-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
261+
createUnlocalizableLoader(
262+
options.isCacheRestore,
263+
options.returnUnlocalizedKeys,
264+
),
199265
);
200266
case "dato":
201267
return composeLoaders(
202268
createDatoLoader(bucketPathPattern),
203269
createSyncLoader(),
204270
createFlatLoader(),
205-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
271+
createUnlocalizableLoader(
272+
options.isCacheRestore,
273+
options.returnUnlocalizedKeys,
274+
),
206275
);
207276
case "vtt":
208277
return composeLoaders(
209278
createTextFileLoader(bucketPathPattern),
210279
createVttLoader(),
211280
createSyncLoader(),
212-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
281+
createUnlocalizableLoader(
282+
options.isCacheRestore,
283+
options.returnUnlocalizedKeys,
284+
),
213285
);
214286
case "php":
215287
return composeLoaders(
216288
createTextFileLoader(bucketPathPattern),
217289
createPhpLoader(),
218290
createSyncLoader(),
219291
createFlatLoader(),
220-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
292+
createUnlocalizableLoader(
293+
options.isCacheRestore,
294+
options.returnUnlocalizedKeys,
295+
),
221296
);
222297
case "vue-json":
223298
return composeLoaders(
224299
createTextFileLoader(bucketPathPattern),
225300
createVueJsonLoader(),
226301
createSyncLoader(),
227302
createFlatLoader(),
228-
createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys),
303+
createUnlocalizableLoader(
304+
options.isCacheRestore,
305+
options.returnUnlocalizedKeys,
306+
),
229307
);
230308
}
231309
}

packages/cli/src/cli/loaders/mdx.ts

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,59 +9,58 @@ import remarkMdxFrontmatter from "remark-mdx-frontmatter";
99
import { VFile } from "vfile";
1010
import { Root } from "mdast";
1111
import { ILoader } from "./_types";
12-
import { composeLoaders, createLoader } from "./_utils";
12+
import { createLoader } from "./_utils";
1313

14-
// Define MDX node types
15-
type MdxNode = {
16-
type: string;
17-
[key: string]: any;
18-
};
14+
const parser = unified()
15+
.use(remarkParse)
16+
.use(remarkMdx)
17+
.use(remarkFrontmatter, ["yaml"])
18+
.use(remarkMdxFrontmatter)
19+
.use(remarkGfm);
1920

20-
type MdxTree = {
21-
type: "root";
22-
children: MdxNode[];
23-
};
21+
const serializer = unified()
22+
.use(remarkStringify)
23+
.use(remarkMdx)
24+
.use(remarkFrontmatter, ["yaml"])
25+
.use(remarkMdxFrontmatter)
26+
.use(remarkGfm);
2427

2528
export function createMdxFormatLoader(): ILoader<string, Record<string, any>> {
26-
// Create a unified processor for MDX parsing with all required plugins
27-
const parser = unified()
28-
.use(remarkParse)
29-
.use(remarkMdx)
30-
.use(remarkFrontmatter, ["yaml"])
31-
.use(remarkMdxFrontmatter)
32-
.use(remarkGfm);
33-
34-
// Create a unified processor for MDX serialization
35-
const serializer = unified()
36-
.use(remarkStringify)
37-
.use(remarkMdx)
38-
.use(remarkFrontmatter, ["yaml"])
39-
.use(remarkMdxFrontmatter)
40-
.use(remarkGfm);
41-
4229
return createLoader({
4330
async pull(locale, input) {
44-
// Parse the MDX content into an AST
4531
const file = new VFile(input);
4632
const ast = parser.parse(file);
47-
48-
// Instead of returning the AST directly, convert it to a plain object
49-
// This ensures compatibility with the ILoader interface
5033
return JSON.parse(JSON.stringify(ast));
5134
},
5235

5336
async push(locale, data) {
54-
// Recreate an AST from the plain object
5537
const ast = data as unknown as Root;
38+
const content = String(serializer.stringify(ast));
39+
return content;
40+
},
41+
});
42+
}
43+
44+
export function createDoubleSerializationLoader(): ILoader<string, string> {
45+
return createLoader({
46+
async pull(locale, input) {
47+
return input;
48+
},
49+
50+
async push(locale, data) {
51+
const file = new VFile(data);
52+
const ast = parser.parse(file);
5653

57-
// Serialize the AST back to MDX content
58-
const file = serializer.stringify(ast);
59-
return String(file);
54+
const finalContent = String(serializer.stringify(ast));
55+
return finalContent;
6056
},
6157
});
6258
}
6359

64-
export function createMdxStructureLoader(): ILoader<Record<string, any>, Record<string, string>> {
60+
export function createMdxStructureLoader(): ILoader<
61+
Record<string, any>,
62+
Record<string, string>
63+
> {
6564
return createLoader({
6665
async pull(locale, input) {
6766
const result = _.chain(input)

0 commit comments

Comments
 (0)