Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,42 @@ follow semantic versioning; release dates are ISO 8601.

### Public API

- **A DOCX export stands the first line of a panel, a table's composed cell and a row's column where
the page sets it, where nothing was written above the line to raise it into.** Word and LibreOffice
stand an exact line's baseline four fifths of the way down it, and a line the page sets higher is
moved up into the space written above it; under half a point, a line with no such space was left
as low as Word set it. A line opening a cell has none of its own: a panel's padding and a table
cell's are the cell's margin, and a row's columns have their space above written above the row's
table. By the export's own measure of Word's seat, 250 lines of the corpus stood so, a median
0.22pt low; measured, `ClassicInvoice`'s "TOTAL DUE" stood 0.18pt low in its panel in Word and
0.2pt in LibreOffice. Under half a point, a line opening a cell now takes what its space above
cannot give from the top padding of the cell it opens — a panel's, less what its top border takes,
the panel's row held as much taller, as Word adds the margin left to the height a row is held at;
a table's composed cell's, in a row whose margins even, the cells beside it taking the margin back
above their first lines — and a row of columns' first row is lifted out of the space above its
table by the most its cells' first lines call for, each line rising by its own and the space under
it taking that back, so what follows stays. Not a row the layout moves to a new page, whose space
above stays on the page above, a row held to a height, or one whose column opens with a panel or a
table, which would rise whole. A paragraph in a table's composed cell, in a row the layout placed,
is raised into the space above it as anywhere else: the cell has no placement of its own, but its
row is kept on one page; one in a table nested in that cell is not yet.
Half a point and more is the position's, as before: taken from the padding, `CobaltRota`'s
masthead, whose position LibreOffice moves further than it says, came out 0.5 to 0.7pt lower there.
LibreOffice 24.2 counts a row's margins inside the height it is held at, so a panel or a table
row held taller than its text — a drawing set where the page puts it — comes out taller there by
the raise.

`ClassicInvoice`'s header, "BILL TO", "FROM" and "TOTAL DUE" moved up 0.24 to 0.36pt in Word and
0.2 to 0.4pt in LibreOffice, `ConsultingInvoice`'s line items 0.24 to 0.36pt and 0.35pt,
`ModernProfessional`'s entries 0.24pt and 0.2pt, everything under them where it was. By median,
12 documents moved nearer the page in Word and none further, 10 in LibreOffice on Windows and 9 in
LibreOffice 24.2, one further in each: `LumaStudioInvoice`, from 0.12pt to 0.14pt, whose line-items
table stands 0.13 to 0.16pt high in LibreOffice at its header's fill and its rules, which its
first lines, set low, made up for. In Word, a text cell beside a composed one that rose can stand a
step of Word's 0.12pt grid off, either way, its share of the row's margin written as space above
it. `ClassicInvoice`'s notes and payment terms still stand 0.2 to 0.26pt low in their rows: their
columns are ruled down their left side, panels in their cells, with no padding above their lines.

- **A DOCX export stands a table text cell's text where the page sets it by the height of its
lines, where its row's margins leave less than half a point of what it calls for.** Word and
LibreOffice stand an exact line's baseline four fifths of the way down it, and the page sets a
Expand Down
Binary file modified assets/readme/examples/word-export-companion.docx
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/architecture/backend-capability-matrix.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/recipes/docx-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ it cannot work out for itself:

