Skip to content

Commit 4eb928c

Browse files
ahueRunDevelopment
andauthoredFeb 19, 2022
Added support for Cooklang (#3337)
Co-authored-by: Michael Schmidt <msrd0000@gmail.com>
1 parent 703881e commit 4eb928c

10 files changed

+580
-1
lines changed
 

‎components.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎components.json

+4
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@
299299
"title": "Content-Security-Policy",
300300
"owner": "ScottHelme"
301301
},
302+
"cooklang": {
303+
"title": "Cooklang",
304+
"owner": "ahue"
305+
},
302306
"coq": {
303307
"title": "Coq",
304308
"owner": "RunDevelopment"

‎components/prism-cooklang.js

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
(function (Prism) {
2+
3+
// see https://github.com/cooklang/spec/blob/main/EBNF.md
4+
5+
var single_token_suffix = /(?:(?!\s)[\d$+<=a-zA-Z\x80-\uFFFF])+/.source;
6+
var multi_token_infix = /[^{}@#]+/.source;
7+
var multi_token_suffix = /\{[^}#@]*\}/.source;
8+
9+
var multi_token = multi_token_infix + multi_token_suffix;
10+
11+
var timer_units = /(?:h|hours|hrs|m|min|minutes)/.source;
12+
13+
var amount_group_impl = {
14+
pattern: /\{[^{}]*\}/,
15+
inside: {
16+
'amount': {
17+
pattern: /([\{|])[^{}|*%]+/,
18+
lookbehind: true,
19+
alias: 'number',
20+
},
21+
'unit': {
22+
pattern: /(%)[^}]+/,
23+
lookbehind: true,
24+
alias: 'symbol',
25+
},
26+
'servings-scaler': {
27+
pattern: /\*/,
28+
alias: 'operator',
29+
},
30+
'servings-alternative-separator': {
31+
pattern: /\|/,
32+
alias: 'operator',
33+
},
34+
'unit-separator': {
35+
pattern: /(?:%|(\*)%)/,
36+
lookbehind: true,
37+
alias: 'operator',
38+
},
39+
'punctuation': /[{}]/,
40+
}
41+
};
42+
43+
44+
Prism.languages.cooklang = {
45+
'comment': {
46+
// [- comment -]
47+
// -- comment
48+
pattern: /\[-[\s\S]*?-\]|--.*/,
49+
greedy: true,
50+
},
51+
'meta': { // >> key: value
52+
pattern: />>.*:.*/,
53+
inside: {
54+
'property': { // key:
55+
pattern: /(>>\s*)[^\s:](?:[^:]*[^\s:])?/,
56+
lookbehind: true,
57+
}
58+
}
59+
},
60+
'cookware-group': { // #...{...}, #...
61+
pattern: new RegExp('#(?:'
62+
+ multi_token
63+
+ '|'
64+
+ single_token_suffix
65+
+ ')'
66+
),
67+
inside: {
68+
'cookware': {
69+
pattern: new RegExp('(^#)(?:'
70+
+ multi_token_infix
71+
+ ')'
72+
),
73+
lookbehind: true,
74+
alias: 'variable',
75+
},
76+
'cookware-keyword': {
77+
pattern: /^#/,
78+
alias: 'keyword',
79+
},
80+
'quantity-group': {
81+
pattern: new RegExp(/\{[^{}@#]*\}/),
82+
inside: {
83+
'quantity': {
84+
pattern: new RegExp(/(^\{)/.source + multi_token_infix),
85+
lookbehind: true,
86+
alias: 'number',
87+
},
88+
'punctuation': /[{}]/,
89+
}
90+
}
91+
},
92+
},
93+
'ingredient-group': { // @...{...}, @...
94+
pattern: new RegExp('@(?:'
95+
+ multi_token
96+
+ '|'
97+
+ single_token_suffix
98+
+ ')'),
99+
inside: {
100+
'ingredient': {
101+
pattern: new RegExp('(^@)(?:'
102+
+ multi_token_infix
103+
+ ')'),
104+
lookbehind: true,
105+
alias: 'variable',
106+
},
107+
'ingredient-keyword': {
108+
pattern: /^@/,
109+
alias: 'keyword',
110+
},
111+
'amount-group': amount_group_impl,
112+
}
113+
},
114+
'timer-group': { // ~timer{...}
115+
// eslint-disable-next-line regexp/sort-alternatives
116+
pattern: /~(?!\s)[^@#~{}]*\{[^{}]*\}/,
117+
inside: {
118+
'timer': {
119+
pattern: /(^~)[^{]+/,
120+
lookbehind: true,
121+
alias: 'variable',
122+
},
123+
'duration-group': { // {...}
124+
pattern: /\{[^{}]*\}/,
125+
inside: {
126+
'punctuation': /[{}]/,
127+
'unit': {
128+
pattern: new RegExp(/(%\s*)/.source + timer_units + /\b/.source),
129+
lookbehind: true,
130+
alias: 'symbol',
131+
},
132+
'operator': /%/,
133+
'duration': {
134+
pattern: /\d+/,
135+
alias: 'number',
136+
},
137+
}
138+
},
139+
'timer-keyword': {
140+
pattern: /^~/,
141+
alias: 'keyword',
142+
},
143+
}
144+
}
145+
};
146+
}(Prism));

‎components/prism-cooklang.min.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/prism-cooklang.html

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<h2>Comments</h2>
2+
<pre><code>
3+
-- This is a single line comment
4+
[- this
5+
is
6+
a multi line comment -]
7+
</code></pre>
8+
9+
<h2>Meta</h2>
10+
<pre><code>
11+
>> servings: 3
12+
>> source: https://cooklang.org/docs/spec
13+
>> any key: any value
14+
</code></pre>
15+
16+
<h2>Ingredients</h2>
17+
<pre><code>
18+
@salt without amount
19+
@egg{1}
20+
@milk{1%l}
21+
@milk{1|2%l}
22+
@egg{1|2}
23+
@egg{1*}
24+
@milk{2*%l}
25+
</code></pre>
26+
27+
<h2>Cookware</h2>
28+
<pre><code>
29+
#spoon without amount
30+
#spoon{10%pair}
31+
#spoon{1|2}
32+
#spoon{1*%pair}
33+
#spoon{1|2%pair}
34+
#spoon{1*}
35+
</code></pre>
36+
37+
<h2>Timer</h2>
38+
<pre><code>
39+
~{25%minutes} without name
40+
~named timer{1%hours}
41+
</code></pre>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- a single line comment
2+
[- a multi line comment on a single line -]
3+
[- a multi
4+
line comment 1 -]
5+
[- a multi
6+
line comment 2
7+
-]
8+
[-
9+
a multi
10+
line comment 3 -]
11+
12+
----------------------------------------------------
13+
14+
[
15+
["comment", "-- a single line comment"],
16+
["comment", "[- a multi line comment on a single line -]"],
17+
["comment", "[- a multi\r\nline comment 1 -]"],
18+
["comment", "[- a multi\r\nline comment 2 \r\n-]"],
19+
["comment", "[- \r\na multi\r\nline comment 3 -]"]
20+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#spoon
2+
#spoon and more #spoon
3+
#spoon is good but more #spoon are better
4+
#more spoon{}
5+
#even more spoon{1}
6+
#spoon{1%set}
7+
#spoon{2*%kg}
8+
#spoon{3|1%set}
9+
#spoon{3*set}
10+
#spoon{3|set}
11+
#spoon{3%*set}
12+
#spoon{3%*%set}
13+
14+
----------------------------------------------------
15+
16+
[
17+
["cookware-group", [
18+
["cookware-keyword", "#"],
19+
["cookware", "spoon"]
20+
]],
21+
22+
["cookware-group", [
23+
["cookware-keyword", "#"],
24+
["cookware", "spoon"]
25+
]],
26+
" and more ",
27+
["cookware-group", [
28+
["cookware-keyword", "#"],
29+
["cookware", "spoon"]
30+
]],
31+
32+
["cookware-group", [
33+
["cookware-keyword", "#"],
34+
["cookware", "spoon"]
35+
]],
36+
" is good but more ",
37+
["cookware-group", [
38+
["cookware-keyword", "#"],
39+
["cookware", "spoon"]
40+
]],
41+
" are better\r\n",
42+
43+
["cookware-group", [
44+
["cookware-keyword", "#"],
45+
["cookware", "more spoon"],
46+
["quantity-group", [
47+
["punctuation", "{"],
48+
["punctuation", "}"]
49+
]]
50+
]],
51+
52+
["cookware-group", [
53+
["cookware-keyword", "#"],
54+
["cookware", "even more spoon"],
55+
["quantity-group", [
56+
["punctuation", "{"],
57+
["quantity", "1"],
58+
["punctuation", "}"]
59+
]]
60+
]],
61+
62+
["cookware-group", [
63+
["cookware-keyword", "#"],
64+
["cookware", "spoon"],
65+
["quantity-group", [
66+
["punctuation", "{"],
67+
["quantity", "1%set"],
68+
["punctuation", "}"]
69+
]]
70+
]],
71+
72+
["cookware-group", [
73+
["cookware-keyword", "#"],
74+
["cookware", "spoon"],
75+
["quantity-group", [
76+
["punctuation", "{"],
77+
["quantity", "2*%kg"],
78+
["punctuation", "}"]
79+
]]
80+
]],
81+
82+
["cookware-group", [
83+
["cookware-keyword", "#"],
84+
["cookware", "spoon"],
85+
["quantity-group", [
86+
["punctuation", "{"],
87+
["quantity", "3|1%set"],
88+
["punctuation", "}"]
89+
]]
90+
]],
91+
92+
["cookware-group", [
93+
["cookware-keyword", "#"],
94+
["cookware", "spoon"],
95+
["quantity-group", [
96+
["punctuation", "{"],
97+
["quantity", "3*set"],
98+
["punctuation", "}"]
99+
]]
100+
]],
101+
102+
["cookware-group", [
103+
["cookware-keyword", "#"],
104+
["cookware", "spoon"],
105+
["quantity-group", [
106+
["punctuation", "{"],
107+
["quantity", "3|set"],
108+
["punctuation", "}"]
109+
]]
110+
]],
111+
112+
["cookware-group", [
113+
["cookware-keyword", "#"],
114+
["cookware", "spoon"],
115+
["quantity-group", [
116+
["punctuation", "{"],
117+
["quantity", "3%*set"],
118+
["punctuation", "}"]
119+
]]
120+
]],
121+
122+
["cookware-group", [
123+
["cookware-keyword", "#"],
124+
["cookware", "spoon"],
125+
["quantity-group", [
126+
["punctuation", "{"],
127+
["quantity", "3%*%set"],
128+
["punctuation", "}"]
129+
]]
130+
]]
131+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
@milk
2+
@milk and more @milk
3+
@milk is good but more @milk is better
4+
@more milk{}
5+
@even more milk{1}
6+
@milk{1%l}
7+
@milk{2*%kg}
8+
@milk{3|1%L}
9+
@milk{3*L} must not match amount-group
10+
@milk{3|L}
11+
@milk{3%*L}
12+
@milk{3%*%L}
13+
14+
----------------------------------------------------
15+
16+
[
17+
["ingredient-group", [
18+
["ingredient-keyword", "@"],
19+
["ingredient", "milk"]
20+
]],
21+
22+
["ingredient-group", [
23+
["ingredient-keyword", "@"],
24+
["ingredient", "milk"]
25+
]],
26+
" and more ",
27+
["ingredient-group", [
28+
["ingredient-keyword", "@"],
29+
["ingredient", "milk"]
30+
]],
31+
32+
["ingredient-group", [
33+
["ingredient-keyword", "@"],
34+
["ingredient", "milk"]
35+
]],
36+
" is good but more ",
37+
["ingredient-group", [
38+
["ingredient-keyword", "@"],
39+
["ingredient", "milk"]
40+
]],
41+
" is better\r\n",
42+
43+
["ingredient-group", [
44+
["ingredient-keyword", "@"],
45+
["ingredient", "more milk"],
46+
["amount-group", [
47+
["punctuation", "{"],
48+
["punctuation", "}"]
49+
]]
50+
]],
51+
52+
["ingredient-group", [
53+
["ingredient-keyword", "@"],
54+
["ingredient", "even more milk"],
55+
["amount-group", [
56+
["punctuation", "{"],
57+
["amount", "1"],
58+
["punctuation", "}"]
59+
]]
60+
]],
61+
62+
["ingredient-group", [
63+
["ingredient-keyword", "@"],
64+
["ingredient", "milk"],
65+
["amount-group", [
66+
["punctuation", "{"],
67+
["amount", "1"],
68+
["unit-separator", "%"],
69+
["unit", "l"],
70+
["punctuation", "}"]
71+
]]
72+
]],
73+
74+
["ingredient-group", [
75+
["ingredient-keyword", "@"],
76+
["ingredient", "milk"],
77+
["amount-group", [
78+
["punctuation", "{"],
79+
["amount", "2"],
80+
["servings-scaler", "*"],
81+
["unit-separator", "%"],
82+
["unit", "kg"],
83+
["punctuation", "}"]
84+
]]
85+
]],
86+
87+
["ingredient-group", [
88+
["ingredient-keyword", "@"],
89+
["ingredient", "milk"],
90+
["amount-group", [
91+
["punctuation", "{"],
92+
["amount", "3"],
93+
["servings-alternative-separator", "|"],
94+
["amount", "1"],
95+
["unit-separator", "%"],
96+
["unit", "L"],
97+
["punctuation", "}"]
98+
]]
99+
]],
100+
101+
["ingredient-group", [
102+
["ingredient-keyword", "@"],
103+
["ingredient", "milk"],
104+
["amount-group", [
105+
["punctuation", "{"],
106+
["amount", "3"],
107+
["servings-scaler", "*"],
108+
"L",
109+
["punctuation", "}"]
110+
]]
111+
]],
112+
" must not match amount-group\r\n",
113+
114+
["ingredient-group", [
115+
["ingredient-keyword", "@"],
116+
["ingredient", "milk"],
117+
["amount-group", [
118+
["punctuation", "{"],
119+
["amount", "3"],
120+
["servings-alternative-separator", "|"],
121+
["amount", "L"],
122+
["punctuation", "}"]
123+
]]
124+
]],
125+
126+
["ingredient-group", [
127+
["ingredient-keyword", "@"],
128+
["ingredient", "milk"],
129+
["amount-group", [
130+
["punctuation", "{"],
131+
["amount", "3"],
132+
["unit-separator", "%"],
133+
["unit", "*L"],
134+
["punctuation", "}"]
135+
]]
136+
]],
137+
138+
["ingredient-group", [
139+
["ingredient-keyword", "@"],
140+
["ingredient", "milk"],
141+
["amount-group", [
142+
["punctuation", "{"],
143+
["amount", "3"],
144+
["unit-separator", "%"],
145+
["unit", "*%L"],
146+
["punctuation", "}"]
147+
]]
148+
]]
149+
]
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
>> servings: 1|2|3
2+
>> servings: 3
3+
>> meta without colon must not match
4+
5+
----------------------------------------------------
6+
7+
[
8+
["meta", [
9+
">> ",
10+
["property", "servings"],
11+
": 1|2|3"
12+
]],
13+
["meta", [
14+
">> ",
15+
["property", "servings"],
16+
": 3"
17+
]],
18+
"\r\n>> meta without colon must not match"
19+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
~{25%minutes}
2+
~eggs{25%minutes}
3+
~{abc%minutes} must not match
4+
~eggs{2%hours}
5+
~eggs{2%h}
6+
7+
----------------------------------------------------
8+
9+
[
10+
["timer-group", [
11+
["timer-keyword", "~"],
12+
["duration-group", [
13+
["punctuation", "{"],
14+
["duration", "25"],
15+
["operator", "%"],
16+
["unit", "minutes"],
17+
["punctuation", "}"]
18+
]]
19+
]],
20+
21+
["timer-group", [
22+
["timer-keyword", "~"],
23+
["timer", "eggs"],
24+
["duration-group", [
25+
["punctuation", "{"],
26+
["duration", "25"],
27+
["operator", "%"],
28+
["unit", "minutes"],
29+
["punctuation", "}"]
30+
]]
31+
]],
32+
33+
["timer-group", [
34+
["timer-keyword", "~"],
35+
["duration-group", [
36+
["punctuation", "{"],
37+
"abc",
38+
["operator", "%"],
39+
["unit", "minutes"],
40+
["punctuation", "}"]
41+
]]
42+
]],
43+
" must not match\r\n",
44+
45+
["timer-group", [
46+
["timer-keyword", "~"],
47+
["timer", "eggs"],
48+
["duration-group", [
49+
["punctuation", "{"],
50+
["duration", "2"],
51+
["operator", "%"],
52+
["unit", "hours"],
53+
["punctuation", "}"]
54+
]]
55+
]],
56+
57+
["timer-group", [
58+
["timer-keyword", "~"],
59+
["timer", "eggs"],
60+
["duration-group", [
61+
["punctuation", "{"],
62+
["duration", "2"],
63+
["operator", "%"],
64+
["unit", "h"],
65+
["punctuation", "}"]
66+
]]
67+
]]
68+
]

0 commit comments

Comments
 (0)
Please sign in to comment.