syntax_tree-haml 1.0.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module Haml
5
+ class PrettyPrint < Visitor
6
+ attr_reader :q
7
+
8
+ def initialize(q)
9
+ @q = q
10
+ end
11
+
12
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#html-comments-
13
+ def visit_comment(node)
14
+ group("comment") do
15
+ if node.value[:conditional]
16
+ pp_field("conditional", node.value[:conditional])
17
+ elsif node.value[:text]
18
+ pp_field("text", node.value[:text])
19
+ end
20
+
21
+ bool_field("revealed") if node.value[:revealed]
22
+ pp_field("children", node.children) if node.children.any?
23
+ end
24
+ end
25
+
26
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#doctype-
27
+ def visit_doctype(node)
28
+ group("doctype") do
29
+ if DOCTYPE_TYPES.key?(node.value[:type])
30
+ pp_field("type", node.value[:type])
31
+ elsif DOCTYPE_VERSIONS.include?(node.value[:version])
32
+ pp_field("version", node.value[:version])
33
+ else
34
+ pp_field("text", node.value[:text])
35
+ end
36
+
37
+ pp_field("encoding", node.value[:encoding]) if node.value[:encoding]
38
+ end
39
+ end
40
+
41
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#filter
42
+ def visit_filter(node)
43
+ group("filter") do
44
+ text_field("name", node.value[:name])
45
+ pp_field("text", node.value[:text])
46
+ end
47
+ end
48
+
49
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#haml-comments--
50
+ def visit_haml_comment(node)
51
+ group("haml_comment") { pp_field("text", node.value[:text]) }
52
+ end
53
+
54
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
55
+ def visit_plain(node)
56
+ group("plain") { pp_field("text", node.value[:text]) }
57
+ end
58
+
59
+ # Visit the root node of the AST.
60
+ def visit_root(node)
61
+ group("root") do
62
+ pp_field("children", node.children) if node.children.any?
63
+ end
64
+ end
65
+
66
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
67
+ def visit_script(node)
68
+ group("script") do
69
+ pp_field("text", node.value[:text])
70
+ bool_field("escape_html") if node.value[:escape_html]
71
+ bool_field("preserve") if node.value[:preserve]
72
+ pp_field("children", node.children) if node.children.any?
73
+ end
74
+ end
75
+
76
+ # https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
77
+ def visit_silent_script(node)
78
+ group("silent-script") do
79
+ pp_field("text", node.value[:text])
80
+ pp_field("children", node.children) if node.children.any?
81
+ end
82
+ end
83
+
84
+ # Visit a tag node.
85
+ def visit_tag(node)
86
+ group("tag") do
87
+ pp_field("name", node.value[:name])
88
+
89
+ if node.value[:attributes].any?
90
+ pp_field("attributes", node.value[:attributes])
91
+ end
92
+
93
+ if node.value[:dynamic_attributes].new
94
+ pp_field(
95
+ "dynamic_attributes.new",
96
+ node.value[:dynamic_attributes].new
97
+ )
98
+ end
99
+
100
+ if node.value[:dynamic_attributes].old
101
+ pp_field(
102
+ "dynamic_attributes.old",
103
+ node.value[:dynamic_attributes].old
104
+ )
105
+ end
106
+
107
+ if node.value[:object_ref] != :nil
108
+ pp_field("object_ref", node.value[:object_ref])
109
+ end
110
+
111
+ if node.value[:nuke_outer_whitespace]
112
+ bool_field("nuke_outer_whitespace")
113
+ end
114
+
115
+ if node.value[:nuke_inner_whitespace]
116
+ bool_field("nuke_inner_whitespace")
117
+ end
118
+
119
+ bool_field("self_closing") if node.value[:self_closing]
120
+ pp_field("value", node.value[:value]) if node.value[:value]
121
+ pp_field("children", node.children) if node.children.any?
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def bool_field(name)
128
+ q.breakable
129
+ q.text(name)
130
+ end
131
+
132
+ def group(name)
133
+ q.group do
134
+ q.text("(")
135
+ q.text(name)
136
+
137
+ q.nest(2) { yield }
138
+ q.breakable("")
139
+ q.text(")")
140
+ end
141
+ end
142
+
143
+ def pp_field(name, value)
144
+ q.breakable
145
+ q.text(name)
146
+ q.text("=")
147
+ q.pp(value)
148
+ end
149
+
150
+ def text_field(name, value)
151
+ q.breakable
152
+ q.text(name)
153
+ q.text("=")
154
+ q.text(value)
155
+ end
156
+ end
157
+ end
158
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module SyntaxTree
4
4
  module Haml
