Skip to content

Instantly share code, notes, and snippets.

@smnh
Created December 8, 2020 13:00
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 smnh/d00e2688e08c6991ced53dc645635851 to your computer and use it in GitHub Desktop.
Save smnh/d00e2688e08c6991ced53dc645635851 to your computer and use it in GitHub Desktop.
Using shortcodes with marked
import React from 'react';
import ReactHtmlParser from 'react-html-parser';
import marked from 'marked';
import _ from 'lodash';
import withPrefix from './withPrefix';
const ShortCodes = {
figure: function(attrs) {
let imgAttrs = '';
let caption = '';
if (_.has(attrs, 'src')) {
imgAttrs += ` src="${withPrefix(attrs.src)}"`;
}
if (_.has(attrs, 'alt')) {
imgAttrs += ` alt="${attrs.alt}"`;
}
if (_.has(attrs, 'caption')) {
caption = `<span class="figure-caption">${attrs.caption}</span>`;
}
return `<div class="figure"><img${imgAttrs}/>${caption}</div>`;
}
};
marked.use({
renderer: {
paragraph: function(text) {
const shortCodeRegExp = /\{<(?<shortcode>\w+)(?<attributes>\s+[\s\S]+?)?>}/g;
const attributesRegExp = /(?<attrName>\w+)(?:=(['"])(?<attrValue>.+?)\2)?/g;
let match = shortCodeRegExp.exec(text);
// if shortcode not found, run default paragraph
if (!match) {
return marked.Renderer.prototype.paragraph.call(this, text);
}
let result = '';
let lastIndex = 0;
while (match !== null) {
result += text.substring(lastIndex, match.index);
lastIndex = shortCodeRegExp.lastIndex;
const shortcode = _.get(match, 'groups.shortcode');
console.log(shortcode);
if (!_.has(ShortCodes, shortcode)) {
result += text.substring(match.index, lastIndex);
match = shortCodeRegExp.exec(text);
continue;
}
const rawAttributes = _.get(match, 'groups.attributes');
let attrMatch;
const attributes = {};
while ((attrMatch = attributesRegExp.exec(rawAttributes)) !== null) {
const attrName = _.get(attrMatch, 'groups.attrName');
attributes[attrName] = _.get(attrMatch, 'groups.attrValue', null);
}
result += ShortCodes[shortcode](attributes);
match = shortCodeRegExp.exec(text);
}
result += text.substring(lastIndex);
return result;
}
}
});
const markdown = `
# Hello world
This is a paragraph
{<figure src="image.jpg" alt="alt text" caption="image caption">}
Another paragraph
`;
const html = marked(markdown);
const react = ReactHtmlParser(html);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment