toc.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict';
  2. const { tocObj, escapeHTML, encodeURL } = require('hexo-util');
  3. function tocHelper(str, options = {}) {
  4. options = Object.assign({
  5. min_depth: 1,
  6. max_depth: 6,
  7. class: 'toc',
  8. list_number: true
  9. }, options);
  10. const data = tocObj(str, { min_depth: options.min_depth, max_depth: options.max_depth });
  11. if (!data.length) return '';
  12. const className = escapeHTML(options.class);
  13. const listNumber = options.list_number;
  14. let result = `<ol class="${className}">`;
  15. const lastNumber = [0, 0, 0, 0, 0, 0];
  16. let firstLevel = 0;
  17. let lastLevel = 0;
  18. for (let i = 0, len = data.length; i < len; i++) {
  19. const el = data[i];
  20. const { level, id, text } = el;
  21. const href = id ? `#${encodeURL(id)}` : null;
  22. lastNumber[level - 1]++;
  23. for (let i = level; i <= 5; i++) {
  24. lastNumber[i] = 0;
  25. }
  26. if (firstLevel) {
  27. for (let 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. if (href) {
  40. result += `<a class="${className}-link" href="${href}">`;
  41. } else {
  42. result += `<a class="${className}-link">`;
  43. }
  44. if (listNumber) {
  45. result += `<span class="${className}-number">`;
  46. for (let i = firstLevel - 1; i < level; i++) {
  47. result += `${lastNumber[i]}.`;
  48. }
  49. result += '</span> ';
  50. }
  51. result += `<span class="${className}-text">${text}</span></a>`;
  52. lastLevel = level;
  53. }
  54. for (let i = firstLevel - 1; i < lastLevel; i++) {
  55. result += '</li></ol>';
  56. }
  57. return result;
  58. }
  59. module.exports = tocHelper;