Skip to content

Render TeX math in the entry preview - #16198

Closed
koppor wants to merge 1 commit into
mainfrom
fix-math-rendering
Closed

Render TeX math in the entry preview#16198
koppor wants to merge 1 commit into
mainfrom
fix-math-rendering

Conversation

@koppor

@koppor koppor commented Jul 7, 2026

Copy link
Copy Markdown
Member

Related issues and pull requests

Depends on JabRef/html-to-node#7 (adds the renderMath support this PR turns on). Originates from the math-in-preview request in #16145.

PR Description

🤖 Enables TeX math rendering in the entry preview. PreviewViewer turns on html-to-node's renderMath, and the default preview layout runs the abstract and comment through a new opt-in HTMLChars(preserveMath) argument. That argument lifts $…$ / $$…$$ / \(…\) / \[…\] spans out before the formatter's LaTeX-command handling (which otherwise strips or mangles them, e.g. $\sigma$$$) and splices them back verbatim — only <, >, & escaped — so the renderer receives intact TeX. The shared HTMLChars behaviour used by exports is unchanged. A preferences migration applies the same switch to existing custom preview styles, and JLaTeXMath (pulled in transitively via html-to-node) is registered as a proper JPMS module with its font companion jars merged.

This is a draft: it depends on JabRef/html-to-node#7 being merged and its 0.1.0-SNAPSHOT republished before CI can resolve withRenderMath; until then the build only succeeds locally with -PuseMavenLocal. Remaining steps once #7 lands: add a CHANGELOG.md entry and requirements doc, attach the required screenshots, and run the full check / checkstyle / modernizer / javadoc suite.

Analogies

Like honey, this change is sweet in small amounts — a crisp equation where raw $…$ used to sit. Like chocolate, it melts the delimiters away cleanly, but only if handled with care, or it smears (hence the deliberate span-protection instead of letting the formatter chew the TeX). And like the moon, the math was always there in the field text, orbiting unseen; this PR just turns the preview to face it so it finally shows.

jabref-contrib-policy:4.2:reviewed​:ok

Steps to test

  1. Add or edit an entry whose abstract (or comment) contains TeX math, for example:
    The relation $E=mc^2$ and the integral $$\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}$$, with a fraction $\frac{a}{b}$. Prices like \$5 stay literal.
  2. Open the entry preview (default preview style).
  3. Expect: the $…$ and $$…$$ spans render as typeset equations, \$5 shows as a literal $ (not math), and non-math LaTeX such as accents still converts as before.

Screenshot of the rendered preview to be attached (the layout → html-to-node pipeline renders $E=mc^2$, the Gaussian integral, $\frac{a}{b}$, and a literal $5).

AI usage

Claude Code (model claude-opus-4-8).

AI CHECKLIST.md walkthrough

1. Code self-review

Nullability and control flow

  • [/] No == null / != null checks — none added in this diff.
  • [/] No Objects.requireNonNull(...) — none added.
  • [/] New classes annotated with @NullMarked — no new classes added (only methods/fields on existing HTMLChars).
  • [/] Optional consumed with ifPresent/… — no Optional in the diff.
  • [/] StringUtil.isBlank(...) — no blank checks in the diff.

Exceptions

  • [/] No catch (Exception e) — no catches added.
  • [/] No throw new RuntimeException(...) / IllegalStateException(...) — none added.
  • [/] Logged exceptions passed as last logger argument — no logging added.

Style and idioms

  • [/] New BibEntry objects built with withers — no BibEntry construction.
  • Modern Java used — precompiled Pattern constant; no legacy idioms introduced.
  • Regexes use a precompiled Pattern.compile(...) constant — MATH_SPAN is a static final Pattern.
  • [/] Background work uses BackgroundTask — no background work.
  • No commented-out code, no trivial comments, no AI-disclosure comments in source.
  • Markdown Javadoc (///) uses Markdown syntax (`code`, [Type]), not {@code}/{@link}.

User-facing text

  • [/] All user-facing text localized — no user-facing strings added (layout format directives + an internal formatter flag).
  • [/] Sentence case / no trailing ! / no trailing : — n/a.
  • [/] Variance expressed with placeholders — n/a.

Security

  • User-controlled data HTML-escaped — reinserted math spans (field content) are escaped for <, >, & via escapeHtmlSpecials before entering the HTML preview.

Tests

  • Behavior changes in logic have added/updated tests — HTMLCharsTest (preserveMath, combined argument) and GuiPreferencesMigrationsTest.
  • Tests assert contents with plain JUnit assertEquals, no @DisplayName, do not catch exceptions, no manual temp dirs.

2. Verification commands

  • ./gradlew :jablib:check — not yet run (draft); ran targeted HTMLCharsTest + GuiPreferencesMigrationsTest + :jabgui:compileJava, all green (with -PuseMavenLocal).
  • ./gradlew checkstyleMain checkstyleTest checkstyleJmh — not yet run (draft).
  • ./gradlew modernizer — not yet run (draft).
  • ./gradlew rewriteRun reports no changes — ran, clean.
  • ./gradlew javadoc — not yet run (draft).
  • [/] markdownlint — no Markdown changed.
  • [/] IntelliJ format docker image — idea format applied locally against .idea/codeStyles/Project.xml.

3. Documentation

  • CHANGELOG.md entry — TODO (draft; user-visible change).
  • [/] Searched issues for a related one — no confident JabRef issue match; kept as a reference to Render entry preview with html-to-node and remove javafx.web #16145, no closes.
  • Requirement added to docs/requirements/ — TODO (draft; new feature).
  • [/] Developer documentation — no architecture change beyond the documented formatter flag.

4. Pull request

  • PR body built from .github/PULL_REQUEST_TEMPLATE.md, every section filled.
  • All checklist items kept and marked.
  • All HTML comments removed from the PR body.
  • PR created with gh pr create --body-file.
  • CHANGELOG.md TODO placeholder replaced with the PR number — no CHANGELOG entry yet (draft).

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

🤖 Generated with Claude Code

Enable html-to-node's math rendering (HtmlRenderOptions#renderMath) in
PreviewViewer so $…$/$$…$$ in fields such as the abstract and comment are
typeset as equations instead of shown as raw TeX.

The default preview layout runs those fields through HTMLChars, whose
LaTeX-command handling would otherwise strip or mangle math delimiters.
A new opt-in HTMLChars(preserveMath) argument lifts $…$ / $$…$$ / \(…\) /
\[…\] spans out before conversion and splices them back verbatim (only
<>& escaped), leaving the shared default behaviour used by exports
untouched. The default preview layout and a preferences migration switch
the abstract to HTMLChars(preserveMath) and the comment to
HTMLChars(keepCurlyBraces,preserveMath).

jlatexmath (pulled in transitively via html-to-node) is registered as a
proper module with its font companion jars merged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Siedlerchr

Copy link
Copy Markdown
Member

Math was already rendered. Only subscribt and superscript were not properly rendered
Fix latex2unicode intead

@Siedlerchr Siedlerchr closed this Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants