From cf23af03ddea66427f940f407c1f921a255697a8 Mon Sep 17 00:00:00 2001 From: David Wessman Date: Sun, 20 Aug 2023 08:36:20 +0200 Subject: [PATCH] Handles doctype more freely (#56) - Support ERB-tags before DOCTYPE. - Parse error on multiple DOCTYPE elements. --- CHANGELOG.md | 9 ++++++++- Gemfile.lock | 2 +- lib/syntax_tree/erb/parser.rb | 18 +++++++++++++----- lib/syntax_tree/erb/version.rb | 2 +- test/html_test.rb | 13 +++++++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daf96b5..9e5bfd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index b97fdc9..0a32a37 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/lib/syntax_tree/erb/parser.rb b/lib/syntax_tree/erb/parser.rb index ed5aea4..3b02695 100644 --- a/lib/syntax_tree/erb/parser.rb +++ b/lib/syntax_tree/erb/parser.rb @@ -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 @@ -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 diff --git a/lib/syntax_tree/erb/version.rb b/lib/syntax_tree/erb/version.rb index b1ae2b5..a4e2d30 100644 --- a/lib/syntax_tree/erb/version.rb +++ b/lib/syntax_tree/erb/version.rb @@ -2,6 +2,6 @@ module SyntaxTree module ERB - VERSION = "0.10.0" + VERSION = "0.10.1" end end diff --git a/test/html_test.rb b/test/html_test.rb index f97cb36..ca55327 100644 --- a/test/html_test.rb +++ b/test/html_test.rb @@ -34,6 +34,19 @@ def test_html_doctype parsed = ERB.parse("") assert_instance_of(SyntaxTree::ERB::Doctype, parsed.elements.first) + + # Allow doctype to not be the first element + parsed = ERB.parse("<% theme = \"general\" %> ") + 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("\n\n") + end end def test_html_comment