Skip to content

Adding low-level support for numbering styles. #582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

jlovegren0
Copy link

This PR addresses the issue with numbering styles identified on StackOverflow and issues #25 and #122 .

My proposal does not add API support for these issues, but it makes it easier to handle work-arounds for users who are familiar with the numbering system from ISO 29500.

Basically, I just define the following types in the oxml submodule:

CT_NumPicBullet
CT_AbstractNum
CT_LongHexNumber
ST_LongHexNumber
CT_MultiLevelType
ST_MultiLevelType
CT_Lvl
CT_NumFmt
ST_NumberFormat
CT_LevelSuffix
ST_LevelSuffix
CT_LevelText
CT_LvlLegacy
CT_Num

Once these are defined, and the appropriate declarations are added to oxml.__init__ so that the parser can recognize them, a user can use the methods exposed by the xmlchemy submodule.

The maintainer has commented in the past that that lag on creating support for numbering is that the standard itself is very byzantine (I agree 100%) and there are some tough design choices for crafting the API. My PR is basically setting up some very low-level support so that more capable developers can look into addressing this within the API.

I have no experience with Open Source projects so I will need help from other community members for qa/qc and testing of the code. However, I have added a detailed write-up to the documentation (contributor guide, numbering section). I'll also be posting a solution to the SE question.

@LilyDreamZhao
Copy link

I cannot understand your meaning,can you give some example?

@jlovegren0
Copy link
Author

jlovegren0 commented Dec 6, 2018

I cannot understand your meaning,can you give some example?

@LilyDreamZhao there's a good example on StackOverflow of the kind of problem that my PR addresses.
https://stackoverflow.com/questions/23446268

Basically, the xmlchemy submodule makes it easy to add and manipulate XML elements, but it requires that the element types be pre-defined. So, for example, the master branch will parse the <w:abstractNum> tag, but it doesn't understand that it's of type CT_AbstractNum, so it's very difficult to make any changes to it within the API. And you need to make changes to it in order to handle numbered and bulleted lists properly.

@Clorel
Copy link

Clorel commented Feb 19, 2020

It's a good PR but the example file code, doesn't work with your branch.
I don't look numbering.xml for the adding AbstractNum OxmElement but the result is not good :
image

@nitinkhosla79
Copy link

@jlovegren0 Do you know if scanny has reviewed this or plans on merging this PR?
@scanny

@jlovegren0
Copy link
Author

jlovegren0 commented Mar 26, 2020 via email

@nitinkhosla79
Copy link

I haven't had any contact with him about it. I think he hasn't had time for the project lately, and my PR would take a bit of study to decide on merging it. Hopefully it gets some attention in the future.

On Thu, Mar 26, 2020 at 12:15:23PM -0700, nitinkhosla79 wrote: @jlovegren0 Do you know if scanny has reviewed this or plans on merging this PR? @scanny -- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: #582 (comment)
-- Jesse Lovegren

@scanny Can you advise on this PR and what all is needed? We can help with testing/regression tests and if anything else is needed, please advise.

@nitinkhosla79
Copy link

It's a good PR but the example file code, doesn't work with your branch.
I don't look numbering.xml for the adding AbstractNum OxmElement but the result is not good :
image

@jlovegren0 Do you have a working example to try? Can you please comment on the observation by @Clorel ?

@Clorel
Copy link

Clorel commented Mar 28, 2020

the example comes from the last post on this topic : https://stackoverflow.com/questions/23446268
I have solved the problem with insert the numbering on the template file docx and manage in low level API the abstractNum/Numbering index with a constant hash index.

@nitinkhosla79
Copy link

the example comes from the last post on this topic : https://stackoverflow.com/questions/23446268
I have solved the problem with insert the numbering on the template file docx and manage in low level API the abstractNum/Numbering index with a constant hash index.

@Clorel Great to hear! Are you saying that you are able use this API (in this PR and) made further edits to make it work? Would you be able to describe those or add here if @jlovegren0 is ok with that?

@Clorel
Copy link

Clorel commented Mar 28, 2020

sorry, not this API, the default API from python docx, with the example function "list_number" from : #25.
I don't search why my example doesn't work because ... i didn't understand what these abstractnum were and deadline...

@nitinkhosla79
Copy link

sorry, not this API, the default API from python docx, with the example function "list_number" from : #25.
I don't search why my example doesn't work because ... i didn't understand what these abstractnum were and deadline...

@Clorel We tried that and that is not working for us. Infact, if the document is opened in libreoffice it shows nested list correctly but in word, it shows in 1 sequence. What change did you make there?

@nitinkhosla79
Copy link

"manage in low level API the abstractNum/Numbering index with a constant hash index"
@Clorel Constant hash index - can you elaborate a bit or share a code snipped for same?

@jlovegren0
Copy link
Author

jlovegren0 commented Mar 29, 2020 via email

@nitinkhosla79
Copy link

nitinkhosla79 commented Mar 29, 2020

@jlovegren0 can you check section 17.9(in particular 17.9.10) in latest iso 29500 version - latest release in Feb 2020.
https://interoperability.blob.core.windows.net/files/MS-OI29500/%5bMS-OI29500%5d.pdf
There are few references on when restart will be ignored.

