using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.IO.Packaging;
using System.IO;
namespace Novacode
{
public abstract class Container : DocXElement
{
///
/// Returns a list of all Paragraphs inside this container.
///
///
///
/// Load a document.
/// using (DocX document = DocX.Load(@"Test.docx"))
/// {
/// // All Paragraphs in this document.
/// List documentParagraphs = document.Paragraphs;
///
/// // Make sure this document contains at least one Table.
/// if (document.Tables.Count() > 0)
/// {
/// // Get the first Table in this document.
/// Table t = document.Tables[0];
///
/// // All Paragraphs in this Table.
/// List tableParagraphs = t.Paragraphs;
///
/// // Make sure this Table contains at least one Row.
/// if (t.Rows.Count() > 0)
/// {
/// // Get the first Row in this document.
/// Row r = t.Rows[0];
///
/// // All Paragraphs in this Row.
/// List rowParagraphs = r.Paragraphs;
///
/// // Make sure this Row contains at least one Cell.
/// if (r.Cells.Count() > 0)
/// {
/// // Get the first Cell in this document.
/// Cell c = r.Cells[0];
///
/// // All Paragraphs in this Cell.
/// List cellParagraphs = c.Paragraphs;
/// }
/// }
/// }
///
/// // Save all changes to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
public virtual List Paragraphs
{
get
{
List paragraphs = GetParagraphs();
foreach (var p in paragraphs)
{
if ((p.Xml.ElementsAfterSelf().FirstOrDefault() != null) && (p.Xml.ElementsAfterSelf().First().Name.Equals(DocX.w + "tbl")))
p.FollowingTable = new Table(this.Document, p.Xml.ElementsAfterSelf().First());
}
return paragraphs;
}
}
internal List GetParagraphs()
{
// Need some memory that can be updated by the recursive search.
int index = 0;
List paragraphs = new List();
GetParagraphsRecursive(Xml, ref index, ref paragraphs);
return paragraphs;
}
internal void GetParagraphsRecursive(XElement Xml, ref int index, ref List paragraphs)
{
// sdtContent are for PageNumbers inside Headers or Footers, don't go any deeper.
//if (Xml.Name.LocalName == "sdtContent")
// return;
if (Xml.Name.LocalName == "p")
{
paragraphs.Add(new Paragraph(Document, Xml, index));
index += HelperFunctions.GetText(Xml).Length;
}
else
{
if (Xml.HasElements)
foreach (XElement e in Xml.Elements())
GetParagraphsRecursive(e, ref index, ref paragraphs);
}
}
public virtual List
Tables
{
get
{
List
tables =
(
from t in Xml.Descendants(DocX.w + "tbl")
select new Table(Document, t)
).ToList();
return tables;
}
}
public virtual List Hyperlinks
{
get
{
List hyperlinks = new List();
foreach (Paragraph p in Paragraphs)
hyperlinks.AddRange(p.Hyperlinks);
return hyperlinks;
}
}
public virtual List Pictures
{
get
{
List pictures = new List();
foreach (Paragraph p in Paragraphs)
pictures.AddRange(p.Pictures);
return pictures;
}
}
///
/// Sets the Direction of content.
///
/// Direction either LeftToRight or RightToLeft
///
/// Set the Direction of content in a Paragraph to RightToLeft.
///
/// // Load a document.
/// using (DocX document = DocX.Load(@"Test.docx"))
/// {
/// // Get the first Paragraph from this document.
/// Paragraph p = document.InsertParagraph();
///
/// // Set the Direction of this Paragraph.
/// p.Direction = Direction.RightToLeft;
///
/// // Make sure the document contains at lest one Table.
/// if (document.Tables.Count() > 0)
/// {
/// // Get the first Table from this document.
/// Table t = document.Tables[0];
///
/// /*
/// * Set the direction of the entire Table.
/// * Note: The same function is available at the Row and Cell level.
/// */
/// t.SetDirection(Direction.RightToLeft);
/// }
///
/// // Save all changes to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
public virtual void SetDirection(Direction direction)
{
foreach (Paragraph p in Paragraphs)
p.Direction = direction;
}
public virtual List FindAll(string str)
{
return FindAll(str, RegexOptions.None);
}
public virtual List FindAll(string str, RegexOptions options)
{
List list = new List();
foreach (Paragraph p in Paragraphs)
{
List indexes = p.FindAll(str, options);
for (int i = 0; i < indexes.Count(); i++)
indexes[0] += p.startIndex;
list.AddRange(indexes);
}
return list;
}
///
/// Find all unique instances of the given Regex Pattern,
/// returning the list of the unique strings found
///
///
///
///
public virtual List FindUniqueByPattern(string pattern, RegexOptions options)
{
List rawResults = new List();
foreach (Paragraph p in Paragraphs)
{ // accumulate the search results from all paragraphs
List partials = p.FindAllByPattern(pattern, options);
rawResults.AddRange(partials);
}
// this dictionary is used to collect results and test for uniqueness
Dictionary uniqueResults = new Dictionary();
foreach (string currValue in rawResults)
{
if (!uniqueResults.ContainsKey(currValue))
{ // if the dictionary doesn't have it, add it
uniqueResults.Add(currValue, 0);
}
}
return uniqueResults.Keys.ToList(); // return the unique list of results
}
public virtual void ReplaceText(string oldValue, string newValue, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch)
{
// ReplaceText in Headers of the document.
Headers headers = Document.Headers;
List headerList = new List { headers.first, headers.even, headers.odd };
foreach (Header h in headerList)
if (h != null)
foreach (Paragraph p in h.Paragraphs)
p.ReplaceText(oldValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo);
// ReplaceText int main body of document.
foreach (Paragraph p in Paragraphs)
p.ReplaceText(oldValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo);
// ReplaceText in Footers of the document.
Footers footers = Document.Footers;
List