| @@ -63,7 +63,7 @@ namespace Novacode | |||
| { | |||
| List<Paragraph> paragraphs = | |||
| ( | |||
| from p in Xml.Descendants(DocX.w + "p") | |||
| from p in Xml.Elements(DocX.w + "p") | |||
| select new Paragraph(Document, p, 0) | |||
| ).ToList(); | |||
| @@ -449,12 +449,9 @@ namespace Novacode | |||
| { | |||
| get | |||
| { | |||
| string text = string.Empty; | |||
| foreach (Paragraph p in Paragraphs) | |||
| { | |||
| text += p.Text + "\n"; | |||
| } | |||
| return text; | |||
| StringBuilder sb = new StringBuilder(); | |||
| HelperFunctions.GetText(Xml, sb); | |||
| return sb.ToString(); | |||
| } | |||
| } | |||
| @@ -13,6 +13,63 @@ namespace Novacode | |||
| { | |||
| internal static class HelperFunctions | |||
| { | |||
| internal static void GetText(XElement e, StringBuilder sb) | |||
| { | |||
| if (e.HasElements) | |||
| { | |||
| XElement clone = CloneElement(e); | |||
| IEnumerable<XElement> children = clone.Elements(); | |||
| children.Remove(); | |||
| sb.Append(ToText(clone)); | |||
| foreach (XElement elem in e.Elements()) | |||
| GetText(elem, sb); | |||
| } | |||
| else | |||
| sb.Append(ToText(e)); | |||
| } | |||
| internal static string ToText(XElement e) | |||
| { | |||
| switch (e.Name.LocalName) | |||
| { | |||
| case "tab": | |||
| return "\t"; | |||
| case "br": | |||
| return "\n"; | |||
| case "t": | |||
| goto case "delText"; | |||
| case "delText": | |||
| return e.Value; | |||
| case "tr": | |||
| goto case "br"; | |||
| case "tc": | |||
| goto case "tab"; | |||
| default: return ""; | |||
| } | |||
| } | |||
| internal static XElement CloneElement(XElement element) | |||
| { | |||
| return new XElement | |||
| ( | |||
| element.Name, | |||
| element.Attributes(), | |||
| element.Nodes().Select | |||
| ( | |||
| n => | |||
| { | |||
| XElement e = n as XElement; | |||
| if (e != null) | |||
| return CloneElement(e); | |||
| return n; | |||
| } | |||
| ) | |||
| ); | |||
| } | |||
| internal static PackagePart CreateOrGetSettingsPart(Package package) | |||
| { | |||
| PackagePart settingsPart; | |||
| @@ -26,7 +26,7 @@ namespace Novacode | |||
| private Alignment alignment; | |||
| // A lookup for the runs in this paragraph | |||
| Dictionary<int, Run> runLookup = new Dictionary<int, Run>(); | |||
| public Dictionary<int, Run> runLookup = new Dictionary<int, Run>(); | |||
| internal int startIndex, endIndex; | |||
| @@ -1103,31 +1103,7 @@ namespace Novacode | |||
| get | |||
| { | |||
| StringBuilder sb = new StringBuilder(); | |||
| // Loop through each run in this paragraph | |||
| foreach (XElement r in Xml.Descendants(XName.Get("r", DocX.w.NamespaceName))) | |||
| { | |||
| // Loop through each text item in this run | |||
| foreach (XElement descendant in r.Descendants()) | |||
| { | |||
| switch (descendant.Name.LocalName) | |||
| { | |||
| case "tab": | |||
| sb.Append("\t"); | |||
| break; | |||
| case "br": | |||
| sb.Append("\n"); | |||
| break; | |||
| case "t": | |||
| goto case "delText"; | |||
| case "delText": | |||
| sb.Append(descendant.Value); | |||
| break; | |||
| default: break; | |||
| } | |||
| } | |||
| } | |||
| HelperFunctions.GetText(Xml, sb); | |||
| return sb.ToString(); | |||
| } | |||
| } | |||
| @@ -3190,7 +3166,7 @@ namespace Novacode | |||
| } | |||
| } | |||
| internal class Run : DocXElement | |||
| public class Run : DocXElement | |||
| { | |||
| // A lookup for the text elements in this paragraph | |||
| Dictionary<int, Text> textLookup = new Dictionary<int, Text>(); | |||
| @@ -1311,7 +1311,11 @@ namespace Novacode | |||
| { | |||
| get | |||
| { | |||
| List<Paragraph> paragraphs = base.Paragraphs; | |||
| List<Paragraph> paragraphs = | |||
| ( | |||
| from p in Xml.Descendants(DocX.w + "p") | |||
| select new Paragraph(Document, p, 0) | |||
| ).ToList(); | |||
| foreach (Paragraph p in paragraphs) | |||
| p.PackagePart = table.mainPart; | |||
| @@ -22,7 +22,7 @@ namespace Novacode | |||
| /// </p> | |||
| /// </summary> | |||
| private XElement xml; | |||
| internal XElement Xml { get { return xml; } set { xml = value; } } | |||
| public XElement Xml { get { return xml; } set { xml = value; } } | |||
| /// <summary> | |||
| /// This is a reference to the DocX object that this element belongs to. | |||
| @@ -4,6 +4,7 @@ using System.Linq; | |||
| using System.Text; | |||
| using System.Drawing; | |||
| using System.IO; | |||
| using System.Xml.Linq; | |||
| namespace Novacode | |||
| { | |||
| @@ -29,5 +30,36 @@ namespace Novacode | |||
| return string.Format("{0}{1}{2}", redHex, greenHex, blueHex); | |||
| } | |||
| public static void Flatten(this XElement e, XName name, List<XElement> flat) | |||
| { | |||
| // Add this element (without its children) to the flat list. | |||
| XElement clone = CloneElement(e); | |||
| clone.Elements().Remove(); | |||
| // Filter elements using XName. | |||
| if (clone.Name == name) | |||
| flat.Add(clone); | |||
| // Process the children. | |||
| if (e.HasElements) | |||
| foreach (XElement elem in e.Elements(name)) // Filter elements using XName | |||
| elem.Flatten(name, flat); | |||
| } | |||
| static XElement CloneElement(XElement element) | |||
| { | |||
| return new XElement(element.Name, | |||
| element.Attributes(), | |||
| element.Nodes().Select(n => | |||
| { | |||
| XElement e = n as XElement; | |||
| if (e != null) | |||
| return CloneElement(e); | |||
| return n; | |||
| } | |||
| ) | |||
| ); | |||
| } | |||
| } | |||
| } | |||