Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"license": "MIT",
"repository": "https://github.com/FormidableLabs/prism-react-renderer",
"scripts": {
"postinstall": "pnpm run --filter generate-prism-languages generate",
"build": "pnpm run --filter prism-react-renderer build",
"build:watch": "pnpm run --filter prism-react-renderer build:watch"
},
Expand Down
104 changes: 104 additions & 0 deletions packages/generate-prism-languages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import flowRight from "lodash.flowright"
import pc from "picocolors"
import { readFile, writeFile, access } from "node:fs/promises"
import { constants } from "node:fs"
import { join, dirname } from "node:path"
import { languages as prismLanguages } from "prismjs/components"
import uglify from "uglify-js"

export const languagesToBundle = <const>[
"jsx",
"tsx",
"swift",
"kotlin",
"objectivec",
"rust",
"graphql",
"yaml",
"go",
"cpp",
"markdown",
]

/**
* We need to disable typechecking on this generated file as it's just concatenating JS code
* that starts off assuming Prism lives in global scope. We also need to provide Prism as that
* gets passed into an iffe preventing us from needing to use global scope.
*/
const header = `// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport Prism from "prismjs"\n`
const prismPath = dirname(require.resolve("prismjs"))

const readLanguageFile = async (language: string): Promise<string> => {
const pathToLanguage = join(prismPath, `components/prism-${language}.js`)
await access(pathToLanguage, constants.R_OK)
const buffer = await readFile(pathToLanguage, { encoding: "utf-8" })
return buffer.toString()
}

const strArrayFromUnknown = (input: unknown) => (array: string[]) => {
if (typeof input === "string") array.push(input)
else if (Array.isArray(input)) array = array.concat(input)
return array
}

const main = async () => {
let output = ""
const bundledLanguages = new Set<keyof typeof prismLanguages>()
const orderBundled = new Set<keyof typeof prismLanguages>()
const outputPath = join(
__dirname,
"../prism-react-renderer/src/prism-langs.ts"
)

const addLanguageToOutput = async (language?: string) => {
if (bundledLanguages.has(language)) {
return
}
if (language == null || prismLanguages[language] == null) {
return
}
bundledLanguages.add(language)

/**
* We need to ensure any language dependencies are bundled first
*/
const prismLang = prismLanguages[language]
const deps = flowRight(
strArrayFromUnknown(prismLang.require),
strArrayFromUnknown(prismLang.optional)
)([])
const peerDeps = strArrayFromUnknown(prismLang.peerDependencies)([])

for await (const language of deps) {
await addLanguageToOutput(language)
}

output += await readLanguageFile(language)
orderBundled.add(language)

for await (const language of peerDeps) {
await addLanguageToOutput(language)
}
}

for await (const language of languagesToBundle) {
await addLanguageToOutput(language)
}

console.info(
pc.bold(pc.bgYellow(pc.black("Formidable Prism React Renderer"))),
"\n"
)
console.info(
pc.bgBlue(`Generated TypeScript output at:`),
pc.cyan(outputPath)
)
console.info(
pc.bgGreen(`Included language definitions in the following order:`),
Array.from(orderBundled.values()).join(", ")
)

await writeFile(outputPath, header + uglify.minify(output).code)
}

main()
23 changes: 23 additions & 0 deletions packages/generate-prism-languages/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "generate-prism-languages",
"private": true,
"scripts": {
"generate": "ts-node ./index.ts"
},
"peerDependencies": {
"react": ">=16.0.0"
},
"devDependencies": {
"@types/lodash.flowright": "^3.5.7",
"@types/node": "^18.15.11",
"@types/prismjs": "^1.26.0",
"@types/uglify-js": "^3.17.1",
"picocolors": "^1.0.0",
"prismjs": "*",
"ts-node": "^10.9.1",
"tslib": "^2.5.0",
"typescript": "*",
"uglify-js": "^3.17.4",
"lodash.flowright": "^3.5.0"
}
}
5 changes: 5 additions & 0 deletions packages/generate-prism-languages/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"esModuleInterop": true,
}
}
5 changes: 1 addition & 4 deletions packages/prism-react-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@
"themes"
],
"scripts": {
"postinstall": "pnpm run build:languages",
"prebuild": "patch-package",
"build": "tsup",
"build:watch": "tsup --watch",
"test": "jest",
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
"format": "prettier --write 'src/**/*.js'",
"prepublishOnly": "run-p flow build",
"build:languages": "ts-node ./scripts/generate-base-languages.ts"
"format": "prettier --write 'src/**/*.js'"
},
"peerDependencies": {
"react": ">=16.0.0"
Expand Down
100 changes: 0 additions & 100 deletions packages/prism-react-renderer/scripts/generate-base-languages.ts

This file was deleted.

53 changes: 53 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.