yaml.js 4.3 KB

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