From 7abe6e67f9842bfe32c11efafbf9bc8395f0bbf9 Mon Sep 17 00:00:00 2001 From: P-SiZK <54477535+P-SiZK@users.noreply.github.com> Date: Mon, 5 Jan 2026 04:34:10 +0900 Subject: [PATCH 1/2] Fix Elixir sigil interpolation --- lib/rouge/lexers/elixir.rb | 2 +- spec/visual/samples/elixir | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/rouge/lexers/elixir.rb b/lib/rouge/lexers/elixir.rb index c48b65350b..c79ca86a48 100644 --- a/lib/rouge/lexers/elixir.rb +++ b/lib/rouge/lexers/elixir.rb @@ -107,7 +107,7 @@ def self.detect?(text) rule %r/~([A-Za-z])?(#{sigil_opens})/ do |m| open = Regexp.escape(m[2]) close = Regexp.escape(delimiter_map[m[2]] || m[2]) - interp = /[SRCW]/ === m[1] + interp = /[srcw]/ === m[1] toktype = Str::Other puts " open: #{open.inspect}" if @debug diff --git a/spec/visual/samples/elixir b/spec/visual/samples/elixir index ac3bb253d1..c2c13895ea 100644 --- a/spec/visual/samples/elixir +++ b/spec/visual/samples/elixir @@ -63,13 +63,13 @@ string |> String.split(~r/[ -]/) |> Enum.map(&abbreviate_word/1) |> Enum.join() ~c|| ~c// -~S(inter #{pol <> "ati#{o}"} n) -~S[inter #{pol <> "ati#{o}"} n] -~S "ati#{o}"} n> -~S'inter #{pol <> "ati#{o}"} n' -~S"inter #{pol <> "ati#{o}"} n" -~S|inter #{pol <> "ati#{o}"} n| -~S/inter #{pol <> "ati#{o}"} n/ +~s(inter #{pol <> "ati#{o}"} n) +~s[inter #{pol <> "ati#{o}"} n] +~s "ati#{o}"} n> +~s'inter #{pol <> "ati#{o}"} n' +~s"inter #{pol <> "ati#{o}"} n" +~s|inter #{pol <> "ati#{o}"} n| +~s/inter #{pol <> "ati#{o}"} n/ # first is Operator, second is &1 variable &(&1) From 163bcbac134179576ba7ed821baeb7e3a0ac7593 Mon Sep 17 00:00:00 2001 From: P-SiZK <54477535+P-SiZK@users.noreply.github.com> Date: Mon, 5 Jan 2026 04:34:48 +0900 Subject: [PATCH 2/2] Fix Elixir lexer sigil pattern to match specification --- lib/rouge/lexers/elixir.rb | 12 ++++++------ spec/visual/samples/elixir | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/rouge/lexers/elixir.rb b/lib/rouge/lexers/elixir.rb index c79ca86a48..06722bb2aa 100644 --- a/lib/rouge/lexers/elixir.rb +++ b/lib/rouge/lexers/elixir.rb @@ -99,27 +99,27 @@ def self.detect?(text) state :sigil_strings do # ~-sigiled strings - # ~(abc), ~[abc], ~, ~|abc|, ~r/abc/, etc + # ~r(abc), ~r[abc], ~r, ~r|abc|, ~r/abc/, etc # Cribbed and adjusted from Ruby lexer delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' } - # Match a-z for custom sigils too sigil_opens = Regexp.union(delimiter_map.keys + %w(| / ' ")) - rule %r/~([A-Za-z])?(#{sigil_opens})/ do |m| + # Match [a-z] or [A-Z][A-Z0-9]* for custom sigils too + rule %r/~([a-z]|[A-Z][A-Z0-9]*)(#{sigil_opens})/ do |m| open = Regexp.escape(m[2]) close = Regexp.escape(delimiter_map[m[2]] || m[2]) - interp = /[srcw]/ === m[1] + interp = /^[srcw]$/ === m[1] toktype = Str::Other puts " open: #{open.inspect}" if @debug puts " close: #{close.inspect}" if @debug # regexes - if 'Rr'.include? m[1] + if m[1] == 'r' || m[1] == 'R' toktype = Str::Regex push :regex_flags end - if 'Ww'.include? m[1] + if m[1] == 'w' || m[1] == 'W' push :list_flags end diff --git a/spec/visual/samples/elixir b/spec/visual/samples/elixir index c2c13895ea..9648dfdfd4 100644 --- a/spec/visual/samples/elixir +++ b/spec/visual/samples/elixir @@ -71,6 +71,11 @@ string |> String.split(~r/[ -]/) |> Enum.map(&abbreviate_word/1) |> Enum.join() ~s|inter #{pol <> "ati#{o}"} n| ~s/inter #{pol <> "ati#{o}"} n/ +# custom sigils +~i(13) +~CUSTOM(custom uppercase) +~ABC123(with digits) + # first is Operator, second is &1 variable &(&1)