syntax_tree-haml 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,75 +4,83 @@ require "haml"
4
4
  require "prettier_print"
5
5
  require "syntax_tree"
6
6
 
7
- require "syntax_tree/haml/comment"
8
- require "syntax_tree/haml/doctype"
9
- require "syntax_tree/haml/filter"
10
- require "syntax_tree/haml/haml_comment"
11
- require "syntax_tree/haml/plain"
12
- require "syntax_tree/haml/root"
13
- require "syntax_tree/haml/script"
14
- require "syntax_tree/haml/silent_script"
15
- require "syntax_tree/haml/tag"
16
-
17
- class Haml::Parser::ParseNode
18
- def format(q)
19
- syntax_tree.format(q)
20
- end
21
-
22
- def pretty_print(q)
23
- syntax_tree.pretty_print(q)
24
- 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
+ }
25
17
 
26
- private
18
+ DOCTYPE_VERSIONS = %w[1.1 5]
27
19
 
28
- def syntax_tree
29
- case type
30
- when :comment then SyntaxTree::Haml::Comment.new(self)
31
- when :doctype then SyntaxTree::Haml::Doctype.new(self)
32
- when :filter then SyntaxTree::Haml::Filter.new(self)
33
- when :haml_comment then SyntaxTree::Haml::HamlComment.new(self)
34
- when :plain then SyntaxTree::Haml::Plain.new(self)
35
- when :root then SyntaxTree::Haml::Root.new(self)
36
- when :script then SyntaxTree::Haml::Script.new(self)
37
- when :silent_script then SyntaxTree::Haml::SilentScript.new(self)
38
- when :tag then SyntaxTree::Haml::Tag.new(self)
39
- else
40
- 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
41
26
  end
42
- end
43
- end
44
27
 
45
- module SyntaxTree
46
- module Haml
28
+ # This is the main parser entrypoint, and just delegates to the Haml gem's
29
+ # parser to do the heavy lifting.
47
30
  def self.parse(source)
48
31
  ::Haml::Parser.new({}).call(source)
49
32
  end
50
33
 
34
+ # This is the main entrypoint for the formatter. It parses the source,
35
+ # builds a formatter, then pretty prints the result.
51
36
  def self.format(source, maxwidth = 80)
52
37
  PrettierPrint.format(+"", maxwidth) { |q| parse(source).format(q) }
53
38
  end
54
39
 
40
+ # This is a required API for syntax tree which just delegates to File.read.
55
41
  def self.read(filepath)
56
42
  File.read(filepath)
57
43
  end
58
-
59
- def self.with_children(node, q)
60
- if node.children.empty?
61
- q.group { yield }
62
- else
63
- q.group do
64
- q.group { yield }
65
- q.indent do
66
- node.children.each do |child|
67
- q.breakable(force: true)
68
- child.format(q)
69
- end
70
- end
71
- end
72
- end
73
- end
74
44
  end
75
45
 
76
46
  # Register our module as a handler for the .haml file type.
77
47
  register_handler(".haml", Haml)
78
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,24 +4,24 @@ 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"
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.2.0
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-05-14 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
@@ -128,15 +128,8 @@ files:
128
128
  - bin/format
129
129
  - bin/parse
130
130
  - lib/syntax_tree/haml.rb
131
- - lib/syntax_tree/haml/comment.rb
132
- - lib/syntax_tree/haml/doctype.rb
133
- - lib/syntax_tree/haml/filter.rb
134
- - lib/syntax_tree/haml/haml_comment.rb
135
- - lib/syntax_tree/haml/plain.rb
136
- - lib/syntax_tree/haml/root.rb
137
- - lib/syntax_tree/haml/script.rb
138
- - lib/syntax_tree/haml/silent_script.rb
139
- - lib/syntax_tree/haml/tag.rb
131
+ - lib/syntax_tree/haml/format.rb
132
+ - lib/syntax_tree/haml/pretty_print.rb
140
133
  - lib/syntax_tree/haml/version.rb
141
134
  - syntax_tree-haml.gemspec
142
135
  homepage: https://github.com/ruby-syntax-tree/syntax_tree-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
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
6
- class Script
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("&") if node.value[:escape_html]
16
-
17
- if node.value[:preserve]
18
- q.text("~")
19
- else
20
- q.text("=")
21
- end
22
-
23
- q.text(" ")
24
- q.text(node.value[:text].strip)
25
- end
26
- end
27
-
28
- def pretty_print(q)
29
- q.group(2, "(script", ")") do
30
- q.breakable
31
- q.text("text=")
32
- q.pp(node.value[:text])
33
-
34
- if node.value[:escape_html]
35
- q.breakable
36
- q.text("escape_html")
37
- end
38
-
39
- if node.value[:preserve]
40
- q.breakable
41
- q.text("preserve")
42
- end
43
-
44
- if node.children.any?
45
- q.breakable
46
- q.text("children=")
47
- q.pp(node.children)
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SyntaxTree
4
- module Haml
5
- # https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
6
- class SilentScript
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[:text].strip)
17
-
18
- node.children.each do |child|
19
- if continuation?(child)
20
- q.breakable(force: true)
21
- child.format(q)
22
- else
23
- q.indent do
24
- q.breakable(force: true)
25
- child.format(q)
26
- end
27
- end
28
- end
29
- end
30
- end
31
-
32
- def pretty_print(q)
33
- q.group(2, "(silent_script", ")") do
34
- q.breakable
35
- q.text("text=")
36
- q.pp(node.value[:text])
37
-
38
- if node.children.any?
39
- q.breakable
40
- q.text("children=")
41
- q.pp(node.children)
42
- end
43
- end
44
- end
45
-
46
- private
47
-
48
- def continuation?(child)
49
- return false if child.type != :silent_script
50
-
51
- case [node.value[:keyword], child.value[:keyword]]
52
- in ["case", "in" | "when" | "else"]
53
- true
54
- in ["if" | "unless", "elsif" | "else"]
55
- true
56
- else
57
- false
58
- end
59
- end
60
- end
61
- end
62
- end