htrb 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5281a4dc84416ce926df1217fd82561eaf134eceb4de9e1df80485a83c504829
4
- data.tar.gz: 55120c3bd787d0e1e5db7810c4056db5dd4ea5af9fceafa2dd68eb265daf564e
3
+ metadata.gz: ad5cdfe6149d8e833971102d2e5f95e1ecb7b30886bbcd890fb185a4b7973155
4
+ data.tar.gz: 9cc8d405be1285a8283da15a2e5474f752ec49886c3521a143229dcd8db7ced6
5
5
  SHA512:
6
- metadata.gz: 34634fa26019d580f59c0a1282cebb0ba5ccae51cb0fe63217a52a275d483161dce4c427ea1a2a608a3b2c2e09a60881aec00a0f30e82c47ea1d59d9b135e572
7
- data.tar.gz: ecfe85b71c35bd03d69e88a7acd5563f6b84c7a453ed432b0595be7e0cf4ef1921987fdb4ce06acaa2ab04ee0e4903e908c68924c92dcac640b09b56e78c157c
6
+ metadata.gz: ee24f87969b9f31237afa0c007508bb607d7eb7a214f6a692811333bdad86374aec618db86e5e0c4f6b27a501b1161a567046b0a6cf9bf49a647278bb0b84307
7
+ data.tar.gz: ae44298f61a33d14a55dcff606e2655fe90531d58067fa90fbbd3f40b715f6b517c3448f25d92dacb89515d539d27c4435d4710dec9052a47348571db1f7c7d5
data/Gemfile CHANGED
@@ -1,9 +1,9 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- group :development do
6
- gem "minitest"
7
- gem "minitest-reporters"
8
- gem "simplecov"
9
- end
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "minitest"
7
+ gem "minitest-reporters"
8
+ gem "simplecov"
9
+ end
data/README.md CHANGED
@@ -1,281 +1,283 @@
1
- # HTRB - HTML DSL Gem
2
-
3
- **HTRB** is a DSL for creating dynamic HTML components with Ruby.
4
-
5
- ## Table of Contents
6
- - [General Info](#general-info)
7
- - [Use](#use)
8
- - [Installation](#installation)
9
- - [DSL](#dsl)
10
- - [Warning](#warning)
11
- - [HTRB#html](#htrbhtml)
12
- - [HTRB#fragment](#htrbfragment)
13
- - [HTRB#document](#htrbdocument)
14
- - [Custom Components](#custom-components)
15
- - [Container Components](#container-components)
16
- - [Reference](#reference)
17
- - [HTRB::HtmlNode](#htrb::htmlnode)
18
- - [HtmlNode#initialize](#htmlnodeinitialize)
19
- - [HtmlNode#parent](#htmlnodeparent)
20
- - [HtmlNode#append](#htmlnodeappend)
21
- - [HtmlNode#insert](#htmlnodeinsert)
22
- - [HtmlNode#remove](#htmlnoderemove)
23
- - [HtmlNode#to_s](#htmlnodeto_s)
24
- - [HtmlNode#to_pretty](#htmlnodeto_pretty)
25
- - [HTRB::Document](#htrb::document)
26
- - [Document#initialize](#documentinitialize)
27
- - [Document#head](#documenthead)
28
- - [Document#body](#documentbody)
29
- - [Document#title](#documenttitle)
30
- - [Document#to_s](#documentto_s)
31
- - [Document#to_pretty](#documentto_pretty)
32
-
33
-
34
- ## General Info
35
-
36
- **HTRB** allows you to write HTML inside your Ruby code through the use of a DSL. It was inspired by [JSX](https://react.dev/learn/writing-markup-with-jsx) and [Hypertext](https://github.com/soveran/hypertext).
37
-
38
- **HTRB** allows you to seamlessly write HTML along with your Ruby code. In addition, it allows you to write your own dynamic custom HTML components which can be inserted in with regular HTML to make truly dynamic content.
39
-
40
- It has been designed with technologies like [htmx](https://htmx.org/), [Alpine.js](https://alpinejs.dev/), and [Tailwind CSS](https://tailwindcss.com/) in mind to allow easy rendering of HTML fragments on the backend.
41
-
42
- ## Use
43
- ### Installation
44
- **HTRB** require Ruby 3.0.0 or higher.
45
-
46
- To use **HTRB**, first you need to install the gem:
47
-
48
- ```bash
49
- gem install htrb
50
- ```
51
-
52
- Then to use it in your own code, you need to `require` it:
53
-
54
- ```ruby
55
- require 'htrb'
56
- ```
57
-
58
- ### DSL
59
-
60
- In general, where applicable, **HTRB** provides methods that mimic html tags. Inside blocks related to HTML, you may call these methods to add the particular tag to the HTML as a child. Every non-depricated HTML5 tag is available in syntax like this:
61
-
62
- ```ruby
63
- tag_name! **attributes, &contents-block
64
- ```
65
-
66
- So the `<a>` tag would be represented by the method `a!`, while the `main` tag is represented by the method `main!`.
67
-
68
- Attributes are comma separated name-value pairs and can be in either `name: value` or `"name" => value` forms. So `a! href='/'` would be the same as `<a href="/"></a>` and `img! src: '/a.png', 'alt' => 'The letter A'` would be the same as `<img src="/a.png' alt="The letter A">`. One thing to note is that **HTRB** will automatically change `_` characters in keys to `-` characters, that means `span hx_post: '/accounts'` would become `<span hx-post="/accounts"></span>`
69
-
70
- Finally, you can optionally pass a block to every tag, though self-closing tags will raise an `HTRB::SelfClosingTagError` if you try to pass a block to them. These blocks allow you to add child elements to the element you are creating. For example the following will create the equivalent to `<a href="/join">Join in!</a>`:
71
-
72
- ```ruby
73
- a! href: '/join' do
74
- t! 'Join in!'
75
- end
76
- ```
77
-
78
- Oh, did I just use `t!`, `<t>` isn't a tag. No, but `t!` is a special method created to make a text node. Its use is just `t! string` and it will make the string a child of the parent element. Do note, `t!` automatically escapes HTML, so if you don't want that use `append` instead(see [HTRB::HtmlNode](#htrb::htmlnode) reference)
79
-
80
- #### Warning
81
-
82
- Due to the nature of Ruby meta-programming in order to make the DSL work, the blocks are ran in the context of the `HtmlNode` it is being passed to. This means that instance variables and instance method calls will use the context of the object and not the scope the block was created in. Local variables are ok.
83
-
84
- ```ruby
85
- @global = 'No'
86
-
87
- HTRB.html do
88
- p @global # => nil, referencing HtmlNode instance
89
-
90
- @text = 'Some text'
91
- text = @text
92
-
93
- a! href: '/join' do
94
- t! text if text == @text
95
- # text = 'Some text' due to closure
96
- # @text = nil, it is referencing the A instance
97
- end
98
- end # <a href="/join"></a>
99
- ```
100
-
101
- So, if you plan on using instance variables in your project, it is best to assign what you need to local variables prior to referencing them in a block.
102
-
103
- ### HTRB#html
104
-
105
- One of the most useful methods provided by **HTRB** is `html`. It allows you to quickly create a string containing the raw HTML you provide via the DSL inside a block.
106
-
107
- ```ruby
108
- HTRB.html do
109
- p! id: 'some-text' do
110
- t! 'This is just some text inside a paragraph tag'
111
- end
112
- img! src: "/smiley.jpg"
113
- end
114
- # => '<p id="some-text">This is just some text inside a paragraph tag</p><img src="/smiley.jg">'
115
- ```
116
-
117
- ### HTRB#fragment
118
-
119
- The `fragment` method is very similar to `HTRB#html`. In fact, the `html` does the same thing, except it calls `to_s` on the resulting object and returns the string.
120
-
121
- `HTRB#fragment` creates an `HtmlNode` and populates its children with the block you pass to it. You are returned the resulting `HtmlNode` object and are free to do with it as you please. See [HTRB::HtmlNode](#htrb::htmlnode) reference.
122
-
123
- ### HTRB#document
124
-
125
- The `document` method is a shortcut to create an `HTRB::Document` object. As such it takes all the arguments to construct that a `HTRB::Document` takes and returns the document object. See [HTRB::Document](#htrb::document) reference.
126
-
127
- ---
128
-
129
- ## Custom Components
130
-
131
- One of the most powerful things that **HTRB** can do is allow you to define your own custom components. In general, you do so by creating a class that inherits from `HTRB::Component` and overriding the `render` method:
132
-
133
- ```ruby
134
- class CustomButton < HTRB::Component
135
- def render
136
- button_text = props.text
137
-
138
- a href: props.href, class: 'button' do
139
- t! button_text
140
- end
141
- end
142
- end
143
- ```
144
-
145
- In the above example, we create a `CustomButton` component, that when used will create an anchor element with the class `'button'` and a specified `href` and `text`. When we define `CustomButton`, **HTRB** will automatically create a `_custombutton!` method on `HtmlNode` that will allow you to insert this custom button anywhere you could HTML:
146
-
147
- ```ruby
148
- HTRB.html do
149
- _custombutton! href: '/join', text: 'Join in!'
150
- end # <a href="/join" class="button">Join in!</a>
151
- ```
152
-
153
- To explain how passing data works, the `props` method will return the attributes passed to your custom tag as a hash, so you are able to access custom data anytime you use the tag. As `props` is an instance method, it is only go to reference your custom tag outside of other HTML blocks. It is best practice to extract the data you need into a local variable if you are going to use it inside another HTML element, like we did with `button_text = props.text`.
154
-
155
- ### Container Components
156
-
157
- By default, custom components are considered self-closing tags. This means, if you try to pass a block to a custom component, it will raise a `HTRB::SelfClosingTagError`, not allowing you to define the inner contents of your custom tag. We can get around this by overiding the `self_closing?` method and using the `remit` method:
158
-
159
- ```ruby
160
- class CustomContainer < HTRB::Component
161
- def render(&contents)
162
- div class: 'modal' do
163
- remit &contents
164
- end
165
- end
166
-
167
- def self_closing?
168
- false
169
- end
170
- end
171
- ```
172
-
173
- In the above, we create a custom container component by overriding the `self_closing?` method and returning false. This allows you to pass a block when using the component. We go one further by using the `remit` method to run the passed block inside the context of our div tag.
174
-
175
- `remit` works a lot like the keywork `yield`, but it changes the context of the block to the instance it was called in. You could call it inside a child of your tag or in the tag itself, it doesn't matter. Whatever tags are called inside the block will be added as children to the context it was called in.
176
-
177
- To call this custom container, is just like calling any other custom component. In this case it will be calling the `_customcontainer!` method and passing that a block:
178
-
179
- ```ruby
180
- HTRB.html do
181
- _customcontainer! do
182
- strong! do
183
- t! 'In a container'
184
- end
185
- end
186
- end # <div class="modal"><strong>In a container</strong></div>
187
- ```
188
-
189
- ---
190
-
191
- ## Reference
192
- ### HTRB::HtmlNode
193
-
194
- Everything in **HTRB** is built around the `HtmlNode` object. Both `HTRB::Component` and `HTRB::Element` are subclasses of it and both automatically make relevant methods inside it for each tag generated.
195
-
196
- While most probably will not manipulate the `HtmlNode` object, it is good to understand the public interface of it. It provides a simple dom like structure to forming pages, thus may have some use in generating full pages.
197
-
198
- The `HtmlNode` class is private, thus you won't be constructing it in general by itself, but again its good to know.
199
-
200
- #### HtmlNode#initialize
201
- - `initialize(**attributes, &contents)`
202
- - Is used to construct an `HtmlNode` object
203
- - Will store the `attributes` hash in an instance variable accessible by the private `props` method and then immediately invoke the `render` method passing the `contents` block along
204
- - Generally will be called by generated methods for tags and `HTRB.fragment`/`HTRB.html`
205
-
206
- #### HtmlNode#parent
207
- - Will return the parent node
208
- - If it has no parent, it will be `nil`
209
-
210
- #### HtmlNode#inner_html
211
- - `inner_html()`
212
- - Returns a duplicate of the child array containing all direct child nodes
213
- - `inner_html(&contents)`
214
- - Directly replaces the children with whatever the passed block evaluates to
215
- - All children will have their parent property changed to `nil`
216
-
217
- #### HtmlNode#append
218
- - `append(child)`
219
- - Appends a `child` to the `HtmlNode` instance
220
- - `child` must be a string or `HtmlNode`
221
- - If `child` is a string, it will not be HTML escaped unlike `t!`
222
- - If `child` is an `HtmlNode`, it will have its parent set to this object and removed from previous parent
223
- - if `child` is `self` or an ancestor of `self`, will raise a `HTRB::TagParadoxError`
224
- - Returns `child`
225
-
226
- #### HtmlNode#insert
227
- - `insert(child, where, at)`
228
- - Inserts a `child` in relation to the `at` child, removing child from previous parent
229
- - `child` must be a string or `HtmlNode`
230
- - `where` must be either `:before` or `:after`
231
- - `at` must be a child of the object
232
- - Returns `child`
233
-
234
- #### HtmlNode#remove
235
- - `remove(child)`
236
- - Removes the `child` from the object
237
- - Returns `child` if it was removed, `nil` otherwise
238
-
239
- #### HtmlNode#to_s
240
- - `to_s()`
241
- - converts the object and its children recursively into an html string with no formatting
242
-
243
- #### HtmlNode#to_pretty
244
- - `to_pretty()`
245
- - converts the object and its children recursively into an html string with tabs and newlines
246
-
247
- ### HTRB::Document
248
-
249
- The document object is used to represent an entire HTML document instead of just fragments of one.
250
-
251
- #### Document#initialize
252
- - `initialize(**options, &body_content)`
253
- - The constructor will construct the core of the html document
254
- - There are only two available `options`
255
- - `title:` The title of the page
256
- - `head:` A proc to be executed to add to the `<head></head>` tag
257
- - By default the `<title>` and `<meta charset="UTF-8">` tags are already defined
258
- - `body_content` is the block passed to fill the `<body></body>` tag
259
-
260
- #### Document#head
261
- - `head(&new_contents)`
262
- - `new_contents` is the block passed to replace the contents of the `<head></head>` tag
263
- - The `<title>` and `<meta>` tag are still inserted
264
-
265
- #### Document#body
266
- - `body(&new_contents)`
267
- - `new_contents` is the block passed to replace the contents of the `<body></body>` tag
268
-
269
- #### Document#title
270
- - `title()`
271
- - Returns the title of the page
272
- - `title(new_title)`
273
- - `new_title` is the new title for the page that replaces the old
274
-
275
- #### Document#to_s
276
- - `to_s()`
277
- - converts the document to an html string with no formatting
278
-
279
- #### Document#to_pretty
280
- - `to_pretty()`
281
- - converts the document to an html string with tabs and newlines
1
+ # HTRB - HTML DSL Gem
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/htrb.svg)](https://badge.fury.io/rb/htrb)
4
+
5
+ **HTRB** is a DSL for creating dynamic HTML components with Ruby.
6
+
7
+ ## Table of Contents
8
+ - [General Info](#general-info)
9
+ - [Use](#use)
10
+ - [Installation](#installation)
11
+ - [DSL](#dsl)
12
+ - [Warning](#warning)
13
+ - [HTRB#html](#htrbhtml)
14
+ - [HTRB#fragment](#htrbfragment)
15
+ - [HTRB#document](#htrbdocument)
16
+ - [Custom Components](#custom-components)
17
+ - [Container Components](#container-components)
18
+ - [Reference](#reference)
19
+ - [HTRB::HtmlNode](#htrbhtmlnode)
20
+ - [HtmlNode#initialize](#htmlnodeinitialize)
21
+ - [HtmlNode#parent](#htmlnodeparent)
22
+ - [HtmlNode#append](#htmlnodeappend)
23
+ - [HtmlNode#insert](#htmlnodeinsert)
24
+ - [HtmlNode#remove](#htmlnoderemove)
25
+ - [HtmlNode#to_s](#htmlnodeto_s)
26
+ - [HtmlNode#to_pretty](#htmlnodeto_pretty)
27
+ - [HTRB::Document](#htrbdocument)
28
+ - [Document#initialize](#documentinitialize)
29
+ - [Document#head](#documenthead)
30
+ - [Document#body](#documentbody)
31
+ - [Document#title](#documenttitle)
32
+ - [Document#to_s](#documentto_s)
33
+ - [Document#to_pretty](#documentto_pretty)
34
+
35
+
36
+ ## General Info
37
+
38
+ **HTRB** allows you to write HTML inside your Ruby code through the use of a DSL. It was inspired by [JSX](https://react.dev/learn/writing-markup-with-jsx) and [Hypertext](https://github.com/soveran/hypertext).
39
+
40
+ **HTRB** allows you to seamlessly write HTML along with your Ruby code. In addition, it allows you to write your own dynamic custom HTML components which can be inserted in with regular HTML to make truly dynamic content.
41
+
42
+ It has been designed with technologies like [htmx](https://htmx.org/), [Alpine.js](https://alpinejs.dev/), and [Tailwind CSS](https://tailwindcss.com/) in mind to allow easy rendering of HTML fragments on the backend.
43
+
44
+ ## Use
45
+ ### Installation
46
+ **HTRB** require Ruby 3.0.0 or higher.
47
+
48
+ To use **HTRB**, first you need to install the gem:
49
+
50
+ ```bash
51
+ gem install htrb
52
+ ```
53
+
54
+ Then to use it in your own code, you need to `require` it:
55
+
56
+ ```ruby
57
+ require 'htrb'
58
+ ```
59
+
60
+ ### DSL
61
+
62
+ In general, where applicable, **HTRB** provides methods that mimic html tags. Inside blocks related to HTML, you may call these methods to add the particular tag to the HTML as a child. Every non-depricated HTML5 tag is available in syntax like this:
63
+
64
+ ```ruby
65
+ tag_name! **attributes, &contents-block
66
+ ```
67
+
68
+ So the `<a>` tag would be represented by the method `a!`, while the `main` tag is represented by the method `main!`.
69
+
70
+ Attributes are comma separated name-value pairs and can be in either `name: value` or `"name" => value` forms. So `a! href='/'` would be the same as `<a href="/"></a>` and `img! src: '/a.png', 'alt' => 'The letter A'` would be the same as `<img src="/a.png' alt="The letter A">`. One thing to note is that **HTRB** will automatically change `_` characters in keys to `-` characters, that means `span hx_post: '/accounts'` would become `<span hx-post="/accounts"></span>`
71
+
72
+ Finally, you can optionally pass a block to every tag, though self-closing tags will raise an `HTRB::SelfClosingTagError` if you try to pass a block to them. These blocks allow you to add child elements to the element you are creating. For example the following will create the equivalent to `<a href="/join">Join in!</a>`:
73
+
74
+ ```ruby
75
+ a! href: '/join' do
76
+ t! 'Join in!'
77
+ end
78
+ ```
79
+
80
+ Oh, did I just use `t!`, `<t>` isn't a tag. No, but `t!` is a special method created to make a text node. Its use is just `t! string` and it will make the string a child of the parent element. Do note, `t!` automatically escapes HTML, so if you don't want that use `append` instead(see [HTRB::HtmlNode](#htrbhtmlnode) reference)
81
+
82
+ #### Warning
83
+
84
+ Due to the nature of Ruby meta-programming in order to make the DSL work, the blocks are ran in the context of the `HtmlNode` it is being passed to. This means that instance variables and instance method calls will use the context of the object and not the scope the block was created in. Local variables are ok.
85
+
86
+ ```ruby
87
+ @global = 'No'
88
+
89
+ HTRB.html do
90
+ p @global # => nil, referencing HtmlNode instance
91
+
92
+ @text = 'Some text'
93
+ text = @text
94
+
95
+ a! href: '/join' do
96
+ t! text if text == @text
97
+ # text = 'Some text' due to closure
98
+ # @text = nil, it is referencing the A instance
99
+ end
100
+ end # <a href="/join"></a>
101
+ ```
102
+
103
+ So, if you plan on using instance variables in your project, it is best to assign what you need to local variables prior to referencing them in a block.
104
+
105
+ ### HTRB#html
106
+
107
+ One of the most useful methods provided by **HTRB** is `html`. It allows you to quickly create a string containing the raw HTML you provide via the DSL inside a block.
108
+
109
+ ```ruby
110
+ HTRB.html do
111
+ p! id: 'some-text' do
112
+ t! 'This is just some text inside a paragraph tag'
113
+ end
114
+ img! src: "/smiley.jpg"
115
+ end
116
+ # => '<p id="some-text">This is just some text inside a paragraph tag</p><img src="/smiley.jg">'
117
+ ```
118
+
119
+ ### HTRB#fragment
120
+
121
+ The `fragment` method is very similar to `HTRB#html`. In fact, the `html` does the same thing, except it calls `to_s` on the resulting object and returns the string.
122
+
123
+ `HTRB#fragment` creates an `HtmlNode` and populates its children with the block you pass to it. You are returned the resulting `HtmlNode` object and are free to do with it as you please. See [HTRB::HtmlNode](#htrbhtmlnode) reference.
124
+
125
+ ### HTRB#document
126
+
127
+ The `document` method is a shortcut to create an `HTRB::Document` object. As such it takes all the arguments to construct that a `HTRB::Document` takes and returns the document object. See [HTRB::Document](#htrbdocument) reference.
128
+
129
+ ---
130
+
131
+ ## Custom Components
132
+
133
+ One of the most powerful things that **HTRB** can do is allow you to define your own custom components. In general, you do so by creating a class that inherits from `HTRB::Component` and overriding the `render` method:
134
+
135
+ ```ruby
136
+ class CustomButton < HTRB::Component
137
+ def render
138
+ button_text = props.text
139
+
140
+ a href: props.href, class: 'button' do
141
+ t! button_text
142
+ end
143
+ end
144
+ end
145
+ ```
146
+
147
+ In the above example, we create a `CustomButton` component, that when used will create an anchor element with the class `'button'` and a specified `href` and `text`. When we define `CustomButton`, **HTRB** will automatically create a `_custombutton!` method on `HtmlNode` that will allow you to insert this custom button anywhere you could HTML:
148
+
149
+ ```ruby
150
+ HTRB.html do
151
+ _custombutton! href: '/join', text: 'Join in!'
152
+ end # <a href="/join" class="button">Join in!</a>
153
+ ```
154
+
155
+ To explain how passing data works, the `props` method will return the attributes passed to your custom tag as a hash, so you are able to access custom data anytime you use the tag. As `props` is an instance method, it is only go to reference your custom tag outside of other HTML blocks. It is best practice to extract the data you need into a local variable if you are going to use it inside another HTML element, like we did with `button_text = props.text`.
156
+
157
+ ### Container Components
158
+
159
+ By default, custom components are considered self-closing tags. This means, if you try to pass a block to a custom component, it will raise a `HTRB::SelfClosingTagError`, not allowing you to define the inner contents of your custom tag. We can get around this by overiding the `self_closing?` method and using the `remit` method:
160
+
161
+ ```ruby
162
+ class CustomContainer < HTRB::Component
163
+ def render(&contents)
164
+ div class: 'modal' do
165
+ remit &contents if block_given?
166
+ end
167
+ end
168
+
169
+ def self_closing?
170
+ false
171
+ end
172
+ end
173
+ ```
174
+
175
+ In the above, we create a custom container component by overriding the `self_closing?` method and returning false. This allows you to pass a block when using the component. We go one further by using the `remit` method to run the passed block inside the context of our div tag.
176
+
177
+ `remit` works a lot like the keywork `yield`, but it changes the context of the block to the instance it was called in. You could call it inside a child of your tag or in the tag itself, it doesn't matter. Whatever tags are called inside the block will be added as children to the context it was called in.
178
+
179
+ To call this custom container, is just like calling any other custom component. In this case it will be calling the `_customcontainer!` method and passing that a block:
180
+
181
+ ```ruby
182
+ HTRB.html do
183
+ _customcontainer! do
184
+ strong! do
185
+ t! 'In a container'
186
+ end
187
+ end
188
+ end # <div class="modal"><strong>In a container</strong></div>
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Reference
194
+ ### HTRB::HtmlNode
195
+
196
+ Everything in **HTRB** is built around the `HtmlNode` object. Both `HTRB::Component` and `HTRB::Element` are subclasses of it and both automatically make relevant methods inside it for each tag generated.
197
+
198
+ While most probably will not manipulate the `HtmlNode` object, it is good to understand the public interface of it. It provides a simple dom like structure to forming pages, thus may have some use in generating full pages.
199
+
200
+ The `HtmlNode` class is private, thus you won't be constructing it in general by itself, but again its good to know.
201
+
202
+ #### HtmlNode#initialize
203
+ - `initialize(**attributes, &contents)`
204
+ - Is used to construct an `HtmlNode` object
205
+ - Will store the `attributes` hash in an instance variable accessible by the private `props` method and then immediately invoke the `render` method passing the `contents` block along
206
+ - Generally will be called by generated methods for tags and `HTRB.fragment`/`HTRB.html`
207
+
208
+ #### HtmlNode#parent
209
+ - Will return the parent node
210
+ - If it has no parent, it will be `nil`
211
+
212
+ #### HtmlNode#inner_html
213
+ - `inner_html()`
214
+ - Returns a duplicate of the child array containing all direct child nodes
215
+ - `inner_html(&contents)`
216
+ - Directly replaces the children with whatever the passed block evaluates to
217
+ - All children will have their parent property changed to `nil`
218
+
219
+ #### HtmlNode#append
220
+ - `append(child)`
221
+ - Appends a `child` to the `HtmlNode` instance
222
+ - `child` must be a string or `HtmlNode`
223
+ - If `child` is a string, it will not be HTML escaped unlike `t!`
224
+ - If `child` is an `HtmlNode`, it will have its parent set to this object and removed from previous parent
225
+ - if `child` is `self` or an ancestor of `self`, will raise a `HTRB::TagParadoxError`
226
+ - Returns `child`
227
+
228
+ #### HtmlNode#insert
229
+ - `insert(child, where, at)`
230
+ - Inserts a `child` in relation to the `at` child, removing child from previous parent
231
+ - `child` must be a string or `HtmlNode`
232
+ - `where` must be either `:before` or `:after`
233
+ - `at` must be a child of the object
234
+ - Returns `child`
235
+
236
+ #### HtmlNode#remove
237
+ - `remove(child)`
238
+ - Removes the `child` from the object
239
+ - Returns `child` if it was removed, `nil` otherwise
240
+
241
+ #### HtmlNode#to_s
242
+ - `to_s()`
243
+ - converts the object and its children recursively into an html string with no formatting
244
+
245
+ #### HtmlNode#to_pretty
246
+ - `to_pretty()`
247
+ - converts the object and its children recursively into an html string with tabs and newlines
248
+
249
+ ### HTRB::Document
250
+
251
+ The document object is used to represent an entire HTML document instead of just fragments of one.
252
+
253
+ #### Document#initialize
254
+ - `initialize(**options, &body_content)`
255
+ - The constructor will construct the core of the html document
256
+ - There are only two available `options`
257
+ - `title:` The title of the page
258
+ - `head:` A proc to be executed to add to the `<head></head>` tag
259
+ - By default the `<title>` and `<meta charset="UTF-8">` tags are already defined
260
+ - `body_content` is the block passed to fill the `<body></body>` tag
261
+
262
+ #### Document#head
263
+ - `head(&new_contents)`
264
+ - `new_contents` is the block passed to replace the contents of the `<head></head>` tag
265
+ - The `<title>` and `<meta>` tag are still inserted
266
+
267
+ #### Document#body
268
+ - `body(&new_contents)`
269
+ - `new_contents` is the block passed to replace the contents of the `<body></body>` tag
270
+
271
+ #### Document#title
272
+ - `title()`
273
+ - Returns the title of the page
274
+ - `title(new_title)`
275
+ - `new_title` is the new title for the page that replaces the old
276
+
277
+ #### Document#to_s
278
+ - `to_s()`
279
+ - converts the document to an html string with no formatting
280
+
281
+ #### Document#to_pretty
282
+ - `to_pretty()`
283
+ - converts the document to an html string with tabs and newlines