Custom heading or how to align paragraph text with numbering

What is the best way to properly indent paragraph text that has numbering in front?
2017-11-23_18-00-23.png (49.9 KB)

on the attached picture - all numbering is custom it may not follow the rules of office numbering - there could be gaps in the numbers, etc. Those numbers come from the database in my case.
But I still want to have a gap under the numbers - the pink rectangles must be empty.

What is the best way to do that?

Thanks,
Nik

@niktv

I have worked over your requirements and like to share with you that, when you add a paragraph on a PDF page, you can indent it with [SubsequentLinesIndent property]. Below code sample sets this property for any text to be added on a particular page in a PDF file.

        //Instantiate a document object
        Document pdfDocument = new Document();

        //Add a page to the document
        pdfDocument.Pages.Add();

        // Get particular page
        Page pdfPage = (Page)pdfDocument.Pages[1];

        // create text paragraph
        TextParagraph paragraph = new TextParagraph();

        // set subsequent lines indent
        paragraph.SubsequentLinesIndent = 20;

        // specify word wraping mode
        paragraph.FormattingOptions.WrapMode = TextFormattingOptions.WordWrapMode.DiscretionaryHyphenation;

        // Create text fragment
        TextFragment textFragment = new TextFragment("A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog.");
        
        // Set text properties
        textFragment.TextState.FontSize = 12;
        textFragment.TextState.Font = FontRepository.FindFont("TimesNewRoman");
        
        // add fragment to paragraph
        paragraph.AppendLine(textFragment);

        // Create TextBuilder object
        TextBuilder textBuilder = new TextBuilder(pdfPage);

        // Append the text fragment to the PDF page
        textBuilder.AppendParagraph(paragraph);

        dataDir = dataDir + "ParagraphIndent.pdf";

        // Save resulting PDF document.
        pdfDocument.Save(dataDir);

I hope this will be helpful. Please let us know if you need any further assistance.

Thanks for the solution!
I have only one problem with it - I ran exactly your code, and it puts the text at the end of the page. Why is that and how to fix it?
Result: test.pdf (44.1 KB)

It seems paragraph.Position or .Rectangle will position it on the page, but I have hundreds of records coming from the database, and each record will be its own text paragraph. Is there a way to auto position it / auto stack TextParagraphs.
page.Paragraphs.Add(new TextSegment(“blah blah”) is doing it with BaseParagraph, but I need the same with TextParagraph.

@niktv

I would like to share with you that specifying the position and rectangle coordinates fixes the position of text on a page. In order to place the text automatically on a PDF page, I have logged an investigation ticket with ID PDFNET-43776 in our issue management system for further investigations and resolution. We will get back to you once some significant progress is made in this regard.

We are sorry for the inconvenience.

Thank you very much!

Basically, can we achieve with TextBuilder.AppendParagraph(), the same auto alignment / stacking of the paragraphs as in page.Paragraphs.Add() ?

I also saw that TextBuilder.AppendParagraph() is not adding the TextParagraph in the page.Paragraphs collection. Any detailed explanation of how both work and is there connection will be highly appreciated.

@niktv

Thanks for your inquiry.

Please note that TextBuilder.AppendParagraph() and page.Paragraphs.Add(), both are used to add text inside the PDF, depending upon the scenario. TextBuilder acts like a container which contains its own collection of paragraphs - whereas page.Paragraphs.Add() method, adds paragraph(s) in Paragraphs collection of page.

However, using TextBuilder and TextParagraph approach, you may set properties (e.g Margins) of entire paragraph (inside TextBuilder) which can have more than one TextFragments in it. Whereas if you are adding different text fragments, which can have different properties from one another (e.g Margins, Style, Font, etc.), you may add them while using page.Paragraphs.Add() method.

Furthermore, TextParagraph is used to append lines within a paragraph, so each new call to AppendLine() method, would add text in new line (Similar to AppendParagraph() method of TextBuilder class). Therefore, AppendText() method of TextBuilder class would append text to existing text.

Now concerning to your original requirement, it can be achieved by specifying margins of TextFragment and adding it through page.Paragraphs.Add() method. Please try using following code snippet, in order to add numbered bullets and its data accordingly inside PDF. For your reference, we have attached a sample out as well, generated by below code snippet.

Aspose.Pdf.Document doc = new Aspose.Pdf.Document();
Page page = doc.Pages.Add();

TextFragment headingNumber = new TextFragment("4.");
headingNumber.IsInLineParagraph = true;
headingNumber.TextState.FontSize = 10;
headingNumber.TextState.FontStyle = FontStyles.Bold;

TextFragment headingFragment = new TextFragment("Lorem Ipsum:");
headingFragment.Margin = new MarginInfo(10, 10, 0, 0);
headingFragment.IsInLineParagraph = true;
headingFragment.TextState.FontSize = 10;
headingFragment.TextState.FontStyle = FontStyles.Bold;

page.Paragraphs.Add(headingNumber);
page.Paragraphs.Add(headingFragment);

TextFragment numberFragment = new TextFragment("4.1.");
numberFragment.Margin = new MarginInfo(10, 0, 0, 0);
// keep this fragment with next paragraph level object
numberFragment.IsKeptWithNext = true;
TextFragment dataFragment = new TextFragment("Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum");
// set margins to specify indenting and bullet formatting
dataFragment.Margin = new MarginInfo(30, 10, 0, 0);
dataFragment.IsInLineParagraph = true;

page.Paragraphs.Add(numberFragment);
page.Paragraphs.Add(dataFragment);

doc.Save(dataDir + "NumberedBullets.pdf");

NumberedBullets.pdf (2.7 KB)

As we have already logged an investigation ticket in our issue tracking system, so as soon as we receive some feedback from our product team, we will let you know. Please spare us little time.

We are sorry for the inconvenience.

@asad.ali pretty neat solution, there! I would of use it, but the new lines inside a paragraph create misalignments and in some cases, part of the text is not in the PDF.
As solution for new lines you guys sugested me to use TextBuilder, so now I’m waiting to see how the ticket you opened will work out.

@niktv

Thanks for writing back.

We were able to notice the issue in our environment and logged this issue as PDFNET-43826 in our issue tracking system. We will further investigate the reasons behind this issue and keep you posted with the status of its correction. Please be patient and spare us little time.

We are sorry for this inconvenience.

@niktv

Thank you for being patient.

I would like to share with you that the issue reported by you PDFNET-43776, has been resolved in Aspose.Pdf for .NET 18.1, as we have added SubsequentLinesIndent property in TextFormattingOptions class. You may use it to specify line indent in PDF generating scenarios with TextFragment and page.Paragraphs collection. Please refer to the code snippet below:

Aspose.Pdf.Document document = new Aspose.Pdf.Document();
Aspose.Pdf.Page page = document.Pages.Add();
        
Aspose.Pdf.Text.TextFragment text = new Aspose.Pdf.Text.TextFragment("A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog. A quick brown fox jumped over the lazy dog.");

// Initilize TextFormattingOptions for the text fragment and specify SubsequentLinesIndent value
text.TextState.FormattingOptions = new Aspose.Pdf.Text.TextFormattingOptions()
{
    SubsequentLinesIndent = 20
};

page.Paragraphs.Add(text);

text = new Aspose.Pdf.Text.TextFragment("Line2");
page.Paragraphs.Add(text);

text = new Aspose.Pdf.Text.TextFragment("Line3");
page.Paragraphs.Add(text);

text = new Aspose.Pdf.Text.TextFragment("Line4");
page.Paragraphs.Add(text);

text = new Aspose.Pdf.Text.TextFragment("Line5");
page.Paragraphs.Add(text);

document.Save(outputFile, Aspose.Pdf.SaveFormat.Pdf);

I have also attached generated PDF file for your kind reference. 43776_out.pdf