Commit 9ea096d
Render every block child of a list item, cell, footnote, box and quote (#11)
* Render every block child of a list item, cell, footnote, box and quote
render_list built each <list-item> from item.findall('p') alone and
joined the paragraphs into one line, so a <list> or <def-list> nested
as a sibling of the paragraph, and the item's own <label>, were dropped
without a trace. Across a corpus of 1,013 Bookshelf chapters (BITS XML)
list items hold 2,951 nested lists — about 196,000 words, every
chapter's sub-bullets in its management and diagnosis sections.
The same shape — collect a fixed subset of children, drop the rest —
recurred in render_def_list, render_boxed_text, render_disp_quote,
render_statement, render_glossary, render_abstract's structured
sections, render_body, render_floats_group, table cells and
<table-wrap-foot> (whose <fn-group> footnotes were dropped), and in the
Elsevier _list, _render_deflist, _render_display, _render_quote,
_render_enunciation, table entries and footnotes. So the fix is one
mechanism rather than a patch per site: a document-order content walker
(jats._render_content, elsevier._Renderer._content) renders each child
through its block renderer — a <p> as its own fragments, a run of text
and inline children between blocks as a paragraph — and returns typed
(tag, markdown) fragments. A tag with no block renderer is inline
content, so nothing falls through; the only exclusions are named
metadata children (sec-meta, permissions, object-id) and the children a
caller renders itself (a label, a title). JATS block dispatch is one
table, _BLOCK_RENDERERS, keyed by tag.
The fragments are laid out by three shared helpers in common: list_item
stacks an item's blocks under its marker, indenting by the marker's
width (CommonMark's content offset) so a nested list nests and a later
paragraph continues the item; definition_item does the same for a
`- **term** — definition` entry; md_cell joins a cell's blocks with
<br>, a GFM row being single-line. The item marker is the <label> when
present (verbatim, as the Elsevier renderer already did), else the
ordinal or a bullet. A flat list of single-paragraph items renders
byte-identically to before.
Also rendered where previously dropped: a section's <label> (joins the
heading), a list's <title>, <term-head>/<def-head>, a term's inline
markup (findtext read only the text before the first child), a
labelled and captioned <media> or <graphic> in a paragraph, an
<inline-graphic> (as an image), bare <mml:math>/<tex-math> in running
text (as inline LaTeX instead of their source), a titled <app-group>,
<bio>, and an Elsevier quote's <source>. Cells iterate <th>/<td> in
document order rather than all <td> first. Inline runs trim ASCII
whitespace only (common.flat), as every other edge does, so an em-space
indented pseudocode line keeps its indentation.
Tests: one hand-written document per container shape, checked both for
the invariant that every text node of the input appears in the output
and for the exact markdown layout of the nesting.
Bump version to 0.7.0: rendered output changes for most documents with
nested lists, list-bearing cells, numbered sections or multi-paragraph
footnotes, so consumers that cache renderings need to re-render.
* Emit only CommonMark list markers; keep heads, titles and floats in place
Review fixes for the block-content walker.
A verbatim <label> is not a CommonMark list marker: "• Outer\n ◦ Inner"
parses as one paragraph, and a label three or more characters wide
("(i)", "Step 1:") indents its continuation paragraphs into an indented
code block. common.list_marker now resolves a label: an ordinal
("3.", "10)") is the marker verbatim, a bare number gets its period, a
bullet glyph becomes "-", and anything else is not a marker at all — the
list's default marker is emitted and the label opens the item's content
("- (i) First."). The indent follows the marker actually emitted. The
Elsevier renderer applies the same rule, keeping the inline rendering of
a non-marker label ("- **(a)** …"). Verified with pandoc: every shape
parses as a (nested) list.
A definition entry, a <statement> and an Elsevier <enunciation> join
their head onto the first block only when that block is a paragraph; a
fence, table or formula now starts beneath the head line.
A run whose ASCII-trimmed text is only non-ASCII whitespace
(<p> </p>) renders nothing, as before; the trim stays ASCII-only,
which table cells and labels already used (headings, attribs and
statement heads trim with str.strip()).
An Elsevier <textbox> without <textbox-body> no longer repeats its
label and head from the body walk. A paragraph nested in another run —
a list item's, a footnote's — restores the run's queued floats instead
of resetting them, so a float anchored there is placed at the
paragraph, not in the end sweep.
A nested, titled <def-list> is preceded by a blank line so its title
does not lazily continue the entry above. A table foot part that is one
italic span is unwrapped before the foot is italicised, so an
<attrib><italic> no longer renders bold. A bare <alternatives> in
running text yields one alternative in _formula_body's preference
order instead of every alternative in turn. A structured abstract's
<sec>s, and a section's <ref-list>, are dispatched inside the walk (an
overrides table per caller), keeping document order for a paragraph
that follows them.
Tests: the text-node invariant now uses multi-character tokens
throughout (a one-character node matches almost any output) and asserts
that; layout-only shapes — a bullet-glyph label, an <alternatives> —
are checked for their markdown alone. New cases: bare-number, ordinal,
glyph, roman and word labels, a definition opening with code, a
statement opening with a table, a titled nested def-list, an italic
attrib foot, whitespace-only paragraphs, a bold Elsevier label and a
body-less textbox.
* Separate a nested list that cannot interrupt a paragraph; one italic foot
Second-pass review fixes for the block-content walker.
Only a bullet or a "1." item can interrupt a paragraph in CommonMark;
"- Steps:\n 3. Third." lazily continues the paragraph, and an empty
first nested item ("-" alone) underlines it as a setext heading.
common.list_item now puts a blank line before a nested list whose first
line is not "[-*+] x" or "1[.)] x" — the same path lays out definition
entries and Elsevier items.
A label that is not a marker is the item's enumerator, so it opens the
content behind a bullet whatever the list type ("- (a) Alpha.", not
"1. (a) Alpha."); the marker is decided on the stripped label (so a
glyph followed by a no-break space counts), the glyph set gains the
dashes and the remaining common bullet shapes, and a lead that would
open a heading, quote or fence is backslash-escaped. An Elsevier label
with no text but an inline rendering (a <math> bullet) is kept as the
lead rather than dropped. list_marker's docstring says that a verbatim
ordinal keeps the source numbering in the markdown while a renderer
renumbers from the first item.
A table foot is italicised as a whole only when no asterisk inside it
— an italic span or a literal significance marker — could pair with the
wrapper, so a partly italic <attrib> no longer renders
"**Adapted* from Doe.*" (unwrapping the inner emphasis was tried and
rejected: it also ate literal asterisks, "DQB1*0302"). A bare
<alternatives> prefers its <tex-math>,
then its <math> whether namespaced or not, before a graphic, so an
un-namespaced <math> beside a <graphic> renders as math. Reference
entries are blank-line separated with none trailing, so a <ref-list>
inside a section no longer leaves a triple newline before the paragraph
that follows it (a document ending in references loses its trailing
newline).
Tests: the italic-foot assertion is anchored on the preceding blank
line and asserts no bold; new shapes cover a nested list opening with
"3.", "10)", a bare "3", "0" and an empty item, an order-typed list with
"(a)" labels, "#"/">" labels, an <alternatives> with un-namespaced math,
a glyph-with-NBSP label, an Elsevier math label and a mid-section
<ref-list>. Verified with pandoc that each shape parses as intended.
* Render a table foot as plain text
A table foot was set in italics as a whole. The wrapper collided with
emphasis inside the foot — an italic gene name at its edge doubled up
to bold — and with the literal asterisks footnotes use as significance
markers; making the wrapper conditional on the foot's content left a
foot's rendering depending on whether it mentions an italic gene. So
neither dialect wraps the foot: it is plain text below the table, its
footnote markers and its own markup as they are.
---------
Co-authored-by: Leonhard Gruenschloss <l.gruenschloss@vcgs.org.au>1 parent 9e04b54 commit 9ea096d
8 files changed
Lines changed: 979 additions & 381 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
96 | 96 | | |
97 | 97 | | |
98 | 98 | | |
99 | | - | |
| 99 | + | |
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
122 | 126 | | |
123 | 127 | | |
124 | 128 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| 20 | + | |
19 | 21 | | |
| 22 | + | |
20 | 23 | | |
21 | 24 | | |
22 | 25 | | |
| |||
73 | 76 | | |
74 | 77 | | |
75 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
76 | 198 | | |
77 | 199 | | |
78 | 200 | | |
| |||
0 commit comments