[^)]*)\)/;
var parseLineNumber = (line) => line ? Number.parseInt(line, 10) : void 0;
var createImportCodeBlockRule = ({ handleImportPath = (str) => str }) => (state, startLine, endLine, silent) => {
if (state.sCount[startLine] - state.blkIndent >= 4) {
return false;
}
const pos = state.bMarks[startLine] + state.tShift[startLine];
const max = state.eMarks[startLine];
if (pos + MIN_LENGTH > max) return false;
for (let i = 0; i < START_CODES.length; i += 1) {
if (state.src.charCodeAt(pos + i) !== START_CODES[i]) {
return false;
}
}
const match = state.src.slice(pos, max).match(SYNTAX_RE);
if (!match?.groups) return false;
if (silent) return true;
const { info, importPath } = match.groups;
const lineSingle = parseLineNumber(match.groups.lineSingle);
const lineStart = lineSingle ?? parseLineNumber(match.groups.lineStart) ?? 0;
const lineEnd = lineSingle ?? parseLineNumber(match.groups.lineEnd);
const meta = {
importPath: handleImportPath(importPath),
lineStart,
lineEnd
};
const token = state.push("import_code", "code", 0);
token.info = info ?? path2.extname(meta.importPath).slice(1);
token.markup = "```";
token.map = [startLine, startLine + 1];
token.meta = meta;
state.line = startLine + 1;
return true;
};
// src/plugins/importCodePlugin/resolveImportCode.ts
import { colors, fs, logger, path as path3 } from "@vuepress/utils";
var resolveImportCode = ({ importPath, lineStart, lineEnd }, { filePath }) => {
let importFilePath = importPath;
if (!path3.isAbsolute(importPath)) {
if (!filePath) {
logger.error(
`Import file ${colors.magenta(importPath)} can not be resolved`
);
return {
importFilePath: null,
importCode: "Error when resolving path"
};
}
importFilePath = path3.resolve(filePath, "..", importPath);
}
if (!fs.existsSync(importFilePath)) {
logger.error(`Import file ${colors.magenta(importPath)} not found`);
return {
importFilePath,
importCode: "File not found"
};
}
const fileContent = fs.readFileSync(importFilePath).toString();
return {
importFilePath,
importCode: fileContent.split("\n").slice(lineStart ? lineStart - 1 : lineStart, lineEnd).join("\n").replace(/\n?$/, "\n")
};
};
// src/plugins/importCodePlugin/importCodePlugin.ts
var importCodePlugin = (md, options = {}) => {
md.block.ruler.before(
"fence",
"import_code",
createImportCodeBlockRule(options),
{
alt: ["paragraph", "reference", "blockquote", "list"]
}
);
md.renderer.rules.import_code = (tokens, idx, options2, env, slf) => {
const token = tokens[idx];
const { importFilePath, importCode } = resolveImportCode(token.meta, env);
token.content = importCode;
if (importFilePath) {
;
(env.importedFiles ??= []).push(importFilePath);
}
return md.renderer.rules.fence(tokens, idx, options2, env, slf);
};
};
// src/plugins/linksPlugin/linksPlugin.ts
import { inferRoutePath, isLinkExternal } from "@vuepress/shared";
// src/plugins/linksPlugin/resolvePaths.ts
import { removeLeadingSlash } from "@vuepress/shared";
import { path as path4 } from "@vuepress/utils";
var resolvePaths = (rawPath, base, filePathRelative) => {
let absolutePath;
let relativePath;
if (rawPath.startsWith("/")) {
if (rawPath.endsWith(".md")) {
absolutePath = path4.join(base, rawPath);
relativePath = removeLeadingSlash(rawPath);
} else {
absolutePath = rawPath;
relativePath = path4.relative(base, absolutePath);
}
} else {
if (filePathRelative) {
relativePath = path4.join(
// file path may contain non-ASCII characters
path4.dirname(encodeURI(filePathRelative)),
rawPath
);
absolutePath = path4.join(base, relativePath);
} else {
relativePath = rawPath.replace(/^(?:\.\/)?(.*)$/, "$1");
absolutePath = null;
}
}
return {
absolutePath,
relativePath
};
};
// src/plugins/linksPlugin/linksPlugin.ts
var linksPlugin = (md, options = {}) => {
const internalTag = options.internalTag || "RouteLink";
const externalAttrs = {
target: "_blank",
rel: "noopener noreferrer",
...options.externalAttrs
};
let hasOpenInternalLink = false;
const handleLinkOpen = (tokens, idx, env) => {
const token = tokens[idx];
const hrefIndex = token.attrIndex("href");
if (hrefIndex < 0) {
return;
}
const hrefAttr = token.attrs[hrefIndex];
const hrefLink = hrefAttr[1];
const { base = "/", filePathRelative = null } = env;
if (isLinkExternal(hrefLink, base)) {
Object.entries(externalAttrs).forEach(
([key, val]) => token.attrSet(key, val)
);
return;
}
const internalLinkMatch = hrefLink.match(
/^([^#?]*?(?:\/|\.md|\.html))([#?].*)?$/
);
if (!internalLinkMatch) {
return;
}
const rawPath = internalLinkMatch[1];
const rawHashAndQueries = internalLinkMatch[2] || "";
const { relativePath, absolutePath } = resolvePaths(
rawPath,
base,
filePathRelative
);
if (["RouterLink", "RouteLink"].includes(internalTag)) {
token.tag = internalTag;
hrefAttr[0] = "to";
const normalizedPath = inferRoutePath(
absolutePath ? absolutePath.replace(new RegExp(`^${base}`), "/") : relativePath
);
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`;
hasOpenInternalLink = true;
} else {
const normalizedPath = inferRoutePath(absolutePath ?? relativePath);
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`;
}
;
(env.links ??= []).push({
raw: hrefLink,
relative: relativePath,
absolute: absolutePath
});
};
md.renderer.rules.link_open = (tokens, idx, options2, env, self) => {
handleLinkOpen(tokens, idx, env);
return self.renderToken(tokens, idx, options2);
};
md.renderer.rules.link_close = (tokens, idx, options2, _env, self) => {
if (hasOpenInternalLink) {
hasOpenInternalLink = false;
tokens[idx].tag = internalTag;
}
return self.renderToken(tokens, idx, options2);
};
};
// src/plugins/vPrePlugin/resolveVPre.ts
var resolveVPre = (info) => {
if (/:v-pre\b/.test(info)) {
return true;
}
if (/:no-v-pre\b/.test(info)) {
return false;
}
return null;
};
// src/plugins/vPrePlugin/vPrePlugin.ts
var vPrePlugin = (md, { inline = true, block = true } = {}) => {
const rawFence = md.renderer.rules.fence;
md.renderer.rules.fence = (...args) => {
const [tokens, idx] = args;
const token = tokens[idx];
const info = token.info ? md.utils.unescapeAll(token.info).trim() : "";
let result = rawFence(...args);
if (resolveVPre(info) ?? block) {
result = ` {
const result = rawInlineCodeRule(...args);
return ` {
const md = MarkdownIt({
...markdownItOptions,
// should always enable html option
html: true
});
if (anchor !== false) {
md.use(anchorPlugin, {
level: [1, 2, 3, 4, 5, 6],
slugify,
permalink: anchorPlugin.permalink.headerLink({
class: "header-anchor",
// Add a span inside the link so Safari shows headings in reader view.
safariReaderFix: true
}),
...anchor
});
}
if (assets !== false) {
md.use(assetsPlugin, assets);
}
if (code) {
logger2.warn(
`\`markdown.code\` option has been removed, please use '@vuepress/plugin-shiki' or '@vuepress/plugin-prismjs' instead.
See https://v2.vuepress.vuejs.org/reference/config.html#markdown-code`
);
}
if (component !== false) {
md.use(componentPlugin);
}
if (emoji !== false) {
md.use(emojiPlugin, emoji);
}
if (frontmatter !== false) {
md.use(frontmatterPlugin, {
...frontmatter,
grayMatterOptions: {
excerpt: false,
...frontmatter?.grayMatterOptions
}
});
}
if (headers !== false) {
md.use(headersPlugin, {
level: [2, 3],
slugify,
...headers
});
}
if (importCode !== false) {
md.use(importCodePlugin, importCode);
}
if (links !== false) {
md.use(linksPlugin, links);
}
if (sfc !== false) {
md.use(sfcPlugin, sfc);
}
if (toc !== false) {
md.use(tocPlugin, {
level: [2, 3],
slugify,
linkTag: "router-link",
...toc
});
}
if (title !== false) {
md.use(titlePlugin);
}
if (vPre !== false) {
md.use(vPrePlugin, vPre);
}
return md;
};
export {
anchorPlugin,
assetsPlugin,
componentPlugin,
createMarkdown,
emojiPlugin,
frontmatterPlugin,
headersPlugin,
importCodePlugin,
linksPlugin,
sfcPlugin,
titlePlugin,
tocPlugin,
vPrePlugin
};