source: rtems-central/rtemsqual/glossary.py @ 05246b3

Last change on this file since 05246b3 was 99c6449, checked in by Sebastian Huber <sebastian.huber@…>, on 05/09/20 at 15:45:46

content: Change gap after indent

  • Property mode set to 100644
File size: 5.5 KB
RevLine 
[c0ac12a]1# SPDX-License-Identifier: BSD-2-Clause
2""" This module provides functions for glossary of terms generation. """
3
4# Copyright (C) 2019, 2020 embedded brains GmbH (http://www.embedded-brains.de)
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26
27import glob
28import re
[a5f3cc1]29from typing import Any, Dict, Optional
[c0ac12a]30
[a5f3cc1]31from rtemsqual.content import SphinxContent, SphinxMapper
32from rtemsqual.items import Item, ItemCache, ItemMapper
[c0ac12a]33
34ItemMap = Dict[str, Item]
35
36
37def _gather_glossary_groups(item: Item, glossary_groups: ItemMap) -> None:
[9dad293]38    for child in item.children():
[c0ac12a]39        _gather_glossary_groups(child, glossary_groups)
40    if item["type"] == "glossary" and item["glossary-type"] == "group":
41        glossary_groups[item.uid] = item
42
43
44def _gather_glossary_terms(item: Item, glossary_terms: ItemMap) -> None:
[9dad293]45    for child in item.children():
[c0ac12a]46        _gather_glossary_terms(child, glossary_terms)
47    if item["type"] == "glossary" and item["glossary-type"] == "term":
48        glossary_terms[item.uid] = item
49
50
51def _generate_glossary_content(terms: ItemMap) -> SphinxContent:
52    content = SphinxContent()
53    content.add_header("Glossary", level="*")
[520ba1dd]54    content.add(".. glossary::")
55    with content.indent():
[99c6449]56        content.add(":sorted:")
57        for item in sorted(terms.values(),
58                           key=lambda x: x["glossary-term"].lower()):
59            content.register_license_and_copyrights_of_item(item)
[a5f3cc1]60            text = SphinxMapper(item).substitute(item["text"])
[520ba1dd]61            content.add_definition_item(item["glossary-term"], text)
[c0ac12a]62    content.add_licence_and_copyrights()
63    return content
64
65
66def _make_glossary_term_uid(term: str) -> str:
[71d8b3c]67    return "/glos/term/" + re.sub(r"[^a-zA-Z0-9]+", "", term.replace(
68        "+", "X")).lower()
[c0ac12a]69
70
71def _find_glossary_terms(path: str, document_terms: ItemMap,
72                         project_terms: ItemMap) -> None:
73    for src in glob.glob(path + "/**/*.rst", recursive=True):
74        if src.endswith("glossary.rst"):
75            continue
76        with open(src, "r") as out:
77            for term in re.findall(":term:`([^`]+)`", out.read()):
78                uid = _make_glossary_term_uid(term)
79                document_terms[uid] = project_terms[uid]
80
81
[a5f3cc1]82class _GlossaryMapper(ItemMapper):
83    def __init__(self, item: Item, document_terms: ItemMap):
84        super().__init__(item)
85        self._document_terms = document_terms
[c0ac12a]86
[a5f3cc1]87    def get_value(self, item: Item, _path: str, _value: Any, key: str,
88                  _index: Optional[int]) -> Any:
89        """ Recursively adds glossary terms to the document terms. """
90        if key == "glossary-term":
91            if item.uid not in self._document_terms:
92                self._document_terms[item.uid] = item
93                _GlossaryMapper(item,
94                                self._document_terms).substitute(item["text"])
95        # The value of this substitute is unused.
96        return ""
[c0ac12a]97
[a5f3cc1]98
99def _resolve_glossary_terms(document_terms: ItemMap) -> None:
[c0ac12a]100    for term in list(document_terms.values()):
[a5f3cc1]101        _GlossaryMapper(term, document_terms).substitute(term["text"])
[c0ac12a]102
103
104def _generate_project_glossary(target: str, project_terms: ItemMap) -> None:
[a4e08c5]105    content = _generate_glossary_content(project_terms)
106    content.write(target)
[c0ac12a]107
108
109def _generate_document_glossary(config: dict, project_terms: ItemMap) -> None:
110    document_terms = {}  # type: ItemMap
111    for path in config["rest-source-paths"]:
112        _find_glossary_terms(path, document_terms, project_terms)
[a5f3cc1]113    _resolve_glossary_terms(document_terms)
[c0ac12a]114    content = _generate_glossary_content(document_terms)
115    content.write(config["target"])
116
117
118def generate(config: dict, item_cache: ItemCache) -> None:
119    """
120    Generates glossaries of terms according to the configuration.
121
122    :param config: A dictionary with configuration entries.
123    :param item_cache: The specification item cache containing the glossary
124                       groups and terms.
125    """
126    groups = {}  # type: ItemMap
127    for item in item_cache.top_level.values():
128        _gather_glossary_groups(item, groups)
129
130    project_terms = {}  # type: ItemMap
131    for group in config["project-groups"]:
132        _gather_glossary_terms(groups[group], project_terms)
133
134    _generate_project_glossary(config["project-target"], project_terms)
135
136    for document_config in config["documents"]:
137        _generate_document_glossary(document_config, project_terms)
Note: See TracBrowser for help on using the repository browser.