LaTeX Real-Time Preview
A VS Code extension that provides fast, approximate real-time preview of LaTeX documents without requiring a TeX installation. It treats LaTeX as structured markup (like Markdown) rather than a full typesetting language, delivering instant visual feedback as you type with sub-100ms latency.
Motivation
Existing LaTeX previewers (e.g., LaTeX Workshop) require a full TeX distribution, take seconds to compile, and break entirely on syntax errors. This extension trades exact layout fidelity for speed, error tolerance, and immediate feedback -- you get a live, readable rendering of your document the moment you start typing.
Features
- Real-time preview -- opens a side panel that updates as you type
- No TeX installation required -- uses a JS-based parser and KaTeX for math
- Error tolerant -- continues rendering even when your LaTeX has syntax errors
- Bidirectional scroll sync -- scroll in the editor or the preview, the other follows
- Double-click to jump -- double-click any element in the preview to jump to its source line (works across files)
- Theming -- light, dark, and sepia backgrounds; configurable font family and size
- Multi-file projects --
\input and \include are resolved and inlined recursively, with file watching for live updates
- Bibliography support -- parses
.bib files and resolves \cite, \citet, \citep to author-year format
- Cross-references --
\label, \ref, \eqref, \autoref, \cref resolved to numbered links
- Custom macros --
\newcommand, \renewcommand, \def, \DeclareMathOperator are expanded
- TikZ diagrams -- rendered asynchronously via node-tikzjax (WASM-based TeX)
- Rich LaTeX support -- sections, math environments, lists, theorems, tables, figures, footnotes, verbatim blocks, and more
Usage
- Open a
.tex file in VS Code
- Press
Ctrl+K V (or Cmd+K V on macOS)
- A preview panel opens to the right and updates in real-time
The toolbar at the top of the preview panel lets you switch themes, adjust font size, change font family, or open the compiled PDF.
Settings
| Setting |
Type |
Default |
Description |
latexPreview.debounceMs |
number |
50 |
Delay (ms) before re-parsing after an edit |
latexPreview.scrollSync |
boolean |
true |
Enable bidirectional scroll sync |
latexPreview.mathRenderer |
string |
"katex" |
Math rendering engine (currently only KaTeX) |
Architecture
User edits .tex file
|
v
[VS Code Extension Host]
onDidChangeTextDocument --> 50ms debounce
|
v
[Parser Layer]
unified-latex parse --> AST
4-pass AST-to-HTML transform:
1. Collect metadata (\title, \author, \date)
2. Collect macro definitions (\newcommand, \def)
3. Collect labels & numbering (\label, section counters)
4. Render document body to HTML
|
v
[Webview Panel]
Receives HTML via postMessage
KaTeX auto-render processes math delimiters
IntersectionObserver for reverse scroll sync
Double-click handler for source jumping
Key Components
| File |
Purpose |
src/extension.ts |
Entry point. Registers the preview command, manages activation. |
src/preview/previewPanel.ts |
Core orchestrator. Manages the webview lifecycle, listens to document changes, triggers parsing, handles TikZ rendering and file watchers. |
src/preview/scrollSync.ts |
Bidirectional scroll sync with feedback loop prevention (150ms suppression). |
src/parser/latexParser.ts |
Thin wrapper around @unified-latex/unified-latex-util-parse. |
src/parser/astToHtml.ts |
Core transformation engine. Walks the unified-latex AST and emits HTML with data-source-line attributes for scroll sync. Handles 100+ LaTeX constructs. |
src/parser/blockCache.ts |
Change detection via source/HTML comparison. Skips webview updates when output is unchanged. |
src/parser/blockSplitter.ts |
Splits documents into logical blocks (paragraphs, environments, sections) for incremental parsing infrastructure. |
src/parser/macroExpander.ts |
Expands \newcommand, \renewcommand, \def with argument substitution and recursion depth limiting. |
src/parser/labelResolver.ts |
Collects \label definitions, tracks section/equation/figure/table/theorem numbering, resolves \ref to numbered links. |
src/parser/bibParser.ts |
Regex-based BibTeX parser. Resolves \bibliography and \addbibresource, extracts author/year/title for citation rendering. |
src/parser/fileResolver.ts |
Resolves \input/\include paths with cycle detection and caching. |
src/parser/tikzRenderer.ts |
Async, queued TikZ-to-SVG rendering via node-tikzjax. Caches by content hash. |
src/webview/preview.js |
Browser-side logic: KaTeX auto-render, scroll sync, DOM updates, toolbar controls, double-click-to-jump. |
src/webview/preview.css |
Theming (light/dark/sepia), typography, and styling for all rendered LaTeX elements. |
LaTeX-to-HTML Mapping
The AST walker maps LaTeX constructs to semantic HTML:
| LaTeX |
HTML |
\section{...} |
<h2> |
\textbf{...} |
<strong> |
\emph{...} |
<em> |
$...$ |
Preserved for KaTeX |
\begin{itemize} |
<ul> with <li> |
\begin{enumerate} |
<ol> with <li> |
\begin{theorem} |
<div class="env-theorem"> with label |
\begin{align} |
Display math block for KaTeX |
\begin{tabular} |
<table> with rows/cells |
\begin{figure} |
<figure> with <figcaption> |
\includegraphics{...} |
<img> (resolved to webview URI) |
\footnote{...} |
Superscript number + text at block bottom |
\href{url}{text} |
<a href="url"> |
\maketitle |
Renders collected title/author/date block |
| Unknown macros |
Content rendered, command name shown in dim gray |
Scroll sync works in both directions with a feedback loop prevention mechanism:
- Editor to preview: listens to
onDidChangeTextEditorVisibleRanges, sends the top visible line to the webview, which finds the closest element with a matching data-source-line attribute and scrolls to it.
- Preview to editor: an
IntersectionObserver in the webview tracks which elements are visible and reports the topmost line back to the extension, which calls editor.revealRange().
- Both directions suppress the reverse direction for 150ms after acting to prevent oscillation.
Tech Stack
- Language: TypeScript (extension), JavaScript (webview)
- LaTeX Parsing: unified-latex -- PEG-based parser producing an AST
- Math Rendering: KaTeX -- fast client-side math rendering via auto-render
- TikZ Rendering: node-tikzjax -- WASM-based minimal TeX for TikZ-to-SVG
- Bundler: esbuild
- Testing: Jest + ts-jest
Building from Source
cd latex-realtime-preview
npm install
npm run build # compile and bundle
npm run watch # watch mode for development
npm run test # run tests
To package as a .vsix:
npx @vscode/vsce package
Limitations
- No exact layout: page breaks, margins, column layouts, and float positioning are not replicated
- Approximate math: KaTeX covers most LaTeX math but not all packages
- TikZ: only packages supported by node-tikzjax will render; complex diagrams may fail
- No PDF output: this is a preview tool, not a compiler (the PDF button opens an existing PDF or runs
pdflatex)
| |