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
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,38 @@ follow semantic versioning; release dates are ISO 8601.

### Public API

- **A DOCX export raises a line Word sets low into the space above it, where both editors keep
it.** Both editors stand an exact line's baseline four fifths of the way down it whatever the
face — measured 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. The text was moved to the page's baseline by
its position, which counts in half points and was left alone under half a point: 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. And LibreOffice moves raised text 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 Spectral's 24pt line,
raised 4pt, stood 2.4pt high there (measured).
- A line Word sets low 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. What the space cannot give is left to
the position where the whole difference calls for one, as is a line Word sets high: moved
down, it would take its room out of the space below it, which is not known when it is written.
- 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, whose lines on the next page the space above does not
move; and not into the space above a panel's first line that its top border takes.

In the DOCX fidelity corpus 27 documents stand nearer the page in Word, the sum of the medians
1.65pt nearer — `letter-blue_banner`'s median line from 0.39pt to 0.18pt, `cv-modern_professional`'s
from 0.32pt to 0.18pt — and 21 in LibreOffice on Windows, `cv-modern_professional`'s from 0.28pt
to 0.04pt. Two move a step of Word's grid further: `invoice-luma_studio`'s company lines, raised
where the page sets them, now show their block standing 0.2 to 0.3pt high (median 0.13pt to
0.14pt),
and `letter-panel`'s median from 0.14pt to 0.16pt; in LibreOffice two medians move 0.01pt. The
report names nothing more.

- **A DOCX export no longer stands what follows a width anchor, or a paragraph Word sets taller,
lower than the page.** Both reached past the block in Word, and neither was taken out of the
space below or named. Each now hangs below its block, as a line held to its icon does: the
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 not owed (measured: owed, it stood `ModernInvoice`'s lines lower in Word). 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), and the page sets it the face's ascent below the line's top: where the two are half a point or more apart — a face with a deep descent, as Spectral's is — a paragraph's text is raised or lowered to the page's baseline by `w:position`, matched at its middle line; a list item's and a table text cell's are not yet. 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 not owed (measured: owed, it stood `ModernInvoice`'s lines lower in Word). 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 and a table text cell's lines are not seated yet. 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