test(extract): a section below markdown's sixth level keeps its own level in the plan
K3-21 D, red. The NISO-STS reader clips `depth` to 6 once and writes that
one value into BOTH the ATX heading, where markdown has six levels, and the
`OutlineMark` the declared route builds its plan from, where nothing clips.
On one standard 9 of 2 761 titled sections sit at depth 7; the plan read them
at 6, and `--shell-parent` gave its two depth-7 shells the ancestor one level
too high.
`sts-deep.xml` (invented setting) reproduces it: the two depth-7 shells point
at the depth-5 section on e717b1c's code and must point at the depth-6 one.
Held: the mark carries depth 7; the heading stays `######` and the extracted
headings do not move one character; the shells point at their depth-6
ancestor.
2 of 3 red on 5970369; the green one is the text guard.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
59703699a5
commit
9822e5500c
2 changed files with 109 additions and 0 deletions
26
tests/fixtures/sts-deep.xml
vendored
Normal file
26
tests/fixtures/sts-deep.xml
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<standard>
|
||||||
|
<front>
|
||||||
|
<std-meta>
|
||||||
|
<title-wrap><main>Fikstur for dyp nesting</main></title-wrap>
|
||||||
|
</std-meta>
|
||||||
|
</front>
|
||||||
|
<body>
|
||||||
|
<sec sec-type="procedure" id="d1"><label>1</label><title>Nivaa en</title>
|
||||||
|
<sec sec-type="procedure" id="d11"><label>1.1</label><title>Nivaa to</title>
|
||||||
|
<sec sec-type="procedure" id="d111"><label>1.11</label><title>Nivaa tre</title>
|
||||||
|
<sec sec-type="procedure" id="d1111"><label>1.111</label><title>Nivaa fire</title>
|
||||||
|
<sec sec-type="procedure" id="d11111"><label>1.1111</label><title>Nivaa fem</title>
|
||||||
|
<sec sec-type="spec"><label>a)</label><p>Omfatter arbeid paa femte nivaa.</p></sec>
|
||||||
|
<sec sec-type="procedure" id="d111111"><label>1.11111</label><title>Nivaa seks</title>
|
||||||
|
<sec sec-type="spec"><label>a)</label><p>Omfatter arbeid paa sjette nivaa.</p></sec>
|
||||||
|
<sec sec-type="procedure" id="d1111111"><label>1.111111</label><title>Nivaa sju foerste</title></sec>
|
||||||
|
<sec sec-type="procedure" id="d1111112"><label>1.111112</label><title>Nivaa sju andre</title></sec>
|
||||||
|
</sec>
|
||||||
|
</sec>
|
||||||
|
</sec>
|
||||||
|
</sec>
|
||||||
|
</sec>
|
||||||
|
</sec>
|
||||||
|
</body>
|
||||||
|
</standard>
|
||||||
83
tests/test_depth_seven.py
Normal file
83
tests/test_depth_seven.py
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
"""A declared section below markdown's sixth level keeps its own level in the plan.
|
||||||
|
|
||||||
|
K3-21 D. The NISO-STS reader wrote ONE clipped level into two places: the ATX
|
||||||
|
heading it emits, where markdown has six levels and the clip is the grammar's,
|
||||||
|
and the `OutlineMark` the declared route builds its plan from, where nothing
|
||||||
|
clips and the source's own depth is the point (`OutlineMark`'s docstring:
|
||||||
|
the level is what the tree declares, "reported rather than fixed up"). On one
|
||||||
|
standard 9 of 2 761 titled sections sit at depth 7, and the plan read them at
|
||||||
|
6 -- so `--shell-parent` gave its two depth-7 shells the ancestor one level
|
||||||
|
too high.
|
||||||
|
|
||||||
|
The heading stays clipped: `#######` matches nothing, and the extracted TEXT
|
||||||
|
does not move one character. Only the mark's level does.
|
||||||
|
|
||||||
|
`sts-deep.xml` is hand-written in an invented setting and carries no sentence
|
||||||
|
from any source.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from llm_ingestion_okf import extract, propose
|
||||||
|
|
||||||
|
FIXTURE = Path(__file__).parent / "fixtures" / "sts-deep.xml"
|
||||||
|
|
||||||
|
#: Every flag `okf build` turns on by default.
|
||||||
|
BUILD_DEFAULTS = dict(
|
||||||
|
outline_run=3,
|
||||||
|
table_grid=True,
|
||||||
|
unit_fold=True,
|
||||||
|
keep_table_heading=True,
|
||||||
|
sheet_section_rows=True,
|
||||||
|
drop_wrapped_outline=True,
|
||||||
|
outline_gate=True,
|
||||||
|
first_span_from_zero=True,
|
||||||
|
close_span_gaps=True,
|
||||||
|
contents_name=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
#: The extracted headings, as they were before this rule and after it.
|
||||||
|
HEADINGS = [
|
||||||
|
"# 1 Nivaa en",
|
||||||
|
"## 1.1 Nivaa to",
|
||||||
|
"### 1.11 Nivaa tre",
|
||||||
|
"#### 1.111 Nivaa fire",
|
||||||
|
"##### 1.1111 Nivaa fem",
|
||||||
|
"###### 1.11111 Nivaa seks",
|
||||||
|
"###### 1.111111 Nivaa sju foerste",
|
||||||
|
"###### 1.111112 Nivaa sju andre",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_mark_carries_the_declared_depth() -> None:
|
||||||
|
marks = extract.xml_outline(FIXTURE.name, FIXTURE.read_bytes())
|
||||||
|
assert [mark.level for mark in marks] == [1, 2, 3, 4, 5, 6, 7, 7]
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_heading_stays_markdown_and_the_text_does_not_move() -> None:
|
||||||
|
data = FIXTURE.read_bytes()
|
||||||
|
text = extract.extract_text(FIXTURE.name, data)
|
||||||
|
lines = text.split("\n")
|
||||||
|
assert [line for line in lines if line.startswith("#")] == HEADINGS
|
||||||
|
for mark in extract.xml_outline(FIXTURE.name, data):
|
||||||
|
assert lines[mark.line] == "#" * min(mark.level, 6) + " " + mark.title
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_depth_seven_shell_points_at_its_depth_six_ancestor() -> None:
|
||||||
|
data = FIXTURE.read_bytes()
|
||||||
|
text = extract.extract_text(FIXTURE.name, data)
|
||||||
|
plan = propose.build_plan(
|
||||||
|
FIXTURE,
|
||||||
|
text,
|
||||||
|
data,
|
||||||
|
okf_type="reference",
|
||||||
|
proposed_at="2026-01-01T00:00:00Z",
|
||||||
|
shell_parent=True,
|
||||||
|
**BUILD_DEFAULTS, # type: ignore[arg-type]
|
||||||
|
)
|
||||||
|
titles = {entry["segment_id"]: entry["title"] for entry in plan["entries"]}
|
||||||
|
parents = {entry["title"]: titles.get(entry.get("parent_id", "")) for entry in plan["entries"]}
|
||||||
|
assert parents["Nivaa sju foerste"] == "Nivaa seks"
|
||||||
|
assert parents["Nivaa sju andre"] == "Nivaa seks"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue