[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