Skip to content

Commit e0c503c

Browse files
Merge pull request #186 from FormidableLabs/v2-gen-lang-script
New Prism Language file generation script for v2
2 parents c22c5ac + ce472ae commit e0c503c

File tree

7 files changed

+187
-104
lines changed

7 files changed

+187
-104
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"license": "MIT",
99
"repository": "https://github.com/FormidableLabs/prism-react-renderer",
1010
"scripts": {
11+
"postinstall": "pnpm run --filter generate-prism-languages generate",
1112
"build": "pnpm run --filter prism-react-renderer build",
1213
"build:watch": "pnpm run --filter prism-react-renderer build:watch"
1314
},
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import flowRight from "lodash.flowright"
2+
import pc from "picocolors"
3+
import { readFile, writeFile, access } from "node:fs/promises"
4+
import { constants } from "node:fs"
5+
import { join, dirname } from "node:path"
6+
import { languages as prismLanguages } from "prismjs/components"
7+
import uglify from "uglify-js"
8+
9+
export const languagesToBundle = <const>[
10+
"jsx",
11+
"tsx",
12+
"swift",
13+
"kotlin",
14+
"objectivec",
15+
"rust",
16+
"graphql",
17+
"yaml",
18+
"go",
19+
"cpp",
20+
"markdown",
21+
]
22+
23+
/**
24+
* We need to disable typechecking on this generated file as it's just concatenating JS code
25+
* that starts off assuming Prism lives in global scope. We also need to provide Prism as that
26+
* gets passed into an iffe preventing us from needing to use global scope.
27+
*/
28+
const header = `// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport Prism from "prismjs"\n`
29+
const prismPath = dirname(require.resolve("prismjs"))
30+
31+
const readLanguageFile = async (language: string): Promise<string> => {
32+
const pathToLanguage = join(prismPath, `components/prism-${language}.js`)
33+
await access(pathToLanguage, constants.R_OK)
34+
const buffer = await readFile(pathToLanguage, { encoding: "utf-8" })
35+
return buffer.toString()
36+
}
37+
38+
const strArrayFromUnknown = (input: unknown) => (array: string[]) => {
39+
if (typeof input === "string") array.push(input)
40+
else if (Array.isArray(input)) array = array.concat(input)
41+
return array
42+
}
43+
44+
const main = async () => {
45+
let output = ""
46+
const bundledLanguages = new Set<keyof typeof prismLanguages>()
47+
const orderBundled = new Set<keyof typeof prismLanguages>()
48+
const outputPath = join(
49+
__dirname,
50+
"../prism-react-renderer/src/prism-langs.ts"
51+
)
52+
53+
const addLanguageToOutput = async (language?: string) => {
54+
if (bundledLanguages.has(language)) {
55+
return
56+
}
57+
if (language == null || prismLanguages[language] == null) {
58+
return
59+
}
60+
bundledLanguages.add(language)
61+
62+
/**
63+
* We need to ensure any language dependencies are bundled first
64+
*/
65+
const prismLang = prismLanguages[language]
66+
const deps = flowRight(
67+
strArrayFromUnknown(prismLang.require),
68+
strArrayFromUnknown(prismLang.optional)
69+
)([])
70+
const peerDeps = strArrayFromUnknown(prismLang.peerDependencies)([])
71+
72+
for await (const language of deps) {
73+
await addLanguageToOutput(language)
74+
}
75+
76+
output += await readLanguageFile(language)
77+
orderBundled.add(language)
78+
79+
for await (const language of peerDeps) {
80+
await addLanguageToOutput(language)
81+
}
82+
}
83+
84+
for await (const language of languagesToBundle) {
85+
await addLanguageToOutput(language)
86+
}
87+
88+
console.info(
89+
pc.bold(pc.bgYellow(pc.black("Formidable Prism React Renderer"))),
90+
"\n"
91+
)
92+
console.info(
93+
pc.bgBlue(`Generated TypeScript output at:`),
94+
pc.cyan(outputPath)
95+
)
96+
console.info(
97+
pc.bgGreen(`Included language definitions in the following order:`),
98+
Array.from(orderBundled.values()).join(", ")
99+
)
100+
101+
await writeFile(outputPath, header + uglify.minify(output).code)
102+
}
103+
104+
main()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "generate-prism-languages",
3+
"private": true,
4+
"scripts": {
5+
"generate": "ts-node ./index.ts"
6+
},
7+
"peerDependencies": {
8+
"react": ">=16.0.0"
9+
},
10+
"devDependencies": {
11+
"@types/lodash.flowright": "^3.5.7",
12+
"@types/node": "^18.15.11",
13+
"@types/prismjs": "^1.26.0",
14+
"@types/uglify-js": "^3.17.1",
15+
"picocolors": "^1.0.0",
16+
"prismjs": "*",
17+
"ts-node": "^10.9.1",
18+
"tslib": "^2.5.0",
19+
"typescript": "*",
20+
"uglify-js": "^3.17.4",
21+
"lodash.flowright": "^3.5.0"
22+
}
23+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"esModuleInterop": true,
4+
}
5+
}

packages/prism-react-renderer/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,12 @@
1515
"themes"
1616
],
1717
"scripts": {
18-
"postinstall": "pnpm run build:languages",
1918
"prebuild": "patch-package",
2019
"build": "tsup",
2120
"build:watch": "tsup --watch",
2221
"test": "jest",
2322
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
24-
"format": "prettier --write 'src/**/*.js'",
25-
"prepublishOnly": "run-p flow build",
26-
"build:languages": "ts-node ./scripts/generate-base-languages.ts"
23+
"format": "prettier --write 'src/**/*.js'"
2724
},
2825
"peerDependencies": {
2926
"react": ">=16.0.0"

packages/prism-react-renderer/scripts/generate-base-languages.ts

Lines changed: 0 additions & 100 deletions
This file was deleted.

pnpm-lock.yaml

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)