Free Support Forum - aspose.com

Problem with left margin of second onwards lines in unordered listing

Hi there,

I am creating a slide using Aspose.Slides.dll of version 15.4.0.0. In unordered listing, for a li content, when content goes in second line, it starts just below the bullet. Ideally the second line should start from exactly the same position, the first line starts.

Current output:
It provides customer and business process management services to organisations in industries such as healthcare, property services, general insurance and investor.

Desired Output:
Second line should start from, just below "It" not from , below the bullet.

Please help. Please see below my code, Please find attached template file and generated pptx as well.

Code:
CreateUnorderedListing();

protected void CreateUnorderedListing()
{
string template = ConfigurationManager.AppSettings["TemplateFilePath"];
Presentation pres = new Presentation(MapPath(".") + "\\Templates\\PPTXTemplate.pptx");

ISlide sld = pres.Slides[pres.Slides.Count - 1];
IAutoShape iShapeBody = null;

//Iterate through shapes to find the placeholder
foreach (IShape shp in sld.Shapes)
{
if (shp.Placeholder != null)
{
if (shp is IAutoShape )
{
iShapeBody = (IAutoShape)shp;
}
}
}

string richText = "
  • Capita was formed in 1984 within the Chartered Institute of Public Finance and Accountancy.
  • The company is headquartered in London, UK, and is listed on the London Stock Exchange.
  • It provides customer and business process management services to organisations in industries such as healthcare, property services, general insurance, investor and banking, services, integrated services, IT services and consulting.
  • The company’s business segments are as follows:
    • Health & Wellbeing
    • IT Services
    • Justice & Secure Services
    • Professional Services
    • Professional Services
    • Professional Services
    • Professional Services
    • Professional Services
    • Professional Services
";

this.ParseHtmlContent(richText, iShapeBody);

pres.Save(System.Web.HttpContext.Current.Server.MapPath(template) + "SamplePPTReport123.pptx", SaveFormat.Pptx);
}

private ITextFrame txtFrame = null;
private IParagraph para = null;
private IPortion portion = null;
private bool isFirstNodeUlOl = false;
float yCoordinateValue = default(float);
float verticalGap = 10;

public IAutoShape ParseHtmlContent(string content, IAutoShape shape)
{
Presentation pres = (Presentation)shape.Presentation;
ILayoutSlide lsTitleWithContent = ((ISlide)shape.Slide).LayoutSlide;
// ISlide currentSlide = null;

try
{
yCoordinateValue = shape.Y;
para = null;
txtFrame = shape.TextFrame;
txtFrame.TextFrameFormat.AutofitType = TextAutofitType.Shape;

if (txtFrame != null)
{
if (txtFrame.Text.Contains("Text"))
{
//Removing the default exisiting paragraph
txtFrame.Paragraphs.RemoveAt(0);
}

para = new Paragraph();
txtFrame.Paragraphs.Add(para);
para.Portions.Add(new Portion());
portion = para.Portions[0];
}

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(content);

if (htmlDoc.DocumentNode.ChildNodes.Count > 0)
{
HtmlNode firstNode = htmlDoc.DocumentNode.ChildNodes[0];

if (firstNode.Name == "ol" || firstNode.Name == "ul")
{
isFirstNodeUlOl = true; // This is used to avoid adding new paragraph for first li when respective ul/ol is the first element in the shape.
}
}

foreach (HtmlNode node in htmlDoc.DocumentNode.ChildNodes)
{
shape = this.TraverseChildNodes(node, shape);

if (yCoordinateValue <= (shape.Y + shape.Height))
{
yCoordinateValue = shape.Y + shape.Height;
}
else
{
yCoordinateValue += verticalGap;

if (node.NextSibling == null)
{
yCoordinateValue += shape.Height;
}
}
}
}
catch (Exception ex)
{}

return shape;
}

public IAutoShape TraverseChildNodes(HtmlNode node, IAutoShape shape)
{
try
{
shape = this.ProcessNode(node, shape);

foreach (HtmlNode chldNode in node.ChildNodes)
{
TraverseChildNodes(chldNode, shape);
}
}
catch (Exception ex)
{}

return shape;
}