5
- VERSION = "1.0.1"
5
+ VERSION = "1.2.1"
6
6
  end
7
7
  end
@@ -1,81 +1,86 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "haml"
4
+ require "prettier_print"
4
5
  require "syntax_tree"
5
6
 
6
- require "syntax_tree/haml/comment"
7
- require "syntax_tree/haml/doctype"
8
- require "syntax_tree/haml/filter"
9
- require "syntax_tree/haml/haml_comment"
10
- require "syntax_tree/haml/plain"
11
- require "syntax_tree/haml/root"
12
- require "syntax_tree/haml/script"
13
- require "syntax_tree/haml/silent_script"
14
- require "syntax_tree/haml/tag"
15
-
16
- class Haml::Parser::ParseNode
17
- def format(q)
18
- syntax_tree.format(q)
19
- end
20
-
21
- def pretty_print(q)
22
- syntax_tree.pretty_print(q)
23
- end
7
+ module SyntaxTree
8
+ module Haml
9
+ DOCTYPE_TYPES = {
10
+ "basic" => "Basic",
11
+ "frameset" => "Frameset",
12
+ "mobile" => "Mobile",
13
+ "rdfa" => "RDFa",
14
+ "strict" => "Strict",
15
+ "xml" => "XML"
16
+ }
24
17
 
25
- private
18
+ DOCTYPE_VERSIONS = %w[1.1 5]
26
19
 
27
- def syntax_tree
28
- case type
29
- when :comment then SyntaxTree::Haml::Comment.new(self)
30
- when :doctype then SyntaxTree::Haml::Doctype.new(self)
31
- when :filter then SyntaxTree::Haml::Filter.new(self)
32
- when :haml_comment then SyntaxTree::Haml::HamlComment.new(self)
33
- when :plain then SyntaxTree::Haml::Plain.new(self)
34
- when :root then SyntaxTree::Haml::Root.new(self)
35
- when :script then SyntaxTree::Haml::Script.new(self)
36
- when :silent_script then SyntaxTree::Haml::SilentScript.new(self)
37
- when :tag then SyntaxTree::Haml::Tag.new(self)
38
- else
39
- raise ArgumentError, "Unsupported type: #{type}"
20
+ # This is the parent class of the various visitors that we provide to access
21
+ # the HAML syntax tree.
22
+ class Visitor
23
+ def visit(node)
24
+ node&.accept(self)
25
+ end
40
26
  end
41
- end
42
- end
43
27
 
44
- module SyntaxTree
45
- module Haml
28
+ # This is the main parser entrypoint, and just delegates to the Haml gem's
29
+ # parser to do the heavy lifting.
46
30
  def self.parse(source)
47
31
  ::Haml::Parser.new({}).call(source)
48
32
  end
49
33
 
50
- def self.format(source)
51
- formatter = PP.new([])
52
- parse(source).format(formatter)
53
-
54
- formatter.flush
55
- formatter.output.join
34
+ # This is the main entrypoint for the formatter. It parses the source,
35
+ # builds a formatter, then pretty prints the result.
36
+ def self.format(source, maxwidth = 80)
37
+ PrettierPrint.format(+"", maxwidth) { |q| parse(source).format(q) }
56
38
  end
57
39
 
40
+ # This is a required API for syntax tree which just delegates to File.read.
58
41
  def self.read(filepath)
59
42
  File.read(filepath)
60
43
  end
61
-
62
- def self.with_children(node, q)
63
- if node.children.empty?
64
- q.group { yield }
65
- else
66
- q.group do
67
- q.group { yield }
68
- q.indent do
69
- node.children.each do |child|
70
- q.breakable(force: true)
71
- child.format(q)
72
- end
73
- end
74
- end
75
- end
76
- end
77
44
  end
78
45
 
79
46
  # Register our module as a handler for the .haml file type.
80
47
  register_handler(".haml", Haml)
81
48
  end
49
+
50
+ require "syntax_tree/haml/format"
51
+ require "syntax_tree/haml/pretty_print"
52
+
53
+ class Haml::Parser::ParseNode
54
+ # Here we're going to hook into the parse node and define a method that will
55
+ # accept a visitor in order to walk through the tree.
56
+ def accept(visitor)
57
+ case type
58
+ in :comment
59
+ visitor.visit_comment(self)
60
+ in :doctype
61
+ visitor.visit_doctype(self)
62
+ in :filter
63
+ visitor.visit_filter(self)
64
+ in :haml_comment
65
+ visitor.visit_haml_comment(self)
66
+ in :plain
67
+ visitor.visit_plain(self)
68
+ in :root
69
+ visitor.visit_root(self)
70
+ in :script
71
+ visitor.visit_script(self)
72
+ in :silent_script
73
+ visitor.visit_silent_script(self)
74
+ in :tag
75
+ visitor.visit_tag(self)
76
+ end
77
+ end
78
+
79
+ def format(q)
80
+ accept(SyntaxTree::Haml::Format.new(q))
81
+ end
82
+
83
+ def pretty_print(q)
84
+ accept(SyntaxTree::Haml::PrettyPrint.new(q))
85
+ end
86
+ end
@@ -4,27 +4,28 @@ require "ripper"
4
4
  require_relative "lib/syntax_tree/haml/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "syntax_tree-haml"
