Support Anhang/Anlage targets, Inhaltsübersicht Angabe commands, and Gliederungs-Überschriften insertion/replacement
Fourth enablement wave: Anhänge/Anlagen resolve as ordinary norm targets with
nested Nummer/Buchstabe block resolution, InhaltsuebersichtAnwender applies
Angabe commands automatically, GliederungsUeberschriften handles inserting and
replacing structural headings, the law's own heading can be recast, and
FontgroessenFilter now determines body text per page instead of document-wide.
Sample data (UWG/AGG/ProdHaftG) now applies with 0 manual cases.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Change-Id: I1a76750afbecfa1aae734bcdabc91470a28420ca
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java b/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java
index fc84172..4272433 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java
@@ -30,4 +30,8 @@
public Gesetz mitGliederungen(List<Gliederung> neueGliederungen) {
return new Gesetz(jurabk, langue, kurzue, normen, neueGliederungen);
}
+
+ public Gesetz mitLangue(String neuerLangtitel) {
+ return new Gesetz(jurabk, neuerLangtitel, kurzue, normen, gliederungen);
+ }
}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Norm.java b/src/main/java/eu/mulk/aendggner/gesetz/Norm.java
index a5703ec..5f9a9fe 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/Norm.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Norm.java
@@ -35,6 +35,10 @@
return new Norm(neuerEnbez, titel, gliederung, absaetze, weggefallen);
}
+ public Norm mitGliederung(@Nullable Gliederung neueGliederung) {
+ return new Norm(enbez, titel, neueGliederung, absaetze, weggefallen);
+ }
+
public Norm alsWeggefallen() {
return new Norm(enbez, titel, gliederung, List.of(new Absatz(null, "(weggefallen)")), true);
}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java b/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java
index eef8536..00e9ef9 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java
@@ -16,7 +16,7 @@
static String flatten(Element p) {
var sb = new StringBuilder();
- flattenKinder(p, sb, 0);
+ flattenKnoten(p, sb, 0);
return normalisiere(sb.toString());
}
@@ -40,6 +40,7 @@
case "DL" -> flattenListe(element, sb, einrueckung);
case "pre" -> sb.append(element.getTextContent());
case "table" -> flattenTabelle(element, sb);
+ case "TOC" -> flattenToc(element, sb);
default -> flattenKinder(element, sb, einrueckung);
}
}
@@ -70,6 +71,45 @@
}
}
+ /**
+ * Flattet ein {@code <TOC>}-Element (Inhaltsübersicht): {@code <Ident>}/{@code <Title>}-Paare
+ * werden zu Überschriftszeilen („Teil 1 | Allgemeiner Teil“), Tabellen zu Angabe-Zeilen.
+ */
+ private static void flattenToc(Element toc, StringBuilder sb) {
+ String ident = null;
+ for (var kind = toc.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
+ if (kind.getNodeType() != Node.ELEMENT_NODE) {
+ continue;
+ }
+ var kindElement = (Element) kind;
+ switch (kindElement.getNodeName()) {
+ case "Ident" -> {
+ if (ident != null && !ident.isEmpty()) {
+ tocZeile(sb, ident);
+ }
+ ident = kindElement.getTextContent().strip();
+ }
+ case "Title" -> {
+ var titel = kindElement.getTextContent().strip();
+ tocZeile(sb, ident != null && !ident.isEmpty() ? ident + " | " + titel : titel);
+ ident = null;
+ }
+ case "table" -> flattenTabelle(kindElement, sb);
+ case "TOC" -> flattenToc(kindElement, sb);
+ default -> {}
+ }
+ }
+ if (ident != null && !ident.isEmpty()) {
+ tocZeile(sb, ident);
+ }
+ }
+
+ private static void tocZeile(StringBuilder sb, String zeile) {
+ neueZeile(sb);
+ sb.append(zeile);
+ sb.append('\n');
+ }
+
private static void flattenTabelle(Element table, StringBuilder sb) {
for (var row : alleNachkommen(table, "row")) {
var zeile = new StringBuilder();
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java b/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java
index b14ec1c..6f5b55a 100644
--- a/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java
+++ b/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java
@@ -100,7 +100,7 @@
return absaetze;
}
- for (var p : kindElemente(content, "P")) {
+ for (var p : kindElemente(content, "P", "TOC")) {
var geflattet = ContentFlattener.flatten(p).strip();
if (geflattet.isEmpty()) {
continue;
@@ -132,10 +132,11 @@
}
}
- private static Iterable<Element> kindElemente(Element parent, String name) {
+ private static Iterable<Element> kindElemente(Element parent, String... namen) {
var ergebnis = new ArrayList<Element>();
for (var kind = parent.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
- if (kind.getNodeType() == Node.ELEMENT_NODE && kind.getNodeName().equals(name)) {
+ if (kind.getNodeType() == Node.ELEMENT_NODE
+ && java.util.Arrays.asList(namen).contains(kind.getNodeName())) {
ergebnis.add((Element) kind);
}
}