Skip to content

Commit 1c6c0bf

Browse files
Scheme: Added bracket support (#2813)
1 parent 4f03d5d commit 1c6c0bf

12 files changed

+369
-121
lines changed

Diff for: components/prism-racket.js

+1-48
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,11 @@ Prism.languages.racket = Prism.languages.extend('scheme', {
22
'lambda-parameter': {
33
// the racket lambda syntax is a lot more complex, so we won't even attempt to capture it.
44
// this will just prevent false positives of the `function` pattern
5-
pattern: /(\(lambda\s+\()[^()'\s]+/,
5+
pattern: /([(\[]lambda\s+[(\[])[^()\[\]'\s]+/,
66
lookbehind: true
77
}
88
});
99

10-
// Add brackets to racket
11-
// The basic idea here is to go through all pattens of Scheme and replace all occurrences of "(" with the union of "("
12-
// and "["; Similar for ")". This is a bit tricky because "(" can be escaped or inside a character set. Both cases
13-
// have to be handled differently and, of course, we don't want to destroy groups, so we can only replace literal "("
14-
// and ")".
15-
// To do this, we use a regular expression which will parse any JS regular expression. It works because regexes are
16-
// matches from left to right and already matched text cannot be matched again. We use this to first capture all
17-
// escaped characters (not really, we don't get escape sequences but we don't need them). Because we already captured
18-
// all escaped characters, we know that any "[" character is the start of a character set, so we match that character
19-
// set whole.
20-
// With the regex parsed, we only have to replace all escaped "(" (they cannot be unescaped outside of character sets)
21-
// with /[([]/ and replace all "(" inside character sets.
22-
// Note: This method does not work for "(" that are escaped like this /\x28/ or this /\u0028/.
23-
Prism.languages.DFS(Prism.languages.racket, function (key, value) {
24-
if (Prism.util.type(value) === 'RegExp') {
25-
var source = value.source.replace(/\\(.)|\[\^?((?:\\.|[^\\\]])*)\]/g, function (m, g1, g2) {
26-
if (g1) {
27-
if (g1 === '(') {
28-
// replace all '(' characters outside character sets
29-
return '[([]';
30-
}
31-
if (g1 === ')') {
32-
// replace all ')' characters outside character sets
33-
return '[)\\]]';
34-
}
35-
}
36-
if (g2) {
37-
var prefix = m[1] === '^' ? '[^' : '[';
38-
return prefix + g2.replace(/\\(.)|[()]/g, function (m, g1) {
39-
if (m === '(' || g1 === '(') {
40-
// replace all '(' characters inside character sets
41-
return '([';
42-
}
43-
if (m === ')' || g1 === ')') {
44-
// replace all ')' characters inside character sets
45-
return ')\\]';
46-
}
47-
return m;
48-
}) + ']';
49-
}
50-
return m;
51-
});
52-
53-
this[key] = RegExp(source, value.flags);
54-
}
55-
});
56-
5710
Prism.languages.insertBefore('racket', 'string', {
5811
'lang': {
5912
pattern: /^#lang.+/m,

Diff for: components/prism-racket.min.js

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

Diff for: components/prism-scheme.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
// and (potentially nested) multiline comments:
66
// #| comment #| nested |# still comment |#
77
// (only 1 level of nesting is supported)
8-
'comment': /;.*|#;\s*\((?:[^()]|\([^()]*\))*\)|#\|(?:[^#|]|#(?!\|)|\|(?!#)|#\|(?:[^#|]|#(?!\|)|\|(?!#))*\|#)*\|#/,
8+
'comment': /;.*|#;\s*(?:\((?:[^()]|\([^()]*\))*\)|\[(?:[^\[\]]|\[[^\[\]]*\])*\])|#\|(?:[^#|]|#(?!\|)|\|(?!#)|#\|(?:[^#|]|#(?!\|)|\|(?!#))*\|#)*\|#/,
99
'string': {
1010
pattern: /"(?:[^"\\]|\\.)*"/,
1111
greedy: true
1212
},
1313
'symbol': {
14-
pattern: /'[^()#'\s]+/,
14+
pattern: /'[^()\[\]#'\s]+/,
1515
greedy: true
1616
},
1717
'character': {
@@ -22,25 +22,25 @@
2222
'lambda-parameter': [
2323
// https://www.cs.cmu.edu/Groups/AI/html/r4rs/r4rs_6.html#SEC30
2424
{
25-
pattern: /((?:^|[^'`#])\(lambda\s+)(?:[^|()'\s]+|\|(?:[^\\|]|\\.)*\|)/,
25+
pattern: /((?:^|[^'`#])[(\[]lambda\s+)(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)/,
2626
lookbehind: true
2727
},
2828
{
29-
pattern: /((?:^|[^'`#])\(lambda\s+\()[^()']+/,
29+
pattern: /((?:^|[^'`#])[(\[]lambda\s+[(\[])[^()\[\]']+/,
3030
lookbehind: true
3131
}
3232
],
3333
'keyword': {
34-
pattern: /((?:^|[^'`#])\()(?:begin|case(?:-lambda)?|cond(?:-expand)?|define(?:-library|-macro|-record-type|-syntax|-values)?|defmacro|delay(?:-force)?|do|else|export|except|guard|if|import|include(?:-ci|-library-declarations)?|lambda|let(?:rec)?(?:-syntax|-values|\*)?|let\*-values|only|parameterize|prefix|(?:quasi-?)?quote|rename|set!|syntax-(?:case|rules)|unless|unquote(?:-splicing)?|when)(?=[()\s]|$)/,
34+
pattern: /((?:^|[^'`#])[(\[])(?:begin|case(?:-lambda)?|cond(?:-expand)?|define(?:-library|-macro|-record-type|-syntax|-values)?|defmacro|delay(?:-force)?|do|else|export|except|guard|if|import|include(?:-ci|-library-declarations)?|lambda|let(?:rec)?(?:-syntax|-values|\*)?|let\*-values|only|parameterize|prefix|(?:quasi-?)?quote|rename|set!|syntax-(?:case|rules)|unless|unquote(?:-splicing)?|when)(?=[()\[\]\s]|$)/,
3535
lookbehind: true
3636
},
3737
'builtin': {
3838
// all functions of the base library of R7RS plus some of built-ins of R5Rs
39-
pattern: /((?:^|[^'`#])\()(?:abs|and|append|apply|assoc|ass[qv]|binary-port\?|boolean=?\?|bytevector(?:-append|-copy|-copy!|-length|-u8-ref|-u8-set!|\?)?|caar|cadr|call-with-(?:current-continuation|port|values)|call\/cc|car|cdar|cddr|cdr|ceiling|char(?:->integer|-ready\?|\?|<\?|<=\?|=\?|>\?|>=\?)|close-(?:input-port|output-port|port)|complex\?|cons|current-(?:error|input|output)-port|denominator|dynamic-wind|eof-object\??|eq\?|equal\?|eqv\?|error|error-object(?:-irritants|-message|\?)|eval|even\?|exact(?:-integer-sqrt|-integer\?|\?)?|expt|features|file-error\?|floor(?:-quotient|-remainder|\/)?|flush-output-port|for-each|gcd|get-output-(?:bytevector|string)|inexact\??|input-port(?:-open\?|\?)|integer(?:->char|\?)|lcm|length|list(?:->string|->vector|-copy|-ref|-set!|-tail|\?)?|make-(?:bytevector|list|parameter|string|vector)|map|max|member|memq|memv|min|modulo|negative\?|newline|not|null\?|number(?:->string|\?)|numerator|odd\?|open-(?:input|output)-(?:bytevector|string)|or|output-port(?:-open\?|\?)|pair\?|peek-char|peek-u8|port\?|positive\?|procedure\?|quotient|raise|raise-continuable|rational\?|rationalize|read-(?:bytevector|bytevector!|char|error\?|line|string|u8)|real\?|remainder|reverse|round|set-c[ad]r!|square|string(?:->list|->number|->symbol|->utf8|->vector|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?|<\?|<=\?|=\?|>\?|>=\?)?|substring|symbol(?:->string|\?|=\?)|syntax-error|textual-port\?|truncate(?:-quotient|-remainder|\/)?|u8-ready\?|utf8->string|values|vector(?:->list|->string|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?)?|with-exception-handler|write-(?:bytevector|char|string|u8)|zero\?)(?=[()\s]|$)/,
39+
pattern: /((?:^|[^'`#])[(\[])(?:abs|and|append|apply|assoc|ass[qv]|binary-port\?|boolean=?\?|bytevector(?:-append|-copy|-copy!|-length|-u8-ref|-u8-set!|\?)?|caar|cadr|call-with-(?:current-continuation|port|values)|call\/cc|car|cdar|cddr|cdr|ceiling|char(?:->integer|-ready\?|\?|<\?|<=\?|=\?|>\?|>=\?)|close-(?:input-port|output-port|port)|complex\?|cons|current-(?:error|input|output)-port|denominator|dynamic-wind|eof-object\??|eq\?|equal\?|eqv\?|error|error-object(?:-irritants|-message|\?)|eval|even\?|exact(?:-integer-sqrt|-integer\?|\?)?|expt|features|file-error\?|floor(?:-quotient|-remainder|\/)?|flush-output-port|for-each|gcd|get-output-(?:bytevector|string)|inexact\??|input-port(?:-open\?|\?)|integer(?:->char|\?)|lcm|length|list(?:->string|->vector|-copy|-ref|-set!|-tail|\?)?|make-(?:bytevector|list|parameter|string|vector)|map|max|member|memq|memv|min|modulo|negative\?|newline|not|null\?|number(?:->string|\?)|numerator|odd\?|open-(?:input|output)-(?:bytevector|string)|or|output-port(?:-open\?|\?)|pair\?|peek-char|peek-u8|port\?|positive\?|procedure\?|quotient|raise|raise-continuable|rational\?|rationalize|read-(?:bytevector|bytevector!|char|error\?|line|string|u8)|real\?|remainder|reverse|round|set-c[ad]r!|square|string(?:->list|->number|->symbol|->utf8|->vector|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?|<\?|<=\?|=\?|>\?|>=\?)?|substring|symbol(?:->string|\?|=\?)|syntax-error|textual-port\?|truncate(?:-quotient|-remainder|\/)?|u8-ready\?|utf8->string|values|vector(?:->list|->string|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?)?|with-exception-handler|write-(?:bytevector|char|string|u8)|zero\?)(?=[()\[\]\s]|$)/,
4040
lookbehind: true
4141
},
4242
'operator': {
43-
pattern: /((?:^|[^'`#])\()(?:[-+*%/]|[<>]=?|=>?)(?=[()\s]|$)/,
43+
pattern: /((?:^|[^'`#])[(\[])(?:[-+*%/]|[<>]=?|=>?)(?=[()\[\]\s]|$)/,
4444
lookbehind: true
4545
},
4646
'number': {
@@ -82,24 +82,24 @@
8282
'<complex box>': /<real box>(?:@<real box>|<imaginary box>)?|<imaginary box>/.source,
8383
'<num box>': /#[box](?:#[ei])?|(?:#[ei])?#[box]<complex box>/.source,
8484

85-
'<number>': /(^|[\s()])(?:<num dec>|<num box>)(?=[()\s]|$)/.source,
85+
'<number>': /(^|[()\[\]\s])(?:<num dec>|<num box>)(?=[()\[\]\s]|$)/.source,
8686
}), 'i'),
8787
lookbehind: true
8888
},
8989
'boolean': {
90-
pattern: /(^|[\s()])#(?:[ft]|false|true)(?=[()\s]|$)/,
90+
pattern: /(^|[()\[\]\s])#(?:[ft]|false|true)(?=[()\[\]\s]|$)/,
9191
lookbehind: true
9292
},
9393
'function': {
94-
pattern: /((?:^|[^'`#])\()(?:[^|()'\s]+|\|(?:[^\\|]|\\.)*\|)(?=[()\s]|$)/,
94+
pattern: /((?:^|[^'`#])[(\[])(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)(?=[()\[\]\s]|$)/,
9595
lookbehind: true
9696
},
9797
'identifier': {
98-
pattern: /(^|[\s()])\|(?:[^\\|]|\\.)*\|(?=[()\s]|$)/,
98+
pattern: /(^|[()\[\]\s])\|(?:[^\\|]|\\.)*\|(?=[()\[\]\s]|$)/,
9999
lookbehind: true,
100100
greedy: true
101101
},
102-
'punctuation': /[()']/
102+
'punctuation': /[()\[\]']/
103103
};
104104

105105
/**

Diff for: components/prism-scheme.min.js

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

Diff for: tests/languages/scheme/builtin_feature.test

+9-1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@
194194
(write-u8
195195
(zero?
196196

197+
; with brackets
198+
[map
199+
[max
200+
197201
----------------------------------------------------
198202

199203
[
@@ -391,7 +395,11 @@
391395
["punctuation", "("], ["builtin", "write-char"],
392396
["punctuation", "("], ["builtin", "write-string"],
393397
["punctuation", "("], ["builtin", "write-u8"],
394-
["punctuation", "("], ["builtin", "zero?"]
398+
["punctuation", "("], ["builtin", "zero?"],
399+
400+
["comment", "; with brackets"],
401+
["punctuation", "["], ["builtin", "map"],
402+
["punctuation", "["], ["builtin", "max"]
395403
]
396404

397405
----------------------------------------------------

Diff for: tests/languages/scheme/comment_feature.test

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#;(foo bar)
55
#; (foo)
6+
#;[foo bar]
7+
#; [foo]
68

79
#|
810
comment
@@ -17,6 +19,8 @@
1719

1820
["comment", "#;(foo bar)"],
1921
["comment", "#; (foo)"],
22+
["comment", "#;[foo bar]"],
23+
["comment", "#; [foo]"],
2024

2125
["comment", "#|\r\n comment\r\n #| nested comment |#\r\n|#"]
2226
]

0 commit comments

Comments
 (0)