[PATCH 2/4] common: Add script to generate glossary

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Jan 7 14:29:40 UTC 2020


Update #3853.
---
 common/glossary.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)
 create mode 100755 common/glossary.py

diff --git a/common/glossary.py b/common/glossary.py
new file mode 100755
index 0000000..1353853
--- /dev/null
+++ b/common/glossary.py
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (C) 2020 embedded brains GmbH
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+import re
+
+class Term(object):
+    terms = {}
+
+    def __init__(self, terms, definition):
+        self.terms = terms
+        self.definition = definition
+        for t in terms:
+            Term.terms[t] = self
+
+    def __cmp__(self, other):
+        for t in other.terms:
+            if t in self.terms:
+                return 0
+        if self.terms[0].lower() < other.terms[0].lower():
+            return -1
+        return 1
+
+    def __hash__(self):
+        return hash(self.terms[0])
+
+    def __str__(self):
+        return "   " + "\n   ".join(self.terms) + "\n" + self.definition
+
+class State(object):
+    def next(self, line):
+        assert 0
+
+class GlossaryTermDefinition(State):
+    def __init__(self, indent, term):
+        self.indent = indent
+        self.terms = [term]
+        self.definition = ""
+
+    def next(self, line):
+        m = re.search("^\\s{" + "{}".format(self.indent) + "}(\\w.*)$", line)
+        if m:
+            self.terms.append(m.group(1))
+            return self
+        m = re.search(r"^\s+(.+)$", line)
+        if m:
+            self.definition += line
+            return self
+        m = re.search(r"^\s*$", line)
+        if m:
+            Term(self.terms, self.definition)
+            return GlossaryTerm()
+        raise Exception("unexpected term definition: {}".format(line))
+
+class GlossaryTerm(State):
+    def next(self, line):
+        m = re.search(r"^(\s+)(.*)$", line)
+        if m:
+            return GlossaryTermDefinition(len(m.group(1)), m.group(2))
+        m = re.search(r"^\s*$", line)
+        if m:
+            return self
+        raise Exception("unexpected term: {}".format(line))
+
+class GlossaryOptions(State):
+    def next(self, line):
+        m = re.search(r"^\s+:", line)
+        if m:
+            return self
+        m = re.search(r"^\s*$", line)
+        if m:
+            return GlossaryTerm()
+        raise Exception("unexpected glossary option: {}".format(line))
+
+class GlossaryInitial(State):
+    def next(self, line):
+        if line.strip() == ".. glossary::":
+            return GlossaryOptions()
+        return self
+
+def cmd_regenerate(ctx):
+    with open(ctx.path.abspath() + "/../c-user/glossary.rst", "r") as f:
+        s = GlossaryInitial()
+        for line in f:
+            s = s.next(line)
+    terms = set()
+    for src in ctx.path.ant_glob("**/*.rst"):
+        if src.abspath().endswith("glossary.rst"):
+            continue
+        for t in re.findall(":term:`[^`]+`", src.read()):
+            term = re.search("`([^`]+)`", re.sub("\s+", " ", t)).group(1)
+            terms.add(Term.terms[term])
+    c = ".. SPDX-License-Identifier: CC-BY-SA-4.0\n\n"
+    c += ".. Automatically generated by \"./waf regenerate\"\n\n"
+    c += "Glossary\n********\n\n"
+    c += ".. glossary::\n   :sorted:\n\n"
+    for t in sorted(terms):
+        c += str(t)
+    g = ctx.path.make_node("glossary.rst")
+    g.write(c)
-- 
2.16.4



More information about the devel mailing list