Skip to content

Notation Prettifier 1.0.7

Choose a tag to compare

@zoroaster1x zoroaster1x released this 27 Sep 11:22
· 8 commits to main since this release

Notation Prettifier 1.0.7

Type rough math notation in Obsidian and read it back as real math. L^' = L + F becomes $L' = L + F$, n^(i) = n^(')i^(') becomes $n^{i} = n'i'$, sqrt r^2-y^2 becomes $\sqrt{r^{2}-y^{2}}$, and 5<degrees> becomes 5°. It works while you type in Live Preview, in Reading view, and on command it bakes the LaTeX into the note.

It also carries the whole arrow and sign map of Symbols Prettifier (-> to →, <= to ⇐, -- to –), so it replaces that plugin.

Everything runs offline. No API key, no model, no network request, no telemetry. The rules are regular expressions you can read, test and extend in the settings tab.

Install

  1. Download main.js, manifest.json, styles.css and versions.json from the assets below.
  2. Put them in <Vault>/.obsidian/plugins/notation-prettifier/.
  3. In Obsidian: Settings, Community plugins, turn Restricted mode off, reload the installed plugins, enable Notation Prettifier.
  4. If Symbols Prettifier is enabled, turn it off: this plugin already carries its shortcuts.

Requires Obsidian 1.5.0 or newer. Desktop and mobile.

Commands

Command What it does
Convert notation in the selection or line to LaTeX Converts the selection, or the current line when there is no selection. Inline $...$.
Convert notation in the whole note to LaTeX Converts every line. A line that is exactly one formula becomes $$...$$.
Preview the whole note conversion A modal with the converted note and Apply and Cancel. Nothing is written until Apply.
Check the current line (diagnostics) Reports the spans, their LaTeX, shortcut matches, the editor mode, the cursor state and the math render state.
Write a debug report to the plugin folder Writes debug-report.json with the plugin version, MathJax state, stylesheet state and the real DOM of a rendered formula.
Toggle live preview Turns live rendering on or off.

All conversion commands are a single undo step.