@Clorel
Copy link

Clorel commented Mar 29, 2020

`def set_numbering(doc, par, prev=None, num_fmt_style='none', level=0, suffix_text='%1)', int_start=None):
# https://stackoverflow.com/questions/23446268/python-docx-how-to-restart-list-lettering
# #852

# \!/ USE TEMPLATE NUMBERING.XML EMBEDDED FOR DONT NEED TO CREATE ABSTRACTNUM \!/
# use list_number for default use (abstract 0-9 single bullet and decimal %1.)

# API Low Level with numbering // abstractNum map embedded because can't create abstractNum with python-docx
# Use the map from template for take NumID.
# We need to wait ISSUE #852 integration on PYTHON-DOCX for a best integration

# Get numbering style enum
# https://docs.microsoft.com/fr-fr/dotnet/api/microsoft.office.interop.word.wdnotenumberstyle?view=word-pia

"""
    Function like Issue #25

    Parameters
    ----------
    doc : docx.document.Document
        The document to add the list into.
    par : docx.paragraph.Paragraph
        The paragraph to turn into a list item.
    prev : docx.paragraph.Paragraph or None
        The previous paragraph in the list. If specified, the numbering
        and styles will be taken as a continuation of this paragraph.
        If omitted, a new numbering scheme will be started.
    num_fmt_style : style of numbering (bullet, none, decimal, lowerRoman, upperRoman, lowerLetter, upperLetter,
    level : int
        The level of the paragraph within the outline. If ``prev`` is
        set, defaults to the same level as in ``prev``. Otherwise,
        defaults to zero.
    suffix_text : suffix of numbering " %1. or %1) "
    int_start : optionnal, if your reset numbering not starting by 1, you can submit your starting override
    """

def get_abstract_id_from_map_embedded(num_fmt, level_numbering, suffix):
    # Default 0-9 (use is single level if you don't want never reset/restart element count)
    # 0 abstractNum SingleLevel Decimal %1. Indent 5 Lvl 0
    # 1 abstractNum SingleLevel Decimal %1. Indent 4 Lvl 0
    # 2 abstractNum SingleLevel Decimal %1. Indent 3 Lvl 0
    # 3 abstractNum SingleLevel Decimal %1. Indent 2 Lvl 0
    # 4 abstractNum SingleLevel Bullet * Indent 4 Lvl 0
    # 5 abstractNum SingleLevel Bullet * Indent 3 Lvl 0
    # 6 abstractNum SingleLevel Bullet * Indent 2 Lvl 0
    # 7 abstractNum SingleLevel Decimal %1. Indent 1 Lvl 0
    # 8 abstractNum SingleLevel Bullet * Indent 1 Lvl 0

    # Embedded AbstractNum
    # 9 abstractNum multilevel upperRoman %N) Indent/Lvl * N
    # 10 abstractNum multilevel decimal %N. Indent/Lvl * N
    # 11 abstractNum multilevel decimal %N Indent/Lvl * N
    # 12 abstractNum multilevel decimal %N) Indent/Lvl * N

    # 13 abstractNum multilevel lowerLetter %N) Indent/Lvl * N
    # 14 abstractNum multilevel upperLetter %N) Indent/Lvl * N
    # 15 abstractNum multilevel upperLetter %N. Indent/Lvl * N
    # 16 abstractNum multilevel Hybrid from Personnal Use
    # 17 abstractNum multilevel Hybrid from Personnal Use (2 with true bullet word)

    # 18 abstractNum multilevel upperRoman %N. Indent/Lvl * N
    # 19 abstractNum multilevel lowerLetter %N. Indent/Lvl * N
    # 20 abstractNum multilevel lowerRoman %N. Indent/Lvl * N
    # 21 abstractNum multilevel lowerRoman %N) Indent/Lvl * N
    # 22 abstractNum multilevel Bullet * Indent/Lvl * N
    # 23 abstractNum multilevel none %N Indent/Lvl * N

    key_abstract_num = int()
    if num_fmt in ['lowerRoman', 'upperRoman', 'lowerLetter', 'upperLetter']:
        is_default_suffix = True
        if suffix != '%1)':
            is_default_suffix = False

        # Mapping
        if num_fmt == 'lowerRoman':
            if is_default_suffix is True:
                key_abstract_num = 21
            else:
                key_abstract_num = 20
        elif num_fmt == 'upperRoman':
            if is_default_suffix is True:
                key_abstract_num = 9
            else:
                key_abstract_num = 18
        elif num_fmt == 'lowerLetter':
            if is_default_suffix is True:
                key_abstract_num = 13
            else:
                key_abstract_num = 19
        elif num_fmt == 'upperLetter':
            if is_default_suffix is True:
                key_abstract_num = 15
            else:
                key_abstract_num = 14
    elif num_fmt == 'bullet':
        key_abstract_num = 22
        """
        # (restart never)
        # default embedded template from python-docx 
        if 0 <= level_numbering <= 3:
            # use singleLevel AbstractNum
            if level_numbering == 0:
                key_abstract_num = 8
            elif level_numbering == 1:
                key_abstract_num = 6
            elif level_numbering == 2:
                key_abstract_num = 5
            else:
                key_abstract_num = 4
        else:
            # use default Personnal use style for indent the rest
            key_abstract_num = 20
        """
    elif num_fmt == 'decimal':
        if suffix == '%1':
            key_abstract_num = 11
            """
            # (restart never)
            # default embedded template from python-docx
            if 0 <= level_numbering <= 4:
                # use singleLevel AbstractNum
                if level_numbering == 0:
                    key_abstract_num = 7
                elif level_numbering == 1:
                    key_abstract_num = 3
                elif level_numbering == 2:
                    key_abstract_num = 2
                elif level_numbering == 3:
                    key_abstract_num = 1
                else:
                    key_abstract_num = 0
            else:
                # use default Personal Use style for indent the rest
                key_abstract_num = 20
            """
        elif suffix == '%1)':  # Default suffix
            key_abstract_num = 12
        else:
            key_abstract_num = 10

    elif num_fmt == 'defaultPersonalUse':
        # defaultPersonalUse style
        key_abstract_num = 17
    elif num_fmt == 'none':
        # None style
        key_abstract_num = 23
    else:
        key_abstract_num = 22

    return key_abstract_num

# Reset list with new numId if need it
if (prev is None or
        prev._p.pPr is None or
        prev._p.pPr.numPr is None or
        prev._p.pPr.numPr.numId is None):

    numbering = doc.part.numbering_part.numbering_definitions._numbering
    # Compute the abstract ID first by style, then by num
    i_num = get_abstract_id_from_map_embedded(num_fmt_style, level, suffix_text)

    # Set the concrete numbering based on the abstract numbering ID
    num = numbering.add_num(i_num)

    # Define the new beginning of numbering count (Default 1)
    int_start_override = 1
    if int_start is not None:
        int_start_override = int_start

    # Make sure to override the abstract continuation property
    num.add_lvlOverride(ilvl=level).add_startOverride(int_start_override)

    # Extract the newly-allocated concrete numbering ID
    num = num.numId
else:
    # Get the previous concrete numbering ID
    num = prev._p.pPr.numPr.numId.val

par._p.get_or_add_pPr().get_or_add_numPr().get_or_add_numId().val = num
par._p.get_or_add_pPr().get_or_add_numPr().get_or_add_ilvl().val = level

pass`

