Skip to content

Commit b017dad

Browse files
committed
Add components
1 parent e37f8d6 commit b017dad

File tree

4 files changed

+310
-49
lines changed

4 files changed

+310
-49
lines changed

README.md

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Library to easily generate XML with a clean Lua DSL.
55
## Installation
66

77
```bash
8-
luarocks insatll luaxmlgenerator
8+
luarocks install luaxmlgenerator
99
```
1010

1111
## Usage
@@ -73,6 +73,49 @@ end)
7373
print(gen())
7474
```
7575

76+
## Components
77+
78+
Using `xml_gen.component` you can create your own components. Here is an example of a `random_number` component
79+
```lua
80+
---@param context fun(args: { [string] : any }, children: XML.Children): XML.Node?
81+
---@return XML.Component
82+
function export.component(context)
83+
```
84+
85+
```lua
86+
local xml_gen = require("xml-generator")
87+
local xml = xml_gen.xml
88+
89+
math.randomseed(os.time())
90+
91+
local random_number = xml_gen.component(function(args, children)
92+
local min = args.min or 0
93+
--remove these from the args so they dont show up in our HTML attributes later
94+
args.min = nil
95+
local max = args.max or 100
96+
args.max = nil
97+
98+
coroutine.yield(xml.p "This is a valid coroutine too!")
99+
100+
return xml.span(args) {
101+
math.random(min, max),
102+
children --children is a table of all the children passed to the component, this may be empty
103+
}
104+
end)
105+
106+
local doc = xml.html {
107+
xml.body {
108+
random_number {min = 0, max = 100};
109+
random_number {max=10} {
110+
xml.p "This is inside the span!"
111+
};
112+
random_number;
113+
}
114+
}
115+
116+
print(doc)
117+
```
118+
76119
## Utilities
77120

78121
### `xml_gen,declare_generator`
@@ -144,3 +187,52 @@ local style = xml_gen.style {
144187

145188
print(style)
146189
```
190+
191+
## API
192+
193+
You do not need to generate XML with this library, instead, you can use an `XML.Node` as its own object.
194+
195+
```lua
196+
---@class XML.Children
197+
---@field [integer] XML.Node | string | fun(): XML.Node
198+
199+
---@class XML.AttributeTable : XML.Children
200+
---@field [string] string | boolean | number
201+
202+
---@class XML.Node
203+
---@operator call(XML.AttributeTable): XML.Node
204+
---@field tag string
205+
---@field children XML.Children
206+
---@field attributes XML.AttributeTable
207+
208+
---@class XML.Component : XML.Node
209+
---@field attributes { [string] : any } The attributes can be any type for `component`s, but not for `node`s
210+
---@field context fun(args: { [string] : any }, children: XML.Children): XML.Node?
211+
212+
```
213+
214+
### `XML.Node`
215+
216+
```lua
217+
local xml_gen = require("xml-generator")
218+
local xml = xml_gen.xml
219+
220+
local my_node = xml.div {id="my-div"} {
221+
xml.p {id="p-1"} "Hello World";
222+
xml.p {id="p-2"} "Hello World";
223+
xml.p {id="p-3"} "Hello World";
224+
}
225+
226+
print(my_node.tag) --div
227+
print(my_node.attributes.id) --my-div
228+
229+
for i, child in ipairs(my_node.children) do
230+
print(i, child.tag, child.attributes.id)
231+
end
232+
233+
print(my_node)
234+
```
235+
236+
`attributes` and `children` can be empty, but will never be `nil`.
237+
238+
`tag` will be `nil` if the node is a `component`.

api-test.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local xml_gen = require("xml-generator")
2+
local xml = xml_gen.xml
3+
4+
local my_node = xml.div {id="my-div"} {
5+
xml.p {id="p-1"} "Hello World";
6+
xml.p {id="p-2"} "Hello World";
7+
xml.p {id="p-3"} "Hello World";
8+
}
9+
10+
print(my_node.tag, my_node.attributes.id)
11+
12+
for i, child in ipairs(my_node.children) do
13+
print(i, child.tag, child.attributes.id)
14+
end
15+
16+
-- print(my_node)

component-test.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
local xml_gen = require("xml-generator")
2+
local xml = xml_gen.xml
3+
4+
math.randomseed(os.time())
5+
6+
local random_number = xml_gen.component(function(args, children)
7+
local min = args.min or 0
8+
local max = args.max or 100
9+
--remove these from the args so they dont show up in our HTML attributes later
10+
args.min = nil
11+
args.max = nil
12+
13+
coroutine.yield(xml.p"This is a valid coroutine too!")
14+
15+
return xml.span(args) {
16+
math.random(min, max),
17+
children --children is a table of all the children passed to the component, this may be empty
18+
}
19+
end)
20+
21+
local doc = xml.html {
22+
xml.body {
23+
random_number {min = 0, max = 100};
24+
random_number {max=10} {
25+
xml.p "This is inside the span!"
26+
};
27+
random_number;
28+
}
29+
}
30+
31+
print(doc)

0 commit comments

Comments
 (0)