philiprehberger-html_builder 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c951cd5a9e74ab6642a9181b01235a4a5a63b39015fd05cf5c41ab0157bc6106
4
- data.tar.gz: ab129d21a86612912a83f460cd49424b4005ac95fe6f7c8c6471f3f5309a6640
3
+ metadata.gz: 2422583ee49313a76a8eb70b50d6d8de0040b3f8ea9a9e22722013b0ab7537f5
4
+ data.tar.gz: b61ca71f0b42e279fdd9fa4375b7d67c7c9c8db7a85cc4c6575d5e9ba455b87e
5
5
  SHA512:
6
- metadata.gz: c6ceba75c99ca6620ba8434521b02703cb42d0113f662fe0789928dec1b1e38f4e3057c4fd44495eefd30bd53d08127d6b95daa470e4d67bf15ed56f61e085a9
7
- data.tar.gz: c70fd51be8e402a223a7a1114a0f0950dd66267f2cf20506a1437a32905ba3185634a980fa314fd9785c985600a947890e05768b35dccdaabdbb40a395cb0191
6
+ metadata.gz: 16b555765bd466535c05261da722bdacd670ee72bae7fc635e09de789a02eed4ad6f9020e17404fcb140e34060e1c1be2c5bfff05674e8c5d3867e4f9c8917ed
7
+ data.tar.gz: 75d90b85a6a865213dda114f6e3880d1f059a96ebbfbe348ad872b702fd644c5eece3e86bb56bb1237eae573b74c721dcbf004d3377a05503fce95319e200b69
data/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2026-04-16
11
+
12
+ ### Added
13
+ - HTML5 `<!DOCTYPE html>` helper via `Builder#doctype` and `HtmlBuilder.document`
14
+
10
15
  ## [0.5.0] - 2026-04-15
11
16
 
12
17
  ### Added
data/README.md CHANGED
@@ -227,6 +227,31 @@ end
227
227
 
228
228
  Components without parameters use a simple block with no arguments. Components with parameters receive a hash of locals.
229
229
 
230
+ ### HTML5 Documents
231
+
232
+ Emit a standards-compliant `<!DOCTYPE html>` declaration via the `doctype` DSL helper, or use `HtmlBuilder.document` for a full HTML5 document shortcut that prefixes the doctype automatically. The block decides the root element, so no hardcoded `<html>` wrapper is added:
233
+
234
+ ```ruby
235
+ Philiprehberger::HtmlBuilder.build do
236
+ doctype
237
+ html { head { title 'Home' } }
238
+ end
239
+ # => '<!DOCTYPE html><html><head><title>Home</title></head></html>'
240
+
241
+ Philiprehberger::HtmlBuilder.document do
242
+ html do
243
+ head { title 'Home' }
244
+ body { h1 'Welcome' }
245
+ end
246
+ end
247
+ # => "<!DOCTYPE html>\n<html><head><title>Home</title></head><body><h1>Welcome</h1></body></html>"
248
+
249
+ Philiprehberger::HtmlBuilder.document(pretty: true) do
250
+ html { head { title 'Home' } }
251
+ end
252
+ # pretty-printed with the doctype on its own line
253
+ ```
254
+
230
255
  ### Output Modes
231
256
 
232
257
  Choose between minified and pretty-printed output:
@@ -279,12 +304,14 @@ Philiprehberger::HtmlBuilder.merge(header, body, footer)
279
304
  | `HtmlBuilder.build { ... }` | Build minified HTML using the tag DSL, returns a string |
280
305
  | `HtmlBuilder.build_pretty { ... }` | Build pretty-printed HTML with indentation |
281
306
  | `HtmlBuilder.build_minified { ... }` | Alias for `build`, explicitly produces minified output |
307
+ | `HtmlBuilder.document(pretty:, indent_size:) { ... }` | Build an HTML5 document; prefixes `<!DOCTYPE html>` before the block output |
282
308
  | `HtmlBuilder.merge(*fragments)` | Merge multiple HTML fragment strings into one |
283
309
  | `HtmlBuilder.escape(value)` | Escape HTML special characters in a string using the DSL's escaper |
284
310
  | `Builder#to_html` | Render builder contents to a minified HTML string |
285
311
  | `Builder#to_pretty_html` | Render builder contents to a pretty-printed HTML string |
286
312
  | `Builder#text(content)` | Add escaped text content to the current element |
287
313
  | `Builder#raw(html)` | Add raw HTML without escaping |
314
+ | `Builder#doctype` | Emit an HTML5 `<!DOCTYPE html>` declaration |
288
315
  | `Builder#render_if(condition) { ... }` | Conditionally render a block if condition is truthy |
289
316
  | `Builder#render_unless(condition) { ... }` | Conditionally render a block if condition is falsy |
290
317
  | `Builder#define_component(name) { ... }` | Define a reusable named block |
@@ -80,6 +80,16 @@ module Philiprehberger
80
80
  current_children << node
81
81
  end
82
82
 
83
+ # Emit an HTML5 doctype declaration (`<!DOCTYPE html>`)
84
+ #
85
+ # Has no children and no attributes. In pretty mode the declaration is
86
+ # rendered on its own line at the current indentation.
87
+ #
88
+ # @return [void]
89
+ def doctype
90
+ current_children << DoctypeNode.new
91
+ end
92
+
83
93
  # Conditionally render a block if the condition is truthy
84
94
  #
85
95
  # @param condition [Object] the condition to evaluate
@@ -306,5 +316,19 @@ module Philiprehberger
306
316
  end
307
317
  end
308
318
  end
319
+
320
+ # A node that renders the HTML5 doctype declaration
321
+ class DoctypeNode
322
+ DECLARATION = '<!DOCTYPE html>'
323
+
324
+ # @return [String] the doctype declaration
325
+ def to_html(indent: nil, indent_size: 2)
326
+ if indent
327
+ "#{' ' * (indent * indent_size)}#{DECLARATION}"
328
+ else
329
+ DECLARATION
330
+ end
331
+ end
332
+ end
309
333
  end
310
334
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module HtmlBuilder
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.0'
6
6
  end
7
7
  end
@@ -45,6 +45,27 @@ module Philiprehberger
45
45
  build(&)
46
46
  end
47
47
 
48
+ # Build a full HTML5 document: emits `<!DOCTYPE html>` followed by the
49
+ # rendered block, separated by a newline.
50
+ #
51
+ # The block is evaluated at the root level exactly like `.build` / `.build_pretty`,
52
+ # so the caller decides whether to add an `<html>` wrapper. When `pretty: true`,
53
+ # output is pretty-printed with the given indent size.
54
+ #
55
+ # @param pretty [Boolean] whether to pretty-print the block output (default false)
56
+ # @param indent_size [Integer] number of spaces per indent level when pretty (default 2)
57
+ # @yield [Builder] the builder instance for DSL evaluation
58
+ # @return [String] the rendered HTML document string
59
+ # @raise [Error] if no block is given
60
+ def self.document(pretty: false, indent_size: 2, &block)
61
+ raise Error, 'a block is required' unless block
62
+
63
+ builder = Builder.new
64
+ builder.instance_eval(&block)
65
+ body = pretty ? builder.to_pretty_html(indent_size: indent_size) : builder.to_html
66
+ "#{DoctypeNode::DECLARATION}\n#{body}"
67
+ end
68
+
48
69
  # Merge multiple HTML fragment strings into one
49
70
  #
50
71
  # @param fragments [Array<String>] HTML fragments to merge
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-html_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger