| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 | 
							- /*
 
- Language: Crystal
 
- Author: TSUYUSATO Kitsune <make.just.on@gmail.com>
 
- Website: https://crystal-lang.org
 
- */
 
- /** @type LanguageFn */
 
- function crystal(hljs) {
 
-   const INT_SUFFIX = '(_?[ui](8|16|32|64|128))?';
 
-   const FLOAT_SUFFIX = '(_?f(32|64))?';
 
-   const CRYSTAL_IDENT_RE = '[a-zA-Z_]\\w*[!?=]?';
 
-   const CRYSTAL_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|[=!]~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?';
 
-   const CRYSTAL_PATH_RE = '[A-Za-z_]\\w*(::\\w+)*(\\?|!)?';
 
-   const CRYSTAL_KEYWORDS = {
 
-     $pattern: CRYSTAL_IDENT_RE,
 
-     keyword:
 
-       'abstract alias annotation as as? asm begin break case class def do else elsif end ensure enum extend for fun if ' +
 
-       'include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? ' +
 
-       'return require select self sizeof struct super then type typeof union uninitialized unless until verbatim when while with yield ' +
 
-       '__DIR__ __END_LINE__ __FILE__ __LINE__',
 
-     literal: 'false nil true'
 
-   };
 
-   const SUBST = {
 
-     className: 'subst',
 
-     begin: /#\{/,
 
-     end: /\}/,
 
-     keywords: CRYSTAL_KEYWORDS
 
-   };
 
-   const EXPANSION = {
 
-     className: 'template-variable',
 
-     variants: [
 
-       {
 
-         begin: '\\{\\{',
 
-         end: '\\}\\}'
 
-       },
 
-       {
 
-         begin: '\\{%',
 
-         end: '%\\}'
 
-       }
 
-     ],
 
-     keywords: CRYSTAL_KEYWORDS
 
-   };
 
-   function recursiveParen(begin, end) {
 
-     const
 
-         contains = [
 
-           {
 
-             begin: begin,
 
-             end: end
 
-           }
 
-         ];
 
-     contains[0].contains = contains;
 
-     return contains;
 
-   }
 
-   const STRING = {
 
-     className: 'string',
 
-     contains: [
 
-       hljs.BACKSLASH_ESCAPE,
 
-       SUBST
 
-     ],
 
-     variants: [
 
-       {
 
-         begin: /'/,
 
-         end: /'/
 
-       },
 
-       {
 
-         begin: /"/,
 
-         end: /"/
 
-       },
 
-       {
 
-         begin: /`/,
 
-         end: /`/
 
-       },
 
-       {
 
-         begin: '%[Qwi]?\\(',
 
-         end: '\\)',
 
-         contains: recursiveParen('\\(', '\\)')
 
-       },
 
-       {
 
-         begin: '%[Qwi]?\\[',
 
-         end: '\\]',
 
-         contains: recursiveParen('\\[', '\\]')
 
-       },
 
-       {
 
-         begin: '%[Qwi]?\\{',
 
-         end: /\}/,
 
-         contains: recursiveParen(/\{/, /\}/)
 
-       },
 
-       {
 
-         begin: '%[Qwi]?<',
 
-         end: '>',
 
-         contains: recursiveParen('<', '>')
 
-       },
 
-       {
 
-         begin: '%[Qwi]?\\|',
 
-         end: '\\|'
 
-       },
 
-       {
 
-         begin: /<<-\w+$/,
 
-         end: /^\s*\w+$/
 
-       }
 
-     ],
 
-     relevance: 0
 
-   };
 
-   const Q_STRING = {
 
-     className: 'string',
 
-     variants: [
 
-       {
 
-         begin: '%q\\(',
 
-         end: '\\)',
 
-         contains: recursiveParen('\\(', '\\)')
 
-       },
 
-       {
 
-         begin: '%q\\[',
 
-         end: '\\]',
 
-         contains: recursiveParen('\\[', '\\]')
 
-       },
 
-       {
 
-         begin: '%q\\{',
 
-         end: /\}/,
 
-         contains: recursiveParen(/\{/, /\}/)
 
-       },
 
-       {
 
-         begin: '%q<',
 
-         end: '>',
 
-         contains: recursiveParen('<', '>')
 
-       },
 
-       {
 
-         begin: '%q\\|',
 
-         end: '\\|'
 
-       },
 
-       {
 
-         begin: /<<-'\w+'$/,
 
-         end: /^\s*\w+$/
 
-       }
 
-     ],
 
-     relevance: 0
 
-   };
 
-   const REGEXP = {
 
-     begin: '(?!%\\})(' + hljs.RE_STARTERS_RE + '|\\n|\\b(case|if|select|unless|until|when|while)\\b)\\s*',
 
-     keywords: 'case if select unless until when while',
 
-     contains: [
 
-       {
 
-         className: 'regexp',
 
-         contains: [
 
-           hljs.BACKSLASH_ESCAPE,
 
-           SUBST
 
-         ],
 
-         variants: [
 
-           {
 
-             begin: '//[a-z]*',
 
-             relevance: 0
 
-           },
 
-           {
 
-             begin: '/(?!\\/)',
 
-             end: '/[a-z]*'
 
-           }
 
-         ]
 
-       }
 
-     ],
 
-     relevance: 0
 
-   };
 
