Adding the TOC

Hi Team,
I am trying to add the Table of content in particular heading below . I used below code its adding TOC but its not moving the heading below the content to next line. image.png (3.9 KB)

Please find the below input and expected output file.
Expected_output (3).docx (165.0 KB)
Input_document_Table of content.docx (163.2 KB)

bool hasToc = doc.Range.Fields.Where(f => f.Type ==
FieldType.FieldTOC).Any();

if (!hasToc)
{
    string headingToFind = "TABLE OF CONTENTS";


    var target = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>();
    foreach (Paragraph p in target)
    {

        if (p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1)
        {
            var isHeading = "";
            foreach (Run runHeading in p.Runs)
            {
                isHeading = isHeading + runHeading.Text;
            }
            if (isHeading.Trim().Equals(headingToFind, StringComparison.InvariantCultureIgnoreCase))
            {
                if (p != null)
                {
                    DocumentBuilder builder = new DocumentBuilder(ruleBaseModel.SourceDocument);
                    builder.MoveTo(p.NextSibling);
                    //  builder.Writeln();
                    builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
                    ruleBaseModel.SourceDocument.Styles[StyleIdentifier.Toc1].Font.Color = Color.Blue;

                }
                ruleBaseModel.SourceDocument.UpdateFields();
            }
            break;
        }
    }
}

@Princeshivananjappa your solution is almost correct. Please notice that when you use the method MoveTo() you point the builder to the next paragraph break, so every new insertion will be placed after that paragraph break. Use the following snippet to correct your code:

...
bool hasToc = doc.Range.Fields.Where(f => f.Type == FieldType.FieldTOC).Any();

if (!hasToc)
{
    const string headingToFind = "TABLE OF CONTENTS";

    var target = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().FirstOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1);
    if (target != null)
    {
        var isHeading = string.Join(string.Empty, target.Runs.Select(r => ((Run)r).Text));
        if (isHeading.Trim().Equals(headingToFind, StringComparison.InvariantCultureIgnoreCase))
        {   
            DocumentBuilder builder = new DocumentBuilder(doc);
            builder.MoveTo(target);
            builder.InsertBreak(BreakType.ParagraphBreak);
            builder.ParagraphFormat.ClearFormatting();
            var toc = builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
            doc.Styles[StyleIdentifier.Toc1].Font.Color = Color.Blue;
        }
        doc.UpdateFields();
    }
}
...

@eduardo.canal Your given code is overriding the heading 1 number style.
kindly understand I don’t want to modify any other property here. I just want to move the heading below the content and add TOC that’s it.

image.png (1.9 KB)

@Princeshivananjappa sorry I cannot see any change in the heading style

output.docx (159.8 KB)

@eduardo.canal kindly see properly its re-writing the number in heading 1.
image.png (7.6 KB)

Test_67.docx (23.1 KB)

@Princeshivananjappa can you please check that you are only using the code that I posted? Otherwise, could you please post it? As you can see in the output file that I uploaded, the headings keep their styles and list numbers. Also, can you share what version of Aspose.Words are you using?

@eduardo.canal Please find the version in below screen short.
image.png (9.8 KB)

Please find the below mentioned code.

bool hasToc = ruleBaseModel.SourceDocument.Range.Fields.Where(f => f.Type ==
FieldType.FieldTOC).Any();

if (!hasToc)
{
    const string headingToFind = "TABLE OF CONTENTS";

    var target = ruleBaseModel.SourceDocument.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().FirstOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1);
    if (target != null)
    {
        var isHeading = string.Join(string.Empty, target.Runs.Select(r => ((Run)r).Text));
        if (isHeading.Trim().Equals(headingToFind, StringComparison.InvariantCultureIgnoreCase))
        {
            DocumentBuilder builder = new DocumentBuilder(ruleBaseModel.SourceDocument);
            builder.MoveTo(target);
            builder.InsertBreak(BreakType.ParagraphBreak);
            builder.ParagraphFormat.ClearFormatting();
            var toc = builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
            ruleBaseModel.SourceDocument.Styles[StyleIdentifier.Toc1].Font.Color = Color.Blue;
        }
        ruleBaseModel.SourceDocument.UpdateFields();
    }
}

@eduardo.canal Any update on this?

@Princeshivananjappa I downgrade to the version 21.5.0 and I still getting the same result, please try running the following project and share your results:
AsposeTest.zip (262.4 KB)

@eduardo.canal I am facing the same problem kindly check your code. In your code you used builder.ParagraphFormat.ClearFormatting(); may be that’s why it’s happening. while seeing the output you should enable the all markup in Microsoft word or in your code to track. Kindly help me asap.

Use below code you can track the issue.

doc.StartTrackRevisions("yuvaraj", DateTime.Now);

bool hasToc = doc.Range.Fields.Where(f => f.Type == FieldType.FieldTOC).Any();

if (!hasToc)
{
    const string headingToFind = "TABLE OF CONTENTS";

    var target = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().FirstOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1);
    if (target != null)
    {
        var isHeading = string.Join(string.Empty, target.Runs.Select(r => ((Run)r).Text));
        if (isHeading.Trim().Equals(headingToFind, StringComparison.InvariantCultureIgnoreCase))
        {
            DocumentBuilder builder = new DocumentBuilder(doc);
            builder.MoveTo(target);
            builder.InsertBreak(BreakType.ParagraphBreak);
            builder.ParagraphFormat.ClearFormatting();
            var toc = builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
            doc.Styles[StyleIdentifier.Toc1].Font.Color = Color.Blue;
        }
        doc.UpdateFields();
    }
}
doc.StopTrackRevisions();

@eduardo.canal /Team,
Any update on this?

Any update on this?

@Princeshivananjappa This occurs because when you move DocumentBuilder cursor to heading paragraph and then insert a paragraph break - another heading paragraph is created and numbering is shifted. Then you clear formatting and numbering is shifted back, but the changes are already remembered by track revisions mechanism. This is what you see in the output.
As a solution, you should insert a normal paragraph after the target heading to avoid numbering shifting. You can achieve this by creating a paragraph from scratch. Please modify your code like the following:

if (isHeading.Trim().Equals(headingToFind, StringComparison.InvariantCultureIgnoreCase))
{
    Paragraph para = new Paragraph(doc);
    target.ParentNode.InsertAfter(para, target);

    DocumentBuilder builder = new DocumentBuilder(doc);
    builder.MoveTo(para);
    var toc = builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
    doc.Styles[StyleIdentifier.Toc1].Font.Color = Color.Blue;
}

Also, UpdateFields method is quite resource consuming, so I would suggest to move it’s call to the end of the document processing - just before saving the document.

FYI @eduardo.canal