mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-24 10:27:44 -06:00
* #1765: WIP * #1765: ASK and SET fields show nothing Like Word, ASK and SET only assign text to a bookmark: they draw no result on the page or in a PDF. The stored result is kept and saved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * file-format-parity: note ASK/SET on the existing Fields row instead of a third one --------- Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
Dmitrii Khlapov
Brandon Thomas
parent
11f1d0aee6
commit
3348e93140
@@ -138,6 +138,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
||||
|
||||
| Date | What landed |
|
||||
| 2026-10-14 | RTF export writes every section (gap 19): `\sect` ends each section and `\sectd` carries its break type, page size and orientation, margins, columns, page numbering and title page, so multi-section documents survive an RTF round trip |
|
||||
| 2026-10-14 | `ASK` and `SET` fields no longer show their stored result on the page or in PDFs (#1765): like Word, they only assign text to a bookmark and draw nothing; the stored result is kept and saved |
|
||||
| 2026-10-14 | ODT export writes sections (gap 19): every new-page section gets its own page layout and master page (the first stays "Standard"), named by its first paragraph or table with the page-numbering restart; a continuous section with columns is written as a columned `text:section`, so a landscape, two-column or restarted part survives a save as .odt |
|
||||
| 2026-10-14 | A bulleted or numbered list item that starts with a lower-case word no longer gets the grammar squiggle for a missing sentence capital (#1741): list items are often fragments, so the sentence-capital rule (every proofed language) skips the first word of a list paragraph (own or style numbering); later sentences in the item are still checked |
|
||||
| 2026-10-16 | The Spike, as in Word: Ctrl+F3 (⌘F3 on macOS) cuts the selection and adds it to the end of the Spike, each piece followed by a paragraph mark; Ctrl+Shift+F3 (⌘⇧F3) inserts everything collected, in order and with its formatting, and empties the Spike. The clipboard is left alone; each is one undo step. The Spike is the AutoText entry "Spike", so Insert › Quick Parts inserts it without emptying it. It lasts for the session (Word keeps it in Normal.dotm) |
|
||||
@@ -468,6 +469,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
||||
| 2026-10-15 | trivial | Progress log: image size limits checked before allocation (#1321) |
|
||||
| 2026-10-17 | trivial | Progress log: Read Aloud speaks each sentence in its own language, #1843 |
|
||||
| 2026-10-17 | trivial | Language dialog keeps inherited proofing language and no-proof choices (#2717); readiness estimates unchanged |
|
||||
| 2026-10-14 | trivial | Progress log: ASK and SET fields show nothing (#1765) |
|
||||
| 2026-10-14 | trivial | Progress log: ODT sections on export (gap 19) |
|
||||
| 2026-10-17 | trivial | Explicit DrawingML preset/custom outline dashes survive import/save and paint in raster/PDF, scaled to the effective stroke width even for zero-width paths. Synthetic controls; theme-inherited dashes and line caps remain unverified. |
|
||||
| 2026-10-15 | trivial | `wordcraft-cli convert --update-fields` explicitly refreshes unlocked fields before conversion; ordinary conversion keeps cached results. Field refresh can change pagination |
|
||||
|
||||
@@ -299,6 +299,30 @@ mod tests {
|
||||
out
|
||||
}
|
||||
|
||||
/// #1765: ASK and SET fields draw nothing on the page; their stored results are kept (and
|
||||
/// saved), and code view still shows them.
|
||||
#[test]
|
||||
fn ask_and_set_fields_draw_nothing() {
|
||||
let mut s = Session::new(wordcraft_doc::Document::new());
|
||||
s.run("insert.field", &json!({"instr": "ASK Nominativo \"Inserire nome\" \\d \"N\"", "result": "«NOME» «COGNOME»"})).unwrap();
|
||||
s.run("insert.field", &json!({"instr": "SET Codice \"COD\"", "result": "COD"})).unwrap();
|
||||
s.run("text.insert", &json!({"text": "Title"})).unwrap();
|
||||
let shown = page_text(&mut s);
|
||||
assert!(!shown.contains("NOME") && !shown.contains("COD"), "{shown}");
|
||||
let para = s.doc.para(wordcraft_doc::StoryRef::Body, &wordcraft_doc::Path::top(0)).unwrap();
|
||||
let results: Vec<&str> = para
|
||||
.objects
|
||||
.iter()
|
||||
.filter_map(|o| match o {
|
||||
InlineObject::Field { result, .. } => Some(result.as_str()),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(results, ["«NOME» «COGNOME»", "COD"]);
|
||||
s.run("view.fieldCodes", &json!({})).unwrap();
|
||||
assert!(page_text(&mut s).contains("{ SET Codice \"COD\" }"));
|
||||
}
|
||||
|
||||
/// Alt+F9 shows every field's code in braces; Shift+F9 flips just the selected one; F9 shows
|
||||
/// its result again.
|
||||
#[test]
|
||||
|
||||
@@ -179,6 +179,8 @@ pub fn field_text_on(instr: &str, result: &str, ctx: &FieldCtx, page: u32) -> (S
|
||||
"TITLE" if result.is_empty() => (ctx.title.to_string(), false),
|
||||
"AUTHOR" if result.is_empty() => (ctx.author.to_string(), false),
|
||||
"FILENAME" if result.is_empty() => (ctx.filename.to_string(), false),
|
||||
// ASK and SET only assign text to a bookmark: they never show a result (ECMA-376 §17.16.5).
|
||||
"ASK" | "SET" => (String::new(), false),
|
||||
"STYLEREF" => match &ctx.styleref {
|
||||
Some((ix, at)) => (ix.eval(instr, *at), true),
|
||||
None => (result.to_string(), false),
|
||||
@@ -235,6 +237,17 @@ mod tests {
|
||||
assert_eq!(field_code_text(""), "{ }");
|
||||
}
|
||||
|
||||
/// #1765: ASK and SET only assign text to a bookmark; they show nothing, whatever result is stored.
|
||||
#[test]
|
||||
fn ask_and_set_show_nothing() {
|
||||
let ctx = FieldCtx::default();
|
||||
assert_eq!(field_text(r#" ASK Nominativo "Inserire nome" \d "«NOME»" "#, "«NOME» «COGNOME»", &ctx), (String::new(), false));
|
||||
assert_eq!(field_text(r#"SET Codice "COD""#, "COD", &ctx), (String::new(), false));
|
||||
assert_eq!(field_text("set Codice COD", "COD", &ctx).0, "");
|
||||
// Other fields still show their stored result.
|
||||
assert_eq!(field_text("MERGEFIELD NOME", "«NOME»", &ctx).0, "«NOME»");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn page_references_show_their_bookmarks_page() {
|
||||
let pages = HashMap::from([("End_1".to_string(), (3, NumFormat::Decimal)), ("Intro".to_string(), (4, NumFormat::LowerRoman))]);
|
||||
|
||||
@@ -78,7 +78,7 @@ Measured by grepping `crates/docx/src/read` and `src/write` for the OOXML elemen
|
||||
| Tracked insertions and deletions (`w:ins`/`w:del`), paragraph-mark revisions | ✅ | ✅ | #125, #244 |
|
||||
| Formatting revisions (`w:rPrChange`, `w:pPrChange`, `w:sectPrChange`, `w:tblPrChange`, `w:trPrChange`, `w:tcPrChange`, `w:numberingChange`) | ✅ | ✅ | #41: kept on open and save, schema order (change element last); changes inside `styles.xml` are dropped. RTF/ODT ignore them |
|
||||
| Move tracking (`w:moveFrom`/`w:moveTo`, `w:moveFromRangeStart/End`, `w:moveToRangeStart/End`), moved paragraph marks | ✅ | ✅ | #400: both ends linked by the range name; ranges rewritten around each moved stretch (ids renumbered); a move missing an end or a range end opens as a plain deletion/insertion. `w:doNotTrackMoves` (Track moves off) round-trips; with it a tracked cut and paste records a plain deletion and insertion. ODT/PDF export the result (moved-away text hidden like deletions); RTF writes a move as a plain tracked deletion and insertion |
|
||||
| Fields (`w:fldChar`, `w:fldSimple`), TOC, cross-references, `ADDIN` citations | ✅ | ✅ | Field codes Word supports but we don't evaluate keep their cached result. Imported TOCs preserve actual result boundaries, formatted entries and nested fields without relying on TOC styles. `EQ \o` (overstrike, enclosed characters) is drawn; enclosed characters are written as Word stores them, their style in the code's run sizes (#297); a cached picture (`INCLUDEPICTURE`) stays as the content of a range field (#465) |
|
||||
| Fields (`w:fldChar`, `w:fldSimple`), TOC, cross-references, `ADDIN` citations | ✅ | ✅ | Field codes Word supports but we don't evaluate keep their cached result; `ASK` and `SET` keep it but show nothing, as in Word (#1765). Imported TOCs preserve actual result boundaries, formatted entries and nested fields without relying on TOC styles. `EQ \o` (overstrike, enclosed characters) is drawn; enclosed characters are written as Word stores them, their style in the code's run sizes (#297); a cached picture (`INCLUDEPICTURE`) stays as the content of a range field (#465) |
|
||||
| Fields (`w:fldChar`, `w:fldSimple`), TOC, cross-references, `ADDIN` citations | ✅ | ✅ | Field codes Word supports but we don't evaluate keep their cached result. Textual `REF` fields with `\h` export internal PDF links without refreshing cached text; existing enclosing links take precedence. `wordcraft-cli convert --update-fields` explicitly runs field updates before saving; ordinary conversion preserves caches and locked fields stay unchanged. Instruction-only paragraphs carry hidden marks instead of blank lines; an empty result paragraph keeps its line. Imported TOCs preserve actual result boundaries, formatted entries and nested fields without relying on TOC styles. `EQ \o` (overstrike, enclosed characters) is drawn; enclosed characters are written as Word stores them, their style in the code's run sizes (#297); a cached picture (`INCLUDEPICTURE`) stays as the content of a range field (#465) |
|
||||
| Move tracking (`w:moveFrom`/`w:moveTo`, `w:moveFromRangeStart/End`, `w:moveToRangeStart/End`), moved paragraph marks | ✅ | ✅ | #400: both ends linked by the range name; ranges rewritten around each moved stretch (ids renumbered); a move missing an end or a range end opens as a plain deletion/insertion. ODT/PDF export the result (moved-away text hidden like deletions); RTF writes a move as a plain tracked deletion and insertion |
|
||||
| Content controls (`w:sdt`) | ✅ | ✅ | Block, inline, row and cell level, nested; title, tag, id, lock, placeholder, temporary, rich/plain text, `w14:checkbox`, combo box, drop-down list, date, picture, building block gallery, `w15` repeating sections; other `w:sdtPr` children (data binding, appearance) kept verbatim (#381). A TOC's control is rebuilt by the TOC. Replace All respects content-edit and control-deletion locks and refuses a batch before making any edit |
|
||||
@@ -224,6 +224,7 @@ Imported text fields use the first nonempty cached result run's formatting on th
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-14 | trivial | RTF export writes sections: `\sectd` formatting and `\sect` per section, round-tripping through the reader (gap 19) |
|
||||
| 2026-10-14 | trivial | `ASK` and `SET` fields keep their result but show nothing (#1765) |
|
||||
| 2026-10-14 | trivial | ODT export writes sections: each new-page section gets its own page layout and master page (the first stays "Standard"), named by its first paragraph or table with the page-numbering restart; a continuous section with columns is a columned `text:section` (gap 19) |
|
||||
| 2026-10-17 | trivial | Paste: an HTML `<blockquote>` (LibreOffice's both-sides indent) pastes as a Normal paragraph with its margins as indents, not the centred italic Quote style; opening .html unchanged (#1270) |
|
||||
| 2026-10-15 | trivial | `wordcraft-cli convert --update-fields` explicitly refreshes unlocked fields before conversion; ordinary conversion keeps cached results. Field refresh can change pagination |
|
||||
|
||||
Reference in New Issue
Block a user