Repository navigation
Installation
latexml-oxide ships as a single self-contained executable. It also calls a few external tools when they are on your PATH:
- a TeX distribution (TeX Live, MacTeX, or MiKTeX) — for the packages, classes, and fonts your documents load.
- graphics tools (ImageMagick, Ghostscript, MuPDF, Poppler, dvipng, dvisvgm) — to convert figures.
Per-platform install instructions are in the README Installation guide.
Download the asset for your platform (each has a matching .sha256 to verify file integrity):
- Linux (x86-64) —
latexml-oxide_0.7.6-1_amd64.deb, or the portablelatexml-oxide-0.7.6-x86_64-unknown-linux-gnu.tar.gz - Linux (aarch64 / arm64) —
latexml-oxide_0.7.6-1_arm64.deb, or the portablelatexml-oxide-0.7.6-aarch64-unknown-linux-gnu.tar.gz - macOS (Apple Silicon) —
latexml-oxide-0.7.6-aarch64-apple-darwin.tar.gz - macOS (Intel) —
latexml-oxide-0.7.6-x86_64-apple-darwin.tar.gz - Windows (x86-64) —
latexml-oxide-0.7.6-x86_64-pc-windows-msvc.zip(unzip;latexml_oxide.exeis self-contained, no installer)
Changelog
[0.7.6] (graphics & SVG figure fidelity; minted highlighting + overpic; author/frontmatter class sweep; Rhai runtime binding API; latexmlpost CLI parity; wider package & bibliography coverage)
-
OmniBus fallback captures
\orcidand no-ops the\lefttitle/\righttitle
running heads. Unbound bundled journal classes fall through to the generic
OmniBus fallback, where Perl'sOmniBus.cls.ltxmlleaves these three undefined
(→Error, content dropped).\orcid[]{}now routes to the existing
\lx@add@orcidhelper, so the identifier is captured as a real
<ltx:contact role="orcid">with anorcid.orglink (surpass-Perl, like
scrartcl's\titlehead); the running-head registers are no-op'd (presentational,
correctly dropped). Only this verified, class-consistent subset is added — the
ambiguous/variant journal spellings (\affis a superscript ref marker in jfm,
NOT affiliation;\contribution/\correspondence/\data/\ack/\reportnumber)
stay unhandled pending per-class review. From the sandbox-arxiv-2606 study;
witnesses 2606.00213 (pasj02\orcid), 2606.00645 (jfm running heads).
OXIDIZED_DESIGN #160; guardomnibus_captures_orcid_and_drops_running_heads. -
Output-neutral performance pass (2026-08-23 audit follow-through).
Debug!
diagnostics are now lazy: their message expressions — which at the
open_text/open_text_internal/close_elementsites serialized the current
subtree vianode_to_stringon every text insert / element close — evaluate
only when--verbose/--debugwould actually emit them (up to ~26% of a
build-bound conversion discarded before; PERFORMANCE.md Open levers P0; the
Debug status tally is preserved at every verbosity). Also:
Token::is_noexpand_familymemoized per arena symbol (was a string-prefix
probe ×2 per CS token);generate_idfinds itsxml:idancestor by a direct
parent walk instead of a per-node XPath parse+eval; post-processing's
collect_walk_matchesiterates siblings instead of materializing a child
Vecper recursion level; the"{encoding}_fontmap"-family Value keys are
memoized per encoding (were rebuilt ~4× per decoded character run, ~1M
allocations on a 1.3 s paper);install_definition's":locked"gate probes
the arena without interning (no more permanent:lockedtwin per defined
cs);LATEXML_TELEMETRY_OUTappends JSONL instead of truncating to the last
record; 13 clippyredundant_clonesites fixed (2 kept as verified false
positives). Measured (interleaved best-of-3, idle box): build/text-bound
witness 2304.10050 6.21 → 2.71 s (−56%); typical math paper 2408.08292
−11%; 82-paper regression-corpus sweep 229.3 → 200.0 s (−12.8%) with
zero exit-status changes and flat max-RSS. Suite green (2175/2175); HTML
byte-identical on all four A/B witnesses. -
--quietreduces console output only; the.latexml.logkeeps a minimum
verbosity floor. Previously--quietlowered the singleloglevel filter to
Warn, which dropped the identity banner, every(Processing …/(Loading …
progress note, and allInfo:records from the on-disk log as well as stderr —
breaking BookML's makefile dependency tracking, which reads the(Loading …
lines from the log (#763, reported by xworld21). The logger now decouples the
two gates (PerlCommon/Error.pm_printline/ProgressSpinup:$LOGis
written whenever the log is open, STDERR only when$VERBOSITY >= 0): the log
floor stays atInforegardless of--quiet, while STDERR follows the console
verbosity;--verbose/--debugraise both.Error/Fatalstill always reach
stderr (the always-emit-errors divergence). The same floor now covers the TeX
terminal-output primitives, which Perl calls without a verbosity guard:\typeout
(PerlNote— log always, stderr when not quiet) and\message(PerlNoteLog
— log-only, never stderr); both previously vanished from the log under--quiet.
Two raweprintln!fallback diagnostics (store.rsStored→Number cast, the math
parser's ambiguous-action fallback) now route through the logger instead of
printing unconditionally and bypassing the report tally. Guards
quiet_keeps_log_floor::{quiet_log_keeps_floor_but_stderr_is_muted, loud_log_and_stderr_both_keep_floor}. -
\newtcblistingnow accepts its leading[init-options]optional argument.
The binding stub took{name}[N][default]{options}, omitting the leading
[init-options]that the real tcolorbox macro carries ({ m +O{} m o +o +m }).
A call like\newtcblisting[auto counter, number within=section]{promptbox}[2][]{…}
therefore read the bracket group as the mandatory name, left{promptbox}
undefined, and let its verbatim body tokenize as ordinary LaTeX — so every_/^
in the listing raised "Script can only appear in math mode" (455 errors on the
witness). The spec now leads with the optional; both it and the trailing tcb
options are dropped as before, and calls without a leading optional are unchanged.
Found in the sandbox-arxiv-2606 study; witness 2606.00555 (455→0 errors). Guard
cluster_newtcblisting_leading_optarg. -
mintedcode blocks render Pygments syntax colors, not just bold-black. When the
source ships a committed_minted/frozencache,minted_frozencache.rscontent-matches
each highlight file's plain code (\PYGunwrapped,\PYGZ*resolved) to a block body
and emits Pygments-colored listing lines, reusing thelistingsconstructors + xcolor;
a cache miss (or no_minted/) falls back byte-identically to the uncolored path. Perl
errors onminted— beyond-Perl (OXIDIZED_DESIGN #157). Guard
minted_frozencache_colors_from_pygments_cache_157; witness 2605.03143. -
acmart affiliation parts break after the comma, not before it.
\lx@acm@addresspart
now\ignorespacesbetween\institution{}\city{}…parts and joins with a comma +
breakable space, matching realacmart.cls— so a line wrap no longer strands the comma
at the start of the next line. SHARED-with-Perl (its binding omits the\unskip/
\ignorespaces); beyond-Perl (OXIDIZED_DESIGN #158). Witness 2605.03143. -
A single affiliation shared by all authors renders once, below the authors.
relocate_annotationsno longer mis-binds a sharedaffiliation:1to author 1 by number,
and gathers the orphaned institute-level contacts onto one trailing name-less
<ltx:creator>. SHARED-with-Perl; beyond-Perl (OXIDIZED_DESIGN #159). Guard
frontmatter_llncs_shared_affiliation_below_authors; witness 2402.19043 (LLNCS, 5
authors + one\institute). -
Author
\thanksrenders as a marked note, not an inline affiliation-like blob.
\author{Name\thanks{…}}(correspondence, funding, equal-contribution, …) was emitted
as an inline<ltx:contact role="thanks">that read like an affiliation next to the
name. It now becomes a marked<ltx:note role="thanks">— a superscript mark on the
author + the content as a margin/footnote — carrying semantic class hooks
(ltx_note_frontmatter,ltx_role_thanks, and a best-effort content-kind class
ltx_thanks_correspondence/_funding/_contribution/_address/_note) so a theme
can style each kind. A surpass — Perl keeps the inline contact (OXIDIZED_DESIGN #156).
ltx:noteis added toltx:creator's content model. Witnesses arXiv 2512.24601,
1510.02728; guardsauthors_test,cluster_author_thanks_marked_note. -
A
.bblpreamble no longer produces a spurious empty(1)bibliography entry.
An ACM-Reference-Format-style.bblputs macro definitions and a blank line between
\begin{thebibliography}and the first\bibitem; the blank line made the bibliography
auto-open a keyless phantom entry that rendered as an empty(1)before the real
references. It is now scrubbed after construction (a bibitem with no key and only
whitespace content). A surpass — Perl LaTeXML emits the identical phantom
(KNOWN_PERL_ERRORS #110, OXIDIZED_DESIGN #155). Witness arXiv 2605.03143; guard
cluster_bib_preamble_no_phantom_entry. -
algorithm2e
\For/\While/\Ifbodies written with\\now indent under the
|rule. A body line ended with\\(rather than\;) was rendered flush-left
after the vertical separator instead of indented beneath it, because algorithm2e's
\\→line-break binding was clobbered by the float setup's tabular guard
(\\→\lx@newline). We re-assert the algorithm line-break binding after that guard,
so each\\-separated body line becomes its own indented listingline. A deliberate
surpass — Perl LaTeXML shares the bug (KNOWN_PERL_ERRORS #109). Witness arXiv 2002.09766
Algorithm 1; guardcluster_algorithm2e_for_body_indentation. -
A bare email trailing an IEEEtran
\authorblock no longer leaks into the body.
\author{\IEEEauthorblockN{…}\IEEEauthorblockA{…} \{…\}@host}places a loose email
after the affiliation block (the\{/\}are literal-brace control symbols, so it is
top-level text); it was digested into the document body as the first paragraph. It now
attaches to the creator as an affiliation. GENUINE-RUST-ONLY (Perl bundles the whole
author argument into<personname>). Witness arXiv 1901.07768; guard
frontmatter_ieee_authorblock_trailing_email. -
Multiple full-line
\hbox to \hsizeseparators stack instead of overflowing.
Following the width:100% relativization (OXIDIZED_DESIGN #152), two\dashfill
separators flanking a centered label on onenowraplistingline still overflowed (two
width:100% inline-blocks side-by-side sum to >200%). The fill-line box is now also
markedclass="ltx_leaderfill", and the stylesheets set itdisplay:block, so each
separator owns its line — matching the pdflatex golden. Witness arXiv 1510.02728
("Modified ellipsoid method"); guardcluster_hbox_to_hsize_leader_fills_width. -
algorithm2e listings render closer to pdflatex: uniform-bold line numbers,
[ruled]captions at the top, inline\Comment*[r]side-comments. Three
algorithm2e rendering fixes. (1) Line numbers now render in uniform upright bold
(\NlSty=\textnormal{\textbf{…}}, restored in\algocf@printnl), instead of
inheriting the ambient keyword bold on\For/\If/\Whilelines and staying plain
elsewhere;renumber_algo_lineswas also made font-preserving so the 1..N relabel no
longer strips the wrapper. (2) The ruled family (ruled/algoruled/boxruled…) draws
its caption at the top of the frame (real sty\@algocf@capt@ruled=top), so
float_sty::reposition_caption_topDOM-moves the caption before the body for that
family only (plain/boxedunchanged). (3) A\Comment*[r]/[l]side comment now
stays inline with its numbered statement, flushed right, instead of breaking onto its
own line. All three are a deliberate surpass — Perl LaTeXML renders them the pre-fix way
too (OXIDIZED_DESIGN #153). Guardscluster_algorithm2e_uniform_line_number_font,
cluster_algorithm2e_ruled_caption_at_top,algorithm2e_linenumbers. -
A
\hbox to \hsize{…}leader separator fills its column instead of overflowing.
A leader-fill rule —\hbox to \hsize{\dashfill\hfil},\hrulefill,\dotfill— was
frozen at an absolutewidth="345.0pt"(the article\textwidthdefault), so inside a
narrower container (an algorithm) the dashed line overflowed. When the box body is a
horizontal leader fill and its width is a full-line register (\hsize/\linewidth/
\columnwidth/\textwidth), the constructor now emits a relativewidth="100%", so
the separator fills its HTML container in any context, matching pdflatex. Text-bearing
full-width boxes (fancyvrb verbatim lines, whose 345pt is deliberate parity) and genuine
fixed-width boxes (\hbox to 100pt) are unchanged. A surpass — Perl emits the same frozen
pt (OXIDIZED_DESIGN #152). Witness arXiv 1510.02728; guard
cluster_hbox_to_hsize_leader_fills_width. -
A document that re-adds its title or abstract no longer duplicates it. Replaceable
frontmatter tags (title/toctitle/subtitle/date/abstract/keywords) now keep a
single entry — a later one replaces the earlier — while multi-authorcreators still
accumulate. The vendored engine pushed unconditionally, so an appendix\twocolumn[\icmltitle{…}]
or a nested{abstract}produced two<title>/<abstract>blocks. Forward-ports upstream
LaTeXML's%ReplaceableFrontmatterTags; a surpass over the vendored Perl (OXIDIZED_DESIGN
#154). Witnesses arXiv 2002.09766, 2511.21969; guardcluster_frontmatter_replaceable_dedup. -
Algorithm listings no longer show a phantom vertical scrollbar. An auto-height
.ltx_listingnever overflows vertically, but the CSS Overflow spec promotes
overflow-y:visible→autowheneveroverflow-xscrolls, painting a spurious vertical
scrollbar (algorithm2e listings). The embeddedLaTeXML.cssnow pins
.ltx_listing:not(.ltx_lstlisting){overflow-y:hidden}(mirroring the ar5iv.css fix).
Witness arXiv 2002.09766. -
aligned/gatherrelations are no longer over-spaced in HTML. An
aligned(oralign/gather/split) nested in math renders as one<math>
with a tight<mtable columnspacing="0pt">, but browsers add a default 0.4em
horizontal padding to every<mtd>on top of that — roughly tripling the space
around a relation, soy(x) = …came out visibly loose.LaTeXML.cssnow
zeroes that padding oncolumnspacing="0pt"tables, leaving only the relation
operator's own spacing; matrices/arrays (bare<mtd>, non-zerocolumnspacing,
which some browsers under-honor and lean on the padding) are untouched. Fixes
issue #755 (reporter nasser1). The ar5iv.css theme already mitigates this with
its globalmtd{padding:0.1rem}and can adopt the same reset for perfect
tightness (follow-up in the ar5iv-css repo). Guards
aligned_emits_zero_columnspacing_and_css_resets_mtd_padding(CI-enforced) and
aligned_relation_is_not_double_spaced_by_mtd_padding(opt-in browser render). -
A control sequence in a hyperref
\url/\hrefno longer disappears. A
non-expandable primitive inside a URL (e.g.\url{https://ex/q=\def}) was read
semiverbatim and then digested —\defexecuted, consumed the following
tokens, truncated the URL to…q=and raised errors — where pdflatex (and real
url.sty, via\meaning) keep it as literal link text. The hyperref reader now
stringifies any leftover control sequence (recatcodes it toother) instead of
handing it to digestion, while still expanding theurl.styescapes (\%,
\_,\^,\textbackslash, …) during the read, so realistic URLs are
unchanged and\url/\hrefnow agree. Perl LaTeXML digests the same way
(byte-identical output, more errors) — a deliberate surpass (OXIDIZED_DESIGN
#147). Follow-up to issue #723's rebuttal (reporter xworld21 / Vincenzo
Mantova); guardscluster_url_cs_verbatim_723,hyperurls_test. -
fairmeta.clspapers now link each author to their institution. The
Meta/FAIR pre-print template (and itsselfevolagent/openmosssiblings)
connects authors to institutions and contribution notes by superscript mark —
\author[1,2,*]{Name},\affiliation[1]{Inst},\contribution[*]{Note}. The
shared meta-class binding dropped the[mark], so every author lost its
institution and affiliations became detached document notes. The binding now
routes the marks through LaTeXML's author-annotation / contact-label plan (the
authblkidiom:\lx@add@creator[annotations]+\lx@add@contact[label]), so
each institution/contribution attaches to the authors that cite its mark. The
mechanism is byte-for-byte Perl-parity; on the fairmeta papers themselves Rust
surpasses Perl, which has no binding and mangles them under OmniBus. Fixes
arXiv/html_feedback#1396 and the fairmeta family (#662, #3512, #4707, #4971,
#5035, #5466); guardfrontmatter_fairmeta_author_affiliation_1396. -
Tables inside a
tcolorboxno longer render upside down. Atabular
inside atcolorboxenhancedskin is drawn as SVG, with the table content
in an<svg:foreignObject>nested in a TeX-y-up (flipped) group; the fo needs
a counter-fliptransform="matrix(1 0 0 -1 0 h)"(set by its size-dependent
afterClose) or it draws vertically upside down. When building that wrapper,
insert_blockrenames a_CaptureBlock_— which carries the block's box — to
svg:foreignObject, but the rename dropped the node box (Perl carries it via
the internal_boxattribute), so the afterClose read a zero size and skipped
the flip.rename_node_internalnow carries the node box across, matching
Perl, and the table renders right-side-up (byte-for-byte Perl parity on the
foreignObject transforms). Fixes arXiv/html_feedback#6873 (reporter tdsmith,
paper 2601.13118); guardcluster_tcolorbox_tabular_not_flipped_6873. -
Every conversion logs an identity banner: executable, version, revision,
start time. At the head of each conversionlatexml_oxide,cortex_worker
andlatexmlmath_oxidenow log a line likelatexml_oxide (latexml-oxide 0.7.6; revision 6ff599cc08) started 2026-08-21 19:01:23 -0400, to both stderr
and the captured.latexml.log. This mirrors Perl's$LaTeXML::IDENTITY
(executable + version +make-filled revision) and adds the exact start time,
so a log always names the precise binary and moment that produced it. The
revision is embedded at build time (build.rs; overridable via the
LATEXML_GIT_SHAenv for packaged builds without.git);--quiet
suppresses the banner. Guards:identity::tests,identity_banner
(cluster_cli). -
Vertical rules in a math
arraynow render, and!{|}aligns like Perl.
Two defects from one report, both now byte-for-byte Perl parity. (1) A|or
\hlinein a display-matharray—\begin{array}{cc|c}, a framed|c|c|, or
acolortbl\arrayrulecolorrule — already carried the correct
border="r"/border="b l r"on each cell in the core XML (identical to Perl),
but the MathML post-processor emitted a bare<m:mtd>and the rule vanished.
pmml_arraynow foldsborder→ltx_border_*(andthead→ltx_th_*) CSS
classes onto them:mtd, matching PerlMathML.pm. As in Perl,
\arrayrulecolor's color is not yet carried (the plain rule renders). (2) The
array-package!{|}inserts its filler past the column's trailing\hfil,
defeating the centering, so Perl right-aligns that cell; a Rust-only alignment
fallback (meant for trailing fills lost in nested\hboxdigestion) wrongly
re-centered it.extract_alignment_columnnow recognises a fill defeated by
inserted content — while a\vrulerule stays skippable, socc|ccells remain
centered. Reported in #740 and #742 (reporter nasser1);
guardcluster_array_vertical_rule_border_740. -
Author ORCID iDs render as the green iD logo, uniformly. Every class that
provides an\orcidnow routes through the one canonical frontmatter macro
\lx@add@orcid, which emits a standardltx:contact[role=orcid]carrying the
ORCID logo linked tohttps://orcid.org/<id>. The logo is a single shared
kernel asset (\lx@orcidlogo/\lx@orcidlink), reused byorcidlink.sty's
\orcidlinkand every class binding — so there is one definition, not a per-
class reimplementation. Previously several classes (ecai, imsart, sigma, aa,
svmult, egpubl, ceurart, …) rendered the ORCID as a bare dagger footnote with
the raw number. The\orcidlink/\orcidlogologo is also sized to the text
(1em) instead of an oversized 1.7em badge that overflowed the line. Fixes
arXiv/html_feedback#6571 and the ORCID-icon cluster (#6895, #6016, #5789,
#2176, #5615, #4958, #4930, #1211, #5879, #3659). Guard:orc_test. -
ecai.cls: reference-linked authors and affiliations.
\author[A,D]{…}
with\address[A]{…}now attaches each affiliation to the author(s) whose
optional-arg labels match (the elsarticle model), instead of piling every
address onto the last author;\fnms/\snm/\orcid/\thanksinside the
author are handled. Fixes arXiv/html_feedback#6571. -
~and^stay ASCII in verbatim under T1 font encoding. The displayed
text of a\verb, theverbatimenvironment,\url/\path, or a
Verbatim/HyperVerbatimargument (including a Rhai binding's verbatim arg)
containing~/^under\usepackage[T1]{fontenc}decoded to the accent glyphs
U+02DC/U+02C6 — e.g. a\url{.../~user}printed˜. (The href attribute was
always ASCII — it is built by reversion, not font decoding.) Every verbatim
context now selects an identity ASCII fontmap for its run (keeping the
typewriter styling), so~/^stay literal, while the T1 fontmap — where those
slots are Bruce Miller's deliberate accents (LaTeXML #2435) — is untouched for
normal text.\url/\pathwere completed after Vincenzo's follow-up on #723
(their\UrlFont-wrapped display is digested separately from the semiverbatim
href arg). A newtools/fontmap_drift.pychecks our fontmaps against pdftex's
glyphtounicodegolden. Surpasses Perl (verbatim/\urldisplay loses ASCII
there too); OXIDIZED_DESIGN #144, #723. -
The first paragraph is no longer indented when
\parindentis zero. With
\setlength{\parindent}{0pt}(or\usepackage{parskip}), the very first paragraph
still picked up the stylesheet's default 2em first-line indent, because the class
that suppresses it is recorded by the previous\parand the first paragraph has
none. It is now markedltx_noindenttoo, matching pdflatex — and only when
\parindentis genuinely zero, so default documents are unchanged. Surpasses Perl
(identical off-by-one); completes theparskipfix (OXIDIZED_DESIGN #143, #719). -
Pandoc relative-width table columns no longer collapse to a "river of
characters". Ap{(\columnwidth - N\tabcolsep) * \real{X}}column — the width
format Pandoc emits by default — is acalcinfix expression the base dimension
reader could not evaluate, so every column came outwidth="0.0pt"and its text
wrapped one character per line. Column widths now route through thecalc
expression parser whencalcis loaded, giving the intended proportional widths.
Surpasses Perl 0.8.8 (which emits the same 0pt +Missing numberwarning);
pdflatex renders the real widths (OXIDIZED_DESIGN #141, arXiv/html_feedback#6909,
witness 2606.08266). -
A framed
fvextraverbatim withbreaklines=truecarries a stableltx_break
css class, so a stylesheet can target wrapping vs non-wrapping verbatims apart
(.ltx_framed_verbatim.ltx_breakvs:not(.ltx_break)) without reaching for the
fragile:has(.ltx_parbox)selector, which was previously the only distinguisher.
Beyond-Perl (both engines emit no breaklines hook natively), same spirit as the
frame=single→ltx_framed_verbatimremap (#702). -
Streaming byte-identity for a framed
breaklines=trueverbatim. A single-line
such verbatim (its parbox layer crosses a fragment seam) used to render nested under
--streamingyet collapsed under the eager path, becausespill_closed_subtrees
spilled the frame's soleltx:textchild before the frame closed, leaving a
<_spilled_/>placeholder thatauto_collapse_childrencould not merge. The spill
guard now keeps that lone child resident until its frame closes, so both paths
collapse identically (#702). -
mintedcode blocks render with syntax highlighting, and inline\mint/\mintinline
work. Themintedfamily now emits highlight token classes so a stylesheet colors the
source; inline\mint/\mintinlinerender like the block form;\newmint*accepts the
optional[env-name]; andescapeinsidelets a\labelinside a listing register on its
own line (#668, #665, #625). Tier-2 (an exact-Pygmentspygmentizesubprocess) is parked
behind issue #670. -
overpicrenders its base graphic plus\putoverlays. Theoverpic/overpic*
environment — agraphicximage carrying apicture-coordinate overlay — was unbound; it
now draws the base graphic and composes the\putoverlays on top, recovering ~37 arXiv
papers that previously lost the annotated figure entirely (#677). -
Figures and SVG pictures render at the right size and shape. A sweep of
graphics/picture/SVG fidelity fixes: an\includegraphicsin a flex-capped figure keeps
its aspect ratio via an emittedaspect-ratio(#711); external SVGs are sized from the root
width/heightlike a browser rather than theviewBox(#700, witness #696);
picture-nested graphics resolve into the SVGforeignObjectinstead of rendering giant,
doubled, or dropped (#675, #682, #609/html_feedback#74); two-column subfigure panels share a
row instead of stacking full-width and a float panel is never wrapped in an invalid
ltx:block(#706, #708);\scalerel*inline icons scale to text height (#712,
html_feedback#6895); sibling-directory graphic candidates are relativized so no absolute path
leaks into@src(#699/#698);wrapfigreduces the inner\linewidthto the wrap width
(#592); and theltx_pictureSVG splice is hardened against attribute order/quoting
(#575/#398). -
A large author/frontmatter class sweep — more journal & conference classes emit a
correct author list. Building on the author-markup pipeline unification, many class idioms
now attach names, affiliations, and emails to the right creator: IEEEtran multi-row grids
transpose to reading order and lazy\\[1em]+shared-email blocks structure (#624, #546);
LNCS/LLNCS shared\emailand deduped\inst(#545, #590); authblk\author{A, B, C}comma
lists split into separate creators (#633, html_feedback#6255); IJCAI/ceurart/cvpr keyval
author blocks stop leakingorcid=/email=as text and pre-load numeric natbib (#691, #692,
#626);neurips_2026registers and neurips/sn-jnl keep the body after the abstract and order
the abstract after the title (#690, #687, #685, #681); and OmniBus\authors, ACL short
names,\andas a hard boundary, nested inline-math markers, one-line\textsuperscript{n}
affiliations,\quad\\line-2 authors, whole-name bold, phantom empty creators, an
\abstractname\centeringleak, a\twocolumnheader-font leak, and figures injected into
the title via\g@addto@macro\@maketitleare all handled (#664, #611, #631, #629, #623,
#620, #615, #619, #613, #632, #618). -
Wider package compatibility — more third-party packages convert cleanly instead of
cascading errors.physics.sty\qty(...)with a braced paren no longer runs away (#654);
comment.sty\end{comment}mid-line no longer swallows the document (#649); acolortbl
\columncoloroverhang read stops eating a\lbrackcell (#642);aa.clsloads
[T1]{fontenc}so text</>render as themselves (#603, html_feedback#84);\verbinside
\indexrenders as typewriter (#601/#354);fancyvrbframe=singlerenders as a semantic
box (#573/#525);parskipsets\parindent=0(#568/#558); an empty\hypertargetno longer
wraps the open note (#565/#526);siunitxempty units render invisibly (#584,
html_feedback#970);\widthofbox widths resolve in every dimension context (#589,
html_feedback#6869);\everyjobis emulated so l3sys system constants are defined (#583);
biblatexno longer globally defines\typeover a user math macro (#689);cleveref
\crefmatches LaTeX for custom\newtheoremtypes and reverts a~tie (#636, #630); a
pdfcol.styno-op stub lets breakabletcolorboxwork (#579/#531); and a wrapper box merges
its class onto a single block child, keepingltx_lstlisting(#614). -
Math rendering fixes. A nested
\sboxinside a discarded math parse no longer
double-frees its subtree (a crash fix, #709/#703); display math is contained inside a
width-constrained table cell (#572/#533); and a unary minus after a relation keeps its
spacing (#569/#535). -
More bibliographies and citations recover their content.
imsartreads the.bibwhen
no.bblships (#658); a leaked active@no longer destroys the.bibbibliography (#646);
chapterbib/bibunits per-unit list ids keep_raw (#641); a numeric-mode natbib.bbl
labels the References with[N]matching pdflatex (#612, #616); and author-year inline
citations match the References list label (#587). -
CLI, Rhai, and build additions.
\subimport*accepts an absolute directory path to
match pdflatex (#701/#697); the serializer keeps foreign mixed content inline without
injected whitespace (#684/#680); a no-dump conversion no longer fails on a benign expl3
raw-load cascade (#660/#651);GetKeyValsaccepts a digested KeyVals andRevertkeeps its
values (#628/#627);canContain/floatToElementare exposed to Rhai (#598/#594);
Note/NoteLog/NoteSTDERRwrite to the correct stream(s) (#596/#593);--opt/--noopt
flag pairs resolve rightmost-wins likeGetOpt::Long(#563/#530);enumitemleftmargin
is surfaced for CSS theming (#567/#559);\LaTeXMLversionreports the running binary version
(#553);\lx@save@parameterletslatexml.stysave conversion params (#551/#536); a UTF-8
SIMD fast-path speeds the.cls/.stydependency scan (#674); and the nightly toolchain
floats again now that the fat-LTO OOM regression is fixed upstream (#582/#512). -
amsart authors declared up front no longer bunch every address/email under the
last author. The idiom\author{A}\author{B}\author{C}followed by one
\address/\emailpair each makes LaTeXML's default "attach a contact to the
preceding creator" pile every contact onto the last author, so A and B render bare
(arXiv/html_feedback#46, witness arXiv:2308.06214v1; Perl 0.8.8 identical — SHARED).
A new DOM passdistribute_upfront_contactsredistributes ONLY a cleanN × m
pile — the other N−1 authors carry no contact and the last author'sKcontacts
split evenly (K = N·m) into a role-periodic sequence — handing group i to
author i. Irregular piles (heterogeneous roles, differing per-author counts) and
the interleaved idiom fail the gate and are left exactly as Perl attached them, so
tests/structure/amsarticle.texis byte-unchanged. Beyond-Perl (OXIDIZED_DESIGN
#140 / KNOWN_PERL_ERRORS #104). Guard
06_cluster_frontmatter::frontmatter_amsart_upfront_contact_distribution. -
A non-default
NOMINAL_FONT_SIZEis persisted as a
<?latexml nominal-font-size="X"?>processing instruction so post-processing
can size font-relative (em) external SVGs correctly — anemis
NOMINAL_FONT_SIZEpt, not always 10pt (#683). Perl never carries this value
(it is digestion-onlyDEFSIZE), so this is beyond-Perl (OXIDIZED_DESIGN #136).
The PI fires only when the value differs from the 10pt default (a0poster=25,
BookML, the NNpt class options), so ordinary documents stay byte-identical.
Emitting it also fixed aninsert_pibug: a PI added after the root element
already exists was queued into the once-drainedpendinglist and silently
lost; it is now inserted directly before the root, matching Perl
Core/Document.pm::insertPI. -
--urlstyle=(server|negotiated|file)rewrites cross-reference URLs for the
serving environment (feature parity withlatexmlpost; #656).server
strips a trailingindex.html(landing page →./),negotiatedalso strips
the.htmlextension (BookML's extensionless URLs),filekeeps full paths.
TheUrlStyletransform existed but was unreachable (hard-coded, and the
output extension was never plumbed into CrossRef, so it stripped the wrong
suffix); now the flag selects it and the extension is threaded through both the
serial and parallel-render paths, matching PerlCrossRef::generateURL+
extension =>(CrossRef.pm L656-663, LaTeXML.pm L479) exactly — including the
(^|/)path boundary (amyindex.htmlis left intact). Default isfile
(Perl defaults toserver; a documented divergence — OXIDIZED_DESIGN #134). -
Rhai bindings can read a verbatim body via
StartSemiverbatim/EndSemiverbatim.
ADefEnvironmentwhose body contains^/_/&/… (e.g. a code block) raised
"Script ^ can only appear in math mode" because the body was digested normally.
The two PerlPackage.pmexports are now on the Rhai surface, so a binding can
bracket its body —beforeDigest: || StartSemiverbatim()+
beforeDigestEnd: || EndSemiverbatim()— to neutralize the math/special
catcodes (^ _ ~ & $ # ') to literal text while keeping\ { }special so
\end{env}still parses. Extra single-char strings customize the set (#653). -
Post-processing keeps the folder component of a resource
@src. A
resource whose@srchad a directory part (e.g.<ltx:resource src="subdir/foo.css">, fromRequireResource("subdir/foo.css")) was copied to
a flattened path (<dest>/foo.css) while the emitted<link>/<script>
href keptsubdir/foo.css— a dangling reference. The copy now preserves the
path relative to the source directory when it stays below the destination (else
flattens to the basename), and rewrites@srcto where the file actually
landed — matching PerlXSLT::copyResource(#662). -
--whatsin=xmlpost-processes an already-converted core document (the
latexmlpostrole). The input type was inferred only from the file
extension, so a core LaTeXML XML document under a project-specific name (e.g.
paper.preprocessed-xml) was mistaken for TeX and re-digested as garbage. Now
any extension ending in-xml/_xml(or exactly.xml) is auto-detected as
XML input, and--whatsin=xmlforces the XML-input path regardless of the
extension — the input analog of--formatfor output. Either way the TeX
engine is skipped and the file goes straight to post-processing, so the same
XML can be re-rendered to several outputs without re-digesting the source
(#655). -
RelaxNGSchema()actually loads a custom schema. Selecting a RelaxNG
schema from raw.rngat runtime (the RhaiRelaxNGSchema()binding, or any
non-LaTeXMLschema with no compiled.model) scanned and parsed the file but
never distilled it into the tag/attribute/namespace tables the runtime consults
— so every element was rejected (<ltx:document> isn't allowed in <#Document>)
and the output came out empty. The scan now populates those tables (a port of
PerlModel/RelaxNG.pm'sextractContent+ tag loop), so a custom schema
validates. Namespaces are now resolved with the full XML expressivity Perl
has: a schema's target namespace given only as a defaultns=(noxmlns:
prefix — howLaTeXML.rngis written) resolves to the conventional code
prefix the engine registered (dlmf →ltx) instead of a synthetic
namespace1, and becomes the default output namespace; foreign namespaces,
whether built-in (svg/m/xlink/xhtml) or supplied by a third-party or
runtime.rhaiRegisterNamespace, serialize under their registered prefix
instead of anamespaceN+ "no prefix registered" warning (ports of Perl
encodeQName/getNamespacePrefix,getDocumentNamespacePrefix's code-prefix
fallback, andRelaxNG.pm's default-namespace registration). Disk lookup also
appends.rngto a bare schema name across all--pathsearch dirs (matching
Perl), soRelaxNGSchema('MySchema')resolvesMySchema.rng(#652). -
An
Undigestedconstructor argument reaches a Rhai body asTokens. A
runtimeDefConstructorwith anUndigested(orOptionalUndigested) parameter
handed its imperative|document, arg|body an opaqueDigestedhandle wrapping
nonsensical-looking token data, soUnTeX/Expandon the argument threw and the
binding degraded. It now arrives asTokens— matching Perl, where an undigested
reader keeps its argument as raw Tokens (Constructor.pmgetArgs) — and
document.absorb(tokens)accepts it directly (#634). -
A Rhai constructor body can read the whatsit's properties. Inside an
imperativeDefConstructorbody onlydocument.absorbProperty(name)existed —
it splices a property into the tree but cannot return one, so a body could not
branch on or compose from a property. Newdocument.getProperty(name)(the
typed value,()when absent) anddocument.getProperties()(the whole map)
read the same construction-time property map, matching Perl, which hands
$whatsit->getPropertiesto a CODE replacement (Constructor.pm:137) (#635). -
The font
encodingis no longer emitted as an output attribute. The
font-encoding property is a FontMap-lookup key used during digestion to decode
unicode; it is meaningless afterwards and noltx:element declares it. It was
still placed in the relativized font-attribute set, where it normally vanished
(no element accepts it) but leaked onto raw xhtml a binding splices in via
insertXML—\fontencoding{T1}\selectfont+ a\bmlRawHTML-style binding
produced<xhtml:div encoding="T1">(the div'sattribute *schema wildcard
accepts anything).Font::relative_tonow omits it, so@encodingappears
nowhere (#638). -
A shared author-email line distributes across the authors instead of bunching
on the last one.\email{a@x, b@y, c@z}(or a single\emailcovering several
authors) previously attached every address to whichever creator was open when the
line was digested — usually the last — leaving the rest email-less. A distributed
list now maps email i to author i; grouped brace-expansion ({a,b,c}@dom)
expands then distributes without leaking into an affiliation; and a single shared
address lands on the lead (first) author (OXIDIZED_DESIGN #52(j)). Witness
arXiv:2605.23553. -
Supplementary-Material documents are converted and joined into the output.
A submission with several top-level.texfiles (a main paper + a
Supplementary-Information document, both.bbl-backed — arXiv's canonical
shape) previously lost everything but the main. The directory front-end now
detects the ordered set (find_top_level_texs, template-safe) and converts
each independently, joining them into one document: the main first, each
supplement an appendix titled by its own\title, with the supplement's
id/label space prefixed so cross-references resolve within each document and
never collide. Several files given side-by-side on the CLI
(latexml_oxide main.tex supplement.tex) are joined the same way. In-memory
join (latexml::multidoc); streaming-scale submissions remain a follow-up. -
Multi-file arXiv submissions select the real paper, not a bundled template.
When the truemain.texdelegates its figures to\input-ed sections (no
direct\includegraphics) but a shipped class template / how-to / supplement
carries an example\includegraphics{fig.png}, the top-level-file guess picked
the decoy — so the HTML rendered "How to Use the IEEEtran Templates",
"Formatting Instructions for ICLR 2025", "Supplementary: …", etc. Two fixes:
(a) a faithful-parity fix — the pdf-\includegraphicsprobe is now
argument-anchored to match Perl exactly (extensionless /.epsexamples with a
stray.pngmention no longer false-positive), recovering papers Perl already
got right (arXiv/html_feedback#442, #859); and (b) a surpass — the matching
.bblsibling now outranks the pdf heuristic (OXIDIZED_DESIGN #132), recovering
8 papers Perl also mis-selects (arXiv/html_feedback#1721, #6100, #5867, #5476,
#4156, #4067, #2369, #2224). 0 regressions across a 133-paper blast-radius sweep. -
\hspace-separated authors split, and equal-contribution superscript marks
render. An\authorblock that lays co-authors out with\hspace{len}/
\hfillinstead of\andcollapsed into one<personname>, and a literal
footnote-symbol mark ($^{*}$,\textsuperscript{\dagger}— equal-contribution
/ corresponding notes) was consumed into an affiliation label that matched
nothing and silently dropped. Horizontal-space macros now normalize to the
\quadauthor separator, and symbol marks render as a visible superscript
(numeric affiliation marks are untouched). For the witness — arXiv 2506.06941,
"The Illusion of Thinking", whose arXiv HTML is byte-identical Perl 0.8.8 — the
six welded authors now split, Iman Mirzadeh's$^{*}$returns, and "Apple"
becomes the last author's affiliation. Surpasses Perl (arXiv/html_feedback#6637). -
apacite's old
.bblformat renders. apacite's pre-2012 bibliography
format labels each\bibitemwith\BCAY{full}{short}{year}and formats
entries with\Bem/\BBACOMMA— macros the binding did not define, so a
theapa/apacite.bblfloodedError:undefined:and leaked the macro names
into the References. They are now defined (\Bem=\emph,\BCAY→author
label,\BBACOMMA=","), so old-format apacite bibliographies convert cleanly
(the modern\citeauthoryearformat already worked). Related
arXiv/html_feedback#6489. -
A
\refto a\nonumbereqnarray row shows the equation number, not the
paper title. A\labelright after\begin{eqnarray}whose first row is
\nonumberbound to that unnumbered row;\reffound no number there and fell
through to the document title, rendering the whole paper title as the link
text. The label now inherits the equation group's number (matching pdflatex's
\ref), so it renders "1". Surpasses Perl, which leaks the title identically.
Witness arXiv 2308.06222 (arXiv/html_feedback#94). -
jcappub (JCAP) papers now render their full author list. jcappub is JCAP's
SISSA/IOP class — the JCAP sibling of jheppub — with the same accumulating
\author[affil]{name}+\affiliation+\emailAddfrontmatter. It was
unbound, so each\authorfell through to article's (which overwrites) and the
list collapsed to the last author, with\affiliation/\emailAddundefined.
jcappub now loads the jheppub binding. Witness arXiv 2404.03569 (63 authors,
previously 1; arXiv/html_feedback#6884). -
Unsorted bibliography styles number the References in citation order.
\bibliographystyle{unsrt}/{ieeetr}/{IEEEtran}alphabetized the reference
list, mismatching the PDF (whose figure captions bake in "[2], [3], [4]"). The
References are now numbered by first citation — matching pdflatex+bibtex
key-for-key — while sorted styles (plain/alpha/…) stay alphabetical.
Surpasses Perl, which alphabetizes every style. Witness arXiv 2510.05438
(arXiv/html_feedback#6294). Now also reaches natbib/revtex papers: the
\bibliographystylename is recorded before natbib can drop it, so a
revtex4-2 or[numbers]natbibpaper withieeetris numbered by citation
order too (arXiv/html_feedback#5930, #6095). -
amsrefs papers that open with
\begin{bibsection}now render their
References.bibsectionis amsrefs' real section-heading wrapper around
{biblist}(withbibdivdefined as it), but onlybibdiv/biblistwere
bound, so\begin{bibsection}was an undefined environment — the reference
list floated into a paragraph and vanished, every\citeleft dangling. The
environment is now bound likebibdiv, titled from its optional heading
(default "References"). Witness arXiv 2405.18501 (arXiv/html_feedback#1393). -
biblatex style packages (
biblatex-chicago,-apa,-ieee, …) now render
their bibliography. A\usepackage{biblatex-chicago}variant never loaded
the biblatex binding, so its preamble\DeclareFieldFormat/\renewbibmacro
customization was undefined and the biber.bbl— guarded on
\ver@biblatex.sty— emptied the whole References list. Variant names now
route to the biblatex binding (as each.styreally does via
\RequirePackage{biblatex}), and the binding marks\ver@biblatex.styso the
.bblrenders. Witness arXiv 2605.11180 (arXiv/html_feedback#6601). -
A biblatex
\DeclareSourcemapblock no longer breaks the conversion.
Source mapping is a biber pre-processing stage LaTeXML does not run;
\DeclareSourcemap(and\DeclareStyleSourcemap) were undefined, so the
nested\maps/\map/\step/\regexpran as undefined control sequences
and cascaded into fatal math-mode errors that dropped the whole bibliography.
They now gobble the rule argument as a no-op (arXiv/html_feedback#6720). -
The REVTeX4 family renders numeric APS citations by default, honoring
author-year/numerical.revtex4/revtex4-1/revtex4-2rendered an
author-year bibliography (Alpha (2001)) with bare inline numbers, where the
PDF and the real classes render numeric — bracketed[N]inline and a
numbered reference list. The family now defaults tonumerical(the real
classes' default) and honors theauthor-year/numericalclass options that
toggle it; an explicit\setcitestyle/\bibpunctstill overrides. Surpasses
Perl, which renders author-year forrevtex4/revtex4-1and ignores those
class options. Witness arXiv 2606.09494 (arXiv/html_feedback#6609). -
A paper's title no longer absorbs publication metadata. Class frontmatter
such as acmart's\acmConference/\acmDOI/\acmISBNwas rendered inside
the title<h1>(a stray dagger hover on the heading), leaking metadata into
the title element. Now only genuine title footnotes (\thanks/\titlenote)
stay on the title; publication metadata renders as a separate block after it
(arXiv/html_feedback#6886). -
A
\text{…}-only display equation renders on one line.\[\text{The solution is not valid}\]collapsed to one word per line: the display
equation's content cell (ltx_eqn_cell) lacked thewhite-space:nowrapthat
aligned table cells get, so its wrappable marked-as-math text was squeezed
between the centering pad cells.LaTeXML.cssnow gives the equation cell the
same nowrap-with-ltx_wrap-optout as a table cell (CSS-only; output HTML
unchanged). Shared bug with Perl (#527). -
Natural-size figures scale with the text (font-relative
emsizing). A
figure included at its natural size (nowidth=/scale=) from a vector source
— a PDF page box, an EPS/PS BoundingBox, or an SVG — is now sized inem(its
true typeset size over the local font) instead of a fixed pixel count, so it
keeps the same proportion to the surrounding text at any reading size and
reaches the correct physical size at the document's font. Author-sized and
raster inclusions are unchanged. Converges with the upstream font-relative
sizing direction; commits no absolute px factor (#562). -
Search paths are now group-scoped, so a package's addition persists.
SEARCHPATHSmoved from a plain global field to a group-scoped value (like
GRAPHICSPATHS, and like Perl's default-localAssignValue). A package that
adds a directory —\lx@append@path, or the RhaiAppendSearchPath/
PrependSearchPath— now keeps it after loading, while an\import/
\subimportgroup still reverts its own change at}. This retires
import.sty's hand-rolled\lx@save@paths/\lx@restore@pathssave/restore
stack (Perl relies only on{…}grouping) and theinput_definitions
SearchPathGuard; a directory-prefixed\usepackage{DIR/pkg}whose binding
raw-loads its own name now resolves the author's bundledDIR/pkgvia
\@currname, exactly as Perl does (#561). -
A runtime
.rhaibinding's load note prints its real file path. Loading
mybinding.sty.rhainow announces(Loading …/mybinding.sty.rhai… )instead
of the synthesizedmybinding_sty.rsproxy name — more useful, and closer to
Perl, which names the actual binding file. The resolved path is threaded
through the binding-dispatch result rather than a State side-channel;
compiled-in bindings (no file) keep their module-proxy name (#560). -
Runtime Rhai bindings can assign typed values, not just strings. New
AssignNumber/AssignFloat/AssignBool/AssignStringcomplete the typed
Assign*family so a value written from a script reads back through
LookupNumber/LookupBool/LookupString; and a newLookupFloat/AssignFloat
pair (plus internalstate::lookup_float) carries fractional values a
Numberwould truncate (#543). -
Runtime Rhai bindings gain the list-value family and search-path control.
PushValue/PopValue/UnshiftValue/ShiftValueexpose the Perl@values
list-op set (e.g. forGRAPHICSPATHS), carrying any Rhai-representable value —
string/int/float/bool/Tokens— with the type preserved across a push/pop
cycle.PrependSearchPath/AppendSearchPathadd an input directory: the Rust
port keepsSEARCHPATHSin a dedicated field, not the value table, so these
reach file resolution wherePushValuewould not (#540). -
Runtime Rhai bindings expose the document hooks.
AtBeginDocument/
AtEndDocument(TeX source or aTokensbody) queue work onto the
@at@begin@document/@at@end@documentlists the engine runs at
\begin{document}/\end{document}, mirroring PerlPackage.pm(#539). -
The
documenthandle gainsinsertPI. A.rhaiconstructor body can
emit a processing instruction (a target, with optional attribute map) under
the Perl name$document->insertPI(#537). -
NOMINAL_FONT_SIZEis read and stored as a float, not truncated to an
integer. The default-font-size reader preserves a fractional value (e.g. the
11ptclass option's10.95), matching Perl'sDEFSIZE, and the default is
now stored as a float so the assign type matches the lookup — a value assigned
for11ptround-trips instead of flooring to 10 (#542). -
Custom RelaxNG schemas resolve
urn:x-LaTeXML:RelaxNG:includes. A
<include href="urn:x-LaTeXML:RelaxNG:…">now falls back to the embedded
schema table (as<externalRef>already did) when the file is not on disk,
soRelaxNGSchema("myschema.rng")that pulls in the bundled LaTeXML modules
works in an installed binary; the no-extension URN form resolves too (#538). -
cargo build/checkno longer rebuilds the crates on every invocation when
consumed from crates.io. Three build scripts emittedcargo:rerun-if-changed
for../paths (../.git/HEAD,../resources/dumps,../.githooks/pre-push)
that are absent from a published tarball — which makes Cargo re-run the script,
and rebuild the crate, every time. Each is now emitted only for a source
checkout, so a git/workspace build tracks them exactly as before (including
dump staleness) while a crates.io build stays cached (#528). -
A
longtable\captionno longer leaves a stray empty row above the
header. The caption text is hoisted into<ltx:caption>, but the body row
it occupied was left as empty cells (a bordered blank line vs the header —
Perl does the same). The now-textless caption row is dropped via the existing
\killrow-discard path, uniformly wherever the caption sits (#534).
What's Changed
- chore(deps): update similar requirement from 2 to 3 by @dependabot[bot] in #529
- docs(skill): /next-release runbook from the 0.7.5 cut by @dginev in #524
- ci: green the lint job after dep-float drift (audit tuples + smartstring advisory) by @dginev in #532
- feat: assign typed (non-string) values from Rhai bindings + LookupFloat/AssignFloat by @dginev in #544
- feat: PushValue list family + search-path bindings for Rhai (#540) by @dginev in #547
- fix: LNCS shared \email attaches to every \inst author (html_feedback#6881) by @dginev in #545
- feat: structure lazy IEEEtran author blocks (\[1em] + shared email), beyond Perl by @dginev in #546
- feat: expose AtBeginDocument/AtEndDocument to Rhai bindings (#539) by @dginev in #548
- docs: KNOWN_PERL_ERRORS #75 now records Rust surpassing Perl by @dginev in #549
- feat: expose document.insertPI to Rhai bindings (#537) by @dginev in #550
- fix #536: define \lx@save@parameter so latexml.sty saves conversion parameters by @dginev in #551
- fix: read NOMINAL_FONT_SIZE as a float, not a truncated integer (#542) by @dginev in #552
- fix #541: \LaTeXMLversion reports the binary version, not a stale 0.4.0 by @dginev in #553
- fix: resolve urn:x-LaTeXML:RelaxNG includes from the embedded table (#538) by @dginev in #554
- fix: guard build-script rerun-if-changed on path existence (#528) by @dginev in #555
- chore: compact docs and consolidate test binaries for CI economy by @dginev in #556
- fix #534: drop the stray empty longtable caption row by @dginev in #557
- fix #560: announce a runtime .rhai binding by its real path by @dginev in #564
- fix #530: resolve --opt/--noopt flag pairs rightmost-wins (GetOpt::Long) by @dginev in #563
- fix #526: empty \hypertarget no longer wraps the open note (surpass-Perl) by @dginev in #565
- feat #559: surface enumitem leftmargin for CSS theming (surpass-Perl) by @dginev in #567
- fix #561: group-scope SEARCHPATHS, retire the SearchPathGuard by @dginev in #566
- fix #558: parskip sets \parindent=0 (no-indent paragraphs) instead of a no-op by @dginev in #568
- fix #535: unary minus after a relation keeps its spacing by @dginev in #569
- fix #562: font-relative (em) sizing for natural-size vector figures by @dginev in #570
- fix #533: contain display math inside width-constrained table cells by @dginev in #572
- fix #527: \text-only display equation renders on one line, not stacked by @dginev in #571
- fix #398: harden the ltx_picture SVG splice against attribute order/quotes by @dginev in #575
- chore: keep the Playwright render test opt-in/local, not in CI by @dginev in #574
- chore: retire ISSUE_AUDIT.md (GitHub tracker + parity docs supersede it) by @dginev in #576
- fix html_feedback#6886: publication metadata no longer pollutes the title
by @dginev in #577
- docs(WISDOM): compact the narrative-heavy early entries; de-stale #38/#46 by @dginev in #578
- fix #525: fancyvrb frame=single renders as a semantic box (frame, stray line, background) by @dginev in #573
- fix #531: pdfcol.sty no-op stub (breakable tcolorbox no longer errors) by @dginev in #579
- test html_feedback#6888: guard title footnote renders mark-only, not inline by @dginev in #580
- test html_feedback#6622: guard Greek math letters render as Unicode, not U+FFFD by @dginev in #581
- fix #512: unpin nightly (fat-LTO OOM regression resolved upstream) by @dginev in #582
- feat: faithfully emulate \everyjob so l3sys system constants are defined (#531 secondary) by @dginev in #583
- fix html_feedback#970: siunitx empty unit renders invisibly, not as "nothing" by @dginev in #584
- fix: REVTeX4 family numeric-by-default citations, honoring author-year/numerical by @dginev in #586
- fix: author-year inline citations match the References list label by @dginev in #587
- fix: biblatex \DeclareSourcemap is a no-op, not a fatal cascade by @dginev in #588
- fix html_feedback#6869: \widthof box widths resolve in all dimension contexts by @dginev in #589
- fix: dedup LLNCS \inst affiliations cited by multiple authors of one creator by @dginev in #590
- fix: unsorted bibliography styles number References in citation order by @dginev in #591
- fix: reduce inner \linewidth to the wrap width inside wrapfig floats by @dginev in #592
- fix #593: Note/NoteLog/NoteSTDERR write to the right stream(s) by @dginev in #596
- test: drive the widthof guard via the in-process convert_to_xml API by @dginev in #597
- fix: citation-order numbering reaches natbib/revtex (ieeetr) by @dginev in #595
- feat #594: expose canContain, floatToElement to Rhai by @dginev in #598
- fix: amsrefs
{bibsection}environment renders its References by @dginev in #600 - fix: biblatex style packages (biblatex-chicago, …) render their bibliography by @dginev in #599
- fix #354:
\verbinside\indexrenders as typewriter, not an empty<verbatim/>by @dginev in #601 - fix html_feedback#84: aa.cls loads [T1]{fontenc} (text
</>render as themselves) by @dginev in #603 - fix:
\refto a\nonumbereqnarray row shows the equation number, not the title by @dginev in #602 - fix: jcappub (JCAP) papers render their full author list by @dginev in #604
- feat: two-machine memory-sync tool (tools/sync_memory.sh) by @dginev in #605
- test: guard 3 self-resolved regressions by @dginev in #606
- test: guard acmart pubnotes stay out of the title (html_feedback#6885) by @dginev in #607
- fix html_feedback#74: picture math/graphics survive into the SVG by @dginev in #609
- feat: apacite binding renders the old .bbl format by @dginev in #608
- docs: record .aux multi-pass parity limit (#6895 \HL/\HA links) by @dginev in #610
- fix html_feedback#6614: short author names in ACL \author blocks stay authors by @dginev in #611
- fix #6870: \centering in a redefined \abstractname stays out of the abstract heading by @dginev in #613
- fix: render natbib citations of a numeric .bbl as [N], not the raw key by @dginev in #616
- fix: recover figures injected into the title via \g@addto@macro@maketitle by @dginev in #618
- fix #61: unwrap whole-name bold so author lines render coherently by @dginev in #615
- fix: multi-line author block with trailing \quad\ keeps line-2 first author by @dginev in #620
- docs: author-markup pipeline unification worklist + baseline by @dginev in #617
- fix #4539: drop phantom empty author creators from comma-split \IEEEmembership by @dginev in #619
- fix: a wrapper box merges its class onto a single block child, keeping ltx_lstlisting by @dginev in #614
- test: guard biblatex preamble macros stay consumed (html_feedback#4276) by @dginev in #621
- fix: numeric-mode natbib .bbl labels the References with [N], matching pdflatex by @dginev in #612
- docs+tool: retract false footnotemark-leak verdict; fix characterization tool by @dginev in #622
- fix #6242: split multiple \textsuperscript{n} affiliations on one line by @dginev in #623
- fix: minted honours escapeinside so a code-line \label links by @dginev in #625
- fix: cvpr pre-loads natbib with [numbers] so citations render as numbers by @dginev in #626
- fix #627: GetKeyVals accepts a digested KeyVals, and Revert keeps its values by @dginev in #628
- fix: transpose IEEEtran multi-row author grid to row-major reading order (arXiv:2403.16405) by @dginev in #624
- fix #1021: nested inline-math author markers no longer desync math mode by @dginev in #629
- fix: bind the derivative package; cleveref tie reverts as a plain ~ by @dginev in #630
- feat: \and is a hard author boundary in the superscript-marker branch (#1021 F2) by @dginev in #631
- fix: \twocolumn spanning-header font no longer leaks into the body by @dginev in #632
- fix #6255: authblk \author{A, B, C} comma list splits into separate creators by @dginev in #633
- fix: cleveref \cref matches LaTeX for custom \newtheorem types by @dginev in #636
- fix html_feedback#6637: \hspace separates co-authors, footnote-symbol marks render by @dginev in #637
- fix: multi-file arXiv submissions pick the real paper, not a bundled template by @dginev in #639
- feat: convert + join Supplementary-Material documents into one output by @dginev in #640
- fix: chapterbib/bibunits per-unit bibliography lists id keeps _ raw by @dginev in #641
- feat: distribute a shared author-email line per author instead of bunching on the last by @dginev in #643
- fix: colortbl \columncolor overhang read no longer eats a \lbrack cell by @dginev in #642
- fix: leaked active
@no longer destroys the.bibbibliography by @dginev in #646 - fix: comment.sty
\end{comment}mid-line no longer swallows the document by @dginev in #649 - fix #634: Undigested constructor arg reaches a Rhai body as Tokens by @dginev in #645
- docs: multi-document join + queued streaming post-join design by @dginev in #644
- feat #635: read whatsit properties inside a Rhai constructor body by @dginev in #647
- fix: physics.sty
\qty(...)with a braced paren no longer runs away by @dginev in #654 - fix #652: RelaxNGSchema() loads a custom schema into the runtime model by @dginev in #657
- fix: imsart bibliography reads the
.bibwhen no.bblships by @dginev in #658 - fix #638: don't leak LaTeXML font attributes onto raw xhtml markup by @dginev in #648
- feat #653: StartSemiverbatim/EndSemiverbatim for verbatim Rhai bodies by @dginev in #661
- fix #651: no-dump conversions no longer fail on a benign expl3 raw-load cascade by @dginev in #660
- fix: OmniBus \authors/\affil register proper creators (AGU frontmatter) by @dginev in #664
- fix #662: post-processing preserves the folder component of a resource @src by @dginev in #663
- feat #655: --whatsin=xml post-processes an already-converted core document by @dginev in #659
- docs #297: Perl .ltxml bindings are not loaded — rewrite as .rhai by @dginev in #667
- feat #656: --urlstyle=(server|negotiated|file) for cross-reference URLs by @dginev in #666
- fix #520: minted \newminted no longer clobbers [ and swallows the document by @dginev in #665
- chore: fold four small unit-test files into one cluster_units binary by @dginev in #669
- feat: minted inline commands render + syntax highlighting (follow-up to #520) by @dginev in #668
- ci: skip jobs a diff can't affect; gate macOS on the libxml surface by @dginev in #671
- docs: prune solved/outdated SYNC_STATUS entries by @dginev in #673
- fix: resolve picture-nested graphics into the SVG foreignObject by @dginev in #675
- test: guard titlepic @maketitle-redefine teaser figure (already surpasses Perl) by @dginev in #672
- perf: UTF-8 SIMD fast-path on the .cls/.sty dependency-scan slurp by @dginev in #674
- fix: stop constant rebuilds until resources/dumps exists (#676) by @dginev in #678
- fix: resolve default/foreign namespaces for runtime RelaxNGSchema() (#652) by @dginev in #679
- feat: overpic renders its graphic + \put overlays (~37 arXiv papers) by @dginev in #677
- fix: sn-jnl sn-apa style loads apacite for its APA bibliography by @dginev in #681
- fix #680: serializer keeps foreign mixed content inline by @dginev in #684
- fix: sn-jnl abstract renders after the title, not before it by @dginev in #685
- feat #683: persist non-default NOMINAL_FONT_SIZE as a PI by @dginev in #686
- fix: picture-nested graphic no longer renders giant or doubled by @dginev in #682
- fix: neurips preprint/final papers keep the body after the abstract by @dginev in #687
- fix: biblatex must not globally define \type (broke user math macros) by @dginev in #689
- feat: register neurips_2026 to the shared neurips binding by @dginev in #690
- test: guard IEEE-journal superscript author/affiliation block by @dginev in #688
- fix: IJCAI-derivative \author blocks split names/affiliations/emails by @dginev in #691
- fix: strip the comma separator from superscript-keyed affiliations by @dginev in #693
- fix: ceurart \author keyval no longer leaks orcid=/email= into the body by @dginev in #692
- fix #698: relativize sibling-dir graphic candidates (no absolute-path leak) by @dginev in #699
- feat #697: \subimport* accepts an absolute directory path (match pdflatex) by @dginev in #701
- docs #702: clarify StartSemiverbatim is semi- not full-verbatim (Rhai API) by @dginev in #705
- fix #696: size SVGs from root width/height like a browser, not the viewBox by @dginev in #700
- docs #704: semiverbatim consumes literal braces as grouping by @dginev in #707
- fix: two-column subfigure panels share a row instead of stacking full-width by @dginev in #706
- fix: arrange_panels never wraps a figure/table panel in an invalid ltx:block (LaTeXML#2709) by @dginev in #708
- fix #703: math-parse discard no longer double-frees nested \sbox subtrees by @dginev in #709
- test: guard svg+subcaption \subfloat survives (surpasses Perl, brucemiller/LaTeXML#2563) by @dginev in #710
- fix: emit img aspect-ratio so flex-capped figures don't distort (brucemiller/LaTeXML#2392) by @dginev in #711
- feat: bind scalerel so \scalerel* inline icons scale to text height (arXiv/html_feedback#6895) by @dginev in #712
- fix: distribute up-front amsart author contacts to their own authors (arXiv/html_feedback#46) by @dginev in #713
- chore(release): prepare 0.7.6-rc1 by @dginev in #714
- feat: evaluate calc column widths so Pandoc tables don't collapse to 0pt (arXiv/html_feedback#6909) by @dginev in #717
- fix: resolve sandbox-arxiv-2605 conversion regressions by @dginev in #720
- chore: audit cc 1.4.4 to unblock the floating-lock CI gate by @dginev in #728
- docs: plan ar5iv.css as default + record #721 image-sizing intent gap by @dginev in #725
- feat #722: preserve \[dimen] optional glue as themeable --ltx-break-space CSS variable by @dginev in #729
- fix: 2606 corpus — cleveref class stubs, AASTeX, subdir package-path shadow by @dginev in #726
- chore: fingerprint-verify native code so byte-identical crate bumps auto-pass the audit by @dginev in #730
- fix #719: first paragraph honors \parindent=0 (no default indent) by @dginev in #724
- fix #723: keep ~ and ^ ASCII in verbatim contexts under T1 by @dginev in #727
- chore(ci): make asan + macOS lanes robust against two recurring flakes by @dginev in #731
- fix: converted graphics sharing a basename no longer collide (arXiv/html_feedback#6922) by @dginev in #735
- feat: render nicematrix matrices with \CodeBefore cell colors (arXiv/html_feedback#6569) by @dginev in #733
- fix #6571: uniform ORCID iD logo + ecai reference-linked affiliations by @dginev in #737
- fix: drop hand-typeset title that duplicates structured \title{} (arXiv/html_feedback#6924) by @dginev in #738
- fix: \fmtversion reflects the precompiled kernel dump (#739) by @dginev in #741
- fix: aliascnt theorem counters get xml:id so labels/refs resolve to the theorem by @dginev in #732
- fix: \url / \path keep ~ and ^ ASCII in display under T1 fontenc by @dginev in #734
- fix: math-array vertical rules render, and !{|} aligns like Perl by @dginev in #743
- feat: per-conversion identity banner (exe, version, revision, start time) by @dginev in #744
- test: guard the listings-tail leak that dropped a paper's second half by @dginev in #745
- fix: tables inside a tcolorbox no longer render upside down by @dginev in #746
- harden: carry the node box onto clones (complete the node-box invariant) by @dginev in #747
- fix #1396: link fairmeta authors to their institutions by superscript mark by @dginev in #748
- docs(sync-status): record fairmeta family trailing items by @dginev in #749
- fix: hyperref \url/\href keep a leftover control sequence literal, not digested by @dginev in #753
- Windows: performance profile + path/portability fixes (green Windows suite) by @dginev in #752
- feat: algorithm2e/float golden-match rendering (Part 1) by @dginev in #751
- fix #755: don't over-space aligned/gather relations (reset native-MathML mtd padding) by @dginev in #756
- feat: minted Pygments colors + acmart affiliation comma wrapping + shared-affiliation-below-authors by @dginev in #757
- fix(algorithm2e): uniform bold line numbers, ruled caption-at-top, inline Comment*[r]; leader separators fill column; frontmatter dedup by @dginev in #754
- feat: frontmatter affiliation surpasses (acmart comma wrapping + shared affiliation below authors) by @dginev in #758
- chore(release): 0.7.6-rc2 (validation RC) by @dginev in #759
- fix #761: math in a title serializes cleanly in cross-ref tooltips by @dginev in #765
- fix #763: keep a minimum log verbosity under --quiet by @dginev in #764
- feat: ltx_break css hook for breaklines=true framed verbatim (#702) by @dginev in #718
- fix: streaming byte-identity for a framed breaklines verbatim by @dginev in #766
- docs(perf): 2026-08-23 audit — eager Debug! P0 lever + ranked findings by @dginev in #768
- fix: \newtcblisting leading [init-options] optarg + 2606 study plan by @dginev in #767
- perf: lazy Debug! + audit mechanical fixes — corpus −12.8%, build-bound witness −56% by @dginev in #770
- feat: OmniBus captures \orcid, no-ops \lefttitle/\righttitle by @dginev in #769
- chore(release): 0.7.6 by @dginev in #771
Full Changelog: 0.7.5...0.7.6