UNPKG

4.67 kBJavaScriptView Raw
1/*
2Language: YAML
3Description: Yet Another Markdown Language
4Author: Stefan Wienert <stwienert@gmail.com>
5Contributors: Carl Baxter <carl@cbax.tech>
6Requires: ruby.js
7Website: https://yaml.org
8Category: common, config
9*/
10function yaml(hljs) {
11 const LITERALS = 'true false yes no null';
12
13 // YAML spec allows non-reserved URI characters in tags.
14 const URI_CHARACTERS = '[\\w#;/?:@&=+$,.~*\'()[\\]]+';
15
16 // Define keys as starting with a word character
17 // ...containing word chars, spaces, colons, forward-slashes, hyphens and periods
18 // ...and ending with a colon followed immediately by a space, tab or newline.
19 // The YAML spec allows for much more than this, but this covers most use-cases.
20 const KEY = {
21 className: 'attr',
22 variants: [
23 {
24 begin: '\\w[\\w :\\/.-]*:(?=[ \t]|$)'
25 },
26 { // double quoted keys
27 begin: '"\\w[\\w :\\/.-]*":(?=[ \t]|$)'
28 },
29 { // single quoted keys
30 begin: '\'\\w[\\w :\\/.-]*\':(?=[ \t]|$)'
31 }
32 ]
33 };
34
35 const TEMPLATE_VARIABLES = {
36 className: 'template-variable',
37 variants: [
38 { // jinja templates Ansible
39 begin: /\{\{/,
40 end: /\}\}/
41 },
42 { // Ruby i18n
43 begin: /%\{/,
44 end: /\}/
45 }
46 ]
47 };
48 const STRING = {
49 className: 'string',
50 relevance: 0,
51 variants: [
52 {
53 begin: /'/,
54 end: /'/
55 },
56 {
57 begin: /"/,
58 end: /"/
59 },
60 {
61 begin: /\S+/
62 }
63 ],
64 contains: [
65 hljs.BACKSLASH_ESCAPE,
66 TEMPLATE_VARIABLES
67 ]
68 };
69
70 // Strings inside of value containers (objects) can't contain braces,
71 // brackets, or commas
72 const CONTAINER_STRING = hljs.inherit(STRING, {
73 variants: [
74 {
75 begin: /'/,
76 end: /'/
77 },
78 {
79 begin: /"/,
80 end: /"/
81 },
82 {
83 begin: /[^\s,{}[\]]+/
84 }
85 ]
86 });
87
88 const DATE_RE = '[0-9]{4}(-[0-9][0-9]){0,2}';
89 const TIME_RE = '([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?';
90 const FRACTION_RE = '(\\.[0-9]*)?';
91 const ZONE_RE = '([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?';
92 const TIMESTAMP = {
93 className: 'number',
94 begin: '\\b' + DATE_RE + TIME_RE + FRACTION_RE + ZONE_RE + '\\b'
95 };
96
97 const VALUE_CONTAINER = {
98 end: ',',
99 endsWithParent: true,
100 excludeEnd: true,
101 keywords: LITERALS,
102 relevance: 0
103 };
104 const OBJECT = {
105 begin: /\{/,
106 end: /\}/,
107 contains: [ VALUE_CONTAINER ],
108 illegal: '\\n',
109 relevance: 0
110 };
111 const ARRAY = {
112 begin: '\\[',
113 end: '\\]',
114 contains: [ VALUE_CONTAINER ],
115 illegal: '\\n',
116 relevance: 0
117 };
118
119 const MODES = [
120 KEY,
121 {
122 className: 'meta',
123 begin: '^---\\s*$',
124 relevance: 10
125 },
126 { // multi line string
127 // Blocks start with a | or > followed by a newline
128 //
129 // Indentation of subsequent lines must be the same to
130 // be considered part of the block
131 className: 'string',
132 begin: '[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*'
133 },
134 { // Ruby/Rails erb
135 begin: '<%[%=-]?',
136 end: '[%-]?%>',
137 subLanguage: 'ruby',
138 excludeBegin: true,
139 excludeEnd: true,
140 relevance: 0
141 },
142 { // named tags
143 className: 'type',
144 begin: '!\\w+!' + URI_CHARACTERS
145 },
146 // https://yaml.org/spec/1.2/spec.html#id2784064
147 { // verbatim tags
148 className: 'type',
149 begin: '!<' + URI_CHARACTERS + ">"
150 },
151 { // primary tags
152 className: 'type',
153 begin: '!' + URI_CHARACTERS
154 },
155 { // secondary tags
156 className: 'type',
157 begin: '!!' + URI_CHARACTERS
158 },
159 { // fragment id &ref
160 className: 'meta',
161 begin: '&' + hljs.UNDERSCORE_IDENT_RE + '$'
162 },
163 { // fragment reference *ref
164 className: 'meta',
165 begin: '\\*' + hljs.UNDERSCORE_IDENT_RE + '$'
166 },
167 { // array listing
168 className: 'bullet',
169 // TODO: remove |$ hack when we have proper look-ahead support
170 begin: '-(?=[ ]|$)',
171 relevance: 0
172 },
173 hljs.HASH_COMMENT_MODE,
174 {
175 beginKeywords: LITERALS,
176 keywords: {
177 literal: LITERALS
178 }
179 },
180 TIMESTAMP,
181 // numbers are any valid C-style number that
182 // sit isolated from other words
183 {
184 className: 'number',
185 begin: hljs.C_NUMBER_RE + '\\b',
186 relevance: 0
187 },
188 OBJECT,
189 ARRAY,
190 STRING
191 ];
192
193 const VALUE_MODES = [ ...MODES ];
194 VALUE_MODES.pop();
195 VALUE_MODES.push(CONTAINER_STRING);
196 VALUE_CONTAINER.contains = VALUE_MODES;
197
198 return {
199 name: 'YAML',
200 case_insensitive: true,
201 aliases: [ 'yml' ],
202 contains: MODES
203 };
204}
205
206export { yaml as default };