The Quarto Review Extension is a modular system for collaborative document review with in-browser editing capabilities. It follows a single-render model where Quarto renders once and all subsequent edits happen in-memory via JavaScript.
┌─────────────────────────────────────────────────────────────┐
│ Quarto Document │
│ (.qmd file) │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌────────────────┐
│ Lua Filter │
│ (review.lua) │◄─── Deterministic ID Generation
└────────┬───────┘
│
▼
┌────────────────┐
│ HTML Output │
│ (with data- │
│ review-id) │
└────────┬───────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Browser Load │ │ Extension JS │
│ │────────►│ (review.js) │
└─────────────────┘ └────────┬─────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ UI Module │ │ Changes Module │
│ (Stateless) │◄────────────────►│ (State Mgmt) │
└────────┬────────┘ └────────┬─────────┘
│ │
┌───────────┼───────────┐ │
▼ ▼ ▼ │
┌─────────┐ ┌──────────┐ ┌────────┐ │
│Markdown │ │Comments │ │User │ │
│Module │ │Module │ │Module │ │
└─────────┘ └──────────┘ └────────┘ │
▼
┌──────────────────┐
│ Git Module │
│ (Persistence) │
└────────┬─────────┘
│
┌───────────────────────┼───────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ GitHub │ │ GitLab │ │ Local │
│ Provider │ │ Provider │ ... │ Provider │
└──────────┘ └──────────┘ └──────────┘
src/modules/changes/)Purpose: Core state management for document edits
Key Concepts:
Data Flow:
Original Elements + Operations → Current State → Markdown
Operations:
interface Operation {
id: string;
type: 'insert' | 'delete' | 'edit' | 'move';
elementId: string;
timestamp: number;
data: OperationData;
}
src/modules/markdown/)Purpose: Bidirectional markdown ↔ HTML conversion
Features:
markdown-it for renderingsrc/modules/comments/)Purpose: CriticMarkup parsing and rendering
CriticMarkup Syntax:
{++addition++}
{--deletion--}
{~~old~>new~~}
{>>comment<<}
{==highlight==}{>>note<<}
Features:
src/modules/git/)Purpose: Version control and persistence
Architecture:
GitModule (core)
│
├─► isomorphic-git (git operations)
│
└─► Providers (API integrations)
├─► GitHub
├─► GitLab
├─► Gitea/Forgejo
└─► Local
Save Flow:
Changes → .qmd → Git Commit → (Optional) Push to Remote
src/modules/user/)Purpose: Authentication and authorization
Roles:
Features:
src/modules/ui/)Purpose: Stateless rendering and interaction orchestration
Key Design: UI is a view layer only - no state (state managed by StateStore)
Architecture (Refactored 2025): The UI Module has been refactored from a monolithic class into a modular orchestration layer with specialized components:
Core Components:
UI Features:
Event Flow:
User Click → UI.openEditor() → EditorManager → Show Modal/Drawer
User Edit → No State Change (just display)
User Save → EditorManager.save() → Changes.edit() → StateStore.emit() → UIStateManager → UI.refresh()
Testing:
_extensions/review/review.lua)Purpose: Deterministic element ID generation
ID Generation Strategy:
-- Example IDs:
"review.para-1"
"review.sec-intro.para-1"
"review.sec-intro.sec-background.header-1"
Structure:
[prefix].[section-path].[element-type]-[counter]
Benefits:
Debug Output:
The Lua filter includes conditional debug logging via the debug_print() function, which outputs to the Quarto render log only when review.debug: true in YAML. This includes:
DEBUG_MODE_SETUP.md for configuration details1. Quarto Render
.qmd → Lua Filter → HTML (with data-review-id)
2. User Opens Page
HTML → Browser → JS Init → Changes.initializeFromDOM()
3. User Clicks Element
Element → UI.openEditor(id) → Show Modal
4. User Edits Content
Textarea → Live Preview (Markdown.render + Comments.renderToHTML)
5. User Saves
Modal → Changes.edit(id, content) → UI.refresh()
6. User Saves to Git
Changes.toMarkdown() → Git.save() → Git Commit
<!-- document_en.qmd -->
# Introduction {#sec-intro}
First paragraph {#para-1}
<!-- document_fr.qmd -->
# Introduction {#sec-intro}
Premier paragraphe {#para-1}
Mapping: Explicit IDs ensure 1:1 correspondence between languages.
# Install dependencies
npm install
# Development mode (watch)
npm run dev
# Run tests
npm test
npm run test:e2e
# Lint and format
npm run lint
npm run format
# Build for production
npm run build
# Render example
cd example
quarto render
quarto-review-extension/
├── src/
│ ├── modules/
│ │ ├── changes/ # State management
│ │ ├── markdown/ # MD ↔ HTML
│ │ ├── comments/ # CriticMarkup
│ │ ├── git/ # Version control
│ │ │ └── providers/ # Git providers
│ │ ├── user/ # Auth/permissions
│ │ └── ui/ # Rendering
│ ├── types/ # TypeScript types
│ └── main.ts # Entry point
├── _extensions/review/
│ ├── review.lua # Lua filter
│ ├── _extension.yml # Config
│ └── assets/ # CSS/JS
├── tests/
│ ├── unit/ # Vitest tests
│ └── e2e/ # Playwright tests
├── example/ # Demo project
└── .github/workflows/ # CI/CD
This extension follows:
MIT