Skip to content

Two rendering bugs: digit before \; , and digit inside a braced subscript _{...} #86

Description

@HeinzMattes

Environment

  • LaTeXSwiftUI: main branch, commit cc677f66b9cc1751e09207621d62d1cda0200675 (just after the v2.0.0 tag)
  • MathJaxSwift: 3.5.0 (00e9c3df6b1c82031c7fe3785028f3d21c0d73ba)
  • SwiftDraw: 0.29.0 (82699f4bdf2f075793cfa0d392eb27c59b41a3fe)
  • swift-html-entities: 4.0.1
  • Xcode / iOS Simulator, Swift 6

Summary

Two distinct, minimal, reliably reproducible cases where a LaTeX(text) view falls back to
displaying the raw source (.errorMode(.original)) instead of rendering the formula, even though
the input is valid TeX/LaTeX.

Important diagnostic detail: in both cases, calling MathJaxSwift's tex2svg(...) directly on
the exact same (stripped) content succeeds and produces a valid, non-empty SVG, and feeding that
SVG into SwiftDraw.SVG(data:) directly also succeeds. The failure only appears when going through
the full LaTeXSwiftUI LaTeX(text) rendering path (tested both in a real app and in a minimal
one-view isolated test target), so the bug does not appear to be reachable from MathJaxSwift or
SwiftDraw in isolation -- it seems to be specific to how LaTeXSwiftUI drives them.


Bug 1: a digit immediately followed by \; (no separator) is not recognized as a spacing command

\; is a TeX control symbol (backslash + exactly one non-letter character), and per the TeX
grammar it should be recognized regardless of what precedes it -- unlike control words (e.g.
\alpha), which need a following space to terminate but are not affected by a preceding
character either. So 3\;x is valid, unambiguous LaTeX.

Minimal repro:

struct ContentView: View {
    // FAILS: shows literal "3\;" as text instead of the expected thin space
    let broken = "\\[ a(3\\; x) \\]"

    // WORKS: adding a space before \; fixes it
    let fixed = "\\[ a(3 \\; x) \\]"

    var body: some View {
        List {
            LaTeX(broken)
            LaTeX(fixed)
        }
    }
}

Observed:

  • a(3\; x) -> the standalone \; characters are shown as literal text inline with the rendered formula.
  • a(3 \; x) -> renders correctly, \; produces the expected small space.

Workaround we're using: insert a space between a digit and a following \; in a preprocessing
pass before handing text to LaTeX(...).


Bug 2: a braced subscript _{...} that contains a digit fails to render at all

Minimal repro:

struct ContentView: View {
    let case1 = "\\[ { E_{1} } \\]"        // FAILS
    let case2 = "\\[ { E_1 } \\]"          // OK (bare, no braces)
    let case3 = "\\[ { E_{Q1} } \\]"       // FAILS
    let case4 = "\\[ { E_{01} } \\]"       // FAILS
    let case5 = "\\[ { E_{p} } \\]"        // OK (braced, but letters only)
    let case6 = "\\[ { E_{\\mathrm{Q1}} } \\]"  // OK (workaround)
    let case7 = "\\[ { E_{\\text{Q1}} } \\]"    // OK (workaround)
    let case8 = "\\[ { E_{Q{1}} } \\]"     // still FAILS (nesting braces around just the digit does not help)

    var body: some View {
        List {
            LaTeX(case1); LaTeX(case2); LaTeX(case3); LaTeX(case4)
            LaTeX(case5); LaTeX(case6); LaTeX(case7); LaTeX(case8)
        }
    }
}

Observed pattern:

  • E_1 (bare, no braces) -> renders correctly
  • E_{p} (braced, letters only) -> renders correctly
  • E_{1} (braced, digit) -> FAILS, raw source shown
  • E_{Q1} (braced, letter+digit) -> FAILS
  • E_{01} (braced, digits) -> FAILS
  • E_{Q{1}} (digit nested in an inner brace) -> FAILS
  • E_{\mathrm{Q1}} -> renders correctly
  • E_{\text{Q1}} -> renders correctly

So: a braced subscript group fails to render as soon as it contains a digit anywhere in it --
unless that digit is inside a \mathrm{...} or \text{...} wrapper, in which case it renders
correctly (and arguably more correctly typeset, upright rather than italic, for label-like
subscripts).

This is a real-world, frequently-occurring case in scientific/engineering notation -- subscripts
like _{01}, _{Q1}, _{Q2} (naming points, charges, etc.) are extremely common, and this bug
makes every single one of them fail to render.

Workaround we're using: in a preprocessing pass, detect every _{...} group whose content
contains at least one digit and wrap the content in \mathrm{...}, e.g. _{Q1} -> _{\mathrm{Q1}}.
Groups that are purely alphabetic (e.g. _{p}) are left untouched since they already render
correctly.


Notes

  • Both bugs were found via real content in a German electrical-engineering textbook app (many
    formulas use vector notation with \; for spacing, and multi-character subscripts like _{01}
    to label points/charges), so they are not obscure/contrived edge cases -- they affect very
    ordinary, common LaTeX usage.
  • Happy to provide more detail, a fuller reproduction project, or test a patch if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions