cupertino-files / TextStorage
Class: TextStorage
Defined in: src/tswp/textstorage.ts:212
Constructors
Constructor
new TextStorage(
store,object):TextStorage
Defined in: src/tswp/textstorage.ts:216
Parameters
store
object
Returns
TextStorage
Properties
object
readonlyobject:IwaObject
Defined in: src/tswp/textstorage.ts:214
store
readonlystore:ObjectStore
Defined in: src/tswp/textstorage.ts:213
Accessors
endsWithEmptyParagraph
Get Signature
get endsWithEmptyParagraph():
boolean
Defined in: src/tswp/textstorage.ts:813
True when the text ends with a paragraph terminator, so the app draws one more, empty paragraph after the last one paragraphs lists.
Both tail states are the apps' own. Of the corpus's 26 body storages, 15 end bare — the shape typing leaves, and what a current Pages saves for a document whose last paragraph was typed, not returned past — 8 end with a terminator and carry the paragraph-style entry at text.length for the phantom paragraph, and 3 are empty. A built document that should not show a stray final line wants the bare shape; normalizeTail produces it, keeping every attribute table lawful on the way.
Returns
boolean
id
Get Signature
get id():
bigint
Defined in: src/tswp/textstorage.ts:221
Returns
bigint
kind
Get Signature
get kind():
number
Defined in: src/tswp/textstorage.ts:259
Returns
number
revision
Get Signature
get revision():
number
Defined in: src/tswp/textstorage.ts:247
Edit count; pair with offsetsStableSince for staleness checks.
Returns
number
stylesheetId
Get Signature
get stylesheetId():
bigint|undefined
Defined in: src/tswp/textstorage.ts:264
Identifier of the TSS.StylesheetArchive governing this storage.
Returns
bigint | undefined
text
Get Signature
get text():
string
Defined in: src/tswp/textstorage.ts:292
Returns
string
Methods
addBookmark()
addBookmark(
start,end,name?):bigint
Defined in: src/tswp/textstorage.ts:1714
Mark [start, end) as a bookmark — a named destination a link can target.
A bookmark with no name is what the apps create for a link pointing at a stretch of text rather than a named place; both shapes occur in the corpus and both are written here.
Parameters
start
number
end
number
name?
string
Returns
bigint
addComment()
addComment(
start,end,text,options?):bigint
Defined in: src/tswp/textstorage.ts:1818
Attach a comment to [start, end).
Creates the three objects a comment needs — highlight, comment storage, author — and spans the highlight over the range, which is what makes the words show highlighted. The author is reused by default: a document where every comment has its own copy of the same person is not what the apps produce.
Returns the comment storage's identifier, which removeComment takes.
Parameters
start
number
end
number
text
string
options?
AddCommentOptions = {}
Returns
bigint
addFootnote()
addFootnote(
pos,text,options?):TextStorage
Defined in: src/tswp/textstorage.ts:1364
Add a footnote anchored at pos, with text as its content.
A footnote is two storages, not one: this one gains a U+000E reference character, and a new storage of kind FOOTNOTE holds the note itself. That note's text starts with its own U+FFFC placeholder — the spot where the app draws the footnote's number — so the note reads "<mark> your text", exactly as Apple writes it.
Numbering is not set here. Which number a footnote gets depends on how many precede it and on the document's numbering settings, both of which the app resolves when it lays the document out.
Returns the new footnote storage, so its text can be styled or edited like any other.
Parameters
pos
number
text
string
options?
markStyle?
bigint | false
Returns
TextStorage
appendParagraph()
appendParagraph(
text,listStyle?):number
Defined in: src/tswp/textstorage.ts:770
Append a paragraph, preserving the file's trailing-newline convention. Returns the new paragraph's index.
The new paragraph states its own list membership rather than inheriting the previous one's: attribute tables are read as runs, so one bulleted paragraph would otherwise turn every later append into a list item — invisibly, because membership lives in the list table and not in the paragraph style. Apple writes the same statement, with a list style named "None" (222 of 222 corpus list-table entries name a style; 82 name that one). Pass a list style to opt in, or call setListStyle afterwards.
Character styling ends at the same seam: a character-style run open at the end of the text is closed before the new paragraph is inserted, so a styled last line never bleeds into what is appended after it. Raw insertText/replaceRange keep the typing model — text inserted inside or at the edge of a run takes the run's style.
Writing direction is stated the same way: when the storage has a bidi table, the new paragraph gets its own pair, copying the baseline at position 0 — 2594 of the corpus's 2896 bidi-bearing storages cover every paragraph start, and an open-ended RTL entry appears only where no paragraph follows it. Without the statement one flipped paragraph turns every later append RTL.
Parameters
text
string
listStyle?
bigint
Returns
number
applyEdits()
applyEdits(
edits):void
Defined in: src/tswp/textstorage.ts:703
Apply several non-overlapping edits from one snapshot of the text.
Every edit's offsets refer to the text as it is now: the batch is sorted descending internally, so no edit shifts another's offsets and callers need no re-reading discipline between spans. Overlapping edits are refused before anything is written. An omitted replacement deletes the range.
Parameters
edits
readonly object[]
Returns
void
attachments()
attachments():
object[]
Defined in: src/tswp/textstorage.ts:1261
Inline attachment runs: page numbers, page counts, footnote marks and anchored drawables, each at its U+FFFC character.
Returns
object[]
bookmarks()
bookmarks():
object[]
Defined in: src/tswp/textstorage.ts:1735
Bookmarks anchored in this storage (named destinations).
Returns
object[]
characterFormattingAt()
characterFormattingAt(
pos):CharacterFormatting
Defined in: src/tswp/textstorage.ts:404
The formatting in effect at pos, with inheritance folded in: the paragraph style's character bag as the base, the character-style chain's values on top — id in, effective CharacterFormatting out, no schema knowledge needed.
Parameters
pos
number
Returns
characterStyleIdAt()
characterStyleIdAt(
pos):bigint|undefined
Defined in: src/tswp/textstorage.ts:394
The character style ruling pos, or undefined when no direct character styling applies there and the paragraph style alone rules — the normal state of most text. Resolve a name with styleNameOf.
Parameters
pos
number
Returns
bigint | undefined
characterStyleRuns()
characterStyleRuns():
StyleRun[]
Defined in: src/tswp/textstorage.ts:891
Character-style runs (undefined objectId = paragraph style applies).
Returns
StyleRun[]
comments()
comments():
CommentInfo[]
Defined in: src/tswp/textstorage.ts:1776
Comments anchored in this storage (from both anchor tables).
Returns
copyShapeFrom()
copyShapeFrom(
sibling):void
Defined in: src/tswp/textstorage.ts:904
Adopt a sibling storage's attribute shape: its paragraph style, and its character-table and language entries when it has them. This is how text written into one of a page master's always-empty header/footer storages becomes drawable — the bare default shape those storages carry is one the app never draws from, while every rendered corpus header/footer storage states its own paragraph style with the char-style table or the language table beside it.
Parameters
sibling
TextStorage
Returns
void
dateFields()
dateFields():
object[]
Defined in: src/tswp/textstorage.ts:1547
The date fields in this storage, with their settings.
Returns
object[]
defineAsPlaceholder()
defineAsPlaceholder(
start,end):bigint
Defined in: src/tswp/textstorage.ts:1695
Mark [start, end) as placeholder text, the way Format → Advanced → Define as Placeholder Text does: a click in the app selects the whole span and typing replaces it. Any smart field already on the span is replaced, like inserting any other field. Returns the field's id.
Parameters
start
number
end
number
Returns
bigint
deleteRange()
deleteRange(
start,end):void
Defined in: src/tswp/textstorage.ts:690
Parameters
start
number
end
number
Returns
void
effectiveObjectAt()
effectiveObjectAt(
tableField,pos):bigint|undefined
Defined in: src/tswp/textstorage.ts:424
Effective object id at a position — the last value set at or before pos in the given attribute table.
tableField is a Storage.* field number (e.g. Storage.TABLE_CHAR_STYLE), not a name. undefined means no run entry rules the position: for the character table that is "no direct character styling here — the paragraph style alone applies", which is the normal state of most text, not an error.
Parameters
tableField
number
pos
number
Returns
bigint | undefined
ensureTrailingParagraphEntry()
ensureTrailingParagraphEntry():
void
Defined in: src/tswp/textstorage.ts:674
Restore the phantom-paragraph invariant: a text ending with a terminator carries a paragraph-style entry at text.length for the empty paragraph the app draws there (31 of 31 corpus body storages; the entry names no style). Pages refuses a file with the terminator and no entry. Idempotent; a no-op when the text ends mid-paragraph.
Returns
void
fillPlaceholder()
fillPlaceholder(
placeholder,text):object
Defined in: src/tswp/textstorage.ts:1662
Fill a placeholder: put real text in its span and shed the placeholder marking, which is what typing into one does in Pages. The replacement keeps the placeholder's styling — a template styles its ghost text the way the final content should look. Returns the filled span.
Address the placeholder by its fieldId — the id placeholders reports, passed bare or on the listing's own entry — and the span is resolved live at this call: filling several from one listing lands each in its own field no matter how earlier fills moved the text. A filled or removed field throws rather than editing whatever text now occupies its old offsets. An entry carrying only start/end keeps positional meaning, offsets against the text as it is now.
Parameters
placeholder
bigint | { end: number; fieldId?: bigint; start: number; }
text
string
Returns
object
end
end:
number
start
start:
number
find()
find(
pattern):TextRange[]
Defined in: src/tswp/textstorage.ts:1032
Find matches as fluent ranges (string = literal; RegExp honored with /g).
Parameters
pattern
string | RegExp
Returns
footnotes()
footnotes():
object[]
Defined in: src/tswp/textstorage.ts:1754
Footnotes/endnotes anchored in this storage (their text is editable).
Returns
object[]
insertAttachment()
insertAttachment(
pos,objectId):void
Defined in: src/tswp/textstorage.ts:1313
Put an existing attachment archive at pos.
Inserts the U+FFFC placeholder through replaceRange, so every other attribute table shifts with it, then anchors the attachment at the new character. Doing it the other way round leaves the entry pointing one character short.
Parameters
pos
number
objectId
bigint
Returns
void
insertDateField()
insertDateField(
pos,text,options?):bigint
Defined in: src/tswp/textstorage.ts:1530
Insert a live date field showing text.
Unlike a page number, a date field spans real characters: the text is in the storage and the app rewrites it when the field updates. So the text to show is supplied rather than rendered here — formatting a date the way a given locale and pattern would is Foundation's job, and approximating it would put subtly wrong text in the document. The field is marked as needing an update, so the app replaces it with its own rendering at the first opportunity.
Parameters
pos
number
text
string
options?
DateFieldOptions = {}
Returns
bigint
insertLink()
insertLink(
start,end,url,options?):bigint
Defined in: src/tswp/textstorage.ts:1118
Make [start, end) a hyperlink. Creates a TSWP.HyperlinkFieldArchive in this storage's component and spans it in the smart-field table.
The link also gets the document's Link character style — identifier character-style-hyperlink, name "Link", property bag {underline: 1} in every native Pages fixture that carries links, and shipped by every template in the corpus. The hyperlink works without it (the first in-app check clicked through fine) and does not look like one: the field makes it live, the style makes it underlined.
characterStyle overrides the convention: a style id or identifier applies that style instead; false leaves the run unstyled — the text keeps whatever formatting it had.
Parameters
start
number
end
number
url
string
options?
characterStyle?
string | bigint | false
Returns
bigint
insertPageCount()
insertPageCount(
pos,options?):bigint
Defined in: src/tswp/textstorage.ts:1301
Insert a live page count — "of 12" — at pos.
Parameters
pos
number
options?
Returns
bigint
insertPageNumber()
insertPageNumber(
pos,options?):bigint
Defined in: src/tswp/textstorage.ts:1292
Insert a live page number (or page count) at pos.
A page number is not text: no digits exist in the storage, because the value depends on pagination the app performs. What is inserted is a U+FFFC placeholder plus an attachment archive that renders it — which is why this cannot simply be insertText("1").
Returns the attachment's object identifier. Nothing here computes the number; the app fills it in when it lays the document out.
Parameters
pos
number
options?
Returns
bigint
insertText()
insertText(
pos,text):void
Defined in: src/tswp/textstorage.ts:686
Parameters
pos
number
text
string
Returns
void
links()
links():
object[]
Defined in: src/tswp/textstorage.ts:1091
Hyperlink runs in this storage.
Returns
object[]
listStyleIdAt()
listStyleIdAt(
paragraphIndex):bigint|undefined
Defined in: src/tswp/textstorage.ts:1058
Effective list-style object id of a paragraph.
Parameters
paragraphIndex
number
Returns
bigint | undefined
normalizeTail()
normalizeTail():
boolean
Defined in: src/tswp/textstorage.ts:831
Delete a final trailing \n terminator so the text ends the way typed text does — bare, with no empty paragraph drawn after the last line. The phantom paragraph's table entries go with it and any character-style run or smart field ending at the old terminator stays closed exactly where its text ends.
Idempotent. A no-op on empty text, a bare tail, or a tail ending with a section, layout or page break — those characters carry structure this call must not remove, and no corpus storage ends with one (all 32 terminator-ending tails are U+000A). Returns whether a terminator was removed.
Returns
boolean
objectRuns()
objectRuns(
tableField,textLength?):StyleRun[]
Defined in: src/tswp/textstorage.ts:340
Decode an object table into runs. objectId undefined covers both "no attribute" and "continues previous" — for paragraph-aligned tables the effective value carries forward (see paragraphValues).
Parameters
tableField
number
textLength?
number = ...
Returns
StyleRun[]
offsetsStableSince()
offsetsStableSince(
revision,end):boolean
Defined in: src/tswp/textstorage.ts:252
True when every edit made after revision began at or after end.
Parameters
revision
number
end
number
Returns
boolean
ownStyleNameOf()
ownStyleNameOf(
styleId):string|undefined
Defined in: src/tswp/textstorage.ts:1017
The name written on this style object itself — undefined for the anonymous style direct formatting creates. Use it to tell "styled as Heading" from "styled as Heading, then modified here".
Parameters
styleId
bigint
Returns
string | undefined
pageNumberFields()
pageNumberFields():
NumberAttachmentInfo&object[]
Defined in: src/tswp/textstorage.ts:1509
Page-number and page-count fields in this storage, with their formats.
Returns
NumberAttachmentInfo & object[]
paragraph()
paragraph(
index):ParagraphHandle
Defined in: src/tswp/textstorage.ts:1027
Fluent handle for one paragraph.
Parameters
index
number
Returns
paragraphDirection()
paragraphDirection(
paragraphIndex):"ltr"|"rtl"|"natural"
Defined in: src/tswp/textstorage.ts:1572
A paragraph's base writing direction, from the storage's bidi table (table_para_bidi): the run-anchored entry pair whose first slot is the direction — 0 LTR, 1 RTL, 65535 natural — with the second slot 0, or 65535 when the first is natural. The paragraph style plays no part; the app writes only this pair when a paragraph is flipped.
Parameters
paragraphIndex
number
Returns
"ltr" | "rtl" | "natural"
paragraphs()
paragraphs():
ParagraphInfo[]
Defined in: src/tswp/textstorage.ts:312
Returns
paragraphStarts()
paragraphStarts(
text?):number[]
Defined in: src/tswp/textstorage.ts:303
UTF-16 offsets where paragraphs begin. Always includes 0 for non-empty text.
Parameters
text?
string = ...
Returns
number[]
placeholders()
placeholders():
object[]
Defined in: src/tswp/textstorage.ts:1631
Placeholder text runs — a template's "tap or click to add …" spans, which the app selects whole on a click and replaces on the first keystroke (TSWP.PlaceholderSmartFieldArchive).
Returns
object[]
range()
range(
start,end):TextRange
Defined in: src/tswp/textstorage.ts:1022
A live fluent handle over [start, end).
Parameters
start
number
end
number
Returns
removeAttachment()
removeAttachment(
objectId):boolean
Defined in: src/tswp/textstorage.ts:1500
Remove an attachment and the placeholder character it occupies.
What goes here is the character and the table entry, which is what makes the field disappear from the text. The archives it left behind — for an image, the drawable and its attachment — are reclaimed by IWorkDocument.compact(), which collects whatever the document no longer reaches. The image bytes stay: a Data/ file's link to its object is not something this library can safely trace, so nothing collects one (see docs/BLOCKERS.md).
Parameters
objectId
bigint
Returns
boolean
removeBookmark()
removeBookmark(
fieldId):boolean
Defined in: src/tswp/textstorage.ts:1727
Remove a bookmark. The text it marked stays.
Parameters
fieldId
bigint
Returns
boolean
removeComment()
removeComment(
commentStorageId):boolean
Defined in: src/tswp/textstorage.ts:1841
Detach a comment. The commented text stays; the highlight goes.
The archives are left in the package, as everywhere else here — what makes the comment disappear is the text no longer pointing at it.
Parameters
commentStorageId
bigint
Returns
boolean
removeFootnote()
removeFootnote(
noteStorageId):boolean
Defined in: src/tswp/textstorage.ts:1473
Remove a footnote: its reference character goes, and with it the note.
Takes the note storage's identifier, which is what footnotes reports. The archives stay in the package; what removes the footnote is the body no longer referencing it.
Parameters
noteStorageId
bigint
Returns
boolean
removeLinks()
removeLinks(
start,end):number
Defined in: src/tswp/textstorage.ts:1176
Remove any hyperlink overlapping [start, end); the text is untouched.
Parameters
start
number
end
number
Returns
number
replaceAll()
replaceAll(
find,replace):number
Defined in: src/tswp/textstorage.ts:729
Literal find/replace across the storage. Returns replacement count.
Parameters
find
string
replace
string
Returns
number
replaceRange()
replaceRange(
start,end,replacement):void
Defined in: src/tswp/textstorage.ts:453
Replace [start, end) with replacement, fixing up every attribute table. Offsets are UTF-16 code units (plain JS string indexes).
Parameters
start
number
end
number
replacement
string
Returns
void
resolveStyle()
resolveStyle(
style,type):bigint
Defined in: src/tswp/textstorage.ts:977
Resolve a style given by name (searched in the sheet chain) or id.
Parameters
style
string | bigint
type
number
Returns
bigint
setCharacterStyleRange()
setCharacterStyleRange(
start,end,styleId):void
Defined in: src/tswp/textstorage.ts:860
Apply (or clear, with undefined) a character-style object over a range. The previous effective style resumes at end.
A range ending at text.length writes no resume entry — no corpus storage (0 of 2896) carries a character-table entry at text.length, so the run is left open there. appendParagraph closes it when it next extends the text, keeping the styled range at exactly [start, end).
Parameters
start
number
end
number
styleId
bigint | undefined
Returns
void
setListStyle()
setListStyle(
paragraphIndex,styleId):void
Defined in: src/tswp/textstorage.ts:1067
Set the list style of a paragraph (see also PagesDocument.setListStyle).
Parameters
paragraphIndex
number
styleId
bigint | undefined
Returns
void
setParagraphDirection()
setParagraphDirection(
paragraphIndex,direction):void
Defined in: src/tswp/textstorage.ts:1588
Set a paragraph's base writing direction, writing the same pair the app writes when the direction control flips a paragraph: (1, 0) for RTL, (0, 0) for LTR, (65535, 65535) for natural. Every paragraph gets its own entry so no run bleeds into a neighbour, with existing values carried.
Parameters
paragraphIndex
number
direction
"ltr" | "rtl" | "natural"
Returns
void
setParagraphStyle()
setParagraphStyle(
paragraphIndex,styleId):void
Defined in: src/tswp/textstorage.ts:838
Set (or clear) the paragraph style of one paragraph.
Parameters
paragraphIndex
number
styleId
bigint | undefined
Returns
void
setParagraphTableValue()
setParagraphTableValue(
tableField,paragraphIndex,styleId):void
Defined in: src/tswp/textstorage.ts:1072
Set one paragraph's value in any paragraph-aligned object table.
Parameters
tableField
number
paragraphIndex
number
styleId
bigint | undefined
Returns
void
setText()
setText(
text):void
Defined in: src/tswp/textstorage.ts:724
Replace the storage's whole text, keeping run structure where possible.
Parameters
text
string
Returns
void
sheet()
sheet():
StylesheetModel|undefined
Defined in: src/tswp/textstorage.ts:970
The stylesheet governing this storage, if resolvable.
Returns
StylesheetModel | undefined
smartFields()
smartFields():
object[]
Defined in: src/tswp/textstorage.ts:1219
All smart-field runs (hyperlinks, page numbers, dates, bookmarks, merge fields, TOC fields, …). kind is the registry name of the field archive so callers can switch on it without importing type IDs.
Returns
object[]
spanObject()
spanObject(
tableField,start,end,objectId):void
Defined in: src/tswp/textstorage.ts:1188
Span an object over [start, end) in a character-run object table.
Parameters
tableField
number
start
number
end
number
objectId
bigint | undefined
Returns
void
styleNameOf()
styleNameOf(
styleId):string|undefined
Defined in: src/tswp/textstorage.ts:999
UI name of a style object — the name the app's style panel shows.
Direct formatting parents a paragraph on an anonymous child of the named style, so the applied object usually carries no name of its own: 644 of 2093 corpus paragraphs sit on such a style, and every one of the 644 has a named ancestor (one fixture's every paragraph does). The name therefore resolves up the parent chain, which is what makes a directly formatted heading still read as "Heading" — and still be collected by a table of contents, which matches on the named style.
ownStyleNameOf answers the literal question instead.
Parameters
styleId
bigint
Returns
string | undefined
tablePositionViolation()
tablePositionViolation(): {
position:number;table:string; } |undefined
Defined in: src/tswp/textstorage.ts:1872
The first attribute-table entry outside its lawful positions, if any.
The law, measured across the corpus's 2921 storages: no entry sits past text.length in any table, and an entry at exactly text.length occurs only in the paragraph-family tables — and only when a final empty paragraph exists to describe: empty text, or text ending with a terminator. The character-content tables (character styles, smart fields, anchors, language runs) leave a run reaching the end of the text open instead.
Returns
{ position: number; table: string; } | undefined