-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
353 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,89 @@ | ||
const LB = '\n' | ||
const TB = '\t' | ||
|
||
const foldString = (obj, sep = '&', eq = '=', pre = '') => | ||
pre + | ||
Object.keys(obj) | ||
.reduce((str, key) => (str += key + eq + obj[key] + sep), '') | ||
.trim() | ||
|
||
const foldAttributes = attributes => | ||
Object.keys(attributes).reduce((acc, cur) => { | ||
const val = attributes[cur] | ||
|
||
acc += ` ${cur}="` | ||
|
||
switch (val.constructor) { | ||
case String: | ||
acc += val | ||
break | ||
case Object: | ||
acc += foldString(val, '; ') | ||
break | ||
case Array: | ||
acc += foldString(val.at(1), '&', '=', val.at(0)) | ||
break | ||
} | ||
acc += '"' | ||
return acc | ||
}, '') | ||
|
||
const indent = n => | ||
Array(n < 0 ? 0 : n) | ||
.fill(TB) | ||
.join('') | ||
|
||
export default function (arr) { | ||
let inner = '' | ||
let indent = '' | ||
function walk(nodes) { | ||
let html = '' | ||
|
||
function walk(nodes, depth = 0) { | ||
for (const node of nodes) { | ||
const [tag, attributes, val] = node || [] | ||
inner += `${indent}<${tag}` | ||
for (const attr in attributes) { | ||
inner += ` ${attr}="${attributes[attr]}"` | ||
const [tag, ...parts] = node || [] | ||
|
||
if (node.constructor === String) { | ||
html += node | ||
html += LB | ||
continue | ||
} | ||
|
||
html += indent(depth) | ||
html += '<' | ||
html += tag | ||
|
||
const [attributes = {}] = parts | ||
|
||
if (attributes.constructor === Object) { | ||
html += foldAttributes(attributes) | ||
parts.shift() | ||
} | ||
|
||
if (!parts.length) { | ||
html += ' />' | ||
html += LB | ||
continue | ||
} | ||
if (val) { | ||
inner += '>' | ||
if (Array.isArray(val)) { | ||
const hasChildren = Array.isArray(val.at(0)) | ||
indent += '\t' | ||
inner += '\n' | ||
walk((hasChildren && val) || [val]) | ||
indent = indent.replace(/\t$/, '') | ||
inner += `${indent}</${tag}>\n` | ||
} else { | ||
inner += `${val}</${tag}>\n` | ||
|
||
html += '>' | ||
html += LB | ||
|
||
for (const line of parts) { | ||
if (typeof line !== 'object') { | ||
html += indent(depth) | ||
html += TB | ||
html += line | ||
html += LB | ||
} | ||
} else { | ||
inner += ' />\n' | ||
|
||
if (Array.isArray(line)) walk([line], depth + 1) | ||
} | ||
|
||
html += indent(depth) | ||
html += `</${tag}>` | ||
html += LB | ||
} | ||
} | ||
|
||
walk(arr) | ||
|
||
return inner | ||
return html | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[ | ||
["span", "bare val with no attr"], | ||
["span", "multi bare val with no attr", "moremore"], | ||
["span", { "id": "bWattr" }, "bare value with attr"], | ||
["span", { "id": "multi-bWattr" }, "multi bare value with attr", "morewithtth"], | ||
[ | ||
"span", | ||
{ "id": "multi-nested-bWattr" }, | ||
"multi bare value with attr", | ||
"morewithtth", | ||
["img", { "src": "zxcy" }, "zz"] | ||
], | ||
[ | ||
"div", | ||
{ "align": "center", "class": "wrapper" }, | ||
["img", { "src": "example.com" }], | ||
["img", { "src": "google.com" }, "xval"] | ||
], | ||
["footer", ["i", { "class": "icon", "x11": "xorg" }]], | ||
[ | ||
"p", | ||
{ "id": "myp" }, | ||
["a", { "href": "foobar.com" }, ["p", { "class": "hoge" }, "foo"]], | ||
["i", { "class": "icon", "x11": "xorg" }] | ||
] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
``` | ||
foo | ||
``` | ||
<div align="center"> | ||
<h1> | ||
HTML.JSON | ||
</h1> | ||
<hr /> | ||
<h5> | ||
HTML DOM tree representation in compact JSON | ||
</h5> | ||
<h4> | ||
Library and CLI | ||
</h4> | ||
<h6> | ||
zero dependencies | ||
</h6> | ||
</div> | ||
<h3> | ||
Draft Spec | ||
</h3> | ||
Designed around Array indices | ||
Every element is a new line | ||
Array's first element is the TAG | ||
<br /> | ||
Both Attribute and Value can be omitted | ||
<p class="primary"> | ||
second element is the attribute object | ||
</p> | ||
<em> | ||
attributes are optional | ||
</em> | ||
<em> | ||
elements | ||
can have | ||
many children | ||
</em> | ||
<em> | ||
every child | ||
is a new line | ||
</em> | ||
values are optional | ||
<b class="opt" /> | ||
<div class="wrapper"> | ||
elements can | ||
be nested | ||
<span> | ||
arrays as values are children | ||
</span> | ||
<em class="fuga"> | ||
nested | ||
</em> | ||
<p> | ||
children can have | ||
<b> | ||
children! | ||
</b> | ||
</p> | ||
</div> | ||
<hr /> | ||
Attributes with primitive values are rendered as they are written | ||
<br foo="bar" x11="xorg" /> | ||
Attributes with | ||
<em> | ||
Array | ||
</em> | ||
or | ||
<em> | ||
Object | ||
</em> | ||
are treated differently | ||
<br /> | ||
<h4> | ||
Attributes with Object as value | ||
</h4> | ||
<div class="wrapper" style="color=indigo; margin=12px;"> | ||
default behaviour for any attribute with object as value | ||
is to fold the object with | ||
semicolon as delimiter | ||
and equal sign to delimit keys and values | ||
</div> | ||
<h4> | ||
Attributes with Array as value | ||
</h4> | ||
<a src="https://github.com/search?q=json&type=repositories&p=2&" /> | ||
Attributes with array values are querystrings | ||
the first element is a prefix and the following object the query params | ||
<span> | ||
bare val with no attr | ||
</span> | ||
<span> | ||
multi bare val with no attr | ||
moremore | ||
</span> | ||
<span id="bare" class="huh"> | ||
bare value with attr | ||
</span> | ||
<span id="multi-bWattr"> | ||
multi bare value with attr | ||
morewithtth | ||
</span> | ||
<span id="nested"> | ||
next is BIG | ||
<h1> | ||
HEAD | ||
</h1> | ||
</span> | ||
<span id="foo"> | ||
okk | ||
<h3> | ||
<p> | ||
deep | ||
</p> | ||
</h3> | ||
<h2> | ||
TITLE | ||
</h2> | ||
</span> | ||
<a href="https://acme.com/search?user=void&org=nada&" /> | ||
<button style="color=indigo; margin=12px;" class="btn"> | ||
GOGO | ||
</button> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { | ||
readFile, | ||
writeFile | ||
} from 'node:fs/promises' | ||
import transpile from '../src/transpile.js' | ||
import validate from '../src/validate.js' | ||
|
||
|
||
const content = JSON.parse(await readFile('./test/preview.json', { encoding: 'utf8' })) | ||
const write = data => writeFile('./test/preview.html', data) | ||
|
||
console.log('content', '::', content, '<<<::') | ||
|
||
validate(content) | ||
.then(transpile) | ||
.then(write) | ||
.then(console.log) | ||
.catch(console.error) | ||
|
||
// validate(content).then(transpile).then(write).then(console.log).catch(console.error) | ||
|
||
// log(transpile([['div', { zzz: 9898 }, 'foo']])) |
Oops, something went wrong.