mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-25 02:47:33 -06:00
* Zotero 1: range fields and custom document properties round-trip Citation managers' ADDIN fields (Zotero, Mendeley, EndNote) are now kept as range fields: FieldStart/FieldEnd markers with the result as ordinary, formatted content between them, possibly spanning paragraphs (a Zotero bibliography). Before, the result was flattened to plain text and a multi-paragraph field lost its end. - doc: InlineObject::FieldStart/FieldEnd, Document::field_ranges, balance_field_ranges; CustomProp and custom_props with get/set/remove. - docx: read ADDIN fields as ranges (field codes up to 2 MiB), write them back as begin/instr/separate…end; orphan markers are dropped on save so files always hold whole fields. docProps/custom.xml is parsed and regenerated (simple types as text, vectors/blobs verbatim) instead of passed through, so Zotero's ZOTERO_PREF_n settings are editable. - engine: file.properties reads and sets custom properties. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero 2: wire-protocol client and document bridge New crate wordcraft-zotero (L5) speaks Zotero's published word-processor protocol (port 23116; 32-bit transaction id + big-endian length frames, JSON payloads, ERR: replies): - client: sends an integration command (addEditCitation, addEditBibliography, addNote, refresh, removeCodes, setDocPrefs) and answers Zotero's calls until Document_complete or the connection closes (cancelled dialog). Answers go through a callback so the app can apply them on its UI thread; run_on_session answers directly. - Bridge: implements Zotero's Document_*/Field_* calls on a Session. Fields are stored as Word's plugin stores them (ADDIN ZOTERO_ range fields; prefs in ZOTERO_PREF_n, with Zotero's ReferenceMark field type kept as Word's Field in the file), so documents stay Word-compatible. Rich text (RTF or HTML) keeps citation formatting; bibliographies get a Bibliography style from setBibliographyStyle; note styles create footnotes/endnotes, and deleting a lone note citation removes its note; placeholder links convert to fields. One transaction = one undo step. Field ids stay stable through inserts and deletes. - Tests: a fake Zotero over a real socket, every call, docx round trip, hostile arguments for every method, random frames (proptest). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero 3: Zotero in the app and the CLI, tested with the real Zotero - ui.zotero.<command> (addEditCitation, addEditBibliography, addNote, refresh, removeCodes, setDocPrefs), ui.zotero.status and ui.zotero.answer. The socket runs on a background thread; each of Zotero's calls is answered on the UI thread against the session, and Zotero's questions become a dialog the session waits on. Web builds report that Zotero needs the desktop app. - wordcraft-cli zotero <command> <file> [--save] [--trace] [--port]. - Bridge: a selection Zotero makes to show a citation is put back when the session ends. - ui_shot: {"wait": ms} keeps frames running for background work. - docs/zotero.md. Checked against Zotero 10.0.6: refresh of a citation and bibliography (APA), its "modified citation" question answered in the app's dialog, RTF results with italics, Bibliography style, prefs round trip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero 4: switching between in-text and note styles moves citations Document_convert and Field_convert now move a citation between the text, footnotes and endnotes, as Zotero asks when the document's style changes between an in-text and a note style: into a new note at the same place, or back into the text where the note mark was (removing a note that held only the citation; keeping one with other text). Field ids survive the move, formatting is kept, and each Zotero session stays one undo step. Checked against Zotero 10.0.6: unlink citations (removeCodes, with its confirmation question) and a refresh after switching the document to Chicago notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero 5: Zotero tab in the ribbon A Zotero tab (before Help) with Add/Edit Citation, Add Note, Add/Edit Bibliography, Refresh, Document Preferences and Unlink Citations. The buttons are disabled while a Zotero command is running and in the web build. Three new icons drawn in code (document preferences, unlink, add note); the others reuse the References tab's. Labels and status messages translated (zh-hans, zh-hant, ja). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero: Add/Edit Bibliography inserted nothing Zotero reads a newly inserted bibliography field back before filling it, and unlinks a field whose text is empty, taking it for a bibliography the user deleted. Our new fields were empty, so Add/Edit Bibliography ended with Field_removeCode and nothing in the document. New fields now hold "{Citation}" until Zotero writes the result. Found by tracing the session with Zotero 10.0.6; regression test added. wordcraft-cli zotero takes --cmd (run before the Zotero command, e.g. caret.docEnd) to reproduce sessions from a given caret position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Zotero: log each command's outcome and Zotero's calls to the app log Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read Aloud player: speed, previous/next sentence, skips citations Read Aloud now speaks sentence by sentence with the system speech program (say / espeak / Windows SAPI) on a worker thread, so it can pause, skip and change speed. A floating player window has previous / play-pause / next / stop, a 0.5-3x speed slider and "Skip citations & bibliography" (on by default: Zotero, Mendeley, EndNote and Word citation fields). The spoken sentence is highlighted and the caret follows it. New commands: readAloud.playPause/next/previous/stop/speed/ skipCitations/status, and caret.pastCitation (Zotero > Move Past Citation). Speed and skip preference persist with the UI prefs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cargo.lock: wordcraft-zotero at the workspace version (0.4.0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read Aloud: no unused BASE_WPM warning on wasm Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Read Aloud: fuzz review.readAloud in hostile_params_never_panic #190 makes the engine's speech backend silent (Hold) under cfg(test), so the #75 skip is no longer needed; assert the backend instead so a test can never start the system synthesiser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
68 lines
3.5 KiB
Markdown
68 lines
3.5 KiB
Markdown
# Zotero
|
||
|
||
WordCraft works with the [Zotero](https://www.zotero.org) desktop app the way Word does: Zotero's
|
||
own citation dialog, all of its citation styles, automatic bibliography and refresh. Nothing to
|
||
install in Zotero; it only has to be running. The **Zotero** tab in the ribbon has the buttons:
|
||
Add/Edit Citation, Add Note, Add/Edit Bibliography, Refresh, Document Preferences and Unlink
|
||
Citations (each runs one of the commands below).
|
||
|
||
## Commands
|
||
|
||
| Command | What it does |
|
||
|---|---|
|
||
| `ui.zotero.addEditCitation` | Add a citation at the caret, or edit the one the caret is in |
|
||
| `ui.zotero.addEditBibliography` | Add the bibliography at the caret, or edit it |
|
||
| `ui.zotero.refresh` | Update every citation and the bibliography |
|
||
| `ui.zotero.setDocPrefs` | Citation style, language, footnotes or in-text |
|
||
| `ui.zotero.removeCodes` | Unlink citations: keep the text, drop Zotero's codes |
|
||
| `ui.zotero.addNote` | Insert a Zotero note |
|
||
| `ui.zotero.status` | `{busy, waitingForAnswer, last}` |
|
||
| `ui.zotero.answer` | `{"button": n}`: answer a question Zotero is asking (OK/Yes 1, No/Cancel 0; with Yes/No/Cancel: Yes 2, No 1, Cancel 0) |
|
||
|
||
They run in the app (and through the control channel and MCP bridged to the app). A command
|
||
returns at once with `{"started": …}`; Zotero then works in its own window and WordCraft answers
|
||
it in the background. All changes from one command are one undo step.
|
||
|
||
From a terminal, against a file:
|
||
|
||
```
|
||
wordcraft-cli zotero refresh paper.docx --save paper.docx [--trace]
|
||
```
|
||
|
||
Two engine commands work with Zotero's fields without Zotero running:
|
||
|
||
- `caret.pastCitation` (Zotero › Move Past Citation) moves the caret to just after the citation
|
||
it is in or before. Adjacent citations count as one. If there is none, it moves past the next
|
||
citation.
|
||
- Read Aloud (`review.readAloud`, Review › Speech, Mod+Alt+Space) skips citations and the
|
||
bibliography by default. This covers Zotero, Mendeley, EndNote and Word's own citation
|
||
fields. The player window has previous/next sentence, pause, stop and speed (0.5–3×).
|
||
Its commands are `readAloud.playPause`, `.next`, `.previous`, `.stop`, `.speed {"value"}`,
|
||
`.skipCitations {"value"}` and `.status`. Set `WORDCRAFT_SPEECH=off` to keep it silent.
|
||
|
||
Switching between an in-text style and a note style in Document Preferences moves the citations:
|
||
into new footnotes (or endnotes) at the same place, and back into the text where the note marks
|
||
were; a note that held only the citation is removed.
|
||
|
||
## Word compatibility
|
||
|
||
Citations are stored as Word's Zotero plugin stores them — fields with the code
|
||
`ADDIN ZOTERO_ITEM CSL_CITATION {…}`, the bibliography as `ADDIN ZOTERO_BIBL … CSL_BIBLIOGRAPHY`,
|
||
document preferences in the custom properties `ZOTERO_PREF_1…n` — so one document can be edited
|
||
in Word and WordCraft in turn, with Zotero working in both. (Zotero talks to WordCraft over the
|
||
protocol it uses for LibreOffice and calls the field type "Reference Mark" there; WordCraft keeps
|
||
Word's "Field" in the file.)
|
||
|
||
## Limits
|
||
|
||
- Zotero's "Bookmarks" field type isn't supported; keep the default.
|
||
- Zotero's document transfer (Export/Import Document) isn't needed and isn't supported.
|
||
- The web version can't reach Zotero (browsers can't open the socket).
|
||
|
||
## How it works
|
||
|
||
`crates/zotero` implements Zotero's published word-processor wire protocol (port 23116):
|
||
`client` runs a session, `Bridge` answers Zotero's `Document_*` / `Field_*` calls against the
|
||
session. The app (`crates/ui-egui/src/zotero.rs`) runs the socket on a thread and answers on the
|
||
UI thread.
|