mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-19 02:10:15 -05:00
Copy puts the formatted text on the system clipboard as HTML, not only copies with equations (#1523) (#1667)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
1 parent
b53796d412
commit
1c814e0269
8 files changed
+40
-22
No files matched your search
+2
-1
@@ -2,7 +2,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-10-14 · **Change:** trivial (progress log: grouped `flowChartOr` shapes draw their circle and crossing spokes; previously trivial: progress log: floating tables ignore empty line-break lines; previously trivial: progress log: comment deletion leaves no dangling anchors or replies, #1345; previously trivial: progress log: open DrawingML freeform paths draw their end arrowhead; previously trivial: progress log: full screen, #980; previously trivial: progress log: PAGE fields on the pages a paragraph runs onto, #1352; 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; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (progress log: grouped `flowChartOr` shapes draw their circle and crossing spokes; previously trivial: progress log: copies keep their formatting in other programs, #1523; 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; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
|
||||
> **Printing update:** 2026-10-12 · direct desktop printing through craft-print; details below.
|
||||
|
||||
@@ -178,6 +178,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
||||
| 2026-10-13 | Dragging a Square-wrapped shape or picture on a multi-column page wraps the text of the column it lands in around it, and its old place closes up (#884) |
|
||||
| 2026-10-13 | Pagination with footnotes follows Word (#1116): a paragraph ending on a page with footnotes keeps its space after above the separator, otherwise its last lines move to the next page with the note; pages without notes are unchanged |
|
||||
| 2026-10-13 | Interface size means what it says (#822): a chosen size is absolute, as in PhotoCraft and PdfCraft, so "100%" is one screen pixel per point even where the system reports 200 % (a bare window manager on X11, where winit guesses the scale from the monitor's DPI). The new default, Auto, keeps the system's display scale and its menu entry shows the size it draws at; sizes run 75–300 %. A saved size from before stays the same if it was the default (now Auto) and becomes absolute otherwise |
|
||||
| 2026-10-14 | Copied text keeps its formatting in other programs (#1523): Copy and Cut put HTML beside the plain text on the system clipboard for every selection, not only one holding an equation, so a browser, mail client or another word processor pastes bold, italic, fonts and sizes. RTF on the clipboard is not written yet |
|
||||
| 2026-10-13 | Copying an equation also puts MathML in HTML on the clipboard beside the linear text like `y=2x_s` (#816; Word/LibreOffice paste not yet verified; OMML is #1297). HTML export writes equations as MathML too, and opening or pasting HTML with MathML gives equations back |
|
||||
| 2026-10-13 | The Equation tab's galleries, structure buttons and symbols keep the theme's colours on Windows: their pictures share a few textures written in place (no wipe of pictures already on screen, room for the built-ins at high display scales), instead of hundreds of small textures freed in bulk, which on DirectX 12 showed inverted, red or teal tiles (#1002) |
|
||||
| 2026-10-13 | `file.close` over the control channel or MCP bridge no longer quits and discards unsaved changes (#1268): it returns an error unless the document is saved or `{"force": true}` is passed; the user's Save / Don't Save / Cancel prompt is unchanged |
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
//!
|
||||
//! Everything read here comes from other programs: sizes are capped as it is read.
|
||||
//!
|
||||
//! Written here: a copy holding an equation puts HTML (the equation as MathML) beside its text
|
||||
//! (#816), for programs that read MathML (pasting into Word and LibreOffice not yet verified). arboard sets HTML with a
|
||||
//! Written here: a copy puts HTML beside its text, so other programs keep its formatting (#1523),
|
||||
//! with equations as MathML (#816; pasting into Word and LibreOffice not yet verified). arboard sets HTML with a
|
||||
//! text alternative on every desktop platform; formats of other names (Word's "Office Open XML"
|
||||
//! with OMML, #1297) it can't, so they aren't offered.
|
||||
|
||||
|
||||
@@ -166,12 +166,12 @@ fn copy(s: &mut Session, _: &Value) -> CmdResult {
|
||||
Ok(copy_result(s))
|
||||
}
|
||||
|
||||
/// What Copy and Cut return: the clipboard's text, and HTML with the equations as MathML when
|
||||
/// the copy holds any (#816), for the host to put on the system clipboard too.
|
||||
/// What Copy and Cut return: the clipboard's text, and the copy as HTML (equations as MathML,
|
||||
/// #816) for the host to put on the system clipboard too, so other programs keep the formatting.
|
||||
pub(crate) fn copy_result(s: &mut Session) -> Value {
|
||||
s.clipboard_html = match &s.clipboard {
|
||||
Some(f) if f.has_equation() => wordcraft_formats::html::export_fragment(&f.to_document()),
|
||||
_ => String::new(),
|
||||
Some(f) => wordcraft_formats::html::export_fragment(&f.to_document()),
|
||||
None => String::new(),
|
||||
};
|
||||
if s.clipboard_html.is_empty() { json!({"text": s.clipboard_text}) } else { json!({"text": s.clipboard_text, "html": s.clipboard_html}) }
|
||||
}
|
||||
|
||||
@@ -351,8 +351,8 @@ pub struct Session {
|
||||
pub pending_move: Option<crate::cmd::moves::PendingMove>,
|
||||
/// Plain text mirror of the clipboard (for the system clipboard).
|
||||
pub clipboard_text: String,
|
||||
/// HTML for the system clipboard beside [`Self::clipboard_text`] when the copy holds an
|
||||
/// equation (as MathML, #816), for programs that read MathML; empty otherwise.
|
||||
/// HTML for the system clipboard beside [`Self::clipboard_text`]: the copy's formatting for
|
||||
/// programs that read HTML, equations as MathML (#816); empty when nothing was copied.
|
||||
pub clipboard_html: String,
|
||||
/// Items collected by Copy and Cut this session, for the Clipboard pane.
|
||||
pub clip_history: crate::cmd::edit::ClipHistory,
|
||||
|
||||
@@ -894,10 +894,23 @@ fn copying_an_equation_puts_mathml_on_the_clipboard() {
|
||||
run(&mut s, "edit.paste", json!({"text": clip, "html": html}));
|
||||
assert_eq!(equations(&s), vec!["y=2x_s".to_string(), "y=2x_s".to_string()]);
|
||||
|
||||
// A copy without an equation carries no HTML.
|
||||
// A copy without an equation carries HTML too (#1523).
|
||||
run(&mut s, "select.range", json!({"anchor": {"block": 0, "off": 0}, "focus": {"block": 0, "off": 5}}));
|
||||
let r = run(&mut s, "edit.copy", json!({}));
|
||||
assert!(r.get("html").is_none() && s.clipboard_html.is_empty(), "{r}");
|
||||
assert!(r["html"].as_str().is_some_and(|h| h.contains("Speed") && !h.contains("<math")), "{r}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copying_bold_text_puts_html_on_the_clipboard() {
|
||||
// #1523: formatted text reaches other programs as HTML, not only as plain text.
|
||||
let mut s = s();
|
||||
run(&mut s, "document.setText", json!({"text": "plain bold"}));
|
||||
s.doc.format_range(&Pos::body(0, 6), &Pos::body(0, 10), &|c| c.bold = Some(true)).unwrap();
|
||||
run(&mut s, "select.all", json!({}));
|
||||
let r = run(&mut s, "edit.copy", json!({}));
|
||||
let html = r["html"].as_str().unwrap_or_default().to_string();
|
||||
assert!(html.contains("<strong>bold</strong>"), "{html}");
|
||||
assert_eq!(s.clipboard_html, html);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -67,8 +67,8 @@ pub(crate) fn fill(app: &mut WordApp, id: &str, params: &mut Value) -> Option<Re
|
||||
None
|
||||
}
|
||||
|
||||
/// Put a copy on the system clipboard: its HTML beside the text when the copy has some (an
|
||||
/// equation as MathML, #816) and the host can set it, else the text through egui. egui sets its
|
||||
/// Put a copy on the system clipboard: its HTML beside the text (the formatting, #1523, and
|
||||
/// equations as MathML, #816) when the host can set it, else the text through egui. egui sets its
|
||||
/// text at the end of the frame, which would replace the HTML, so only one of them runs.
|
||||
pub(crate) fn put(app: &WordApp, ctx: &egui::Context, text: &str, html: &str) {
|
||||
if text.is_empty() {
|
||||
@@ -263,10 +263,12 @@ mod tests {
|
||||
let got_now = got.borrow().clone();
|
||||
assert_eq!(got_now.len(), 1);
|
||||
assert!(got_now[0].0.contains("<math") && got_now[0].1.contains("y=2x_s"), "{got_now:?}");
|
||||
// Plain text needs no HTML.
|
||||
// Text without an equation gets HTML too, so other programs keep its formatting (#1523).
|
||||
a.run("select.range", json!({"anchor": {"block": 0, "off": 0}, "focus": {"block": 0, "off": 5}})).unwrap();
|
||||
let r = a.run("edit.copy", json!({})).unwrap();
|
||||
put_result(&a, &ctx, &r);
|
||||
assert_eq!(got.borrow().len(), 1);
|
||||
let got_now = got.borrow().clone();
|
||||
assert_eq!(got_now.len(), 2);
|
||||
assert!(got_now[1].0.contains("Speed") && !got_now[1].0.contains("<math") && got_now[1].1 == "Speed", "{got_now:?}");
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -1,6 +1,6 @@
|
||||
# Where WordCraft falls short of Word
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (floating-table overlap ignores empty line-break lines; previously trivial: gap #3: dragging a Behind Text picture or shape over text now works, in the body and headers, and plain clicks still reach the text; previously trivial: crop handles on the canvas landed; previously trivial: re-audited every row against main: stale PR and issue states, counts and landed items corrected; previously trivial: Windows Magnifier follows the caret onto a new line, #1119; previously trivial: sample-text formulas on Enter, #1067; previously trivial: #29: copied equations as MathML, OMML open as #1297, #816; previously trivial: the Font list no longer keeps every previewed font in memory, #848; 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 Table and Eraser landed, #303; previously minor: beta distance restated: ~15 points, ~150–230 h; previously: first version; every known shortfall from the 2026-10-10 re-measure, ranked) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (floating-table overlap ignores empty line-break lines; previously trivial: copies keep their formatting on the clipboard as HTML, #1523; previously trivial: sample-text formulas on Enter, #1067; previously trivial: #29: copied equations as MathML, OMML open as #1297, #816; previously trivial: the Font list no longer keeps every previewed font in memory, #848; 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 Table and Eraser landed, #303; previously minor: beta distance restated: ~15 points, ~150–230 h; previously: first version; every known shortfall from the 2026-10-10 re-measure, ranked) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
|
||||
> **Printing update:** 2026-10-12 · direct desktop printing through craft-print; details below.
|
||||
|
||||
@@ -52,7 +52,7 @@ Document renaming: desktop renaming requires a filesystem that supports hard lin
|
||||
| 27 | **View windows**: Side by Side, Synchronous Scrolling, Arrange All, Switch Windows | | [parity-checklist.md](parity-checklist.md) (View 25/29); PR #331 open | Comparing documents | 3–5 | [ui-parity.md](ui-parity.md) |
|
||||
| 26 | **Minor formats**: MHT, Works/WordPerfect | | Word XML Document (Flat OPC) opens and saves, Word 2003 XML opens (#548) and saves (#1081, not yet checked in Word) | Rare | 14–26 | [file-format-parity.md](file-format-parity.md) |
|
||||
| 28 | **Dictate** | | `tools.dictate` missing | Dictation users | 8–15 + owner (speech model) | [hardware-parity.md](hardware-parity.md) |
|
||||
| 29 | **Equations**: ink equations; copied equations as OMML for Word (#816, #1297) | | #191 notes; long display equations wrap at operators (#326); a copy holding an equation puts MathML in HTML on the clipboard (#816; Word/LibreOffice paste not yet verified); only copies containing an equation get HTML, text-only copies stay plain | Maths-heavy documents | 2–3 | [layout-parity.md](layout-parity.md) |
|
||||
| 29 | **Equations**: ink equations; copied equations as OMML for Word (#816, #1297) | | #191 notes; long display equations wrap at operators (#326); a copy holding an equation puts MathML in HTML on the clipboard (#816; Word/LibreOffice paste not yet verified) | Maths-heavy documents | 2–3 | [layout-parity.md](layout-parity.md) |
|
||||
|
||||
**Beta needs #1–#7** (~150–230 h with the stability and layout work they imply): they are the
|
||||
blocking gaps, and closing them lifts file formats, layout, stability and UI enough to take the
|
||||
@@ -70,11 +70,11 @@ The same gaps grouped the way the parity documents are, for agents working in on
|
||||
styles, and Draw Table and Eraser (#303) landed on 2026-10-10. Paste from other programs keeps
|
||||
their formatting (system clipboard HTML/RTF), Merge Formatting keeps emphasis, Paste Special lists
|
||||
what the system clipboard holds, and Linux/Wayland clipboard pictures paste (#687, #833);
|
||||
still missing: the Paste Options button after a paste, and RTF on macOS and X11. Copying an
|
||||
equation puts MathML in HTML on the clipboard (#816; pasting into Word/LibreOffice not yet
|
||||
verified; OMML on the clipboard is #1297); only copies containing an equation get HTML,
|
||||
text-only copies stay plain text.
|
||||
- **UI/UX gaps:** #7, #18, #24; context menus for objects (the table's landed; it still lacks Border Styles); Linux title bar theming (#78); File ›
|
||||
still missing: the Paste Options button after a paste, and RTF on macOS and X11. Copy puts
|
||||
HTML beside the text on the clipboard, so other programs keep the formatting (#1523), with
|
||||
equations as MathML (#816; pasting into Word/LibreOffice not yet verified; OMML on the
|
||||
clipboard is #1297); RTF on the clipboard is not written yet.
|
||||
Options › Animation effects › Use system setting reads macOS (Reduce motion) and the Linux/BSD
|
||||
desktops (`apps/wordcraft/src/animations.rs`) but hasn't been tried on a Mac or in a real
|
||||
GNOME or KDE session yet.
|
||||
@@ -174,6 +174,7 @@ The same gaps grouped the way the parity documents are, for agents working in on
|
||||
| 2026-10-10 | trivial | #10: Tight and Through wrapping follow the object's outline (#354) |
|
||||
| 2026-10-10 | trivial | #10: free rotation and flips for pictures, shapes and text boxes, with a rotation handle (#332); text boxes rotate their frame; their text stays upright |
|
||||
| 2026-10-10 | trivial | #10: Drawing Canvas landed (#344); in-canvas dragging of members remains |
|
||||
| 2026-10-14 | trivial | Feature gaps: every copy puts HTML beside its text on the clipboard, not only copies with an equation (#1523); writing RTF stays open |
|
||||
| 2026-10-13 | trivial | #29: copied equations reach the clipboard as MathML in HTML (#816); OMML for Word stays open (#1297) |
|
||||
| 2026-10-10 | trivial | #29: long display equations wrap across lines (#326) |
|
||||
| 2026-10-10 | trivial | #3: Windows lag on GPUs without a DirectX 12 driver fixed with an OpenGL fallback (#316) |
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
# UI parity with Microsoft Word
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (Page Setup vertical alignment, #1320; previously trivial: the Save Changes prompt takes the keyboard from the page, #1597; previously trivial: no document behind the Start screen, #1129; previously trivial: equation pictures share a few textures, #1002; previously trivial: selection bar in the left margin, #856; 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 major: first version; ribbon, dialogs, shortcuts and on-canvas interaction measured from `crates/ui-egui` and the command registry) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** trivial (Page Setup vertical alignment, #1320; previously trivial: copies keep their formatting on the clipboard as HTML, #1523; previously trivial: no document behind the Start screen, #1129; previously trivial: equation pictures share a few textures, #1002; previously trivial: selection bar in the left margin, #856; 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 major: first version; ribbon, dialogs, shortcuts and on-canvas interaction measured from `crates/ui-egui` and the command registry) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4
|
||||
|
||||
How WordCraft looks and feels next to Word: ribbon, dialogs, panes, keyboard, mouse and touch.
|
||||
Typing behaviour has its own checklist ([`typing-parity.md`](typing-parity.md)). All assets are our
|
||||
@@ -63,6 +63,7 @@ Document title opens Rename Document; the account badge opens Options › Genera
|
||||
| 2026-10-12 | trivial | Document title opens Rename Document; the account badge opens Options › General for user name and initials. |
|
||||
| 2026-10-13 | trivial | Magnifiers: a line's end mark (paragraph mark or line break) takes room in what the canvas tells assistive technology, so Windows Magnifier, which places the caret by the character after it, follows the caret onto an empty line after Enter or Shift+Enter instead of staying on the line above (#1119) |
|
||||
| 2026-10-14 | trivial | Save Changes prompt: Save takes focus from the page too, so after typing the arrow keys, Tab and Enter answer it instead of moving the caret behind it (#1597) |
|
||||
| 2026-10-14 | trivial | Copy and Cut put HTML beside the text on the system clipboard for every selection, not only one holding an equation, so pasting into a browser, mail client or another word processor keeps bold, italic, fonts and sizes (desktop, through arboard; Wayland without data-control and the web: text only) (#1523) |
|
||||
| 2026-10-13 | trivial | The caret is black or white by contrast with the paper, page colour, dark page, shading or highlight under it (#299) |
|
||||
| 2026-10-13 | trivial | Clicks on ribbon and status-bar chrome that run no command button (Styles and style-set gallery tiles, tab names, empty ribbon space, View check boxes, the status bar's view buttons and language menu) no longer take keyboard focus from the page: the caret stays and typing continues, as in Word; text fields such as the font size box still take focus. Tabs, gallery tiles and the status bar's view buttons report their name and state to screen readers (#1093) |
|
||||
| 2026-10-13 | trivial | Interface size: a chosen size is absolute ("100%" is one screen pixel per point, even where the system reports 200 % under a bare window manager) and the new default, Auto, keeps the display scale and shows the size it draws at; 75–300 %; an old saved size becomes the size it drew at; on the web a chosen size cancels browser zoom, Auto follows it (#822) |
|
||||
|
||||
Reference in new issue
Block a user