Send a co-author a Word document built from the Markdown source, and bring their edits and comments back without letting a hand-typed number or citation in. Use when a co-author wants a .docx to edit, when an edited .docx comes back, or before running manuscript-guard import.
Instal·la
npx skillscat add basilechretien/manuscript-guard/word-roundtrip Instal·la des del registre de SkillsCat.
Bringing a co-author's Word edits back
The .docx is a build artefact: the Markdown is the source, and the document is regenerated
from it. That rule is right, and on its own it is unusable, because co-authors edit in
Word. So the round trip exists, and the whole question is what it may carry back.
It carries prose back and refuses everything that was generated. A naive import would
replace each binding with the number it currently shows, and the manuscript would still pass
every check, because the literals match the analysis today. It would fail quietly months
later, the first time the analysis changed. So a paragraph where a number or a citation
changed is refused, and the co-author's point has to be made at its source, in the analysis
or the ledger.
The round trip has never been through a real co-author round. Earlier versions lost text
while reporting success (step 4 lists what is now refused instead). Treat every --apply as
something to check, not something that has been checked.
1. Before sending
git commit -am "manuscript as sent to <co-author>" # know what they received
manuscript-guard build --offline- Send the
--offlinebuild, without--csl. The returned document is compared against
an offline build in the default citation style, so a document built with a journal style
comes back with every cited paragraph refused. A live Zotero build probably does the same. - Send
build/manuscript.docx, andbuild/supplementary.docxif the supplement needs
reading too. Each comes back as its own file and is imported on its own:importreads
from the paragraph identifiers which of the two it is, and compares it with a fresh build
of that one. Text pasted from one document into the other is not applied: one paragraph
comes back as new text without an identifier, listed but not applied, and several are
refused. Move text between them in the .md. In a project with a supplement, a document
that has lost every identifier is refused, and so is a supplement of only headings,
tables and figures, which holds nothing to compare. - Send a freshly built document. Builds from before Word could record moves told it not
to, so no paragraph moved in them can be moved back: each is refused and has to be moved
in the.mdby hand.importsays so when a returned document is one of them. - Do not send
manuscript.annotated.docxto anyone who will edit it. It carries no source
stamp and no paragraph identifiers, so nothing in it can come back. It is for someone who
needs to see where each number came from. - While the document is out, change nothing it was built from: the manuscript, the
results, the ledger orreferences.bib. Any change makesimportrefuse the returned
copy without--force, and with it every paragraph you changed, and every one below a
paragraph you added or removed, is listed as not compared, its co-author edit to port by
hand. Keep new wording aside and apply it after the import.
Tell the co-author, in these words or better ones:
Edit the wording freely. Please do not change numbers, citations or tables in the text;
put what you want changed in a comment, because those come from the analysis and the
reference manager. Please do not split or merge paragraphs. Please keep Track Changes on
throughout: to move a paragraph, cut the whole paragraph and paste it at the start of
another one. Reject any change you do not want before sending it back.
2. When it comes back
Save it outside build/, which every build overwrites. With the plugin installed, a shell
command that copies or moves a .docx can be intercepted by the submission guard, so pass
the file's path straight to import rather than moving it.
Commit, or at least make sure git status is clean. --apply writes the source in place and
keeps no backup.
3. Read the dry run
manuscript-guard import returned.docxIt changes nothing and reports each paragraph:
| Reported as | Meaning |
|---|---|
would merge into manuscript/… |
reworded prose; the bindings and citations in it survive |
NOT merged |
refused, with the reason under it: a number or citation changed ('3.84' comes from results.ror.point), the paragraph was split or has new text beside it, its identifier came back on text that is not its own (a paste or a copy landed in front of it), a heading was joined into it, a heading or other block beside it changed in the .md since the build or, in a document forced in, prints otherwise now or was deleted in Word (a heading run into it could not be told from a rewording), text was typed where it renders nothing, a line directly under it looks as if it opens or closes a block (such as an unmatched \end{table}; a paragraph with a fence, </div> or a definition under it, or a comment in it that closes past it, carries no identifier, and its edit is listed instead), it holds a <!-- that never closes, Word shows it as more than one paragraph, the edited text carries markup Word's text cannot bring back (named: a footnote, an HTML comment, a link, an equation, raw TeX…), merged it would not read as the text that came back, the text between two numbers or citations was deleted so they would touch, Word draws something in it that has no text the source can hold (named: Wingdings character F04A, often an AutoCorrect symbol for :) or -->, or a piece of a tall bracket; retype it as the character itself, or make the edit in the .md), it holds a private-use character (named: private-use character F06D, a symbol or icon font's own code, which the build would draw in the body font; retype the character itself), part of it is in the Symbol font because a style, the defaults or the theme sets it (read, but not taken as exact; set the font on the text itself), everything but a table, figure or misspelt placeholder was deleted so it would build with no identifier, the braces would not pair (a brace kept from the .md lost its partner, edited, moved or deleted in Word, or a brace typed in Word pairs with nothing), or its numbers, citations and markup could not be told apart from its prose, as when two tokens touch in the source; or reworded so, the next build would give it no identifier. The whole paragraph is refused, including any rewording in it |
came back joined into one |
two or more paragraphs were merged in Word. Not applied; join them in the .md yourself |
deleted in Word, left in place here |
deleted outright or as a tracked change. Not applied; delete it in the .md yourself if that was intended. If it was in fact moved, move it in the .md: never retype Word's copy, which has numbers where the source has bindings |
moved in Word, left in place here |
cut and pasted where Word recorded no move of whole paragraphs: Track Changes off, a document built before Word could record moves (import says so), or move tracking turned off in Word. Word's copy is shown under it. Not applied; move it in the .md and make any rewording there. Never delete it and retype Word's copy |
came back in a different place |
a move within one section (between the same two headings, tables, figures, lists, quotations or other blocks without an identifier, including an HTML comment or \newpage, which Word does not show), made by cut and paste with Track Changes on, which Word records; --apply reorders from the text on disk, so bindings stay intact, and applies any rewording in the same pass |
came back in a different place, not applied |
a recorded move in a section that also gained text - a paragraph split, a new one, an edited heading or caption, quoted under it - or holds a paragraph whose identifier came back on other text, so where its paragraphs now stand cannot be read with certainty. Move them in the .md yourself |
moved where a paragraph would reach the next build without its identifier |
a move that would leave a paragraph where pandoc reads it, with what is around it, as something other than itself: a definition, a heading, part of a comment. Not applied, nor any other move in that section; each move made is named with the paragraph it would leave behind. Rewordings there still land in place, unless one would cost a paragraph its identifier there too. Make the moves in the .md |
moved into a different section or file |
a move past a heading, table, figure, list, quotation or other block without an identifier, past an HTML comment or \newpage, which Word does not show, past a paragraph import holds in place (one Word shows as an empty line, one with a line such as \end{table} directly under it, one with a <!-- that never closes, or one Word shows as more than one paragraph), into another file, or between the parts of a paragraph Word shows as more than one. A held paragraph dragged past two paragraphs or more is named here itself; dragged past one, that one is named. Not applied; move it in the .md yourself |
came back somewhere else |
a heading, table, figure, caption or equation was dragged to another place in Word. When the text without an identifier all came back, only reordered, a heading, list item or caption out of place is listed in the different order row instead. Not applied; move the heading, the table's or figure's placeholder, or the equation in the .md yourself; a caption goes with its table or figure |
could not be found in the returned one |
a table, figure or display equation was deleted, pasted twice, or changed while others were added or removed. Nothing about it is applied, and a move past it cannot be seen: look for one in the text diff below |
paragraph(s) without an identifier … came back different |
a heading, list item, quotation, caption, new paragraph, or paragraph tied to markup in or around it (such as display maths, a comment closing past it, or a fence, </div> or definition directly under it) was edited (- the old text, + the new), deleted or added. Not applied; make the edit in the .md. A paragraph moved past one of these may not be reported as moved, so compare the documents as text (below) |
… came back in a different order |
headings, list items or quotations came back unchanged but reordered (~). Not applied; reorder them in the .md |
N of M paragraphs … carry no identifier |
headings, table cells, captions, list items, block quotes, paragraphs tied to markup in or around them (such as display maths, a comment closing past them, or a fence, </div> or definition directly under them), and new paragraphs. None of these was compared; those outside tables that changed are listed by the rows above, and an edit inside a table is not reported at all |
N paragraph(s) … were not compared |
the paragraph's identifier no longer names the text it was built from: the source changed there since the build, or this version numbers or tags paragraphs differently (a list tagged by a version before 0.2.45, for one). Not applied; carry any edit in it over by hand (step 6) |
… did not come back |
such a paragraph was deleted or joined in Word; or, in a document built before 0.2.60, a paragraph that is only a value was never in it. Not applied; delete or join it in the .md if that was intended |
Anything refused, joined, deleted, not compared, moved without a record Word kept, moved
but not applied, or moved between sections or files, any move held back for a paragraph
it would leave without an identifier, any heading, table,
figure or equation that was moved or could not be found, and any paragraph without an
identifier that came back different or in a different order, makes the command exit 1,
with or without --apply; the safe changes are still applied.
A would merge line shows the Markdown that will be written, bindings included; a NOT merged line shows what came back from Word. The stamp check refuses a document built from
a different version of the source; see step 6.
For the paragraphs nobody compared, look yourself. Converting both documents to text shows
every difference, compared or not:
pandoc build/manuscript.docx -t plain -o sent.txt
pandoc returned.docx -t plain -o returned.txt
git diff --no-index sent.txt returned.txtA new paragraph, a changed heading, a list or quotation edit, or a table edit is typed into
the .md, or taken back to the analysis if it touched a number.
4. What import refuses on its own, and what still needs you
Each of these once corrupted the source while import reported success. They are now
handled, and each has a test:
- A move together with rewording is applied in one pass: the paragraph goes to its new
place in its section, reworded if it was. A move into another section is reported and not
applied, rather than pushing a paragraph out of every section in between. - A paragraph cut and pasted with Track Changes on is moved, not reported deleted. Word
leaves a paragraph's identifier behind when it cuts the paragraph, and the move is read
from Word's record of it instead. Two paragraphs moved together are no longer reported as
a join, and Enter pressed at the start of a paragraph no longer reports that paragraph
deleted. A move made with Track Changes off is refused and named as a move, never
reported as a deletion to act on. - A paragraph split in two in Word is refused, not cut down to its first half, even with a
moved paragraph pasted between the halves; that move is not applied either. - A move beside an HTML comment with a blank line in it no longer writes the moved paragraph
inside the comment. A paragraph with a fence,</div>,\end, a definition or a
heading's underline written directly under it is neither moved nor reworded: its edit is
listed or refused. - Tables and figures are recognised by what they hold, so deleting a table or pasting in a
picture no longer hides a paragraph moved past a figure. A heading, table, figure or
display equation dragged elsewhere, and a table, figure or equation deleted, is reported
rather than passed over. A deleted heading or caption is listed with the other paragraphs
without an identifier. - Two paragraphs joined in Word are reported as joined and left alone, not duplicated.
So is a heading joined into the paragraph under it. - A paragraph deleted just before a heading, a table caption or the reference list is
reported deleted, even when that heading was retitled or that caption edited in the same
round; it used to be merged as the new title. Not when the new title or caption and the
deleted paragraph share most of their words: that still merges into the paragraph's slot. - A tab or other Word layout in a paragraph no longer leaks XML into the merge.
- A digit added to a number (
3.84to13.84), or a sign or dash glued in front of it
(–3.84,<3.84), is refused as a changed number. A sign separated by a space, or a unit
added after the number, is not caught: read those in the diff. - A citation ending a paragraph, "(Smith et al. 2020).", is no longer cut at "al."; a
narrative@keycomes back as@key, not as the text "Smith (2020)"; and apostrophes
and dashes no longer stop a paragraph with a binding from taking a rewording. - A rewording is refused, not merged, when the edited text carries something Word's text
cannot bring back: a footnote, an HTML comment, a link, an image, an equation, raw TeX or
HTML, a superscript or subscript (10^9^reads "109" in Word), a hard line break,
emphasis or code wrapped around a binding, or code holding a--, a...or a quote
(written back as text,--offlineprinted as "–offline"). The reason names it. In a
paragraph with a binding, markup of those kinds on one side of the binding does not stop
an edit on the other side. Markup the import does not recognise does:[Methods], a link
to the heading, refuses every edit to its paragraph. A paragraph without a binding is all
one piece, so onekg/m^2^in it refuses every edit to it. - A no-break space comes back as the character it is, so a rewording around it merges and
keeps it: one in the source ("5 mg",\, ), and one Word's French AutoCorrect
put before a colon or inside « ». - An edit that would make pandoc read a citation differently is refused: a space deleted
after a full stop before a citation, or between two citations, or text deleted between a
citation and a number. - What comes back is written as text, not Markdown: a
*, an@name, a<or a{{the
co-author typed is escaped, so it cannot become italics, a citation, a tag or a binding. - A move or a rewording after which the next build would not find a paragraph again is
refused: each file is worked out as it would be written and read the way the build reads
it. A footnote marked because an indented block below would run into it prints as text;
moved in Word over a plain paragraph, it would become a footnote again and leave the body.
No move in its section is applied, and the moves are named; rewordings there, and changes
elsewhere, still land.
What is still yours to do by hand: every refused, joined or deleted paragraph, and every
paragraph without an identifier. Port those edits from the dry run and the text diff above.--apply takes all the safe changes at once; there is no way to pick among them, so if the
dry run shows a merge you do not want, port the whole import by hand instead.
Some things still need care:
- A paragraph moved where Word recorded no move - Track Changes off, a document built
before Word could record moves, or move tracking turned off in Word - is reported asmoved in Wordand left where it was. Move it in the.mdand port any rewording from
the copy shown under it. Do not delete it and paste Word's copy in: its numbers and
citations would come back as typed text, andcheckwould then report each one as
unbound. - A footnote or an equation edited in Word, a changed link address, or a deleted footnote
is not seen at all:importreads each paragraph's text, and those live elsewhere in the
file. Look for them in the text diff above.
5. Apply, then read what was written
manuscript-guard import returned.docx --apply
git diff manuscript/
manuscript-guard checkRead the whole diff. What to look for:
- Formatting lost. An edited stretch of text comes back as plain text, so bold, italics and
inline code in it are gone. (A footnote, a comment, a link or an equation is refused
instead, because merging would delete it.) - Backslashes. Every character in Word's text that Markdown could read as markup is
escaped (CYP2D6\*4,\@admin,US\$5), and a<of yours may come back as\<.
Each prints as it did. The exception is a straight quote: an escaped one of yours,\",
comes back bare, and one the co-author typed is left bare, and pandoc curls both. Put a
backslash in front where the straight quote mattered. A co-author who only turned curly
quotes straight has changed nothing that reaches the build. A{typed straight before a
binding comes back as{. Leave it: a bare{there joins the binding's braces,
andcheckreports{{{results.x}}as malformed. Once a<before a letter (<LLOQ,<µg) stands earlier in the paragraph, a>in an edited stretch comes back as\>, or
as>where it ends a value after an=(=>,HR=2.1>1). If that<is yours or
a value's rather than the co-author's, a straight quote typed just after an=comes
back as\'or\", and prints straight; so does a curly’typed there to close a
quote of yours. Leave them: pandoc can read a bare<and>with words between them as an HTML tag and drop everything from one to the
other, andcheckreadsROR \> 2as the threshold it prints. A<before a number or
a space, as inp < 0.05, opens nothing, and what follows it comes back as typed. - Invisible no-break spaces. A
\or of yours in an edited stretch comes back as
the character itself. It prints as it did, but a diff can show a line as changed where
nothing visible changed. The one pandoc puts after "e.g." or "et al." is written back as a
plain space, because pandoc puts it back at the next build. - A number or citation the co-author typed. These merge as literals, and
checkthen
reports them as unbound. Bind the number, and turn the citation into[@citekey]. - A binding cut short, a
{{without its}}.checknow reports it as a malformed
placeholder; it should not happen, and if it does, it is a bug to report.
After an import the internal review records covering the edited files are stale, and the
built document is out of date. Rebuild before sending anything on.
6. Comments, and several co-authors
Comments are printed, never stored. Recording them is the reader's job:
- A co-author's or internal reviewer's comment belongs in an internal review record, so G11
sees it answered:manuscript-guard review --record <reviewer> --remit "…" --verdict …,
then write each comment into itsfindingswith a severity. The
review-panel skill covers the record. - A journal reviewer's comment belongs in a revision round. Run
manuscript-guard respond --open --from returned.docxbeforeimport --apply, because
applying changes the source the comments point at. See
reviewer-response.
A built document records what each of its paragraphs said in the source, and what came
before it. import merges an edit only into a paragraph that still reads that way; any
other is listed as were not compared, because its identifier now names other text, and
has to be carried over by hand. One of those deleted in Word usually leaves its identifier
on the paragraph after it and is listed there; deleted as a tracked change, cut, or joined
by retyping across the break, it is listed as did not come back. That happens where the
source changed since the build, below any paragraph added or removed there since, and
across an upgrade that numbers or tags paragraphs differently. A paragraph that reads word for word like another
in its file, such as "Not applicable." under two declarations, is also listed once the block
before it changed.
When several people edited copies of the same build, dry-run every copy before applying any.
Apply one, then --force the others: each merges only into paragraphs the earlier imports
left alone, and lists the ones they changed as not compared, for you to port by hand. An
edit beside one of those is refused if the two may have been joined in Word. Every hunk
still has to be read: a changed result changes what a paragraph displays without changing
its source, and a paragraph moved past one that was not compared may not be reported as
moved. DESIGN.md's Known gaps lists what the record cannot tell apart.
A document built before paragraphs were recorded in it is refused, --force included, and
so is respond --open --from on it, when anything it was built from has changed since the
build, the results included. Otherwise it is refused only when a file it carries has front
matter that is now read differently. Rebuild, send the new document, and carry over by hand
anything already written in the old one.
If you are a model doing this
Never run --apply without having read the dry run in full, and never report an import as
done without having read git diff. In earlier versions the command's exit code and its
"bindings intact" line were both seen alongside a corrupted source, and the round trip has
still not been through a real co-author round.
When a co-author changed a number, do not type their number into the source to make the
paragraph merge. Ask whether the analysis should change, and if so, change it there.