// src/markdown.ts import { slugify as defaultSlugify } from "@mdit-vue/shared"; import { logger as logger2 } from "@vuepress/utils"; import MarkdownIt from "markdown-it"; // src/plugins.ts import { componentPlugin } from "@mdit-vue/plugin-component"; import { frontmatterPlugin } from "@mdit-vue/plugin-frontmatter"; import { headersPlugin } from "@mdit-vue/plugin-headers"; import { sfcPlugin } from "@mdit-vue/plugin-sfc"; import { titlePlugin } from "@mdit-vue/plugin-title"; import { tocPlugin } from "@mdit-vue/plugin-toc"; // src/plugins/anchorPlugin.ts import { default as anchorPlugin } from "markdown-it-anchor"; // src/plugins/assetsPlugin/resolveLink.ts import { path } from "@vuepress/utils"; import { decode } from "mdurl"; var resolveLink = (link, { env, absolutePathPrependBase = false, relativePathPrefix, strict = false }) => { if (link.startsWith("data:")) return link; let resolvedLink = decode(link); const isRelativePath = strict ? ( // in strict mode, only link that starts with `./` or `../` is considered as relative path /^\.{1,2}\//.test(link) ) : ( // in non-strict mode, link that does not start with `/` and does not have protocol is considered as relative path !link.startsWith("/") && !/[A-z]+:\/\//.test(link) ); if (isRelativePath && env.filePathRelative) { resolvedLink = `${relativePathPrefix}/${path.join( path.dirname(env.filePathRelative), resolvedLink )}`; } if (absolutePathPrependBase && env.base && link.startsWith("/")) { resolvedLink = path.join(env.base, resolvedLink); } return resolvedLink; }; // src/plugins/assetsPlugin/assetsPlugin.ts var assetsPlugin = (md, { absolutePathPrependBase = false, relativePathPrefix = "@source" } = {}) => { const rawImageRule = md.renderer.rules.image; md.renderer.rules.image = (tokens, idx, options, env, self) => { const token = tokens[idx]; const link = token.attrGet("src"); if (link) { token.attrSet( "src", resolveLink(link, { env, absolutePathPrependBase, relativePathPrefix }) ); } return rawImageRule(tokens, idx, options, env, self); }; const createHtmlRule = (rawHtmlRule) => (tokens, idx, options, env, self) => { tokens[idx].content = tokens[idx].content.replace( /( `${prefix}${quote}${resolveLink(src.trim(), { env, absolutePathPrependBase, relativePathPrefix, strict: true })}${quote}` ).replace( /( `${prefix}${quote}${srcset.split(",").map( (item) => item.trim().replace( /^([^ ]*?)([ \n].*)?$/, (_2, url, descriptor = "") => `${resolveLink(url.trim(), { env, absolutePathPrependBase, relativePathPrefix, strict: true })}${descriptor.replace(/[ \n]+/g, " ").trimEnd()}` ) ).join(", ")}${quote}` ); return rawHtmlRule(tokens, idx, options, env, self); }; const rawHtmlBlockRule = md.renderer.rules.html_block; const rawHtmlInlineRule = md.renderer.rules.html_inline; md.renderer.rules.html_block = createHtmlRule(rawHtmlBlockRule); md.renderer.rules.html_inline = createHtmlRule(rawHtmlInlineRule); }; // src/plugins/emojiPlugin.ts import { full as emojiPlugin } from "markdown-it-emoji"; // src/plugins/importCodePlugin/createImportCodeBlockRule.ts import { path as path2 } from "@vuepress/utils"; var MIN_LENGTH = 9; var START_CODES = [64, 91, 99, 111, 100, 101]; var SYNTAX_RE = /^@\[code(?:{(?:(?:(?\d+)?-(?\d+)?)|(?\d+))})?(?: (?[^\]]+))?\]\((?[^)]*)\)/; 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
};