Mini Markdown with Lists
const isLi = val => val.match(/(^\s+)?- /)
function mark(str) {
const lines = str.split`\n`;
let wasLi = false
let lastDepth = 0;
let depth;
for (let i = 0; i < lines.length; i++) {
let curr = lines[i];
const line = curr.trim();
const hdr = line.split`#`.length - 1;
if (line === '') {
lines[i] = '<br>';
} else if (hdr > 0) {
lines[i] = `<h${hdr} style="margin-bottom:0">
${curr.replace(/#/g, '')}</h${hdr}>`;
} else if (line === '***') {
lines[i] = '<hr>';
} else if (isLi(curr)) {
depth = curr.split('-')[0].length + 1;
lines[i] = '';
if (depth < lastDepth) {
const diff = (lastDepth - depth) / 2
lines[i] += '</ul>'.repeat(diff);
lastDepth = depth
}
lines[i] += `${depth > lastDepth ? '<ul>' : ''}
<li>${curr.replace(/-\s+/, '')}</li>`;
lastDepth = depth;
wasLi = true;
} else if (wasLi) {
lines[i - 1] = '</ul>\n'.repeat(lastDepth)
wasLi = false
}
}
return lines.join`\n`
.replace(/\*\*(.+)\*\*/gm, '<b>$1</b>')
.replace(/_(.+)_/gm, '<i>$1</i>')
.replace(/~~(.+)~~/gm, '<strike>$1</strike>')
.replace(/`(.+)`/gm, '<code>$1</code>');
}
// try it out
const md = document.body.appendChild(document.createElement('div'));
md.style.fontFamily = 'sans-serif';
md.innerHTML = `
#Snippet Zone
This snippet renders a subset of markdown.
- **bold** and _italic text_
- lists
- this particulate
- snippet can render
- nested
- lists
- _**~~strikethrough text~~**_
In a real project you will probably want to use
something more complete like the great <a href="https://github.com/markedjs/marked" target="blank" rel="noopener">marked.js</a> library.
`;
md.innerHTML = mark(md.innerHTML);
This snippet renders a small subset of markdown. This is the same as a post from the other day with the addition of support for nested lists.