| What | Where it lands |
|---|---|
| Line height | `w:spacing w:lineRule="exact"` on every paragraph, cells and list items included — the height the engine measured, not a multiple Word would measure again against a substituted font. Word has one height for a paragraph's lines: it is the tallest line's text, or, where the page sets lines of different heights further apart than that, the page's mean distance between their baselines, with what a paragraph on one page then falls short of the page owed below it, and what it passes the page by — written at its tallest line, a wrapped line after a large first one, which the page sets at its own height — hung below it, as a line held to its icon is: the space below takes it, and what it cannot take is named (`space above`) (not yet a list item's, or text set over the flow; measured: `CompactMono`'s sidebar, whose skills are two lines a paragraph and each written 0.12pt taller than the page, ended a point low in Word). Lines rounded up to the twip, over enough of them, hang the same way; what rounding takes from a paragraph written at its tallest line is owed below it as well (measured: `ModernInvoice`'s address blocks, six lines of 11.475pt written at 11.45, stood the table under them 0.15pt high in Word and LibreOffice). A tenth of a point or less is left either way: Word sets lines on a grid of its own, 0.12pt apart (measured). In a paragraph of more than one line on one page, the spaces a `bulletOffset` sets before a line, written as an indent, do not count towards that line's text. A paragraph of lines as tall as their text, on one page, opening a table cell takes the gap above its first line from the cell's top padding, no more than steps its lines the page's distance apart — not in a row beside a merged cell or a cell opening with a table, whose margin Word would set the whole row at, nor in a panel. One with no room above it for the gap (opening a column, or a cell padded less) shares the gaps out over all its lines, so its lines stand a little closer than on the page. A paragraph the layout did not measure — one in a composed table cell — is left to the editor, and a line holding a picture above its text is written "at least" that height — except a paragraph of one line of text with room above for its pictures' reach, held exact at the page's height (see "Inline pictures"); in both the paragraph mark is set in the text's size and face, since the mark counts towards the last line's height. A line holding pictures and no text, where they fill the page's line, has its mark and its pictures' runs set at a point instead, so Word makes the line as tall as the pictures and no taller: in the paragraph's own size the mark's depth went under the picture (measured: `SlateOrange`'s skills, a 12.4pt icon beside each label, stood 0.2pt taller each in Word). A smaller picture in a line the page sets at its font's height keeps its mark, and so does a line holding a letter, a break, a tab, a field or a link's text. A paragraph's own line of drawn shapes and no text written at least their reach, which Word grows to the pictures and the transparent frame each keeps around its ink, has that frame taken from the space above the line and above what follows, where it passes the height written: the ink stands where the page draws it, and what follows where the page sets it. Both editors stand the baseline of an exact line four fifths of the way down it whatever the face (measured in Word and LibreOffice on the fifteen faces the templates use and JetBrains Mono, 8 to 36pt), and the page sets it the face's ascent below the line's top, matched at a paragraph's middle line. A line Word sets lower than the page by a tenth of a point or more is moved up into the space written above it, written to the twip, and that space is owed below it, so what follows stays where it was; both editors keep a paragraph's space above as written (by its position alone, Helvetica's lines, which the page seats 0.78 of the way down, stood 0.12 to 0.38pt low in Word). A column's later layer, which measures the space to itself from the page, takes back the raise of the line above it. Not a line pair's shared line, which moved would move its other half; not a line in an overlay — a band, a layer stack, a shape container, a canvas, a text box — whose writers measure what follows them from the page; not a line cut to fit, a container's stacked lines or one held to its pictures; not a paragraph the layout moves to a new page, whose space above Word drops there, or breaks over one; and not into the space above a panel's first line that its top border takes. What that space cannot give, and a line Word sets higher than the page — moved down, it would take its room out of the space below it, not known when it is written — is raised or lowered to the page's baseline by `w:position` where the whole difference is half a point or more, a face with a deep descent, as Spectral's is. A list item's lines are not seated yet; a table text cell's are seated by its row's margins where its row allows (see "Tables"). LibreOffice moves text by `w:position` further than it is raised, by the face's height over its em — Spectral's 1.53 times, Poppins' 1.49, Volkhov's 1.31 (measured) — so a line raised by its position stands where the page sets it in Word only: Spectral's 24pt line, raised 4pt, stood 2.4pt high in LibreOffice. A picture among such text moves with it in Word; LibreOffice keeps a picture on its own baseline, where it stood before. Lines a container stacks tighter than their face — a title's lines a pitch apart — each end halfway between their letters and the next line's, since Word draws an exact line's text on screen only inside the line, and the last layer of a shape container, where its line runs past the foot, ends at the foot or below its letters |
| Line height | `w:spacing w:lineRule="exact"` on every paragraph, cells and list items included — the height the engine measured, not a multiple Word would measure again against a substituted font. Word has one height for a paragraph's lines: it is the tallest line's text, or, where the page sets lines of different heights further apart than that, the page's mean distance between their baselines, with what a paragraph on one page then falls short of the page owed below it, and what it passes the page by — written at its tallest line, a wrapped line after a large first one, which the page sets at its own height — hung below it, as a line held to its icon is: the space below takes it, and what it cannot take is named (`space above`) (not yet a list item's, or text set over the flow; measured: `CompactMono`'s sidebar, whose skills are two lines a paragraph and each written 0.12pt taller than the page, ended a point low in Word). Lines rounded up to the twip, over enough of them, hang the same way; what rounding takes from a paragraph written at its tallest line is owed below it as well (measured: `ModernInvoice`'s address blocks, six lines of 11.475pt written at 11.45, stood the table under them 0.15pt high in Word and LibreOffice). A tenth of a point or less is left either way: Word sets lines on a grid of its own, 0.12pt apart (measured). In a paragraph of more than one line on one page, the spaces a `bulletOffset` sets before a line, written as an indent, do not count towards that line's text. A paragraph of lines as tall as their text, on one page, opening a table cell takes the gap above its first line from the cell's top padding, no more than steps its lines the page's distance apart — not in a row beside a merged cell or a cell that may open with a table — anything but text, a paragraph, a list, a picture or a spacer: a table, a row of columns, a painted container, a shape — whose margin Word would set the whole row at, nor in a panel. One with no room above it for the gap (opening a column, or a cell padded less) shares the gaps out over all its lines, so its lines stand a little closer than on the page. A paragraph the layout did not measure — one an export without a layout writes — is left to the editor, and a line holding a picture above its text is written "at least" that height — except a paragraph of one line of text with room above for its pictures' reach, held exact at the page's height (see "Inline pictures"); in both the paragraph mark is set in the text's size and face, since the mark counts towards the last line's height. A line holding pictures and no text, where they fill the page's line, has its mark and its pictures' runs set at a point instead, so Word makes the line as tall as the pictures and no taller: in the paragraph's own size the mark's depth went under the picture (measured: `SlateOrange`'s skills, a 12.4pt icon beside each label, stood 0.2pt taller each in Word). A smaller picture in a line the page sets at its font's height keeps its mark, and so does a line holding a letter, a break, a tab, a field or a link's text. A paragraph's own line of drawn shapes and no text written at least their reach, which Word grows to the pictures and the transparent frame each keeps around its ink, has that frame taken from the space above the line and above what follows, where it passes the height written: the ink stands where the page draws it, and what follows where the page sets it. Both editors stand the baseline of an exact line four fifths of the way down it whatever the face (measured in Word and LibreOffice on the fifteen faces the templates use and JetBrains Mono, 8 to 36pt), and the page sets it the face's ascent below the line's top, matched at a paragraph's middle line. A line Word sets lower than the page by a tenth of a point or more is moved up into the space written above it, written to the twip, and that space is owed below it, so what follows stays where it was; both editors keep a paragraph's space above as written (by its position alone, Helvetica's lines, which the page seats 0.78 of the way down, stood 0.12 to 0.38pt low in Word). A column's later layer, which measures the space to itself from the page, takes back the raise of the line above it. Not a line pair's shared line, which moved would move its other half; not a line in an overlay — a band, a layer stack, a shape container, a canvas, a text box — whose writers measure what follows them from the page; not a line cut to fit, a container's stacked lines or one held to its pictures; not a paragraph the layout moves to a new page, whose space above Word drops there, or breaks over one; and not into the space above a panel's first line that its top border takes. A line opening a cell has no space above it of its own: a panel's padding and a table cell's are the cell's margin, and a row's columns have their space above written above the row's table. One Word sets less than half a point low takes what its space above cannot give from the top padding of the cell it opens: a table's composed cell's, in a row whose margins all even, as the gap above a first line does, the cells beside it taking the margin back above their first lines; and a panel's, which the gap does not take, less what its top border takes, the panel's row then held as much taller, as Word adds the margin left to the height a row is held at. A row of columns' first row is lifted out of the space above its table by the most its cells' first lines call for, each line rising by its own and the space under it taking that back, so what follows stays (measured: `ModernProfessional`'s entries, a title beside its dates in a row of their own, moved up 0.24pt in Word and 0.2pt in LibreOffice, `ConsultingInvoice`'s line items, composed cells, 0.24 to 0.36pt and 0.35pt, everything under them where it was). Not a row the layout moves to a new page, whose space above stays on the page above, a row held to a height, or one whose column opens with a panel or a table — a column with a fill or a border is a panel in its cell — which would rise whole; LibreOffice 24.2 counts a row's margins inside the height it is held at, so a panel or a table row held taller than its text — a drawing set where the page puts it — comes out taller there by the raise. A paragraph in a table's composed cell, in a row the layout placed, is raised into the space above it as anywhere else: the cell has no placement of its own, but its row is kept on one page; one in a table nested in that cell is not yet. What that space cannot give, and a line Word sets higher than the page — moved down, it would take its room out of the space below it, not known when it is written — is raised or lowered to the page's baseline by `w:position` where the whole difference is half a point or more, a face with a deep descent, as Spectral's is. A list item's lines are not seated yet; a table text cell's are seated by its row's margins where its row allows (see "Tables"). LibreOffice moves text by `w:position` further than it is raised, by the face's height over its em — Spectral's 1.53 times, Poppins' 1.49, Volkhov's 1.31 (measured) — so a line raised by its position stands where the page sets it in Word only: Spectral's 24pt line, raised 4pt, stood 2.4pt high in LibreOffice. A picture among such text moves with it in Word; LibreOffice keeps a picture on its own baseline, where it stood before. Lines a container stacks tighter than their face — a title's lines a pitch apart — each end halfway between their letters and the next line's, since Word draws an exact line's text on screen only inside the line, and the last layer of a shape container, where its line runs past the foot, ends at the foot or below its letters |
| Table columns | the resolved cell widths as `w:gridCol`, with `w:tblLayout` fixed so Word does not re-fit them |
| Row columns | where the layout placed each child, with the row's gap and padding folded into the neighbouring column and taken back out as that cell's margin — in a painted row's panel the padding is the panel cell's margins instead, and the columns are without it. A column sized to its content (`DocumentRowColumn.auto()`) gets a point more, taken from the row's weight columns so the row keeps its width, for the reason a table's does: the editor's substitute font would wrap it — a table of contents' labels broke mid-word ("Intr" / "o") in LibreOffice without it. A row with no auto column, no weight column, or no stated columns (weights, an even split) is written as placed |

Expand Down
Loading
Loading