Skip to content

Instantly share code, notes, and snippets.

@developit
Created May 18, 2020 22:47
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developit/9970bb919dc25b1a356a9ac726b44c17 to your computer and use it in GitHub Desktop.
Save developit/9970bb919dc25b1a356a9ac726b44c17 to your computer and use it in GitHub Desktop.
worlds-worst-jsx-transform.js
/**
* Write JSX, but make sure you have `import html from 'htm/preact'` in your files.
* Run them through this horrid attrocity and get JSX support with basically no overhead.
*/
export function transformJsxToHtm(code) {
const tokenizer = /(^|)(?:<\/([a-z$_][a-z0-9_.-:]*)>|<([a-z$_][a-z0-9_.-:]*)(\s+[a-z0-9._-]+(?:=(?:".*?"|'.*?'|\{.+?\}))?)*(\s*\/\s*)?>|<(\/?)>)/gi;
let out='', index=0, token;
let depth = 0;
let stacks = [];
let shouldPop = false;
while (token = tokenizer.exec(code)) {
const [, before, end, start, attrs, selfClosing, fragment] = token;
let leading = code.substring(index, token.index) + before;
if (depth || shouldPop) leading = leading.replace(/{/g, '${');
if (leading.match(/\$\{[^}]*$/) && depth) {
stacks.push(depth);
depth = 0;
}
out += leading;
if (!start && depth===0 && shouldPop) {
depth = stacks.pop() || 0;
shouldPop = false;
}
if (start) {
if (depth++ === 0) {
// console.log('start', start);
out += 'html`';
shouldPop = false;
}
}
index = tokenizer.lastIndex;
if (fragment!=null) {
out += fragment || (depth++) ? '' : 'html`';
}
else {
out += code.substring(token.index + before.length, index).replace(/(\.\.\.|=){/g, '$1${');
}
if (end || selfClosing || fragment==='/') {
// console.log('end', depth, end || (start + selfClosing));
if (--depth === 0) {
//console.log('end', end || (start + selfClosing));
out += '`';
shouldPop = true;
}
}
}
out += code.substring(index);
return out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment