Feature Discussion: Live Preview with Forward/Inverse Search and Document Outline
Summary
This discussion presents a prototype implementation of LaTeX Workshop-style live preview and source navigation features for the pretext-tools VS Code extension. The motivation for this work arose from porting an academic research paper from LaTeX to PreTeXt, during which the absence of in-editor preview and source-preview synchronization became apparent. The features described below are intended to complement the existing functionality in pretext-tools without modifying any current behavior.
This post is a request for feedback on whether these features align with the project's direction, and whether the implementation approach is suitable for potential upstream integration. All code is available for review in a working fork.
Working fork: https://github.com/saustinp/pretext-tools
Features Implemented
1. Live Side-by-Side Preview
A new command (Ctrl+Alt+L / Cmd+Alt+L) opens the compiled HTML/PDF/EPUB/Braille output in a VS Code WebviewPanel adjacent to the source editor.
HTML Live Preview

PDF Live Preview

Toolbar provides Refresh and Open in Browser controls:

Implementation details:
- The extension invokes
pretext view --no-launch to start the local preview server without opening an external browser
- The output is displayed within an embedded iframe in a VS Code panel
- A toolbar provides Refresh and Open in Browser controls
- Server lifecycle management includes
--restart-server on startup and --stop-server on panel close to prevent orphaned processes
- If no compiled output exists, the extension automatically runs
pretext build <target> before starting the server, with build progress reported in the PreTeXt output channel
- The build process is tolerant of partial failures (e.g., missing optional tools such as Sage); if HTML files are generated despite non-zero exit codes, the preview proceeds
2. Auto-Rebuild on Save
When the live preview is active, saving any .ptx or .xml file triggers an automatic rebuild followed by a preview refresh.
- This behavior is configurable via the
pretext-tools.livePreview.autoCompile setting (default: enabled)
- A one-second debounce prevents redundant builds during rapid successive saves
- Build status is reflected in the VS Code status bar
3. Inverse Search (Preview to Source)
Clicking on any element in the HTML preview navigates the editor to the corresponding location in the source file.
Hovering over an element turns the bounding box blue:

Clicking anywhere inside the bounding box turns the border orange and triggers the inverse search functionality:

Implementation:
- A JavaScript snippet is injected into the built HTML files (appended before
</body>) that attaches click and hover handlers to all elements with id attributes
- Hovering displays a blue outline to indicate clickable regions
- Clicking transmits the element's
id to the extension via window.parent.postMessage (cross-origin compatible)
- The extension resolves the HTML element ID to a source location through a series of strategies applied in order:
- Direct ID match against
xml:id and label attributes
- Suffix stripping to handle PreTeXt's auto-generated child element IDs (e.g.,
section-foo-3-1 is progressively reduced to section-foo-3, section-foo)
- Prefix stripping to accommodate
label attributes that prepend structural prefixes (e.g., section-) to the xml:id
- Text-based refinement within the matched block, using distinctive words extracted from the clicked paragraph to locate the exact source line
- Pure text fallback for deeply auto-generated IDs with no source counterpart, searching the entire file by content
Edge cases addressed:
- Chunked HTML output where each section resides in a separate file
- Deeply nested structures such as corollaries, proofs, and objectives
- Elements whose
label attribute differs from their xml:id
- Paragraphs within list items
- Both
.ptx and .xml source file extensions
4. Forward Search (Source to Preview)
Pressing Ctrl+Alt+J / Cmd+Alt+J scrolls the preview to the location corresponding to the editor cursor.
Implementation:
- Approximately 300 characters of plain text following the cursor position are extracted (with XML tags removed)
- Distinctive words (five or more characters) are identified
- All HTML output files are searched for a matching word sequence
- The nearest preceding HTML element with an
id attribute is identified
- The preview navigates to the appropriate HTML page (supporting chunked output) and scrolls to the identified element
Text-based matching was selected over paragraph counting because PreTeXt's HTML ID numbering scheme is structurally complex and varies with nesting depth and element type. Text matching provides more reliable results across diverse document structures.
5. Document Outline
A PreTeXt icon is added to the VS Code Activity Bar, providing a hierarchical document structure view in the sidebar.
Displayed elements:
- Article and Book root elements
- Chapters, Sections, Subsections, and Subsubsections
- Front Matter, Back Matter, and Appendices
- References
- Named
<paragraphs> blocks (e.g., Acknowledgments)
Excluded elements (to maintain clarity):
- Figures, tables, and equations
- Untitled paragraphs
- Non-structural elements
Behavior:
- Each item is clickable and navigates to the corresponding source line
- The outline updates automatically on document edits and file switches
- A refresh control is available in the panel header
- Both
.ptx and .xml files are supported
6. Multi-Format Live View
The live preview command supports all PreTeXt output targets:
| Target |
Behavior |
| HTML |
Embedded WebviewPanel with forward/inverse search |
| PDF |
Opened in VS Code's PDF viewer (requires an extension such as vscode-pdf) |
| Braille |
Opened as a .brf text file in the VS Code editor |
| EPUB |
Opened in VS Code if an EPUB reader extension is detected; otherwise opened with the system default application |
All targets automatically build if the output file does not yet exist, with progress displayed in the output channel.
7. Integration with Existing View Methods
"Live Preview (side-by-side)" is added as an option in both the Ctrl+Alt+V quick-pick dialog and the pretext-tools.viewMethod configuration dropdown, alongside the existing "Use PreTeXt's view command" and "Use CodeChat" options.
Scope of Changes
These features are entirely additive. No existing functionality has been modified:
- All existing commands, keybindings, snippets, and schema validation remain unchanged
- The Visual Editor and LSP server are unaffected
- The existing external browser view (
Ctrl+Alt+V) continues to function as before
- No new npm dependencies have been introduced; all features use VS Code's built-in APIs and the existing
child_process patterns in the codebase
Technical Summary
Files added:
packages/vscode-extension/src/livePreview.ts (~1100 lines)
packages/vscode-extension/src/documentOutline.ts (~400 lines)
Files modified:
packages/vscode-extension/src/extension.ts — Command registration (+8 lines)
packages/vscode-extension/src/commands/view.ts — "Live Preview" added to view method picker
packages/vscode-extension/package.json — Commands, keybindings, view container, and configuration additions
packages/format/index.js — Corrected a broken symlink that prevented building from source
New keybindings:
| Keybinding |
Command |
Ctrl+Alt+L / Cmd+Alt+L |
Open Live Preview |
Ctrl+Alt+J / Cmd+Alt+J |
Forward Search |
New configuration options:
pretext-tools.livePreview.autoCompile (boolean, default: true)
"Live Preview" added to the pretext-tools.viewMethod enumeration
Testing
The implementation has been tested with the following configurations:
- Custom article (single-page, AIAA conference paper format): All features functional
- PreTeXt sample-article (283 pages, chunked HTML, complex structure including proofs, corollaries, objectives, and reading questions): Forward search, inverse search, and document outline all functional; auto-build handles partial failures gracefully
- EPUB viewer: Tested with the epub-reader-vscode extension
- PDF viewer: Tested with the vscode-pdf extension
- Platform: Linux (Ubuntu 24.04), VS Code, Node.js 22
Known Limitations
- Forward/inverse search is HTML-only. Source-to-preview and preview-to-source navigation is available only for the HTML live preview. PDF, braille, and EPUB targets open as static files without navigation capabilities.
- Forward search precision. The search typically resolves to the paragraph level but may fall back to the enclosing section for very short paragraphs or elements with few distinctive prose words.
- Math-heavy paragraphs. Forward search may default to section-level navigation for paragraphs consisting primarily of mathematical content, since LaTeX expressions in the source do not correspond to the rendered text in HTML. Inverse search remains functional for these paragraphs.
- Knowl popups. Inverse search does not operate within dynamically generated knowl popups (expandable cross-reference boxes). The knowl's built-in navigation link provides an alternative path to the referenced element.
- Multi-page HTML navigation. When the HTML output is split across multiple pages (chunking level 1 or higher), forward search to a different page requires a full page reload rather than an in-page scroll.
Questions for Discussion
- Feature alignment. Does this direction complement the project's existing roadmap? Given that CodeChat integration already provides some preview capability, would a built-in alternative be welcome?
- Architecture. The live preview implementation resides in a single ~1100-line module. Would the maintainers prefer this decomposed into smaller, focused modules?
- Script injection. The inverse search mechanism injects a
<script> tag into the built HTML files. Is this approach acceptable, or would an alternative mechanism be preferred?
- Document outline scope. The outline currently displays only section-level headings. Would it be desirable to include figures, tables, and theorem-like environments, perhaps behind a configuration toggle?
Feedback and suggestions are welcome. Thank you for the excellent work on this project.
Feature Discussion: Live Preview with Forward/Inverse Search and Document Outline
Summary
This discussion presents a prototype implementation of LaTeX Workshop-style live preview and source navigation features for the pretext-tools VS Code extension. The motivation for this work arose from porting an academic research paper from LaTeX to PreTeXt, during which the absence of in-editor preview and source-preview synchronization became apparent. The features described below are intended to complement the existing functionality in pretext-tools without modifying any current behavior.
This post is a request for feedback on whether these features align with the project's direction, and whether the implementation approach is suitable for potential upstream integration. All code is available for review in a working fork.
Working fork: https://github.com/saustinp/pretext-tools
Features Implemented
1. Live Side-by-Side Preview
A new command (
Ctrl+Alt+L/Cmd+Alt+L) opens the compiled HTML/PDF/EPUB/Braille output in a VS Code WebviewPanel adjacent to the source editor.HTML Live Preview

