Skip to content

Commit edb450f

Browse files
authored
Merge pull request #22 from ruby-syntax-tree/unescape
Add support for unescape plain and script
2 parents 23ec9a8 + c1c45ff commit edb450f

File tree

5 files changed

+53
-23
lines changed

5 files changed

+53
-23
lines changed

lib/syntax_tree/haml.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ def self.parse(source)
3434
# This is the main entrypoint for the formatter. It parses the source,
3535
# builds a formatter, then pretty prints the result.
3636
def self.format(source, maxwidth = 80)
37-
PrettierPrint.format(+"", maxwidth) { |q| parse(source).format(q) }
37+
formatter = Format::Formatter.new(source, +"", maxwidth)
38+
parse(source).format(formatter)
39+
40+
formatter.flush
41+
formatter.output
3842
end
3943

4044
# This is a required API for syntax tree which just delegates to File.read.

lib/syntax_tree/haml/format.rb

+37-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@
33
module SyntaxTree
44
module Haml
55
class Format < Visitor
6+
class Formatter < ::SyntaxTree::Formatter
7+
attr_reader :literal_lines, :quote
8+
9+
def initialize(source, ...)
10+
@literal_lines = {}
11+
source
12+
.lines
13+
.each
14+
.with_index(1) do |line, index|
15+
@literal_lines[index] = line.rstrip if line.start_with?("!")
16+
end
17+
18+
super(source, ...)
19+
end
20+
end
21+
622
attr_reader :q
723

824
def initialize(q)
@@ -62,12 +78,11 @@ def visit_haml_comment(node)
6278
text = node.value[:text].strip
6379

6480
if text.include?("\n")
81+
separator = -> { q.breakable(force: true) }
82+
6583
q.indent do
66-
q.breakable(force: true)
67-
q.seplist(
68-
text.split("\n"),
69-
-> { q.breakable(force: true) }
70-
) { |segment| q.text(segment) }
84+
separator.call
85+
q.seplist(text.split("\n"), separator) { |segment| q.text(segment) }
7186
end
7287
else
7388
q.text(" #{text}")
@@ -76,9 +91,13 @@ def visit_haml_comment(node)
7691

7792
# https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
7893
def visit_plain(node)
79-
text = node.value[:text]
80-
q.text("\\") if escaped?(text)
81-
q.text(text)
94+
if line = q.literal_lines[node.line]
95+
q.text(line)
96+
else
97+
text = node.value[:text]
98+
q.text("\\") if escaped?(text)
99+
q.text(text)
100+
end
82101
end
83102

84103
# Visit the root node of the AST.
@@ -92,12 +111,14 @@ def visit_root(node)
92111
# https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
93112
def visit_script(node)
94113
with_children(node) do
95-
q.text("&") if node.value[:escape_html]
96-
97-
node.value[:preserve] ? q.text("~") : q.text("=")
98-
99-
q.text(" ")
100-
q.text(node.value[:text].strip)
114+
if line = q.literal_lines[node.line]
115+
q.text(line)
116+
else
117+
q.text("&") if node.value[:escape_html]
118+
q.text(node.value[:preserve] ? "~" : "=")
119+
q.text(" ")
120+
q.text(node.value[:text].strip)
121+
end
101122
end
102123
end
103124

@@ -222,7 +243,7 @@ def length
222243
private
223244

224245
def format_value(q, hash, level = 0)
225-
quote = SyntaxTree::Formatter::OPTIONS[:quote]
246+
quote = q.quote
226247

227248
q.group do
228249
q.text("{")
@@ -244,8 +265,7 @@ def format_value(q, hash, level = 0)
244265
when LiteralHashValue
245266
q.text(value.value)
246267
when StringLiteral
247-
qq = Formatter.new("")
248-
qq.with_target(q.target) { value.format(qq) }
268+
value.format(q)
249269
when String
250270
q.text("#{quote}#{Quotes.normalize(value, quote)}#{quote}")
251271
else

test/plain_test.rb

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ def test_escapes_percent
1414
def test_escapes_period
1515
assert_format("\\.")
1616
end
17+
18+
def test_unescapes
19+
assert_format("! hello")
20+
end
1721
end

test/script_test.rb

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ def test_escape_html
1818
def test_preserve_escape_html
1919
assert_format("&~ foo")
2020
end
21+
22+
def test_unescape
23+
assert_format("!= hello")
24+
end
2125
end

test/tag_test.rb

+3-5
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,9 @@ def test_quotes_in_strings
137137
end
138138

139139
def test_interpolation_in_strings
140-
with_single_quotes do
141-
assert_format(<<~HAML)
142-
%div{style: "background: center/cover url(\#{url_for(page.resource.file)})"}
143-
HAML
144-
end
140+
with_single_quotes { assert_format(<<~HAML) }
141+
%div{style: "background: center/cover url(\#{url_for(page.resource.file)})"}
142+
HAML
145143
end
146144

147145
def test_interpolation_in_value

0 commit comments

Comments
 (0)