Skip to content

Commit

Permalink
Handles doctype more freely (#56)
Browse files Browse the repository at this point in the history
- Support ERB-tags before DOCTYPE.
- Parse error on multiple DOCTYPE elements.
  • Loading branch information
davidwessman authored Aug 20, 2023
1 parent 375d720 commit cf23af0
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 8 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

## [0.10.1] - 2023-08-20

### Added

- Allow `DOCTYPE` to be after other tags, to work with e.g. ERB-tags on first line.

## [0.10.0] - 2023-08-20

- Changes how whitespace and newlines are handled.
Expand Down Expand Up @@ -70,7 +76,8 @@ Output:
- Can format a lot of .html.erb-syntax and works as a plugin to syntax_tree.
- This is still early and there are a lot of different weird syntaxes out there.

[unreleased]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.10.0...HEAD
[unreleased]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.10.1...HEAD
[0.10.1]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.10.0...v0.10.1
[0.10.0]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.9.5...v0.10.0
[0.9.5]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.9.4...v0.9.5
[0.9.4]: https://github.com/davidwessman/syntax_tree-erb/compare/v0.9.3...v0.9.4
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
w_syntax_tree-erb (0.10.0)
w_syntax_tree-erb (0.10.1)
prettier_print (~> 1.2, >= 1.2.0)
syntax_tree (~> 6.1, >= 6.1.1)

Expand Down
18 changes: 13 additions & 5 deletions lib/syntax_tree/erb/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ class MissingTokenError < ParseError
def initialize(source)
@source = source
@tokens = make_tokens
@found_doctype = false
end

def parse
doctype = maybe { parse_doctype }
elements = many { parse_any_tag }

location =
elements.first.location.to(elements.last.location) if elements.any?

Document.new(elements: [doctype].compact + elements, location: location)
Document.new(elements: elements, location: location)
end

def debug_tokens
Expand All @@ -44,11 +44,19 @@ def parse_any_tag
loop do
tag =
atleast do
maybe { parse_html_comment } || maybe { parse_erb_tag } ||
maybe { parse_erb_comment } || maybe { parse_html_element } ||
maybe { parse_new_line } || maybe { parse_chardata }
maybe { parse_doctype } || maybe { parse_html_comment } ||
maybe { parse_erb_tag } || maybe { parse_erb_comment } ||
maybe { parse_html_element } || maybe { parse_new_line } ||
maybe { parse_chardata }
end

if tag.is_a?(Doctype)
if @found_doctype
raise(ParseError, "Only one doctype element is allowed")
else
@found_doctype = true
end
end
# Allow skipping empty CharData
return tag unless tag.skip?
end
Expand Down
2 changes: 1 addition & 1 deletion lib/syntax_tree/erb/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module SyntaxTree
module ERB
VERSION = "0.10.0"
VERSION = "0.10.1"
end
end
13 changes: 13 additions & 0 deletions test/html_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ def test_html_doctype

parsed = ERB.parse("<!doctype html>")
assert_instance_of(SyntaxTree::ERB::Doctype, parsed.elements.first)

# Allow doctype to not be the first element
parsed = ERB.parse("<% theme = \"general\" %> <!DOCTYPE html>")
assert_equal(2, parsed.elements.size)
assert_equal(
[SyntaxTree::ERB::ErbNode, SyntaxTree::ERB::Doctype],
parsed.elements.map(&:class)
)

# Do not allow multiple doctype elements
assert_raises(SyntaxTree::ERB::Parser::ParseError) do
ERB.parse("<!DOCTYPE html>\n<!DOCTYPE html>\n")
end
end

def test_html_comment
Expand Down

0 comments on commit cf23af0

Please sign in to comment.