YAML: Improvements (#2226)

The patterns for tags, anchors, and aliases and their usage in other patterns are improved to match the YAML spec as close as possible.
This commit is contained in:
Michael Schmidt 2020-02-23 14:06:24 +01:00 committed by GitHub
parent c5de5aa86b
commit 5362ba16e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 260 additions and 133 deletions

View File

@ -1,47 +1,76 @@
Prism.languages.yaml = {
'scalar': {
pattern: /([\-:]\s*(?:\s[!&*][^\s]+)*[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,
lookbehind: true,
alias: 'string'
},
'comment': /#.*/,
'key': {
pattern: /(\s*(?:^|[:\-,[{\r\n?])[ \t]*(?:![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,
lookbehind: true,
alias: 'atrule'
},
'directive': {
pattern: /(^[ \t]*)%.+/m,
lookbehind: true,
alias: 'important'
},
'datetime': {
pattern: /([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?)(?=[ \t]*(?:$|,|]|}))/m,
lookbehind: true,
alias: 'number'
},
'boolean': {
pattern: /([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:true|false)[ \t]*(?=$|,|]|})/im,
lookbehind: true,
alias: 'important'
},
'null': {
pattern: /([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:null|~)[ \t]*(?=$|,|]|})/im,
lookbehind: true,
alias: 'important'
},
'string': {
pattern: /([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ \t]*(?:$|,|]|}|\s*#))/m,
lookbehind: true,
greedy: true
},
'number': {
pattern: /([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,
lookbehind: true
},
'tag': /![^\s]+/,
'important': /[&*][^\s\[\]{},]+/,
'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
};
(function (Prism) {
Prism.languages.yml = Prism.languages.yaml;
// https://yaml.org/spec/1.2/spec.html#c-ns-anchor-property
// https://yaml.org/spec/1.2/spec.html#c-ns-alias-node
var anchorOrAlias = /[*&][^\s[\]{},]+/;
// https://yaml.org/spec/1.2/spec.html#c-ns-tag-property
var tag = /!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/;
// https://yaml.org/spec/1.2/spec.html#c-ns-properties(n,c)
var properties = '(?:' + tag.source + '(?:[ \t]+' + anchorOrAlias.source + ')?|'
+ anchorOrAlias.source + '(?:[ \t]+' + tag.source + ')?)';
/**
*
* @param {string} value
* @param {string} [flags]
* @returns {RegExp}
*/
function createValuePattern(value, flags) {
flags = (flags || '').replace(/m/g, '') + 'm'; // add m flag
var pattern = /([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|]|}|\s*#))/.source
.replace(/<<prop>>/g, properties).replace(/<<value>>/g, value);
return RegExp(pattern, flags)
}
Prism.languages.yaml = {
'scalar': {
pattern: RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/.source
.replace(/<<prop>>/g, properties)),
lookbehind: true,
alias: 'string'
},
'comment': /#.*/,
'key': {
pattern: RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)[^\r\n{[\]},#\s]+?(?=\s*:\s)/.source
.replace(/<<prop>>/g, properties)),
lookbehind: true,
alias: 'atrule'
},
'directive': {
pattern: /(^[ \t]*)%.+/m,
lookbehind: true,
alias: 'important'
},
'datetime': {
pattern: createValuePattern(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),
lookbehind: true,
alias: 'number'
},
'boolean': {
pattern: createValuePattern(/true|false/.source, 'i'),
lookbehind: true,
alias: 'important'
},
'null': {
pattern: createValuePattern(/null|~/.source, 'i'),
lookbehind: true,
alias: 'important'
},
'string': {
// \2 because of the lookbehind group
pattern: createValuePattern(/("|')(?:(?!\2)[^\\\r\n]|\\.)*\2/.source),
lookbehind: true,
greedy: true
},
'number': {
pattern: createValuePattern(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source, 'i'),
lookbehind: true
},
'tag': tag,
'important': anchorOrAlias,
'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
};
Prism.languages.yml = Prism.languages.yaml;
}(Prism));

View File

@ -1 +1 @@
Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(?:\s[!&*][^\s]+)*[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:/(\s*(?:^|[:\-,[{\r\n?])[ \t]*(?:![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?)(?=[ \t]*(?:$|,|]|}))/m,lookbehind:!0,alias:"number"},boolean:{pattern:/([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:true|false)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},null:{pattern:/([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)(?:null|~)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ \t]*(?:$|,|]|}|\s*#))/m,lookbehind:!0,greedy:!0},number:{pattern:/([:\-,[{]\s*(?:\s[!&*][^\s]+)*[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,lookbehind:!0},tag:/![^\s]+/,important:/[&*][^\s\[\]{},]+/,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},Prism.languages.yml=Prism.languages.yaml;
!function(e){var a=/[*&][^\s[\]{},]+/,t=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+t.source+"(?:[ \t]+"+a.source+")?|"+a.source+"(?:[ \t]+"+t.source+")?)";function n(e,a){a=(a||"").replace(/m/g,"")+"m";var t="([:\\-,[{]\\s*(?:\\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|]|}|\\s*#))".replace(/<<prop>>/g,r).replace(/<<value>>/g,e);return RegExp(t,a)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\\n]+(?:\\2[^\r\\n]+)*)".replace(/<<prop>>/g,r)),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\\n?])[ \t]*(?:<<prop>>[ \t]+)?)[^\r\\n{[\\]},#\\s]+?(?=\\s*:\\s)".replace(/<<prop>>/g,r)),lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:n("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:n("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:n("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:n("(\"|')(?:(?!\\2)[^\\\\\\r\n]|\\\\.)*\\2"),lookbehind:!0,greedy:!0},number:{pattern:n("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:t,important:a,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism);

View File

@ -4,8 +4,8 @@ x-null: &nu-ll null
x-boolean: &boo-lean true
x-datetime: &date-time 2001-12-15T02:59:43.1Z
x-scalar: &sca-lar |
foo
bar
foo
bar
x-utf8: &アンカー "japanese anchor"
@ -15,8 +15,8 @@ x-tag-null: &tag-null !!tag-null null
x-tag-boolean: &tag-bool !!tag-bool true
x-tag-datetime: &tag-date !!tag-date 2001-12-15T02:59:43.1Z
x-tag-scalar: &tag-scalar !!tag-scalar |
foo
bar
foo
bar
x-tag-string: !!tag-string &tag-string "13"
x-tag-number: !!tag-number &tag-number 42
@ -24,8 +24,8 @@ x-tag-null: !!tag-null &tag-null null
x-tag-boolean: !!tag-bool &tag-bool true
x-tag-datetime: !!tag-date &tag-date 2001-12-15T02:59:43.1Z
x-tag-scalar: !!tag-scalar &tag-scalar |
foo
bar
foo
bar
foobar: *num-ber
fubar: *stri_ng
@ -33,140 +33,161 @@ japanese: *アンカー
taga: *tag-a !!taga
tagb: !!tagb *tag-b
# https://yaml.org/spec/1.2/spec.html#id2783797
!!str &a1 "foo":
!!str bar
&a2 baz : *a1
----------------------------------------------------
[
["key", "x-number"],
["punctuation", ":"],
["important", "&num-ber"],
["number", "13"],
["number", "13"],
["key", "x-string"],
["punctuation", ":"],
["important", "&stri_ng"],
["string", "\"good\""],
["string", "\"good\""],
["key", "x-null"],
["key", "x-null"],
["punctuation", ":"],
["important", "&nu-ll"],
["null", "null"],
["null", "null"],
["key", "x-boolean"],
["key", "x-boolean"],
["punctuation", ":"],
["important", "&boo-lean"],
["boolean", "true"],
["boolean", "true"],
["key", "x-datetime"],
["key", "x-datetime"],
["punctuation", ":"],
["important", "&date-time"],
["datetime", "2001-12-15T02:59:43.1Z"],
["datetime", "2001-12-15T02:59:43.1Z"],
["key", "x-scalar"],
["key", "x-scalar"],
["punctuation", ":"],
["important", "&sca-lar"],
["punctuation", "|"],
["scalar", "\n foo\n bar"],
["punctuation", "|"],
["scalar", "\n\tfoo\n\tbar"],
["key", "x-utf8"],
["key", "x-utf8"],
["punctuation", ":"],
["important", "&アンカー"],
["string", "\"japanese anchor\""],
["string", "\"japanese anchor\""],
["key", "x-tag-string"],
["punctuation", ":"],
["important", "&tag-string"],
["tag", "!!tag-string"],
["string", "\"13\""],
["key", "x-tag-string"],
["punctuation", ":"],
["important", "&tag-string"],
["tag", "!!tag-string"],
["string", "\"13\""],
["key", "x-tag-number"],
["punctuation", ":"],
["important", "&tag-number"],
["tag", "!!tag-number"],
["number", "42"],
["key", "x-tag-number"],
["punctuation", ":"],
["important", "&tag-number"],
["tag", "!!tag-number"],
["number", "42"],
["key", "x-tag-null"],
["key", "x-tag-null"],
["punctuation", ":"],
["important", "&tag-null"],
["tag", "!!tag-null"],
["null", "null"],
["tag", "!!tag-null"],
["null", "null"],
["key", "x-tag-boolean"],
["key", "x-tag-boolean"],
["punctuation", ":"],
["important", "&tag-bool"],
["tag", "!!tag-bool"],
["boolean", "true"],
["tag", "!!tag-bool"],
["boolean", "true"],
["key", "x-tag-datetime"],
["key", "x-tag-datetime"],
["punctuation", ":"],
["important", "&tag-date"],
["tag", "!!tag-date"],
["datetime", "2001-12-15T02:59:43.1Z"],
["tag", "!!tag-date"],
["datetime", "2001-12-15T02:59:43.1Z"],
["key", "x-tag-scalar"],
["key", "x-tag-scalar"],
["punctuation", ":"],
["important", "&tag-scalar"],
["tag", "!!tag-scalar"],
["punctuation", "|"],
["scalar", "\n foo\n bar"],
["tag", "!!tag-scalar"],
["punctuation", "|"],
["scalar", "\n\tfoo\n\tbar"],
["key", "x-tag-string"],
["punctuation", ":"],
["tag", "!!tag-string"],
["important", "&tag-string"],
["string", "\"13\""],
["key", "x-tag-number"],
["punctuation", ":"],
["tag", "!!tag-number"],
["important", "&tag-number"],
["number", "42"],
["key", "x-tag-null"],
["key", "x-tag-string"],
["punctuation", ":"],
["tag", "!!tag-null"],
["tag", "!!tag-string"],
["important", "&tag-string"],
["string", "\"13\""],
["key", "x-tag-number"],
["punctuation", ":"],
["tag", "!!tag-number"],
["important", "&tag-number"],
["number", "42"],
["key", "x-tag-null"],
["punctuation", ":"],
["tag", "!!tag-null"],
["important", "&tag-null"],
["null", "null"],
["null", "null"],
["key", "x-tag-boolean"],
["key", "x-tag-boolean"],
["punctuation", ":"],
["tag", "!!tag-bool"],
["tag", "!!tag-bool"],
["important", "&tag-bool"],
["boolean", "true"],
["boolean", "true"],
["key", "x-tag-datetime"],
["key", "x-tag-datetime"],
["punctuation", ":"],
["tag", "!!tag-date"],
["tag", "!!tag-date"],
["important", "&tag-date"],
["datetime", "2001-12-15T02:59:43.1Z"],
["datetime", "2001-12-15T02:59:43.1Z"],
["key", "x-tag-scalar"],
["key", "x-tag-scalar"],
["punctuation", ":"],
["tag", "!!tag-scalar"],
["tag", "!!tag-scalar"],
["important", "&tag-scalar"],
["punctuation", "|"],
["scalar", "\n foo\n bar"],
["punctuation", "|"],
["scalar", "\n\tfoo\n\tbar"],
["key", "foobar"],
["punctuation", ":"],
["important", "*num-ber"],
["key", "foobar"],
["punctuation", ":"],
["important", "*num-ber"],
["key", "fubar"],
["punctuation", ":"],
["important", "*stri_ng"],
["key", "fubar"],
["punctuation", ":"],
["important", "*stri_ng"],
["key", "japanese"],
["punctuation", ":"],
["important", "*アンカー"],
["key", "japanese"],
["punctuation", ":"],
["important", "*アンカー"],
["key", "taga"],
["punctuation", ":"],
["important", "*tag-a"],
["tag", "!!taga"],
["key", "taga"],
["punctuation", ":"],
["important", "*tag-a"],
["tag", "!!taga"],
["key", "tagb"],
["punctuation", ":"],
["tag", "!!tagb"],
["important", "*tag-b"]
["key", "tagb"],
["punctuation", ":"],
["tag", "!!tagb"],
["important", "*tag-b"],
["comment", "# https://yaml.org/spec/1.2/spec.html#id2783797"],
["tag", "!!str"],
["important", "&a1"],
["key", "\"foo\""],
["punctuation", ":"],
["tag", "!!str"],
" bar\n",
["important", "&a2"],
["key", "baz"],
["punctuation", ":"],
["important", "*a1"]
]
----------------------------------------------------

View File

@ -2,14 +2,91 @@
!!str
!!seq
# https://yaml.org/spec/1.2/spec.html#c-ns-tag-property
!<tag:yaml.org,2002:str> foo : !<!bar> baz
- !local foo
- !!str bar
- !e!tag%21 baz
!!seq [
!<!local> "foo",
!<tag:yaml.org,2002:str> "bar",
!<tag:example.com,2000:app/tag!> "baz"
]
# Assuming conventional resolution:
- "12"
- 12
- ! 12
!!seq [
!<tag:yaml.org,2002:str> "12",
!<tag:yaml.org,2002:int> "12",
!<tag:yaml.org,2002:str> "12",
]
----------------------------------------------------
[
["tag", "!!map"],
["tag", "!!str"],
["tag", "!!seq"]
["tag", "!!seq"],
["comment", "# https://yaml.org/spec/1.2/spec.html#c-ns-tag-property"],
["tag", "!<tag:yaml.org,2002:str>"],
["key", "foo"],
["punctuation", ":"],
["tag", "!<!bar>"],
" baz\r\n\r\n",
["punctuation", "-"],
["tag", "!local"],
" foo\r\n",
["punctuation", "-"],
["tag", "!!str"],
" bar\r\n",
["punctuation", "-"],
["tag", "!e!tag%21"],
" baz\r\n\r\n",
["tag", "!!seq"],
["punctuation", "["],
["tag", "!<!local>"],
["string", "\"foo\""],
["punctuation", ","],
["tag", "!<tag:yaml.org,2002:str>"],
["string", "\"bar\""],
["punctuation", ","],
["tag", "!<tag:example.com,2000:app/tag!>"],
["string", "\"baz\""],
["punctuation", "]"],
["comment", "# Assuming conventional resolution:"],
["punctuation", "-"],
["string", "\"12\""],
["punctuation", "-"],
["number", "12"],
["punctuation", "-"],
["tag", "!"],
["number", "12"],
["tag", "!!seq"],
["punctuation", "["],
["tag", "!<tag:yaml.org,2002:str>"],
["string", "\"12\""],
["punctuation", ","],
["tag", "!<tag:yaml.org,2002:int>"],
["string", "\"12\""],
["punctuation", ","],
["tag", "!<tag:yaml.org,2002:str>"],
["string", "\"12\""],
["punctuation", ","],
["punctuation", "]"]
]
----------------------------------------------------
Checks for tags
Checks for tags