RTF bullet list to numbered list via stream

@deisenberg Actually, while you are making your source document more complicated, you are coming closer to DocumentBuilder.InsertDocument method. The next level will be inserting tables. So I would suggest you to use this method to insert content of source document into the destination document:

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
            
Document src = new Document(@"C:\Temp\src.docx");

builder.MoveToBookmark("level1");

ImportFormatOptions opt = new ImportFormatOptions();
opt.MergePastedLists = true;
builder.InsertDocument(src, ImportFormatMode.UseDestinationStyles, opt);

doc.Save(@"C:\Temp\out.docx");

You can also preprocess your document document to remove empty paragraphs.

Well, this is how we started this and it was not working well keeping the styling correct.
Let’s try another way:
I can loop through a list of paragraphs and write their contents to an existing numbered list. The numbered list will increase each time there is an ending paragraph.
But, if I need to add multiple paragraphs to a single number, then continue numbering, I must stop numbering and then re-start numbering at the previous list where I left off (and at the previous margin/indent level) not at 0 again.
How can I know what the current margin, indent level, number/letter, left-margin is from a builder object?

builder = templateDoc
paragraphs = listofItemsToImport
foreach (paragraphs p in paragraphs) {
  if (p.IsListItem) {
    //If we saved a previous position, set that position HERE: Margin, Number/Letter value, left-margin, etc.
  }
  else {
    //Remember where we are in the list HERE if we must go back to this position later in the list: Margin, Number/Letter value, left-margin, etc.
    builder.ListFormat.RemoveNumbers
  }
  builder.Writeln(p.GetText)
}

@deisenberg You can get the required values from DocumentBuilder.ListFormat property. You can remember ListFormat.List and ListFormat.ListLevelNumber.

Yes, I’ve tried those but it doesn’t seem to work… for example:

//Save list position:
currentList = builder.ListFormat.List
//Write plain text without numbering:
builder.RemoveNumbering
builder.Writeln(text)
//Start up again where we left off numbering:
builder.ListFormat.List = currentList
builder.Writeln(newText) //This is not numbered
builder.ListFormat.ApplyNumberDefault //This starts at 1 again

etc…
Applying ListLevelNumber and Indent Level too, these all do nothing. Or, if they do anything, they just start at 1 again at the same left-margin level we’re current at in the previous list.

@deisenberg You do not need to call ApplyNumberDefault, it is enough to set list. Code can look like this:

private static void InsertListItems(DocumentBuilder builder, Document src, string bookmark)
{
    builder.MoveToBookmark(bookmark);

    // Insert only text content fom the source document paragraphs.
    // In this case formatting will be inherited fron the formatting applied to the current builder position.
    List<Paragraph> paragraphs = src.GetChildNodes(NodeType.Paragraph, true)
        .Cast<Paragraph>().Where(p => p.HasChildNodes).ToList();

    Aspose.Words.Lists.List lst = null;
    int levelNumber = 0;

    foreach (Paragraph p in paragraphs)
    {
        // Disable numbering if paragrap is not list item.
        if (!p.IsListItem && builder.ListFormat.IsListItem)
        {
            lst = builder.ListFormat.List;
            levelNumber = builder.ListFormat.ListLevelNumber;

            builder.ListFormat.RemoveNumbers();
        }
        else if ((lst != null) && p.IsListItem)
        {
            builder.ListFormat.List = lst;
            builder.ListFormat.ListLevelNumber = levelNumber;
        }

        foreach (Node child in p.ChildNodes)
        {
            Node dstNode = builder.Document.ImportNode(child, true, ImportFormatMode.UseDestinationStyles);

            // Apply formattign from the current DocumentBuilder position.
            Inline inline = dstNode as Inline;
            if (inline != null)
                ApplyCurrentNodeFormatting(builder.Font, inline.Font);

            // Put the nodes into the current paragraph.
            builder.InsertNode(dstNode);
        }

        // Insert a paragraph break if required.
        if (paragraphs.IndexOf(p) < (paragraphs.Count-1))
            builder.Writeln();
    }
}

Yes, while this approach will work, when you re-enable numbering by assigning builder.ListFormat to its previous values, the left-margin is still indented too much. It needs to move left, back to the same position it was when it was numbered.
See image example
image.png (21.9 KB)

I believe I can fix this by storing builder.ParagraphFormat.LeftIndent along with the others. So, I store ListFormat.List, ListFormat.ListLevelNumber, and now ParagraphFormat.LeftIndent

@deisenberg Only side the indents are preserved. See the attached output produced on my side: out.docx (11.1 KB)
Yes, the problem on your side might occur because indents of list items are manually adjusted in your template.