Skip to content

Support milestone citeStructures nested under a non-traversing parent - #36

Merged
PonteIneptique merged 1 commit into
mainfrom
fix/nested-milestone-citestructure
Sep 17, 2026
Merged

PonteIneptique merged 1 commit into
mainfrom
fix/nested-milestone-citestructure

Conversation

@PonteIneptique

Copy link
Copy Markdown
Member

A citeStructure such as match="/TEI/text/body/div" with a child matching ".//milestone[@Unit='section']" was unusable: the same @n value occurs in every chapter, and the parent path is absolute, so nothing scoped the child to its own parent.

  • normalize_xpath: drop the "." step a ".//" child match produces, which made reconstruct_doc copy the parent twice (
    ).
  • reverse_ancestor: that same "." step generated the invalid "[ancestor::]" (XPST0003).
  • _get_sibling_xpath: bind $end with head(), several siblings could match the boundary xpath and "<<" rejects a sequence (XPTY0004).
  • get_passage: always prefer a concrete boundary node over a tag/attribute xpath fragment, which otherwise matched a later chapter's section and over-copied. _prune_at_node prunes at a node, and _treat_siblings excludes the sibling that contains the boundary from the "<<" copy (it starts before it) to copy it pruned instead.
  • get_next_unit_boundary: a unit with no next sibling fell through to COPY_UNTIL_END, returning the rest of the document (157KB for one section). It now stops at the next unit of the same kind, clamped to the end of its own parent so a section never reaches into the next chapter.
  • find_refs / _resolve_groups: a child match written "//x" joined to ".///x"; treat it as ".//x", like generate_xpath already does.
  • find_refs: raise a located error on an empty citation value instead of "Reference '' does not match the expected format." further down.

A citeStructure such as match="/TEI/text/body/div" with a child matching
".//milestone[@Unit='section']" was unusable: the same @n value occurs in
every chapter, and the parent path is absolute, so nothing scoped the
child to its own parent.

- normalize_xpath: drop the "." step a ".//" child match produces, which
  made reconstruct_doc copy the parent twice (<div n="7"><div n="7">).
- reverse_ancestor: that same "." step generated the invalid
  "[ancestor::]" (XPST0003).
- _get_sibling_xpath: bind $end with head(), several siblings could match
  the boundary xpath and "<<" rejects a sequence (XPTY0004).
- get_passage: always prefer a concrete boundary node over a
  tag/attribute xpath fragment, which otherwise matched a later chapter's
  section and over-copied. _prune_at_node prunes at a node, and
  _treat_siblings excludes the sibling that contains the boundary from
  the "<<" copy (it starts before it) to copy it pruned instead.
- get_next_unit_boundary: a unit with no next sibling fell through to
  COPY_UNTIL_END, returning the rest of the document (157KB for one
  section). It now stops at the next unit of the same kind, clamped to
  the end of its own parent so a section never reaches into the next
  chapter.
- find_refs / _resolve_groups: a child match written "//x" joined to
  ".///x"; treat it as ".//x", like generate_xpath already does.
- find_refs: raise a located error on an empty citation value instead of
  "Reference '' does not match the expected format." further down.
@PonteIneptique
PonteIneptique merged commit 8188459 into main Sep 17, 2026
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant