260 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| Language: Elixir
 | |
| Author: Josh Adams <josh@isotope11.com>
 | |
| Description: language definition for Elixir source code files (.ex and .exs).  Based on ruby language support.
 | |
| Category: functional
 | |
| Website: https://elixir-lang.org
 | |
| */
 | |
| 
 | |
| /** @type LanguageFn */
 | |
| function elixir(hljs) {
 | |
|   const ELIXIR_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_.]*(!|\\?)?';
 | |
|   const ELIXIR_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
 | |
|   const ELIXIR_KEYWORDS = {
 | |
|     $pattern: ELIXIR_IDENT_RE,
 | |
|     keyword: 'and false then defined module in return redo retry end for true self when ' +
 | |
|     'next until do begin unless nil break not case cond alias while ensure or ' +
 | |
|     'include use alias fn quote require import with|0'
 | |
|   };
 | |
|   const SUBST = {
 | |
|     className: 'subst',
 | |
|     begin: /#\{/,
 | |
|     end: /\}/,
 | |
|     keywords: ELIXIR_KEYWORDS
 | |
|   };
 | |
|   const NUMBER = {
 | |
|     className: 'number',
 | |
|     begin: '(\\b0o[0-7_]+)|(\\b0b[01_]+)|(\\b0x[0-9a-fA-F_]+)|(-?\\b[1-9][0-9_]*(\\.[0-9_]+([eE][-+]?[0-9]+)?)?)',
 | |
|     relevance: 0
 | |
|   };
 | |
|   const SIGIL_DELIMITERS = '[/|([{<"\']';
 | |
|   const LOWERCASE_SIGIL = {
 | |
|     className: 'string',
 | |
|     begin: '~[a-z]' + '(?=' + SIGIL_DELIMITERS + ')',
 | |
|     contains: [
 | |
|       {
 | |
|         endsParent: true,
 | |
|         contains: [
 | |
|           {
 | |
|             contains: [
 | |
|               hljs.BACKSLASH_ESCAPE,
 | |
|               SUBST
 | |
|             ],
 | |
|             variants: [
 | |
|               {
 | |
|                 begin: /"/,
 | |
|                 end: /"/
 | |
|               },
 | |
|               {
 | |
|                 begin: /'/,
 | |
|                 end: /'/
 | |
|               },
 | |
|               {
 | |
|                 begin: /\//,
 | |
|                 end: /\//
 | |
|               },
 | |
|               {
 | |
|                 begin: /\|/,
 | |
|                 end: /\|/
 | |
|               },
 | |
|               {
 | |
|                 begin: /\(/,
 | |
|                 end: /\)/
 | |
|               },
 | |
|               {
 | |
|                 begin: /\[/,
 | |
|                 end: /\]/
 | |
|               },
 | |
|               {
 | |
|                 begin: /\{/,
 | |
|                 end: /\}/
 | |
|               },
 | |
|               {
 | |
|                 begin: /</,
 | |
|                 end: />/
 | |
|               }
 | |
|             ]
 | |
|           }
 | |
|         ]
 | |
|       }
 | |
|     ]
 | |
|   };
 | |
| 
 | |
|   const UPCASE_SIGIL = {
 | |
|     className: 'string',
 | |
|     begin: '~[A-Z]' + '(?=' + SIGIL_DELIMITERS + ')',
 | |
|     contains: [
 | |
|       {
 | |
|         begin: /"/,
 | |
|         end: /"/
 | |
|       },
 | |
|       {
 | |
|         begin: /'/,
 | |
|         end: /'/
 | |
|       },
 | |
|       {
 | |
|         begin: /\//,
 | |
|         end: /\//
 | |
|       },
 | |
|       {
 | |
|         begin: /\|/,
 | |
|         end: /\|/
 | |
|       },
 | |
|       {
 | |
|         begin: /\(/,
 | |
|         end: /\)/
 | |
|       },
 | |
|       {
 | |
|         begin: /\[/,
 | |
|         end: /\]/
 | |
|       },
 | |
|       {
 | |
|         begin: /\{/,
 | |
|         end: /\}/
 | |
|       },
 | |
|       {
 | |
|         begin: /</,
 | |
|         end: />/
 | |
|       }
 | |
|     ]
 | |
|   };
 | |
| 
 | |
