Skip to content

0.7.6

Latest

Choose a tag to compare

@github-actions github-actions released this 23 Aug 22:05
1ef264a

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 portable latexml-oxide-0.7.6-x86_64-unknown-linux-gnu.tar.gz
  • Linux (aarch64 / arm64) — latexml-oxide_0.7.6-1_arm64.deb, or the portable latexml-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.exe is 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 \orcid and no-ops the \lefttitle/\righttitle
    running heads.
    Unbound bundled journal classes fall through to the generic
    OmniBus fallback, where Perl's OmniBus.cls.ltxml leaves these three undefined
    (→ Error, content dropped). \orcid[]{} now routes to the existing
    \lx@add@orcid helper, so the identifier is captured as a real
    <ltx:contact role="orcid"> with an orcid.org link (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 (\aff is 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; guard omnibus_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_element sites serialized the current
    subtree via node_to_string on every text insert / element close — evaluate
    only when --verbose/--debug would 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_family memoized per arena symbol (was a string-prefix
    probe ×2 per CS token); generate_id finds its xml:id ancestor by a direct
    parent walk instead of a per-node XPath parse+eval; post-processing's
    collect_walk_matches iterates siblings instead of materializing a child
    Vec per 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 :locked twin per defined
    cs); LATEXML_TELEMETRY_OUT appends JSONL instead of truncating to the last
    record; 13 clippy redundant_clone sites 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.

  • --quiet reduces console output only; the .latexml.log keeps a minimum
    verbosity floor.
    Previously --quiet lowered the single log level filter to
    Warn, which dropped the identity banner, every (Processing …/(Loading …
    progress note, and all Info: 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 (Perl Common/Error.pm _printline/ProgressSpinup: $LOG is
    written whenever the log is open, STDERR only when $VERBOSITY >= 0): the log
    floor stays at Info regardless of --quiet, while STDERR follows the console
    verbosity; --verbose/--debug raise both. Error/Fatal still 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
    (Perl Note — log always, stderr when not quiet) and \message (Perl NoteLog
    — log-only, never stderr); both previously vanished from the log under --quiet.
    Two raw eprintln! fallback diagnostics (store.rs Stored→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}.

  • \newtcblisting now 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.

  • minted code blocks render Pygments syntax colors, not just bold-black. When the
    source ships a committed _minted/ frozencache, minted_frozencache.rs content-matches
    each highlight file's plain code (\PYG unwrapped, \PYGZ* resolved) to a block body
    and emits Pygments-colored listing lines, reusing the listings constructors + xcolor;
    a cache miss (or no _minted/) falls back byte-identically to the uncolored path. Perl
    errors on minted — 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 \ignorespaces between \institution{}\city{}… parts and joins with a comma +
    breakable space, matching real acmart.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_annotations no longer mis-binds a shared affiliation:1 to 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 \thanks renders 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:note is added to ltx:creator's content model. Witnesses arXiv 2512.24601,
    1510.02728; guards authors_test, cluster_author_thanks_marked_note.

  • A .bbl preamble no longer produces a spurious empty (1) bibliography entry.
    An ACM-Reference-Format-style .bbl puts 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/\If bodies 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; guard cluster_algorithm2e_for_body_indentation.

  • A bare email trailing an IEEEtran \author block 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 \hsize separators stack instead of overflowing.
    Following the width:100% relativization (OXIDIZED_DESIGN #152), two \dashfill
    separators flanking a centered label on one nowrap listingline still overflowed (two
    width:100% inline-blocks side-by-side sum to >200%). The fill-line box is now also
    marked class="ltx_leaderfill", and the stylesheets set it display:block, so each
    separator owns its line — matching the pdflatex golden. Witness arXiv 1510.02728
    ("Modified ellipsoid method"); guard cluster_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/\While lines and staying plain
    elsewhere; renumber_algo_lines was 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_top DOM-moves the caption before the body for that
    family only (plain/boxed unchanged). (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). Guards cluster_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 absolute width="345.0pt" (the article \textwidth default), 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 relative width="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-author creators 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; guard cluster_frontmatter_replaceable_dedup.

  • Algorithm listings no longer show a phantom vertical scrollbar. An auto-height
    .ltx_listing never overflows vertically, but the CSS Overflow spec promotes
    overflow-y:visible→auto whenever overflow-x scrolls, painting a spurious vertical
    scrollbar (algorithm2e listings). The embedded LaTeXML.css now pins
    .ltx_listing:not(.ltx_lstlisting){overflow-y:hidden} (mirroring the ar5iv.css fix).
    Witness arXiv 2002.09766.

  • aligned/gather relations are no longer over-spaced in HTML. An
    aligned (or align/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, so y(x) = … came out visibly loose. LaTeXML.css now
    zeroes that padding on columnspacing="0pt" tables, leaving only the relation
    operator's own spacing; matrices/arrays (bare <mtd>, non-zero columnspacing,
    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 global mtd{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/\href no longer disappears. A
    non-expandable primitive inside a URL (e.g. \url{https://ex/q=\def}) was read
    semiverbatim and then digested — \def executed, 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 to other) instead of
    handing it to digestion, while still expanding the url.sty escapes (\%,
    \_, \^, \textbackslash, …) during the read, so realistic URLs are
    unchanged and \url/\href now 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); guards cluster_url_cs_verbatim_723, hyperurls_test.

  • fairmeta.cls papers now link each author to their institution. The
    Meta/FAIR pre-print template (and its selfevolagent/openmoss siblings)
    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
    authblk idiom: \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); guard frontmatter_fairmeta_author_affiliation_1396.

  • Tables inside a tcolorbox no longer render upside down. A tabular
    inside a tcolorbox enhanced skin 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-flip transform="matrix(1 0 0 -1 0 h)" (set by its size-dependent
    afterClose) or it draws vertically upside down. When building that wrapper,
    insert_block renames a _CaptureBlock_ — which carries the block's box — to
    svg:foreignObject, but the rename dropped the node box (Perl carries it via
    the internal _box attribute), so the afterClose read a zero size and skipped
    the flip. rename_node_internal now 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); guard cluster_tcolorbox_tabular_not_flipped_6873.

  • Every conversion logs an identity banner: executable, version, revision,
    start time.
    At the head of each conversion latexml_oxide, cortex_worker
    and latexmlmath_oxide now log a line like latexml_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_SHA env for packaged builds without .git); --quiet
    suppresses the banner. Guards: identity::tests, identity_banner
    (cluster_cli).

  • Vertical rules in a math array now render, and !{|} aligns like Perl.
    Two defects from one report, both now byte-for-byte Perl parity. (1) A | or
    \hline in a display-math array — \begin{array}{cc|c}, a framed |c|c|, or
    a colortbl \arrayrulecolor rule — 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_array now folds border → ltx_border_* (and thead → ltx_th_*) CSS
    classes onto the m:mtd, matching Perl MathML.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 \hbox digestion) wrongly
    re-centered it. extract_alignment_column now recognises a fill defeated by
    inserted content — while a \vrule rule stays skippable, so cc|c cells remain
    centered. Reported in #740 and #742 (reporter nasser1);
    guard cluster_array_vertical_rule_border_740.

  • Author ORCID iDs render as the green iD logo, uniformly. Every class that
    provides an \orcid now routes through the one canonical frontmatter macro
    \lx@add@orcid, which emits a standard ltx:contact[role=orcid] carrying the
    ORCID logo linked to https://orcid.org/<id>. The logo is a single shared
    kernel asset (\lx@orcidlogo / \lx@orcidlink), reused by orcidlink.sty's
    \orcidlink and 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/\orcidlogo logo 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/\thanks inside the
    author are handled. Fixes arXiv/html_feedback#6571.

  • ~ and ^ stay ASCII in verbatim under T1 font encoding. The displayed
    text of a \verb, the verbatim environment, \url/\path, or a
    Verbatim/HyperVerbatim argument (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/\path were completed after Vincenzo's follow-up on #723
    (their \UrlFont-wrapped display is digested separately from the semiverbatim
    href arg). A new tools/fontmap_drift.py checks our fontmaps against pdftex's
    glyphtounicode golden. Surpasses Perl (verbatim/\url display loses ASCII
    there too); OXIDIZED_DESIGN #144, #723.

  • The first paragraph is no longer indented when \parindent is 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 \par and the first paragraph has
    none. It is now marked ltx_noindent too, matching pdflatex — and only when
    \parindent is genuinely zero, so default documents are unchanged. Surpasses Perl
    (identical off-by-one); completes the parskip fix (OXIDIZED_DESIGN #143, #719).

  • Pandoc relative-width table columns no longer collapse to a "river of
    characters".
    A p{(\columnwidth - N\tabcolsep) * \real{X}} column — the width
    format Pandoc emits by default — is a calc infix expression the base dimension
    reader could not evaluate, so every column came out width="0.0pt" and its text
    wrapped one character per line. Column widths now route through the calc
    expression parser when calc is loaded, giving the intended proportional widths.
    Surpasses Perl 0.8.8 (which emits the same 0pt + Missing number warning);
    pdflatex renders the real widths (OXIDIZED_DESIGN #141, arXiv/html_feedback#6909,
    witness 2606.08266).

  • A framed fvextra verbatim with breaklines=true carries a stable ltx_break
    css class
    , so a stylesheet can target wrapping vs non-wrapping verbatims apart
    (.ltx_framed_verbatim.ltx_break vs :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_verbatim remap (#702).

  • Streaming byte-identity for a framed breaklines=true verbatim. A single-line
    such verbatim (its parbox layer crosses a fragment seam) used to render nested under
    --streaming yet collapsed under the eager path, because spill_closed_subtrees
    spilled the frame's sole ltx:text child before the frame closed, leaving a
    <_spilled_/> placeholder that auto_collapse_children could not merge. The spill
    guard now keeps that lone child resident until its frame closes, so both paths
    collapse identically (#702).

  • minted code blocks render with syntax highlighting, and inline \mint/\mintinline
    work.
    The minted family now emits highlight token classes so a stylesheet colors the
    source; inline \mint/\mintinline render like the block form; \newmint* accepts the
    optional [env-name]; and escapeinside lets a \label inside a listing register on its
    own line (#668, #665, #625). Tier-2 (an exact-Pygments pygmentize subprocess) is parked
    behind issue #670.

  • overpic renders its base graphic plus \put overlays. The overpic/overpic*
    environment — a graphicx image carrying a picture-coordinate overlay — was unbound; it
    now draws the base graphic and composes the \put overlays 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 \includegraphics in a flex-capped figure keeps
    its aspect ratio via an emitted aspect-ratio (#711); external SVGs are sized from the root
    width/height like a browser rather than the viewBox (#700, witness #696);
    picture-nested graphics resolve into the SVG foreignObject instead 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); wrapfig reduces the inner \linewidth to the wrap width
    (#592); and the ltx_picture SVG 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 \email and 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 leaking orcid=/email= as text and pre-load numeric natbib (#691, #692,
    #626); neurips_2026 registers 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, \and as a hard boundary, nested inline-math markers, one-line \textsuperscript{n}
    affiliations, \quad\\ line-2 authors, whole-name bold, phantom empty creators, an
    \abstractname \centering leak, a \twocolumn header-font leak, and figures injected into
    the title via \g@addto@macro\@maketitle are 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); a colortbl
    \columncolor overhang read stops eating a \lbrack cell (#642); aa.cls loads
    [T1]{fontenc} so text </> render as themselves (#603, html_feedback#84); \verb inside
    \index renders as typewriter (#601/#354); fancyvrb frame=single renders as a semantic
    box (#573/#525); parskip sets \parindent=0 (#568/#558); an empty \hypertarget no longer
    wraps the open note (#565/#526); siunitx empty units render invisibly (#584,
    html_feedback#970); \widthof box widths resolve in every dimension context (#589,
    html_feedback#6869); \everyjob is emulated so l3sys system constants are defined (#583);
    biblatex no longer globally defines \type over a user math macro (#689); cleveref
    \cref matches LaTeX for custom \newtheorem types and reverts a ~ tie (#636, #630); a
    pdfcol.sty no-op stub lets breakable tcolorbox work (#579/#531); and a wrapper box merges
    its class onto a single block child, keeping ltx_lstlisting (#614).

  • Math rendering fixes. A nested \sbox inside 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. imsart reads the .bib when
    no .bbl ships (#658); a leaked active @ no longer destroys the .bib bibliography (#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); GetKeyVals accepts a digested KeyVals and Revert keeps its
    values (#628/#627); canContain/floatToElement are exposed to Rhai (#598/#594);
    Note/NoteLog/NoteSTDERR write to the correct stream(s) (#596/#593); --opt/--noopt
    flag pairs resolve rightmost-wins like GetOpt::Long (#563/#530); enumitem leftmargin
    is surfaced for CSS theming (#567/#559); \LaTeXMLversion reports the running binary version
    (#553); \lx@save@parameter lets latexml.sty save conversion params (#551/#536); a UTF-8
    SIMD fast-path speeds the .cls/.sty dependency 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/\email pair 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 pass distribute_upfront_contacts redistributes ONLY a clean N × m
    pile — the other N−1 authors carry no contact and the last author's K contacts
    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.tex is 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_SIZE is persisted as a
    <?latexml nominal-font-size="X"?> processing instruction
    so post-processing
    can size font-relative (em) external SVGs correctly — an em is
    NOMINAL_FONT_SIZEpt, not always 10pt (#683). Perl never carries this value
    (it is digestion-only DEFSIZE), 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 an insert_pi bug: a PI added after the root element
    already exists was queued into the once-drained pending list 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 with latexmlpost; #656). server
    strips a trailing index.html (landing page → ./), negotiated also strips
    the .html extension (BookML's extensionless URLs), file keeps full paths.
    The UrlStyle transform 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 Perl CrossRef::generateURL +
    extension => (CrossRef.pm L656-663, LaTeXML.pm L479) exactly — including the
    (^|/) path boundary (a myindex.html is left intact). Default is file
    (Perl defaults to server; a documented divergence — OXIDIZED_DESIGN #134).

  • Rhai bindings can read a verbatim body via StartSemiverbatim/EndSemiverbatim.
    A DefEnvironment whose body contains ^/_/&/… (e.g. a code block) raised
    "Script ^ can only appear in math mode" because the body was digested normally.
    The two Perl Package.pm exports 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 @src had a directory part (e.g. <ltx:resource src="subdir/foo.css">, from RequireResource("subdir/foo.css")) was copied to
    a flattened path (<dest>/foo.css) while the emitted <link>/<script>
    href kept subdir/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 @src to where the file actually
    landed — matching Perl XSLT::copyResource (#662).

  • --whatsin=xml post-processes an already-converted core document (the
    latexmlpost role).
    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=xml forces the XML-input path regardless of the
    extension — the input analog of --format for 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 .rng at runtime (the Rhai RelaxNGSchema() binding, or any
    non-LaTeXML schema 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
    Perl Model/RelaxNG.pm's extractContent + 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 default ns= (no xmlns:
    prefix — how LaTeXML.rng is 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 .rhai RegisterNamespace, serialize under their registered prefix
    instead of a namespaceN + "no prefix registered" warning (ports of Perl
    encodeQName/getNamespacePrefix, getDocumentNamespacePrefix's code-prefix
    fallback, and RelaxNG.pm's default-namespace registration). Disk lookup also
    appends .rng to a bare schema name across all --path search dirs (matching
    Perl), so RelaxNGSchema('MySchema') resolves MySchema.rng (#652).

  • An Undigested constructor argument reaches a Rhai body as Tokens. A
    runtime DefConstructor with an Undigested (or OptionalUndigested) parameter
    handed its imperative |document, arg| body an opaque Digested handle wrapping
    nonsensical-looking token data, so UnTeX/Expand on the argument threw and the
    binding degraded. It now arrives as Tokens — matching Perl, where an undigested
    reader keeps its argument as raw Tokens (Constructor.pm getArgs) — and
    document.absorb(tokens) accepts it directly (#634).

  • A Rhai constructor body can read the whatsit's properties. Inside an
    imperative DefConstructor body only document.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. New document.getProperty(name) (the
    typed value, () when absent) and document.getProperties() (the whole map)
    read the same construction-time property map, matching Perl, which hands
    $whatsit->getProperties to a CODE replacement (Constructor.pm:137) (#635).

  • The font encoding is 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 no ltx: 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's attribute * schema wildcard
    accepts anything). Font::relative_to now omits it, so @encoding appears
    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 \email covering 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 .tex files (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 true main.tex delegates 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-\includegraphics probe is now
    argument-anchored to match Perl exactly (extensionless / .eps examples with a
    stray .png mention no longer false-positive), recovering papers Perl already
    got right (arXiv/html_feedback#442, #859); and (b) a surpass — the matching
    .bbl sibling 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 \author block that lays co-authors out with \hspace{len}/
    \hfill instead of \and collapsed 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
    \quad author 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 .bbl format renders. apacite's pre-2012 bibliography
    format labels each \bibitem with \BCAY{full}{short}{year} and formats
    entries with \Bem/\BBACOMMA — macros the binding did not define, so a
    theapa/apacite .bbl flooded Error: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 \citeauthoryear format already worked). Related
    arXiv/html_feedback#6489.

  • A \ref to a \nonumber eqnarray row shows the equation number, not the
    paper title.
    A \label right after \begin{eqnarray} whose first row is
    \nonumber bound to that unnumbered row; \ref found 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 + \emailAdd frontmatter. It was
    unbound, so each \author fell through to article's (which overwrites) and the
    list collapsed to the last author, with \affiliation/\emailAdd undefined.
    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
    \bibliographystyle name is recorded before natbib can drop it, so a
    revtex4-2 or [numbers]natbib paper with ieeetr is numbered by citation
    order too (arXiv/html_feedback#5930, #6095).

  • amsrefs papers that open with \begin{bibsection} now render their
    References.
    bibsection is amsrefs' real section-heading wrapper around
    {biblist} (with bibdiv defined as it), but only bibdiv/biblist were
    bound, so \begin{bibsection} was an undefined environment — the reference
    list floated into a paragraph and vanished, every \cite left dangling. The
    environment is now bound like bibdiv, 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 .sty really does via
    \RequirePackage{biblatex}), and the binding marks \ver@biblatex.sty so the
    .bbl renders. Witness arXiv 2605.11180 (arXiv/html_feedback#6601).

  • A biblatex \DeclareSourcemap block 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/\regexp ran 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-2 rendered 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 to numerical (the real
    classes' default) and honors the author-year/numerical class options that
    toggle it; an explicit \setcitestyle/\bibpunct still overrides. Surpasses
    Perl, which renders author-year for revtex4/revtex4-1 and 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/\acmISBN was 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 the white-space:nowrap that
    aligned table cells get, so its wrappable marked-as-math text was squeezed
    between the centering pad cells. LaTeXML.css now 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 em sizing). A
    figure included at its natural size (no width=/scale=) from a vector source
    — a PDF page box, an EPS/PS BoundingBox, or an SVG — is now sized in em (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.
    SEARCHPATHS moved from a plain global field to a group-scoped value (like
    GRAPHICSPATHS, and like Perl's default-local AssignValue). A package that
    adds a directory — \lx@append@path, or the Rhai AppendSearchPath/
    PrependSearchPath — now keeps it after loading, while an \import/
    \subimport group still reverts its own change at }. This retires
    import.sty's hand-rolled \lx@save@paths/\lx@restore@paths save/restore
    stack (Perl relies only on {…} grouping) and the input_definitions
    SearchPathGuard; a directory-prefixed \usepackage{DIR/pkg} whose binding
    raw-loads its own name now resolves the author's bundled DIR/pkg via
    \@currname, exactly as Perl does (#561).

  • A runtime .rhai binding's load note prints its real file path. Loading
    mybinding.sty.rhai now announces (Loading …/mybinding.sty.rhai… ) instead
    of the synthesized mybinding_sty.rs proxy 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/AssignString complete the typed
    Assign* family so a value written from a script reads back through
    LookupNumber/LookupBool/LookupString; and a new LookupFloat/AssignFloat
    pair (plus internal state::lookup_float) carries fractional values a
    Number would truncate (#543).

  • Runtime Rhai bindings gain the list-value family and search-path control.
    PushValue/PopValue/UnshiftValue/ShiftValue expose the Perl @values
    list-op set (e.g. for GRAPHICSPATHS), carrying any Rhai-representable value —
    string/int/float/bool/Tokens — with the type preserved across a push/pop
    cycle. PrependSearchPath/AppendSearchPath add an input directory: the Rust
    port keeps SEARCHPATHS in a dedicated field, not the value table, so these
    reach file resolution where PushValue would not (#540).

  • Runtime Rhai bindings expose the document hooks. AtBeginDocument/
    AtEndDocument (TeX source or a Tokens body) queue work onto the
    @at@begin@document/@at@end@document lists the engine runs at
    \begin{document}/\end{document}, mirroring Perl Package.pm (#539).

  • The document handle gains insertPI. A .rhai constructor body can
    emit a processing instruction (a target, with optional attribute map) under
    the Perl name $document->insertPI (#537).

  • NOMINAL_FONT_SIZE is read and stored as a float, not truncated to an
    integer.
    The default-font-size reader preserves a fractional value (e.g. the
    11pt class option's 10.95), matching Perl's DEFSIZE, and the default is
    now stored as a float so the assign type matches the lookup — a value assigned
    for 11pt round-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,
    so RelaxNGSchema("myschema.rng") that pulls in the bundled LaTeXML modules
    works in an installed binary; the no-extension URN form resolves too (#538).

  • cargo build/check no longer rebuilds the crates on every invocation when
    consumed from crates.io.
    Three build scripts emitted cargo: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 \caption no 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
    \kill row-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: \verb inside \index renders 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: \ref to a \nonumber eqnarray 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 .bib bibliography 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 .bib when no .bbl ships 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