and the xml content embedded :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14"> <w:abstractNum w:abstractNumId="0" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF7C"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="C310EC42"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1800"/> </w:tabs> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="1" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF7D"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="E4089024"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1440"/> </w:tabs> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="2" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF7E"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="FB12693A"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber3"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1080"/> </w:tabs> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="3" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF7F"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="38441652"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber2"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="720"/> </w:tabs> <w:ind w:left="720" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="4" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF81"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="171AC3A4"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1440"/> </w:tabs> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="5" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF82"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="F3EAFDEC"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet3"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1080"/> </w:tabs> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="6" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF83"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="3D1EFFD4"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet2"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="720"/> </w:tabs> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="7" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF88"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="D0A62B40"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="360"/> </w:tabs> <w:ind w:left="360" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="8" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="FFFFFF89"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="29761A62"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="360"/> </w:tabs> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="9" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="0C647DA1"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="59BA9FDA"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%2)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%4)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%5)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%6)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%7)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%8)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%9)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="10" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="13753292"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="BCA24D4E"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%2."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%3."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%4."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%5."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%6."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%7."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%8."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%9."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="11" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="1A5A15D8"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="5C5242CE"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%2"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%3"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%4"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%5"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%6"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%7"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%8"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%9"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="12" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="257C4B1F"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="63DAFCC8"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%2)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%4)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%5)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%6)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%7)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%8)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%9)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="13" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="3B7F246B"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="96C6BA6C"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%2)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%4)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%5)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%6)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%7)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%8)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%9)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="14" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="3E46416B"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="51EC5CD2"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%2)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%4)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%5)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%6)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%7)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%8)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%9)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="15" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="51380F66"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="D7B24454"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%2."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%3."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%4."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%5."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%6."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%7."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%8."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="upperLetter"/> <w:lvlText w:val="%9."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="16" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="55196267"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="2FD0C538"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val="%2"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="357" w:hanging="357"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1077" w:hanging="357"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val="w"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Wingdings" w:hAnsi="Wingdings" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1797" w:hanging="357"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val="%7"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="17" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="5BB90EA0"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="98EAB322"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="18" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="5D9B56A1"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="F7F63982"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%2."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%3."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%4."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%5."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%6."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%7."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%8."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlText w:val="%9."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="19" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="615F4BDB"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="12162188"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%2."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%3."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%4."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%5."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%6."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%7."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%8."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="lowerLetter"/> <w:lvlText w:val="%9."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="20" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="62051C66"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="CD3624A8"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%2."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%3."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%4."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%5."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%6."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%7."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%8."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%9."/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="21" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="668A7C24"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="A0DA66B6"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%1)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%2)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%3)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%4)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%5)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%6)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%7)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%8)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="lowerRoman"/> <w:lvlText w:val="%9)"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="22" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="692B6527"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="02584028"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="23" w15:restartNumberingAfterBreak="0"> <w:nsid w:val="72101706"/> <w:multiLevelType w:val="multilevel"/> <w:tmpl w:val="FA98295A"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val="%1"/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="3"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="4"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="5"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2160" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="6"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2520" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="7"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="2880" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> <w:lvl w:ilvl="8"> <w:start w:val="1"/> <w:numFmt w:val="none"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:ind w:left="3240" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:num w:numId="1"> <w:abstractNumId w:val="8"/> </w:num> <w:num w:numId="2"> <w:abstractNumId w:val="6"/> </w:num> <w:num w:numId="3"> <w:abstractNumId w:val="5"/> </w:num> <w:num w:numId="4"> <w:abstractNumId w:val="4"/> </w:num> <w:num w:numId="5"> <w:abstractNumId w:val="7"/> </w:num> <w:num w:numId="6"> <w:abstractNumId w:val="3"/> </w:num> <w:num w:numId="7"> <w:abstractNumId w:val="2"/> </w:num> <w:num w:numId="8"> <w:abstractNumId w:val="1"/> </w:num> <w:num w:numId="9"> <w:abstractNumId w:val="0"/> </w:num> <w:num w:numId="10"> <w:abstractNumId w:val="12"/> </w:num> <w:num w:numId="11"> <w:abstractNumId w:val="10"/> </w:num> <w:num w:numId="12"> <w:abstractNumId w:val="9"/> </w:num> <w:num w:numId="13"> <w:abstractNumId w:val="18"/> </w:num> <w:num w:numId="14"> <w:abstractNumId w:val="20"/> </w:num> <w:num w:numId="15"> <w:abstractNumId w:val="21"/> </w:num> <w:num w:numId="16"> <w:abstractNumId w:val="14"/> </w:num> <w:num w:numId="17"> <w:abstractNumId w:val="15"/> </w:num> <w:num w:numId="18"> <w:abstractNumId w:val="19"/> </w:num> <w:num w:numId="19"> <w:abstractNumId w:val="13"/> </w:num> <w:num w:numId="20"> <w:abstractNumId w:val="23"/> </w:num> <w:num w:numId="21"> <w:abstractNumId w:val="16"/> </w:num> <w:num w:numId="22"> <w:abstractNumId w:val="22"/> </w:num> <w:num w:numId="23"> <w:abstractNumId w:val="17"/> </w:num> <w:num w:numId="24"> <w:abstractNumId w:val="11"/> </w:num> </w:numbering>

@nitinkhosla79
Copy link

@jlovegren0 Did you get a chance to review that section or if it gave you any clues on whether something is missing for level/restart conditions?

@jlovegren0
Copy link
Author

jlovegren0 commented Mar 29, 2020 via email

@jlovegren0
Copy link
Author

jlovegren0 commented Mar 30, 2020 via email

@komawar
Copy link

komawar commented Mar 31, 2020

@Clorel I work with @nitinkhosla79 on the python-docx stuff. we are trying your script and observe that this works correctly for nested numbering however, when using bullets (completely or partly) the nesting does not work. (the list shows up as single indent level list not nested)

have you faced this issue?
also, can you please elaborate further on how to incorporate your numbering.xml file in the script or when saving the file?
when I try to use it, error is shown that word is unable to read, please check contents of the file.

@komawar
Copy link

komawar commented Mar 31, 2020

@jlovegren0 (like the above comment) did you face any issue with bulleting or nested/hybridnested numbering+bulleting?

@nitinkhosla79
Copy link

@jlovegren0 Can you point out on why list_number(by @Clorel ) is working? Is it because his abstractnum definition has "multileveltype" defined as "multilevel"?
If you have any pointers on where should we focus on, we can dig deep and explore that area. If we can solve using your APIs it will be great.

@komawar
Copy link

komawar commented Apr 5, 2020

@komawar my library can also solve the Issue #25 that you mention, at least the initial question. Below is example code showing how you restart numbering for a specific paragraph. This is done by creating a new numbering style which is derived from the existing one, but which contains a lvlOverride element, directing which level to restart from. It doesn't have to be one. This could be wrapped up into a restart_numbering method, I suppose. The result renders properly in MS Word and google docs, but not LibreOffice. #!/usr/bin/python3 from docx import Document from docx import oxml import docx STYP = docx.enum.style.WD_STYLE_TYPE d = Document() """ 1. Make some text """ for x in [1, 2, 3]: d.add_paragraph("Item # %i" % x, style="List Number") d.add_paragraph("Some intervening text.") pnew = d.add_paragraph("Item # 4", style="List Number") d.add_paragraph("Item # 5", style="List Number") d.add_paragraph("Item # 6", style="List Number") """ 2. Look up the associated level and numbering style associated with the paragraph's style """ assocStyle = d.styles.get_by_id( pnew._element.pPr.pStyle.val , STYP.PARAGRAPH ).element.pPr.numPr try: assocLevel = assocStyle.ilvl.val except: assocLevel = 0 assocNumId = assocStyle.numId.val assocAbstractNumId = d.part.numbering_part.element.num_having_numId( assocNumId ).abstractNumId.val """ 3. Insert a new numbering definition with an override, then associate it to the paragraph """ newNum = d.part.numbering_part.element.add_num(assocAbstractNumId) newNum.add_lvlOverride(assocLevel).get_or_add_startOverride().val = 1 nn = pnew._element.pPr.get_or_add_numPr() nn.get_or_add_ilvl().val = assocLevel nn.get_or_add_numId().val = assocNumId d.save('test.docx')