8
- spec.version = SyntaxTree::Haml::VERSION
9
- spec.authors = ["Kevin Newton"]
10
- spec.email = ["kddnewton@gmail.com"]
7
+ spec.name = "syntax_tree-haml"
8
+ spec.version = SyntaxTree::Haml::VERSION
9
+ spec.authors = ["Kevin Newton"]
10
+ spec.email = ["kddnewton@gmail.com"]
11
11
 
12
- spec.summary = "Syntax Tree support for Haml"
13
- spec.homepage = "https://github.com/ruby-syntax-tree/syntax_tree-haml"
14
- spec.license = "MIT"
15
- spec.metadata = { "rubygems_mfa_required" => "true" }
12
+ spec.summary = "Syntax Tree support for Haml"
13
+ spec.homepage = "https://github.com/ruby-syntax-tree/syntax_tree-haml"
14
+ spec.license = "MIT"
15
+ spec.metadata = { "rubygems_mfa_required" => "true" }
16
16
 
17
- spec.files = Dir.chdir(__dir__) do
18
- `git ls-files -z`.split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
17
+ spec.files =
18
+ Dir.chdir(__dir__) do
19
+ `git ls-files -z`.split("\x0")
20
+ .reject { |f| f.match(%r{^(test|spec|features)/}) }
20
21
  end
21
- end
22
22
 
23
- spec.bindir = "exe"
24
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = %w[lib]
26
26
 
27
27
  spec.add_dependency "haml", ">= 5.2"
28
+ spec.add_dependency "prettier_print"
28
29
  spec.add_dependency "syntax_tree", ">= 2.0.1"
29
30
 
30
31
  spec.add_development_dependency "bundler"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syntax_tree-haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Newton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-31 00:00:00.000000000 Z
11
+ date: 2022-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: prettier_print
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: syntax_tree
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,15 +128,8 @@ files:
114
128
  - bin/format
115
129
  - bin/parse
116
130
  - lib/syntax_tree/haml.rb
117
- - lib/syntax_tree/haml/comment.rb
118
- - lib/syntax_tree/haml/doctype.rb
119
- - lib/syntax_tree/haml/filter.rb
120
- - lib/syntax_tree/haml/haml_comment.rb
121
- - lib/syntax_tree/haml/plain.rb
122
- - lib/syntax_tree/haml/root.rb
123
- - lib/syntax_tree/haml/script.rb
124
- - lib/syntax_tree/haml/silent_script.rb
125
- - lib/syntax_tree/haml/tag.rb
131
+ - lib/syntax_tree/haml/format.rb
132
+ - lib/syntax_tree/haml/pretty_print.rb
126
133
  - lib/syntax_tree/haml/version.rb
127
134
  - syntax_tree-haml.gemspec
128
135
  homepage: https://github.com/ruby-syntax-tree/syntax_tree-haml
@@ -145,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
152
  - !ruby/object:Gem::Version
146
153
  version: '0'
147
154
  requirements: []
148
- rubygems_version: 3.4.0.dev
155
+ rubygems_version: 3.3.3
149
156
  signing_key:
150
157
  specification_version: 4
