]> BookStack Code Mirror - bookstack/blob - resources/js/code/languages.js
Updated cm6 theme handling to allow extension via API
[bookstack] / resources / js / code / languages.js
1 import {StreamLanguage} from "@codemirror/language"
2
3 import {css} from '@codemirror/lang-css';
4 import {json} from '@codemirror/lang-json';
5 import {javascript} from '@codemirror/lang-javascript';
6 import {markdown} from '@codemirror/lang-markdown';
7 import {php} from '@codemirror/lang-php';
8 export {twig} from "@ssddanbrown/codemirror-lang-twig";
9
10 const legacyLoad = async (mode) => {
11     const modes = await window.importVersioned('legacy-modes');
12     return StreamLanguage.define(modes[mode]);
13 };
14
15
16 // Mapping of possible languages or formats from user input to their codemirror modes.
17 // Value can be a mode string or a function that will receive the code content & return the mode string.
18 // The function option is used in the event the exact mode could be dynamic depending on the code.
19 const modeMap = {
20     bash: () => legacyLoad('shell'),
21     c: () => legacyLoad('c'),
22     css: async () => css(),
23     'c++': () => legacyLoad('cpp'),
24     'c#': () => legacyLoad('csharp'),
25     csharp: () => legacyLoad('csharp'),
26     dart: () => legacyLoad('dart'),
27     diff: () => legacyLoad('diff'),
28     for: () => legacyLoad('fortran'),
29     fortran: () => legacyLoad('fortran'),
30     'f#': () => legacyLoad('fSharp'),
31     fsharp: () => legacyLoad('fSharp'),
32     go: () => legacyLoad('go'),
33     haskell: () => legacyLoad('haskell'),
34     hs: () => legacyLoad('haskell'),
35     html: () => legacyLoad('html'),
36     ini: () => legacyLoad('properties'),
37     java: () => legacyLoad('java'),
38     javascript: async () => javascript(),
39     json: async () => json(),
40     js: async () => javascript(),
41     jl: () => legacyLoad('julia'),
42     julia: () => legacyLoad('julia'),
43     kotlin: () => legacyLoad('kotlin'),
44     latex: () => legacyLoad('stex'),
45     lua: () => legacyLoad('lua'),
46     markdown: async () => markdown(),
47     matlab: () => legacyLoad('octave'),
48     md: async () => markdown(),
49     mdown: async () => markdown(),
50     ml: () => legacyLoad('sml'),
51     mssql: () => legacyLoad('msSQL'),
52     mysql: () => legacyLoad('mySQL'),
53     nginx: () => legacyLoad('nginx'),
54     octave: () => legacyLoad('octave'),
55     pas: () => legacyLoad('pascal'),
56     pascal: () => legacyLoad('pascal'),
57     perl: () => legacyLoad('perl'),
58     pgsql: () => legacyLoad('pgSQL'),
59     php: async (code) => {
60         const hasTags = code.includes('<?php');
61         return php({plain: !hasTags});
62     },
63     pl: () => legacyLoad('perl'),
64     'pl/sql': () => legacyLoad('plSQL'),
65     postgresql: () => legacyLoad('pgSQL'),
66     powershell: () => legacyLoad('powerShell'),
67     properties: () => legacyLoad('properties'),
68     ocaml: () => legacyLoad('oCaml'),
69     py: () => legacyLoad('python'),
70     python: () => legacyLoad('python'),
71     rb: () => legacyLoad('ruby'),
72     rs: () => legacyLoad('rust'),
73     ruby: () => legacyLoad('ruby'),
74     rust: () => legacyLoad('rust'),
75     scala: () => legacyLoad('scala'),
76     scheme: () => legacyLoad('scheme'),
77     shell: () => legacyLoad('shell'),
78     sh: () => legacyLoad('shell'),
79     smarty: () => legacyLoad('smarty'),
80     stext: () => legacyLoad('stex'),
81     swift: () => legacyLoad('swift'),
82     toml: () => legacyLoad('toml'),
83     ts: async () => javascript({typescript: true}),
84     twig: async () => twig(),
85     typescript: async () => javascript({typescript: true}),
86     sql: () => legacyLoad('standardSQL'),
87     sqlite: () => legacyLoad('sqlite'),
88     vbs: () => legacyLoad('vbScript'),
89     vbscript: () => legacyLoad('vbScript'),
90     'vb.net': () => legacyLoad('vb'),
91     vbnet: () => legacyLoad('vb'),
92     xml: () => legacyLoad('xml'),
93     yaml: () => legacyLoad('yaml'),
94     yml: () => legacyLoad('yaml'),
95 };
96
97 /**
98  * Get the relevant codemirror language extension based upon the given language
99  * suggestion and content.
100  * @param {String} langSuggestion
101  * @param {String} content
102  * @returns {Promise<StreamLanguage|LanguageSupport>}
103  */
104 export function getLanguageExtension(langSuggestion, content) {
105     const suggestion = langSuggestion.trim().replace(/^\./g, '').toLowerCase();
106
107     const language = modeMap[suggestion];
108
109     if (typeof language === 'undefined') {
110         return undefined;
111     }
112
113     return language(content);
114 }