Skip to content

Commit 06c17fc

Browse files
authored
Merge pull request #4 from RickBarretto/html-v2
Html v2 - Proposal
2 parents aa5c8a5 + 4f1df85 commit 06c17fc

File tree

7 files changed

+352
-59
lines changed

7 files changed

+352
-59
lines changed

exp.art

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import.verbose {src/html}!
2+
3+
4+
print html [
5+
head [
6+
title "Hello"
7+
meta #[name: "twitter:card"]
8+
]
9+
10+
body [
11+
h1 "Title"
12+
input #[name: "user" type: "username"]
13+
]
14+
15+
]

info.art

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
entry: {src/html}
12
requires: [> 0.9.83]

main.art

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/html.art

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
define :html [
2+
3+
init: method [][
4+
elements: [
5+
; Main
6+
body head
7+
8+
; Web Components
9+
slot template
10+
11+
; Editing
12+
del ins
13+
14+
; Embedded Content
15+
embed iframe object picture portal source svg math
16+
17+
; Forms
18+
button datails fieldset form input label legend meter optgroup
19+
option output progress select textarea
20+
21+
; Inline Text
22+
a abbr b bdi bdo br cite code data dfn em i kbd mark q s rp rt
23+
ruby samp small span strong sub sup time u var wbr
24+
25+
; Interactives
26+
details dialog summary
27+
28+
; Metadata Content
29+
base link meta title style
30+
31+
; Multimedia
32+
area audio img map track video
33+
34+
; Scripting
35+
canvas noscript script
36+
37+
; Content Sectioning
38+
address article aside footer header h1 h2 h3 h4 h5 h6 hgroup main
39+
nav section search
40+
41+
; Tables
42+
caption col colgroup table tbody td tfoot th thead tr
43+
44+
; Text Content
45+
blockquote dd div dl dt figcaption figure hr li menu ol p pre ul
46+
]
47+
48+
loop elements 'el [
49+
body: [\element x]
50+
insert 'body 1 to :literal el
51+
this\[el]: method [x] body
52+
]
53+
]
54+
55+
_process: method [content][
56+
@content
57+
]
58+
59+
kebab: method [content :string][
60+
replace content "_" "-"
61+
]
62+
63+
voidElement: method [tag :string :literal :word htmlAttributes :dictionary][
64+
;; Void \elements are \elements without closing-tags.
65+
;;
66+
;; Format
67+
;; ------
68+
;; They follows the pattern: ``<tag key="value" .../>``
69+
;;
70+
;; Features
71+
;; --------
72+
;; Use Arturo's attributes to dynamically add html's attributes to it.
73+
;;
74+
;; Extra
75+
;; -----
76+
;; Read more about void \elements here:
77+
;; <https://html.spec.whatwg.org/multipage/syntax.html#void-\elements/>
78+
79+
attributes: (
80+
map htmlAttributes [key value] -> render {|\kebab key|="|value|"}
81+
| append (map attrs [key value] -> render {|\kebab key|="|value|"})
82+
| join.with: " "
83+
)
84+
85+
if attributes <> "" -> prepend 'attributes " "
86+
~"<|tag||attributes|/>"
87+
]
88+
89+
element: method.public [tag :string :literal content :block :string :dictionary][
90+
;; \elements refers to the normal \elements defined by the HTML5 standard.
91+
;;
92+
;; Format
93+
;; ------
94+
;; * They follows the pattern: ``<tag key="value" .../>content<tag />``.
95+
;; * When ``content`` is a :block, the content will be intended by 2 spaces.
96+
;;
97+
;; Features
98+
;; --------
99+
;; Use Arturo's attributes to dynamically add html's attributes to it.
100+
;;
101+
;; Extra
102+
;; -----
103+
;; Read more about \elements here:
104+
;; <https://html.spec.whatwg.org/multipage/syntax.html#\elements-2/>
105+
106+
if dictionary? content ->
107+
return \voidElement tag content
108+
109+
attributes: (join.with: " " map attrs [key value] -> render {|\kebab key|="|value|"})
110+
if attributes <> "" -> prepend 'attributes " "
111+
112+
if block? content ->
113+
join.with: "\n" @[
114+
~"<|tag||attributes|>"
115+
indent.n: 2 join.with: "\n" @content
116+
~"</|tag|>"
117+
]
118+
119+
if string? content ->
120+
~"<|tag||attributes|>|content|</|tag|>"
121+
]
122+
123+
html: method [page :block][
124+
html4: attr 'html4
125+
126+
doctype: (html4)?
127+
-> {!html
128+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
129+
}
130+
-> {!html
131+
<!DOCTYPE html>
132+
}
133+
134+
join.with: "\n" @[
135+
doctype
136+
\element 'html page
137+
]
138+
]
139+
140+
]
141+
142+
html: to :html []
143+
fragment: $[content][
144+
join.with: "\n" @ html\_process content
145+
]!

