Skip to content

Instantly share code, notes, and snippets.

@alephao
Created September 26, 2024 13:32
Show Gist options
  • Select an option

  • Save alephao/db44ab883394fba0a8ddcd5df62d3521 to your computer and use it in GitHub Desktop.

Select an option

Save alephao/db44ab883394fba0a8ddcd5df62d3521 to your computer and use it in GitHub Desktop.
Convert raw html into swift/elementary
// Update this value w/ the HTML you want to convert
const htmlToConvert = `<div>Hello World</div>`
// Below is the conversion script
const indentation = " "
const _voidElements = new Set([
'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'link',
'meta',
'param',
'source',
'track',
'wbr',
])
function isVoideElement(node) {
return _voidElements.has(node.tagName.toLowerCase())
}
const _htmlRawSet = new Set(['svg'])
function shouldUseHTMLRaw(node) {
return _htmlRawSet.has(node.tagName.toLowerCase())
}
const _availableAttributes = new Set(['id', 'class', 'placeholder'])
function isAttributeAvailable(attribute) {
return _availableAttributes.has(attribute)
}
function docToElementary(htmlStr) {
const parser = new DOMParser()
const parsedDocument = parser.parseFromString(htmlStr, 'text/html');
const children = parsedDocument.body.childNodes
var output = ""
for (child of children) {
output += nodeToElementary(child, "")
}
return output
}
function nodeToElementary(node, currentIndentation) {
if (node.nodeName == '#cdata-section') {
console.log('skipped #cdata-section')
return ''
}
if (node.nodeName == '#document') {
console.log('skipped #document')
return ''
}
if (node.nodeName == '#document-fragment') {
console.log('skipped #document-fragment')
return ''
}
var output = currentIndentation
if (node.nodeName == '#text') {
output += `"${node.wholeText}"`
return output
}
if (node.nodeName == '#comment') {
output += `.comment("${node.outerHTML}")`
return output
}
if (shouldUseHTMLRaw(node)) {
output += `HTMLRaw(\n`
const idt = currentIndentation + indentation
output += `${idt}"""\n`
output += idt
output += node.outerHTML.replaceAll("\n", `\n${idt}`);
output += `\n${idt}"""\n`
output += `${currentIndentation})`
return output
}
output += node.tagName.toLowerCase()
if (node.attributes && node.attributes.length > 0) {
output += "("
var firstAttribute = true
for (let attribute of node.attributes) {
if (!firstAttribute) {
output += ", "
}
if (isAttributeAvailable(attribute.name)) {
output += `.${attribute.name}("${attribute.value}")`
} else {
output += `.init(name: "${attribute.name}", value: "${attribute.value}")`
}
firstAttribute = false
}
output += ")"
}
if (isVoideElement(node)) {
return output
}
output += ` {`
if (node.childNodes) {
var nextIndentation = `${currentIndentation}${indentation}`
for (child of node.childNodes) {
output += "\n"
output += nodeToElementary(child, nextIndentation)
}
}
output += `\n${currentIndentation}}`
return output
}
const output = docToElementary(htmlToConvert)
console.log(output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment