index.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. const loaderUtils = require('loader-utils'); //:loader-utils 是一个npm i loader-utils -D 安装的插件,便于获取webpack.config.js 中配置loader的options;
  2. const MarkdownIt = require('markdown-it'); //渲染 markdown 基本语法
  3. const markdownItAnchor = require('markdown-it-anchor'); //为各级标题添加锚点
  4. const frontMatter = require('front-matter'); //就是md文档最上面的内容 类似于docz中的路由/标题的设置部分
  5. const highlight = require('./highlight');
  6. const linkOpen = require('./link-open');
  7. const cardWrapper = require('./card-wrapper');
  8. const codeWrapper = require('./code-wrapper');
  9. const { slugify } = require('transliteration');
  10. function wrapper(content) {
  11. content = cardWrapper(content);
  12. content = codeWrapper(content);
  13. content = escape(content);
  14. return `
  15. import { h } from 'vue';
  16. const content = unescape(\`${content}\`);
  17. export default {
  18. mounted() {
  19. const anchors = [].slice.call(this.$el.querySelectorAll('h2, h3, h4, h5'));
  20. anchors.forEach(anchor => {
  21. anchor.addEventListener('click', this.scrollToAnchor);
  22. });
  23. },
  24. methods: {
  25. scrollToAnchor(event) {
  26. if (event.target.id) {
  27. this.$router.push({
  28. path: this.$route.path,
  29. hash: '#'+event.target.id
  30. })
  31. }
  32. }
  33. },
  34. render() {
  35. return h('section', { innerHTML: content });
  36. }
  37. };
  38. `;
  39. }
  40. const parser = new MarkdownIt({
  41. html: true,
  42. linkify: true,
  43. highlight
  44. }).use(markdownItAnchor, {
  45. level: 2, // 添加超链接锚点的最小标题级别, 如: #标题 不会添加锚点
  46. slugify // 自定义slugify, 我们使用的是将中文转为汉语拼音,最终生成为标题id属性
  47. });
  48. module.exports = function(source) {
  49. let options = loaderUtils.getOptions(this) || {}; // 获取loader的参数
  50. this.cacheable && this.cacheable();
  51. options = {
  52. wrapper,
  53. linkOpen: true,
  54. ...options
  55. };
  56. let fm;
  57. if (options.enableMetaData) {
  58. fm = frontMatter(source);
  59. source = fm.body;
  60. }
  61. if (options.linkOpen) {
  62. linkOpen(parser);
  63. }
  64. return options.wrapper(parser.render(source), fm);
  65. };