utopia-project 0.37.6 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/documentation-guidelines.md +12 -7
- data/lib/utopia/project/import_map.rb +1 -0
- data/lib/utopia/project/version.rb +1 -1
- data/pages/_page.xnode +8 -13
- data/public/_components/@socketry/syntax/Syntax/CodeElement.js +293 -0
- data/public/_components/@socketry/syntax/Syntax/Errors.js +52 -0
- data/public/_components/@socketry/syntax/Syntax/Language/apache.js +49 -0
- data/public/_components/@socketry/syntax/Syntax/Language/applescript.js +157 -0
- data/public/_components/@socketry/syntax/Syntax/Language/assembly.js +42 -0
- data/public/_components/@socketry/syntax/Syntax/Language/bash-script.js +108 -0
- data/public/_components/@socketry/syntax/Syntax/Language/bash.js +32 -0
- data/public/_components/@socketry/syntax/Syntax/Language/basic.js +232 -0
- data/public/_components/@socketry/syntax/Syntax/Language/c++.js +1 -0
- data/public/_components/@socketry/syntax/Syntax/Language/c.js +1 -0
- data/public/_components/@socketry/syntax/Syntax/Language/clang.js +201 -0
- data/public/_components/@socketry/syntax/Syntax/Language/cpp.js +1 -0
- data/public/_components/@socketry/syntax/Syntax/Language/csharp.js +166 -0
- data/public/_components/@socketry/syntax/Syntax/Language/css.js +244 -0
- data/public/_components/@socketry/syntax/Syntax/Language/diff.js +24 -0
- data/public/_components/@socketry/syntax/Syntax/Language/go.js +135 -0
- data/public/_components/@socketry/syntax/Syntax/Language/haskell.js +110 -0
- data/public/_components/@socketry/syntax/Syntax/Language/html.js +69 -0
- data/public/_components/@socketry/syntax/Syntax/Language/io.js +68 -0
- data/public/_components/@socketry/syntax/Syntax/Language/java.js +134 -0
- data/public/_components/@socketry/syntax/Syntax/Language/javascript.js +89 -0
- data/public/_components/@socketry/syntax/Syntax/Language/json.js +36 -0
- data/public/_components/@socketry/syntax/Syntax/Language/lisp.js +38 -0
- data/public/_components/@socketry/syntax/Syntax/Language/lua.js +87 -0
- data/public/_components/@socketry/syntax/Syntax/Language/markdown.js +112 -0
- data/public/_components/@socketry/syntax/Syntax/Language/nginx.js +37 -0
- data/public/_components/@socketry/syntax/Syntax/Language/objective-c.js +1 -0
- data/public/_components/@socketry/syntax/Syntax/Language/ocaml.js +225 -0
- data/public/_components/@socketry/syntax/Syntax/Language/pascal.js +166 -0
- data/public/_components/@socketry/syntax/Syntax/Language/patch.js +2 -0
- data/public/_components/@socketry/syntax/Syntax/Language/perl5.js +317 -0
- data/public/_components/@socketry/syntax/Syntax/Language/php-script.js +112 -0
- data/public/_components/@socketry/syntax/Syntax/Language/php.js +18 -0
- data/public/_components/@socketry/syntax/Syntax/Language/plain.js +20 -0
- data/public/_components/@socketry/syntax/Syntax/Language/protobuf.js +77 -0
- data/public/_components/@socketry/syntax/Syntax/Language/python.js +208 -0
- data/public/_components/@socketry/syntax/Syntax/Language/ruby.js +124 -0
- data/public/_components/@socketry/syntax/Syntax/Language/scala.js +81 -0
- data/public/_components/@socketry/syntax/Syntax/Language/smalltalk.js +30 -0
- data/public/_components/@socketry/syntax/Syntax/Language/sql.js +865 -0
- data/public/_components/@socketry/syntax/Syntax/Language/super-collider.js +70 -0
- data/public/_components/@socketry/syntax/Syntax/Language/swift.js +176 -0
- data/public/_components/@socketry/syntax/Syntax/Language/xml.js +76 -0
- data/public/_components/@socketry/syntax/Syntax/Language/xrb.js +33 -0
- data/public/_components/@socketry/syntax/Syntax/Language/yaml.js +29 -0
- data/public/_components/@socketry/syntax/Syntax/Language.js +276 -0
- data/public/_components/@socketry/syntax/Syntax/Loader.js +78 -0
- data/public/_components/@socketry/syntax/Syntax/Match.js +546 -0
- data/public/_components/@socketry/syntax/Syntax/Rule.js +306 -0
- data/public/_components/@socketry/syntax/Syntax.js +356 -0
- data/public/_components/@socketry/syntax/license.md +21 -0
- data/public/_components/@socketry/syntax/package.json +43 -0
- data/public/_components/@socketry/syntax/readme.md +162 -0
- data/public/_components/@socketry/syntax/themes/base/apache.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/applescript.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/assembly.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/bash.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/basic.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/c.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/clang.css +0 -0
- data/public/_components/@socketry/syntax/themes/base/csharp.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/css.css +22 -0
- data/public/_components/@socketry/syntax/themes/base/diff.css +48 -0
- data/public/_components/@socketry/syntax/themes/base/go.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/haskell.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/html.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/io.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/java.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/javascript.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/json.css +41 -0
- data/public/_components/@socketry/syntax/themes/base/lisp.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/lua.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/markdown.css +16 -0
- data/public/_components/@socketry/syntax/themes/base/nginx.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/ocaml.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/pascal.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/perl5.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/php-script.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/php.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/plain.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/protobuf.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/python.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/ruby.css +23 -0
- data/public/_components/@socketry/syntax/themes/base/scala.css +3 -0
- data/public/_components/@socketry/syntax/themes/base/smalltalk.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/sql.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/super-collider.css +33 -0
- data/public/_components/@socketry/syntax/themes/base/swift.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/syntax.css +63 -0
- data/public/_components/@socketry/syntax/themes/base/xml.css +1 -0
- data/public/_components/@socketry/syntax/themes/base/xrb.css +29 -0
- data/public/_components/@socketry/syntax/themes/base/yaml.css +1 -0
- data/public/_components/@socketry/syntax/themes/theming.md +233 -0
- data/public/_static/sidebar.js +55 -22
- data/public/_static/site.css +0 -4
- data.tar.gz.sig +0 -0
- metadata +94 -1
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {Language} from '../Language.js';
|
|
2
|
+
import {Rule} from '../Rule.js';
|
|
3
|
+
|
|
4
|
+
const language = new Language('super-collider');
|
|
5
|
+
|
|
6
|
+
// Keywords
|
|
7
|
+
language.push(['const', 'arg', 'classvar', 'var'], {type: 'keyword'});
|
|
8
|
+
|
|
9
|
+
// Operators
|
|
10
|
+
language.push(
|
|
11
|
+
['`', '+', '@', ':', '*', '/', '-', '&', '|', '~', '!', '%', '<', '=', '>'],
|
|
12
|
+
{
|
|
13
|
+
type: 'operator'
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
// Constants/values
|
|
18
|
+
language.push(
|
|
19
|
+
[
|
|
20
|
+
'thisFunctionDef',
|
|
21
|
+
'thisFunction',
|
|
22
|
+
'thisMethod',
|
|
23
|
+
'thisProcess',
|
|
24
|
+
'thisThread',
|
|
25
|
+
'this',
|
|
26
|
+
'super',
|
|
27
|
+
'true',
|
|
28
|
+
'false',
|
|
29
|
+
'nil',
|
|
30
|
+
'inf'
|
|
31
|
+
],
|
|
32
|
+
{type: 'constant'}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// CamelCase class/type names
|
|
36
|
+
language.push(Rule.camelCaseType);
|
|
37
|
+
|
|
38
|
+
// Single Characters like $a or $\n
|
|
39
|
+
language.push({pattern: /\$(\\)?.\b/, type: 'constant'});
|
|
40
|
+
|
|
41
|
+
// Symbols: \symbol and 'quotedSymbol'
|
|
42
|
+
language.push({pattern: /\\[a-z_][a-z0-9_]*/i, type: 'symbol'});
|
|
43
|
+
language.push({pattern: /'[^']+'/, type: 'symbol'});
|
|
44
|
+
|
|
45
|
+
// Comments and links
|
|
46
|
+
language.push(Rule.cStyleComment);
|
|
47
|
+
language.push(Rule.cppStyleComment);
|
|
48
|
+
language.push(Rule.webLink);
|
|
49
|
+
|
|
50
|
+
// Strings: SuperCollider uses double quotes for Strings
|
|
51
|
+
// Single quotes denote Symbols and are handled above.
|
|
52
|
+
language.push(Rule.doubleQuotedString);
|
|
53
|
+
language.push(Rule.stringEscape);
|
|
54
|
+
|
|
55
|
+
// Numbers
|
|
56
|
+
language.push(Rule.decimalNumber);
|
|
57
|
+
language.push(Rule.hexNumber);
|
|
58
|
+
|
|
59
|
+
// Method calls .method and c-style function pattern (identifier()
|
|
60
|
+
language.push({
|
|
61
|
+
pattern: /(?:\.)([a-z_][a-z0-9_]*)/i,
|
|
62
|
+
matches: Rule.extractMatches({type: 'function'})
|
|
63
|
+
});
|
|
64
|
+
language.push(Rule.cStyleFunction);
|
|
65
|
+
|
|
66
|
+
export default function register(syntax) {
|
|
67
|
+
syntax.register('super-collider', language);
|
|
68
|
+
// Alias: sc
|
|
69
|
+
syntax.alias('super-collider', ['sc']);
|
|
70
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {Language} from '../Language.js';
|
|
2
|
+
import {Rule} from '../Rule.js';
|
|
3
|
+
|
|
4
|
+
const language = new Language('swift');
|
|
5
|
+
|
|
6
|
+
const keywords = [
|
|
7
|
+
'associatedtype',
|
|
8
|
+
'class',
|
|
9
|
+
'deinit',
|
|
10
|
+
'enum',
|
|
11
|
+
'extension',
|
|
12
|
+
'fileprivate',
|
|
13
|
+
'func',
|
|
14
|
+
'import',
|
|
15
|
+
'init',
|
|
16
|
+
'inout',
|
|
17
|
+
'internal',
|
|
18
|
+
'let',
|
|
19
|
+
'operator',
|
|
20
|
+
'private',
|
|
21
|
+
'protocol',
|
|
22
|
+
'static',
|
|
23
|
+
'struct',
|
|
24
|
+
'subscript',
|
|
25
|
+
'typealias',
|
|
26
|
+
'var',
|
|
27
|
+
'break',
|
|
28
|
+
'case',
|
|
29
|
+
'continue',
|
|
30
|
+
'default',
|
|
31
|
+
'defer',
|
|
32
|
+
'do',
|
|
33
|
+
'else',
|
|
34
|
+
'fallthrough',
|
|
35
|
+
'for',
|
|
36
|
+
'guard',
|
|
37
|
+
'if',
|
|
38
|
+
'in',
|
|
39
|
+
'repeat',
|
|
40
|
+
'return',
|
|
41
|
+
'switch',
|
|
42
|
+
'where',
|
|
43
|
+
'while',
|
|
44
|
+
'as',
|
|
45
|
+
'catch',
|
|
46
|
+
'is',
|
|
47
|
+
'rethrows',
|
|
48
|
+
'throw',
|
|
49
|
+
'throws',
|
|
50
|
+
'try',
|
|
51
|
+
'_',
|
|
52
|
+
'#available',
|
|
53
|
+
'#colorLiteral',
|
|
54
|
+
'#column',
|
|
55
|
+
'#else',
|
|
56
|
+
'#elseif',
|
|
57
|
+
'#endif',
|
|
58
|
+
'#file',
|
|
59
|
+
'#fileLiteral',
|
|
60
|
+
'#function',
|
|
61
|
+
'#if',
|
|
62
|
+
'#imageLiteral',
|
|
63
|
+
'#line',
|
|
64
|
+
'#selector',
|
|
65
|
+
'#sourceLocation',
|
|
66
|
+
'associativity',
|
|
67
|
+
'convenience',
|
|
68
|
+
'dynamic',
|
|
69
|
+
'didSet',
|
|
70
|
+
'final',
|
|
71
|
+
'get',
|
|
72
|
+
'infix',
|
|
73
|
+
'indirect',
|
|
74
|
+
'lazy',
|
|
75
|
+
'left',
|
|
76
|
+
'mutating',
|
|
77
|
+
'none',
|
|
78
|
+
'nonmutating',
|
|
79
|
+
'optional',
|
|
80
|
+
'override',
|
|
81
|
+
'postfix',
|
|
82
|
+
'precedence',
|
|
83
|
+
'prefix',
|
|
84
|
+
'Protocol',
|
|
85
|
+
'required',
|
|
86
|
+
'right',
|
|
87
|
+
'set',
|
|
88
|
+
'Type',
|
|
89
|
+
'unowned',
|
|
90
|
+
'weak',
|
|
91
|
+
'willSet'
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
// Operators - ordered longest to shortest
|
|
95
|
+
const operators = [
|
|
96
|
+
'...',
|
|
97
|
+
'..<',
|
|
98
|
+
'->',
|
|
99
|
+
'+',
|
|
100
|
+
'*',
|
|
101
|
+
'/',
|
|
102
|
+
'-',
|
|
103
|
+
'&',
|
|
104
|
+
'|',
|
|
105
|
+
'~',
|
|
106
|
+
'!',
|
|
107
|
+
'%',
|
|
108
|
+
'<',
|
|
109
|
+
'=',
|
|
110
|
+
'>',
|
|
111
|
+
'(',
|
|
112
|
+
')',
|
|
113
|
+
'{',
|
|
114
|
+
'}',
|
|
115
|
+
'[',
|
|
116
|
+
']',
|
|
117
|
+
'.',
|
|
118
|
+
',',
|
|
119
|
+
':',
|
|
120
|
+
';',
|
|
121
|
+
'@',
|
|
122
|
+
'#',
|
|
123
|
+
'`',
|
|
124
|
+
'?'
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const values = ['self', 'super', 'true', 'false', 'nil'];
|
|
128
|
+
const access = ['fileprivate', 'open', 'private', 'public'];
|
|
129
|
+
|
|
130
|
+
// Access modifiers
|
|
131
|
+
language.push(access, {type: 'access'});
|
|
132
|
+
|
|
133
|
+
// Built-in values
|
|
134
|
+
language.push(values, {type: 'constant'});
|
|
135
|
+
|
|
136
|
+
// Backtick identifiers
|
|
137
|
+
language.push({
|
|
138
|
+
pattern: /`[^`]+`/g,
|
|
139
|
+
type: 'identifier'
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// String interpolation \(...) - needs special handling
|
|
143
|
+
language.push({
|
|
144
|
+
pattern: /\\\(([^)]*)\)/g,
|
|
145
|
+
klass: 'string'
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Types (CamelCase)
|
|
149
|
+
language.push(Rule.camelCaseType);
|
|
150
|
+
|
|
151
|
+
// Keywords
|
|
152
|
+
language.push(keywords, {type: 'keyword'});
|
|
153
|
+
|
|
154
|
+
// Operators
|
|
155
|
+
language.push(operators, {type: 'operator'});
|
|
156
|
+
|
|
157
|
+
// Comments
|
|
158
|
+
language.push(Rule.cStyleComment);
|
|
159
|
+
language.push(Rule.cppStyleComment);
|
|
160
|
+
language.push(Rule.webLink);
|
|
161
|
+
|
|
162
|
+
// Strings
|
|
163
|
+
language.push(Rule.singleQuotedString);
|
|
164
|
+
language.push(Rule.doubleQuotedString);
|
|
165
|
+
language.push(Rule.stringEscape);
|
|
166
|
+
|
|
167
|
+
// Numbers
|
|
168
|
+
language.push(Rule.decimalNumber);
|
|
169
|
+
language.push(Rule.hexNumber);
|
|
170
|
+
|
|
171
|
+
// Functions
|
|
172
|
+
language.push(Rule.cStyleFunction);
|
|
173
|
+
|
|
174
|
+
export default function register(syntax) {
|
|
175
|
+
syntax.register('swift', language);
|
|
176
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XML language syntax highlighting
|
|
3
|
+
* Supports XML tags, attributes, entities, CDATA sections, and comments
|
|
4
|
+
*/
|
|
5
|
+
import {Language} from '../Language.js';
|
|
6
|
+
import {Rule} from '../Rule.js';
|
|
7
|
+
|
|
8
|
+
// XML entity pattern: &entity;
|
|
9
|
+
const xmlEntity = {pattern: /&\w+;/, type: 'entity'};
|
|
10
|
+
|
|
11
|
+
// XML percent escape pattern for URL encoding
|
|
12
|
+
const xmlPercentEscape = {
|
|
13
|
+
pattern: /(%[0-9a-f]{2})/i,
|
|
14
|
+
type: 'percent-escape',
|
|
15
|
+
only: ['string']
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Create xml-tag language for highlighting XML tag internals
|
|
19
|
+
const xmlTagLanguage = new Language('xml-tag');
|
|
20
|
+
|
|
21
|
+
// Match opening/closing tags with optional namespace
|
|
22
|
+
// Pattern: <tag>, <ns:tag>, </tag>, </ns:tag>, <tag/>, etc.
|
|
23
|
+
xmlTagLanguage.push({
|
|
24
|
+
pattern: /<\/?((?:[^:\s>]+:)?)([^\s>]+)(\s[^>]*)?\/?>/,
|
|
25
|
+
matches: Rule.extractMatches({type: 'namespace'}, {type: 'tag-name'})
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Match attributes with values
|
|
29
|
+
// Pattern: attribute="value", attribute='value', attribute=value
|
|
30
|
+
xmlTagLanguage.push({
|
|
31
|
+
pattern: /([^=\s]+)=(".*?"|'.*?'|[^\s>]+)/,
|
|
32
|
+
matches: Rule.extractMatches(
|
|
33
|
+
{type: 'attribute', only: ['tag']},
|
|
34
|
+
{type: 'string', only: ['tag']}
|
|
35
|
+
)
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
xmlTagLanguage.push(xmlEntity);
|
|
39
|
+
xmlTagLanguage.push(xmlPercentEscape);
|
|
40
|
+
xmlTagLanguage.push(Rule.singleQuotedString);
|
|
41
|
+
xmlTagLanguage.push(Rule.doubleQuotedString);
|
|
42
|
+
|
|
43
|
+
// Create main XML language
|
|
44
|
+
|
|
45
|
+
const language = new Language('xml');
|
|
46
|
+
|
|
47
|
+
// Match CDATA sections
|
|
48
|
+
// Pattern: <![CDATA[content]]>
|
|
49
|
+
language.push({
|
|
50
|
+
pattern: /(<!(\[CDATA\[)([\s\S]*?)(\]\])>)/m,
|
|
51
|
+
matches: Rule.extractMatches(
|
|
52
|
+
{type: 'cdata', allow: ['cdata-content', 'cdata-tag']},
|
|
53
|
+
{type: 'cdata-tag'},
|
|
54
|
+
{type: 'cdata-content'},
|
|
55
|
+
{type: 'cdata-tag'}
|
|
56
|
+
)
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// XML comments
|
|
60
|
+
language.push(Rule.xmlComment);
|
|
61
|
+
|
|
62
|
+
// Match all XML tags and delegate to xml-tag language
|
|
63
|
+
language.push({
|
|
64
|
+
pattern: /<[^>\-\s]([^>'"!\/;\?@\[\]^`\{\}\|]|"[^"]*"|'[^']')*[\/?]?>/,
|
|
65
|
+
language: 'xml-tag'
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
language.push(xmlEntity);
|
|
69
|
+
language.push(xmlPercentEscape);
|
|
70
|
+
language.push(Rule.webLink);
|
|
71
|
+
|
|
72
|
+
// Register both languages
|
|
73
|
+
export default function register(syntax) {
|
|
74
|
+
syntax.register('xml-tag', xmlTagLanguage);
|
|
75
|
+
syntax.register('xml', language);
|
|
76
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {Language} from '../Language.js';
|
|
2
|
+
import {Rule} from '../Rule.js';
|
|
3
|
+
|
|
4
|
+
const language = new Language('xrb');
|
|
5
|
+
|
|
6
|
+
// Embedded Ruby processing instruction: <?r ... ?>
|
|
7
|
+
language.push({
|
|
8
|
+
pattern: /(<\?r)([\s\S]*?)(\?>)/m,
|
|
9
|
+
matches: Rule.extractMatches(
|
|
10
|
+
{type: 'keyword'},
|
|
11
|
+
{language: 'ruby'},
|
|
12
|
+
{type: 'keyword'}
|
|
13
|
+
)
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Ruby interpolation within text: #{ ... }
|
|
17
|
+
language.push({
|
|
18
|
+
pattern: /(#{)([\s\S]*?)(})/m,
|
|
19
|
+
matches: Rule.extractMatches(
|
|
20
|
+
{type: 'keyword'},
|
|
21
|
+
{language: 'ruby'},
|
|
22
|
+
{type: 'keyword'}
|
|
23
|
+
)
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Derive XML so tags/attributes/entities are highlighted around embedded Ruby
|
|
27
|
+
language.derives('xml');
|
|
28
|
+
|
|
29
|
+
export default function register(syntax) {
|
|
30
|
+
syntax.register('xrb', language);
|
|
31
|
+
// Alias 'trenni' if used historically
|
|
32
|
+
syntax.alias('xrb', ['trenni']);
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {Language} from '../Language.js';
|
|
2
|
+
import {Rule} from '../Rule.js';
|
|
3
|
+
|
|
4
|
+
const language = new Language('yaml');
|
|
5
|
+
|
|
6
|
+
language.push({
|
|
7
|
+
pattern: /^\s*#.*$/m,
|
|
8
|
+
type: 'comment',
|
|
9
|
+
allow: ['href']
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
language.push(Rule.singleQuotedString);
|
|
13
|
+
language.push(Rule.doubleQuotedString);
|
|
14
|
+
|
|
15
|
+
language.push({
|
|
16
|
+
pattern: /(&|\*)[a-z0-9]+/i,
|
|
17
|
+
type: 'constant'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
language.push({
|
|
21
|
+
pattern: /(.*?):/i,
|
|
22
|
+
matches: Rule.extractMatches({type: 'keyword'})
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
language.push(Rule.webLink);
|
|
26
|
+
|
|
27
|
+
export default function register(syntax) {
|
|
28
|
+
syntax.register('yaml', language);
|
|
29
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import {Match} from './Match.js';
|
|
2
|
+
import {Rule} from './Rule.js';
|
|
3
|
+
import {LanguageNotFoundError, RuleApplyError} from './Errors.js';
|
|
4
|
+
|
|
5
|
+
export class Language {
|
|
6
|
+
// Public properties that define the language
|
|
7
|
+
name;
|
|
8
|
+
|
|
9
|
+
// A list of processes that may be run after extracting matches.
|
|
10
|
+
processes = {};
|
|
11
|
+
|
|
12
|
+
// A sequential list of rules for extracting matches.
|
|
13
|
+
#rules = [];
|
|
14
|
+
|
|
15
|
+
// A list of all the parent languages this language derives from.
|
|
16
|
+
#parents = [];
|
|
17
|
+
|
|
18
|
+
constructor(name = null) {
|
|
19
|
+
// The primary class of this language. Must be unique.
|
|
20
|
+
this.name = name;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Add a parent to the language. This language should be loaded as a dependency.
|
|
25
|
+
*/
|
|
26
|
+
derives(name) {
|
|
27
|
+
this.#parents.push(name);
|
|
28
|
+
this.#rules.push({
|
|
29
|
+
apply: async function (syntax, rule, text) {
|
|
30
|
+
const parentLanguage = await syntax.getLanguage(name);
|
|
31
|
+
return parentLanguage.getMatches(syntax, text);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Return an array of all classes that the language consists of.
|
|
38
|
+
*/
|
|
39
|
+
async allNames(syntax) {
|
|
40
|
+
const names = [this.name];
|
|
41
|
+
|
|
42
|
+
for (const parent of this.#parents) {
|
|
43
|
+
if (syntax) {
|
|
44
|
+
const parentLanguage = await syntax.getLanguage(parent);
|
|
45
|
+
if (parentLanguage) names.push(...(await parentLanguage.allNames(syntax)));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return names;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Push a rule onto the language.
|
|
54
|
+
*/
|
|
55
|
+
push(...args) {
|
|
56
|
+
if (Array.isArray(args[0])) {
|
|
57
|
+
const patterns = args[0];
|
|
58
|
+
const rule = args[1];
|
|
59
|
+
|
|
60
|
+
let all = '(';
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < patterns.length; i += 1) {
|
|
63
|
+
if (i > 0) all += '|';
|
|
64
|
+
|
|
65
|
+
const p = patterns[i];
|
|
66
|
+
|
|
67
|
+
if (p instanceof RegExp) {
|
|
68
|
+
all += p.source;
|
|
69
|
+
} else {
|
|
70
|
+
all += Rule.convertStringToTokenPattern(p, true);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
all += ')';
|
|
75
|
+
|
|
76
|
+
this.push({
|
|
77
|
+
...rule,
|
|
78
|
+
pattern: new RegExp(all, rule.options)
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
const rule = args[0];
|
|
82
|
+
|
|
83
|
+
// Normalize and validate the rule
|
|
84
|
+
const normalized = Rule.normalizeRule(rule, this);
|
|
85
|
+
|
|
86
|
+
if (
|
|
87
|
+
typeof normalized.pattern === 'undefined' ||
|
|
88
|
+
normalized.pattern instanceof RegExp
|
|
89
|
+
) {
|
|
90
|
+
this.#rules.push(normalized);
|
|
91
|
+
} else {
|
|
92
|
+
console.error('Syntax Error: Malformed rule: ', rule);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get matches for a specific rule.
|
|
99
|
+
*/
|
|
100
|
+
async getMatchesForRule(syntax, text, rule) {
|
|
101
|
+
let matches = [];
|
|
102
|
+
|
|
103
|
+
// Short circuit (user defined) function:
|
|
104
|
+
if (typeof rule.apply !== 'undefined') {
|
|
105
|
+
try {
|
|
106
|
+
const result = rule.apply(syntax, rule, text);
|
|
107
|
+
matches = result instanceof Promise ? await result : result;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (syntax?.defaultOptions?.strict) {
|
|
110
|
+
// If the underlying error is a strict language resolution error, surface it directly:
|
|
111
|
+
if (error instanceof LanguageNotFoundError) throw error;
|
|
112
|
+
throw new RuleApplyError(rule, {cause: error});
|
|
113
|
+
} else {
|
|
114
|
+
console.warn('Syntax Warning: Rule apply failed:', rule, error);
|
|
115
|
+
matches = [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (rule.debug) {
|
|
121
|
+
console.log('Syntax matches:', rule, text, matches);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return matches;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the rule for a specific type.
|
|
129
|
+
*/
|
|
130
|
+
getRuleForType(type) {
|
|
131
|
+
for (const rule of this.#rules) {
|
|
132
|
+
if (rule.type === type) {
|
|
133
|
+
return rule;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get all matches for the given text.
|
|
142
|
+
*/
|
|
143
|
+
async getMatches(syntax, text) {
|
|
144
|
+
const matches = [];
|
|
145
|
+
|
|
146
|
+
for (const rule of this.#rules) {
|
|
147
|
+
matches.push(...(await this.getMatchesForRule(syntax, text, rule)));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return matches;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A helper function for building a tree from a specific rule.
|
|
155
|
+
*/
|
|
156
|
+
static async buildTree(syntax, rule, text, offset, additionalMatches) {
|
|
157
|
+
let language;
|
|
158
|
+
try {
|
|
159
|
+
language = await syntax.getLanguage(rule.language);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (syntax?.defaultOptions?.strict) {
|
|
162
|
+
// Normalize any load error to LanguageNotFoundError for consistency:
|
|
163
|
+
throw new LanguageNotFoundError(rule.language, {cause: error});
|
|
164
|
+
} else {
|
|
165
|
+
console.warn(
|
|
166
|
+
`Syntax Warning: Failed to load language '${rule.language}' for building tree:`,
|
|
167
|
+
error
|
|
168
|
+
);
|
|
169
|
+
return new Match(offset || 0, text.length, rule, text);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!language) {
|
|
174
|
+
if (syntax?.defaultOptions?.strict) {
|
|
175
|
+
throw new LanguageNotFoundError(rule.language);
|
|
176
|
+
} else {
|
|
177
|
+
console.warn(
|
|
178
|
+
`Syntax Warning: Language '${rule.language}' not found for building tree.`
|
|
179
|
+
);
|
|
180
|
+
// Return a simple match without children as fallback
|
|
181
|
+
return new Match(offset || 0, text.length, rule, text);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const match = await language.buildTree(
|
|
186
|
+
syntax,
|
|
187
|
+
text,
|
|
188
|
+
offset,
|
|
189
|
+
additionalMatches
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
Object.assign(match.expression, rule);
|
|
193
|
+
|
|
194
|
+
return match;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Build a syntax tree from a given block of text.
|
|
199
|
+
*/
|
|
200
|
+
async buildTree(syntax, text, offset, additionalMatches) {
|
|
201
|
+
offset = offset || 0;
|
|
202
|
+
|
|
203
|
+
// Fixes code that uses \r\n for line endings
|
|
204
|
+
text = text.replace(/\r/g, '');
|
|
205
|
+
|
|
206
|
+
const matches = await this.getMatches(syntax, text);
|
|
207
|
+
|
|
208
|
+
// Shift matches if offset is provided
|
|
209
|
+
if (offset && offset > 0) {
|
|
210
|
+
for (const match of matches) {
|
|
211
|
+
match.shift(offset);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const top = new Match(
|
|
216
|
+
offset,
|
|
217
|
+
text.length,
|
|
218
|
+
{type: (await this.allNames(syntax)).join(' '), allow: '*', owner: this},
|
|
219
|
+
text
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// This sort is absolutely key to the tree insertion algorithm
|
|
223
|
+
matches.sort(Match.sort);
|
|
224
|
+
|
|
225
|
+
for (const match of matches) {
|
|
226
|
+
top.insertAtEnd(match);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (additionalMatches) {
|
|
230
|
+
for (const match of additionalMatches) {
|
|
231
|
+
top.insert(match, true);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
top.complete = true;
|
|
236
|
+
|
|
237
|
+
return top;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Build a syntax tree and process it into HTML.
|
|
242
|
+
*/
|
|
243
|
+
async process(syntax, text, options) {
|
|
244
|
+
const top = await this.buildTree(syntax, text, 0);
|
|
245
|
+
|
|
246
|
+
const lines = top.splitLines();
|
|
247
|
+
|
|
248
|
+
const html = document.createElement('code');
|
|
249
|
+
html.className = 'syntax highlighted';
|
|
250
|
+
html.setAttribute('part', 'code');
|
|
251
|
+
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
const processedLine = line.reduce(null, (container, match) => {
|
|
254
|
+
if (match.expression) {
|
|
255
|
+
if (match.expression.process) {
|
|
256
|
+
container = match.expression.process(container, match, options);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (match.expression.owner) {
|
|
260
|
+
const process = match.expression.owner.processes[match.expression.type];
|
|
261
|
+
if (process) {
|
|
262
|
+
container = process(container, match, options);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return container;
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
html.appendChild(processedLine);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return html;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export default Language;
|