Skip to content

Instantly share code, notes, and snippets.

@gera2ld
Created July 9, 2020 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gera2ld/686f08b88d9faef3a59dc5228ed8f23b to your computer and use it in GitHub Desktop.
Save gera2ld/686f08b88d9faef3a59dc5228ed8f23b to your computer and use it in GitHub Desktop.
Babel macro to create HTML from Markdown
function getConverter(showdown) {
showdown.setFlavor('github');
showdown.subParser('runExtension', (ext, source, options, globals) => {
let text = source;
if (ext.filter) {
text = ext.filter(text, globals.converter, options, globals);
}
return text;
});
return new showdown.Converter({
extensions: [
() => [
/*
* Transform custom syntax
* [[hello]]
*
* To:
* <span class="box">hello</span>
*
*/
{
type: 'lang',
filter(source) {
const pattern = /\[\[(.*?)\]\]/g;
let text = source;
text = text.replace(pattern, (wholeMatch, content) => (
`<span class="box">${content}</span>`
));
return text;
},
},
],
],
});
}
exports.getConverter = getConverter;
const fs = require('fs');
const path = require('path');
const { createMacro } = require('babel-plugin-macros');
const showdown = require('showdown');
const { getConverter } = require('./converter');
function richdown({ references, babel, state }) {
references.default.forEach(referencePath => {
if (babel.types.isTaggedTemplateExpression(referencePath.parent)) {
const quasiPath = referencePath.parentPath.get('quasi');
const valueString = quasiPath.parentPath.get('quasi').evaluate().value;
const value = converter.makeHtml(valueString);
const valueNode = babel.types.stringLiteral(value);
quasiPath.parentPath.replaceWith(valueNode);
} else if (babel.types.isCallExpression(referencePath.parent)) {
const quasiPath = referencePath.parentPath.get('quasi');
const filepath = referencePath.parent.arguments[0].value;
const fullpath = path.resolve(path.dirname(state.filename), filepath)
const valueString = fs.readFileSync(fullpath, 'utf8');
const value = converter.makeHtml(valueString);
const valueNode = babel.types.stringLiteral(value);
quasiPath.parentPath.replaceWith(valueNode);
}
});
}
const converter = getConverter(showdown);
module.exports = createMacro(richdown);
import richdown from './richdown.macro';
const htmlFromInline = richdown`
hello, **world**
`;
const htmlFromFile = richdown('hello.md');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment