Multi-Line formatting with variable page numbers

I’m working on a project that requires a title in italics (which can line wrap) followed by a description below that is indented (which can line wrap) followed by leader dots and possibly numerous page numbers separated by commas (right justified margin). When using single page numbers, I’m close to what I need, but multiple page numbers reset the margin and are indented incorrectly. I’ve uploaded two word documents, one with single page numbers and one with multiple page numbers (which has the indention issue).
I’m apparently missing something as I’m unable to achieve the desired results. I’m hoping someone in the community can help me get on the right track.

Example Documents.zip (10.0 KB)

Below is the code I’ve come up with:

using System.Drawing;
using ILSLibrary.Graphic;
using Word = Aspose.Words;

namespace AsposeTOC.Classes
{
public class TableOfContents
{
private Word.Document m_Document = null;
private Word.DocumentBuilder m_Builder = null;
private Word.Section m_CurrentSection = null;
private double m_RightMargin = 0;

    public TableOfContents()
    {
        License();
    }

    public string FontName { get; set; } = "Times New Roman";
    public double FontSize { get; set; } = 14;
    public double HeadingMargin { get; set; } = Word.ConvertUtil.InchToPoint(1);
    public double IndentMargin { get; set; } = Word.ConvertUtil.InchToPoint(0.25);

    public void WordTOA()
    {
        m_Document = new Word.Document();
        m_Builder = new Word.DocumentBuilder(m_Document);

        m_CurrentSection = m_Builder.CurrentSection;
        Word.PageSetup pageSetup = m_CurrentSection.PageSetup;

        pageSetup.PageStartingNumber = 1;
        pageSetup.PageNumberStyle = Word.NumberStyle.LowercaseRoman;
        pageSetup.RestartPageNumbering = true;

        m_Builder.MoveToHeaderFooter(Word.HeaderFooterType.FooterPrimary);
        m_Builder.ParagraphFormat.Alignment = Word.ParagraphAlignment.Center;
        m_Builder.InsertField("Page", "i");

        pageSetup.PaperSize = Word.PaperSize.Letter;

        m_RightMargin = pageSetup.PageWidth - pageSetup.LeftMargin - pageSetup.RightMargin;

        Headings();

        for (int x = 0; x < 10; x++)
        {
            TOAEntry("Aspose.Words for .NET examples, plug ins and showcases - aspose words Aspose Words for aspose words Aspose Words for", "Aspose.Words for .NET examples, plug ins and showcases");
        }

        m_Document.Save(@"C:\temp\TOA.docx", Word.SaveFormat.Docx);
    }

    private void TOAEntry(string title, string citations)
    {
        Word.Paragraph paragraph = new Word.Paragraph(m_Document);

        //Word.Paragraph paragraph = m_Document.LastSection.Body.LastParagraph;
        Word.ParagraphFormat paragraphFormat = m_Builder.ParagraphFormat;

        m_Builder.Font.Name = FontName;
        m_Builder.Font.Size = FontSize;

        string pageNumber = "100";

        //Leave space for page number
        paragraphFormat.RightIndent = 40;
        paragraphFormat.SpaceAfter = 1;
        paragraphFormat.Alignment = Word.ParagraphAlignment.Left;

        paragraph.ParagraphFormat.KeepWithNext = true;

        Word.TabStop tabStop = new Word.TabStop(m_RightMargin - TextWidth(pageNumber), Word.TabAlignment.Right, Word.TabLeader.Dots);
        paragraph.ParagraphFormat.TabStops.Add(tabStop);

        m_Builder.Font.Italic = true;
        paragraphFormat.LeftIndent = IndentMargin;

        m_Builder.Writeln(title);

        m_Builder.Font.Italic = false;
        paragraphFormat.LeftIndent = 0;

        m_Builder.Write($"{citations}{Word.ControlChar.Tab}");
        m_Builder.Writeln($"{pageNumber}");

        m_Builder.InsertBreak(Word.BreakType.LineBreak);
    }

    private double TextWidth(string text)
    {
        return PixelSizeOfString(new Font(FontName, (float)FontSize), text).Width;
    }

    public SizeF PixelSizeOfString(Font font, string text)
    {
        using (Graphics graphics = Graphics.FromImage(new Bitmap(1, 1)))
        {
            return graphics.MeasureString(text, font);
        }
    }

    private void Headings()
    {
        Word.PageSetup pageSetup = m_CurrentSection.PageSetup;

        pageSetup.DifferentFirstPageHeaderFooter = true;
        pageSetup.OddAndEvenPagesHeaderFooter = false;

        //First Page
        m_Builder.MoveToHeaderFooter(Word.HeaderFooterType.HeaderFirst);

        pageSetup.HeaderDistance = HeadingMargin;

        m_Builder.Font.Name = FontName;
        m_Builder.Font.Size = FontSize;
        m_Builder.Font.Bold = true;

        m_Builder.ParagraphFormat.Alignment = Word.ParagraphAlignment.Center;
        m_Builder.Writeln("TABLE OF AUTHORITIES");

        m_Builder.ParagraphFormat.Alignment = Word.ParagraphAlignment.Left;
        m_Builder.Writeln("Cases");

        //Subsequent Pages
        m_Builder.MoveToHeaderFooter(Word.HeaderFooterType.HeaderPrimary);

        pageSetup.HeaderDistance = HeadingMargin;

        m_Builder.Font.Name = FontName;
        m_Builder.Font.Size = FontSize;
        m_Builder.Font.Bold = true;

        m_Builder.ParagraphFormat.Alignment = Word.ParagraphAlignment.Center;
        m_Builder.Writeln("TABLE OF AUTHORITIES (Continued)");

        m_Builder.ParagraphFormat.Alignment = Word.ParagraphAlignment.Left;
        m_Builder.Writeln("Cases");

        //Return to document section
        m_Builder.MoveToSection(0);

        m_Builder.Font.Bold = false;
    }

    private void License()
    {
        Word.License wLicense = new Word.License();
        wLicense.SetLicense("Aspose.Total.lic");
    }
}

}

One thing I didn’t mention in my previous post. The Title and description need to me thought of as a single unit and cannot be split between pages.

Thanks!

@ILSTech,

We are working on your query and will get back to you soon.

@ILSTech,

Thanks for being patient. You can use the following simple code to fix the output of “Incorrect Margins.docx”.

Document doc = new Document("E:\\example documents\\Incorrect Margins.docx");

foreach (Paragraph para in doc.GetChildNodes(NodeType.Paragraph, true))
{
    if (para.ParagraphFormat.TabStops.Count > 0)
    {
        para.ParagraphFormat.TabStops.Clear();

        TabStop ts = new TabStop(6.28 * 72, Aspose.Words.TabAlignment.Right, TabLeader.Dots);
        para.ParagraphFormat.TabStops.Add(ts);
    }
}        

doc.Save("E:\\example documents\\19.5.docx"); 

Output document is attached: 19.5.zip (7.7 KB)