Files
coopgo/node_modules/decap-cms-widget-markdown/dist/esm/serializers/remarkShortcodes.js
sgauthier 6e64e138e2
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
planning
2024-10-14 09:15:30 +02:00

123 lines
3.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createRemarkShortcodeStringifier = createRemarkShortcodeStringifier;
exports.getLinesWithOffsets = getLinesWithOffsets;
exports.remarkParseShortcodes = remarkParseShortcodes;
function remarkParseShortcodes({
plugins
}) {
const Parser = this.Parser;
const tokenizers = Parser.prototype.blockTokenizers;
const methods = Parser.prototype.blockMethods;
tokenizers.shortcode = createShortcodeTokenizer({
plugins
});
methods.unshift('shortcode');
}
function getLinesWithOffsets(value) {
const SEPARATOR = '\n\n';
const splitted = value.split(SEPARATOR);
const trimmedLines = splitted.reduce((acc, line) => {
const {
start: previousLineStart,
originalLength: previousLineOriginalLength
} = acc[acc.length - 1];
return [...acc, {
line: line.trimEnd(),
start: previousLineStart + previousLineOriginalLength + SEPARATOR.length,
originalLength: line.length
}];
}, [{
start: -SEPARATOR.length,
originalLength: 0
}]).slice(1).map(({
line,
start
}) => ({
line,
start
}));
return trimmedLines;
}
function matchFromLines({
trimmedLines,
plugin
}) {
for (const {
line,
start
} of trimmedLines) {
const match = line.match(plugin.pattern);
if (match) {
match.index += start;
return match;
}
}
}
function createShortcodeTokenizer({
plugins
}) {
return function tokenizeShortcode(eat, value, silent) {
// Plugin patterns may rely on `^` and `$` tokens, even if they don't
// use the multiline flag. To support this, we fall back to searching
// through each line individually, trimming trailing whitespace and
// newlines, if we don't initially match on a pattern. We keep track of
// the starting position of each line so that we can sort correctly
// across the full multiline matches.
const trimmedLines = getLinesWithOffsets(value);
// Attempt to find a regex match for each plugin's pattern, and then
// select the first by its occurrence in `value`. This ensures we won't
// skip a plugin that occurs later in the plugin registry, but earlier
// in the `value`.
const [{
plugin,
match
} = {}] = plugins.toArray().map(plugin => ({
match: value.match(plugin.pattern) || matchFromLines({
trimmedLines,
plugin
}),
plugin
})).filter(({
match
}) => !!match).sort((a, b) => a.match.index - b.match.index);
if (match) {
if (silent) {
return true;
}
const shortcodeData = plugin.fromBlock(match);
try {
return eat(match[0])({
type: 'shortcode',
data: {
shortcode: plugin.id,
shortcodeData
}
});
} catch (e) {
console.warn(`Sent invalid data to remark. Plugin: ${plugin.id}. Value: ${match[0]}. Data: ${JSON.stringify(shortcodeData)}`);
return false;
}
}
};
}
function createRemarkShortcodeStringifier({
plugins
}) {
return function remarkStringifyShortcodes() {
const Compiler = this.Compiler;
const visitors = Compiler.prototype.visitors;
visitors.shortcode = shortcode;
function shortcode(node) {
const {
data
} = node;
const plugin = plugins.find(plugin => data.shortcode === plugin.id);
return plugin.toBlock(data.shortcodeData);
}
};
}