F#: Improved character literals (#1956) This adds support for all F# character escapes which should result in all characters being highlighted as such. The problem was that character literals with escape sequences longer than two characters were not recognized.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
diff --git a/components/prism-fsharp.js b/components/prism-fsharp.js
index f6bce8d..4215622 100644
--- a/components/prism-fsharp.js
+++ b/components/prism-fsharp.js
@@ -10,7 +10,7 @@ Prism.languages.fsharp = Prism.languages.extend('clike', {
}
],
'string': {
- pattern: /(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\.)'B?/,
+ pattern: /(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\(?:.|\d{3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}|U[a-fA-F\d]{8}))'B?/,
greedy: true
},
'class-name': {
diff --git a/components/prism-fsharp.min.js b/components/prism-fsharp.min.js
index f4ea280..144653e 100644
--- a/components/prism-fsharp.min.js
+++ b/components/prism-fsharp.min.js
@@ -1 +1 @@
-Prism.languages.fsharp=Prism.languages.extend("clike",{comment:[{pattern:/(^|[^\\])\(\*[\s\S]*?\*\)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\.)'B?/,greedy:!0},"class-name":{pattern:/(\b(?:exception|inherit|interface|new|of|type)\s+|\w\s*:\s*|\s:\??>\s*)[.\w]+\b(?:\s*(?:->|\*)\s*[.\w]+\b)*(?!\s*[:.])/,lookbehind:!0,inside:{operator:/->|\*/,punctuation:/\./}},keyword:/\b(?:let|return|use|yield)(?:!\B|\b)|\b(abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|select|static|struct|then|to|true|try|type|upcast|val|void|when|while|with|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,number:[/\b0x[\da-fA-F]+(?:un|lf|LF)?\b/,/\b0b[01]+(?:y|uy)?\b/,/(?:\b\d+\.?\d*|\B\.\d+)(?:[fm]|e[+-]?\d+)?\b/i,/\b\d+(?:[IlLsy]|u[lsy]?|UL)?\b/],operator:/([<>~&^])\1\1|([*.:<>&])\2|<-|->|[!=:]=|<?\|{1,3}>?|\??(?:<=|>=|<>|[-+*/%=<>])\??|[!?^&]|~[+~-]|:>|:\?>?/}),Prism.languages.insertBefore("fsharp","keyword",{preprocessor:{pattern:/^[^\r\n\S]*#.*/m,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:else|endif|if|light|line|nowarn)\b/,lookbehind:!0,alias:"keyword"}}}}),Prism.languages.insertBefore("fsharp","punctuation",{"computation-expression":{pattern:/[_a-z]\w*(?=\s*\{)/i,alias:"keyword"}}),Prism.languages.insertBefore("fsharp","string",{annotation:{pattern:/\[<.+?>\]/,inside:{punctuation:/^\[<|>\]$/,"class-name":{pattern:/^\w+$|(^|;\s*)[A-Z]\w*(?=\()/,lookbehind:!0},"annotation-content":{pattern:/[\s\S]+/,inside:Prism.languages.fsharp}}}});
\ No newline at end of file
+Prism.languages.fsharp=Prism.languages.extend("clike",{comment:[{pattern:/(^|[^\\])\(\*[\s\S]*?\*\)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\(?:.|\d{3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}|U[a-fA-F\d]{8}))'B?/,greedy:!0},"class-name":{pattern:/(\b(?:exception|inherit|interface|new|of|type)\s+|\w\s*:\s*|\s:\??>\s*)[.\w]+\b(?:\s*(?:->|\*)\s*[.\w]+\b)*(?!\s*[:.])/,lookbehind:!0,inside:{operator:/->|\*/,punctuation:/\./}},keyword:/\b(?:let|return|use|yield)(?:!\B|\b)|\b(abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|select|static|struct|then|to|true|try|type|upcast|val|void|when|while|with|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,number:[/\b0x[\da-fA-F]+(?:un|lf|LF)?\b/,/\b0b[01]+(?:y|uy)?\b/,/(?:\b\d+\.?\d*|\B\.\d+)(?:[fm]|e[+-]?\d+)?\b/i,/\b\d+(?:[IlLsy]|u[lsy]?|UL)?\b/],operator:/([<>~&^])\1\1|([*.:<>&])\2|<-|->|[!=:]=|<?\|{1,3}>?|\??(?:<=|>=|<>|[-+*/%=<>])\??|[!?^&]|~[+~-]|:>|:\?>?/}),Prism.languages.insertBefore("fsharp","keyword",{preprocessor:{pattern:/^[^\r\n\S]*#.*/m,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:else|endif|if|light|line|nowarn)\b/,lookbehind:!0,alias:"keyword"}}}}),Prism.languages.insertBefore("fsharp","punctuation",{"computation-expression":{pattern:/[_a-z]\w*(?=\s*\{)/i,alias:"keyword"}}),Prism.languages.insertBefore("fsharp","string",{annotation:{pattern:/\[<.+?>\]/,inside:{punctuation:/^\[<|>\]$/,"class-name":{pattern:/^\w+$|(^|;\s*)[A-Z]\w*(?=\()/,lookbehind:!0},"annotation-content":{pattern:/[\s\S]+/,inside:Prism.languages.fsharp}}}});
\ No newline at end of file
diff --git a/examples/prism-fsharp.html b/examples/prism-fsharp.html
index 6a4330b..c0b9921 100644
--- a/examples/prism-fsharp.html
+++ b/examples/prism-fsharp.html
@@ -5,7 +5,6 @@ comment *)</code></pre>
<h2>Strings</h2>
<pre><code>"foo \"bar\" baz"
-'foo \'bar\' baz'
@"Verbatim strings"
"""Alternate "verbatim" strings"""
</code></pre>
@@ -58,32 +57,32 @@ comment *)</code></pre>
</code></pre>
<h2>Full example</h2>
-<pre><code>// The declaration creates a constructor that takes two values, name and age.
+<pre><code>// The declaration creates a constructor that takes two values, name and age.
type Person(name:string, age:int) =
- // A Person object's age can be changed. The mutable keyword in the
- // declaration makes that possible.
+ // A Person object's age can be changed. The mutable keyword in the
+ // declaration makes that possible.
let mutable internalAge = age
- // Declare a second constructor that takes only one argument, a name.
- // This constructor calls the constructor that requires two arguments,
- // sending 0 as the value for age.
+ // Declare a second constructor that takes only one argument, a name.
+ // This constructor calls the constructor that requires two arguments,
+ // sending 0 as the value for age.
new(name:string) = Person(name, 0)
- // A read-only property.
+ // A read-only property.
member this.Name = name
- // A read/write property.
+ // A read/write property.
member this.Age
with get() = internalAge
and set(value) = internalAge <- value
- // Instance methods.
- // Increment the person's age.
+ // Instance methods.
+ // Increment the person's age.
member this.HasABirthday () = internalAge <- internalAge + 1
- // Check current age against some threshold.
+ // Check current age against some threshold.
member this.IsOfAge targetAge = internalAge >= targetAge
- // Display the person's name and age.
- override this.ToString () =
+ // Display the person's name and age.
+ override this.ToString () =
"Name: " + name + "\n" + "Age: " + (string)internalAge
-</code></pre>
\ No newline at end of file
+</code></pre>
diff --git a/tests/languages/fsharp/string_feature.test b/tests/languages/fsharp/string_feature.test
index 3c984a8..c6310d8 100644
--- a/tests/languages/fsharp/string_feature.test
+++ b/tests/languages/fsharp/string_feature.test
@@ -18,6 +18,10 @@ bar"""
'a'B
'\''
'\\'
+'\231'
+'\x41'
+'\u0041'
+'\U0001F47D'
----------------------------------------------------
@@ -39,9 +43,13 @@ bar"""
["string", "'a'"],
["string", "'a'B"],
["string", "'\\''"],
- ["string", "'\\\\'"]
+ ["string", "'\\\\'"],
+ ["string", "'\\231'"],
+ ["string", "'\\x41'"],
+ ["string", "'\\u0041'"],
+ ["string", "'\\U0001F47D'"]
]
----------------------------------------------------
-Checks for normal strings, verbatim strings, triple-quoted strings and character literals.
\ No newline at end of file
+Checks for normal strings, verbatim strings, triple-quoted strings and character literals.