On Thu, Apr 02, 2020 at 02:45:34PM +0000, Nikhil Komawar wrote: @jlovegren0 thanks for the script, it works great have you tried the numbering restart on custom/builtin styles? say for example we use document.add_paragraph(data, style="List Number") can we work with it's abstract num to set the restart counter? or do you rather work with setting <w:pStyle w:val="List Number"/> explicitly in the abstract num creation? (I am trying to find a way to be able to use custom styles and restart numbering) -- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: #582 (comment)
-- Jesse Lovegren

@jlovegren0 for this example (as it is), I am not seeing the restart in numbering and we have the numbering.xml without <w:multiLevelType w:val="multilevel"/>. Though this is working for you, which is why I was wondering if there was issue on my UA (possibly missing inherent multilevel styles)?

for this one:

attaching the py script and numXML as txt and the resulted docx on my system
and resulted docx
new 123.docx
numxml.xml.txt

html-to-docx.py.txt

@jlovegren0 I thought of sending a script that is more clear about the data and its levels being set.
I'm attaching the same here (multilevel with multiple indentations and restarts aren't happening

please find attached concerned files that demostrate the same
docx eg2.docx

docx-example2.py.txt

numbering.xml for the above:

<w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14"> <w:abstractNum w:abstractNumId="0"> <w:nsid w:val="FFFFFF7C"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="C310EC42"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1800"/> </w:tabs> <w:ind w:left="1800" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="1"> <w:nsid w:val="FFFFFF7D"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="E4089024"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1440"/> </w:tabs> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="2"> <w:nsid w:val="FFFFFF7E"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="FB12693A"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber3"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1080"/> </w:tabs> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="3"> <w:nsid w:val="FFFFFF7F"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="38441652"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber2"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="720"/> </w:tabs> <w:ind w:left="720" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="4"> <w:nsid w:val="FFFFFF81"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="171AC3A4"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1440"/> </w:tabs> <w:ind w:left="1440" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="5"> <w:nsid w:val="FFFFFF82"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="F3EAFDEC"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet3"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="1080"/> </w:tabs> <w:ind w:left="1080" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="6"> <w:nsid w:val="FFFFFF83"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="3D1EFFD4"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet2"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="720"/> </w:tabs> <w:ind w:left="720" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="7"> <w:nsid w:val="FFFFFF88"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="D0A62B40"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:pStyle w:val="ListNumber"/> <w:lvlText w:val="%1."/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="360"/> </w:tabs> <w:ind w:left="360" w:hanging="360"/> </w:pPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="8"> <w:nsid w:val="FFFFFF89"/> <w:multiLevelType w:val="singleLevel"/> <w:tmpl w:val="29761A62"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="bullet"/> <w:pStyle w:val="ListBullet"/> <w:lvlText w:val=""/> <w:lvlJc w:val="left"/> <w:pPr> <w:tabs> <w:tab w:val="num" w:pos="360"/> </w:tabs> <w:ind w:left="360" w:hanging="360"/> </w:pPr> <w:rPr> <w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/> </w:rPr> </w:lvl> </w:abstractNum> <w:abstractNum w:abstractNumId="9"> <w:multiLevelType w:val="multilevel"/> <w:lvl w:ilvl="0"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlRestart w:val="99"/> <w:lvlText w:val="%1"/> <w:suff w:val="tab"/> <w:pPr> <w:ind w:left="0"/> </w:pPr> </w:lvl> <w:lvl w:ilvl="1"> <w:start w:val="1"/> <w:numFmt w:val="decimal"/> <w:lvlRestart w:val="99"/> <w:lvlText w:val="%1.%2."/> <w:suff w:val="tab"/> <w:pPr> <w:ind w:left="720"/> </w:pPr> </w:lvl> <w:lvl w:ilvl="2"> <w:start w:val="1"/> <w:numFmt w:val="upperRoman"/> <w:lvlRestart w:val="99"/> <w:lvlText w:val="%1.%2.%3."/> <w:suff w:val="tab"/> <w:pPr> <w:ind w:left="1440"/> </w:pPr> </w:lvl> </w:abstractNum> <w:num w:numId="1"> <w:abstractNumId w:val="8"/> </w:num> <w:num w:numId="2"> <w:abstractNumId w:val="6"/> </w:num> <w:num w:numId="3"> <w:abstractNumId w:val="5"/> </w:num> <w:num w:numId="4"> <w:abstractNumId w:val="4"/> </w:num> <w:num w:numId="5"> <w:abstractNumId w:val="7"/> </w:num> <w:num w:numId="6"> <w:abstractNumId w:val="3"/> </w:num> <w:num w:numId="7"> <w:abstractNumId w:val="2"/> </w:num> <w:num w:numId="8"> <w:abstractNumId w:val="1"/> </w:num> <w:num w:numId="9"> <w:abstractNumId w:val="0"/> </w:num> <w:num w:numId="10"> <w:abstractNumId w:val="9"/> </w:num> </w:numbering>

