74 lines
2.6 KiB
JavaScript
74 lines
2.6 KiB
JavaScript
import container from 'markdown-it-container';
|
|
import { ensureLeadingSlash, resolveLocalePath } from 'vuepress/shared';
|
|
import { colors, logger } from 'vuepress/utils';
|
|
export const markdownContainerPlugin = ({
|
|
// plugin options
|
|
type, after, before, locales,
|
|
// raw options for markdown-it-container
|
|
validate, marker, render, }) => {
|
|
const plugin = {
|
|
name: '@vuepress/plugin-markdown-container',
|
|
multiple: true,
|
|
};
|
|
// `type` option is required
|
|
if (!type) {
|
|
logger.warn(`[${plugin.name}] ${colors.magenta('type')} option is required`);
|
|
return plugin;
|
|
}
|
|
// if `render` option is not specified
|
|
// use `before` and `after` to generate render function
|
|
if (!render) {
|
|
let renderBefore;
|
|
let renderAfter;
|
|
if (before !== undefined && after !== undefined) {
|
|
// user defined
|
|
renderBefore = before;
|
|
renderAfter = after;
|
|
}
|
|
else {
|
|
// fallback
|
|
renderBefore = (info) => `<div class="custom-container ${type}">${info ? `<p class="custom-container-title">${info}</p>` : ''}\n`;
|
|
renderAfter = () => '</div>\n';
|
|
}
|
|
// token info stack
|
|
const infoStack = [];
|
|
render = (tokens, index, opts, env) => {
|
|
const token = tokens[index];
|
|
if (token.nesting === 1) {
|
|
// `before` tag
|
|
// resolve info (title)
|
|
let info = token.info.trim().slice(type.length).trim();
|
|
if (!info && locales) {
|
|
// locale
|
|
const { filePathRelative } = env;
|
|
const relativePath = ensureLeadingSlash(filePathRelative ?? '');
|
|
const localePath = resolveLocalePath(locales, relativePath);
|
|
const localeData = locales[localePath] ?? {};
|
|
if (localeData.defaultInfo) {
|
|
info = localeData.defaultInfo;
|
|
}
|
|
else {
|
|
info = type.toUpperCase();
|
|
}
|
|
}
|
|
// push the info to stack
|
|
infoStack.push(info);
|
|
// render
|
|
return renderBefore(info);
|
|
}
|
|
else {
|
|
// `after` tag
|
|
// pop the info from stack
|
|
const info = infoStack.pop() || '';
|
|
// render
|
|
return renderAfter(info);
|
|
}
|
|
};
|
|
}
|
|
// use markdown-it-container
|
|
plugin.extendsMarkdown = (md) => {
|
|
md.use(container, type, { render, validate, marker });
|
|
};
|
|
return plugin;
|
|
};
|