2.4.6.3 Determining List Formatting of a Paragraph

A list in an MS-DOC file consists of one or more paragraphs. Each paragraph in a list has a nonzero iLfo property (see sprmPIlfo) and an iLvl property (see sprmPIlvl), which are used to determine the information that is necessary to format the paragraph as a member in a specific list. Paragraphs that share the same iLfo property, and exist in a range of text that constitutes a Valid Selection, are considered to be part of the same list. Paragraphs in a list do not need to be consecutive, and a list can overlap with other lists. This section describes an algorithm to add list formatting to a paragraph containing a given character position.

Given character position cp, use the following three-part algorithm to add list formatting to the paragraph containing cp.

Part 1

  1. Follow the procedure for determining formatting properties, as specified in section 2.4.6.6, to find the paragraph properties for the paragraph that cp belongs to.

  2. Let iLfoCur and iLvlCur be the iLfo (see sprmPIlfo) and iLvl (see sprmPIlvl) properties of the paragraph, respectively. If iLfoCur is zero, the paragraph is not part of a list, and the algorithm ends.

  3. Let lfo be the LFO at PlfLfo.rgLfo[iLfoCur -1]. If there is no such LFO, the file is invalid and the algorithm ends.

  4. Let lstf be the LSTF in PlfLst.rgLstf such that lstf.lsid equals lfo.lsid. If there is no such LSTF, the file is invalid and the algorithm ends.

  5. Let lfodata be the LFOData at PlfLfo.rgLfoData[iLfoCur -1].

  6. Let lfolvl be the LFOLVL in lfodata.rgLfoLvl such that lfolvl.iLvl equals iLvlCur, if such an LFOLVL exists. If there is no such LFOLVL, go to part 1 step 8.

  7. If lfolvl.fFormatting is nonzero, let lvl be lfolvl.lvl and go to part 2 step 1.

  8. Let i be 0. For each LSTF in PlfLst.rgLstf prior to lstf, if LSTF.fSimpleList is zero, let i = i + 9, if LSTF.fSimpleList is nonzero, let i be i + 1.

  9. Let i be i + iLvlCur.

  10. Let lvl be the ith LVL in the array of LVLs appended to PlfLst (see the fcPlfLst field of FibRgFcLcb97).

Part 2

After the lstf and lvl are determined, the next step is to determine the number text of the paragraph.

  1. Let xstNumberText be a copy of lvl.xst.

  2. If lvl.lvlf.nfc is not equal to 0x17, go to part 2 step 4. If lvl.lvlf.nfc is equal to 0x17, the paragraph is in a bulleted level.

  3. Let xchBullet be the 16-bit character at xstNumberText.rgtchar[0]. If xchBullet & 0xF000 is nonzero, let xstNumberText.rgtchar[0] equal xchBullet & 0x0FFF. Go to part 3 step 1.

  4. For each entry j in lvl.lvlf.rgbxchNums such that lvl.lvlf.rgbxchNums[j] is nonzero, let iLvlTemp be the 16-bit integer stored at lvl.xst.rgtchar[lvl.lvlf.rgbxchNums[j] - 1]. If iLvlTemp == iLvlCur, replace the iLvlTemp placeholder in xstNumberText with the level number of the current paragraph. If iLvlTemp < iLvlCur, replace the iLvlTemp placeholder in xstNumberText with the level number of the closest previous paragraph in the list that has an iLvl property that equals iLvlTemp. If iLvlTemp > iLvlCur, the file is invalid and the algorithm ends. If lvl.lvlf.fLegal is nonzero, each of these level numbers MUST be reformatted as according to the fLegal field description in LVLF before they replace their respective placeholders.

Part 3

After the number text of the paragraphs is determined, the final step is to format the paragraph and the number text.

  1. If lstf.rgistdPara[iLvlCur] != 0x0FFF, apply the style specified by lstf.rgistdPara[iLvlCur] to both the paragraph and xstNumberText.

  2. Apply the character properties specified by lvl.grpprlChpx to xstNumberText.

  3. Append the character specified by lvl.lvlf.ixchFollow to xstNumberText. xstNumberText is now the number text that will be displayed at the beginning of the paragraph.

  4. Apply the paragraph properties specified by lvl.grpprlPapx to the paragraph, including xstNumberText.

  5. Justify only the xstNumberText according to the justification specified by lvl.lvlf.jc.

The paragraph is now formatted as part of a list.