Skip to content

Develop - #71

Merged
drnachio merged 18 commits into
mainfrom
develop
Jun 9, 2026
Merged

Develop#71
drnachio merged 18 commits into
mainfrom
develop

Conversation

@drnachio

@drnachio drnachio commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #49

Area

  • Enriched markdown input / parser
  • Layout engine — column flow / balancing / convergence (VDT)
  • Layout engine — resource placement / text flow around obstacles
  • Typography — orphan/widow, keep-together, rag, spacing rules
  • Typography — hyphenation (language: ____)
  • References — footnotes / endnotes / margin notes / pull quotes
  • Renderer — HTML / CSS
  • Renderer — PDF
  • Renderer — canvas / rasterization
  • Web Worker (postext/worker) — build, cancellation, font pipeline
  • Configuration — schema, defaults, validation
  • Playground / docs site (apps/web)
  • Build, types, packaging, CI
  • Internal refactor with no behavior change

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds capability)
  • Breaking change (fix or feature that changes existing API, configuration shape, or rendered output)
  • Documentation only
  • Refactor / chore (no behavior change)

Motivation and context

Implementation notes

Visual impact

Tests

  • pnpm lint passes
  • pnpm check-types passes
  • pnpm test passes (run inside packages/postext)
  • pnpm build passes at the repo root
  • I tested the change manually in the playground (apps/web) where applicable

Breaking changes

Checklist

  • My commits follow the project's existing style (small, focused, imperative subject line).
  • I updated the documentation under apps/web/ and/or README where relevant.
  • I did not bump the version in packages/postext/package.json — releases are handled separately.
  • I did not include unrelated refactors, formatting changes, or dependency bumps in this PR.
  • If this change introduces new configuration, it has sensible defaults and keeps the zero-config path working.
  • If this change affects the worker surface (postext/worker), the main-thread and worker code paths stay behavior-compatible.

