Lists and numbering

Create lists, attach paragraphs, configure nine levels, choose markers, and restart numbering.

A List groups paragraphs by their numbering definition within a body story. Use Body.lists to discover existing lists, or Paragraph.startNewList() to create one. List levels use zero-based indexes from 0 through 8.

Create a runtime with Runtime and setup. Use context and document proxies inside runtime.run().

Create and configure a list

Sync after paragraph and list creation before configuring their returned objects:

await runtime.run(async (context) => {
  const first = context.document.body.insertParagraph('Review contract', 'End');
  await context.sync();
  const list = first.startNewList();
  await context.sync();

  list.setLevelNumbering(0, 'Arabic', [0, '.']);
  list.setLevelStartingNumber(0, 1);
  list.setLevelIndents(0, 36, -18);
  await context.sync();

  const second = list.insertParagraph('Approve changes', 'End');
  await context.sync();
  second.listItem.level = 0;
  await context.sync();
});

A new list starts as an independent bullet list and defines all nine levels. List.insertParagraph(text, location) accepts Start, End, Before, and After. Before and After insert inside the list, at its first or last position. Use Paragraph.insertParagraph() to create content outside the list. The returned paragraph requires sync before dependent work.

Discover and join existing lists

ListCollection exposes items, getFirst(), and getById(id). Load a list's id before using its numeric value. List.paragraphs returns all its paragraphs. List.getLevelParagraphs(level) returns the paragraphs at one level. Load collection items, then load their text or formatting properties.

To attach an existing paragraph, pass a loaded list ID and defined level:

const list = context.document.body.lists.getFirst();
list.load('id');
await context.sync();
paragraph.attachToList(list.id, 1);
await context.sync();

Paragraph.attachToList(listId, level) returns the addressed List. Paragraph.detachFromList() removes that paragraph's list membership. Paragraph.list returns its existing list. If the paragraph has no list, the operation fails with InvalidArgument. Paragraph.listItem.level reads or writes its level. Existing lists can omit levels. The runtime rejects assignments to a missing level. There is no marker-text listString or siblingIndex property in this subset.

Choose level markers

MethodArguments and behavior
setLevelBullet(level, listBullet, charCode?, fontName?)Select a built-in bullet, or supply a custom Unicode character and font
setLevelNumbering(level, listNumbering, formatString?)Choose numbering and an optional array of text and level references
setLevelStartingNumber(level, startingNumber)Set this list instance's starting counter
setLevelIndents(level, textIndent, bulletNumberPictureIndent)Set point measurements; the second indent is relative to the text indent

ListBullet provides Custom, Solid, Hollow, Square, Diamonds, Arrow, and Checkmark. A custom bullet requires a Unicode character code. For example, list.setLevelBullet(0, 'Custom', 0x2022, 'Calibri') uses a bullet in Calibri. The rendering or pagination host must provide that font. Picture bullets are unavailable.

ListNumbering provides None, Arabic, UpperRoman, LowerRoman, UpperLetter, and LowerLetter. Numeric entries in formatString reference zero-based levels. For example, [0, '.', 1, ')'] combines level counters with literal punctuation. The runtime validates level references and counters and rejects unsupported values.

Respect batching and tracking limits

Changes to one list level coalesce on its list proxy within a sync. Changes to different levels can share a sync after list creation completes. Compatible level assignments and paragraph attachments can join that batch. Different proxies that write the same list level still conflict. Structural changes sharing a paragraph can also conflict. Sync list creation before attaching paragraphs or changing level properties.

The runtime rejects list creation and formatting while tracking changes. Edits to protected paragraphs and unsupported numbering structures also fail. The runtime rejects formatting for numbering instances shared across stories, such as the main body and notes. It also rejects instances referenced by styles, including unused styles, because inherited membership can affect protected paragraphs. On a conflict, read the document again before separating the proposed operations. Do not remove existing numbering structure to force a write.

Next steps

See Formatting and styles, Fields and pagination, and API member directory.

On this page