Skip to content

Instantly share code, notes, and snippets.

@swyxio
Last active September 28, 2021 03:10
Show Gist options
  • Save swyxio/d5910b613e6f7cec3a849c1a870c1598 to your computer and use it in GitHub Desktop.
Save swyxio/d5910b613e6f7cec3a849c1a870c1598 to your computer and use it in GitHub Desktop.
Custom shortcode syntax for Elder.js

why you may need to customize shortcode syntax

  • elder.js self closing shortcodes look like this: {{foo bar="true"/}}. Note the / at the end is for Elder.js to parse both self closing and content wrapping shortcodes.
  • this clashes with other shortcode systems, eg. dev.to, which uses shortcodes that look like this: {% youtube abc123 %}
  • in elder.config.js you can customize the start and end shortcode: {%foo bar="true"/%}
  • however that / there is non negotiable.
  • this is why you need to customize the shortcode syntax

the strategy is, if you use remark to process the text, to write a custom remark plugin to replace specifically this %} ending code of the dev.to shortcode to what Elder.js expects

the plugin source follows below

const visit = require("unist-util-visit");
// info used in writing this
// https://github.com/angeloashmore/gatsby-remark-find-replace/blob/master/src/index.js
// https://swizec.com/blog/how-to-build-a-remark-plugin-to-supercharge-your-static-site/
const replacements = {
' %}': ` /%}` // the key replacement we are doing
}
// RegExp to find any replacement keys.
const regexp = RegExp(
'(' +
Object.keys(replacements)
.join('|') +
')',
'g',
)
const replacer = (_match, name) => replacements[name]
module.exports = function plugin(){
return function transformer(tree) {
visit(tree, ['text', 'html'], node => {
const processedText = node.value.replace(regexp, replacer)
node.value = processedText
});
};
}
/*
*
* usage... eg in elderjs markdown plugin
*
*/
let _preset = {
settings: {},
plugins: [
// other plugins here
require('./remark-replace') // the one we wrote above
],
}
async function parseMarkdown({filePath, markdown}) {
var post_vfile = vfile({ path: filePath, contents: markdown });
const file = await unified()
.use(_preset) // using the plugins
.process(post_vfile)
.catch((err) => {
console.error(report(post_vfile));
throw err;
});
file.extname = '.html';
return file.toString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment