Skip to content

Commit

Permalink
enh(elixir) improve heredoc and sigil support (#2257)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshgoebel authored Nov 12, 2019
1 parent 980ac21 commit c87f538
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/languages/elixir.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,78 @@ function(hljs) {
lexemes: ELIXIR_IDENT_RE,
keywords: ELIXIR_KEYWORDS
};

var SIGIL_DELIMITERS = '[/|([{<"\']'
var 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: />/ }
]
}]
},
],
};

var 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: /\>/ }
]
};

var STRING = {
className: 'string',
contains: [hljs.BACKSLASH_ESCAPE, SUBST],
variants: [
{
begin: /"""/, end: /"""/,
},
{
begin: /'''/, end: /'''/,
},
{
begin: /~S"""/, end: /"""/,
contains: []
},
{
begin: /~S"/, end: /"/,
contains: []
},
{
begin: /~S'''/, end: /'''/,
contains: []
},
{
begin: /~S'/, end: /'/,
contains: []
},
{
begin: /'/, end: /'/
},
{
begin: /"/, end: /"/
}
},
]
};
var FUNCTION = {
Expand All @@ -47,6 +109,8 @@ function(hljs) {
});
var ELIXIR_DEFAULT_CONTAINS = [
STRING,
UPCASE_SIGIL,
LOWERCASE_SIGIL,
hljs.HASH_COMMENT_MODE,
CLASS,
FUNCTION,
Expand Down
23 changes: 23 additions & 0 deletions test/markup/elixir/sigils.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<span class="hljs-string">~R'this + i\s "a" regex too'</span>
<span class="hljs-string">~w(hello <span class="hljs-subst">#{ [<span class="hljs-string">"has"</span> &lt;&gt; <span class="hljs-string">"123"</span>, <span class="hljs-string">'\c\d'</span>, <span class="hljs-string">"\123 interpol"</span> | []] }</span> world)</span>s
<span class="hljs-string">~W(hello #{no "123" \c\d \123 interpol} world)</span>s
<span class="hljs-string">~s{Escapes terminators \{ and \}, but no {balancing}</span> <span class="hljs-comment"># outside of sigil here }</span>
<span class="hljs-string">~S"No escapes \s\t\n and no #{interpolation}"</span>

<span class="hljs-string">~S/hello/</span>
<span class="hljs-string">~S|hello|</span>
<span class="hljs-string">~S"hello"</span>
<span class="hljs-string">~S'hello'</span>
<span class="hljs-string">~S(hello)</span>
<span class="hljs-string">~S[hello]</span>
<span class="hljs-string">~S{hello}</span>
<span class="hljs-string">~S&lt;hello&gt;</span>

<span class="hljs-string">~s/hello <span class="hljs-subst">#{name}</span>/</span>
<span class="hljs-string">~s|hello <span class="hljs-subst">#{name}</span>|</span>
<span class="hljs-string">~s"hello <span class="hljs-subst">#{name}</span>"</span>
<span class="hljs-string">~s'hello <span class="hljs-subst">#{name}</span>'</span>
<span class="hljs-string">~s(hello <span class="hljs-subst">#{name}</span>)</span>
<span class="hljs-string">~s[hello <span class="hljs-subst">#{name}</span>]</span>
<span class="hljs-string">~s{hello <span class="hljs-subst">#{name}</span>}</span>
<span class="hljs-string">~s&lt;hello <span class="hljs-subst">#{name}</span>&gt;</span>
23 changes: 23 additions & 0 deletions test/markup/elixir/sigils.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
~R'this + i\s "a" regex too'
~w(hello #{ ["has" <> "123", '\c\d', "\123 interpol" | []] } world)s
~W(hello #{no "123" \c\d \123 interpol} world)s
~s{Escapes terminators \{ and \}, but no {balancing} # outside of sigil here }
~S"No escapes \s\t\n and no #{interpolation}"

~S/hello/
~S|hello|
~S"hello"
~S'hello'
~S(hello)
~S[hello]
~S{hello}
~S<hello>

~s/hello #{name}/
~s|hello #{name}|
~s"hello #{name}"
~s'hello #{name}'
~s(hello #{name})
~s[hello #{name}]
~s{hello #{name}}
~s<hello #{name}>
4 changes: 4 additions & 0 deletions test/markup/elixir/strings.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a = <span class="hljs-string">"""test"""</span>
b = <span class="hljs-string">'''test'''</span>
c = <span class="hljs-string">"test"</span>
d = <span class="hljs-string">'test'</span>
4 changes: 4 additions & 0 deletions test/markup/elixir/strings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a = """test"""
b = '''test'''
c = "test"
d = 'test'
17 changes: 17 additions & 0 deletions test/markup/elixir/uppercase-string-sigil.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<span class="hljs-class"><span class="hljs-keyword">defmodule</span> <span class="hljs-title">Long.Module.Name</span></span> <span class="hljs-keyword">do</span>
<span class="hljs-variable">@doc</span> <span class="hljs-string">~S'''
No #{interpolation} of any kind.
\000 \x{ff}

\n #{\x{ff}}
'''</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span></span>(a, b \\ []), <span class="hljs-symbol">do:</span> <span class="hljs-symbol">:ok</span>

<span class="hljs-variable">@doc</span> <span class="hljs-string">~S"""
No #{interpolation} of any kind.
\000 \x{ff}

\n #{\x{ff}}
"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span></span>(a, b \\ []), <span class="hljs-symbol">do:</span> <span class="hljs-symbol">:ok</span>
<span class="hljs-keyword">end</span>
17 changes: 17 additions & 0 deletions test/markup/elixir/uppercase-string-sigil.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Long.Module.Name do
@doc ~S'''
No #{interpolation} of any kind.
\000 \x{ff}

\n #{\x{ff}}
'''
def func(a, b \\ []), do: :ok

@doc ~S"""
No #{interpolation} of any kind.
\000 \x{ff}

\n #{\x{ff}}
"""
def func(a, b \\ []), do: :ok
end

0 comments on commit c87f538

Please sign in to comment.