glossary.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. """
  2. Builds a glossary page containing definition lists found in articles
  3. and pages, and adds a `definitions` variable visible to all page templates.
  4. """
  5. import bs4
  6. from pelican import signals
  7. class Definitions():
  8. definitions = []
  9. exclude = []
  10. def make_title(def_title):
  11. return def_title.text
  12. def make_def(def_title):
  13. return ''.join(str(t) for t in def_title.find_next('dd').contents)
  14. def make_anchor(def_title):
  15. return def_title.text.lower().replace(' ', '-')
  16. def set_definitions(generator, metadata):
  17. generator.context['definitions'] = Definitions.definitions
  18. def get_excludes(pelican):
  19. Definitions.exclude = pelican.settings.get('GLOSSARY_EXCLUDE', [])
  20. def parse_content(content):
  21. soup = bs4.BeautifulSoup(content._content, 'html.parser')
  22. for def_list in soup.find_all('dl'):
  23. defns = []
  24. for def_title in def_list.find_all('dt'):
  25. if def_title.text not in Definitions.exclude:
  26. anchor_name = make_anchor(def_title)
  27. anchor_tag = bs4.Tag(name="a", attrs={'name': anchor_name})
  28. index = def_list.parent.index(def_list)-1
  29. def_list.parent.insert(index, anchor_tag)
  30. defns.append(
  31. {'title': make_title(def_title),
  32. 'definition': make_def(def_title),
  33. 'anchor': anchor_name,
  34. 'source': content})
  35. for defn in defns:
  36. defn['see_also'] = [d for d in defns if d is not defn]
  37. Definitions.definitions += defns
  38. content._content = str(soup)
  39. def parse_articles(generator):
  40. for article in generator.articles:
  41. parse_content(article)
  42. def register():
  43. signals.initialized.connect(get_excludes)
  44. signals.article_generator_finalized.connect(parse_articles)
  45. signals.page_generator_context.connect(set_definitions)