using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Security.Principal;
using System.Collections;
namespace Novacode
{
///
/// Represents a document paragraph.
///
public class Paragraph
{
// This paragraphs text alignment
private Alignment alignment;
// A lookup for the runs in this paragraph
Dictionary runLookup = new Dictionary();
// The underlying XElement which this Paragraph wraps
internal XElement xml;
internal int startIndex, endIndex;
// A collection of Images in this Paragraph
private List pictures;
///
/// Returns a list of Pictures in this Paragraph.
///
public List Pictures { get { return pictures; } }
DocX document;
internal Paragraph(DocX document, int startIndex, XElement p)
{
this.document = document;
this.startIndex = startIndex;
this.endIndex = startIndex + GetElementTextLength(p);
this.xml = p;
BuildRunLookup(p);
// Get all of the images in this document
pictures = (from i in p.Descendants(XName.Get("drawing", DocX.w.NamespaceName))
select new Picture(i)).ToList();
}
///
/// Gets or set this Paragraphs text alignment.
///
public Alignment Alignment
{
get { return alignment; }
set
{
alignment = value;
XElement pPr = xml.Element(XName.Get("pPr", DocX.w.NamespaceName));
if (alignment != Novacode.Alignment.left)
{
if (pPr == null)
xml.Add(new XElement(XName.Get("pPr", DocX.w.NamespaceName)));
pPr = xml.Element(XName.Get("pPr", DocX.w.NamespaceName));
XElement jc = pPr.Element(XName.Get("jc", DocX.w.NamespaceName));
if(jc == null)
pPr.Add(new XElement(XName.Get("jc", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), alignment.ToString())));
else
jc.Attribute(XName.Get("val", DocX.w.NamespaceName)).Value = alignment.ToString();
}
else
{
if (pPr != null)
{
XElement jc = pPr.Element(XName.Get("jc", DocX.w.NamespaceName));
if (jc != null)
jc.Remove();
}
}
}
}
///
/// Remove this Paragraph from the document.
///
/// Should this remove be tracked as a change?
///
/// Remove a Paragraph from a document and track it as a change.
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Create and Insert a new Paragraph into this document.
/// Paragraph p = document.InsertParagraph("Hello", false);
///
/// // Remove the Paragraph and track this as a change.
/// p.Remove(true);
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
public void Remove(bool trackChanges)
{
if (trackChanges)
{
DateTime now = DateTime.Now.ToUniversalTime();
List elements = xml.Elements().ToList();
List temp = new List();
for (int i = 0; i < elements.Count(); i++ )
{
XElement e = elements[i];
if (e.Name.LocalName != "del")
{
temp.Add(e);
e.Remove();
}
else
{
if (temp.Count() > 0)
{
e.AddBeforeSelf(CreateEdit(EditType.del, now, temp.Elements()));
temp.Clear();
}
}
}
if (temp.Count() > 0)
xml.Add(CreateEdit(EditType.del, now, temp));
}
else
{
runLookup.Clear();
if (xml.Parent.Name.LocalName == "tc")
xml.Value = string.Empty;
else
{
// Remove this paragraph from the document
xml.Remove();
xml = null;
runLookup = null;
}
}
DocX.RebuildParagraphs(document);
}
private void BuildRunLookup(XElement p)
{
// Get the runs in this paragraph
IEnumerable runs = p.Descendants(XName.Get("r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"));
int startIndex = 0;
// Loop through each run in this paragraph
foreach (XElement run in runs)
{
// Only add runs which contain text
if (GetElementTextLength(run) > 0)
{
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
}
}
}
///
/// Gets the text value of this Paragraph.
///
public string Text
{
// Returns the underlying XElement's Value property.
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;
}
}
}
return sb.ToString();
}
}
//public Picture InsertPicture(Picture picture)
//{
// Picture newPicture = picture;
// newPicture.i = new XElement(picture.i);
// xml.Add(newPicture.i);
// pictures.Add(newPicture);
// return newPicture;
//}
///
/// Insert a Picture at the end of this paragraph.
///
/// A string to describe this Picture.
/// The unique id that identifies the Image this Picture represents.
/// The name of this image.
/// A Picture.
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add a new Paragraph to this document.
/// Paragraph p = document.InsertParagraph("Here is Picture 1", false);
///
/// // Add an Image to this document.
/// Novacode.Image img = document.AddImage(@"Image.jpg");
///
/// // Insert pic at the end of Paragraph p.
/// Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked.");
///
/// // Rotate the Picture clockwise by 30 degrees.
/// pic.Rotation = 30;
///
/// // Resize the Picture.
/// pic.Width = 400;
/// pic.Height = 300;
///
/// // Set the shape of this Picture to be a cube.
/// pic.SetPictureShape(BasicShapes.cube);
///
/// // Flip the Picture Horizontally.
/// pic.FlipHorizontal = true;
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
public Picture InsertPicture(string imageID, string name, string description)
{
Picture p = new Picture(document, imageID, name, description);
xml.Add(p.i);
pictures.Add(p);
return p;
}
//public Picture InsertPicture(int index, Picture picture)
//{
// Picture p = picture;
// p.i = new XElement(picture.i);
// Run run = GetFirstRunEffectedByEdit(index);
// if (run == null)
// xml.Add(p.i);
// else
// {
// // Split this run at the point you want to insert
// XElement[] splitRun = Run.SplitRun(run, index);
// // Replace the origional run
// run.xml.ReplaceWith
// (
// splitRun[0],
// p.i,
// splitRun[1]
// );
// }
// // Rebuild the run lookup for this paragraph
// runLookup.Clear();
// BuildRunLookup(xml);
// DocX.RenumberIDs(document);
// return p;
//}
///
/// Insert a Picture into this Paragraph at a specified index.
///
/// A string to describe this Picture.
/// The unique id that identifies the Image this Picture represents.
/// The name of this image.
/// The index to insert this Picture at.
/// A Picture.
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add a new Paragraph to this document.
/// Paragraph p = document.InsertParagraph("Here is Picture 1", false);
///
/// // Add an Image to this document.
/// Novacode.Image img = document.AddImage(@"Image.jpg");
///
/// // Insert pic at the start of Paragraph p.
/// Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked.");
///
/// // Rotate the Picture clockwise by 30 degrees.
/// pic.Rotation = 30;
///
/// // Resize the Picture.
/// pic.Width = 400;
/// pic.Height = 300;
///
/// // Set the shape of this Picture to be a cube.
/// pic.SetPictureShape(BasicShapes.cube);
///
/// // Flip the Picture Horizontally.
/// pic.FlipHorizontal = true;
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
public Picture InsertPicture(int index, string imageID, string name, string description)
{
Picture picture = new Picture(document, imageID, name, description);
Run run = GetFirstRunEffectedByEdit(index);
if (run == null)
xml.Add(picture.i);
else
{
// Split this run at the point you want to insert
XElement[] splitRun = Run.SplitRun(run, index);
// Replace the origional run
run.xml.ReplaceWith
(
splitRun[0],
picture.i,
splitRun[1]
);
}
// Rebuild the run lookup for this paragraph
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs(document);
return picture;
}
///
/// Creates an Edit either a ins or a del with the specified content and date
///
/// The type of this edit (ins or del)
/// The time stamp to use for this edit
/// The initial content of this edit
///
private XElement CreateEdit(EditType t, DateTime edit_time, object content)
{
if (t == EditType.del)
{
foreach (object o in (IEnumerable)content)
{
if (o is XElement)
{
XElement e = (o as XElement);
IEnumerable ts = e.DescendantsAndSelf(XName.Get("t", DocX.w.NamespaceName));
for(int i = 0; i < ts.Count(); i ++)
{
XElement text = ts.ElementAt(i);
text.ReplaceWith(new XElement(DocX.w + "delText", text.Attributes(), text.Value));
}
}
}
}
return
(
new XElement(DocX.w + t.ToString(),
new XAttribute(DocX.w + "id", 0),
new XAttribute(DocX.w + "author", WindowsIdentity.GetCurrent().Name),
new XAttribute(DocX.w + "date", edit_time),
content)
);
}
internal Run GetFirstRunEffectedByEdit(int index)
{
foreach (int runEndIndex in runLookup.Keys)
{
if (runEndIndex > index)
return runLookup[runEndIndex];
}
if (runLookup.Last().Value.EndIndex == index)
return runLookup.Last().Value;
throw new ArgumentOutOfRangeException();
}
internal Run GetFirstRunEffectedByInsert(int index)
{
// This paragraph contains no Runs and insertion is at index 0
if (runLookup.Keys.Count() == 0 && index == 0)
return null;
foreach (int runEndIndex in runLookup.Keys)
{
if (runEndIndex >= index)
return runLookup[runEndIndex];
}
throw new ArgumentOutOfRangeException();
}
private List FormatInput(string text, XElement rPr)
{
// Need to support /n as non breaking space
List newRuns = new List();
XElement tabRun = new XElement(DocX.w + "tab");
string[] runTexts = text.Split('\t');
XElement firstRun;
if (runTexts[0] != String.Empty)
{
XElement firstText = new XElement(DocX.w + "t", runTexts[0]);
Novacode.Text.PreserveSpace(firstText);
firstRun = new XElement(DocX.w + "r", rPr, firstText);
newRuns.Add(firstRun);
}
if (runTexts.Length > 1)
{
for (int k = 1; k < runTexts.Length; k++)
{
XElement newText = new XElement(DocX.w + "t", runTexts[k]);
XElement newRun;
if (runTexts[k] == String.Empty)
newRun = new XElement(DocX.w + "r", tabRun);
else
{
// Value begins or ends with a space
Novacode.Text.PreserveSpace(newText);
newRun = new XElement(DocX.w + "r", rPr, tabRun, newText);
}
newRuns.Add(newRun);
}
}
return newRuns;
}
static internal int GetElementTextLength(XElement run)
{
int count = 0;
if (run == null)
return count;
foreach (var d in run.Descendants())
{
switch (d.Name.LocalName)
{
case "tab": goto case "br";
case "br": count++; break;
case "t": goto case "delText";
case "delText": count += d.Value.Length; break;
default: break;
}
}
return count;
}
internal XElement[] SplitEdit(XElement edit, int index, EditType type)
{
Run run;
if(type == EditType.del)
run = GetFirstRunEffectedByEdit(index);
else
run = GetFirstRunEffectedByInsert(index);
XElement[] splitRun = Run.SplitRun(run, index);
XElement splitLeft = new XElement(edit.Name, edit.Attributes(), run.xml.ElementsBeforeSelf(), splitRun[0]);
if (GetElementTextLength(splitLeft) == 0)
splitLeft = null;
XElement splitRight = new XElement(edit.Name, edit.Attributes(), splitRun[1], run.xml.ElementsAfterSelf());
if (GetElementTextLength(splitRight) == 0)
splitRight = null;
return
(
new XElement[]
{
splitLeft,
splitRight
}
);
}
///
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText(0, "Start: ", true);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
/// Inserting tabs using the \t switch.
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tStart:\t" at the begining of every paragraph and flag it as a change.
/// p.InsertText(0, "\tStart:\t", true);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
/// The index position of the insertion.
/// The System.String to insert.
/// Flag this insert as a change.
public void InsertText(int index, string value, bool trackChanges)
{
InsertText(index, value, trackChanges, null);
}
///
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "End: " at the end of every Paragraph and flag it as a change.
/// p.InsertText("End: ", true);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
/// Inserting tabs using the \t switch.
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tEnd" at the end of every paragraph and flag it as a change.
/// p.InsertText("\tEnd", true);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
/// The System.String to insert.
/// Flag this insert as a change.
public void InsertText(string value, bool trackChanges)
{
List newRuns = FormatInput(value, null);
xml.Add(newRuns);
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs(document);
}
///
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText("Start: ", true, f);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
/// Inserting tabs using the \t switch.
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tEnd" at the end of every paragraph and flag it as a change.
/// p.InsertText("\tEnd", true, f);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
/// The System.String to insert.
/// Flag this insert as a change.
/// The text formatting.
public void InsertText(string value, bool trackChanges, Formatting formatting)
{
List newRuns = FormatInput(value, formatting.Xml);
xml.Add(newRuns);
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs(document);
}
///
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText(0, "Start: ", true, f);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
/// Inserting tabs using the \t switch.
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tStart:\t" at the begining of every paragraph and flag it as a change.
/// p.InsertText(0, "\tStart:\t", true, f);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
/// The index position of the insertion.
/// The System.String to insert.
/// Flag this insert as a change.
/// The text formatting.
public void InsertText(int index, string value, bool trackChanges, Formatting formatting)
{
// Timestamp to mark the start of insert
DateTime now = DateTime.Now;
DateTime insert_datetime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);
// Get the first run effected by this Insert
Run run = GetFirstRunEffectedByInsert(index);
if (run == null)
{
object insert;
if (formatting != null)
insert = FormatInput(value, formatting.Xml);
else
insert = FormatInput(value, null);
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, insert);
xml.Add(insert);
}
else
{
object newRuns;
if (formatting != null)
newRuns = FormatInput(value, formatting.Xml);
else
newRuns = FormatInput(value, run.xml.Element(XName.Get("rPr", DocX.w.NamespaceName)));
// The parent of this Run
XElement parentElement = run.xml.Parent;
switch (parentElement.Name.LocalName)
{
case "ins":
{
// The datetime that this ins was created
DateTime parent_ins_date = DateTime.Parse(parentElement.Attribute(XName.Get("date", DocX.w.NamespaceName)).Value);
/*
* Special case: You want to track changes,
* and the first Run effected by this insert
* has a datetime stamp equal to now.
*/
if (trackChanges && parent_ins_date.CompareTo(insert_datetime) == 0)
{
/*
* Inserting into a non edit and this special case, is the same procedure.
*/
goto default;
}
/*
* If not the special case above,
* then inserting into an ins or a del, is the same procedure.
*/
goto case "del";
}
case "del":
{
object insert = newRuns;
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, newRuns);
// Split this Edit at the point you want to insert
XElement[] splitEdit = SplitEdit(parentElement, index, EditType.ins);
// Replace the origional run
parentElement.ReplaceWith
(
splitEdit[0],
insert,
splitEdit[1]
);
break;
}
default:
{
object insert = newRuns;
if (trackChanges && !parentElement.Name.LocalName.Equals("ins"))
insert = CreateEdit(EditType.ins, insert_datetime, newRuns);
// Split this run at the point you want to insert
XElement[] splitRun = Run.SplitRun(run, index);
// Replace the origional run
run.xml.ReplaceWith
(
splitRun[0],
insert,
splitRun[1]
);
break;
}
}
}
// Rebuild the run lookup for this paragraph
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs(document);
}
///
/// Removes characters from a Novacode.DocX.Paragraph.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Remove the first two characters from every paragraph
/// p.RemoveText(0, 2, false);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
///
///
/// The position to begin deleting characters.
/// The number of characters to delete
/// Track changes
public void RemoveText(int index, int count, bool trackChanges)
{
// Timestamp to mark the start of insert
DateTime now = DateTime.Now;
DateTime remove_datetime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);
// The number of characters processed so far
int processed = 0;
do
{
// Get the first run effected by this Remove
Run run = GetFirstRunEffectedByEdit(index + processed);
// The parent of this Run
XElement parentElement = run.xml.Parent;
switch (parentElement.Name.LocalName)
{
case "ins":
{
XElement[] splitEditBefore = SplitEdit(parentElement, index + processed, EditType.del);
int min = Math.Min(count - processed, run.xml.ElementsAfterSelf().Sum(e => GetElementTextLength(e)));
XElement[] splitEditAfter = SplitEdit(parentElement, index + processed + min, EditType.del);
XElement temp = SplitEdit(splitEditBefore[1], index + processed + min, EditType.del)[0];
object middle = CreateEdit(EditType.del, remove_datetime, temp.Elements());
processed += GetElementTextLength(middle as XElement);
if (!trackChanges)
middle = null;
parentElement.ReplaceWith
(
splitEditBefore[0],
middle,
splitEditAfter[1]
);
processed += GetElementTextLength(middle as XElement);
break;
}
case "del":
{
if (trackChanges)
{
// You cannot delete from a deletion, advance processed to the end of this del
processed += GetElementTextLength(parentElement);
}
else
goto case "ins";
break;
}
default:
{
XElement[] splitRunBefore = Run.SplitRun(run, index + processed);
int min = Math.Min(index + processed + (count - processed), run.EndIndex);
XElement[] splitRunAfter = Run.SplitRun(run, min);
object middle = CreateEdit(EditType.del, remove_datetime, new List() { Run.SplitRun(new Run(run.StartIndex + GetElementTextLength(splitRunBefore[0]), splitRunBefore[1]), min)[0] });
processed += GetElementTextLength(middle as XElement);
if (!trackChanges)
middle = null;
run.xml.ReplaceWith
(
splitRunBefore[0],
middle,
splitRunAfter[1]
);
break;
}
}
// If after this remove the parent element is empty, remove it.
if (GetElementTextLength(parentElement) == 0)
{
if (parentElement.Parent != null && parentElement.Parent.Name.LocalName != "tc")
parentElement.Remove();
}
}
while (processed < count);
// Rebuild the run lookup
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs(document);
}
///
/// Removes characters from a Novacode.DocX.Paragraph.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Remove all but the first 2 characters from this Paragraph.
/// p.RemoveText(2, false);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
///
///
/// The position to begin deleting characters.
/// Track changes
public void RemoveText(int index, bool trackChanges)
{
RemoveText(index, Text.Length - index, trackChanges);
}
///
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Replace all instances of the string "wrong" with the string "right" and ignore case.
/// p.ReplaceText("wrong", "right", false, RegexOptions.IgnoreCase);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
///
///
/// A System.String to replace all occurances of oldValue.
/// A System.String to be replaced.
/// A bitwise OR combination of RegexOption enumeration options.
/// Track changes
public void ReplaceText(string oldValue, string newValue, bool trackChanges, RegexOptions options)
{
MatchCollection mc = Regex.Matches(this.Text, Regex.Escape(oldValue), options);
// Loop through the matches in reverse order
foreach (Match m in mc.Cast().Reverse())
{
InsertText(m.Index + oldValue.Length, newValue, trackChanges);
RemoveText(m.Index, m.Length, trackChanges);
}
}
///
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
///
///
///
/// // Create a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Replace all instances of the string "wrong" with the string "right".
/// p.ReplaceText("wrong", "right", false);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
///
///
///
///
///
///
///
///
/// A System.String to replace all occurances of oldValue.
/// A System.String to be replaced.
/// Track changes
public void ReplaceText(string oldValue, string newValue, bool trackChanges)
{
ReplaceText(oldValue, newValue, trackChanges, RegexOptions.None);
}
}
}