markdownToVue.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.createMarkdownToVueRenderFn = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const gray_matter_1 = __importDefault(require("gray-matter"));
  9. const lru_cache_1 = __importDefault(require("lru-cache"));
  10. const markdown_1 = require("./markdown/markdown");
  11. const parseHeader_1 = require("./utils/parseHeader");
  12. const debug = require('debug')('vitepress:md');
  13. const cache = new lru_cache_1.default({ max: 1024 });
  14. function createMarkdownToVueRenderFn(root, options = {}) {
  15. const md = markdown_1.createMarkdownRenderer(options);
  16. return (src, file, lastUpdated, injectData = true) => {
  17. file = path_1.default.relative(root, file);
  18. const cached = cache.get(src);
  19. if (cached) {
  20. debug(`[cache hit] ${file}`);
  21. return cached;
  22. }
  23. const start = Date.now();
  24. const { content, data: frontmatter } = gray_matter_1.default(src);
  25. const { html, data } = md.render(content);
  26. // TODO validate data.links?
  27. // inject page data
  28. const pageData = {
  29. title: inferTitle(frontmatter, content),
  30. frontmatter,
  31. headers: data.headers,
  32. relativePath: file.replace(/\\/g, '/'),
  33. lastUpdated
  34. };
  35. const additionalBlocks = injectData
  36. ? injectPageData(data.hoistedTags || [], pageData)
  37. : data.hoistedTags || [];
  38. const vueSrc = additionalBlocks.join('\n') + `\n<template><div>${html}</div></template>`;
  39. debug(`[render] ${file} in ${Date.now() - start}ms.`);
  40. const result = { vueSrc, pageData };
  41. cache.set(src, result);
  42. return result;
  43. };
  44. }
  45. exports.createMarkdownToVueRenderFn = createMarkdownToVueRenderFn;
  46. const scriptRE = /<\/script>/;
  47. const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
  48. const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/;
  49. function injectPageData(tags, data) {
  50. const code = `\nexport const __pageData = ${JSON.stringify(JSON.stringify(data))}`;
  51. const existingScriptIndex = tags.findIndex((tag) => scriptRE.test(tag));
  52. if (existingScriptIndex > -1) {
  53. const tagSrc = tags[existingScriptIndex];
  54. // user has <script> tag inside markdown
  55. // if it doesn't have export default it will error out on build
  56. const hasDefaultExport = defaultExportRE.test(tagSrc) || namedDefaultExportRE.test(tagSrc);
  57. tags[existingScriptIndex] = tagSrc.replace(scriptRE, code + (hasDefaultExport ? `` : `\nexport default{}\n`) + `</script>`);
  58. }
  59. else {
  60. tags.push(`<script>${code}\nexport default {}</script>`);
  61. }
  62. return tags;
  63. }
  64. const inferTitle = (frontmatter, content) => {
  65. if (frontmatter.home) {
  66. return 'Home';
  67. }
  68. if (frontmatter.title) {
  69. return parseHeader_1.deeplyParseHeader(frontmatter.title);
  70. }
  71. const match = content.match(/^\s*#+\s+(.*)/m);
  72. if (match) {
  73. return parseHeader_1.deeplyParseHeader(match[1].trim());
  74. }
  75. return '';
  76. };
  77. //# sourceMappingURL=markdownToVue.js.map