From 23851662133deff867786ef173137967437246df Mon Sep 17 00:00:00 2001 From: claude Date: Wed, 3 Jun 2026 10:31:49 +0000 Subject: [PATCH] Dashboard footer fix, larger version text, rewrite README - Fix the projects dashboard footer needing a scroll to reach: the main area used min-height: 100% which always pushed the footer a full screen down. Lay the content out as a flex column with main growing (flex: 1 0 auto), so the footer sticks to the bottom of the viewport when the list is short. - Bump the instance-name/version text to ~33px ('7.5', between font-size-07 and -08). - Rewrite README to match the current triple-compiler product (Quarto + LaTeX + Typst), the editor language support, format badge, publishing flow and Python venv option; drop the stale 'Quarto-only / TeX Live removed' notes. Co-Authored-By: Claude Opus 4.8 --- README.md | 182 ++++++++++++------ .../frontend/stylesheets/components/nav.scss | 5 +- .../pages/project-list-ds-nav.scss | 9 +- 3 files changed, 131 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 3fa9ed33fb..b46d2a496b 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,72 @@ # Verso -**A collaborative real-time editor for Quarto and LaTeX presentations and documents.** +**A collaborative, real-time editor for Quarto, LaTeX and Typst — documents and presentations.** -Verso is a fork of [Overleaf](https://github.com/overleaf/overleaf) that adds first-class [Quarto](https://quarto.org) support alongside Overleaf's existing LaTeX toolchain. It keeps Overleaf's real-time collaboration infrastructure and runs **three compilers side by side**, chosen automatically from the root file's extension: `.qmd` builds with Quarto (PDF via Typst, or HTML via RevealJS), `.tex` with `latexmk`/TeX Live, and `.typ` straight through [Typst](https://typst.app). All three coexist on one server. +Verso is a fork of [Overleaf](https://github.com/overleaf/overleaf) that adds +first-class [Quarto](https://quarto.org) and [Typst](https://typst.app) support +alongside Overleaf's LaTeX toolchain. It keeps Overleaf's real-time +collaboration infrastructure and runs **three compilers side by side**, chosen +automatically from the root file's extension: + +| Root file | Compiler | Typical output | +|-----------|----------|----------------| +| `.qmd` | Quarto | PDF (via Typst or LaTeX), or an HTML/RevealJS deck | +| `.tex` | `latexmk` / TeX Live | PDF | +| `.typ` | Typst | PDF | + +All three coexist on one server; no per-project configuration is required to +pick the engine. --- ## Features -- **Real-time collaboration** — multiple users editing the same `.qmd` file simultaneously, powered by Overleaf's operational-transformation engine -- **Three compilers** — `.qmd` builds with Quarto, `.tex` with `latexmk`/TeX Live, and `.typ` with Typst. The runner is chosen by the root file's extension, so Quarto, LaTeX and Typst projects live side by side -- **Two output formats** — set `format: typst` in the YAML frontmatter for a PDF preview, or `format: revealjs` for an interactive HTML presentation rendered in an iframe -- **Document outline** — headings (`#`, `##`, `###`) are extracted and shown in the sidebar outline panel -- **Math, code, tables** — standard Quarto/Pandoc Markdown features all work -- **Auto-compile** — the preview refreshes automatically 2.5 s after you stop typing -- **Project history** — full change history inherited from Overleaf +- **Real-time collaboration** — multiple people editing the same file at once, + powered by Overleaf's operational-transformation engine, with live cursors + and full project history. +- **Three compilers, auto-dispatched** — Quarto, LaTeX and Typst projects live + side by side; the runner is selected from the root file's extension. +- **Language-aware editor for all three**: + - *LaTeX* — syntax highlighting, command/environment/reference autocomplete, + linting (inherited from Overleaf). + - *Quarto (`.qmd`)* — Markdown highlighting plus Quarto-aware completions: + code chunks (```` ```{python} ````, `{r}`, `{julia}`, `{ojs}`…), callouts + and fenced divs (`::: {.callout-note}`, columns, tabsets) and + cross-references (`@fig-`, `@tbl-`, `@sec-`, `@eq-`). + - *Typst (`.typ`)* — syntax highlighting and completions for the common + functions and markup (`#import`, `#let`, `#set`, `#show`, `#figure`, + `#table`, `#cite`, …). +- **Document outline** — section headings are extracted into the sidebar + outline panel for LaTeX, Quarto (`#`, `##`, …) and Typst (`=`, `==`, …). +- **Format at a glance** — the project dashboard shows a per-project format + badge (Quarto / Typst / LaTeX), and the compiler dropdown greys out engines + that don't apply to the current root file. +- **Publish & share compiled output** — publish the compiled result as a + standalone page at `/p/:token`, with three independent access tiers (project + members / any logged-in user / public). Works for both HTML/RevealJS decks + (served live) and PDFs (embedded inline). HTML decks also get a one-click + **Present** button in the toolbar. +- **Quarto Python cells** — optional per-project virtual environment built from + the project's `requirements.txt`, so Python code chunks run during render + (gated to the project owner and invited collaborators). +- **Auto-compile** — the preview refreshes automatically shortly after you stop + typing. ## Output formats -In the YAML frontmatter of your `.qmd` file: +In the YAML frontmatter of a `.qmd` file: ```yaml -format: typst # → PDF preview via Typst (no LaTeX required) -format: revealjs # → HTML slideshow preview +format: typst # → PDF preview, rendered via Typst (no LaTeX required) +format: pdf # → PDF preview, rendered via LaTeX +format: revealjs # → interactive HTML slideshow preview +format: html # → a static HTML page ``` -Typst is bundled with Quarto — no separate installation is needed. +Typst ships inside Quarto, so `format: typst` needs no separate installation. + +> **Note on display math**: keep `$$ … $$` blocks on a single line. Multi-line +> display-math blocks can trigger YAML parse errors in some Quarto versions. ## Quick start @@ -39,12 +80,13 @@ docker run -d \ registry.alocoq.fr/verso:latest ``` -Then open `http://localhost` in your browser. On first run, visit `/launchpad` to create an admin account. +Open `http://localhost` in your browser, then visit `/launchpad` on first run to +create the admin account. ### Build from source ```bash -# Build the base image (installs Quarto + TeX Live) +# Build the base image (system deps + Quarto + TeX Live) cd server-ce make build-base @@ -52,42 +94,40 @@ make build-base make build-community ``` -The two Dockerfiles are: - | File | Purpose | |------|---------| -| `server-ce/Dockerfile-base` | Base OS image — installs system deps, Quarto, and a TeX Live (`latexmk`) toolchain | -| `server-ce/Dockerfile` | Application image — installs Node services, compiles frontend | +| `server-ce/Dockerfile-base` | Base OS image — system deps, Quarto (with Typst) and a TeX Live (`latexmk`) toolchain | +| `server-ce/Dockerfile` | Application image — Node services and the compiled frontend | ## Architecture -Verso is a microservices monorepo (Yarn workspaces). All services run inside a single container managed by `runit`, with `nginx` as the front router. +Verso is a microservices monorepo (Yarn workspaces). All services run inside a +single container managed by `runit`, with `nginx` as the front router. ``` browser ──→ nginx:80 - ├── / ──────────────────→ web:4000 (main app, React UI) - ├── /socket.io ──────────→ real-time:3026 (WebSocket, OT engine) - └── /project/*/output/* → clsi-nginx:8080 (compiled output files) + ├── / ──────────────────→ web:4000 (main app, React UI) + ├── /socket.io ──────────→ real-time:3026 (WebSocket, OT engine) + ├── /p/:token ───────────→ web (published output) + └── /project/*/output/* → clsi-nginx:8080 (compiled output files) web → document-updater → Redis pub/sub → real-time → browser web → CLSI (quarto render / latexmk / typst) → output files → nginx → browser ``` -Key services: - | Service | Role | |---------|------| -| `web` | HTTP API, React frontend, auth, project management | -| `real-time` | WebSocket layer, live cursor and edit sync | +| `web` | HTTP API, React frontend, auth, project & sharing management | +| `real-time` | WebSocket layer, live cursors and edit sync | | `document-updater` | Operational transformation, Redis pub/sub | | `clsi` | Compiler — runs `quarto render` (`.qmd`), `latexmk` (`.tex`) or `typst` (`.typ`) and serves output | | `docstore` | Document text storage (MongoDB) | | `filestore` | Binary file storage (S3 or local) | | `project-history` | Change history and version tracking | -## Writing a Quarto document +## Writing documents -Minimal working example (`main.qmd`): +### Quarto (`main.qmd`) ```markdown --- @@ -106,68 +146,86 @@ Write **Markdown** here. $$\int_0^\infty e^{-x^2}\,dx = \frac{\sqrt{\pi}}{2}$$ ``` -For PDF output, change `format: revealjs` to `format: typst`. +Switch `format: revealjs` to `format: typst` (or `pdf`) for a PDF preview. -> **Note on display math**: put `$$...$$` on a single line. -> Multi-line display math blocks can cause YAML parse errors in some Quarto versions. +### LaTeX (`main.tex`) -## Writing a LaTeX document +LaTeX works exactly as in Overleaf: a project whose root file is a `.tex` file +compiles with `latexmk`/TeX Live, no setting required. The **Example LaTeX +project** in the *New project* menu is a ready-made starting point. -LaTeX still works exactly as in Overleaf. A project whose root file is a `.tex` -file (e.g. `main.tex`) compiles with `latexmk`/TeX Live instead of Quarto — the -engine is chosen from the root file's extension, no setting required. The -**Example LaTeX project** in the *New project* menu is a ready-made starting -point; **Blank LaTeX project** gives you an empty `main.tex`. +> The bundled TeX Live is a minimal install. Documents that need extra packages +> may not build out of the box — see `server-ce/Dockerfile-base` for how to +> switch to a fuller TeX Live scheme. -> The bundled TeX Live is a minimal `scheme-basic` install. Documents needing -> extra packages may not build out of the box yet — see `server-ce/Dockerfile-base` -> for how to switch to a fuller TeX Live scheme. - -## Writing a Typst document +### Typst (`main.typ`) A project whose root file is a `.typ` file compiles directly to PDF with [Typst](https://typst.app) — fast, modern markup with a real scripting -language. No extra install is needed: Verso drives the Typst that ships inside -Quarto (`quarto typst compile`). Use the **Blank Typst project** or **Example -Typst project** entries in the *New project* menu to get started. +language. Verso drives the Typst bundled with Quarto, so no extra install is +needed. Use the **Blank Typst project** entry in the *New project* menu to get +started. + +## Publishing compiled output + +From **Share → Publish**, Verso compiles the project and snapshots the result to +a standalone page at `/p/:token`: + +- **HTML / RevealJS** decks are served as a live page (the **Present** toolbar + button is a one-click shortcut to this). +- **PDF** output is embedded inline; the raw file stays reachable at + `/p/:token/output.pdf`. + +Three stable links are issued, one per access tier — project members, any +logged-in user, or anyone — and each can be copied or independently reset. ## Environment variables Verso inherits all of Overleaf's environment variables (prefixed `OVERLEAF_`). -The most commonly needed ones: +The most commonly needed: | Variable | Default | Description | |----------|---------|-------------| | `OVERLEAF_APP_NAME` | `Verso` | Name shown in the UI | +| `OVERLEAF_NAV_TITLE` | — | Instance name/version shown in the top bar | | `OVERLEAF_MONGO_URL` | `mongodb://mongo/sharelatex` | MongoDB connection string | | `OVERLEAF_REDIS_HOST` | `localhost` | Redis host | -| `OVERLEAF_SITE_URL` | — | Public URL (used in emails) | +| `OVERLEAF_SITE_URL` | — | Public URL (used in emails and published links) | +| `OVERLEAF_SITE_LANGUAGE` | `en` | Default UI language (e.g. `fr`) | +| `OVERLEAF_ENABLE_PROJECT_PYTHON_VENV` | `false` | Allow Quarto Python cells to use a project `requirements.txt` | | `OVERLEAF_ADMIN_EMAIL` | — | Email for the first admin account | -See the [Overleaf Server documentation](https://github.com/overleaf/overleaf/wiki) for the full list. +See the [Overleaf Server documentation](https://github.com/overleaf/overleaf/wiki) +for the full list. ## Relation to Overleaf -Verso is a fork of [Overleaf Community Edition](https://github.com/overleaf/overleaf) with the following changes: +Verso is a fork of [Overleaf Community Edition](https://github.com/overleaf/overleaf). +The main additions on top of upstream are: -- LaTeX/CLSI compiler replaced by Quarto (PDF via Typst, HTML via RevealJS) -- Default project template changed from `main.tex` to `main.qmd` -- Document outline parser extended to read Markdown headings -- Compiler selector in the UI replaced with a single "Quarto" option -- Brand colours updated to Quarto's palette; name changed from Overleaf to Verso -- TeX Live removed from the base Docker image; Quarto installed instead +- Quarto and Typst compilers running alongside LaTeX, dispatched by the root + file's extension. +- Editor language support (highlighting, autocomplete, outline) for Quarto and + Typst. +- A per-project format badge on the dashboard and a root-file-aware compiler + selector. +- Publishing/sharing of compiled output (HTML decks and PDFs) via `/p/:token` + with tiered access links, and a toolbar **Present** shortcut. +- Optional per-project Python virtual environments for Quarto code execution. +- Verso branding (name, logo, palette, loading animation). -All other infrastructure — real-time collaboration, history, auth, file storage, project management — is unchanged from Overleaf. +All other infrastructure — real-time collaboration, history, auth, file +storage, project management — is unchanged from Overleaf. ## Contributing -Contributions are welcome. Please open an issue or pull request on the [Verso repository](https://git.alocoq.fr/alois/verso). - -The upstream Overleaf contribution guidelines are in [CONTRIBUTING.md](CONTRIBUTING.md). +Contributions are welcome — open an issue or pull request on the +[Verso repository](https://git.alocoq.fr/alois/verso). The upstream Overleaf +contribution guidelines are in [CONTRIBUTING.md](CONTRIBUTING.md). ## License GNU Affero General Public License v3 — see [LICENSE](LICENSE). -Copyright © Overleaf, 2014–2025 (original code). -Verso modifications © Aloïs Coquillard, 2026–present. +Copyright © Overleaf, 2014–2025 (original code). +Verso modifications © Aloïs Coquillard, 2025–2026. diff --git a/services/web/frontend/stylesheets/components/nav.scss b/services/web/frontend/stylesheets/components/nav.scss index 33d0792318..bb62ce079d 100644 --- a/services/web/frontend/stylesheets/components/nav.scss +++ b/services/web/frontend/stylesheets/components/nav.scss @@ -13,8 +13,9 @@ url('../../../public/img/ol-brand/overleaf-white.svg') ); - // Title, when used instead of a logo (the Verso instance name + version) - --navbar-title-font-size: var(--font-size-06); + // Title, when used instead of a logo (the Verso instance name + version). + // Sits between --font-size-07 (30px) and --font-size-08 (36px): "7.5" ≈ 33px. + --navbar-title-font-size: 2.0625rem; --navbar-title-color: var(--neutral-20); --navbar-title-color-hover: var(--neutral-40); diff --git a/services/web/frontend/stylesheets/pages/project-list-ds-nav.scss b/services/web/frontend/stylesheets/pages/project-list-ds-nav.scss index 7000192ea1..a5bb35b339 100644 --- a/services/web/frontend/stylesheets/pages/project-list-ds-nav.scss +++ b/services/web/frontend/stylesheets/pages/project-list-ds-nav.scss @@ -355,7 +355,10 @@ body { } .project-ds-nav-main { - min-height: 100%; + // Grow to fill the scroll area so the footer sits at the bottom of the + // viewport when the list is short, instead of being pushed a full screen + // down by a min-height: 100% (which always forced a scroll to reach it). + flex: 1 0 auto; padding: var(--spacing-08) var(--spacing-06); @include media-breakpoint-up(md) { @@ -399,6 +402,10 @@ body { overflow-y: auto; position: relative; background-color: var(--ds-nav-content-bg-secondary); + // Lay out main + footer as a column so the footer can stick to the + // bottom (main grows via flex: 1 0 auto above). + display: flex; + flex-direction: column; @include media-breakpoint-up(md) { border-top-left-radius: var(--border-radius-large);