Skip to content

Commit e23b940

Browse files
committed
Created new language generation script.
1 parent c22c5ac commit e23b940

File tree

7 files changed

+195
-103
lines changed

7 files changed

+195
-103
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 start",
1112
"build": "pnpm run --filter prism-react-renderer build",
1213
"build:watch": "pnpm run --filter prism-react-renderer build:watch"
1314
},
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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+
try {
34+
await access(pathToLanguage, constants.R_OK)
35+
const buffer = await readFile(pathToLanguage, { encoding: "utf-8" })
36+
return buffer.toString()
37+
} catch (e) {
38+
return ""
39+
}
40+
}
41+
42+
const strArrayFromUnknown = (input: unknown) => (array: string[]) => {
43+
if (typeof input === "string") array.push(input)
44+
else if (Array.isArray(input)) {
45+
array = [...array, ...input.filter(i => typeof i === "string")]
46+
}
47+
return array
48+
}
49+
50+
const main = async () => {
51+
let output = ""
52+
const bundledLanguages = new Set<keyof typeof prismLanguages>()
53+
const orderBundled = new Set<keyof typeof prismLanguages>()
54+
const outputPath = join(
55+
__dirname,
56+
"../prism-react-renderer/src/prism-langs.ts"
57+
)
58+
59+
const addLanguageToOutput = async (language: string) => {
60+
if (bundledLanguages.has(language)) {
61+
return
62+
}
63+
if (prismLanguages[language] == null) {
64+
return
65+
}
66+
bundledLanguages.add(language)
67+
68+
/**
69+
* We need to ensure any language dependencies are bundled first
70+
*/
71+
const prismLang = prismLanguages[language]
72+
const deps = flowRight(
73+
strArrayFromUnknown(prismLang.require),
74+
strArrayFromUnknown(prismLang.optional)
75+
)([])
76+
const peerDeps = strArrayFromUnknown(prismLang.peerDependencies)([])
77+
78+
for await (const language of deps) {
79+
await addLanguageToOutput(language)
80+
}
81+
82+
output += await readLanguageFile(language)
83+
orderBundled.add(language)
84+
85+
for await (const language of peerDeps) {
86+
await addLanguageToOutput(language)
87+
}
88+
}
89+
90+
for await (const language of languagesToBundle) {
91+
await addLanguageToOutput(language)
92+
}
93+
94+
console.info(
95+
pc.bold(pc.bgYellow(pc.black("Formidable Prism React Renderer"))),
96+
"\n"
97+
)
98+
console.info(
99+
pc.bgBlue(`Generated TypeScript output at:`),
100+
pc.cyan(outputPath)
101+
)
102+
console.info(
103+
pc.bgGreen(`Included language definitions in the following order:`),
104+
Array.from(orderBundled.values()).join(", ")
105+
)
106+
107+
await writeFile(outputPath, header + uglify.minify(output).code)
108+
}
109+
110+
main()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "generate-prism-languages",
3+
"private": true,
4+
"scripts": {
5+
"start": "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+
},
22+
"dependencies": {
23+
"lodash.flowright": "^3.5.0"
24+
}
25+
}
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
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}'",
2423
"format": "prettier --write 'src/**/*.js'",
25-
"prepublishOnly": "run-p flow build",
26-
"build:languages": "ts-node ./scripts/generate-base-languages.ts"
24+
"prepublishOnly": "run-p flow build"
2725
},
2826
"peerDependencies": {
2927
"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)