Skip to content

Commit

Permalink
Improve parsing of code attributes (#115)
Browse files Browse the repository at this point in the history
Any attribute that had an Elixir expression with a space in it would not
be parsed correctly. This commit should mitigate most instances.

Fixes #32
  • Loading branch information
bfad authored and doomspork committed Dec 22, 2016
1 parent 10aedb8 commit 462c737
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/slime/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ defmodule Slime.Parser do
@script "-"
@smart "="

@attr_delim_regex ~r/[ ]+(?=([^"]*"[^"]*")*[^"]*$)/
@attr_delim_regex ~r/[ ]+(?=([^"]*"[^"]*")*[^"]*$)(?=(?:[^ "']+=|(?:allowfullscreen|async|autofocus|autoplay|checked|compact|controls|declare|default|defaultchecked|defaultmuted|defaultselected|defer|disabled|draggable|enabled|formnovalidate|hidden|indeterminate|inert|ismap|itemscope|loop|multiple|muted|nohref|noresize|noshade|novalidate|nowrap|open|pauseonexit|readonly|required|reversed|scoped|seamless|selected|sortable|spellcheck|translate|truespeed|typemustmatch|visible)(?: |$)))/
@attr_list_delims Application.get_env(:slime, :attr_list_delims, %{"{" => "}", "[" => "]", "(" => ")"})
@attr_group_regex ~r/(?:\s*[\w-]+\s*=\s*(?:[^\s"'][^\s]+[^\s"']|"(?:(?<z>\{(?:[^{}]|\g<z>)*\})|[^"])*"|'[^']*'))*/
@attr_group_regex ~r/(?:\s*[\w-]+\s*=\s*(?:[^"'].*?(?= [^ "']+=|$)|"(?:(?<z>\{(?:[^{}]|\g<z>)*\})|[^"])*"|'[^']*'))*/

@parse_line_split_regexes @attr_list_delims
|> Dict.keys
Expand Down
3 changes: 3 additions & 0 deletions test/parser_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ defmodule ParserTest do

{_, {"meta", opts}} = ~S(meta content=user["name"]) |> Parser.parse_line
assert opts[:attributes] == [content: {:eex, content: ~S(user["name"]), inline: true}]

{_, {"meta", opts}} = ~S[meta content=Module.function(param1, param2)] |> Parser.parse_line
assert opts[:attributes] == [content: {:eex, content: ~S[Module.function(param1, param2)], inline: true}]
end

test "parses attributes and inline children" do
Expand Down
10 changes: 5 additions & 5 deletions test/rendering/attributes_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ defmodule RenderAttributesTest do
end

test "rendering of boolean attributes" do
assert render(~s(div [ab="ab" a] a)) == ~s(<div ab="ab" a>a</div>)
assert render(~s(div [a b="b"] c)) == ~s(<div a b="b">c</div>)
assert render(~s(div [ab="ab" hidden] a)) == ~s(<div ab="ab" hidden>a</div>)
assert render(~s(div [hidden b="b"] c)) == ~s(<div hidden b="b">c</div>)
assert render(~S(div ab="#{b} a" a), b: "b") == ~s(<div ab="b a">a</div>)
assert render(~S(div[ab="a #{b}" a] a), b: "b") == ~s(<div ab="a b" a>a</div>)
assert render(~S<div[ab="a #{b.("c")}" a] a>, b: &(&1)) == ~s(<div ab="a c" a>a</div>)
assert render(~S<div[ab="a #{b.({"c", "d"})}" a] a>, b: fn {_, r} -> r end) == ~s(<div ab="a d" a>a</div>)
assert render(~S(div[ab="a #{b}" hidden] a), b: "b") == ~s(<div ab="a b" hidden>a</div>)
assert render(~S<div[ab="a #{b.("c")}" hidden] a>, b: &(&1)) == ~s(<div ab="a c" hidden>a</div>)
assert render(~S<div[ab="a #{b.({"c", "d"})}" hidden] a>, b: fn {_, r} -> r end) == ~s(<div ab="a d" hidden>a</div>)
assert render(~s(script[defer async src="..."])) == ~s(<script defer async src="..."></script>)
end

Expand Down

0 comments on commit 462c737

Please sign in to comment.