Expand description
Per-block character formatting as sorted, non-overlapping byte spans.
Each block carries a Vec<FormatRun> (formatting) and a
Vec<ImageAnchor> (image positions). The block’s plain_text is
the authoritative character source for byte offsets used by both.
Replaces the pre-Phase-1 model where every formatted run and every
inline image was a row in the now-deleted inline_elements entity
table; the InlineSegment type in this module is a transient
view synthesized from (plain_text, format_runs, block_images)
for readers (export, fragments, cursor) that still consume a
per-segment shape.
Invariants are documented on FormatRun and enforced by
debug_assert_well_formed and by splice_range / shift_after
which rebuild the run list while preserving them.
In a release build a debug_assert! is not enforcement. It is compiled out, so
a contract violation there produced a malformed run list silently — and autosave
wrote that corruption to the writer’s file seconds later. The bulk-edit path
therefore uses the checked siblings, which report instead of assert:
check_well_formed, try_splice_range and shift_runs_for_replace, all
returning FormatRunError.
Structs§
- Character
Format - Character-level formatting for a contiguous byte span. One per
FormatRun; one perImageAnchor. Fields mirror thefmt_*set onInlineSegmentand onFragmentElementso values copy across types verbatim. - Footnote
RefAnchor - A footnote reference embedded at a specific byte position inside a block.
- Format
Run - One run of identical character formatting inside a block. Byte offsets
are relative to the block’s
plain_text(Phase 1) or to the block’s rope range (Phase 2). - Image
Anchor - An image embedded at a specific byte position inside a block. In
Phase 1 the byte position is an index into the block’s
plain_text; in Phase 2 it points at the U+FFFC sentinel character in the rope. - Inline
Segment - A lean view type representing one inline segment (text or image) with its
associated formatting. Used by readers (export, fragments, cursor) to
consume per-segment data synthesized from
(plain_text, format_runs, block_images)viacrate::format_runs_query::inline_segments_for_block. Never stored — synthesized on demand.
Enums§
- Block
Anchor - One inline object anchored in a block: an image, or a footnote reference.
- Format
RunError - A violation of the format-run invariants, reported instead of asserted.
- Inline
Content - Content type for an inline segment: text, image, footnote reference, or empty.
- Inline
Piece - One ordered piece of a block’s inline content: a run of text, or an image.
- Replace
Format Policy - What the replacement text wears when it overwrites formatted text.
Functions§
- apply_
character_ format_ to_ segment - Apply a
CharacterFormatonto anInlineSegment’s fmt_* fields. - block_
anchors - Every anchor in a block, in byte order.
- capture_
image_ formats_ in_ range - Capture the
(byte_offset, format)pairs for every image anchor inside[start..end). Used together withcapture_runs_in_rangeby hand-rolled-inverse undo for format-only edits. - capture_
runs_ in_ range - Capture the slice of
runsthat intersects[start..end), clipped to those bounds. Used by hand-rolled-inverse undo for format-only edits: callers capture this BEFORE callingsplice_range, and on undo splice the captured runs back into the same byte range to restore the prior state without paying the cost of a fullRopeStoreSnapshot. - character_
format_ from_ segment - Copy the
fmt_*fields of anInlineSegmentinto aCharacterFormat. - check_
well_ formed - The same invariants as
debug_assert_well_formed, but reported rather than asserted — so a caller that must not corrupt a block can refuse the edit. - coalesce_
in_ place - Merge adjacent runs that have identical formatting. O(n).
- debug_
assert_ well_ formed - Debug-only invariant check. Run from
debug_assert!callsites in the use cases that mutate format runs. Cheap: O(n) where n is the run count (typically < 100 per block in real prose). - inline_
segments_ view - Synthesize a
Vec<InlineSegment>view of a block from itsplain_text,format_runs, andblock_images. Returns segments in document order: a Text segment per format run (with a fallback default-format segment for any uncovered bytes), and an Image segment per anchor at its byte offset. - logical_
offset_ to_ byte - Translate a logical character offset (counting text characters AND
image positions interleaved by their
byte_offset) into a UTF-8 byte offset withinplain_text. Used by writer use cases to map a document-space char position to the byte position where text edits should land inblock.plain_text. - merge_
runs_ and_ anchors - Interleave a block’s format runs and image anchors into one ordered stream.
- shift_
after - Shift the byte offsets of every run whose
byte_start >= thresholdbydelta. Used after a text insert/delete to keep downstream runs in sync with the new block text. Runs strictly before the threshold are unaffected; runs that straddle the threshold are left alone (the caller should have spliced them first). - shift_
footnote_ refs_ for_ insert - Apply an “insert” shift to a block’s image anchors. Anchors at or
past the offset move forward by
inserted_bytes. Apply an “insert” mutation to a block’s footnote references — the ruleshift_images_for_insertapplies, for the same reason. - shift_
images_ after - Same as
shift_afterfor image anchors. Anchors AT the threshold are shifted (treated as part of the inserted region’s right side). - shift_
images_ for_ delete - Apply a “delete” mutation to a block’s image anchors. Anchors whose
byte_offsetfalls inside[byte_start..byte_end)are removed; anchors at or pastbyte_endshift back by the deleted length. Returns the number of anchors removed. - shift_
images_ for_ insert - shift_
runs_ for_ delete - Apply a “delete byte range
[byte_start..byte_end)” mutation to a block’s runs. Splices the range with empty replacement (clipping straddling runs) and shifts everything pastbyte_endback by the deleted length. Adjacent runs that end up equal-format are coalesced. - shift_
runs_ for_ insert - Apply an “insert
inserted_bytesof text atbyte_offset” mutation to a block’s runs in place. Runs strictly before the offset are unchanged; runs strictly after are shifted by +inserted_bytes; runs that straddle the offset are extended (the inserted text inherits the surrounding run’s format — Qt / ProseMirror convention). - shift_
runs_ for_ replace - Apply a “replace byte range
[byte_start..byte_end)withreplacement_bytesbytes” mutation to a block’s runs, choosing explicitly what the replacement wears. - splice_
range - Replace the runs covering
rangewithreplacement, preserving the invariants. Runs that straddle the range boundary are clipped on either side; runs fully contained are removed. - split_
footnote_ refs_ at - Split block image anchors at
byte_offset. Anchors at exactlybyte_offsetgo to the right half (rebased to offset 0). Split footnote references atbyte_offset, rebasing the right-hand side to zero — the exact rulesplit_images_atapplies, because a reference occupies a block the same way an image does. - split_
images_ at - split_
runs_ at - Split a block’s format runs at
byte_offset. The returned right-hand vector has its run offsets re-based so they start at byte 0 of the new (right) block. Straddling runs are split with theirformatcloned to both halves. - synth_
element_ id - Synthesize a stable per-fragment id from a block id and byte offset
within that block. Populates the
element_idfield inFragmentContent::{Text, Image}(the public layout-engine type), giving callers a stable handle across renders even though the underlyingInlineSegments are never stored. Two segments at the same(block_id, byte_start)always produce the same id; a segment that moves to a new byte_start (e.g. due to an insert upstream) gets a new id. - try_
splice_ range splice_range, but the contract is checked and reported instead of asserted.