• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: utf-8 -*-
2"""
3    glossary_search.py
4    ~~~~~~~~~~~~~~~~
5
6    Feature search results for glossary items prominently.
7
8    :license: Python license.
9"""
10import json
11import os.path
12from docutils.nodes import definition_list_item
13from sphinx.addnodes import glossary
14from sphinx.util import logging
15
16
17logger = logging.getLogger(__name__)
18STATIC_DIR = '_static'
19JSON = 'glossary.json'
20
21
22def process_glossary_nodes(app, doctree, fromdocname):
23    if app.builder.format != 'html':
24        return
25
26    terms = {}
27
28    for node in doctree.traverse(glossary):
29        for glossary_item in node.traverse(definition_list_item):
30            term = glossary_item[0].astext().lower()
31            definition = glossary_item[1]
32
33            rendered = app.builder.render_partial(definition)
34            terms[term] = {
35                'title': glossary_item[0].astext(),
36                'body': rendered['html_body']
37            }
38
39    if hasattr(app.env, 'glossary_terms'):
40        app.env.glossary_terms.update(terms)
41    else:
42        app.env.glossary_terms = terms
43
44def on_build_finish(app, exc):
45    if not hasattr(app.env, 'glossary_terms'):
46        return
47    if not app.env.glossary_terms:
48        return
49
50    logger.info(f'Writing {JSON}', color='green')
51
52    dest_dir = os.path.join(app.outdir, STATIC_DIR)
53    os.makedirs(dest_dir, exist_ok=True)
54
55    with open(os.path.join(dest_dir, JSON), 'w') as f:
56        json.dump(app.env.glossary_terms, f)
57
58
59def setup(app):
60    app.connect('doctree-resolved', process_glossary_nodes)
61    app.connect('build-finished', on_build_finish)
62
63    return {'version': '0.1', 'parallel_read_safe': True}
64