index.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 { slugify } = require('transliteration');
  9. function wrapper(content) {
  10. content = cardWrapper(content);
  11. content = escape(content);
  12. return `
  13. import { h } from 'vue';
  14. const content = unescape(\`${content}\`);
  15. export default {
  16. mounted() {
  17. const anchors = [].slice.call(this.$el.querySelectorAll('h2, h3, h4, h5'));
  18. anchors.forEach(anchor => {
  19. anchor.addEventListener('click', this.scrollToAnchor);
  20. });
  21. },
  22. methods: {
  23. scrollToAnchor(event) {
  24. if (event.target.id) {
  25. this.$router.push({
  26. path: this.$route.path,
  27. hash: '#'+event.target.id
  28. })
  29. }
  30. }
  31. },
  32. render() {
  33. return h('section', { innerHTML: content });
  34. }
  35. };
  36. `;
  37. }
  38. const parser = new MarkdownIt({
  39. html: true,
  40. linkify: true,
  41. highlight
  42. }).use(markdownItAnchor, {
  43. level: 2, // 添加超链接锚点的最小标题级别, 如: #标题 不会添加锚点
  44. slugify // 自定义slugify, 我们使用的是将中文转为汉语拼音,最终生成为标题id属性
  45. });
  46. module.exports = function(source) {
  47. let options = loaderUtils.getOptions(this) || {}; // 获取loader的参数
  48. this.cacheable && this.cacheable();
  49. options = {
  50. wrapper,
  51. linkOpen: true,
  52. ...options
  53. };
  54. let fm;
  55. if (options.enableMetaData) {
  56. fm = frontMatter(source);
  57. source = fm.body;
  58. }
  59. if (options.linkOpen) {
  60. linkOpen(parser);
  61. }
  62. return options.wrapper(parser.render(source), fm);
  63. };