@jlovegren0
Copy link
Author

@komawar I think the issue is that MS Word is not strictly adhering to the standard. It says the following about lvlRestart:

If this element is omitted, the numbering level shall restart each time the previous numbering level or any earlier level is used. If the specified level is higher than the current level, then this element shall be ignored. As well, a value of 0 shall specify that this level shall never restart.

So the default restarting behavior is obtained by simply omitting the element. In theory this is also possible by specifying a level higher than the current level. So you have "99," which should be valid. However, Word departs from this portion of the normative standard, according to [MS-OI29500]

2.1.282 Part 1 Section 17.9.10, lvlRestart (Restart Numbering Level Symbol)
a. The standard allows any integer for the value of lvlRestart.
Word only allows values between 0 and 7 for lvlRestart.

However, I tried entering "6" but still did not get predicatble behvior (LibreOffice seems to handle the issue fine). Anyways, the surest way to get default restart behvaior is to not specify lvlRestart. In the code below I show how you get default behavior for levels 1 and 2, but level 3 is set to restart only after an intervening level 1 paragraph. I have also simplified the code somewhat (note that you do not need my set_ilvl function once you tie the paragraph styles to the new numbering style).

import docx
from docx import Document
from docx.oxml import simpletypes


def test_data_to_docx():
    STYP = docx.enum.style.WD_STYLE_TYPE
    d = Document()

    numXML = d.part.numbering_part.element
    nextAbstractId = max([J.abstractNumId for J in numXML.abstractNum_lst]) + 1
    l = numXML._new_abstractNum()
    l.abstractNumId = nextAbstractId
    l.add_multiLevelType().val = 'multilevel'


    formats = {0: "decimal", 1: "decimal", 2: "upperRoman", }
    textFmts = {0: '%1', 1: '%1.%2.', 2: '%1.%2.%3.', }
    starts = {0: 1, 1: 1, 2: 1}
    restarts = {0: False, 1: False, 2: 1}
    hosts = {0: "List Number", 1: "List Number 2", 2: "List Number 3"}

    numXML.abstractNum_lst[-1].addnext(l)
    nNum = numXML.add_num(nextAbstractId)

    for i in range(3):
        lvl = l.add_lvl()
        lvl.ilvl = i
        lvl.add_start().val = starts[i]
        lvl.add_numFmt().val = formats[i]
        if ( restarts[i] ):
            lvl.add_lvlRestart().val = restarts[i]
        lvl.add_lvlText().val = textFmts[i]
        lvl.add_suff().val = "tab"
        pPr = lvl.add_pPr()
        pPr.ind_left = simpletypes.Twips(i * 720)
        ho = d.styles.get_by_id(d.styles.get_style_id(
            hosts[i], STYP.PARAGRAPH), STYP.PARAGRAPH).element.pPr.numPr
        ho.get_or_add_ilvl().val = i
        ho.get_or_add_numId().val = nNum.numId

    d.add_paragraph("Sample List")

    d.add_paragraph("First item", style="List Number")
    d.add_paragraph("First item from First item", style="List Number 2")
    d.add_paragraph("Second item from First item", style="List Number 2")
    d.add_paragraph("Second item", style="List Number")
    d.add_paragraph("First item from Second item", style="List Number 2")
    d.add_paragraph("First item from first item of Second item", style="List Number 3")
    d.add_paragraph("Second item from first item of Second item", style="List Number 3")
    d.add_paragraph("Second item from Second item", style="List Number 2")
    d.add_paragraph("First item from second item of Second item", style="List Number 3")
    d.add_paragraph("Second item from second item of Second item", style="List Number 3")
    d.add_paragraph("Third item from Second item", style="List Number 2")
    d.add_paragraph("Third item", style="List Number")
    d.add_paragraph("First item from Third item", style="List Number 2")
    d.add_paragraph("First item from first item of Third item", style="List Number 3")
    d.add_paragraph("Second item from Third item", style="List Number 2")

    d.save('docx_eg2.docx')


if __name__ == "__main__":
    test_data_to_docx()

@komawar
Copy link

komawar commented Apr 6, 2020

@jlovegren0 thanks a ton for this analysis!

Word seems a bit convoluted, but this explanation gives great clarity on the divergence

@komawar
Copy link

komawar commented Apr 8, 2020

@jlovegren0 hi again,
I have some questions around usage of abstractnumId (or reuse of the same):

we are trying to use custom style definitions that have color, font, txtFmt, ind, hanging, values. however, restarts, start and hanging aren't what's expected. so, I was trying to create new abstractnumId and new numId associated with them (which are then tied back to styles).

However, to get back all of the style information to new abstract num ID is quite complex. We have to manually get these values and copy them to the new abstract num ID definition

for example: right now I'm using

num_xml = d.part.numbering_part.numbering_definitions._numbering
    abs_num = None
    for j in num_xml.abstractNum_lst:
        if j.abstractNumId == abs_num_elem.abstractNumId:
            abs_num = j

st = lvl.add_start()
st.val = abs_num.get_or_add_lvl().get_or_add_start().val

