Text Runs and Paragraphs
Index-Based Model
Univer Docs does not store rich text as a nested tree. It stores plain text in body.dataStream, and then uses index ranges to attach style and structure to the text.
The most common index-based structures are:
ITextRun: inline text style range.IParagraph: paragraph metadata and paragraph style.ISectionBreak: section break metadata.
ITextRun
ITextRun describes the style of a continuous text range.
| Property | Type | Description |
|---|---|---|
| st | number | Start index, inclusive. |
| ed | number | End index, exclusive. |
| sId? | string | Referenced style ID. |
| ts? | ITextStyle | Inline text style object. |
TypeScript
const body: IDocumentBody = { dataStream: 'Hello Univer\r\n', textRuns: [ { st: 0, ed: 5, ts: { bl: 1 }, }, { st: 6, ed: 12, ts: { cl: { rgb: '#2563eb' } }, }, ],}In this example, Hello is bold and Univer is blue. The paragraph break \r\n is not included in the styled ranges.
IParagraph
IParagraph describes paragraph-level metadata. startIndex points to the paragraph break position in dataStream.
| Property | Type | Description |
|---|---|---|
| startIndex | number | Index of the paragraph break. |
| paragraphId | string | Stable paragraph ID. |
| paragraphStyle? | IParagraphStyle | Paragraph style such as alignment, indentation, line spacing, and heading type. |
| bullet? | IBullet | List marker metadata. |
TypeScript
const body: IDocumentBody = { dataStream: 'Hello Univer\r\nSecond line\r\n', paragraphs: [ { startIndex: 12, paragraphId: 'p-1', paragraphStyle: { namedStyleType: NamedStyleType.HEADING_1, }, }, { startIndex: 25, paragraphId: 'p-2', }, ],}ISectionBreak
ISectionBreak also uses an index to connect section-level settings to the text stream. It can override page size, margins, headers, footers, columns, and text direction for a section.
TypeScript
const body: IDocumentBody = { dataStream: 'First section\nSecond section\r\n', sectionBreaks: [ { startIndex: 13, pageSize: { width: 595, height: 842 }, marginTop: 72, marginBottom: 72, }, ],}Notes
- Keep indexes aligned with
dataStream. Incorrect indexes can cause style ranges, paragraphs, selections, or rendering to become inconsistent. - Prefer Facade APIs and commands for editing an active document.
- When generating snapshots manually, build
dataStreamfirst, then compute ranges and paragraph positions from that string.
How is this guide?