fix: my own gate was forcing sections to open on "4."
The clinical view of an article was often one numbered list running from the presenting complaint to discharge. Splitting it into Clinical paths / Diagnosis / Management necessarily divides that list — and because the validator required every numeric token to survive, the restructure kept the original numbering. Sections opened on "2." and "4.". The "3." of a list item is a position, not a fact. It is stripped before numbers are compared, so a restructure is free to renumber; and import renumbers every section's lists from 1 regardless, per indentation level, so a nested list counts independently of its parent. A blank line between items is a loose list, not a new one, and does not reset it. 25 sections across 16 of the 54 already applied were repaired in place. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
This commit is contained in:
parent
3b45eaf3a6
commit
a9969d8d90
1 changed files with 43 additions and 2 deletions
|
|
@ -44,6 +44,44 @@ REQUIRED = MDM_SECTIONS[:3]
|
|||
|
||||
MARKER = re.compile(r"\[\[(\d+)\|")
|
||||
NUMBER = re.compile(r"\d+(?:\.\d+)?")
|
||||
#: The "3." that opens an ordered-list item. It is a position in a list, not a
|
||||
#: fact, and it necessarily changes when a list is split across sections — so
|
||||
#: it is stripped before the numbers are compared. Requiring it to survive made
|
||||
#: the first pass keep the original numbering, which left sections opening on
|
||||
#: "2." and "4." because the list they came from had been divided.
|
||||
LIST_MARKER = re.compile(r"^(\s*)\d+([.)])(\s)", re.M)
|
||||
|
||||
|
||||
def facts_only(text: str) -> str:
|
||||
"""The text with ordered-list numbering removed, for comparing numbers."""
|
||||
return LIST_MARKER.sub(r"\1\2\3", text)
|
||||
|
||||
|
||||
def renumber(text: str) -> str:
|
||||
"""Number every ordered-list item in this section from 1.
|
||||
|
||||
A list split across two sections leaves the second starting wherever the
|
||||
first stopped — "2. Blood cultures" opening the Diagnosis section. Counting
|
||||
is per indentation level, so a nested list is numbered independently of its
|
||||
parent, and nothing else resets it: a blank line between items is a loose
|
||||
list, not a new one, and prose in between does not restart the count.
|
||||
"""
|
||||
counters: dict[int, int] = {}
|
||||
out = []
|
||||
for line in text.split("\n"):
|
||||
match = re.match(r"^(\s*)(\d+)([.)])(\s.*)$", line)
|
||||
if not match:
|
||||
out.append(line)
|
||||
continue
|
||||
indent, _was, dot, rest = match.groups()
|
||||
depth = len(indent)
|
||||
for deeper in [level for level in counters if level > depth]:
|
||||
del counters[deeper]
|
||||
counters[depth] = counters.get(depth, 0) + 1
|
||||
out.append(f"{indent}{counters[depth]}{dot}{rest}")
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
MIN_RATIO, MAX_RATIO = 0.75, 1.35
|
||||
|
||||
|
||||
|
|
@ -94,7 +132,8 @@ def validate(before: list[dict], after: list[dict]) -> list[str]:
|
|||
if want != got:
|
||||
problems.append(f"cross-references changed (lost {sorted(set(want) - set(got)) or '-'}, "
|
||||
f"added {sorted(set(got) - set(want)) or '-'})")
|
||||
want_n, got_n = sorted(NUMBER.findall(old_text)), sorted(NUMBER.findall(new_text))
|
||||
want_n = sorted(NUMBER.findall(facts_only(old_text)))
|
||||
got_n = sorted(NUMBER.findall(facts_only(new_text)))
|
||||
if want_n != got_n:
|
||||
problems.append(f"numbers changed (lost {sorted(set(want_n) - set(got_n)) or '-'}, "
|
||||
f"added {sorted(set(got_n) - set(want_n)) or '-'})")
|
||||
|
|
@ -172,7 +211,9 @@ def cmd_import(args) -> int:
|
|||
"id": uuid.uuid4().hex,
|
||||
"slug": slugify(section["title"]),
|
||||
"title": section["title"],
|
||||
"content": section["content"],
|
||||
# Each section's lists start at 1, whatever they started at
|
||||
# in the block they were carved out of.
|
||||
"content": renumber(section["content"]),
|
||||
"parent_id": None,
|
||||
"variant": "clinical",
|
||||
} for section in after]
|
||||
|
|
|
|||
Loading…
Reference in a new issue