UNPKG

5.53 kBJavaScriptView Raw
1/*
2Language: QML
3Requires: javascript.js, xml.js
4Author: John Foster <jfoster@esri.com>
5Description: Syntax highlighting for the Qt Quick QML scripting language, based mostly off
6 the JavaScript parser.
7Website: https://doc.qt.io/qt-5/qmlapplications.html
8Category: scripting
9*/
10
11function qml(hljs) {
12 const regex = hljs.regex;
13 const KEYWORDS = {
14 keyword:
15 'in of on if for while finally var new function do return void else break catch '
16 + 'instanceof with throw case default try this switch continue typeof delete '
17 + 'let yield const export super debugger as async await import',
18 literal:
19 'true false null undefined NaN Infinity',
20 built_in:
21 'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent '
22 + 'encodeURI encodeURIComponent escape unescape Object Function Boolean Error '
23 + 'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError '
24 + 'TypeError URIError Number Math Date String RegExp Array Float32Array '
25 + 'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array '
26 + 'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require '
27 + 'module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect '
28 + 'Behavior bool color coordinate date double enumeration font geocircle georectangle '
29 + 'geoshape int list matrix4x4 parent point quaternion real rect '
30 + 'size string url variant vector2d vector3d vector4d '
31 + 'Promise'
32 };
33
34 const QML_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9\\._]*';
35
36 // Isolate property statements. Ends at a :, =, ;, ,, a comment or end of line.
37 // Use property class.
38 const PROPERTY = {
39 className: 'keyword',
40 begin: '\\bproperty\\b',
41 starts: {
42 className: 'string',
43 end: '(:|=|;|,|//|/\\*|$)',
44 returnEnd: true
45 }
46 };
47
48 // Isolate signal statements. Ends at a ) a comment or end of line.
49 // Use property class.
50 const SIGNAL = {
51 className: 'keyword',
52 begin: '\\bsignal\\b',
53 starts: {
54 className: 'string',
55 end: '(\\(|:|=|;|,|//|/\\*|$)',
56 returnEnd: true
57 }
58 };
59
60 // id: is special in QML. When we see id: we want to mark the id: as attribute and
61 // emphasize the token following.
62 const ID_ID = {
63 className: 'attribute',
64 begin: '\\bid\\s*:',
65 starts: {
66 className: 'string',
67 end: QML_IDENT_RE,
68 returnEnd: false
69 }
70 };
71
72 // Find QML object attribute. An attribute is a QML identifier followed by :.
73 // Unfortunately it's hard to know where it ends, as it may contain scalars,
74 // objects, object definitions, or javascript. The true end is either when the parent
75 // ends or the next attribute is detected.
76 const QML_ATTRIBUTE = {
77 begin: QML_IDENT_RE + '\\s*:',
78 returnBegin: true,
79 contains: [
80 {
81 className: 'attribute',
82 begin: QML_IDENT_RE,
83 end: '\\s*:',
84 excludeEnd: true,
85 relevance: 0
86 }
87 ],
88 relevance: 0
89 };
90
91 // Find QML object. A QML object is a QML identifier followed by { and ends at the matching }.
92 // All we really care about is finding IDENT followed by { and just mark up the IDENT and ignore the {.
93 const QML_OBJECT = {
94 begin: regex.concat(QML_IDENT_RE, /\s*\{/),
95 end: /\{/,
96 returnBegin: true,
97 relevance: 0,
98 contains: [ hljs.inherit(hljs.TITLE_MODE, { begin: QML_IDENT_RE }) ]
99 };
100
101 return {
102 name: 'QML',
103 aliases: [ 'qt' ],
104 case_insensitive: false,
105 keywords: KEYWORDS,
106 contains: [
107 {
108 className: 'meta',
109 begin: /^\s*['"]use (strict|asm)['"]/
110 },
111 hljs.APOS_STRING_MODE,
112 hljs.QUOTE_STRING_MODE,
113 { // template string
114 className: 'string',
115 begin: '`',
116 end: '`',
117 contains: [
118 hljs.BACKSLASH_ESCAPE,
119 {
120 className: 'subst',
121 begin: '\\$\\{',
122 end: '\\}'
123 }
124 ]
125 },
126 hljs.C_LINE_COMMENT_MODE,
127 hljs.C_BLOCK_COMMENT_MODE,
128 {
129 className: 'number',
130 variants: [
131 { begin: '\\b(0[bB][01]+)' },
132 { begin: '\\b(0[oO][0-7]+)' },
133 { begin: hljs.C_NUMBER_RE }
134 ],
135 relevance: 0
136 },
137 { // "value" container
138 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
139 keywords: 'return throw case',
140 contains: [
141 hljs.C_LINE_COMMENT_MODE,
142 hljs.C_BLOCK_COMMENT_MODE,
143 hljs.REGEXP_MODE,
144 { // E4X / JSX
145 begin: /</,
146 end: />\s*[);\]]/,
147 relevance: 0,
148 subLanguage: 'xml'
149 }
150 ],
151 relevance: 0
152 },
153 SIGNAL,
154 PROPERTY,
155 {
156 className: 'function',
157 beginKeywords: 'function',
158 end: /\{/,
159 excludeEnd: true,
160 contains: [
161 hljs.inherit(hljs.TITLE_MODE, { begin: /[A-Za-z$_][0-9A-Za-z$_]*/ }),
162 {
163 className: 'params',
164 begin: /\(/,
165 end: /\)/,
166 excludeBegin: true,
167 excludeEnd: true,
168 contains: [
169 hljs.C_LINE_COMMENT_MODE,
170 hljs.C_BLOCK_COMMENT_MODE
171 ]
172 }
173 ],
174 illegal: /\[|%/
175 },
176 {
177 // hack: prevents detection of keywords after dots
178 begin: '\\.' + hljs.IDENT_RE,
179 relevance: 0
180 },
181 ID_ID,
182 QML_ATTRIBUTE,
183 QML_OBJECT
184 ],
185 illegal: /#/
186 };
187}
188
189module.exports = qml;