|
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