What it converts

  • Primes, superscripts and subscripts: L^' to L', n^(') to n', n^(i) to n^{i}, x^(n-1), x^2, 10^1.204, x_1, i_2^', L_next, F_{LM}, curly primes, and unicode scripts such as 10⁸ and CO₂.
  • Greek letter names: theta, Delta, lambda and the rest, inside formulas only.
  • Operators: ->, <-, <->, <=>, =>, <=, =<, >=, !=, +-, -+, and the unicode forms of ≤ ≥ ≠ ≡ ± ∓, ×, ÷, ·, −, %.
  • Functions and roots: sin(, cos(, tan(, log( and the rest to \sin(; sqrt(...) to \sqrt{...}; sqrt r^2-y^2 to \sqrt{r^{2}-y^{2}}; tan θ to \tan θ.
  • Units after a number: 1.6mm to 1.6\,\text{mm}, +5.00DS, −2.00DC, 3.50 D, 40 mg/mm^2, 30c/deg, 20 °C.
  • x as multiplication: 25^2x6.5, (1/25^2)x1000, 120x10^-3, (20^2x-8.5), F_LMx((n'-1)/0.523).
  • Text shortcuts, everywhere, also outside formulas: -> to →, <-> to ↔, <= to ⇐, >= to ≥, -- to –, +- to ±, and the degree forms <deg>, <degrees>, [deg], [degrees] to °.

A run of notation becomes a formula only when it earns it: it needs a relation (=, an arrow, a comparison with an operand on both sides) or a prime or script on a symbol-like base. Ordinary words never start a span, which is why Course_AT_12_Topic_SS.pptx, AB_12CD_34, 98-99%, <40, 40 mg/mm^2 and endothelium→TM stay exactly as typed.

Protected regions are never touched: YAML frontmatter, fenced and inline code, existing $...$ and $$...$$ math, wikilinks and embeds, markdown links, bare URLs, footnote references, thematic break lines, setext === lines and markdown table separator rows.

Settings

  • Live preview, Reading view, display math for a single-formula line.
  • Rewrite angle bracket shortcuts as you type, so <deg> becomes ° before Markdown can read it as an HTML tag.
  • Group toggles: text shortcuts, functions and roots, x multiply, scripts, Greek names, operators, units.
  • Text shortcut list: one literal => replacement per line.
  • Custom formula rules: one regex => replacement per line, applied after the built-in groups, with a validation hint.
  • Try it box with a live render and the exact baked source.
  • Built-in rule reference listing every pattern.
  • Restore defaults.

Performance

The live layer tokenizes only a 1,500 character window around the viewport, caches the scan for an open code fence or $$ block until an edit touches that part, skips pure prose with one character check, and memoises converted spans. Baking a note over 200,000 characters runs in chunks and yields to the UI with a progress notice.

Measured on a synthetic 1,000,000 character note: 0.37 ms warm keystroke, 1.3 ms cold prefix scan, 238 ms full bake, 152 ms chunked bake. A 5,000,000 character note bakes in 773 ms. No WebAssembly and no worker threads, on purpose: this is regex text work, and CodeMirror decorations must be produced synchronously.

Testing

  • Engine 77 checks, live window scanner 13, documented examples 45, bundle 57, privacy 0 violations.
  • Corpus over 225 real notes (23,860 lines, read only): 0 failures, 607 formulas wrapped, 3,317 protected regions preserved, 300 lines rendered through the reading view.
  • test/bench.mjs reports timings and fails only on generous bounds.

Fixed in 1.0.7

This release fixes a chain of rendering faults found against real notes:

  • Invisible formulas. Obsidian loads MathJax lazily and attaches its CHTML glyph stylesheet only when its own math renders; renderMath alone returns containers that draw nothing. The plugin now warms the app renderer, attaches the stylesheet directly, and refuses to draw a container without it, so you see raw text at worst, never an invisible box.
  • A typed letter looked invisible. The widget's size arrived asynchronously from MathJax CSS and fonts, and CodeMirror had already measured it. The widget now asks the editor to measure again on layout, the next frame, at 60 and 300 ms, and when fonts are ready.
  • A cursor at the span edge kept the formula raw. Only a cursor strictly inside shows raw text now.
  • Spaces did not end a formula. Whitespace was skipped when tokenizing, so a single letter after any number of spaces welded onto the formula while a two letter word broke it. A spaced single letter now ends a script-qualified formula (n^2 x), while relations keep their spaced operands (L = L + F, cos θ = 0.5, F = 2.50 D).
  • Angle bracket shortcuts broke markdown. <deg> at the start of a line is an HTML block to Markdown and swallowed the lines below. The plugin now rewrites those shortcuts as you type (setting, on by default), ships [deg] forms, and unwraps an existing tag element in Reading view.
  • Possessives were primes. Y2's, 2's and don't are prose now; i_1' still converts.

Privacy

No telemetry and no network. The only file the plugin writes on its own is its settings. The test suite that reads real notes is read only, and a privacy guard scans tracked files for home paths, emails, hostnames and any patterns you add locally.

License

GPL-3.0-or-later. Copyright (C) 2026 Zoroaster1x. The arrow and sign shortcut map follows Symbols Prettifier by Florian Woelki (MIT).

Funding

If this plugin saves you time, consider supporting its development.

Monero (XMR):

8BdxmQSniku4dBJXWPXeXvgjztmj5nmvWQqeCrVvCtYciusbAyo4rqrGCefTfQ4gGaVZmLN7VgLiYUYyBdYFEwHn1UWPjWs

Tip: You can easily purchase Litecoin using Cake Wallet and then, within the app, create a Monero wallet and exchange the Litecoin into it, pointed at the address above.

Crypto isn't your thing? Starring the repository, filing clear bug reports with a sample line of notation, and telling other Obsidian users about the plugin all help just as much.