...
...

lvl.add_lvlRestart().val = 1

Would be really great if:

  1. (Best) we are able to modify the existing abstract num ID so that some of the above information like restart, start, hanging can be specified (other elements too as we see more complex styles)
  2. or a next better approach could be that we have a copy.deepcopy like functionality for abstract num Ids so that we do not have to copy all the data

Also, if I have to get all the level for an existing abstract numId, can I simply use:

lvl_lst = abs_num.get_or_add_lvl()

for i in lvl_lst:
    print (i.ilvl)

Can you point us in the right direction for this?

@jlovegren0
Copy link
Author

@komawar I think what needs to be done is to elaborate the definitions in oxml/numbering.py. This takes a bit of care to make sure that it sticks to the style in the base code and is sufficiently "pythonic." I committed one change where you can look up an abstractNum by its definition. I.e.,

>>> d = docx.Document('test.docx')
>>> d.part.numbering_part.element.abstractNum_having_abstractNumId(3)
<CT_AbstractNum '<w:abstractNum>' at 0x7f96432db110>

I'll try to add other methods as time permits. Just let me know what would be most useful.

@komawar
Copy link

komawar commented Apr 9, 2020

@jlovegren0 I am trying to look into the styles API on python-docx and the best way to get style appears to be
d.styles.get_by_id(d.styles.get_style_id("List Number", STYP.PARAGRAPH), STYP.PARAGRAPH)
however that fetches _ParagraphStyle object. This is posing some challenges, so what would be the best way to fetch a basedOn value for the style and then fetch that style. I see a method base_style that gives what is required.

class CT_Style(BaseOxmlElement):
    name = ZeroOrOne('w:name', successors=_tag_seq[1:])
    basedOn = ZeroOrOne('w:basedOn', successors=_tag_seq[3:])
...
...
    @property
    def basedOn_val(self):
...
     @property
     def base_style(self):

How do we get this CT_Style style object rather than _ParagraphStyle? or do you recommend a better way to fetch base_style?

@jlovegren0
Copy link
Author

jlovegren0 commented Apr 10, 2020

@komawar _ParagraphStyle is ultimately an instance of ElementProxy. It is aptly named, as it's just a proxy for an lxml element and you can access the lxml representation through its element attribute. So just use (I hard code for clarity)

S = d.styles.get_by_id("ListNumber",1)
e = S.element

Then e is a CT_Style object which is in turn an instance of BaseOxmlElement: an lxml element with some sugar provided by xmlchemy. So you can use the properties provided by xmlchemy as follows:

>>> e.basedOn.val
'Normal'

Note that there are numerous paragraph styles based on "Normal," so it's not possible to get a unique style by its basedOn element.

@jlovegren0
Copy link
Author

@komawar One other thing to note when working with paragraph styles is that the .docx OPC container does not contain all of the styles that are visible through the UI. There are built-in styles but the styles.xml file will only contain the ones actually used in the document, I think. The issue is discussed in the base package's documentation.

@komawar
Copy link

komawar commented Apr 10, 2020

@jlovegren0 thank you for the awesome tips!

@alsedev
Copy link

alsedev commented Jun 17, 2020

Hello @jlovegren0 and @komawar, @nitinkhosla79 and all contributing to the MS Word numbering nightmare. I do really appreciate all time you spend to solve these issues. I already read this page conversation and want to say "Thank you all!". I am working on a project and I need to generate several documents based on one template (a simple docx) and restart numbering for each new document (only for "Heading 1" and "Heading 2").

Can you please give some simple guide (python sample) to achieve that? Thank you again.

@trannhutle
Copy link

Hi @jlovegren0 and @komawar ,

Would you please showing me how to run your current nested list example. I am running on the version 0.8.10 and it has this issue. AttributeError: 'CT_Numbering' object has no attribute 'abstractNum_lst'. Would you mind showing me how to fix it. Thank you so much!

image

@jlovegren0
Copy link
Author

jlovegren0 commented Nov 14, 2020 via email

@WilliamWCYoung
Copy link

What's the current state here? We have just come across this issue and it seems like this has become stale?

@theonesean
Copy link

What's the current state here? We have just come across this issue and it seems like this has become stale?

Seconded.

@jlovegren0 @scanny -- do we have any updates here?

@jlovegren0
Copy link
Author

jlovegren0 commented Dec 2, 2022 via email

@Ridhaa25
Copy link

Ridhaa25 commented Sep 12, 2023

Hi @jlovegren0 , @komawar

Thank you for your work on this. I have been working through the code snippets mentioned above. I have been hitting my head against the wall with restarting level 0 numbered list. Do you have a python code snippet that would achieve something like this:

  1. Some text
    1.1 Some text 1

Paragraph or heading section

  1. Some text
    1.1 Some text 1

Any help with this would be GREATLY appreciated.

@msbike
Copy link

msbike commented Sep 13, 2023

Hi @Ridhaa25,
I solved this problem some months ago. I can't remember any detail but maybe following code snipping will help you. I extended the Paragraph class and implemented a new method called restarting_numbering( ).

