BHoM / PowerPoint_Toolkit

GNU Lesser General Public License v3.0
0 stars 0 forks source link

MultiLineTextUpdate Paragraphs/Run structure #23

Open Tom-Kingstone opened 3 months ago

Tom-Kingstone commented 3 months ago

My understanding of how openxml text works, is that TextBody is split into Paragraphs, which are split into Runs. The way that you are inserting the text, while it produces the right result, is creating badly formed xml. I would expect for an inputted list of strings to make a new Paragraph for each string, rather than putting them all into one run. This also has the side-effect of only ever replacing the first paragraph, and leaving all the rest of the paragraphs as before.

As I understand, the runs are for if - in a paragraph - a bit of text has different properties to the rest of the paragraph (such as a different font, or italics etc.).

The following code would be more what I had in mind for this. This also fixes any ignored text:

// Create text body and internal properties if they do not exist.
TextBody textBody = shape.TextBody ?? shape.AppendChild(new TextBody(new Drawing.BodyProperties(), new Drawing.ListStyle()));

List<Drawing.Paragraph> paragraphs = textBody.Elements<Drawing.Paragraph>().ToList();

//create a new paragraph in the text body with the text for that paragraph in a run if it does not already exist, otherwise change 

bool updateColour = !string.IsNullOrEmpty(update.Colour);
List<Drawing.Paragraph> newParagraphs = new List<Drawing.Paragraph>();

for (int paragraphIndex = 0; paragraphIndex < update.Text.Count; paragraphIndex++)
{
    Drawing.Paragraph paragraph = (Drawing.Paragraph)paragraphs.ElementAtOrDefault(paragraphIndex)?.CloneNode(true) ?? new Drawing.Paragraph();

    Drawing.Run run = (Drawing.Run)paragraph.GetFirstChild<Drawing.Run>()?.CloneNode(true) ?? paragraph.AppendChild(new Drawing.Run());

    if (run.RunProperties != null)
        run.RunProperties.SpellingError = null;
    else
        run.RunProperties = new Drawing.RunProperties();

    if (updateColour)
        SetFillColour(run.RunProperties, update.Colour);

    paragraph.RemoveAllChildren<Drawing.Run>();
    paragraph.AddChild(run);

    Drawing.Text text = run.Text ?? run.AppendChild(new Drawing.Text());
    text.Text = update.Text[paragraphIndex];

    newParagraphs.Add(paragraph);
}

textBody.RemoveAllChildren<Drawing.Paragraph>();
textBody.Append(newParagraphs);

_Originally posted by @Tom-Kingstone in https://github.com/BHoM/PowerPoint_Toolkit/pull/21#discussion_r1657182980_

Tom-Kingstone commented 3 months ago

MultiLineTextUpdate.pptx