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. contains: [],
  68. keywords: LITERALS,
  69. relevance: 0
  70. };
  71. var OBJECT = {
  72. begin: '{',
  73. end: '}',
  74. contains: [VALUE_CONTAINER],
  75. illegal: '\\n',
  76. relevance: 0
  77. };
  78. var ARRAY = {
  79. begin: '\\[',
  80. end: '\\]',
  81. contains: [VALUE_CONTAINER],
  82. illegal: '\\n',
  83. relevance: 0
  84. };
  85. var MODES = [
  86. KEY,
  87. {
  88. className: 'meta',
  89. begin: '^---\s*$',
  90. relevance: 10
  91. },
  92. { // multi line string
  93. // Blocks start with a | or > followed by a newline
  94. //
  95. // Indentation of subsequent lines must be the same to
  96. // be considered part of the block
  97. className: 'string',
  98. begin: '[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*'
  99. },
  100. { // Ruby/Rails erb
  101. begin: '<%[%=-]?',
  102. end: '[%-]?%>',
  103. subLanguage: 'ruby',
  104. excludeBegin: true,
  105. excludeEnd: true,
  106. relevance: 0
  107. },
  108. { // named tags
  109. className: 'type',
  110. begin: '!\\w+!' + URI_CHARACTERS
  111. },
  112. // https://yaml.org/spec/1.2/spec.html#id2784064
  113. { // verbatim tags
  114. className: 'type',
  115. begin: '!<' + URI_CHARACTERS + ">"
  116. },
  117. { // primary tags
  118. className: 'type',
  119. begin: '!' + URI_CHARACTERS
  120. },
  121. { // secondary tags
  122. className: 'type',
  123. begin: '!!' + URI_CHARACTERS
  124. },
  125. { // fragment id &ref
  126. className: 'meta',
  127. begin: '&' + hljs.UNDERSCORE_IDENT_RE + '$'
  128. },
  129. { // fragment reference *ref
  130. className: 'meta',
  131. begin: '\\*' + hljs.UNDERSCORE_IDENT_RE + '$'
  132. },
  133. { // array listing
  134. className: 'bullet',
  135. // TODO: remove |$ hack when we have proper look-ahead support
  136. begin: '\\-(?=[ ]|$)',
  137. relevance: 0
  138. },
  139. hljs.HASH_COMMENT_MODE,
  140. {
  141. beginKeywords: LITERALS,
  142. keywords: { literal: LITERALS }
  143. },
  144. TIMESTAMP,
  145. // numbers are any valid C-style number that
  146. // sit isolated from other words
  147. {
  148. className: 'number',
  149. begin: hljs.C_NUMBER_RE + '\\b'
  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', 'YAML'],
  163. contains: MODES
  164. };
  165. }
  166. module.exports = yaml;