class ParagraphExt:

    p = None

    def __init__(self, p: Paragraph):
        self.p = p

    def restart_numbering(self):
        """
        Restarting the numbering of paragraph
        """

        # Getting the abstract number of paragraph
        abstract_num_id = self.p.part.document.part.numbering_part.element.num_having_numId(
            self.p.style.element.get_or_add_pPr().get_or_add_numPr().numId.val).abstractNumId.val

        # Add abstract number to numbering part and reset
        num = self.p.part.numbering_part.element.add_num(abstract_num_id)
        num.add_lvlOverride(ilvl=0).add_startOverride(1)

        # Get or add elements to paragraph
        p_pr = self.p._p.get_or_add_pPr()
        num_pr = p_pr.get_or_add_numPr()
        ilvl = num_pr.get_or_add_ilvl()
        ilvl.val = int("0")
        num_id = num_pr.get_or_add_numId()
        num_id.val = int(num.numId)

To use this method you need to create an instance of this class with the normal Paragraph (here p) and call the method.

p_ext = ParagraphExtDocx(p)
p_ext.restart_numbering()

Hope that will help you.

@Ridhaa25
Copy link

Hi @msbike

Thanks so much for this. This is exactly what I was looking for. Much appreciated

@diggity801
Copy link

Thank you for

Hi @Ridhaa25, I solved this problem some months ago. I can't remember any detail but maybe following code snipping will help you. I extended the Paragraph class and implemented a new method called restarting_numbering( ).

class ParagraphExt:

    p = None

    def __init__(self, p: Paragraph):
        self.p = p

    def restart_numbering(self):
        """
        Restarting the numbering of paragraph
        """

        # Getting the abstract number of paragraph
        abstract_num_id = self.p.part.document.part.numbering_part.element.num_having_numId(
            self.p.style.element.get_or_add_pPr().get_or_add_numPr().numId.val).abstractNumId.val

        # Add abstract number to numbering part and reset
        num = self.p.part.numbering_part.element.add_num(abstract_num_id)
        num.add_lvlOverride(ilvl=0).add_startOverride(1)

        # Get or add elements to paragraph
        p_pr = self.p._p.get_or_add_pPr()
        num_pr = p_pr.get_or_add_numPr()
        ilvl = num_pr.get_or_add_ilvl()
        ilvl.val = int("0")
        num_id = num_pr.get_or_add_numId()
        num_id.val = int(num.numId)

To use this method you need to create an instance of this class with the normal Paragraph (here p) and call the method.

p_ext = ParagraphExtDocx(p)
p_ext.restart_numbering()

Hope that will help you.

Thank you! This is what saved me.

@bmoore27
Copy link

bmoore27 commented Oct 2, 2023

@msbike This snippet causes the numbering to reset to 1 on every element...Am I missing something?

@scanny
Copy link
Contributor

scanny commented Oct 2, 2023

@bmoore27 There is some library code by @madphysicist described here and with code here that handles the grisly details of list-numbering. It might be worth looking at and perhaps using via his haggis library or just vendoring into your own code. His work is very solid.

@madphysicist
Copy link

madphysicist commented Oct 3, 2023 via email

@zebulmace
Copy link

Hi @Ridhaa25, 你好 I solved this problem some months ago. I can't remember any detail but maybe following code snipping will help you. I extended the Paragraph class and implemented a new method called restarting_numbering( ).几个月前我解决了这个问题。我不记得任何细节,但也许以下代码截取会对您有所帮助。我扩展了 Paragraph 类并实现了一个名为 restarting_numbering( )的新方法。

class ParagraphExt:

    p = None

    def __init__(self, p: Paragraph):
        self.p = p

    def restart_numbering(self):
        """
        Restarting the numbering of paragraph
        """

        # Getting the abstract number of paragraph
        abstract_num_id = self.p.part.document.part.numbering_part.element.num_having_numId(
            self.p.style.element.get_or_add_pPr().get_or_add_numPr().numId.val).abstractNumId.val

        # Add abstract number to numbering part and reset
        num = self.p.part.numbering_part.element.add_num(abstract_num_id)
        num.add_lvlOverride(ilvl=0).add_startOverride(1)

        # Get or add elements to paragraph
        p_pr = self.p._p.get_or_add_pPr()
        num_pr = p_pr.get_or_add_numPr()
        ilvl = num_pr.get_or_add_ilvl()
        ilvl.val = int("0")
        num_id = num_pr.get_or_add_numId()
        num_id.val = int(num.numId)

To use this method you need to create an instance of this class with the normal Paragraph (here p) and call the method.要使用此方法,您需要使用普通的 Paragraph(此处为 p)创建此类的实例并调用该方法。

p_ext = ParagraphExtDocx(p)
p_ext.restart_numbering()

Hope that will help you.希望对你有所帮助。

thanks

@Airor4
Copy link

Airor4 commented Jan 25, 2024

Please consider implementing Ridhaa25's solution to the restart numbering problem. It being an actual feature in word leads me to believe that this would be the fitting place to implement it rather than all of us users' codebases.

@diggity801
Copy link

diggity801 commented Jan 31, 2024 via email

@Blezz-tech
Copy link

please, add this function

@diggity801
Copy link

diggity801 commented Feb 7, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.