JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://unpkg.com/markty@0.0.3/dist/markty.umd.js"></script>
<div id='app'>
<h3>Input:</h3>
<div id='originalString'></div>
<h3>Parse into:</h3>
<div><pre id='htmlResult'></pre></div>
<h3>Result:</h3>
<div id='final'></div>
</div>
CSS
body {max-width: 100%; padding: 0 20px; line-height: 1.5em;}
mark { padding: 4px 6px; background: #f18c16; color:white;}
code { padding: 0 4px; background: #ddd; color: #a151d2; border-radius:3px; border:1px solid #ccc; }
em {font-family: 'sans-serif'}
pre {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
line-height: 2em;
background: #ddd;
padding: 15px;
border:1px solid #ccc;
border-radius: 3px;
color: #a151d2;
}
Babel + JSX
// =====================================
// ======== helper
// =====================================
function escapeHTML(s) {
return s.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
// =====================================
// ======== GENERAL USE
// =====================================
// 1. Need a string :)
let myString = `//italic//, **strong**, ==higlight==, --strikethrough--, __underline__, h~~2~~0 (sub), 7^^th^^ (sup), \`code\`. <br />
And: ==__Nest__ //stuff// like **crazy**, while being ~~ultra~~-^^fast^^==.`
document.querySelector('#originalString').innerHTML = myString
// 2. We tell what patterns we would like to match, using regex
// let matchThis = /([/*=\-_^~]{2})(?!\s)((?:(?!\n\n|\s?\1).)+)(\1)|([`])(?!\s)((?:(?!\n\n|\s?\`).)+)(\`)/gm
// OR
// we can cut down regex into more maintainable pieces, but we need to escape all backslashes from the string
let emph = '([/*=\\-_^~]{2})(?!\\s)((?:(?!\\n\\n|\\s?\\1).)+)(\\1)'
let code = '([`])(?!\\s)((?:(?!\\n\\n|\\s?\\`).)+)(\\`)'
let matchThis = new RegExp(`${emph}|${code}`, 'gm')
// 3. we call markty and provide the business rules we'd like to have on each match
let result = markty(myString, matchThis, (string, match) => {
let [token,
emph_o, emph_v, emph_c,
code_o, code_v, code_c
] = match
let t;
const TAGS = ['em', 'strong', 'mark', 's', 'u', 'sup', 'sub']
const PATTERNS = ['//', '**', '==', '--', '__', '^^', '~~']
if (emph_v) {
t = TAGS[PATTERNS.indexOf(emph_o)]
return `<${t}>${emph_v}</${t}>`
}
else if (code_v){
return `<code>${code_v}</code>`
}
},
true // we can provide this option to force the code to rerun until no match was found: be carefull #loop
)
// UNRELATED: just to print results in the browser side
document.querySelector('#htmlResult').innerHTML = escapeHTML(result)
document.querySelector('#final').innerHTML = result