|   const STRING = {
 | |
|     className: 'string',
 | |
|     contains: [
 | |
|       hljs.BACKSLASH_ESCAPE,
 | |
|       SUBST
 | |
|     ],
 | |
|     variants: [
 | |
|       {
 | |
|         begin: /"""/,
 | |
|         end: /"""/
 | |
|       },
 | |
|       {
 | |
|         begin: /'''/,
 | |
|         end: /'''/
 | |
|       },
 | |
|       {
 | |
|         begin: /~S"""/,
 | |
|         end: /"""/,
 | |
|         contains: [] // override default
 | |
|       },
 | |
|       {
 | |
|         begin: /~S"/,
 | |
|         end: /"/,
 | |
|         contains: [] // override default
 | |
|       },
 | |
|       {
 | |
|         begin: /~S'''/,
 | |
|         end: /'''/,
 | |
|         contains: [] // override default
 | |
|       },
 | |
|       {
 | |
|         begin: /~S'/,
 | |
|         end: /'/,
 | |
|         contains: [] // override default
 | |
|       },
 | |
|       {
 | |
|         begin: /'/,
 | |
|         end: /'/
 | |
|       },
 | |
|       {
 | |
|         begin: /"/,
 | |
|         end: /"/
 | |
|       }
 | |
|     ]
 | |
|   };
 | |
|   const FUNCTION = {
 | |
|     className: 'function',
 | |
|     beginKeywords: 'def defp defmacro',
 | |
|     end: /\B\b/, // the mode is ended by the title
 | |
|     contains: [
 | |
|       hljs.inherit(hljs.TITLE_MODE, {
 | |
|         begin: ELIXIR_IDENT_RE,
 | |
|         endsParent: true
 | |
|       })
 | |
|     ]
 | |
|   };
 | |
|   const CLASS = hljs.inherit(FUNCTION, {
 | |
|     className: 'class',
 | |
|     beginKeywords: 'defimpl defmodule defprotocol defrecord',
 | |
|     end: /\bdo\b|$|;/
 | |
|   });
 | |
|   const ELIXIR_DEFAULT_CONTAINS = [
 | |
|     STRING,
 | |
|     UPCASE_SIGIL,
 | |
|     LOWERCASE_SIGIL,
 | |
|     hljs.HASH_COMMENT_MODE,
 | |
|     CLASS,
 | |
|     FUNCTION,
 | |
|     {
 | |
|       begin: '::'
 | |
|     },
 | |
|     {
 | |
|       className: 'symbol',
 | |
|       begin: ':(?![\\s:])',
 | |
|       contains: [
 | |
|         STRING,
 | |
|         {
 | |
|           begin: ELIXIR_METHOD_RE
 | |
|         }
 | |
|       ],
 | |
|       relevance: 0
 | |
|     },
 | |
|     {
 | |
|       className: 'symbol',
 | |
|       begin: ELIXIR_IDENT_RE + ':(?!:)',
 | |
|       relevance: 0
 | |
|     },
 | |
|     NUMBER,
 | |
|     {
 | |
|       className: 'variable',
 | |
|       begin: '(\\$\\W)|((\\$|@@?)(\\w+))'
 | |
|     },
 | |
|     {
 | |
|       begin: '->'
 | |
|     },
 | |
|     { // regexp container
 | |
|       begin: '(' + hljs.RE_STARTERS_RE + ')\\s*',
 | |
|       contains: [
 | |
|         hljs.HASH_COMMENT_MODE,
 | |
|         {
 | |
|           // to prevent false regex triggers for the division function:
 | |
|           // /:
 | |
|           begin: /\/: (?=\d+\s*[,\]])/,
 | |
|           relevance: 0,
 | |
|           contains: [NUMBER]
 | |
|         },
 | |
|         {
 | |
|           className: 'regexp',
 | |
|           illegal: '\\n',
 | |
|           contains: [
 | |
|             hljs.BACKSLASH_ESCAPE,
 | |
|             SUBST
 | |
|           ],
 | |
|           variants: [
 | |
|             {
 | |
|               begin: '/',
 | |
|               end: '/[a-z]*'
 | |
|             },
 | |
|             {
 | |
|               begin: '%r\\[',
 | |
|               end: '\\][a-z]*'
 | |
|             }
 | |
|           ]
 | |
|         }
 | |
|       ],
 | |
|       relevance: 0
 | |
|     }
 | |
|   ];
 | |
|   SUBST.contains = ELIXIR_DEFAULT_CONTAINS;
 | |
| 
 | |
|   return {
 | |
|     name: 'Elixir',
 | |
|     keywords: ELIXIR_KEYWORDS,
 | |
|     contains: ELIXIR_DEFAULT_CONTAINS
 | |
|   };
 | |
| }
 | |
| 
 | |
| module.exports = elixir;
 |