syntax_tree-haml 1.0.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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