-   const REGEXP2 = {
 
-     className: 'regexp',
 
-     contains: [
 
-       hljs.BACKSLASH_ESCAPE,
 
-       SUBST
 
-     ],
 
-     variants: [
 
-       {
 
-         begin: '%r\\(',
 
-         end: '\\)',
 
-         contains: recursiveParen('\\(', '\\)')
 
-       },
 
-       {
 
-         begin: '%r\\[',
 
-         end: '\\]',
 
-         contains: recursiveParen('\\[', '\\]')
 
-       },
 
-       {
 
-         begin: '%r\\{',
 
-         end: /\}/,
 
-         contains: recursiveParen(/\{/, /\}/)
 
-       },
 
-       {
 
-         begin: '%r<',
 
-         end: '>',
 
-         contains: recursiveParen('<', '>')
 
-       },
 
-       {
 
-         begin: '%r\\|',
 
-         end: '\\|'
 
-       }
 
-     ],
 
-     relevance: 0
 
-   };
 
-   const ATTRIBUTE = {
 
-     className: 'meta',
 
-     begin: '@\\[',
 
-     end: '\\]',
 
-     contains: [
 
-       hljs.inherit(hljs.QUOTE_STRING_MODE, {
 
-         className: 'meta-string'
 
-       })
 
-     ]
 
-   };
 
-   const CRYSTAL_DEFAULT_CONTAINS = [
 
-     EXPANSION,
 
-     STRING,
 
-     Q_STRING,
 
-     REGEXP2,
 
-     REGEXP,
 
-     ATTRIBUTE,
 
-     hljs.HASH_COMMENT_MODE,
 
-     {
 
-       className: 'class',
 
-       beginKeywords: 'class module struct',
 
-       end: '$|;',
 
-       illegal: /=/,
 
-       contains: [
 
-         hljs.HASH_COMMENT_MODE,
 
-         hljs.inherit(hljs.TITLE_MODE, {
 
-           begin: CRYSTAL_PATH_RE
 
-         }),
 
-         { // relevance booster for inheritance
 
-           begin: '<'
 
-         }
 
-       ]
 
-     },
 
-     {
 
-       className: 'class',
 
-       beginKeywords: 'lib enum union',
 
-       end: '$|;',
 
-       illegal: /=/,
 
-       contains: [
 
-         hljs.HASH_COMMENT_MODE,
 
-         hljs.inherit(hljs.TITLE_MODE, {
 
-           begin: CRYSTAL_PATH_RE
 
-         })
 
-       ]
 
-     },
 
-     {
 
-       beginKeywords: 'annotation',
 
-       end: '$|;',
 
-       illegal: /=/,
 
-       contains: [
 
-         hljs.HASH_COMMENT_MODE,
 
-         hljs.inherit(hljs.TITLE_MODE, {
 
-           begin: CRYSTAL_PATH_RE
 
-         })
 
-       ],
 
-       relevance: 2
 
-     },
 
-     {
 
-       className: 'function',
 
-       beginKeywords: 'def',
 
-       end: /\B\b/,
 
-       contains: [
 
-         hljs.inherit(hljs.TITLE_MODE, {
 
-           begin: CRYSTAL_METHOD_RE,
 
-           endsParent: true
 
-         })
 
-       ]
 
-     },
 
-     {
 
-       className: 'function',
 
-       beginKeywords: 'fun macro',
 
-       end: /\B\b/,
 
-       contains: [
 
-         hljs.inherit(hljs.TITLE_MODE, {
 
-           begin: CRYSTAL_METHOD_RE,
 
-           endsParent: true
 
-         })
 
-       ],
 
-       relevance: 2
 
-     },
 
-     {
 
-       className: 'symbol',
 
-       begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
 
-       relevance: 0
 
-     },
 
-     {
 
-       className: 'symbol',
 
-       begin: ':',
 
-       contains: [
 
-         STRING,
 
-         {
 
-           begin: CRYSTAL_METHOD_RE
 
-         }
 
-       ],
 
-       relevance: 0
 
-     },
 
-     {
 
-       className: 'number',
 
-       variants: [
 
-         {
 
-           begin: '\\b0b([01_]+)' + INT_SUFFIX
 
-         },
 
-         {
 
-           begin: '\\b0o([0-7_]+)' + INT_SUFFIX
 
-         },
 
-         {
 
-           begin: '\\b0x([A-Fa-f0-9_]+)' + INT_SUFFIX
 
-         },
 
-         {
 
-           begin: '\\b([1-9][0-9_]*[0-9]|[0-9])(\\.[0-9][0-9_]*)?([eE]_?[-+]?[0-9_]*)?' + FLOAT_SUFFIX + '(?!_)'
 
-         },
 
-         {
 
-           begin: '\\b([1-9][0-9_]*|0)' + INT_SUFFIX
 
-         }
 
-       ],
 
-       relevance: 0
 
-     }
 
-   ];
 
-   SUBST.contains = CRYSTAL_DEFAULT_CONTAINS;
 
-   EXPANSION.contains = CRYSTAL_DEFAULT_CONTAINS.slice(1); // without EXPANSION
 
-   return {
 
-     name: 'Crystal',
 
-     aliases: [ 'cr' ],
 
-     keywords: CRYSTAL_KEYWORDS,
 
-     contains: CRYSTAL_DEFAULT_CONTAINS
 
-   };
 
- }
 
- module.exports = crystal;
 
 
  |