Make Glossary (mkgloss)#
Wir halten das Glossar in der Excel-Datei mkgloss.xls
und/oder der Mindmap mkgloss.mm
vor (beide Dateien lassen sich mischen).
Das vorliegende Notebook 0_mkgloss.ipynb
generiert dann daraus die Datei mkgloss_glossar.txt
,
die wir in der Markdown-Datei Glossar dann importieren. Dazu muss dieses Notebook die Datei mkgloss_glossar.txt
erzeugen, bevor diese Datei selbst compiliert wird, und also von Sphinx vor dieser Datei durchlaufen. Weil die Notebooks in alfabetischer Reihenfolge durchlaufen werden, startet der Namen dieses Notebooks mit einer 0_...
.
Installation#
das Notebook
0_mkgloss.ipynb
von dieser Seite herunterladen, in den Ordner der anderen Notebooks legen, in die Datei_toc.yml
einfügenbei Bedarf die Variablen
gloss_xls_path
etc. anpassen
Dateien:
Excel-Datei
mkgloss.xls
anlegen. Ausgewertet werden nur die zwei Spaltendt
(wie in html: definition term) unddd
(definition definition), alle anderen werden ignoriert und können anders verwendet werden.Freeplane Mindmap
mkgloss.mm
anlegen. Ausgewertet werden alle Nodes der Art:
Begriff
DEF
Definition 1
noch eine Definition
verbose = 1
gloss_xls_path = "./mkgloss.xls"
gloss_mm_path = "./mkgloss.mm"
gloss_output_path = "./mkgloss_glossar.txt"
# gloss_dict = { "definition term" : [ "Definition eins", "Definition zwei", ...] }
gloss_dict = {}
Excel einlesen#
Quelle: Eine Excel-Tabelle mit den Spalten dt
und dd
.
import pandas as pd
import os
#!pip install xlrd
if os.path.exists(gloss_xls_path):
# Wir lesen Excel als pandas dataframe ein
gloss_df = pd.read_excel(gloss_xls_path)
# und erzeugen daraus ein dict,
# siehe https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_dict.html
gloss_dictdict = gloss_df.to_dict(orient='index')
for row in gloss_dictdict.values():
dt = row["dt"]
dd = row["dd"]
if dt not in gloss_dict:
# intitialisiere key mit einer Liste von Defs, hier mit Def 1
gloss_dict[dt] = [ dd ]
else:
# dt ist als key schon da: erweitere Liste von Defs
gloss_dict[dt].append(dd)
if verbose >= 1 :
print(f"mkgloss: read {len(gloss_df['dd'])} dd from {gloss_mm_path}")
# gloss_dict
Mindmap einlesen#
Quelle: Eine freemind- oder freeplane-Mindmap, mit Teilästen der Struktur
...
Term
DEF
Definition 1
Definition 2
def get_text_from_mm_node(current):
"""returns a mindmap node's text"""
# nachschauen: ist current ein rich content Knoten mit html text?
rich_content = current.find('richcontent[@TYPE="NODE"]')
if rich_content is not None:
# html Knoteninhalt als Markdown zurückliefern
return markdownify(etree.tostring(rich_content, encoding="utf8"), heading_style="ATX")
else:
# Knoten ist Plaintext im Attribut @TEXT
return current.get("TEXT")
# das standard etree hat eine unvollständige xpath Implementierung,
# besser ist <https://lxml.de/>
from lxml import etree
# https://pypi.org/project/markdownify/
# pip install markdownify
from markdownify import markdownify
if os.path.exists(gloss_mm_path):
tree = etree.parse(gloss_mm_path)
dd_nodes = tree.xpath('//node[@TEXT="DEF"]/node')
for node in dd_nodes:
dt = get_text_from_mm_node(node.getparent().getparent())
dd = get_text_from_mm_node(node)
if dt not in gloss_dict:
gloss_dict[dt] = [ dd ]
else:
gloss_dict[dt].append(dd)
if verbose >= 1 :
print(f"mkgloss: read {len(dd_nodes)} dd from {gloss_mm_path}")
mkgloss: read 3 dd from ./mkgloss.mm
# gloss_dict
Glossar erzeugen#
sorted_gloss_dict = dict(sorted(gloss_dict.items(), key = lambda x: x[0].lower()))
if verbose >=1 :
print(sorted_gloss_dict)
{'Jupyter Notebook': ['Eine browser-basierte Entwicklungsumgebung, die Literate Programming unterstützt.'], 'Jupyterbook': ['Ein Tool, das eine Menge von Jupyter Notebooks in eine verlinkte Website und eine pdf-Datei übersetzt.'], 'Jupytext': ['Ein Plugin für Jupyter Notebooks']}
# erste Zeile unseres Glossary
gloss_md_list = [ "```{glossary}" ]
for k, v in sorted_gloss_dict.items():
v_string = "\n\n ".join(v)
gloss_entry = "\n" + k + "\n " + v_string
gloss_md_list.append(gloss_entry)
# letzte Zeile unseres Glossary
gloss_md_list.append("\n```\n")
gloss = "\n".join(gloss_md_list)
if verbose >=2 :
print(gloss)
# sorted_gloss_dict
with open(gloss_output_path, "w") as gloss_output:
gloss_output.write(gloss)
if verbose >= 1:
print(f"mkgloss: wrote {len(sorted_gloss_dict)} dt to {gloss_output_path}")
mkgloss: wrote 3 dt to ./mkgloss_glossar.txt