docxwright
docxwright converts a LaTeX manuscript into an editable DOCX document without
requiring Pandoc. It is intended for handing a LaTeX paper to co-authors and
editors who work in Microsoft Word, and aims to reproduce the content and look
of the LaTeX-compiled PDF as closely as a Word document can. It can also show
everything that changed since an earlier version of the manuscript (a git
revision) as Word tracked changes.
Quickstart
Install (Python 3.10 or newer):
pip install docxwright
Figures are rendered by LaTeX, so a TeX distribution and pdftoppm (poppler-utils)
should be installed; showing changes requires git. Without LaTeX the conversion
still works, with marked placeholders in place of the figures.
Convert a paper into an editable Word document:
docxwright paper/main.tex -o paper.docx
Show what changed since an earlier version. The paper must be in a git repository; the current version is the files on disk, uncommitted edits included.
# as Word tracked changes, since the last commit whose message mentions "submitted"
docxwright paper/main.tex -o review.docx --compare-to ':/submitted'
# as a clean copy of the new version with every insertion and change highlighted
docxwright paper/main.tex -o review.docx --compare-to ':/submitted' --changes highlight
Use the default (tracked) for revisers who should accept or reject the changes in
Word or LibreOffice. Use highlight for readers who only need to see what is new:
nothing is struck through, removed passages are quoted in comments, and it is the
easiest to read in LibreOffice's dark mode. A comment on the title of either
document says which version it is compared with.
Other common cases:
--compare-toaccepts any git revision: a commit hash, tag, branch,HEAD~3, or:/textfor the most recent commit whose message contains text.--compare-to v1.0 --revision v2.0compares two commits instead of the files on disk.--no-figuresskips the figure rendering for a quick draft.- Warnings on stderr list anything that could not be converted faithfully (unknown commands, unresolved references, ...). Check them before handing the document on.
The rest of this README covers what is supported (Features), the comparison in detail (Showing changes), all options (Usage) and the Limitations.
Features
- Structure: title block (authors, affiliations, date), abstract, a table of
contents (a real Word TOC field that Word can update with page numbers), lists of
figures and tables,
numbered sections, unnumbered
\section*headings, run-in\paragraphheadings, bullet/numbered/description lists (numbering restarts per list,enumitemlabels, itemize and enumerate nested in each other labelled as LaTeX does), footnotes as real Word footnotes (including\thanks,\footnotemark/\footnotetextand stand-alone\footnotetext[n]{...}affiliation notes) and page breaks. Included files (\subfile,\input,\include) are followed; LaTeX comments never reach the output - neither%comments nor text commented out with thecommentenvironment (or one declared with\excludecomment),\iffalse … \fior a\newifswitch (\ifdraft … \else … \fi, also in the preamble: an\ifanonymousaround\authorgives the anonymous title block). Sections deeper thansecnumdepthare unnumbered as in LaTeX (\subsubsectioninreport/book/llncs), the table of contents goes down totocdepth, and\setcounter/\addtocounterare honoured (for sections, floats, equations, theorems, footnotes and list items). enumitem'sresume,resume*,series,start,\newlistand\setlistlists are numbered as in LaTeX. - Text: bold/italic/monospace/small caps,
\verb, hyperlinks (\href,\url), LaTeX and csquotes quotes (\enquote), dashes, accents and special characters, epigraphs, indentedquote/quotation/verseblocks, framed boxes (framed,mdframed,tcolorbox: a grey frame around their paragraphs),siunitxquantities (\SI,\qty,\si,\num, ranges, lists, uncertainties;\sisetupoptions such asgroup-separator,output-decimal-marker,per-mode,separate-uncertaintyandround-mode/round-precision; units of the document's own from\DeclareSIUnit), simple user macros (\newcommand,\def, xparse's\NewDocumentCommandwithm/o/O/sarguments and\IfBooleanTF/\IfNoValueTF,\let, also macros that define macros) and environments (\newenvironment,\NewDocumentEnvironment;\renewenvironmentof the abstract, keywords and acknowledgments) defined in the preamble or document;\begingroup/\endgroupand\bgroup/\egroupscope like braces. - Math: inline formulas become formatted text (italic variables, real
superscripts/subscripts, TeX-like spacing); anything beyond that (fractions,
sums, roots, matrices, cases, ...) and all display equations become native,
editable Word equations. Numbered equations get their number flush right;
alignrows stay aligned,multlinegets one number on its last line (first line flush left, last flush right),subequationsare numbered (1a), (1b).\DeclareMathOperator,\mathbb/\mathcal/\mathfrakand mhchem's\ce{...}chemical formulas are supported. - Theorems and algorithms:
\newtheoremenvironments (theorem, lemma, definition, remark styles, shared and per-section counters) andproofwith its end-of-proof box;algorithm/algorithm2epseudocode is rendered by LaTeX like a figure and captioned "Algorithm N";lstlistingcode keeps its caption. - Document classes: article-like classes (including KOMA-Script) and
report/bookwith numbered chapters ("Chapter 1"), per-chapter numbering of sections, figures, tables and equations, and appendices. Journal classes get their own title block and numbering: IEEEtran (author blocks, "Abstract—", "Index Terms—", sections I, II, A, B, run-in "a) …:" paragraphs, "Fig. 1." and "Table I", "Appendix" / "Appendix A"), REVTeX (authors with numbered affiliations, e-mail notes, "(Dated: …)", abstract below the title, sections I, II, tables I, II, footnotes as numbered references as in APS journals, "Appendix A:" with equations (A1)), elsarticle (front matter with labelled affiliations, corresponding-author and e-mail notes, highlights, keywords, "Appendix A." with Table A.1), the AMS classes amsart/amsproc (several authors, addresses and e-mail addresses at the end, subject classification, keywords and\thanksnotes, "1. Introduction", "Figure 1.", "Appendix A.", amsplain's "1." labels and\bysamerules), Springer llncs (authors with institute numbers and ORCID iDs, numbered institutes with e-mail addresses, "Fig. 1." captions, "·"-separated keywords, its theorem-like environments with theenvcountsame/envcountsectoptions), ACM's acmart (authors with institutions and e-mail addresses, teaser figure, abstract, CCS concepts and keywords below the title,acmnumeric/acmauthoryearcitations, its theorem environments), book-class\frontmatter/\mainmatter/\backmatter, KOMA-Script (\subtitle,\subject,\publishers,\addsec,\minisec) and Springer Nature /authblkauthor lists;\renewcommand{\thesection}{...},\numberwithin{equation}{section}(equations (3.1), (A.1)) and\counterwithinare honoured. - Languages: German, French, Spanish and Italian documents (babel or
polyglossia) get the names LaTeX prints in that language ("Literatur",
"Abbildung 1", "Inhaltsverzeichnis", ...), localized dates for
\today, the language's quotation marks for csquotes, babel's German shorthands ("\``…"',"=,"-,"a), siunitx'slocaleoption and biblatex's strings and punctuation of the language ("und", "u. a.", "S."; "et", "In :", "p.", « … »); French documents also get babel-french's\og … \fg,1\ier,\up{e},\no, (non-breaking) spaces before ; : ! ? (also where none was typed), "Figure 1 – …" captions, em-dash list labels, biblatex's "2e éd." and cleveref's/\autoref's French names and conjunctions ("figures 1 et 2", "1 à 3"). Passages in another language (\foreignlanguage,otherlanguage,\selectlanguage- local to its group, as in LaTeX -, polyglossia's\textenglish/englishenvironment, babel's\babeltags, ...) are set as such: an English abstract in a French thesis gets English dates, names, spacing, caption format and Word proofing language (also a phrase or a footnote in another language); babelbib bibliographies set each entry in its own language. Caption names changed with\addto\captions…/\appto,\renewcommand/\def(also in\AtBeginDocumentor in the document),\setlocalecaptionor\captionsetup[figure]{name=…}` are used where LaTeX uses them. - Cross-references:
\ref,\eqref, hyperref's\autorefand cleveref's\cref/\Cref(with itscapitalise/noabbrevoptions and\crefname) are resolved to exactly the text LaTeX prints ("fig. 1", "eqs. (1) and (2)", "Theorem 2.1", "section 3", "Appendix A", "item 2", ...), in two passes like LaTeX;\namerefprints the section title or caption (without a final period, as nameref does), cleveref's\namecrefand friends the name; subcaption's\subrefprints the sub-figure letter,\addcontentslineadds unnumbered headings to the table of contents. - Citations and bibliography:
biblatexis emulated from the.bibfile(s) for theauthoryear,numeric(incl.numeric-comp) andalphabeticstyle families: citation labels (\parencite,\cite,\textcite,\citeauthor,\citeyear, pre/postnotes,maxcitenames,sorting,uniquelist,uniquename, disambiguation letters such as 2018a/2018b) and a "References" list sorted (like biber) and formatted like biblatex's standard drivers (including the "dashed" repeated-author style; fields cleared with\AtEveryBibitem{\clearfield{...}}are honoured, as are "and others" and\printbibliography[heading=bibintoc, title={...}]). DOI placeholders written with a\doicite{doi1,doi2}macro are printed as linked[doi1, doi2]. Documents that use BibTeX (\bibliographywith any\bibliographystyle, e.g.plain,unsrt,alpha,plainnat,IEEEtran,apsrev4-2,elsarticle-num, or a style file of the paper's own) get their reference list from the realbibtexprogram, exactly as in the PDF; citations follow standard LaTeX ([1, 2]), thecitepackage (sorted and compressed,[1–3]) or natbib (\citet,\citepwith pre/postnotes,\citealt,\citealp,\citeauthor,\citeyear, starred and capitalized forms; author-year, numerical or superscript mode with the punctuation natbib takes from the style, its package options,\setcitestyleand\bibpunct). Hand-writtenthebibliographyenvironments are supported as well (\citeresolves to their labels). - Tables: real Word tables with the column alignment of the LaTeX column
specification (including
siunitxScolumns),\hline/booktabs rules as borders,\multicolumnand\multirowas merged cells,\rowcolor/\cellcolor/\rowcolorsbackgrounds (white ones are left to the page, which also suits dark mode), multi-line cells (\shortstack,\makecell, a tabular in a cell),threeparttablenotes, and the caption above or below as in the source. A table float keeps all its tabulars (stacked panels, side by side, inside\resizebox,adjustbox,center, ...) and the text around them (panel headings, notes, a source line); side-by-side minipages with captions of their own (also\captionof, and a table next to a figure) become separate tables or figures,subtable/\subcaptionboxsub-tables get their "(a) …" captions and "1a" references; a panel title or note between a caption and its tabular stays between them, as in the PDF.\caption*is unnumbered (also next to a numbered\caption, as a "Source: …" line),\ContinuedFloatkeeps the number,\newcolumntypecolumn types (with arguments) are expanded,sidewaystable/sidewaysfigureare floats,\captionofoutside a float numbers a figure or table in acenterorminipageenvironment, and tabularray'stblrbecomes a Word table (with\SetCelland the like, or for a table built some other way, the table is rendered by LaTeX like a figure). Tables made withlongtablekeep their caption, print their foot once and repeat their head on every page. - Figures: every
figureenvironment (TikZ, PGFPlots,\includegraphics, sub-figures, anything) is rendered by LaTeX with the document's own preamble, inside a real figure environment (sub-figure labels read "(a)", "(b)" as in the PDF), trimmed to its visible content (figures wider than the text are not cut off) and embedded as a high-resolution PNG (400 dpi by default) at the size it has in the PDF. Each figure is placed on its own page: a page break is inserted right after the text preceding the figure and after its caption, which sits below the figure. - Dark mode: all text uses Word's automatic color, so documents stay readable when Word or LibreOffice show them on a dark page background; text on colored backgrounds (highlights, table cell colors, comments) gets an explicit dark color instead.
Showing changes since an earlier version
If the manuscript lives in a git repository, --compare-to REV compares the
current manuscript with any earlier revision and marks every difference:
# everything that changed since the last commit whose message mentions "submitted"
docxwright paper/main.tex -o review.docx --compare-to ':/submitted'
# compare two revisions instead of the working tree
docxwright paper/main.tex -o review.docx --compare-to v1.0 --revision v2.0
REV can be anything git understands: a commit hash, a branch or tag, HEAD~5,
or :/text for the most recent commit whose message contains text (if no
message contains it with that capitalization, the search is repeated ignoring
case; a misspelled word gets a suggestion such as "did you mean ':/submitted'?").
A plain word that is not a revision name is also searched in the commit messages.
The comparison is made on the rendered document, not on the LaTeX source, so it shows exactly what a reader of the PDF would notice — and nothing else:
- Text is compared word by word (more precisely than git's line-based diffs), and fragmented edits are merged into readable phrase-level changes. Inserted, deleted, split and merged paragraphs, changed list items, footnotes, captions, table cells and rows, renumbered sections/figures/tables/equations, changed citations and bibliography entries are all shown in place.
- Paragraphs, list items and headings that were moved are shown as moves (not as unrelated deletions and insertions); words changed while moving are marked as such within the moved text.
- Edits that do not change the output (LaTeX comments, whitespace, re-wrapping,
refactoring into
\inputfiles, renamed\labels, macro changes with identical output) do not appear. - Formatting-only changes (e.g.
\texttt{x}→x) are shown as formatting changes, and so is a heading that changed level (a section that became a subsection). - A comment on the title says what the document compares with (commit, message and date) and what the markings mean — or that nothing visible changed.
- Figures and tables that moved, and equations that moved together with their paragraphs, are shown as moved, not as removed and new; a sentence that moved into another paragraph is highlighted as moved text in highlight mode, and a comment says where it came from. A reworded section heading stays in place (text added at the end of the previous section is not shown under it), and of two paragraphs that swapped places across a heading the one that changed sections is the one shown as moved. Table rows are matched by their cells, so a row whose numbers (and even label) changed is still diffed cell by cell.
- Changed equations are shown as replaced. Figures are compared by rendering both versions with LaTeX and comparing their pixels, so a replaced image file or changed plot data is detected even when the file name stayed the same; a figure that is only rendered at a different size because the page layout changed is not reported. A table with added or removed columns is replaced as a whole in tracked mode (Word cannot track column changes); highlight mode marks just the changed cells and the new column.
Two presentations are available:
--changes tracked(default): native Word tracked changes. Insertions, deletions and moves appear exactly like changes made in Word itself (Review › Track Changes) and can be reviewed, accepted or rejected one by one or all at once — accepting all changes gives exactly the new version, rejecting all gives the old one. A changed figure shows the previous image as deleted just before the new one, with an explanatory comment on its caption; added or removed paragraph breaks and sentences moved to another place get a comment as well. Track Changes is switched on in the document so that the revisers' own edits are tracked as well (also in highlight mode;--no-track-editsto disable). The changes are attributed to the author of the newest commit (--authorto override).--changes highlight: the new version only, as a clean document in which every insertion or modification is highlighted in green (no strike-through; deleted text is absent, but a word next to a deletion of a few words is highlighted, so that "−0.24" → "0.24" does not look unchanged, and a comment quotes a longer removed passage). Moved text is highlighted in light blue with a comment saying where it came from, new and changed figures and display equations get a green frame (moved ones a blue frame), new inline formulas and footnotes are flanked by green marks, and comments mark new and changed figures, removed paragraphs, sections, figures, tables, table rows, cell contents, equations and footnotes, moved table rows, and paragraph breaks that were added or removed. This is usually the easiest version for revisers who only need to see what is new.
Both presentations stay readable in dark mode in Word and LibreOffice.
LibreOffice notes (checked with LibreOffice 26.8, 24.2 and 7.4). LibreOffice displays and accepts/rejects the tracked changes of text, paragraphs, footnotes, table rows, moves and figures, but it ignores revision marks on equations: an inserted or deleted display equation is only recognizable by its row background or its colored equation number, and LibreOffice's Accept All/Reject All keep both the old and the new version of a changed equation (Word handles them correctly); after Reject All of a changed list label (an item that got a label of its own, a bulleted list that became numbered) LibreOffice may restart the old numbering or lose an item's nesting level. LibreOffice also paints inserted and deleted table rows (and thus numbered equations) with a fixed light-cyan or pink background, on which text is hard to read in dark mode; the highlight mode, which frames changed equations and marks changed cells itself, is readable in both modes. Comment text is black, because LibreOffice up to version 24 draws comments on a light background even in dark mode (newer versions draw them in a dark author colour in dark mode, where black text is less contrasty but still readable; no text colour suits both). A few constructs are written so that LibreOffice's Accept/Reject All give exactly the old/new document as well, and comment and revision ids are chosen so that LibreOffice 7.4 shows the footnotes of commented documents correctly. (For example, LibreOffice would turn a heading into body text when it accepts or rejects whole paragraphs right before it; such paragraphs are separated from the heading - or from other paragraphs whose layout differs, such as a caption - by an invisible, 1-pt-high empty paragraph, which remains after Accept/Reject All.)
Installation
pip install docxwright
Figure rendering requires a LaTeX installation (pdflatex; lualatex/xelatex
are used automatically for documents that load fontspec/unicode-math) and a
PDF rasterizer: pdftoppm (poppler-utils), Ghostscript or MuPDF's mutool.
Without them the conversion still succeeds and figures are replaced by clearly
marked placeholders. The document is compiled from the directory of the main
.tex file, so relative \input/\includegraphics paths work as in LaTeX.
Comparisons with earlier revisions additionally require git; documents that
use BibTeX need the bibtex program (part of every TeX distribution).
Usage
docxwright paper/main.tex -o paper/out/main.docx
Options:
| option | meaning |
|---|---|
--markdown FILE |
also write a Markdown rendering of the document (revisions in CriticMarkup) |
--no-figures |
skip LaTeX figure rendering and insert placeholders |
--dpi N |
resolution of rendered figures (default 400) |
--latex-engine {pdflatex,lualatex,xelatex} |
override the engine used for figures |
--compare-to REV (--since REV) |
show the changes since git revision REV |
--revision REV |
convert git revision REV instead of the working tree |
--changes {tracked,highlight} |
how changes are shown (default tracked) |
--author NAME |
author name for the tracked changes |
--no-track-edits |
do not switch on Track Changes for further edits |
--no-comments |
no explanatory comments (legend, changed figures and tables, moved text) |
Anything that cannot be converted faithfully (unknown commands, unresolved references or citation keys, ...) is reported as a warning on stderr; in comparison mode a one-line summary of the changes is printed as well.
Limitations
- Pagination, fonts and float placement are not reproduced; tables stay where they appear in the source, figures get their own page.
- biblatex styles beyond the authoryear/numeric/alphabetic families are approximated with author-year formatting (BibTeX styles are reproduced exactly).
- Equations are compared as a whole: a changed equation is shown as replaced.
- Font sizes inside tables and other size switches are not reproduced.
- In tracked mode, moves are recorded as Word moves for whole paragraphs, list
items and headings; a moved sentence, figure, table or equation is a deletion
plus an insertion there, explained by a comment (highlight mode shows all of
them as moved); a figure that moved and changed is recognized by its
\label. - Footnotes are numbered continuously through the document (
reportandbookrestart them in every chapter). - Figures get a page of their own; a page break that exists in only one version (next to an added or removed figure) is not a tracked change, so a document with all changes rejected may break pages differently from the old version (its text is exactly the old one).
- LibreOffice ignores tracked changes inside formulas (see above); in Word they are accepted and rejected like any other change.
- Words removed from a paragraph that also moved are quoted in the "moved here" comment in highlight mode; in tracked mode they are visible only in the old (moved-away) text, plus a comment below the moved paragraph that quotes them. A footnote that moved and changed is shown as removed and new in tracked mode (highlight mode shows it as moved, with its changes).
- A merged
\multirowcell whose group changed size keeps its old span in tracked mode after Accept All (highlight mode shows the new merge); a deleted figure in tracked mode is crossed out in the author colour, which can be hard to see on the white figure in dark mode (the comment on the new figure explains it). \renewenvironmentof other built-in environments and tabularray's cell/row settings are not reproduced (atblrtable that uses\SetCellis rendered by LaTeX as a picture).- Highlight mode puts thin shaded spaces around new or changed inline formulas and footnote marks, because LibreOffice does not shade formulas or footnote marks.
Metadata
Release files for docxwright 2.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| docxwright-2.1.1.tar.gz | 280.2 kB | Without provenance | Details for docxwright-2.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| docxwright-2.1.1-py3-none-any.whl | Python 3 | none | any | Details for docxwright-2.1.1-py3-none-any.whl |
Total release size: 531.5 kB
Release files / docxwright-2.1.1.tar.gz
| Download URL | docxwright-2.1.1.tar.gz |
|---|---|
| Size | 280.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d404bc58f05a8cca5120509cf18ce89183562b5f6fa3d8de5c5db5376032e5eb
|
|
BLAKE2b-256 checksum How to use checksums |
b99afc3453e369850b3c045ad66c9782d6e7274d1da5e379bee45cae80dd7ae7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / docxwright-2.1.1-py3-none-any.whl
| Download URL | docxwright-2.1.1-py3-none-any.whl |
|---|---|
| Size | 251.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83b85c5772d12b90b01eb4d7845e4878da352dd11ffa9029bf9f73d44fb6a181
|
|
BLAKE2b-256 checksum How to use checksums |
718008c43503320c685aead5ca8a1ea57bd2bfe6b6c7083b5bb8e1aa53135f63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for docxwright 2.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.