drnachio and others added 18 commits April 28, 2026 10:51
Add the resource data model (ResourceType, Resource, ResourceKind,
TableModel/TableCell) and resourceTypes to PostextConfig, with built-in
'figure'/'table' defaults. Extend the parser types with a 'resourceBlock'
content block, ContentBlock.resourceId, and InlineSpan.ref for inline
references. Add IndexedDB-backed blobStore and resources persistence in the
sandbox, and wire resources into SandboxContext (async load on init,
SET_RESOURCES/UPSERT_RESOURCE/DELETE_RESOURCE actions, diffed persistence
effect, resourceTypes defaulting).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the markdown extension for resources (issue #49 §2):

- blockParser: recognize `::resource{id="..."}` as a `resourceBlock`
  (matched after math fences, before headings); malformed forms fall
  through to a paragraph.
- inlineFormatting: add a `:ref{id="..." style? text?}` inline pre-pass
  using a distinct atomic placeholder so sourceMap stays 1-to-1; pass
  order is refs -> math -> formatting.
- sourceMapping: map the ref placeholder back to the `:ref{...}` source
  span so per-character source offsets remain accurate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the template renderer from numbering.ts into a shared
renderCounterTemplate() helper used by both heading and resource
numbering (heading behavior unchanged). Add resourceNumbering.ts which
computes a ResourceNumberingMap by first-reference order, partitioning
by typeId and honoring each type's resetOn against heading context, and
rendering via numberingTemplate + counterFormat. Wire computation into
build.ts ahead of the placement loop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add packages/postext/src/table/model.ts with dependency-free, immutable
TableModel operations: addRow, addColumn, removeRow, removeColumn,
mergeCells, unmergeCell, setCellContent, setAlignment, parseTSV. Merges
track a primary cell via colSpan/rowSpan and mark covered cells with
hiddenBy: TableCellPos; unmerge restores them. Export helper types
CellPos, CellRange, Align, VAlign.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add ResourceTypesSection to the config sidebar for managing user-defined
resource types (figures, tables, etc.). Each row exposes editable name,
namePlural, shortLabel, numberingTemplate, resetOn, counterFormat and
captionPrefix fields (id is read-only), with a live preview of the
rendered label (e.g. "Fig. 1.7"). Deletion is guarded by ConfirmPopover
and warns when existing resources use the type. Defaults to the built-in
types and supports reset-to-defaults. Registered in ConfigPanel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the ResourcesPanel placeholder with a two-column manager: a grouped
resource list with thumbnails/glyphs and a "New" menu, and an editable detail
pane (id with slugify auto-suggest, type selector, inline-microformat caption
editor, alt text, kind-specific controls, mock preview).

Adds the reusable InlineMarkdownInput control (live bold/italic/code/math/:ref
preview), bitmap/SVG drag-drop uploaders (createImageBitmap + DOMParser
validation, putBlob storage), a slugify util, and a reference-counting delete
flow. Rename copies the blob to a fresh fileId so the persistence cascade does
not destroy a still-referenced payload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a TableEditor that drives table resources through the Phase-4 pure model
functions. Includes keyboard cell navigation (Tab/Shift-Tab with row wrap,
arrow keys at cell edges, Shift+arrows to extend the merge selection),
a snapshot-based undo/redo stack (Cmd/Ctrl+Z, Shift+Cmd/Ctrl+Z, Ctrl+Y),
a toolbar (add/remove row & column, merge/split, header-row/column toggles,
per-cell alignment, paste-as-table), and TSV/CSV paste detection that
overwrites the model. Wired into ResourceDetail; edits persist via
UPSERT_RESOURCE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render embedded resources (bitmap / svg / table) plus captions through
the measurement, placement, and both rendering backends (issue #49 §7).

- vdt: ResolvedResourceBlock + table layout types; VDTLineSegment.refResourceId
- pipeline: resourceLayout measures image/table + caption as one group,
  resolving inline :ref labels; buildBlockKind resolves resourceBlock ->
  'resource'; buildMeasurement threads resources + numbering; build wires
  content.resources and places resources atomically (keep-together);
  placement gains placeResourceBlock
- canvas: renderResourceBlock with a fileId-keyed image registry, table
  borders/header fills + delegated cell text, link-coloured :ref segments
- pdf: renderResourceBlock embeds bitmaps (WebP -> PNG via canvas; SVG
  raster fallback, TODO(#49-svg-vector)), draws tables, emits :ref link
  annotations via named destinations (links.ts); images preloaded async

Resources flow via PostextContent.resources (repurposed from the unused
legacy field). All three packages type-check clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add resource-related warning kinds (unknownResourceId, unusedResource,
duplicateResourceId, danglingTypeRef, bitmapTooSmall, storageUnavailable),
their collectors in computeWarnings, and rendering in WarningsPanel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ypes

Add a Resources section to document-format-{en,es} (block embed, inline
reference with style/text options, first-reference numbering) and a
Resource types section to configuration-{en,es} (ResourceType shape,
{h1}/{n} template tokens, resetOn, counterFormat, captionPrefix), with
cross-links to heading numbering.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… model

Add vitest coverage for issue #49 core logic:
- parse/resourceDirective: ::resource{id} -> resourceBlock; malformed falls
  through to paragraph
- parse/inlineRef: :ref style/text variations, mixing with bold/italic/math,
  placeholder-count == ref-span-count
- pipeline/resourceNumbering: first-reference ordering, resetOn:h1, template
  rendering, decimal/roman/alpha counter formats
- table/model: row/col + merge/unmerge invariants, TSV normalization, round-trip
- defaults/resourceTypes: built-in defaults have valid templates & prefixes
- exports: include new resource image / table runtime exports and assert the
  Resource/ResourceType/ResourceKind/TableModel/TableCell type exports

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…upload

Replace the two-column resources panel with a single-column flow: the list
fills the panel and selecting a resource swaps to a detail view with a back
button. The whole panel is now a drop target that auto-uploads one or many
images/SVGs dragged from disk (shared uploadFiles helper). Also drop a stale
unused import in ResourceTypesSection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ship built-in example resources (a pipeline diagram SVG and a comparison
table) seeded on first entry and restored on document reset, with deterministic
blob ids (putBlobAt) so re-seeding is idempotent. The default markdown (en+es)
now embeds them via ::resource and cross-references them with :ref, so the
resources system is functional out of the box.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The viewports built documents without passing the sandbox resources, so
::resource embeds never resolved. Thread resources into the canvas, HTML, and
PDF build calls so tables, captions, numbering, and inline :ref all resolve.
Decode bitmap/SVG blobs on the main thread and register them with the canvas
backend (font-load -> repaint pattern) so figure pixels actually draw. Include
resources in the ActivityBar warning-badge count so unknown-reference warnings
are counted consistently with the warnings panel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ections

- Introduced `svgIntrinsicSize` and `isValidSvg` functions for SVG size extraction and validation.
- Added `CaptionStyleSection` component for configuring caption styles, including font, size, alignment, and color options.
- Implemented `TableStyleSection` component for styling tables, allowing customization of body/header typography, fills, borders, and cell padding.
- Created default configurations for caption and table styles to ensure consistent rendering.
- Developed float placement logic to manage resource positioning in document layouts, ensuring proper handling of inline and floated resources.
- Added tests for float placement and inline reference rendering to ensure functionality and correctness.
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
postext Ready Ready Preview, Comment Jun 9, 2026 7:03pm

Request Review

@drnachio
drnachio merged commit 0c67078 into main Jun 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resources panel: images, SVGs, HTML tables with captions, typed numbering & inline references

1 participant