private IAutoShape ProcessNode(HtmlNode node, IAutoShape shape)
{
try
{
//This is for plain text after any ul/ol
if (node.PreviousSibling != null && (node.PreviousSibling.Name == "ul" || node.PreviousSibling.Name == "ol") && node.Name != "li" && node.Name != "p" && node.Name != "br")
{
if (txtFrame != null)
{
para = new Paragraph();
txtFrame.Paragraphs.Add(para);
para.Portions.Add(new Portion());
portion = para.Portions[0];
}
}

if (node.Name == "#text")
{
if (para != null && portion == null)
{
portion = new Portion();
para.Portions.Add(portion);
}

//handle bold, italic and underline tags for each text node. This also handles the nested tags
HtmlNode parentNode = node.ParentNode;

while (parentNode != null)
{
if (parentNode.Name == "b" || parentNode.Name == "strong")
portion.PortionFormat.FontBold = NullableBool.True;
else if (parentNode.Name == "i")
portion.PortionFormat.FontItalic = NullableBool.True;
else if (parentNode.Name == "u")
portion.PortionFormat.FontUnderline = TextUnderlineType.Single;

parentNode = parentNode.ParentNode;
}

StringBuilder textBuilder = new StringBuilder(node.InnerText);
textBuilder = textBuilder.Replace("[gt]", ">");
textBuilder = textBuilder.Replace("[lt]", "<");
textBuilder = textBuilder.Replace("[quot]", """);
textBuilder = textBuilder.Replace("[lsquo]", "‘");
textBuilder = textBuilder.Replace("[rsquo]", "’");
textBuilder = textBuilder.Replace("[ldquo]", "“");
textBuilder = textBuilder.Replace("[rdquo]", "”");
textBuilder = textBuilder.Replace("[apos]", "'");
textBuilder = textBuilder.Replace("[amp]", "&");

portion.Text = WebUtility.HtmlDecode(textBuilder.ToString());

portion = null;
//cell = null;
}
else if (node.Name == "p")
{
// para = null;

if (txtFrame != null)
{
if (!(txtFrame.Paragraphs.Count == 1 && txtFrame.Paragraphs[0].Text == string.Empty))
{

txtFrame.Paragraphs.Add(new Paragraph());
para = txtFrame.Paragraphs[txtFrame.Paragraphs.Count - 1];

para.Portions.Add(new Portion());
portion = para.Portions[0];
}
}
}
else if (node.Name == "br")
{
//para = null;

if (txtFrame != null)
{
txtFrame.Paragraphs.Add(new Paragraph());
para = txtFrame.Paragraphs[txtFrame.Paragraphs.Count - 1];

para.Portions.Add(new Portion());
portion = para.Portions[0];
}
}
else if (node.Name == "h1" || node.Name == "h2" || node.Name == "h3" || node.Name == "h4")
{
}
else if (node.Name == "li")
{
//Avoid adding new paragraph for first li when respective ul/ol is the first element in the shape
if (!isFirstNodeUlOl)
{
//Every list item needs to be new paragraph
para = new Paragraph();

if (txtFrame != null)
{
if (txtFrame.Text.Contains("Text"))
{
//Removing the default exisiting paragraph
txtFrame.Paragraphs.RemoveAt(0);
}

txtFrame.Paragraphs.Add(para);
para.Portions.Add(new Portion());
portion = para.Portions[0];
}
}

if (node.ParentNode.Name == "ul")
{
para.ParagraphFormat.Bullet.Type = BulletType.Symbol;
para.ParagraphFormat.Bullet.Height = 100;
para.ParagraphFormat.Alignment = TextAlignment.Left;
para.ParagraphFormat.Indent = 20;
}
else if (node.ParentNode.Name == "ol")
{
para.ParagraphFormat.Bullet.Type = BulletType.Numbered;
para.ParagraphFormat.Bullet.NumberedBulletStyle = NumberedBulletStyle.BulletArabicPeriod;
para.ParagraphFormat.Bullet.NumberedBulletStartWith = 1;
para.ParagraphFormat.Bullet.Height = 100;

para.ParagraphFormat.Alignment = TextAlignment.Left;
}

//finding the list indent level for each list item
short indentLevel = 0;
HtmlNode tempNode = node;

do
{
tempNode = tempNode.ParentNode;
if (tempNode.Name == "ul" || tempNode.Name == "ol")
indentLevel++;
} while (tempNode != null && (tempNode.Name == "ul" || tempNode.Name == "ol" || tempNode.Name == "li"));

para.ParagraphFormat.Depth = --indentLevel;

isFirstNodeUlOl = false;
}
}
catch (Exception ex)
{
//logger.Error(ex);
HttpContext.Current.Session["Error"] = "Error occured while parsing rich text || " + ex.Message;

throw ex;
}

return shape;
}

Hi Kavita,


Thank you for your interest in Aspose.Slides.

I have observed your requirements and like to request you to please visit this link for your kind reference and then share the feedback with us. I have observed that you are using Aspose.Slides for .NET 15.1.0.0 on your end. I request you to please try using Aspose.Slides for .NET 15.4.0 on your end. I hope this will help. If you still face the issue then please share the sample project with us so that I can investigate it on my end, to help you out.

Best Regard,

Hi Adnan,


Now I am using Aspose.Slides for .NET 15.4.0 on my end but the problem still exists. I have simplified my sample code and shared the sample project as a zip file. Please see the attachment for the same and help me out. I am reiterating my problem below:

Text alignment (in case of large text for one bullet
point) in bulleted list is not correct. I have attached
two png files “CurrentOutput.png” and “DesiredOutput.png” for your help.

You can see “CurrentOutput.png” , starting words of both lines are not vertically aligned where in “DesiredOutput.png”, starting words of both lines are vertically aligned.


Thank you.

Hi Kavita,


I have observed your requirements and have worked with the sample project shared by you. I have made few changes in order to meet the requirements. I am attaching the project with this post for your kind reference. It is working as per your requirements. Please observe the generated presentation and then share the feedback with us.

I hope this will be helpful. Please share if I may help you further in this regard.

Best Regards,