toc.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. 'use strict';
  2. let cheerio;
  3. const escape = require('lodash/escape');
  4. function tocHelper(str, options = {}) {
  5. if (!cheerio) cheerio = require('cheerio');
  6. const $ = cheerio.load(str);
  7. const headingsMaxDepth = options.hasOwnProperty('max_depth') ? options.max_depth : 6;
  8. const headingsSelector = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].slice(0, headingsMaxDepth).join(',');
  9. const headings = $(headingsSelector);
  10. if (!headings.length) return '';
  11. const className = options.class || 'toc';
  12. const listNumber = options.hasOwnProperty('list_number') ? options.list_number : true;
  13. let result = `<ol class="${className}">`;
  14. const lastNumber = [0, 0, 0, 0, 0, 0];
  15. let firstLevel = 0;
  16. let lastLevel = 0;
  17. let i = 0;
  18. headings.each(function() {
  19. const level = +this.name[1];
  20. const id = $(this).attr('id');
  21. const text = escape($(this).text());
  22. lastNumber[level - 1]++;
  23. for (i = level; i <= 5; i++) {
  24. lastNumber[i] = 0;
  25. }
  26. if (firstLevel) {
  27. for (i = level; i < lastLevel; i++) {
  28. result += '</li></ol>';
  29. }
  30. if (level > lastLevel) {
  31. result += `<ol class="${className}-child">`;
  32. } else {
  33. result += '</li>';
  34. }
  35. } else {
  36. firstLevel = level;
  37. }
  38. result += `<li class="${className}-item ${className}-level-${level}">`;
  39. result += `<a class="${className}-link" href="#${id}">`;
  40. if (listNumber) {
  41. result += `<span class="${className}-number">`;
  42. for (i = firstLevel - 1; i < level; i++) {
  43. result += `${lastNumber[i]}.`;
  44. }
  45. result += '</span> ';
  46. }
  47. result += `<span class="${className}-text">${text}</span></a>`;
  48. lastLevel = level;
  49. });
  50. for (i = firstLevel - 1; i < lastLevel; i++) {
  51. result += '</li></ol>';
  52. }
  53. return result;
  54. }
  55. module.exports = tocHelper;