|
| 1 | +import Prism from 'prismjs'; |
| 2 | +/** |
| 3 | + * |
| 4 | + * The dependencies map which syncs from |
| 5 | + * https://github.com/PrismJS/prism/blob/master/plugins/autoloader/prism-autoloader.js |
| 6 | + * |
| 7 | + */ |
| 8 | +const lang_dependencies = { |
| 9 | + javascript: 'clike', |
| 10 | + actionscript: 'javascript', |
| 11 | + apex: ['clike', 'sql'], |
| 12 | + arduino: 'cpp', |
| 13 | + aspnet: ['markup', 'csharp'], |
| 14 | + birb: 'clike', |
| 15 | + bison: 'c', |
| 16 | + c: 'clike', |
| 17 | + csharp: 'clike', |
| 18 | + cpp: 'c', |
| 19 | + cfscript: 'clike', |
| 20 | + chaiscript: ['clike', 'cpp'], |
| 21 | + cilkc: 'c', |
| 22 | + cilkcpp: 'cpp', |
| 23 | + coffeescript: 'javascript', |
| 24 | + crystal: 'ruby', |
| 25 | + 'css-extras': 'css', |
| 26 | + d: 'clike', |
| 27 | + dart: 'clike', |
| 28 | + django: 'markup-templating', |
| 29 | + ejs: ['javascript', 'markup-templating'], |
| 30 | + etlua: ['lua', 'markup-templating'], |
| 31 | + erb: ['ruby', 'markup-templating'], |
| 32 | + fsharp: 'clike', |
| 33 | + 'firestore-security-rules': 'clike', |
| 34 | + flow: 'javascript', |
| 35 | + ftl: 'markup-templating', |
| 36 | + gml: 'clike', |
| 37 | + glsl: 'c', |
| 38 | + go: 'clike', |
| 39 | + gradle: 'clike', |
| 40 | + groovy: 'clike', |
| 41 | + haml: 'ruby', |
| 42 | + handlebars: 'markup-templating', |
| 43 | + haxe: 'clike', |
| 44 | + hlsl: 'c', |
| 45 | + idris: 'haskell', |
| 46 | + java: 'clike', |
| 47 | + javadoc: ['markup', 'java', 'javadoclike'], |
| 48 | + jolie: 'clike', |
| 49 | + jsdoc: ['javascript', 'javadoclike', 'typescript'], |
| 50 | + 'js-extras': 'javascript', |
| 51 | + json5: 'json', |
| 52 | + jsonp: 'json', |
| 53 | + 'js-templates': 'javascript', |
| 54 | + kotlin: 'clike', |
| 55 | + latte: ['clike', 'markup-templating', 'php'], |
| 56 | + less: 'css', |
| 57 | + lilypond: 'scheme', |
| 58 | + liquid: 'markup-templating', |
| 59 | + markdown: 'markup', |
| 60 | + 'markup-templating': 'markup', |
| 61 | + mongodb: 'javascript', |
| 62 | + n4js: 'javascript', |
| 63 | + objectivec: 'c', |
| 64 | + opencl: 'c', |
| 65 | + parser: 'markup', |
| 66 | + php: 'markup-templating', |
| 67 | + phpdoc: ['php', 'javadoclike'], |
| 68 | + 'php-extras': 'php', |
| 69 | + plsql: 'sql', |
| 70 | + processing: 'clike', |
| 71 | + protobuf: 'clike', |
| 72 | + pug: ['markup', 'javascript'], |
| 73 | + purebasic: 'clike', |
| 74 | + purescript: 'haskell', |
| 75 | + qsharp: 'clike', |
| 76 | + qml: 'javascript', |
| 77 | + qore: 'clike', |
| 78 | + racket: 'scheme', |
| 79 | + cshtml: ['markup', 'csharp'], |
| 80 | + jsx: ['markup', 'javascript'], |
| 81 | + tsx: ['jsx', 'typescript'], |
| 82 | + reason: 'clike', |
| 83 | + ruby: 'clike', |
| 84 | + sass: 'css', |
| 85 | + scss: 'css', |
| 86 | + scala: 'java', |
| 87 | + 'shell-session': 'bash', |
| 88 | + smarty: 'markup-templating', |
| 89 | + solidity: 'clike', |
| 90 | + soy: 'markup-templating', |
| 91 | + sparql: 'turtle', |
| 92 | + sqf: 'clike', |
| 93 | + squirrel: 'clike', |
| 94 | + stata: ['mata', 'java', 'python'], |
| 95 | + 't4-cs': ['t4-templating', 'csharp'], |
| 96 | + 't4-vb': ['t4-templating', 'vbnet'], |
| 97 | + tap: 'yaml', |
| 98 | + tt2: ['clike', 'markup-templating'], |
| 99 | + textile: 'markup', |
| 100 | + twig: 'markup-templating', |
| 101 | + typescript: 'javascript', |
| 102 | + v: 'clike', |
| 103 | + vala: 'clike', |
| 104 | + vbnet: 'basic', |
| 105 | + velocity: 'markup', |
| 106 | + wiki: 'markup', |
| 107 | + xeora: 'markup', |
| 108 | + 'xml-doc': 'markup', |
| 109 | + xquery: 'markup', |
| 110 | +}; |
| 111 | + |
| 112 | +const lang_aliases = { |
| 113 | + html: 'markup', |
| 114 | + xml: 'markup', |
| 115 | + svg: 'markup', |
| 116 | + mathml: 'markup', |
| 117 | + ssml: 'markup', |
| 118 | + atom: 'markup', |
| 119 | + rss: 'markup', |
| 120 | + js: 'javascript', |
| 121 | + g4: 'antlr4', |
| 122 | + ino: 'arduino', |
| 123 | + 'arm-asm': 'armasm', |
| 124 | + art: 'arturo', |
| 125 | + adoc: 'asciidoc', |
| 126 | + avs: 'avisynth', |
| 127 | + avdl: 'avro-idl', |
| 128 | + gawk: 'awk', |
| 129 | + sh: 'bash', |
| 130 | + shell: 'bash', |
| 131 | + shortcode: 'bbcode', |
| 132 | + rbnf: 'bnf', |
| 133 | + oscript: 'bsl', |
| 134 | + cs: 'csharp', |
| 135 | + dotnet: 'csharp', |
| 136 | + cfc: 'cfscript', |
| 137 | + 'cilk-c': 'cilkc', |
| 138 | + 'cilk-cpp': 'cilkcpp', |
| 139 | + cilk: 'cilkcpp', |
| 140 | + coffee: 'coffeescript', |
| 141 | + conc: 'concurnas', |
| 142 | + jinja2: 'django', |
| 143 | + 'dns-zone': 'dns-zone-file', |
| 144 | + dockerfile: 'docker', |
| 145 | + gv: 'dot', |
| 146 | + eta: 'ejs', |
| 147 | + xlsx: 'excel-formula', |
| 148 | + xls: 'excel-formula', |
| 149 | + gamemakerlanguage: 'gml', |
| 150 | + po: 'gettext', |
| 151 | + gni: 'gn', |
| 152 | + ld: 'linker-script', |
| 153 | + 'go-mod': 'go-module', |
| 154 | + hbs: 'handlebars', |
| 155 | + mustache: 'handlebars', |
| 156 | + hs: 'haskell', |
| 157 | + idr: 'idris', |
| 158 | + gitignore: 'ignore', |
| 159 | + hgignore: 'ignore', |
| 160 | + npmignore: 'ignore', |
| 161 | + webmanifest: 'json', |
| 162 | + kt: 'kotlin', |
| 163 | + kts: 'kotlin', |
| 164 | + kum: 'kumir', |
| 165 | + tex: 'latex', |
| 166 | + context: 'latex', |
| 167 | + ly: 'lilypond', |
| 168 | + emacs: 'lisp', |
| 169 | + elisp: 'lisp', |
| 170 | + 'emacs-lisp': 'lisp', |
| 171 | + md: 'markdown', |
| 172 | + moon: 'moonscript', |
| 173 | + n4jsd: 'n4js', |
| 174 | + nani: 'naniscript', |
| 175 | + objc: 'objectivec', |
| 176 | + qasm: 'openqasm', |
| 177 | + objectpascal: 'pascal', |
| 178 | + px: 'pcaxis', |
| 179 | + pcode: 'peoplecode', |
| 180 | + plantuml: 'plant-uml', |
| 181 | + pq: 'powerquery', |
| 182 | + mscript: 'powerquery', |
| 183 | + pbfasm: 'purebasic', |
| 184 | + purs: 'purescript', |
| 185 | + py: 'python', |
| 186 | + qs: 'qsharp', |
| 187 | + rkt: 'racket', |
| 188 | + razor: 'cshtml', |
| 189 | + rpy: 'renpy', |
| 190 | + res: 'rescript', |
| 191 | + robot: 'robotframework', |
| 192 | + rb: 'ruby', |
| 193 | + 'sh-session': 'shell-session', |
| 194 | + shellsession: 'shell-session', |
| 195 | + smlnj: 'sml', |
| 196 | + sol: 'solidity', |
| 197 | + sln: 'solution-file', |
| 198 | + rq: 'sparql', |
| 199 | + sclang: 'supercollider', |
| 200 | + t4: 't4-cs', |
| 201 | + trickle: 'tremor', |
| 202 | + troy: 'tremor', |
| 203 | + trig: 'turtle', |
| 204 | + ts: 'typescript', |
| 205 | + tsconfig: 'typoscript', |
| 206 | + uscript: 'unrealscript', |
| 207 | + uc: 'unrealscript', |
| 208 | + url: 'uri', |
| 209 | + vb: 'visual-basic', |
| 210 | + vba: 'visual-basic', |
| 211 | + webidl: 'web-idl', |
| 212 | + mathematica: 'wolfram', |
| 213 | + nb: 'wolfram', |
| 214 | + wl: 'wolfram', |
| 215 | + xeoracube: 'xeora', |
| 216 | + yml: 'yaml', |
| 217 | +}; |
| 218 | + |
| 219 | +// The `depTreeCache` is used to cache the dependency tree for each language, |
| 220 | +// preventing duplicate calculations and avoiding repeated warning messages. |
| 221 | +const depTreeCache = {}; |
| 222 | + |
| 223 | +/** |
| 224 | + * PrismJs language dependencies required a specific order to load. |
| 225 | + * Try to check and print a warning message if some dependencies missing or in wrong order. |
| 226 | + * @param {*} lang current lang to check dependencies |
| 227 | + */ |
| 228 | +export default function checkLangDependenciesAllLoaded(lang) { |
| 229 | + if (!lang) { |
| 230 | + return; |
| 231 | + } |
| 232 | + |
| 233 | + lang = lang_aliases[lang] || lang; |
| 234 | + |
| 235 | + const validLang = lang_dependencies[lang]; |
| 236 | + if (!validLang) { |
| 237 | + return; |
| 238 | + } |
| 239 | + |
| 240 | + if (!depTreeCache[lang]) { |
| 241 | + /** |
| 242 | + * The dummy node constructs the dependency tree as the root |
| 243 | + * and maintains the final global loading status (dummy.loaded) for current lang. |
| 244 | + */ |
| 245 | + const dummy = { |
| 246 | + cur: '', |
| 247 | + loaded: true, |
| 248 | + dependencies: [], |
| 249 | + }; |
| 250 | + |
| 251 | + buildAndCheckDepTree(lang, dummy, dummy); |
| 252 | + |
| 253 | + const depTree = dummy.dependencies[0]; |
| 254 | + depTreeCache[lang] = depTree; |
| 255 | + |
| 256 | + if (!dummy.loaded) { |
| 257 | + const prettyOutput = prettryPrint(depTree, 1); |
| 258 | + // eslint-disable-next-line no-console |
| 259 | + console.warn( |
| 260 | + `The language '${lang}' required dependencies for code block highlighting are not satisfied.`, |
| 261 | + `Priority dependencies from low to high, consider to place all the necessary dependencie by priority (higher first): \n`, |
| 262 | + prettyOutput, |
| 263 | + ); |
| 264 | + } |
| 265 | + } |
| 266 | +} |
| 267 | + |
| 268 | +const buildAndCheckDepTree = (lang, parent, dummy) => { |
| 269 | + if (!lang) { |
| 270 | + return; |
| 271 | + } |
| 272 | + const cur = { cur: lang, loaded: true, dependencies: [] }; |
| 273 | + let deps = lang_dependencies[lang] || []; |
| 274 | + |
| 275 | + if (!(lang in Prism.languages)) { |
| 276 | + dummy.loaded = false; |
| 277 | + cur.loaded = false; |
| 278 | + } |
| 279 | + |
| 280 | + if (typeof deps === 'string') { |
| 281 | + deps = [deps]; |
| 282 | + } |
| 283 | + |
| 284 | + deps.forEach(dep => { |
| 285 | + buildAndCheckDepTree(dep, cur, dummy); |
| 286 | + }); |
| 287 | + |
| 288 | + parent.dependencies.push(cur); |
| 289 | +}; |
| 290 | + |
| 291 | +const prettryPrint = (depTree, level) => { |
| 292 | + let cur = `${' '.repeat(level * 3)} ${depTree.cur} ${depTree.loaded ? '(+)' : '(-)'}`; |
| 293 | + if (depTree.dependencies.length) { |
| 294 | + depTree.dependencies.forEach(dep => { |
| 295 | + cur += prettryPrint(dep, level + 1, cur); |
| 296 | + }); |
| 297 | + } |
| 298 | + return '\n' + cur; |
| 299 | +}; |
0 commit comments