pug.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. export var conf = {
  6. comments: {
  7. lineComment: '//'
  8. },
  9. brackets: [
  10. ['{', '}'],
  11. ['[', ']'],
  12. ['(', ')']
  13. ],
  14. autoClosingPairs: [
  15. { open: '"', close: '"', notIn: ['string', 'comment'] },
  16. { open: "'", close: "'", notIn: ['string', 'comment'] },
  17. { open: '{', close: '}', notIn: ['string', 'comment'] },
  18. { open: '[', close: ']', notIn: ['string', 'comment'] },
  19. { open: '(', close: ')', notIn: ['string', 'comment'] }
  20. ],
  21. folding: {
  22. offSide: true
  23. }
  24. };
  25. export var language = {
  26. defaultToken: '',
  27. tokenPostfix: '.pug',
  28. ignoreCase: true,
  29. brackets: [
  30. { token: 'delimiter.curly', open: '{', close: '}' },
  31. { token: 'delimiter.array', open: '[', close: ']' },
  32. { token: 'delimiter.parenthesis', open: '(', close: ')' }
  33. ],
  34. keywords: [
  35. 'append',
  36. 'block',
  37. 'case',
  38. 'default',
  39. 'doctype',
  40. 'each',
  41. 'else',
  42. 'extends',
  43. 'for',
  44. 'if',
  45. 'in',
  46. 'include',
  47. 'mixin',
  48. 'typeof',
  49. 'unless',
  50. 'var',
  51. 'when'
  52. ],
  53. tags: [
  54. 'a',
  55. 'abbr',
  56. 'acronym',
  57. 'address',
  58. 'area',
  59. 'article',
  60. 'aside',
  61. 'audio',
  62. 'b',
  63. 'base',
  64. 'basefont',
  65. 'bdi',
  66. 'bdo',
  67. 'blockquote',
  68. 'body',
  69. 'br',
  70. 'button',
  71. 'canvas',
  72. 'caption',
  73. 'center',
  74. 'cite',
  75. 'code',
  76. 'col',
  77. 'colgroup',
  78. 'command',
  79. 'datalist',
  80. 'dd',
  81. 'del',
  82. 'details',
  83. 'dfn',
  84. 'div',
  85. 'dl',
  86. 'dt',
  87. 'em',
  88. 'embed',
  89. 'fieldset',
  90. 'figcaption',
  91. 'figure',
  92. 'font',
  93. 'footer',
  94. 'form',
  95. 'frame',
  96. 'frameset',
  97. 'h1',
  98. 'h2',
  99. 'h3',
  100. 'h4',
  101. 'h5',
  102. 'h6',
  103. 'head',
  104. 'header',
  105. 'hgroup',
  106. 'hr',
  107. 'html',
  108. 'i',
  109. 'iframe',
  110. 'img',
  111. 'input',
  112. 'ins',
  113. 'keygen',
  114. 'kbd',
  115. 'label',
  116. 'li',
  117. 'link',
  118. 'map',
  119. 'mark',
  120. 'menu',
  121. 'meta',
  122. 'meter',
  123. 'nav',
  124. 'noframes',
  125. 'noscript',
  126. 'object',
  127. 'ol',
  128. 'optgroup',
  129. 'option',
  130. 'output',
  131. 'p',
  132. 'param',
  133. 'pre',
  134. 'progress',
  135. 'q',
  136. 'rp',
  137. 'rt',
  138. 'ruby',
  139. 's',
  140. 'samp',
  141. 'script',
  142. 'section',
  143. 'select',
  144. 'small',
  145. 'source',
  146. 'span',
  147. 'strike',
  148. 'strong',
  149. 'style',
  150. 'sub',
  151. 'summary',
  152. 'sup',
  153. 'table',
  154. 'tbody',
  155. 'td',
  156. 'textarea',
  157. 'tfoot',
  158. 'th',
  159. 'thead',
  160. 'time',
  161. 'title',
  162. 'tr',
  163. 'tracks',
  164. 'tt',
  165. 'u',
  166. 'ul',
  167. 'video',
  168. 'wbr'
  169. ],
  170. // we include these common regular expressions
  171. symbols: /[\+\-\*\%\&\|\!\=\/\.\,\:]+/,
  172. escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
  173. tokenizer: {
  174. root: [
  175. // Tag or a keyword at start
  176. [
  177. /^(\s*)([a-zA-Z_-][\w-]*)/,
  178. {
  179. cases: {
  180. '$2@tags': {
  181. cases: {
  182. '@eos': ['', 'tag'],
  183. '@default': ['', { token: 'tag', next: '@tag.$1' }]
  184. }
  185. },
  186. '$2@keywords': ['', { token: 'keyword.$2' }],
  187. '@default': ['', '']
  188. }
  189. }
  190. ],
  191. // id
  192. [
  193. /^(\s*)(#[a-zA-Z_-][\w-]*)/,
  194. {
  195. cases: {
  196. '@eos': ['', 'tag.id'],
  197. '@default': ['', { token: 'tag.id', next: '@tag.$1' }]
  198. }
  199. }
  200. ],
  201. // class
  202. [
  203. /^(\s*)(\.[a-zA-Z_-][\w-]*)/,
  204. {
  205. cases: {
  206. '@eos': ['', 'tag.class'],
  207. '@default': ['', { token: 'tag.class', next: '@tag.$1' }]
  208. }
  209. }
  210. ],
  211. // plain text with pipe
  212. [/^(\s*)(\|.*)$/, ''],
  213. { include: '@whitespace' },
  214. // keywords
  215. [
  216. /[a-zA-Z_$][\w$]*/,
  217. {
  218. cases: {
  219. '@keywords': { token: 'keyword.$0' },
  220. '@default': ''
  221. }
  222. }
  223. ],
  224. // delimiters and operators
  225. [/[{}()\[\]]/, '@brackets'],
  226. [/@symbols/, 'delimiter'],
  227. // numbers
  228. [/\d+\.\d+([eE][\-+]?\d+)?/, 'number.float'],
  229. [/\d+/, 'number'],
  230. // strings:
  231. [/"/, 'string', '@string."'],
  232. [/'/, 'string', "@string.'"]
  233. ],
  234. tag: [
  235. [/(\.)(\s*$)/, [{ token: 'delimiter', next: '@blockText.$S2.' }, '']],
  236. [/\s+/, { token: '', next: '@simpleText' }],
  237. // id
  238. [
  239. /#[a-zA-Z_-][\w-]*/,
  240. {
  241. cases: {
  242. '@eos': { token: 'tag.id', next: '@pop' },
  243. '@default': 'tag.id'
  244. }
  245. }
  246. ],
  247. // class
  248. [
  249. /\.[a-zA-Z_-][\w-]*/,
  250. {
  251. cases: {
  252. '@eos': { token: 'tag.class', next: '@pop' },
  253. '@default': 'tag.class'
  254. }
  255. }
  256. ],
  257. // attributes
  258. [/\(/, { token: 'delimiter.parenthesis', next: '@attributeList' }]
  259. ],
  260. simpleText: [
  261. [/[^#]+$/, { token: '', next: '@popall' }],
  262. [/[^#]+/, { token: '' }],
  263. // interpolation
  264. [
  265. /(#{)([^}]*)(})/,
  266. {
  267. cases: {
  268. '@eos': [
  269. 'interpolation.delimiter',
  270. 'interpolation',
  271. {
  272. token: 'interpolation.delimiter',
  273. next: '@popall'
  274. }
  275. ],
  276. '@default': [
  277. 'interpolation.delimiter',
  278. 'interpolation',
  279. 'interpolation.delimiter'
  280. ]
  281. }
  282. }
  283. ],
  284. [/#$/, { token: '', next: '@popall' }],
  285. [/#/, '']
  286. ],
  287. attributeList: [
  288. [/\s+/, ''],
  289. [
  290. /(\w+)(\s*=\s*)("|')/,
  291. ['attribute.name', 'delimiter', { token: 'attribute.value', next: '@value.$3' }]
  292. ],
  293. [/\w+/, 'attribute.name'],
  294. [
  295. /,/,
  296. {
  297. cases: {
  298. '@eos': {
  299. token: 'attribute.delimiter',
  300. next: '@popall'
  301. },
  302. '@default': 'attribute.delimiter'
  303. }
  304. }
  305. ],
  306. [/\)$/, { token: 'delimiter.parenthesis', next: '@popall' }],
  307. [/\)/, { token: 'delimiter.parenthesis', next: '@pop' }]
  308. ],
  309. whitespace: [
  310. [/^(\s*)(\/\/.*)$/, { token: 'comment', next: '@blockText.$1.comment' }],
  311. [/[ \t\r\n]+/, ''],
  312. [/<!--/, { token: 'comment', next: '@comment' }]
  313. ],
  314. blockText: [
  315. [
  316. /^\s+.*$/,
  317. {
  318. cases: {
  319. '($S2\\s+.*$)': { token: '$S3' },
  320. '@default': { token: '@rematch', next: '@popall' }
  321. }
  322. }
  323. ],
  324. [/./, { token: '@rematch', next: '@popall' }]
  325. ],
  326. comment: [
  327. [/[^<\-]+/, 'comment.content'],
  328. [/-->/, { token: 'comment', next: '@pop' }],
  329. [/<!--/, 'comment.content.invalid'],
  330. [/[<\-]/, 'comment.content']
  331. ],
  332. string: [
  333. [
  334. /[^\\"'#]+/,
  335. {
  336. cases: {
  337. '@eos': { token: 'string', next: '@popall' },
  338. '@default': 'string'
  339. }
  340. }
  341. ],
  342. [
  343. /@escapes/,
  344. {
  345. cases: {
  346. '@eos': { token: 'string.escape', next: '@popall' },
  347. '@default': 'string.escape'
  348. }
  349. }
  350. ],
  351. [
  352. /\\./,
  353. {
  354. cases: {
  355. '@eos': {
  356. token: 'string.escape.invalid',
  357. next: '@popall'
  358. },
  359. '@default': 'string.escape.invalid'
  360. }
  361. }
  362. ],
  363. // interpolation
  364. [
  365. /(#{)([^}]*)(})/,
  366. ['interpolation.delimiter', 'interpolation', 'interpolation.delimiter']
  367. ],
  368. [/#/, 'string'],
  369. [
  370. /["']/,
  371. {
  372. cases: {
  373. '$#==$S2': { token: 'string', next: '@pop' },
  374. '@default': { token: 'string' }
  375. }
  376. }
  377. ]
  378. ],
  379. // Almost identical to above, except for escapes and the output token
  380. value: [
  381. [
  382. /[^\\"']+/,
  383. {
  384. cases: {
  385. '@eos': { token: 'attribute.value', next: '@popall' },
  386. '@default': 'attribute.value'
  387. }
  388. }
  389. ],
  390. [
  391. /\\./,
  392. {
  393. cases: {
  394. '@eos': { token: 'attribute.value', next: '@popall' },
  395. '@default': 'attribute.value'
  396. }
  397. }
  398. ],
  399. [
  400. /["']/,
  401. {
  402. cases: {
  403. '$#==$S2': { token: 'attribute.value', next: '@pop' },
  404. '@default': { token: 'attribute.value' }
  405. }
  406. }
  407. ]
  408. ]
  409. }
  410. };