|
1 | | -# -*- coding: utf-8 -*- |
2 | | -""" |
3 | | - glossary_search.py |
4 | | - ~~~~~~~~~~~~~~~~ |
| 1 | +"""Feature search results for glossary items prominently.""" |
5 | 2 |
|
6 | | - Feature search results for glossary items prominently. |
| 3 | +from __future__ import annotations |
7 | 4 |
|
8 | | - :license: Python license. |
9 | | -""" |
10 | 5 | import json |
11 | | -import os.path |
12 | | -from docutils.nodes import definition_list_item |
| 6 | +from pathlib import Path |
| 7 | +from typing import TYPE_CHECKING |
| 8 | + |
| 9 | +from docutils import nodes |
13 | 10 | from sphinx.addnodes import glossary |
14 | 11 | from sphinx.util import logging |
15 | 12 |
|
| 13 | +if TYPE_CHECKING: |
| 14 | + from sphinx.application import Sphinx |
| 15 | + from sphinx.util.typing import ExtensionMetadata |
16 | 16 |
|
17 | 17 | logger = logging.getLogger(__name__) |
18 | | -STATIC_DIR = '_static' |
19 | | -JSON = 'glossary.json' |
20 | 18 |
|
21 | 19 |
|
22 | | -def process_glossary_nodes(app, doctree, fromdocname): |
| 20 | +def process_glossary_nodes(app: Sphinx, doctree: nodes.document, _docname: str) -> None: |
23 | 21 | if app.builder.format != 'html' or app.builder.embedded: |
24 | 22 | return |
25 | 23 |
|
26 | | - terms = {} |
| 24 | + if hasattr(app.env, 'glossary_terms'): |
| 25 | + terms = app.env.glossary_terms |
| 26 | + else: |
| 27 | + terms = app.env.glossary_terms = {} |
27 | 28 |
|
28 | 29 | for node in doctree.findall(glossary): |
29 | | - for glossary_item in node.findall(definition_list_item): |
30 | | - term = glossary_item[0].astext().lower() |
31 | | - definition = glossary_item[1] |
| 30 | + for glossary_item in node.findall(nodes.definition_list_item): |
| 31 | + term = glossary_item[0].astext() |
| 32 | + definition = glossary_item[-1] |
32 | 33 |
|
33 | 34 | rendered = app.builder.render_partial(definition) |
34 | | - terms[term] = { |
35 | | - 'title': glossary_item[0].astext(), |
| 35 | + terms[term.lower()] = { |
| 36 | + 'title': term, |
36 | 37 | 'body': rendered['html_body'] |
37 | 38 | } |
38 | 39 |
|
39 | | - if hasattr(app.env, 'glossary_terms'): |
40 | | - app.env.glossary_terms.update(terms) |
41 | | - else: |
42 | | - app.env.glossary_terms = terms |
43 | 40 |
|
44 | | -def on_build_finish(app, exc): |
45 | | - if not hasattr(app.env, 'glossary_terms'): |
46 | | - return |
47 | | - if not app.env.glossary_terms: |
| 41 | +def write_glossary_json(app: Sphinx, _exc: Exception) -> None: |
| 42 | + if not getattr(app.env, 'glossary_terms', None): |
48 | 43 | return |
49 | 44 |
|
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) |
| 45 | + logger.info(f'Writing glossary.json', color='green') |
| 46 | + dest = Path(app.outdir, '_static', 'glossary.json') |
| 47 | + dest.parent.mkdir(exist_ok=True) |
| 48 | + dest.write_text(json.dumps(app.env.glossary_terms), encoding='utf-8') |
57 | 49 |
|
58 | 50 |
|
59 | | -def setup(app): |
| 51 | +def setup(app: Sphinx) -> ExtensionMetadata: |
60 | 52 | app.connect('doctree-resolved', process_glossary_nodes) |
61 | | - app.connect('build-finished', on_build_finish) |
| 53 | + app.connect('build-finished', write_glossary_json) |
62 | 54 |
|
63 | | - return {'version': '0.1', 'parallel_read_safe': True} |
| 55 | + return { |
| 56 | + 'version': '1.0', |
| 57 | + 'parallel_read_safe': True, |
| 58 | + 'parallel_write_safe': True, |
| 59 | + } |
0 commit comments