diff options
| author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-25 22:55:02 +0200 |
|---|---|---|
| committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-25 22:55:02 +0200 |
| commit | a231681883935e0bee2f453b2a4ef3d798ed3534 (patch) | |
| tree | d7cff50c1dd9b70709e1d06a3a72507cd5bbbe51 /src/main | |
| parent | 20d8b08492bea77f42d019af5db66ef184f105b3 (diff) | |
Wer verweist, wird gelesen, auch wenn ihm nicht gefolgt wird
„Die Inhaltsübersicht wird entsprechend der vorstehenden Nummer 8 Buchst. a
geändert.“ Ein Befehl, der seinen Inhalt nicht nennt, sondern auf einen anderen
Punkt desselben Artikels verweist. Er galt bislang als nicht erkannt.
Zwei Prüfungen haben ergeben, dass die naheliegende Abhilfe nicht trägt. Die
Inhaltsübersicht wird nicht selbsttätig mitgeführt — der Anwender rührt sie bei
einer Umnummerierung oder Neufassung nicht an —, und das rheinland-pfälzische
Stammgesetz führt überhaupt keine Inhaltsübersicht. Den Befehl als „bereits
bewirkt“ zu quittieren wäre also aktenwidrig; ihn auszuführen verlangte, dass der
Anwender die Befehlsliste zurückliest und das Ziel umdeutet („Überschrift des
§ 13“ wird zur Titelspalte einer Übersichtszeile). Das ist ein eigenes Vorhaben.
Er wird deshalb gelesen und ausdrücklich als Grenze gerügt. Der Unterschied ist
kein kosmetischer: Der Rest wandert von „Befehl nicht erkannt“ zu „Nicht
unterstützt“ und damit in die Gruppe, die das Handbuch für die bewusst gezogenen
Grenzen führt. Die Synopse sagt fortan, dass hier das Erzeugnis die Grenze zieht,
und nennt dabei den Verweis; sie sagt nicht mehr, die Vorlage sei
unverständlich. Das Muster ist auf den ganzen Satz verankert, damit ein bloß
adverbiales „entsprechend“ nicht mitgerissen wird.
Damit sind sämtliche 23 Befehle des rheinland-pfälzischen Heftes erschlossen.
Geprüft: 388 Tests (zuvor 386).
Change-Id: I70d5ac52676310bf9bc2c95ab921bd74155a16b7
Diffstat (limited to 'src/main')
3 files changed, 50 insertions, 0 deletions
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java index 47bca25..3138eeb 100644 --- a/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java +++ b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java @@ -239,4 +239,19 @@ public sealed interface Aenderungsbefehl { /** Fallback für alles, was der Parser nicht versteht — muss manuell geprüft werden. */ record UnbekannterBefehl(Stelle stelle, String originalText, Provenienz provenienz) implements Aenderungsbefehl {} + + /** + * „Die Inhaltsübersicht wird entsprechend der vorstehenden Nummer 8 Buchst. a geändert.“ + * + * <p>Ein Befehl, der seinen Inhalt nicht selbst nennt, sondern auf einen anderen Punkt desselben + * Artikels verweist. Er wird erkannt, aber nicht angewandt: Die sinngemäße Übertragung setzte + * voraus, dass der Anwender die Befehlsliste zurückliest und das Ziel umdeutet („Überschrift des + * § 13“ → Titelspalte der Übersichtszeile). Erkannt zu werden ist gleichwohl mehr als gar nichts + * — die Rüge sagt dann, dass das Erzeugnis die Grenze zieht, und nicht, dass die Vorlage + * unverständlich sei. + * + * @param verweis der Wortlaut der Verweisung („Nummer 8 Buchst. a“). + */ + record VerweisenderBefehl(Stelle stelle, String verweis, Provenienz provenienz) + implements Aenderungsbefehl {} } diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java index ef49b7b..f1cece5 100644 --- a/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java +++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java @@ -17,6 +17,7 @@ import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Streichung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturErsetzung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Umnummerierung; +import eu.mulk.aendggner.aenderung.Aenderungsbefehl.VerweisenderBefehl; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WoerterEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortlautVoranstellung; @@ -520,6 +521,15 @@ final class BefehlErkenner { private static final Pattern HALBSATZ = Pattern.compile("Halbsatz(?: \\d+[a-z]?)?"); + // „Die Inhaltsübersicht wird entsprechend der vorstehenden Nummer 8 Buchst. a geändert.“ — ein + // Befehl, der seinen Inhalt nicht nennt, sondern auf einen anderen Punkt verweist. Verankert auf + // den ganzen Satz, damit ein bloß adverbiales „entsprechend“ nicht mitgerissen wird; ohne + // verschachtelte Quantoren und daher für die Mustersuche kostenneutral. + private static final Pattern VERWEISENDE_AENDERUNG = + Pattern.compile( + "^Die Inhaltsübersicht wird entsprechend (?:der|dem) " + + "(?:vorstehenden |vorgenannten |nachstehenden )?(.+?) geändert\\.$"); + private static final Pattern EBENE_BEZEICHNUNG = Pattern.compile( "^(?:(?:§|Art\\.) (\\d+[a-z]?)|(?:Absatz|Abs\\.) (\\d+[a-z]?)|Satz(?: (\\d+[a-z]?))?|Sätze" @@ -880,6 +890,13 @@ final class BefehlErkenner { Matcher m; + // Die Verweisung auf einen anderen Punkt desselben Artikels. Sie steht ganz vorn, weil sie + // den vollen Satz beansprucht und sonst von der Neufassung an sich gezogen würde. + if ((m = VERWEISENDE_AENDERUNG.matcher(text)).matches()) { + return Optional.of( + new VerweisenderBefehl(mitInhaltsuebersicht(kontext), m.group(1).strip(), provenienz)); + } + // Inhaltsübersichts-Angaben zuerst prüfen, bevor NEUFASSUNG/STRUKTUR_ERSETZUNG die Phrase // strukturell (aber mit unparsbarer Stelle) an sich ziehen. if ((m = INHALTSUEBERSICHT_ANGABE.matcher(text)).matches()) { diff --git a/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java index 64c6564..8d9b7e7 100644 --- a/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java +++ b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java @@ -18,6 +18,7 @@ import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturErsetzung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Umnummerierung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.UnbekannterBefehl; +import eu.mulk.aendggner.aenderung.Aenderungsbefehl.VerweisenderBefehl; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WoerterEinfuegung; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker; import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortlautVoranstellung; @@ -667,6 +668,20 @@ public final class BefehlAnwender { if (befehl instanceof UnbekannterBefehl) { return manuell(befehl, Grund.NICHT_ERKANNT, "Befehl nicht erkannt."); } + // Gelesen, aber bewusst nicht ausgeführt. Die Weiche steht vor der Inhaltsübersichts-Weiche, + // damit die Rüge den Verweis nennt und nicht bloß die allgemeine Grenze jener Norm: Die + // sinngemäße Übertragung eines anderen Punktes setzte einen Rückgriff auf die Befehlsliste und + // eine Umdeutung des Ziels voraus („Überschrift des § 13“ → Titelspalte der Übersichtszeile), + // die dieser Anwender nicht leistet. Sie zu erraten wäre schlimmer, als sie zu benennen. + if (befehl instanceof VerweisenderBefehl v) { + return manuell( + befehl, + Grund.NICHT_UNTERSTUETZT, + "Der Befehl verweist auf „" + + v.verweis() + + "“ desselben Artikels; die sinngemäße Übertragung auf die Inhaltsübersicht ist" + + " nicht umgesetzt."); + } // Sammelbefehle vor den Spezialweichen dispatchen (jeder Teil wird einzeln geroutet). if (befehl instanceof Sammelbefehl s) { return wendeSammelAn(normen, gliederungen, s); @@ -724,6 +739,9 @@ public final class BefehlAnwender { wendeGliederungsUeberschriftenAn(normen, gliederungen, g); case Sammelbefehl s -> wendeSammelAn(normen, gliederungen, s); case UnbekannterBefehl u -> manuell(befehl, Grund.NICHT_ERKANNT, "Befehl nicht erkannt."); + // Oben abgefangen; die Weiche muss ihn gleichwohl kennen. + case VerweisenderBefehl v -> + manuell(befehl, Grund.NICHT_UNTERSTUETZT, "Verweisender Befehl."); }; } catch (RuntimeException e) { return manuell(befehl, Grund.FEHLGESCHLAGEN, "Anwendung fehlgeschlagen: " + e); |
