Skip to content

Commit 315b593

Browse files
committed
Engine: Add auto_close_omitted_tags option
1 parent 799cbe9 commit 315b593

41 files changed

Lines changed: 625 additions & 3 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/herb/cli.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
class Herb::CLI
99
include Herb::Colors
1010

11-
attr_accessor :json, :silent, :no_interactive, :no_log_file, :no_timing, :local, :escape, :no_escape, :freeze, :debug, :tool, :strict
11+
attr_accessor :json, :silent, :no_interactive, :no_log_file, :no_timing, :local, :escape, :no_escape, :freeze, :debug, :tool, :strict,
12+
:auto_close_tags
1213

1314
def initialize(args)
1415
@args = args
@@ -246,6 +247,10 @@ def option_parser
246247
self.strict = false
247248
end
248249

250+
parser.on("--auto-close-tags", "Auto-insert closing tags for elements with omitted closing tags (for compile/render commands)") do
251+
self.auto_close_tags = true
252+
end
253+
249254
parser.on("--tool TOOL", "Show config for specific tool: linter, formatter (for config command)") do |t|
250255
self.tool = t.to_sym
251256
end
@@ -294,6 +299,7 @@ def compile_template
294299
options[:escape] = no_escape ? false : true
295300
options[:freeze] = true if freeze
296301
options[:strict] = strict.nil? || strict
302+
options[:auto_close_omitted_tags] = auto_close_tags
297303

298304
if debug
299305
options[:debug] = true
@@ -309,6 +315,7 @@ def compile_template
309315
filename: engine.filename,
310316
bufvar: engine.bufvar,
311317
strict: options[:strict],
318+
auto_close_omitted_tags: options[:auto_close_omitted_tags],
312319
}
313320

314321
puts result.to_json
@@ -362,6 +369,7 @@ def render_template
362369
options[:escape] = no_escape ? false : true
363370
options[:freeze] = true if freeze
364371
options[:strict] = strict.nil? || strict
372+
options[:auto_close_omitted_tags] = auto_close_tags
365373

366374
if debug
367375
options[:debug] = true
@@ -379,6 +387,7 @@ def render_template
379387
output: rendered_output,
380388
filename: engine.filename,
381389
strict: options[:strict],
390+
auto_close_omitted_tags: options[:auto_close_omitted_tags],
382391
}
383392

384393
puts result.to_json

lib/herb/engine.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
module Herb
1818
class Engine
1919
attr_reader :src, :filename, :project_path, :relative_file_path, :bufvar, :debug, :content_for_head,
20-
:validation_error_template, :visitors
20+
:validation_error_template, :visitors, :auto_close_omitted_tags
2121

2222
ESCAPE_TABLE = {
2323
"&" => "&",
@@ -52,6 +52,7 @@ def initialize(input, properties = {})
5252
@validation_error_template = nil
5353
@validation_mode = properties.fetch(:validation_mode, :raise)
5454
@strict = properties.fetch(:strict, true)
55+
@auto_close_omitted_tags = properties.fetch(:auto_close_omitted_tags, false)
5556
@visitors = properties.fetch(:visitors, default_visitors)
5657

5758
if @debug && @visitors.empty?

lib/herb/engine/compiler.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def initialize(engine, options = {})
1313
@attrfunc = options.fetch(:attrfunc, @escape ? "__herb.attr" : "::Herb::Engine.attr")
1414
@jsfunc = options.fetch(:jsfunc, @escape ? "__herb.js" : "::Herb::Engine.js")
1515
@cssfunc = options.fetch(:cssfunc, @escape ? "__herb.css" : "::Herb::Engine.css")
16+
@auto_close_omitted_tags = options.fetch(:auto_close_omitted_tags, false)
1617
@tokens = [] #: Array[untyped]
1718
@element_stack = [] #: Array[String]
1819
@context_stack = [:html_content]
@@ -146,7 +147,18 @@ def visit_html_close_tag_node(node)
146147
end
147148

148149
def visit_html_omitted_close_tag_node(node)
149-
# no-op
150+
return unless @auto_close_omitted_tags
151+
152+
tag_name = node.tag_name&.value
153+
154+
if @engine.content_for_head && tag_name&.downcase == "head"
155+
escaped_html = @engine.content_for_head.gsub("'", "\\\\'")
156+
@tokens << [:expr, "'#{escaped_html}'.html_safe", current_context]
157+
end
158+
159+
add_text("</")
160+
add_text(tag_name)
161+
add_text(">")
150162
end
151163

152164
def visit_html_text_node(node)

0 commit comments

Comments
 (0)