Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
41132c3
Upgrade decoupled linebender deps (parley/fontique/skrifa generation)…
claude Jun 21, 2026
bcb431c
Add full-workspace audit (security, performance, code smells, dead co…
claude Jun 21, 2026
b2120c5
Fix critical audit items: CI gates, ODT-export docs, tests for zero-t…
claude Jun 21, 2026
f2fbfde
P1 audit items: drop per-paint clone in loki-vello; correct ceiling t…
claude Jun 21, 2026
1a5e65d
P2/#9: eliminate per-styled-run CharProps clone in the layout resolve…
claude Jun 21, 2026
df47b83
Q-2: extract shared app-shell cluster into loki-app-shell crate
claude Jun 21, 2026
915ac46
P-4: generalize incremental Loro reconstruction to all sections
claude Jun 21, 2026
11ada76
Enable multi-section editing (global block addressing)
claude Jun 21, 2026
d94fb34
Q-1 split pass: split odt/mapper/props.rs (925) into props/ submodules
claude Jun 21, 2026
9aa74c7
Q-1 split pass: extract inline test modules from 9 over-ceiling files
claude Jun 21, 2026
5560d6b
test(crdt): add concurrency, merge, undo, and pathological-state test…
claude Jun 21, 2026
db8cd81
test(export): add EPUB/PDF/PPTX integration suites and run feature-ga…
claude Jun 21, 2026
1896077
test(acid): supply acid_pptx.pptx fixture and wire a presentation pat…
claude Jun 21, 2026
2593b2a
feat(epub): carry table caption, column widths, and cell alignment
claude Jun 21, 2026
d98222b
fix(renderer): unregister page textures when tiles unmount (scroll RA…
claude Jun 21, 2026
b0823bb
refactor(renderer): remove the vestigial resolution-tiering subsystem
claude Jun 21, 2026
45cd183
diag(text): instrument Loro history growth to pinpoint the slow edit-…
claude Jun 21, 2026
57394fb
fix(blitz): stop the continuous idle render loop caused by static can…
claude Jun 21, 2026
694f916
fix(ui): distinct Save As icon + bundle the UI font as a data URI
claude Jun 21, 2026
ea27582
fix(ribbon): remove the empty Insert/Format/Review/View tabs
claude Jun 21, 2026
cb10cff
fix(layout): register bundled fallback fonts for the document rendere…
claude Jun 21, 2026
8696dde
Add full paragraph style editor (font, weight, indent, spacing)
claude Jun 21, 2026
d7b61e6
Persist style catalog through DOCX save/reload
claude Jun 21, 2026
b942602
Route the style catalog through Loro for undo/redo
claude Jun 22, 2026
247e478
Open OTT/DOTX templates as new documents (foundation)
claude Jun 22, 2026
b4c87a7
Add 5 bundled .dotx templates and DOTX export
claude Jun 22, 2026
7c1b9de
Add "Save as Template" (.dotx) export to the ribbon
claude Jun 22, 2026
0125418
docs: record template open/export support in fidelity registry
claude Jun 22, 2026
45f8c55
Implement ODF (ODT) export
claude Jun 22, 2026
ef825a5
Make ODF export near-lossless (properties, images, fields, bookmarks)
claude Jun 22, 2026
06a614c
Export headers/footers in ODF
claude Jun 22, 2026
6fe47bf
Tackle DOCX headers/footers: even-page round-trip + settings.xml
claude Jun 22, 2026
de9ae4e
Export body-text dynamic fields to DOCX
claude Jun 22, 2026
31822b1
Export multi-section page geometry to ODT
claude Jun 22, 2026
e770106
Export multi-column sections for OOXML and ODF
claude Jun 22, 2026
23a799e
Flow text into multi-column sections at layout time
claude Jun 22, 2026
88fae9e
Import w:fldSimple simple fields (with round-trip)
claude Jun 22, 2026
1434b43
Export document metadata + extended Dublin Core (DOCX & ODT)
claude Jun 22, 2026
f08bcce
Round-trip comments (annotations) for DOCX and ODT
claude Jun 22, 2026
92eda66
Comment bodies as structured blocks (multi-paragraph)
claude Jun 22, 2026
2285c98
Persist document comments through the Loro CRDT
claude Jun 22, 2026
3ea3888
Render comments as a margin panel in paginated layout
claude Jun 22, 2026
e81e9f4
Add DOCX math (OMML) round-trip via MathML
claude Jun 22, 2026
6923a98
Add ODT math round-trip via embedded formula objects
claude Jun 22, 2026
0ddd8e4
Render math inline with a first-pass MathML typesetter
claude Jun 23, 2026
f7a5e7b
Math rendering: baseline alignment + stretchy radicals & delimiters
claude Jun 23, 2026
7b1dbd4
Fix CI: add missing StyleSpan.math field + clippy 1.96 collapsible_match
claude Jun 23, 2026
73027e5
Include paragraph left indent in cursor / hit-test / selection geometry
claude Jun 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,33 @@ env:
CARGO_TERM_COLOR: always

jobs:
build:

# Fast-failing quality gates mandated by CLAUDE.md: formatting and clippy.
# These run first so style/lint regressions surface before the slower build.
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install toolchain (rustfmt + clippy)
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- name: Format check
run: cargo fmt --all --check
- name: Clippy (workspace, all features, warnings denied)
run: cargo clippy --workspace --all-features -- -D warnings

build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install toolchain
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# `--all-features` so the feature-gated format crates (pptx, xlsx) and their
# integration tests actually compile and run — under the default feature set
# `cargo test --workspace` silently skips `#![cfg(feature = ...)]` suites.
- name: Build
run: cargo build --verbose
run: cargo build --workspace --all-features --verbose
- name: Run tests
run: cargo test --verbose
run: cargo test --workspace --all-features --verbose
48 changes: 41 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,43 @@ When adding `#[allow]` to any file:
These files existed before the ceiling convention was established and have not
yet been split. Do not add new code to them without splitting first.

A 2026-06-21 audit found **43 production files** over the ceiling (16 over 600
lines). The full list and a proposed split strategy live in
[docs/audit-2026-06.md](docs/audit-2026-06.md) (finding Q-1); the worst
offenders are below. This is a dedicated split-pass backlog, not a per-change
blocker — but do not *grow* these files or add new ones over the ceiling.

The split pass is **in progress** — **10 of 43 files done** (≈33 remain). Two
techniques:
1. *Inline-test extraction* (safest, no production-code change): move a file's
`#[cfg(test)] mod tests { … }` into a sibling `<name>_tests.rs` referenced via
`#[cfg(test)] #[path = "<name>_tests.rs"] mod tests;`. Done 2026-06-21 for
`block.rs`, `docx/mapper/{paragraph,numbering,mod,table}.rs`, `odt/import.rs`,
`odt/mapper/lists.rs`, `layout/result.rs`, `renderer/render_layout.rs` — each
was over the ceiling only because of a large inline test module.
2. *Directory split*: convert `foo.rs` → a `foo/` directory with section-cohesive
submodules (each starting `use super::*;`), re-export the public entry points
from `foo/mod.rs`, and move the tests via the same `#[path]` idiom. Done for
`odt/mapper/props.rs` → `odt/mapper/props/` (worked example).

(Test files are exempt from the production-line count.)

| File | Current lines | Priority |
|---|---|---|
| `loki-text/src/components/document_source.rs` | 1117 | High |
| `loki-text/src/routes/editor/editor_inner.rs` | ~945 | High |
| `loki-doc-model/src/loro_bridge/inlines.rs` | ~280 | Low |

(`read.rs` was split into `read.rs` + `props_read.rs`; both are now under 300 lines.)
| `loki-layout/src/flow.rs` | 1612 | High |
| `loki-odf/src/odt/reader/styles.rs` | 1441 | High |
| `loki-odf/src/odt/reader/document.rs` | 1428 | High |
| `loki-layout/src/para.rs` | 1278 | High |
| `loki-spreadsheet/src/routes/editor/editor_inner.rs` | 1241 | High |
| `loki-ooxml/src/docx/write/document.rs` | 1169 | High |
| `loki-ooxml/src/docx/reader/document.rs` | 1126 | High |
| `loki-odf/src/odt/mapper/document.rs` | 1094 | High |
| `loki-text/src/routes/editor/editor_inner.rs` | 968 | High |
| … 24 more (300–600 lines) — see the audit (10 files split 2026-06-21) | | |

(`read.rs` was split into `read.rs` + `props_read.rs`; both are now under 300
lines. `loro_bridge/inlines.rs` is now 219 lines, under the ceiling.
`loki-text/src/components/document_source.rs` no longer exists.)

## Known tech debt — Loro bridge round-trip gaps

Expand All @@ -157,12 +187,16 @@ The workspace is a set of focused crates (one responsibility each). Key groups:
- **Formats (one crate per family):**
- `loki-opc` — OPC/ZIP container shared by OOXML/ODF.
- `loki-ooxml` — DOCX/XLSX import + DOCX export.
- `loki-odf` — ODT/ODS import + ODT/ODS export.
- `loki-odf` — ODT/ODS import + ODT/ODS export. ODT export (`odt/write/`)
writes `content.xml` / `styles.xml` / `meta.xml`: paragraphs, headings,
styled paragraphs, lists, tables, inline formatting, the named style
catalog, page geometry, and metadata.
- `loki-pdf` — **PDF/X** export (X-1a/X-3/X-4) via `pdf-writer`; reuses
`loki-layout` for positioning, embeds fonts + images (CMYK).
- `loki-epub` — **EPUB 3.3** export (XHTML + OCF ZIP).
- **Layout & rendering:** `loki-layout` (renderer-agnostic, Parley-based),
`loki-vello` / `loki-renderer` / `loki-render-cache` (GPU paint + tiering).
`loki-vello` / `loki-renderer` / `loki-render-cache` (GPU paint; per-page
tiles bounded by viewport virtualization).
- **UI & apps:** `appthere-ui` (shared design system), `appthere-canvas`,
`loki-i18n`, `loki-fonts`, and the binaries `loki-text` (word processor —
the mature app), `loki-spreadsheet`, `loki-presentation`.
Expand Down
Loading
Loading