Skip to content

Instantly share code, notes, and snippets.

@tomhodgins
Last active April 23, 2020 19:14
Show Gist options
  • Save tomhodgins/f18774e8778a58200aa4d0aec6743eeb to your computer and use it in GitHub Desktop.
Save tomhodgins/f18774e8778a58200aa4d0aec6743eeb to your computer and use it in GitHub Desktop.
const flags = {
bold: false,
italic: false,
underline: false,
strikethrough: false,
highlight: false,
code: false,
uppercase: false,
lowercase: false
}
export default function commark(object = '') {
let currentNode
const dom = new DocumentFragment
const nodeIterator = document.createNodeIterator(
object instanceof Node
? object
: document.implementation
.createHTMLDocument()
.createRange()
.createContextualFragment(object)
)
while (currentNode = nodeIterator.nextNode()) {
if (currentNode.nodeName === '#text') {
const tag = document.createElement('span')
tag.className = Object.entries(flags).reduce(
(classNames, [key, value]) => classNames += value ? ` ${key}` : '',
''
).trim()
tag.textContent = currentNode.nodeValue
dom.append(tag)
} else if (currentNode instanceof Element) {
if (currentNode.childNodes.length) {
const frag = new DocumentFragment()
Array.from(currentNode.childNodes).forEach(node => frag.append(node))
currentNode.append(commark(frag))
}
dom.append(currentNode)
}
if (currentNode.nodeName === '#comment') {
const currentSymbol = currentNode.nodeValue.trim().replace(/^\//, '')
const symbols = {
'&': 'bold',
'%': 'italic',
'_': 'underline',
'~': 'strikethrough',
'#': 'highlight',
'`': 'code',
'^': 'uppercase',
'v': 'lowercase'
}
if (symbols[currentSymbol]) {
flags[symbols[currentSymbol]] = (currentNode.nodeValue.trim()[0] !== '/')
currentNode.remove()
}
}
}
return dom
}
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Commark demo</title>
<style>
.bold { font-weight: bold }
.italic { font-style: italic }
.underline { text-decoration: underline }
.strikethrough { text-decoration: line-through }
.highlight { background-color: rgb(255, 255, 0, .8) }
.code { font-family: monospace }
.uppercase { text-transform: uppercase }
.lowercase { text-transform: lowercase }
</style>
<script type=module>
import commark from './commark.js'
document.body.append(
commark(`
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sit amet malesuada lacus, et malesuada ligula. <!#>Ut varius libero eget diam condimentum, sit amet varius magna dignissim. <!&>Nam tristique nunc a lacus vestibulum, in ornare tortor ultricies.<!/#> Mauris urna nisi, placerat vitae commodo eget, volutpat ac augue. Nam id augue ligula.<!/&> Mauris consectetur semper vulputate. Sed dapibus elit nec felis efficitur faucibus.
`)
)
document.body.append(
commark(`
All supported tags:
<!&> Bold <!/&>
<!%> Italic <!/%>
<!_> Underline <!/_>
<!~> Strikethrough <!/~>
<!#> Highlight <!/#>
<!\`> Code <!/\`>
<!^> Uppercase <!/^>
<!v> Lowercase <!/v>
`)
)
document.body.append(
commark(`
<ul>
<li>on<!#>e
<li>two
<li>three
<li>fo<!/#>ur
</ul>
`)
)
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment