section_number.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- coding: utf-8 -*-
  2. """
  3. Section number plugin for Pelican
  4. ================================
  5. Adds section numbers to section titles of the article
  6. """
  7. from pelican import signals
  8. def _extract_level(text, idx):
  9. end = text.find(">", idx)
  10. if end == -1:
  11. return (idx, -1)
  12. try:
  13. level = int(text[idx: end])
  14. return (end, level)
  15. except:
  16. return (idx, -1)
  17. def _level_str(level_nums, level_max):
  18. ret = u''
  19. if len(level_nums) > level_max:
  20. return ret
  21. for n in level_nums:
  22. ret += str(n) + '.'
  23. return ret[:-1]
  24. def _insert_title_number(text, level_max):
  25. idx = 0
  26. levels = []
  27. level_nums = []
  28. while True:
  29. idx = text.find("<h", idx)
  30. if idx == -1:
  31. break
  32. (idx, level) = _extract_level(text, idx + 2)
  33. if level == -1:
  34. continue
  35. if not levels:
  36. levels += [level]
  37. level_nums += [1]
  38. elif level == levels[-1]:
  39. level_nums[-1] += 1
  40. elif level < levels[-1]:
  41. while level < levels[-1]:
  42. levels.pop()
  43. level_nums.pop()
  44. level_nums[-1] += 1
  45. else:
  46. while level > levels[-1]:
  47. levels += [levels[-1] + 1]
  48. level_nums += [1]
  49. text = text[:idx + 1] + \
  50. _level_str(level_nums, level_max) + '. ' + text[idx + 1:]
  51. # print text.encode('gb2312')
  52. return text
  53. def process_content(content):
  54. if content._content is None:
  55. return
  56. level_max = content.settings.get('SECTION_NUMBER_MAX', 3)
  57. if level_max <= 0:
  58. return
  59. content._content = _insert_title_number(content._content, level_max)
  60. def register():
  61. signals.content_object_init.connect(process_content)