TOC when inserted in the document Right to left Text direction not honoured for "("

StC Original TOC Template.docx (6.6 MB)
Hi

I am trying to inset TOC in the document at a pre defiend bookmark location everything works fine but the brackets “(” comes inverted. Once the document is opened in workd i right click the TOC and click updated fiel the brackets become proper . The way my code works , first check if there is an existing TOC in the document if yes it add bookmark in the document in TOC location and removes the TOC. Once some other processes are done new TOC is inseted in the place of bookmark and the bookmark is removed.

Please see the screenshot of the problem below.

The code used to inset TOC is below

public void AddTableOfContents(ref Document doc, ArrayList TocFormatCodes)
{
    List<Bookmark> bookmarks = doc.Range.Bookmarks.Where(b => b.Name.StartsWith("BM_TOC")).ToList();
    DocumentBuilder builder = new DocumentBuilder(doc);
    for (int i = 0; i < bookmarks.Count; i++)
    {
        string tocFormatSwitches = "\\o \"1-3\" \\h \\z \\u";
        Bookmark bm = bookmarks[i];
        try
        {
            tocFormatSwitches = (string)TocFormatCodes[i];
        }
        catch (Exception)
        {
        }
        builder.ParagraphFormat.Bidi = true;
        builder.MoveToBookmark(bm.Name);

        Field toc = builder.InsertTableOfContents(tocFormatSwitches);
        toc.Update();
        bm.Remove();
    }
}

Please find the attached input and output document

out-rountrip.docx (6.4 MB)

@cyrusdaru1 Unfortunately, I cannot reproduce the problem on m y side. I have tested with the following simple code:

Document doc = new Document("C:\\Temp\\in.docx");
doc.UpdateFields();
doc.Save("C:\\Temp\\out.docx");

tried with both attached documents and in both cases TOC is updated properly by Aspose.Words. Please see the output document produced on my side: out.docx (4.7 MB)

I have used the latest 22.12 version of Aspose.Words for testing.

Hi,

The way you can reproduce is

  1. Remove TOC from the existing document and add bookmark in its place
public void RemoveTableOfContents(Document doc)
{
    DocumentBuilder builder = new DocumentBuilder(doc);
    int index = 1;
    foreach (Field field in doc.Range.Fields)
    {
        if (field.Type == FieldType.FieldTOC)
        {

            if (field.Start.ParentNode.GetChildNodes(NodeType.BookmarkEnd, true).Cast<BookmarkEnd>().Where(e => e.Name.Contains("BM_TOC")).ToList().Count == 0)
            {
                builder.MoveToField(field, true);

                BookmarkStart bm_start = builder.StartBookmark("BM_TOC" + "_" + index);
                BookmarkEnd bm_end = builder.EndBookmark(bm_start.Name);
                builder.Writeln();
                builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal;
                builder.ListFormat.List = null;
                index++;
            }
            field.Remove();
        }
    }
}
  1. Insert New TOC in place of bookmark created in step 1
public void AddTableOfContents(ref Document doc, ArrayList TocFormatCodes)
{
    List<Bookmark> bookmarks = doc.Range.Bookmarks.Where(b => b.Name.StartsWith("BM_TOC")).ToList();
    DocumentBuilder builder = new DocumentBuilder(doc);
    for (int i = 0; i < bookmarks.Count; i++)
    {
        string tocFormatSwitches = "\\o \"1-3\" \\h \\z \\u";
        Bookmark bm = bookmarks[i];
        try
        {
            tocFormatSwitches = (string)TocFormatCodes[i];
        }
        catch (Exception)
        {
        }
        builder.ParagraphFormat.Bidi = true;
        builder.MoveToBookmark(bm.Name);

        Field toc = builder.InsertTableOfContents(tocFormatSwitches);
        toc.Update();
        bm.Remove();
    }
}

I am sharing the code on the link below

@cyrusdaru1 Thank you for additional information. I have managed to reproduce the problem on my side and logged it as WORDSNET-24804. We will keep you informed and let you know once it is resolved.

PS: Please do not share project with your license file publicly. The license can be blacklisted in such case. For now I have removed link to your test project.

Hi
is there a workaround to create TOC some other way.

Also i want to set bidi =true for TOC can you please help me with that

Thanks

@cyrusdaru1 Actually setting Bidi options is the workaround the problem. Please see the following code:

Document doc = new Document(@"C:\Temp\simplified.docx");

// Update TOC
doc.UpdateFields();
doc.UpdatePageLayout();

StyleIdentifier[] tocStyleIdentifiers =
    new StyleIdentifier[] {
        StyleIdentifier.Toc1,
        StyleIdentifier.Toc2,
        StyleIdentifier.Toc3,
        StyleIdentifier.Toc4,
        StyleIdentifier.Toc5,
        StyleIdentifier.Toc6,
        StyleIdentifier.Toc7,
        StyleIdentifier.Toc8,
        StyleIdentifier.Toc9
    };

// Select the TOC paragrphs.
List<Paragraph> tocParagraphs = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>()
    .Where(p => tocStyleIdentifiers.Any(i => i == p.ParagraphFormat.StyleIdentifier)).ToList();

// Mark the paragraph and child runs as RTL.
foreach (Paragraph p in tocParagraphs)
{
    p.ParagraphFormat.Bidi = true;
    foreach (Run r in p.Runs)
        r.Font.Bidi = true;
}

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

Hi
I have slightly modified the above code for Table of Figures and Table of Tables. I want page numbers to come on the left but even after setting Bidi Page numbers still come on right . Please see the screenshot below
image.png (15.5 KB)

Below is the code that i am using

public void SetTableOfContentToRTL(ref Document doc)
{
    doc.UpdateFields();
    doc.UpdatePageLayout();

    StyleIdentifier[] tocStyleIdentifiers = new StyleIdentifier[] {
        //StyleIdentifier.Toc1,
        //StyleIdentifier.Toc2,
        //StyleIdentifier.Toc3,
        //StyleIdentifier.Toc4,
        //StyleIdentifier.Toc5,
        //StyleIdentifier.Toc6,
        //StyleIdentifier.Toc7,
        //StyleIdentifier.Toc8,
        //StyleIdentifier.Toc9,
        StyleIdentifier.TableOfFigures
        };
    List<Paragraph> tocParagraphs = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().Where(p => tocStyleIdentifiers.Any(i => i == p.ParagraphFormat.StyleIdentifier)).ToList();

    // Mark the paragraph and child runs as RTL.
    foreach (Paragraph p in tocParagraphs)
    {
        p.ParagraphFormat.Bidi = true;
        p.ParagraphFormat.Style.Font.Bidi = true;
        foreach (Run r in p.Runs)
            r.Font.Bidi = true;
    }
}

@cyrusdaru1 Could you please attach your output document here for testing? I will check it and provide you more information.

out-rountrip.docx (4.7 MB)

Please find the output document

@cyrusdaru1 Thank you for additional information. The following code produces the correct output:

Document doc = new Document(@"C:\Temp\out-rountrip.docx");

// Update TOC
doc.UpdateFields();
doc.UpdatePageLayout();

StyleIdentifier[] tocStyleIdentifiers =
    new StyleIdentifier[] {
        StyleIdentifier.Toc1,
        StyleIdentifier.Toc2,
        StyleIdentifier.Toc3,
        StyleIdentifier.Toc4,
        StyleIdentifier.Toc5,
        StyleIdentifier.Toc6,
        StyleIdentifier.Toc7,
        StyleIdentifier.Toc8,
        StyleIdentifier.Toc9,
        StyleIdentifier.TableOfFigures
    };

// Select the TOC paragrphs.
List<Paragraph> tocParagraphs = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>()
    .Where(p => tocStyleIdentifiers.Any(i => i == p.ParagraphFormat.StyleIdentifier)).ToList();

// Mark the paragraph and child runs as RTL.
foreach (Paragraph p in tocParagraphs)
{
    p.ParagraphFormat.Bidi = true;
    foreach (Run r in p.Runs)
        r.Font.Bidi = true;
}

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

out.docx (4.7 MB)