test.art

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#! arturo
2+
3+
import.version: 1.1.2 'unitt!
4+
5+
testPath: "test"
6+
7+
runTests (empty? arg)?
8+
-> findTests.thatMatches: "*.test.art" testPath
9+
-> map arg 'file [ ~"|testPath|/|file|.test.art" ]

test/element.test.art

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import {unitt}!
2+
import {src/html}!
3+
4+
test "generic elements follows the standard for :string" [
5+
result: html\element "el" "Hello, World!"
6+
assert -> "<el>Hello, World!</el>" = result
7+
]
8+
9+
10+
test "generic elements follows the standard for nested :block s" [
11+
;; This test tests multiple things:
12+
;; * Opening and closing tags:
13+
;; Each element should be opened and closed
14+
;; * Indentation
15+
;; Two spaces must be added per element nesting
16+
;; * Evaluation
17+
;; the user shouldn't use '@ to evaluate, the element must do it
18+
19+
breakLine: "<br>"
20+
bold: $[x][html\element "b" x]
21+
paragraph: $[x][html\element "p" x]
22+
23+
expect: {!html
24+
<p>
25+
Hello,
26+
<br>
27+
<b>World</b>
28+
!
29+
</p>
30+
}
31+
32+
result: paragraph [
33+
"Hello,"
34+
breakLine
35+
bold "World" "!"
36+
]
37+
38+
assert -> expect = result
39+
]
40+
41+
test "indentation follows the nesting of elements" [
42+
;; Also verifies the nesting for strings
43+
;;
44+
;; How the formatation must work:
45+
;;
46+
;; tag "Content"
47+
;; ; <tag>Content</tag>
48+
;;
49+
;; tag ["Content"]
50+
;; ; <tag>
51+
;; ; Content
52+
;; ; </tag>
53+
54+
divisory: $[x][html\element "div" x]
55+
56+
expect: {!html
57+
<div>
58+
Level 01
59+
<div>
60+
Level 02
61+
<div>Level 03</div>
62+
Level 02
63+
</div>
64+
Level 01
65+
</div>
66+
}
67+
68+
result: divisory [
69+
"Level 01"
70+
divisory [
71+
"Level 02"
72+
divisory "Level 03"
73+
"Level 02"
74+
]
75+
"Level 01"
76+
]
77+
78+
assert -> expect = result
79+
]
80+
81+
test "dynamic attributes follows standard" [
82+
;; We can dynamically add Elements's attributes by using Arturo's attributes
83+
;;
84+
;; How this must work:
85+
;;
86+
;; tag.class: "content" "Content"
87+
;; ; <tag class="content">Content</tag>
88+
;;
89+
;; tag.author: "RickB" ["Content"]
90+
;; ; <tag author="RickB">
91+
;; ; Content
92+
;; ; </tag>
93+
94+
divisory: $[x][html\element "div" x]
95+
entry: $[x][html\element .name: x "input" ""]
96+
button: $[x][html\element "button" x]
97+
98+
expect: {!html
99+
<div class="login-box">
100+
<input type="email" name="user"></input>
101+
<input type="password" name="pwd"></input>
102+
<button class="enter">Log In</button>
103+
<button class="recover">Forgot my password</button>
104+
</div>
105+
}
106+
107+
result: divisory.class: "login-box" [
108+
entry.type: 'email "user"
109+
entry.type: 'password "pwd"
110+
button.class: 'enter "Log In"
111+
button.class: 'recover "Forgot my password"
112+
]
113+
114+
assert -> expect = result
115+
]
116+
117+
118+
test "snake-case should be converted to kebab" [
119+
divisory: $[x][html\element 'div x]
120+
expect: {!html
121+
<div aria-valuenow="50"></div>
122+
}
123+
124+
result: divisory.aria_valuenow: 50 ""
125+
assert -> expect = result
126+
127+
]
128+
129+
130+
test "auto void elements when pass a :dictionary as parameter" [
131+
input: $[x][html\element 'input x]
132+
expect: {!html
133+
<input type="email"></input>
134+
}
135+
136+
result: input.type: "email" ""
137+
assert -> expect = result
138+
139+
140+
expect: {!html
141+
<input type="email"/>
142+
}
143+
144+
result: input #[type: "email"]
145+
assert -> expect = result
146+
147+
]

0 commit comments

Comments
 (0)