PDF Live Preview

Toolbar provides Refresh and Open in Browser controls:

Implementation details:
pretext view --no-launchto start the local preview server without opening an external browser--restart-serveron startup and--stop-serveron panel close to prevent orphaned processespretext build <target>before starting the server, with build progress reported in the PreTeXt output channel2. Auto-Rebuild on Save
When the live preview is active, saving any
.ptxor.xmlfile triggers an automatic rebuild followed by a preview refresh.pretext-tools.livePreview.autoCompilesetting (default: enabled)3. Inverse Search (Preview to Source)
Clicking on any element in the HTML preview navigates the editor to the corresponding location in the source file.
Hovering over an element turns the bounding box blue:

Clicking anywhere inside the bounding box turns the border orange and triggers the inverse search functionality:

Implementation:
</body>) that attaches click and hover handlers to all elements withidattributesidto the extension viawindow.parent.postMessage(cross-origin compatible)xml:idandlabelattributessection-foo-3-1is progressively reduced tosection-foo-3,section-foo)labelattributes that prepend structural prefixes (e.g.,section-) to thexml:idEdge cases addressed:
labelattribute differs from theirxml:id.ptxand.xmlsource file extensions4. Forward Search (Source to Preview)
Pressing
Ctrl+Alt+J/Cmd+Alt+Jscrolls the preview to the location corresponding to the editor cursor.Implementation:
idattribute is identifiedText-based matching was selected over paragraph counting because PreTeXt's HTML ID numbering scheme is structurally complex and varies with nesting depth and element type. Text matching provides more reliable results across diverse document structures.
5. Document Outline
A PreTeXt icon is added to the VS Code Activity Bar, providing a hierarchical document structure view in the sidebar.
Displayed elements:
<paragraphs>blocks (e.g., Acknowledgments)Excluded elements (to maintain clarity):
Behavior:
.ptxand.xmlfiles are supported6. Multi-Format Live View
The live preview command supports all PreTeXt output targets:
vscode-pdf).brftext file in the VS Code editorAll targets automatically build if the output file does not yet exist, with progress displayed in the output channel.
7. Integration with Existing View Methods
"Live Preview (side-by-side)" is added as an option in both the
Ctrl+Alt+Vquick-pick dialog and thepretext-tools.viewMethodconfiguration dropdown, alongside the existing "Use PreTeXt's view command" and "Use CodeChat" options.Scope of Changes
These features are entirely additive. No existing functionality has been modified:
Ctrl+Alt+V) continues to function as beforechild_processpatterns in the codebaseTechnical Summary
Files added:
packages/vscode-extension/src/livePreview.ts(~1100 lines)packages/vscode-extension/src/documentOutline.ts(~400 lines)Files modified:
packages/vscode-extension/src/extension.ts— Command registration (+8 lines)packages/vscode-extension/src/commands/view.ts— "Live Preview" added to view method pickerpackages/vscode-extension/package.json— Commands, keybindings, view container, and configuration additionspackages/format/index.js— Corrected a broken symlink that prevented building from sourceNew keybindings:
Ctrl+Alt+L/Cmd+Alt+LCtrl+Alt+J/Cmd+Alt+JNew configuration options:
pretext-tools.livePreview.autoCompile(boolean, default:true)"Live Preview"added to thepretext-tools.viewMethodenumerationTesting
The implementation has been tested with the following configurations:
Known Limitations
Questions for Discussion
<script>tag into the built HTML files. Is this approach acceptable, or would an alternative mechanism be preferred?Feedback and suggestions are welcome. Thank you for the excellent work on this project.