151
158
  summary: Syntax Tree support for Haml
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#html-comments-
6
- class Comment
7
- attr_reader :node
8
-
9
- def initialize(node)
10
- @node = node
11
- end
12
-
13
- def format(q)
14
- Haml.with_children(node, q) do
15
- q.text("/")
16
- q.text("!") if node.value[:revealed]
17
-
18
- if node.value[:conditional]
19
- q.text(node.value[:conditional])
20
- elsif node.value[:text]
21
- q.text(" #{node.value[:text]}")
22
- end
23
- end
24
- end
25
-
26
- def pretty_print(q)
27
- q.group(2, "(comment", ")") do
28
- q.breakable
29
-
30
- if node.value[:conditional]
31
- q.text("conditional=")
32
- q.pp(node.value[:conditional])
33
- elsif node.value[:text]
34
- q.text("text=")
35
- q.pp(node.value[:text])
36
- end
37
-
38
- if node.value[:revealed]
39
- q.breakable
40
- q.text("revealed")
41
- end
42
-
43
- if node.children.any?
44
- q.breakable
45
- q.text("children=")
46
- q.pp(node.children)
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#doctype-
6
- class Doctype
7
- TYPES = {
8
- "basic" => "Basic",
9
- "frameset" => "Frameset",
10
- "mobile" => "Mobile",
11
- "rdfa" => "RDFa",
12
- "strict" => "Strict",
13
- "xml" => "XML"
14
- }
15
-
16
- VERSIONS = ["1.1", "5"]
17
-
18
- attr_reader :node
19
-
20
- def initialize(node)
21
- @node = node
22
- end
23
-
24
- def format(q)
25
- parts = ["!!!"]
26
-
27
- parts <<
28
- if TYPES.key?(node.value[:type])
29
- TYPES[node.value[:type]]
30
- elsif VERSIONS.include?(node.value[:version])
31
- node.value[:version]
32
- else
33
- node.value[:type]
34
- end
35
-
36
- parts << node.value[:encoding] if node.value[:encoding]
37
- q.text(parts.join(" "))
38
- end
39
-
40
- def pretty_print(q)
41
- q.group(2, "(doctype", ")") do
42
- q.breakable
43
-
44
- if TYPES.key?(node.value[:type])
45
- q.text("type=")
46
- q.pp(node.value[:type])
47
- elsif VERSIONS.include?(node.value[:version])
48
- q.text("version=")
49
- q.pp(node.value[:version])
50
- else
51
- q.text("type=")
52
- q.pp(node.value[:type])
53
- end
54
-
55
- if node.value[:encoding]
56
- q.breakable
57
- q.text("encoding=")
58
- q.pp(node.value[:encoding])
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#filters
6
- class Filter
7
- attr_reader :node
8
-
9
- def initialize(node)
10
- @node = node
11
- end
12
-
13
- def format(q)
14
- q.group do
15
- q.text(":")
16
- q.text(node.value[:name])
17
-
18
- q.indent do
19
- q.breakable(force: true)
20
-
21
- segments = node.value[:text].strip.split("\n")
22
- q.seplist(segments, -> { q.breakable(force: true) }) do |segment|
23
- q.text(segment)
24
- end
25
- end
26
- end
27
- end
28
-
29
- def pretty_print(q)
30
- q.group(2, "(filter", ")") do
31
- q.breakable
32
- q.text("name=")
33
- q.text(node.value[:name])
34
-
35
- q.breakable
36
- q.text("text=")
37
- q.pp(node.value[:text])
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#haml-comments--
6
- class HamlComment
7
- attr_reader :node
8
-
9
- def initialize(node)
10
- @node = node
11
- end
12
-
13
- def format(q)
14
- q.text("-#")
15
- text = node.value[:text].strip
16
-
17
- if text.include?("\n")
18
- q.indent do
19
- q.breakable(force: true)
20
- q.seplist(text.split("\n"), -> { q.breakable(force: true) }) do |segment|
21
- q.text(segment)
22
- end
23
- end
24
- else
25
- q.text(" #{text}")
26
- end
27
- end
28
-
29
- def pretty_print(q)
30
- q.group(2, "(haml_comment", ")") do
31
- q.breakable
32
- q.text("text=")
33
- q.pp(node.value[:text])
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
6
- class Plain
7
- attr_reader :node
8
-
9
- def initialize(node)
10
- @node = node
11
- end
12
-
13
- def format(q)
14
- text = node.value[:text]
15
-
16
- q.text("\\") if escaped?(text)
17
- q.text(text)
18
- end
19
-
20
- def pretty_print(q)
21
- q.group(2, "(plain", ")") do
22
- q.breakable
23
- q.text("text=")
24
- q.pp(node.value[:text])
25
- end
26
- end
27
-
28
- private
29
-
30
- # If a node comes in as the plain type but starts with one of the special
31
- # characters that haml parses, then we need to escape it with a \ when
32
- # printing.
33
- def escaped?(text)
34
- ::Haml::Parser::SPECIAL_CHARACTERS.any? do |special|
35
- text.start_with?(special)
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- class Root
6
- attr_reader :node
7
-
8
- def initialize(node)
9
- @node = node
10
- end
11
-
12
- def format(q)
13
- node.children.each do |child|
14
- child.format(q)
15
- q.breakable(force: true)
16
- end
17
- end
18
-
19
- def pretty_print(q)
20
- q.group(2, "(root", ")") do
21
- if node.children.any?
22
- q.breakable
23
- q.text("children=")
24
- q.pp(node.children)
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end