mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-06 18:51:26 +00:00
Gap 19: ODT pictures alone in a paragraph keep its size and their raise
Found with LibreOffice's elegant agenda: - Paragraph size: a paragraph holding only pictures lost its own font size, since the flow model's picture runs carry no formatting, so its line grew. Such a paragraph (`Para::textless`) now keeps its formatting as the paragraph mark's, which its pictures' runs take too. Read and written as for empty paragraphs. - Raise: an in-line frame's raise was dropped when a parent style gave it a relation no in-line frame has (the Graphics style's `style:vertical-rel="paragraph"`). It is now measured from the baseline, as LibreOffice reads it. The agenda's round-trip difference falls from 6,542 to 1,331 pixels, and two business fax templates' from about 5,300 to 270 and 350. Across the corpus it falls from 185k to 155k. No document changes page count. WordCraft's own rendering of a picture-only line is still taller than LibreOffice's, a layout difference left for later. gaps.md row 19 and the ROADMAP log are updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GBVQLyDnrG8Tn1yDQcUabC
This commit is contained in:
10 files changed
+80
-14
No files matched your search
+3
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
**Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-02 · **Change:** trivial (progress log: ODT round trips keep their page count); previously trivial (progress log: emphasis marks, SET fields, ODT page backgrounds and tables); previously trivial (progress log: ODT checked against LibreOffice's templates); previously trivial (progress log: ODT at ~90%); previously trivial (progress log: ODT read and written nearly whole); previously trivial (progress log: ODT text boxes); previously trivial (progress log: ODT layout settings); previously trivial (progress log: ODT character styles); previously trivial (progress log: ODT custom styles); previously trivial (progress log: ODT equations saved); previously trivial (progress log: ODT floating pictures); previously trivial (progress log: ODT paragraph borders); previously trivial (progress log: ODT heading numbering); previously trivial (progress log: ODT table borders); previously trivial (progress log: ODT heading styles); previously trivial (progress log: ODT tab stops); previously trivial (progress log: ODT character formatting); previously trivial (progress log: ODT lists); previously trivial (progress log: ODT comments); previously trivial (progress log: ODT footnotes and endnotes); previously trivial (progress log: ODT headers, footers and fields); previously trivial (progress log: ODT paragraph spacing); previously trivial (progress log: a paragraph naming an undefined style is formatted as Normal, #5077); previously trivial (progress log: TOC page numbers as PAGEREF fields, #5097); previously trivial (progress log: Backstage keytips, #4960); previously trivial (Progress log: only the printer's PDF leaves out links; Save these pages as PDF keeps them, #4734); previously trivial (progress log: Chinese and Japanese text counts a word per character, #4547; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (progress log: corporate authors in bibliographies, #4848); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (progress log: Table Properties follows the selection, #4857); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion walks reference offsets and formatting runs together, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (progress log: RTF pictures stored as Windows or Enhanced Metafiles are imported, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (progress log: Insert › Shapes icon grid, #4349); previously trivial (progress log: AutoCorrect Options with no document open, #4585); previously trivial (progress log: window fallback geometry and equation symbol tooltips); previously trivial (progress log: window titles omit NUL characters, #3634); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (progress log: Custom document properties dialog, #2982; previously trivial: progress log: View › New Window; previously trivial: progress log: interface translations come from storytold/craft-i18n through the `craft-i18n` crate; previously trivial: progress log: disabled-control reasons translated in every interface language, #2678; previously trivial: progress log: mail merge record navigation and record ranges for printing, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: group connector rerouting preserves rotated and flipped free or unresolved endpoints under nonuniform group scaling; readiness estimates unchanged; previously trivial: progress log: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: progress log: a relationship the markup names without the prefix is read as it wrote, and an ordinary `id` names no part; previously trivial: progress log: a document with many relationships opens in the time its part takes, and an id the text only mentions is not a reference, #3411; previously trivial: progress log: read only and comments-only protection grey out edits; previously trivial: progress log: an empty paragraph with a hidden mark shows nothing, not even its list number, #3982; previously trivial: progress log: "NaN" in the Font dialog's Size box no longer closes the app, #3663; previously trivial: progress log: a table cell span from a `.json` file no longer overLine truncated
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-02 · **Change:** trivial (progress log: ODT tables, header spacing, picture paragraphs); previously trivial (progress log: ODT round trips keep their page count); previously trivial (progress log: emphasis marks, SET fields, ODT page backgrounds and tables); previously trivial (progress log: ODT checked against LibreOffice's templates); previously trivial (progress log: ODT at ~90%); previously trivial (progress log: ODT read and written nearly whole); previously trivial (progress log: ODT text boxes); previously trivial (progress log: ODT layout settings); previously trivial (progress log: ODT character styles); previously trivial (progress log: ODT custom styles); previously trivial (progress log: ODT equations saved); previously trivial (progress log: ODT floating pictures); previously trivial (progress log: ODT paragraph borders); previously trivial (progress log: ODT heading numbering); previously trivial (progress log: ODT table borders); previously trivial (progress log: ODT heading styles); previously trivial (progress log: ODT tab stops); previously trivial (progress log: ODT character formatting); previously trivial (progress log: ODT lists); previously trivial (progress log: ODT comments); previously trivial (progress log: ODT footnotes and endnotes); previously trivial (progress log: ODT headers, footers and fields); previously trivial (progress log: ODT paragraph spacing); previously trivial (progress log: a paragraph naming an undefined style is formatted as Normal, #5077); previously trivial (progress log: TOC page numbers as PAGEREF fields, #5097); previously trivial (progress log: Backstage keytips, #4960); previously trivial (Progress log: only the printer's PDF leaves out links; Save these pages as PDF keeps them, #4734); previously trivial (progress log: Chinese and Japanese text counts a word per character, #4547; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (progress log: corporate authors in bibliographies, #4848); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (progress log: Table Properties follows the selection, #4857); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion walks reference offsets and formatting runs together, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (progress log: RTF pictures stored as Windows or Enhanced Metafiles are imported, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (progress log: Insert › Shapes icon grid, #4349); previously trivial (progress log: AutoCorrect Options with no document open, #4585); previously trivial (progress log: window fallback geometry and equation symbol tooltips); previously trivial (progress log: window titles omit NUL characters, #3634); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (progress log: Custom document properties dialog, #2982; previously trivial: progress log: View › New Window; previously trivial: progress log: interface translations come from storytold/craft-i18n through the `craft-i18n` crate; previously trivial: progress log: disabled-control reasons translated in every interface language, #2678; previously trivial: progress log: mail merge record navigation and record ranges for printing, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: group connector rerouting preserves rotated and flipped free or unresolved endpoints under nonuniform group scaling; readiness estimates unchanged; previously trivial: progress log: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: progress log: a relationship the markup names without the prefix is read as it wrote, and an ordinary `id` names no part; previously trivial: progress log: a document with many relationships opens in the time its part takes, and an id the text only mentions is not a reference, #3411; previously trivial: progress log: read only and comments-only protection grey out edits; previously trivial: progress log: an empty paragraph with a hidden mark shows nothing, not even its list number, #3982; previously trivial: progress log: "NaN" in the Font dialog's Size box no longer closes the app, #3663; preLine truncated
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-29 · **Change:** trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (English dialects in proofing, #1281; previously trivial: triple borders draw three lines, #1740; previously trivial: progress log: double-clicking a later page's footer no longer scrolls up, #2103; previously trivial: long navigation headings wrap onto further lines within the pane, #3015; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: a word after a slash wraps whole, like Word, #2963; previously trivial: RTF export writes sections (gap 19); previously trivial: ODT export writes sections (gap 19); previously trivial: progress log: pasted blockquotes are indented paragraphs, #1270; previously trivial: progress log: print-area strings translated in every catalog; previously trivial: progress log: comments readable in the dark theme, #2045; previously trivial: progress log: ODT sections, #1379; previously trivial: progress log: table deletes, Change Case and Unlink Fields respect Track Changes and locked content controls, #1329; previously trivial: progress log: rounded rectangle corners, #1476; previously trivial: progress log: Save As type list, #1399; previously trivial: progress log: privacy options on save, #1062; previously trivial: progress log: equation pictures in theme colours on Windows, #1002; previously trivial: symbol fonts, #776; previously trivial: the save prompt answers from the keyboard, #861; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; progress docs restructured) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
> **Printing update:** 2026-10-12 · direct desktop printing through craft-print; details below.
|
||||
|
||||
@@ -140,6 +140,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
||||
|
||||
## Progress log
|
||||
|
||||
- 2026-11-02: ODT, from LibreOffice's report templates and agenda: tables filling the margins fit them, and a table's own space above and below is kept and laid out (new `TableProps::space_before`/`space_after`); a header's spacing stays below one taller than its band (new `SectionProps::header_gap`/`footer_gap`); a picture alone in a paragraph keeps the paragraph's size and its raise. The corpus round-trip difference falls from 241k to 155k pixels, 62% below this morning's 408k (gap 19). Readiness unchanged.
|
||||
- 2026-11-02: ODT: none of the 125 test documents (LibreOffice's 78 templates among them) changes its page count through a WordCraft save any more, and their round-trip difference falls by 40%: the default font size, page-anchored frames, styles used only in text boxes, empty paragraphs' size (a new paragraph-mark field in the flow model) and frames anchored by their style (gap 19). Readiness unchanged.
|
||||
- 2026-11-02: Emphasis marks (Font › Emphasis mark: a dot, comma or circle over each character, or a dot under it) are new: drawn with room made in the line, set by `format.emphasisMark`, kept in DOCX (`w:em`) and ODT. SET fields now give REF their value, so ODT variables open and update as fields. A page break before a table's first row moves the table, as in Word. ODT: page background pictures, fixed-width tables, tables starting a page, the document's default font size and dates in the locale's order (gap 19). Readiness unchanged.
|
||||
- 2026-11-02: ODT checked against LibreOffice's own 78 bundled templates (letters, faxes, agendas, reports, CVs), all of which now open and round-trip (gap 19): placeholders ("<Recipient's name>") open as content controls you click and type over; a "First Page" style followed by another is a different first page; pages without a size take the regional default and LibreOffice's 2 cm margins; WMF and EMF logos are kept; template dates show the day; USERNAME shows your name; hidden form controls and `.ott` templates (open and save, with a password too) are kept. Readiness unchanged.
|
||||
@@ -1088,6 +1089,7 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps
|
||||
| 2026-10-23 | trivial | Progress log: "NaN" in the Font dialog's Size box no longer closes the app (#3663) |
|
||||
| 2026-10-23 | trivial | Progress log: a table cell span from a `.json` file no longer overflows (#3637) |
|
||||
| 2026-10-28 | trivial | Progress log: chart and SmartArt text the font lacks is drawn in a fallback face (#4720) |
|
||||
| 2026-11-02 | trivial | Progress log: ODT tables, header spacing, picture paragraphs (gap 19) |
|
||||
| 2026-11-02 | trivial | Progress log: ODT round trips keep their page count (gap 19) |
|
||||
| 2026-11-02 | trivial | Progress log: emphasis marks, SET fields, ODT page backgrounds and tables (gap 19) |
|
||||
| 2026-11-02 | trivial | Progress log: ODT checked against LibreOffice's templates (gap 19) |
|
||||
|
||||
@@ -588,11 +588,12 @@ fn flow_paras_in(doc: &Document, p: &Paragraph, opts: FlowOpts) -> Vec<Para> {
|
||||
done
|
||||
}
|
||||
|
||||
/// The mark formatting of `out`, the last piece of `p`, when it holds no text (its height), for
|
||||
/// The mark formatting of `out`, the last piece of `p`, when it holds no text (its height, its
|
||||
/// drawings' formatting), for
|
||||
/// formats that keep it (flows asked for paragraph formatting).
|
||||
fn empty_mark(out: &Para, p: &Paragraph, opts: FlowOpts) -> Option<Box<CharProps>> {
|
||||
let m = CharProps { ins: None, del: None, fmt_change: None, ..p.mark.clone() };
|
||||
(opts.paras && out.inlines.is_empty() && !m.is_empty()).then(|| Box::new(m))
|
||||
(opts.paras && out.textless() && !m.is_empty()).then(|| Box::new(m))
|
||||
}
|
||||
|
||||
/// The drawings from `from` on (just added) raised by their run's position `raise` (points): a
|
||||
|
||||
@@ -510,8 +510,14 @@ impl<'a> Builder<'a> {
|
||||
Inline::FieldEnd => append(&mut out, "", &CharProps::default(), Some(InlineObject::FieldEnd)),
|
||||
Inline::Image(_) | Inline::Chart(_) | Inline::Shape { .. } | Inline::Group { .. } => {
|
||||
if let Some(mut obj) = self.drawing(i, 0) {
|
||||
// In line, raised or lowered: its run's position (as Word keeps it).
|
||||
let mut cp = CharProps::default();
|
||||
// In line, raised or lowered: its run's position (as Word keeps it). In
|
||||
// a paragraph of its own, its run has the paragraph's formatting.
|
||||
let mut cp = p
|
||||
.mark
|
||||
.as_deref()
|
||||
.filter(|_| p.textless())
|
||||
.map(|m| self.budget(CharProps { ins: None, del: None, fmt_change: None, ..m.clone() }))
|
||||
.unwrap_or_default();
|
||||
if let Some(f) = obj.float_mut()
|
||||
&& f.wrap == wordcraft_doc::para::Wrap::Inline
|
||||
&& f.y != 0.0
|
||||
@@ -597,7 +603,7 @@ impl<'a> Builder<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(m) = p.mark.as_deref().filter(|_| out.text.is_empty()) {
|
||||
if let Some(m) = p.mark.as_deref().filter(|_| p.textless()) {
|
||||
out.mark = self.budget(CharProps { ins: None, del: None, fmt_change: None, ..m.clone() });
|
||||
}
|
||||
out.mark.ins = p.mark_ins.as_deref().map(|m| self.revision(RevisionKind::Insert, m));
|
||||
|
||||
@@ -654,7 +654,8 @@ pub struct Para {
|
||||
pub extra: Option<Box<wordcraft_doc::props::ParaProps>>,
|
||||
/// The paragraph mark's direct formatting (its size sets an empty paragraph's height), for
|
||||
/// formats that keep it (ODT): only flows asked for paragraph formatting
|
||||
/// ([`FlowOpts::paras`]) hold it, and only for paragraphs without text.
|
||||
/// ([`FlowOpts::paras`]) hold it, and only for paragraphs without text ([`Para::textless`]),
|
||||
/// whose drawings' runs take it too.
|
||||
pub mark: Option<Box<wordcraft_doc::props::CharProps>>,
|
||||
}
|
||||
|
||||
@@ -662,6 +663,26 @@ impl Para {
|
||||
pub fn new(kind: Kind) -> Para {
|
||||
Para { kind, ..Default::default() }
|
||||
}
|
||||
|
||||
/// It holds no text of its own: nothing, or only drawings, bookmarks and field bounds. Its
|
||||
/// [`Para::mark`] formatting is then its own (its height, its drawings' runs).
|
||||
pub fn textless(&self) -> bool {
|
||||
self.inlines.iter().all(|i| {
|
||||
matches!(
|
||||
i,
|
||||
Inline::Image(_)
|
||||
| Inline::Chart(_)
|
||||
| Inline::Shape { .. }
|
||||
| Inline::Group { .. }
|
||||
| Inline::Figure(_)
|
||||
| Inline::Anchor(_)
|
||||
| Inline::AnchorEnd(_)
|
||||
| Inline::CommentEnd(_)
|
||||
| Inline::FieldStart(_)
|
||||
| Inline::FieldEnd
|
||||
)
|
||||
})
|
||||
}
|
||||
/// Append text, merging with the previous span when the formatting matches.
|
||||
pub fn push_text(&mut self, s: &str, f: &Fmt) {
|
||||
if s.is_empty() {
|
||||
|
||||
@@ -546,9 +546,10 @@ impl Body<'_> {
|
||||
self.index_marks.clear();
|
||||
let Some(mut p) = self.para.take() else { return };
|
||||
self.glue_connectors(&mut p);
|
||||
// An empty paragraph's own text formatting is its mark's: its size is its height.
|
||||
// A paragraph without text has its own text formatting as its mark's: its size is its
|
||||
// height, and its drawings' runs have it.
|
||||
if let Some(base) = self.fmt.pop()
|
||||
&& p.inlines.is_empty()
|
||||
&& p.textless()
|
||||
&& base != model::Fmt::default()
|
||||
{
|
||||
p.mark = Some(Box::new(crate::model::char_props(&base)));
|
||||
|
||||
@@ -395,7 +395,9 @@ pub(super) fn place(a: &Attrs, w: f32, h: f32, g: &Graphic) -> Float {
|
||||
/// `bottom` hangs from it, `from-top` has its top `svg:y` below it. Placement relative to the
|
||||
/// character or line stays on the baseline.
|
||||
fn inline_raise(g: &Graphic, y: Option<f32>, h: f32) -> f32 {
|
||||
if !matches!(g.vrel.as_deref(), None | Some("baseline")) || !h.is_finite() {
|
||||
// Measured from the baseline; a relation an in-line frame can't have (a paragraph's, from
|
||||
// a parent style for anchored frames) is the baseline too, as LibreOffice reads it.
|
||||
if matches!(g.vrel.as_deref(), Some("char" | "line" | "text")) || !h.is_finite() {
|
||||
return 0.0;
|
||||
}
|
||||
let raise = match g.vpos.as_deref() {
|
||||
|
||||
@@ -56,6 +56,37 @@ fn wrap_modes_and_offsets() {
|
||||
assert_eq!(float(&open("", r#"text:anchor-type="as-char""#)).wrap, Wrap::Inline);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_picture_alone_in_its_paragraph_keeps_its_raise_and_the_paragraphs_size() {
|
||||
// LibreOffice's elegant agenda: a rule raised 0.2 in above the baseline (its parent style's
|
||||
// `vertical-rel="paragraph"` is no in-line frame's, so the baseline's), in a 9 pt paragraph.
|
||||
let pic = {
|
||||
let img = image::RgbaImage::from_fn(4, 4, |_, _| image::Rgba([10, 20, 30, 255]));
|
||||
let mut png = Vec::new();
|
||||
img.write_to(&mut std::io::Cursor::new(&mut png), image::ImageFormat::Png).unwrap();
|
||||
png
|
||||
};
|
||||
let content = format!(
|
||||
r#"<office:document-content {NS} xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink"><office:automatic-styles><style:style style:name="P2" style:family="paragraph"><style:text-properties fo:font-size="9pt"/></style:style><style:style style:name="g1" style:family="graphic" style:parent-style-name="G"><style:graphic-properties style:vertical-pos="from-top"/></style:style></office:automatic-styles><office:body><office:text><text:p text:style-name="P2"><draw:frame draw:style-name="g1" text:anchor-type="as-char" svg:y="-0.2in" svg:width="6in" svg:height="0.05in"><draw:image xlink:href="Pictures/p.png"/></draw:frame></text:p></office:text></office:body></office:document-content>"#,
|
||||
NS = crate::odt::tests::NS_T
|
||||
);
|
||||
let styles = format!(
|
||||
r#"<office:document-styles {NS} xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"><office:styles><style:style style:name="G" style:family="graphic"><style:graphic-properties text:anchor-type="paragraph" style:vertical-pos="top" style:vertical-rel="paragraph"/></style:style></office:styles></office:document-styles>"#,
|
||||
NS = crate::odt::tests::NS_T
|
||||
);
|
||||
let pkg = crate::odt::tests::zip_of(&[("content.xml", content.as_bytes()), ("styles.xml", styles.as_bytes()), ("Pictures/p.png", &pic)]);
|
||||
let look = |doc: &Document| {
|
||||
let p = doc.body.iter().find_map(|b| b.as_para()).unwrap();
|
||||
let (off, _) = p.objects_with_offsets().next().unwrap();
|
||||
let props = p.props_at(off + wordcraft_doc::para::OBJ.len_utf8());
|
||||
(props.position.map(|v| (v * 10.0).round() / 10.0), props.size, p.mark.size)
|
||||
};
|
||||
let doc = crate::odt::import(&pkg).unwrap();
|
||||
assert_eq!(look(&doc), (Some(10.8), Some(9.0), Some(9.0)));
|
||||
let again = crate::odt::import(&crate::odt::export(&doc).unwrap()).unwrap();
|
||||
assert_eq!(look(&again), (Some(10.8), Some(9.0), Some(9.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_page_anchored_frames_paragraph_relations_are_the_pages() {
|
||||
// LibreOffice's letter templates: a page-anchored frame "from the paragraph" is placed from
|
||||
|
||||
@@ -301,8 +301,8 @@ impl Writer {
|
||||
props.push('\u{1}');
|
||||
props.push_str(&children);
|
||||
}
|
||||
// An empty paragraph's mark formatting, its size giving its height.
|
||||
let mark = p.mark.as_deref().filter(|_| p.inlines.is_empty()).map(super::writer::props::props_text).unwrap_or_default();
|
||||
// A paragraph without text: its mark formatting, its size giving its height.
|
||||
let mark = p.mark.as_deref().filter(|_| p.textless()).map(super::writer::props::props_text).unwrap_or_default();
|
||||
let hyphenate = p.extra.as_ref().and_then(|x| x.suppress_hyphens) == Some(false);
|
||||
if hyphenate || !mark.is_empty() {
|
||||
props.push('\u{2}');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# File-format parity with Microsoft Word
|
||||
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-11-02 · **Change:** trivial (ODT tables fit the margins and keep their space above and below; header spacing kept); previously trivial (ODT frames anchored and placed by their style); previously trivial (ODT default font size saved; page-anchored frames placed from the page; text box paragraph styles kept; empty paragraphs keep their size); previously trivial (ODT default font size; locale-ordered dates); previously trivial (ODT page background pictures); previously trivial (ODT tables fixed layout; tables starting a page); previously trivial (emphasis marks: model, layout, DOCX `w:em`, ODT `style:text-emphasize`, `format.emphasisMark`); previously trivial (ODT variables as SET/REF fields; character styles keep what they turn off); previously trivial (ODT styles keep what they turn off; WMF/EMF pictures kept; pictures in text boxes shown by LibreOffice); previously trivial (ODT unstated page margins are LibreOffice's 2 cm; drawings outside a paragraph join the next one); previously trivial (ODT placeholders as content controls, template dates, user name fields, unsized pages, style-only templates, found with LibreOffice's own templates); previously trivial (ODT hidden form controls kept; `.ott` templates opened and saved); previously trivial (ODT fidelity re-estimated at ~90%; a kept form control made another kind is saved as that kind); previously trivial (ODT form control sizes and buttons kept); previously trivial (ODT turned text in cells and text boxes); previously trivial (ODT macros and unknown package parts kept); previously trivial (ODT table cell formulas as formula fields); previously trivial (ODT custom shapes drawn from their own geometry); previously trivial (ODT bibliography marks as citations of sources); previously trivial (ODT linked text boxes); previously trivial (ODT picture crops and contour wrapping); previously trivial (ODT fidelity re-estimated at ~85%); previously trivial (ODT custom document properties and user fields as DOCPROPERTY); previously trivial (ODT connectors read and written glued); previously trivial (ODT borders around text read and written); previously trivial (ODT index marks read and written as XE fields; an index held around its entries updates); previously trivial (ODT ruby read and written); previously trivial (ODT page breaks after a paragraph, kept lines, widow control, hyphenation, table alignment and width and row heights); previously trivial (in-line drawings raised or lowered by their run's position; ODT in-line frames keep their place on the baseline; leading's space after the last line; text box borders shown by LibreOffice); previously trivial (ODT form controls opened and saved as content controls); previously trivial (password-protected ODT opened and saved); previously trivial (ODT headers and footers keep their shapes, text boxes, charts and embedded objects on save); previously trivial (ODT embedded spreadsheets and OLE objects kept whole instead of lost; flat ODT sub-documents valid `office:document`s); previously trivial (ODT charts in drawing groups drawn on open); previously trivial (ODT charts opened and saved as editable charts; flat ODT sub-documents no longer end the body); previously trivial (ODT leading read as an at-least spacing); previously trivial (ODT tracked formatting changes; changed regions named by `xml:id`); previously trivial (ODT drop caps; tab stops no longer drop a paragraph's background); previously trivial (flat ODT `.fodt` opened and saved; ODT fidelity re-estimated at ~80%); previously trivial (ODT page settings; a footnote no longer takes a footer's text); previously trivial (ODT dates in their formats, sequences, chapters and references); previously trivial (ODT bookmarks over text); previously trivial (ODT tables of contents and indexes; ODT fidelity re-estimated); previously trivial (ODT polygons, polylines and paths); previously trivial (ODT arrowheads, dashes and gradients); previously trivial (ODT groups of shapes and pictures); previously trivial (ODT rotated and mirrored shapes and pictures); previously trivial (ODT drawing shapes read and written); previously trivial (ODT text box frames keep their line, fill, padding and fit); previously trivial (ODT Asian and complex-script fonts); previously trivial (ODT right-to-left paragraphs); previously trivial (ODT text boxes kept); previously trivial (ODT unnumbered headings detached from the outline); previously trivial (ODT contextual spacing and layout settings); previously trivial (ODT custom character styles kept); previously trivial (ODT list level positions); previously trivial (ODT custom paragraph styles kept); previously trivial (ODT equations written as formula objects); previously trivial (ODT numbered headings written as headings); previously trivial (ODT floating pictures); previously trivial (ODT paragraph borders and background); previously trivial (ODT heading numbering); previously trivial Line truncated
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-11-02 · **Change:** trivial (ODT pictures alone in a paragraph keep its size; in-line frames raised under an inherited paragraph relation); previously trivial (ODT tables fit the margins and keep their space above and below; header spacing kept); previously trivial (ODT frames anchored and placed by their style); previously trivial (ODT default font size saved; page-anchored frames placed from the page; text box paragraph styles kept; empty paragraphs keep their size); previously trivial (ODT default font size; locale-ordered dates); previously trivial (ODT page background pictures); previously trivial (ODT tables fixed layout; tables starting a page); previously trivial (emphasis marks: model, layout, DOCX `w:em`, ODT `style:text-emphasize`, `format.emphasisMark`); previously trivial (ODT variables as SET/REF fields; character styles keep what they turn off); previously trivial (ODT styles keep what they turn off; WMF/EMF pictures kept; pictures in text boxes shown by LibreOffice); previously trivial (ODT unstated page margins are LibreOffice's 2 cm; drawings outside a paragraph join the next one); previously trivial (ODT placeholders as content controls, template dates, user name fields, unsized pages, style-only templates, found with LibreOffice's own templates); previously trivial (ODT hidden form controls kept; `.ott` templates opened and saved); previously trivial (ODT fidelity re-estimated at ~90%; a kept form control made another kind is saved as that kind); previously trivial (ODT form control sizes and buttons kept); previously trivial (ODT turned text in cells and text boxes); previously trivial (ODT macros and unknown package parts kept); previously trivial (ODT table cell formulas as formula fields); previously trivial (ODT custom shapes drawn from their own geometry); previously trivial (ODT bibliography marks as citations of sources); previously trivial (ODT linked text boxes); previously trivial (ODT picture crops and contour wrapping); previously trivial (ODT fidelity re-estimated at ~85%); previously trivial (ODT custom document properties and user fields as DOCPROPERTY); previously trivial (ODT connectors read and written glued); previously trivial (ODT borders around text read and written); previously trivial (ODT index marks read and written as XE fields; an index held around its entries updates); previously trivial (ODT ruby read and written); previously trivial (ODT page breaks after a paragraph, kept lines, widow control, hyphenation, table alignment and width and row heights); previously trivial (in-line drawings raised or lowered by their run's position; ODT in-line frames keep their place on the baseline; leading's space after the last line; text box borders shown by LibreOffice); previously trivial (ODT form controls opened and saved as content controls); previously trivial (password-protected ODT opened and saved); previously trivial (ODT headers and footers keep their shapes, text boxes, charts and embedded objects on save); previously trivial (ODT embedded spreadsheets and OLE objects kept whole instead of lost; flat ODT sub-documents valid `office:document`s); previously trivial (ODT charts in drawing groups drawn on open); previously trivial (ODT charts opened and saved as editable charts; flat ODT sub-documents no longer end the body); previously trivial (ODT leading read as an at-least spacing); previously trivial (ODT tracked formatting changes; changed regions named by `xml:id`); previously trivial (ODT drop caps; tab stops no longer drop a paragraph's background); previously trivial (flat ODT `.fodt` opened and saved; ODT fidelity re-estimated at ~80%); previously trivial (ODT page settings; a footnote no longer takes a footer's text); previously trivial (ODT dates in their formats, sequences, chapters and references); previously trivial (ODT bookmarks over text); previously trivial (ODT tables of contents and indexes; ODT fidelity re-estimated); previously trivial (ODT polygons, polylines and paths); previously trivial (ODT arrowheads, dashes and gradients); previously trivial (ODT groups of shapes and pictures); previously trivial (ODT rotated and mirrored shapes and pictures); previously trivial (ODT drawing shapes read and written); previously trivial (ODT text box frames keep their line, fill, padding and fit); previously trivial (ODT Asian and complex-script fonts); previously trivial (ODT right-to-left paragraphs); previously trivial (ODT text boxes kept); previously trivial (ODT unnumbered headings detached from the outline); previously trivial (ODT contextual spacing and layout settings); previously trivial (ODT custom character styles kept); previously trivial (ODT list level positions); previously trivial (ODT custom paragraph styles kept); previously trivial (ODT equations written as formula objects); previously trivial (ODT numbered headings written as headings); previously trivial (ODT floating piLine truncated
|
||||
|
||||
Every format Word opens or saves, what WordCraft does with it, and how it's tested. Fidelity is the
|
||||
share of a typical real-world file's content and formatting that survives (read: shows correctly;
|
||||
@@ -280,6 +280,7 @@ Custom document properties retain their bookmark link targets through DOCX saves
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-02 | trivial | ODT, found with LibreOffice's elegant agenda: a paragraph holding only pictures lost its own font size (the pictures' runs had none), so its line grew; the size is the paragraph mark's and the pictures' runs', read and written. An in-line frame's raise was dropped when a parent style gave it a relation no in-line frame has (`style:vertical-rel="paragraph"`); it's measured from the baseline, as LibreOffice reads it. The agenda's round-trip difference falls from 6,542 to 1,331 pixels (`floats::a_picture_alone_in_its_paragraph_keeps_its_raise_and_the_paragraphs_size`) |
|
||||
| 2026-11-02 | trivial | ODT, found with LibreOffice's report templates: a table filling the margins (`table:align="margins"`) wider than them ran off the page; it's fitted to them, as LibreOffice fits it. A table's own space above and below (`fo:margin-top`/`fo:margin-bottom`) was dropped; it's kept, laid out and written back. A header or footer taller than its band lost its spacing from the body, moving the text up; it's kept unless the spacing is dynamic (`style:dynamic-spacing`). One report template's round-trip difference falls from 7,646 to 602 pixels (`flow_breaks::a_tables_own_space_above_and_below_is_kept`, `a_tables_columns_keep_their_widths`, `headers::a_headers_spacing_stays_below_content_taller_than_it`) |
|
||||
| 2026-11-02 | trivial | ODT: a frame that doesn't say how it's anchored or where it sits takes both from its graphic style (`text:anchor-type`, `svg:x`, `svg:y` in `style:graphic-properties`). LibreOffice's business card holds its card in line by the Labels style and puts its credit at the top of the page by the Graphics style; WordCraft had floated the card, and a save gained a page (`floats::a_frames_style_gives_the_anchor_and_place_it_leaves_unsaid`) |
|
||||
| 2026-11-02 | trivial | ODT: saving wrote the default font size as 12 pt whatever the document's was, so LibreOffice's 11 pt letters gained a page after a save; Normal's size is written. A page-anchored frame placed "from the paragraph" (LibreOffice's letter logos) was moved by the page margin; it's placed from the page, and "from the paragraph's content" from the page's text area. A custom style naming only paragraphs in text boxes (the fax template's centred "Frame contents") was dropped, leaving them Normal; it's kept. An empty paragraph's own font size (its height: the fax's 6 pt line) was dropped; it's the paragraph mark's, read and written (`odt::tests::the_default_styles_font_size_is_the_documents`, `odt::tests::an_empty_paragraph_keeps_its_marks_size`, `floats::a_page_anchored_frames_paragraph_relations_are_the_pages`, `text_boxes::a_custom_style_only_in_a_text_box_is_kept`) |
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
# Where WordCraft falls short of Word
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-02 · **Change:** trivial (#19: no LibreOffice template changes page count through a save); previously trivial (#19: ODT variables, emphasis marks, page backgrounds, fixed tables, default size); previously trivial (#19: ODT checked against LibreOffice's own templates: placeholders, first-page styles, unsized pages, metafile logos, `.ott`); previously trivial (#19: ODT at ~90%: custom shapes, cell formulas, macros kept, turned text, control sizes and buttons); previously trivial (#19 narrowed: ODT read and written nearly whole; estimate 18–27 h → 10–16 h); previously trivial (#10 narrowed: text in a turned text box is drawn turned with it); previously trivial (gap 19 narrowed: ODT heading numbering read and written); previously trivial (gap 19 narrowed: ODT table borders and padding read and written); previously trivial (gap 19 narrowed: ODT heading style looks read and written); previously trivial (gap 19 narrowed: ODT tab stops read and written); previously trivial (gap 19 narrowed: ODT character formatting read and written); previously trivial (gap 19 narrowed: ODT list formats read and written); previously trivial (gap 19 narrowed: ODT comments read and written); previously trivial (gap 19 narrowed: ODT footnotes and endnotes read and written); previously trivial (gap 19 narrowed: ODT headers and footers written, text fields and paragraph spacing read and written); previously trivial (only the PDF sent to the printer leaves out link annotations; Save these pages as PDF keeps them, #4734; no ranked gap changed); previously trivial (documents with links print: the print job leaves out link annotations, #4734; no ranked gap changed; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion reference-run membership uses one ordered walk, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (gap 19: RTF reads and writes WMF and EMF pictures, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (View windows: several open documents and Switch Windows in the engine; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: text mini toolbar available with the right-click menu, #2959; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: tracked table/row/cell/section property changes record in WordCraft, narrowing gap 5; previously trivial: a document with many content controls saves in the time the controls take, #13; previously trivial: Format Page Numbers dialog carries Word's number formats and Continue from previous section / Start at, #1113; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: fixed font inputs in four layout controls; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial: Russian sorting keeps ё with е and recognises decomposed ё/й; previously trivial: #8: English dialects — en-GB, en-CA, en-AU… flag each other's spellings, #1281; previously trivial: #1: shape gradients and transparency, #1500; previously trivial: text typed into a content control takes the control's formatting; localized placeholder styles recognised; previously trivial: forms protection keeps its content controls: no inserting, Properties or Remove Content Control; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: line breaking: a slash opening a word travels whole to the next line, #2963; previously trivial: recipient list search and merged-only view, #1576; previously trivial: #2 impact restated: only ink rendering and OLE editing remain; previously trivial: #2 narrowed: native ink nested in groups and drawing canvaseLine truncated
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-02 · **Change:** trivial (#19: ODT tables' margins and spacing, header spacing, pictures alone in a paragraph); previously trivial (#19: no LibreOffice template changes page count through a save); previously trivial (#19: ODT variables, emphasis marks, page backgrounds, fixed tables, default size); previously trivial (#19: ODT checked against LibreOffice's own templates: placeholders, first-page styles, unsized pages, metafile logos, `.ott`); previously trivial (#19: ODT at ~90%: custom shapes, cell formulas, macros kept, turned text, control sizes and buttons); previously trivial (#19 narrowed: ODT read and written nearly whole; estimate 18–27 h → 10–16 h); previously trivial (#10 narrowed: text in a turned text box is drawn turned with it); previously trivial (gap 19 narrowed: ODT heading numbering read and written); previously trivial (gap 19 narrowed: ODT table borders and padding read and written); previously trivial (gap 19 narrowed: ODT heading style looks read and written); previously trivial (gap 19 narrowed: ODT tab stops read and written); previously trivial (gap 19 narrowed: ODT character formatting read and written); previously trivial (gap 19 narrowed: ODT list formats read and written); previously trivial (gap 19 narrowed: ODT comments read and written); previously trivial (gap 19 narrowed: ODT footnotes and endnotes read and written); previously trivial (gap 19 narrowed: ODT headers and footers written, text fields and paragraph spacing read and written); previously trivial (only the PDF sent to the printer leaves out link annotations; Save these pages as PDF keeps them, #4734; no ranked gap changed); previously trivial (documents with links print: the print job leaves out link annotations, #4734; no ranked gap changed; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion reference-run membership uses one ordered walk, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (gap 19: RTF reads and writes WMF and EMF pictures, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (View windows: several open documents and Switch Windows in the engine; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: text mini toolbar available with the right-click menu, #2959; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: tracked table/row/cell/section property changes record in WordCraft, narrowing gap 5; previously trivial: a document with many content controls saves in the time the controls take, #13; previously trivial: Format Page Numbers dialog carries Word's number formats and Continue from previous section / Start at, #1113; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: fixed font inputs in four layout controls; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial: Russian sorting keeps ё with е and recognises decomposed ё/й; previously trivial: #8: English dialects — en-GB, en-CA, en-AU… flag each other's spellings, #1281; previously trivial: #1: shape gradients and transparency, #1500; previously trivial: text typed into a content control takes the control's formatting; localized placeholder styles recognised; previously trivial: forms protection keeps its content controls: no inserting, Properties or Remove Content Control; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: line breaking: a slash opening a word travels whole to the next line, #2963; previously trivial: recipient list search and merged-only view, #1576; previously trivial: #2 impact restated: only ink renderinLine truncated
|
||||
> **Highlight update:** 2026-10-25 · Highlight shortcut toggles the last chosen colour off when the whole selection has it; explicit colour commands remain setters (#4085). Readiness estimates unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-29 · **Change:** trivial (aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (#15: bibliography sources keep a corporate author, #4848); previously trivial (Table Properties applies to the selected rows, columns and cells, #4857); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (#7: Custom Document Properties dialog, #2982; previously trivial: egui 0.37 migration: the interface catalogs stay shared and pinned by `craft-i18n.rev` at `9205108cfdced5177706264038848b68b2422d2b` (27 languages, English fallback); input-method handling has new regressions but managed CI passed, and native IME acceptance plus native-speaker catalog review remain open; previously trivial: Markdown code spans keep line-broken text literal, #3738; previously trivial: small follow-ups from the field, table and AutoFormat batch, #4232; previously trivial: highlight target includes selected paragraph marks, #4085; previously trivial: full-target highlight check beyond 10,000 runs, #4085; previously trivial: Exact-spacing table contact uses the specified line height rather than paragraph-mark metrics (#3977); previously trivial: cu20we: restrict pre-spacing float origins to paragraph anchors; document cap helpers and regressions; previously trivial: a command that changes nothing is not an edit: no undo step, no unsaved changes, no relayout, and the redo stack survives it; previously minor: #8 narrowed: Spanish proofing (Spain, Mexico, Latin America, Uruguay) from the installed Hunspell dictionaries, #3360, #3553; previously trivial: gap 10: group connector rerouting preserves transformed free and unresolved endpoints under nonuniform scaling; obstacle routing still missing; readiness estimates unchanged; previously trivial: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: the ranked gap list held two rows each for #19, #20 and #21; each gap appears once now; a document with many relationships opens in the time its part takes, #3411; previously trivial: the file commands that change the document are checked on a protected document, the protection of a protected document needs an explicit stop, the session author can't change through `file.setAuthor` under protection (the CLI's `--author` uses the same protection check), and the post-check compares the settings and the metadata; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: text mini toolbar available with the right-click menu, #2959; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: tracked table/row/cell/section property changes record in WordCraft, narrowing gap 5; previously trivial: a document with many content controls saves in the time the controls take, #13; previously trivial: Format Page Numbers dialog carries Word's number formats and Continue from previous section / Start at, #1113; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: fixed font inputs in four layout controls; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial: Russian sorting keeps ё with е and recognises decomposed ё/й; previously trivial: #8: English dialects — en-GB, en-CA, en-AU… flag each other's spellings, #1281; previously trivial: #1: shape gradients and transparency, #1500; previously trivial: text typed into a content control takes the control's formatting; localized placeholder styles recognised; previously trivial: forms protection keeps its content controls: no inserting, Properties or Remove Content Control; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: line breaking: a slash opening a word travels whole to the next line, #2963; previously trivial: recipient list search and merged-only view, #1576; previously trivial: #2 impact restated: only ink rendering and OLE editing remain; previously trivial: #2 narrowed: native ink nested in groups and drawing canvases kept on save; previously trivial: opening a DOCX no lonLine truncated
|
||||
|
||||
@@ -370,6 +370,7 @@ Recipient label generation (#4880) now includes all selected recipients across a
|
||||
| 2026-10-12 | trivial | #811: large-table scrolling fixed; performance gap (#20) narrowed |
|
||||
| 2026-10-12 | trivial | #13: radar, stock and other undrawn chart types show a placeholder instead of blank space (#998) |
|
||||
| 2026-10-19 | trivial | Personal templates in File › New and Save as Word Template (#2852); no gap entry tracked it |
|
||||
| 2026-11-02 | trivial | #19 narrowed: ODT tables filling the margins fit them and keep their own space above and below; header and footer spacing kept past a tall header; pictures alone in a paragraph keep its size and their raise. The corpus round-trip difference falls from 241k to 155k pixels. Left: paragraph padding without a border, cell background pictures (no Word equivalent), WordCraft's own height for a picture-only line |
|
||||
| 2026-11-02 | trivial | #19 narrowed: all 125 corpus documents keep their page count through a save (letters, faxes, business card): the default font size, page-anchored frames, text box styles, empty paragraphs' size and frames anchored by their style |
|
||||
| 2026-11-02 | trivial | #19 narrowed: ODT variables (as SET/REF, SET now evaluated), emphasis marks (new: model, layout, DOCX, ODT, command), page background pictures, fixed-width tables and tables starting a page, the default font size, styles turning off bold or italic |
|
||||
| 2026-11-02 | trivial | #19 narrowed: ODT round-trips all 78 of LibreOffice's bundled templates; placeholders as content controls, first-page page styles, unsized pages and LibreOffice's default margins, WMF/EMF pictures, hidden form controls and `.ott` templates done |
|
||||
|
||||
Reference in new issue
Block a user