Skip to content

Instantly share code, notes, and snippets.

@tomhodgins
Last active December 17, 2018 07:15
Show Gist options
  • Save tomhodgins/172dc78386902629de4a182d3892a3ba to your computer and use it in GitHub Desktop.
Save tomhodgins/172dc78386902629de4a182d3892a3ba to your computer and use it in GitHub Desktop.
function todoml(string) {
return string
.split('\n')
.reduce((html, line) => {
// prepare the line
line = line.trim()
// bold
.replace(
/(\*\*)([^\*]+)(\*\*)/g,
(string, open, match, close) => `<strong>${match}</strong>`
)
// italic
.replace(
/(\*)([^\*]+)(\*)/g,
(string, open, match, close) => `<em>${match}</em>`
)
// underline
.replace(
/(_)([\w\s]+)(_)/g,
(string, open, match, close) => `<u>${match}</u>`
)
// strikethrough
.replace(
/(~)([^~]+)(~)/g,
(string, open, match, close) => `<del>${match}</del>`
)
// code
.replace(
/`([^`]+)`/g,
(string, match) => `<code>${match}</code>`
)
// hyperlink
.replace(
/\[([^\]]+)\]\(([^\)]+)\)/g,
(string, text, url) => `<a href=${url}>${text}</a>`
)
// raw HTML
if (/^<.+\>/.test(line)) {
html += line
}
// paragraph
if (/^[^#<>`-]/.test(line)) {
html += `<p>${line}</p>`
}
// horizontal rule
if (/^---/.test(line)) {
html += `<hr>`
}
// heading
if (/^(#+)\s*/.test(line)) {
const heading = 'h' + line.match(/^(#+)\s*/)[1].length
html += `<${heading}>${line.replace(/^#+\s*/, '')}</${heading}>`
}
// blockquote
if (/^(>+)\s*/.test(line)) {
const level = `class=level-${line.match(/^(>+)\s*/)[1].length}`
html += `
<blockquote ${level}>
${line.replace(/^(>+)\s*/, '')}
</blockquote>
`
}
// third-level list
if (/^-\s+-\s+-\s+/.test(line)) {
html += `
<ul>
<li>
<ul>
<li>
<ul>
<li>${line = line.replace(/^-\s+-\s+-\s+/, '')}
</ul>
</ul>
</ul>
`
}
// second-level list
if (/^-\s+-\s+/.test(line)) {
html += `
<ul>
<li>
<ul>
<li>${line = line.replace(/^-\s+-\s+/, '')}
</ul>
</ul>
`
}
// list item
if (/^-\s+[^\[]/.test(line)) {
html += `
<ul>
<li>${line.replace(/^-\s+/, '')}
</ul>
`
}
// empty checkbox
if (/^-\s*\[\s+\]/.test(line)) {
html += `
<label>
<ul>
<li><input type=checkbox>${line.replace(/^-\s*\[\s+\]/, '')}
</ul>
</label>
`
}
// checked checkbox
if (/^-\s*\[[xX]\]/.test(line)) {
html += `
<label>
<ul>
<li><input type=checkbox checked>${line.replace(/^-\s*\[[xX]\]/, '')}
</ul>
</label>
`
}
return html
}, '')
}
function todoML() {
var script = document.querySelectorAll('script[type="text/todo"]')
for (var i=0; i<script.length; i++) {
var todoDoc = ''
var source = script[i].textContent.split('\n')
var output = document.createElement('div')
for (var j=0; j<source.length; j++) {
var line = source[j].replace(/^\s+/, '')
// Bold
line = line.replace(/(\*\*)([^\*]+)(\*\*)/g,
function(string, open, match, close) {
return '<strong>' + match + '</strong>' })
// Italic
line = line.replace(/(\*)([^\*]+)(\*)/g,
function(string, open, match, close) {
return '<em>' + match + '</em>' })
// Underline
line = line.replace(/(_)([\w\s]+)(_)/g,
function(string, open, match, close) {
return '<u>' + match + '</u>' })
// Strikethrough
line = line.replace(/(~)([^~]+)(~)/g,
function(string, open, match, close) {
return '<del>' + match + '</del>' })
// Code
line = line.replace(/`([^`]+)`/g,
function(string, match) {
return '<code>' + match + '</code>' })
// Hyperlink
line = line.replace(/\[([^\]]+)\]\(([^\)]+)\)/g,
function(string, text, link) {
return '<a href="' + link + '">' + text + '</a>' })
// Raw HTML Tag
;/^<.+\>/.test(line) &&
(todoDoc += line)
// Paragraph
;/^[^#<>`-]/.test(line) &&
(todoDoc +=
'<p>'
+ line
+ '</p>')
// Heading
var heading = line.match(/^(#+)\s*/)
var tag = heading && ('h' + heading[1].length)
;heading &&
(todoDoc +=
'<' + tag + '>'
+ line.replace(/^#+\s*/, '')
+ '</' + tag + '>')
// Blockquote
var blockquote = line.match(/^(>+)\s*/)
var level = blockquote &&
('class="level-' + blockquote[1].length + '"')
;blockquote &&
(todoDoc +=
'<blockquote ' + level + '>'
+ line.replace(/^(>+)\s*/, '')
+ '</blockquote>')
// List item
;/^-\s+[^\[]/.test(line) &&
(todoDoc +=
'<ul><li>'
+ line.replace(/^- /, '')
+ '</li></ul>')
// Empty checkbox
;/^-\s*\[\s+\]/.test(line) &&
(todoDoc +=
'<label><ul><li>'
+ '<input type=checkbox>'
+ line.replace(/^-\s*\[\s+\]/, '')
+ '</li></ul></label>')
// Checked checkbox
;/^-\s*\[[xX]\]/.test(line) &&
(todoDoc +=
'<label><ul><li>'
+ '<input type=checkbox checked>'
+ line.replace(/^-\s*\[[xX]\]/, '')
+ '</li></ul></label>')
}
output.innerHTML = todoDoc
script[i].parentNode.insertBefore(output, script[i])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment