Sfoglia il codice sorgente

Added the independent Font implementation

master
Maxim Korsukov 9 anni fa
parent
commit
f3298e0dc5
8 ha cambiato i file con 348 aggiunte e 294 eliminazioni
  1. 56
    55
      DocX/Container.cs
  2. 1
    1
      DocX/DocX.cs
  3. 1
    0
      DocX/DocX.csproj
  4. 38
    0
      DocX/Font.cs
  5. 3
    3
      DocX/Formatting.cs
  6. 184
    173
      DocX/Paragraph.cs
  7. 44
    40
      Examples/Program.cs
  8. 21
    22
      UnitTests/DocXUnitTests.cs

+ 56
- 55
DocX/Container.cs Vedi File

@@ -18,7 +18,7 @@ namespace Novacode
{
List<Content> contents = GetContents();
return contents.AsReadOnly();
}
@@ -129,9 +129,9 @@ namespace Novacode
return true;
}
++i;
}
return false;
}
@@ -204,32 +204,32 @@ namespace Novacode
//find num node in numbering
var numNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "num");
XElement numNode = numNodes.FirstOrDefault(node => node.Attribute(DocX.w + "numId").Value.Equals(numIdValue));
if (numNode != null)
if (numNode != null)
{
//Get abstractNumId node and its value from numNode
var abstractNumIdNode = numNode.Descendants().First(n => n.Name.LocalName == "abstractNumId");
var abstractNumNodeValue = abstractNumIdNode.Attribute(DocX.w + "val").Value;
var abstractNumNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "abstractNum");
XElement abstractNumNode =
abstractNumNodes.FirstOrDefault(node => node.Attribute(DocX.w + "abstractNumId").Value.Equals(abstractNumNodeValue));
//Find lvl node
var lvlNodes = abstractNumNode.Descendants().Where(n => n.Name.LocalName == "lvl");
XElement lvlNode = null;
foreach (XElement node in lvlNodes)
{
if (node.Attribute(DocX.w + "ilvl").Value.Equals(ilvlValue))
{
lvlNode = node;
break;
}
}
var numFmtNode = lvlNode.Descendants().First(n => n.Name.LocalName == "numFmt");
p.ListItemType = GetListItemType(numFmtNode.Attribute(DocX.w + "val").Value);
}
//Get abstractNumId node and its value from numNode
var abstractNumIdNode = numNode.Descendants().First(n => n.Name.LocalName == "abstractNumId");
var abstractNumNodeValue = abstractNumIdNode.Attribute(DocX.w + "val").Value;
var abstractNumNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "abstractNum");
XElement abstractNumNode =
abstractNumNodes.FirstOrDefault(node => node.Attribute(DocX.w + "abstractNumId").Value.Equals(abstractNumNodeValue));
//Find lvl node
var lvlNodes = abstractNumNode.Descendants().Where(n => n.Name.LocalName == "lvl");
XElement lvlNode = null;
foreach (XElement node in lvlNodes)
{
if (node.Attribute(DocX.w + "ilvl").Value.Equals(ilvlValue))
{
lvlNode = node;
break;
}
}
var numFmtNode = lvlNode.Descendants().First(n => n.Name.LocalName == "numFmt");
p.ListItemType = GetListItemType(numFmtNode.Attribute(DocX.w + "val").Value);
}
}
@@ -263,13 +263,13 @@ namespace Novacode
}
catch (Exception)
{
val = "Missing";
val = "Missing";
}
return val;
}
internal List<Paragraph> GetParagraphs(bool deepSearch=false)
internal List<Paragraph> GetParagraphs(bool deepSearch = false)
{
// Need some memory that can be updated by the recursive search.
int index = 0;
@@ -280,12 +280,12 @@ namespace Novacode
Paragraph paragraph = new Paragraph(Document, e, index);
paragraphs.Add(paragraph);
}
// GetParagraphsRecursive(Xml, ref index, ref paragraphs, deepSearch);
// GetParagraphsRecursive(Xml, ref index, ref paragraphs, deepSearch);
return paragraphs;
}
internal void GetParagraphsRecursive(XElement Xml, ref int index, ref List<Paragraph> paragraphs, bool deepSearch=false)
internal void GetParagraphsRecursive(XElement Xml, ref int index, ref List<Paragraph> paragraphs, bool deepSearch = false)
{
// sdtContent are for PageNumbers inside Headers or Footers, don't go any deeper.
//if (Xml.Name.LocalName == "sdtContent")
@@ -508,14 +508,14 @@ namespace Novacode
/// <param name="newFormatting"></param>
/// <param name="matchFormatting"></param>
/// <param name="formattingOptions"></param>
public virtual void ReplaceText(string searchValue, Func<string,string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions formattingOptions = MatchFormattingOptions.SubsetMatch)
public virtual void ReplaceText(string searchValue, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions formattingOptions = MatchFormattingOptions.SubsetMatch)
{
if (string.IsNullOrEmpty(searchValue))
throw new ArgumentException("oldValue cannot be null or empty", "searchValue");
if (regexMatchHandler == null)
throw new ArgumentException("regexMatchHandler cannot be null", "regexMatchHandler");
// ReplaceText in Headers/Footers of the document.
var containerList = new List<IParagraphContainer> {
Document.Headers.first, Document.Headers.even, Document.Headers.odd,
@@ -588,8 +588,8 @@ namespace Novacode
public string[] ValidateBookmarks(params string[] bookmarkNames)
{
var headers = new[] {Document.Headers.first, Document.Headers.even, Document.Headers.odd}.Where(h => h != null).ToList();
var footers = new[] {Document.Footers.first, Document.Footers.even, Document.Footers.odd}.Where(f => f != null).ToList();
var headers = new[] { Document.Headers.first, Document.Headers.even, Document.Headers.odd }.Where(h => h != null).ToList();
var footers = new[] { Document.Footers.first, Document.Footers.even, Document.Footers.odd }.Where(f => f != null).ToList();
var nonMatching = new List<string>();
foreach (var bookmarkName in bookmarkNames)
@@ -599,7 +599,7 @@ namespace Novacode
if (Paragraphs.Any(p => p.ValidateBookmark(bookmarkName))) return new string[0];
nonMatching.Add(bookmarkName);
}
return nonMatching.ToArray();
}
@@ -719,21 +719,22 @@ namespace Novacode
if (firstPar != null)
{
var splitindex = index - firstPar.startIndex;
if (splitindex <= 0)
{
firstPar.Xml.ReplaceWith(newParagraph.Xml, firstPar.Xml);
}
else {
XElement[] splitParagraph = HelperFunctions.SplitParagraph(firstPar, splitindex);
firstPar.Xml.ReplaceWith
(
splitParagraph[0],
newParagraph.Xml,
splitParagraph[1]
);
}
var splitindex = index - firstPar.startIndex;
if (splitindex <= 0)
{
firstPar.Xml.ReplaceWith(newParagraph.Xml, firstPar.Xml);
}
else
{
XElement[] splitParagraph = HelperFunctions.SplitParagraph(firstPar, splitindex);
firstPar.Xml.ReplaceWith
(
splitParagraph[0],
newParagraph.Xml,
splitParagraph[1]
);
}
}
else
@@ -929,7 +930,7 @@ namespace Novacode
XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount);
Xml.Add(newTable);
return new Table(Document, newTable) { mainPart = mainPart};
return new Table(Document, newTable) { mainPart = mainPart };
}
public Table InsertTable(int index, int rowCount, int columnCount)
@@ -1017,7 +1018,7 @@ namespace Novacode
return list;
}
public List InsertList(List list, System.Drawing.FontFamily fontFamily, double fontSize)
public List InsertList(List list, Font fontFamily, double fontSize)
{
foreach (var item in list.Items)
{
@@ -1041,4 +1042,4 @@ namespace Novacode
return list;
}
}
}
}

+ 1
- 1
DocX/DocX.cs Vedi File

@@ -2063,7 +2063,7 @@ namespace Novacode
base.InsertList(list);
return list;
}
public new List InsertList(List list, System.Drawing.FontFamily fontFamily, double fontSize)
public new List InsertList(List list, Font fontFamily, double fontSize)
{
base.InsertList(list, fontFamily, fontSize);
return list;

+ 1
- 0
DocX/DocX.csproj Vedi File

@@ -105,6 +105,7 @@
<Compile Include="ContentCollection.cs" />
<Compile Include="DocumentTypes.cs" />
<Compile Include="ExtensionsHeadings.cs" />
<Compile Include="Font.cs" />
<Compile Include="Footers.cs" />
<Compile Include="Footer.cs" />
<Compile Include="CustomProperty.cs" />

+ 38
- 0
DocX/Font.cs Vedi File

@@ -0,0 +1,38 @@
using System;

namespace Novacode
{
/// <summary>
/// Represents a font family
/// </summary>
public sealed class Font
{
/// <summary>
/// Initializes a new instance of <see cref="Font" />
/// </summary>
/// <param name="name">The name of the font family</param>
public Font(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}

Name = name;
}

/// <summary>
/// The name of the font family
/// </summary>
public string Name { get; private set; }

/// <summary>
/// Returns a string representation of an object
/// </summary>
/// <returns>The name of the font family</returns>
public override string ToString()
{
return Name;
}
}
}

+ 3
- 3
DocX/Formatting.cs Vedi File

@@ -23,7 +23,7 @@ namespace Novacode
private UnderlineStyle? underlineStyle;
private Misc? misc;
private CapsStyle? capsStyle;
private FontFamily fontFamily;
private Font fontFamily;
private int? percentageScale;
private int? kerning;
private int? position;
@@ -133,7 +133,7 @@ namespace Novacode
case "rFonts":
formatting.FontFamily =
new FontFamily(
new Font(
option.GetAttribute(XName.Get("cs", DocX.w.NamespaceName), null) ??
option.GetAttribute(XName.Get("ascii", DocX.w.NamespaceName), null) ??
option.GetAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), null) ??
@@ -478,7 +478,7 @@ namespace Novacode
/// Bug found and fixed by krugs525 on August 12 2009.
/// Use TFS compare to see exact code change.
/// -->
public FontFamily FontFamily { get { return fontFamily; } set { fontFamily = value; } }
public Font FontFamily { get { return fontFamily; } set { fontFamily = value; } }
public int CompareTo(object obj)
{

+ 184
- 173
DocX/Paragraph.cs Vedi File

@@ -132,24 +132,24 @@ namespace Novacode
select new Picture(Document, p, img)
).ToList();
List<Picture> shapes =
(
from p in Xml.Descendants()
where (p.Name.LocalName == "pict")
let id =
(
from e in p.Descendants()
where e.Name.LocalName.Equals("imagedata")
select e.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
).SingleOrDefault()
where id != null
let img = new Image(Document, mainPart.GetRelationship(id))
select new Picture(Document, p, img)
).ToList();
foreach (Picture p in shapes)
pictures.Add(p);
List<Picture> shapes =
(
from p in Xml.Descendants()
where (p.Name.LocalName == "pict")
let id =
(
from e in p.Descendants()
where e.Name.LocalName.Equals("imagedata")
select e.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
).SingleOrDefault()
where id != null
let img = new Image(Document, mainPart.GetRelationship(id))
select new Picture(Document, p, img)
).ToList();
foreach (Picture p in shapes)
pictures.Add(p);
return pictures;
}
@@ -2002,66 +2002,67 @@ namespace Novacode
// Get the first run effected by this Insert
Run run = GetFirstRunEffectedByEdit(index);
if (run == null)
{
object insert;
if (formatting != null) //not sure how to get original formatting here when run == null
insert = HelperFunctions.FormatInput(value, formatting.Xml);
else
insert = HelperFunctions.FormatInput(value, null);
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, insert);
Xml.Add(insert);
}
else
{
object newRuns;
var rprel = run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName));
if (formatting != null)
{
//merge 2 formattings properly
Formatting finfmt = null;
Formatting oldfmt = null;
if (rprel != null)
{
oldfmt = Formatting.Parse(rprel);
}
if (oldfmt != null)
{
finfmt = oldfmt.Clone();
if (formatting.Bold.HasValue) { finfmt.Bold = formatting.Bold; }
if (formatting.CapsStyle.HasValue) { finfmt.CapsStyle = formatting.CapsStyle; }
if (formatting.FontColor.HasValue) { finfmt.FontColor = formatting.FontColor; }
finfmt.FontFamily = formatting.FontFamily;
if (formatting.Hidden.HasValue) { finfmt.Hidden = formatting.Hidden; }
if (formatting.Highlight.HasValue) { finfmt.Highlight = formatting.Highlight; }
if (formatting.Italic.HasValue) { finfmt.Italic = formatting.Italic; }
if (formatting.Kerning.HasValue) { finfmt.Kerning = formatting.Kerning; }
finfmt.Language = formatting.Language;
if (formatting.Misc.HasValue) { finfmt.Misc = formatting.Misc; }
if (formatting.PercentageScale.HasValue) { finfmt.PercentageScale = formatting.PercentageScale; }
if (formatting.Position.HasValue) { finfmt.Position = formatting.Position; }
if (formatting.Script.HasValue) { finfmt.Script = formatting.Script; }
if (formatting.Size.HasValue) { finfmt.Size = formatting.Size; }
if (formatting.Spacing.HasValue) { finfmt.Spacing = formatting.Spacing; }
if (formatting.StrikeThrough.HasValue) { finfmt.StrikeThrough = formatting.StrikeThrough; }
if (formatting.UnderlineColor.HasValue) { finfmt.UnderlineColor = formatting.UnderlineColor; }
if (formatting.UnderlineStyle.HasValue) { finfmt.UnderlineStyle = formatting.UnderlineStyle; }
}
else {
finfmt = formatting;
}
newRuns = HelperFunctions.FormatInput(value, finfmt.Xml);
}
else
{
newRuns = HelperFunctions.FormatInput(value, rprel);
}
if (run == null)
{
object insert;
if (formatting != null) //not sure how to get original formatting here when run == null
insert = HelperFunctions.FormatInput(value, formatting.Xml);
else
insert = HelperFunctions.FormatInput(value, null);
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, insert);
Xml.Add(insert);
}
else
{
object newRuns;
var rprel = run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName));
if (formatting != null)
{
//merge 2 formattings properly
Formatting finfmt = null;
Formatting oldfmt = null;
if (rprel != null)
{
oldfmt = Formatting.Parse(rprel);
}
if (oldfmt != null)
{
finfmt = oldfmt.Clone();
if (formatting.Bold.HasValue) { finfmt.Bold = formatting.Bold; }
if (formatting.CapsStyle.HasValue) { finfmt.CapsStyle = formatting.CapsStyle; }
if (formatting.FontColor.HasValue) { finfmt.FontColor = formatting.FontColor; }
finfmt.FontFamily = formatting.FontFamily;
if (formatting.Hidden.HasValue) { finfmt.Hidden = formatting.Hidden; }
if (formatting.Highlight.HasValue) { finfmt.Highlight = formatting.Highlight; }
if (formatting.Italic.HasValue) { finfmt.Italic = formatting.Italic; }
if (formatting.Kerning.HasValue) { finfmt.Kerning = formatting.Kerning; }
finfmt.Language = formatting.Language;
if (formatting.Misc.HasValue) { finfmt.Misc = formatting.Misc; }
if (formatting.PercentageScale.HasValue) { finfmt.PercentageScale = formatting.PercentageScale; }
if (formatting.Position.HasValue) { finfmt.Position = formatting.Position; }
if (formatting.Script.HasValue) { finfmt.Script = formatting.Script; }
if (formatting.Size.HasValue) { finfmt.Size = formatting.Size; }
if (formatting.Spacing.HasValue) { finfmt.Spacing = formatting.Spacing; }
if (formatting.StrikeThrough.HasValue) { finfmt.StrikeThrough = formatting.StrikeThrough; }
if (formatting.UnderlineColor.HasValue) { finfmt.UnderlineColor = formatting.UnderlineColor; }
if (formatting.UnderlineStyle.HasValue) { finfmt.UnderlineStyle = formatting.UnderlineStyle; }
}
else
{
finfmt = formatting;
}
newRuns = HelperFunctions.FormatInput(value, finfmt.Xml);
}
else
{
newRuns = HelperFunctions.FormatInput(value, rprel);
}
// The parent of this Run
XElement parentElement = run.Xml.Parent;
@@ -2384,7 +2385,7 @@ namespace Novacode
new XElement
(
XName.Get("r", DocX.w.NamespaceName),
new Formatting() { FontFamily = new System.Drawing.FontFamily("Cambria Math") }.Xml, // create formatting
new Formatting() { FontFamily = new Font("Cambria Math") }.Xml, // create formatting
new XElement(XName.Get("t", DocX.m.NamespaceName), equation) // create equation string
)
)
@@ -2437,7 +2438,7 @@ namespace Novacode
.Where(x => x.Attribute(XName.Get("name", DocX.w.NamespaceName)).Value == bookmarkName).SingleOrDefault();
if (bookmark != null)
{
var run = HelperFunctions.FormatInput(toInsert, null);
bookmark.AddBeforeSelf(run);
runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).ToList();
@@ -2973,13 +2974,23 @@ namespace Novacode
else
throw new ArgumentException("Size", "Value must be either a whole or half number, examples: 32, 32.5");
ApplyTextFormattingProperty(XName.Get("sz", DocX.w.NamespaceName), string.Empty, new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontSize * 2));
ApplyTextFormattingProperty(XName.Get("szCs", DocX.w.NamespaceName), string.Empty, new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontSize * 2));
return this;
}
/// <summary>
/// For use with Append() and AppendLine()
/// </summary>
/// <param name="fontName">The font to use for the appended text.</param>
/// <returns>This Paragraph with the last appended text's font changed.</returns>
public Paragraph Font(string fontName)
{
return Font(new Font(fontName));
}
/// <summary>
/// For use with Append() and AppendLine()
/// </summary>
@@ -3003,13 +3014,13 @@ namespace Novacode
/// }// Release this document from memory.
/// </code>
/// </example>
public Paragraph Font(FontFamily fontFamily)
public Paragraph Font(Font fontFamily)
{
ApplyTextFormattingProperty
(
XName.Get("rFonts", DocX.w.NamespaceName),
string.Empty,
new[]
new[]
{
new XAttribute(XName.Get("ascii", DocX.w.NamespaceName), fontFamily.Name),
new XAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), fontFamily.Name), // Added by Maurits Elbers to support non-standard characters. See http://docx.codeplex.com/Thread/View.aspx?ThreadId=70097&ANCHOR#Post453865
@@ -3809,62 +3820,62 @@ namespace Novacode
RemoveText(index, Text.Length - index, trackChanges);
}
/// <summary>
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
/// </summary>
/// <example>
/// <code>
/// // Load a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // The formatting to match.
/// Formatting matchFormatting = new Formatting();
/// matchFormatting.Size = 10;
/// matchFormatting.Italic = true;
/// matchFormatting.FontFamily = new FontFamily("Times New Roman");
///
/// // The formatting to apply to the inserted text.
/// Formatting newFormatting = new Formatting();
/// newFormatting.Size = 22;
/// newFormatting.UnderlineStyle = UnderlineStyle.dotted;
/// newFormatting.Bold = true;
///
/// // 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.
/// * Each inserted instance of "wrong" should use the Formatting newFormatting.
/// * Only replace an instance of "wrong" if it is Size 10, Italic and Times New Roman.
/// * SubsetMatch means that the formatting must contain all elements of the match formatting,
/// * but it can also contain additional formatting for example Color, UnderlineStyle, etc.
/// * ExactMatch means it must not contain additional formatting.
/// */
/// p.ReplaceText("wrong", "right", false, RegexOptions.IgnoreCase, newFormatting, matchFormatting, MatchFormattingOptions.SubsetMatch);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="newValue">A System.String to replace all occurrences of oldValue.</param>
/// <param name="oldValue">A System.String to be replaced.</param>
/// <param name="options">A bitwise OR combination of RegexOption enumeration options.</param>
/// <param name="trackChanges">Track changes</param>
/// <param name="newFormatting">The formatting to apply to the text being inserted.</param>
/// <param name="matchFormatting">The formatting that the text must match in order to be replaced.</param>
/// <param name="fo">How should formatting be matched?</param>
/// <param name="escapeRegEx">True if the oldValue needs to be escaped, otherwise false. If it represents a valid RegEx pattern this should be false.</param>
/// <param name="useRegExSubstitutions">True if RegEx-like replace should be performed, i.e. if newValue contains RegEx substitutions. Does not perform named-group substitutions (only numbered groups).</param>
public void ReplaceText(string oldValue, string newValue, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, bool escapeRegEx = true, bool useRegExSubstitutions = false)
/// <summary>
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
/// </summary>
/// <example>
/// <code>
/// // Load a document using a relative filename.
/// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
/// {
/// // The formatting to match.
/// Formatting matchFormatting = new Formatting();
/// matchFormatting.Size = 10;
/// matchFormatting.Italic = true;
/// matchFormatting.FontFamily = new FontFamily("Times New Roman");
///
/// // The formatting to apply to the inserted text.
/// Formatting newFormatting = new Formatting();
/// newFormatting.Size = 22;
/// newFormatting.UnderlineStyle = UnderlineStyle.dotted;
/// newFormatting.Bold = true;
///
/// // 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.
/// * Each inserted instance of "wrong" should use the Formatting newFormatting.
/// * Only replace an instance of "wrong" if it is Size 10, Italic and Times New Roman.
/// * SubsetMatch means that the formatting must contain all elements of the match formatting,
/// * but it can also contain additional formatting for example Color, UnderlineStyle, etc.
/// * ExactMatch means it must not contain additional formatting.
/// */
/// p.ReplaceText("wrong", "right", false, RegexOptions.IgnoreCase, newFormatting, matchFormatting, MatchFormattingOptions.SubsetMatch);
/// }
///
/// // Save all changes made to this document.
/// document.Save();
/// }// Release this document from memory.
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="newValue">A System.String to replace all occurrences of oldValue.</param>
/// <param name="oldValue">A System.String to be replaced.</param>
/// <param name="options">A bitwise OR combination of RegexOption enumeration options.</param>
/// <param name="trackChanges">Track changes</param>
/// <param name="newFormatting">The formatting to apply to the text being inserted.</param>
/// <param name="matchFormatting">The formatting that the text must match in order to be replaced.</param>
/// <param name="fo">How should formatting be matched?</param>
/// <param name="escapeRegEx">True if the oldValue needs to be escaped, otherwise false. If it represents a valid RegEx pattern this should be false.</param>
/// <param name="useRegExSubstitutions">True if RegEx-like replace should be performed, i.e. if newValue contains RegEx substitutions. Does not perform named-group substitutions (only numbered groups).</param>
public void ReplaceText(string oldValue, string newValue, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, bool escapeRegEx = true, bool useRegExSubstitutions = false)
{
string tText = Text;
MatchCollection mc = Regex.Matches(tText, escapeRegEx ? Regex.Escape(oldValue) : oldValue, options);
string tText = Text;
MatchCollection mc = Regex.Matches(tText, escapeRegEx ? Regex.Escape(oldValue) : oldValue, options);
// Loop through the matches in reverse order
foreach (Match m in mc.Cast<Match>().Reverse())
@@ -3908,40 +3919,40 @@ namespace Novacode
// If the formatting matches, do the replace.
if (formattingMatch)
{
string repl = newValue;
//perform RegEx substitutions. Only named groups are not supported. Everything else is supported. However character escapes are not covered.
if (useRegExSubstitutions && !String.IsNullOrEmpty(repl))
{
repl = repl.Replace("$&", m.Value);
if (m.Groups.Count > 0)
{
int lastcap = 0;
for (int k = 0; k < m.Groups.Count; k++)
{
var g = m.Groups[k];
if ((g == null) || (g.Value == ""))
continue;
repl = repl.Replace("$" + k.ToString(), g.Value);
lastcap = k;
//cannot get named groups ATM
}
repl = repl.Replace("$+", m.Groups[lastcap].Value);
}
if (m.Index > 0)
{
repl = repl.Replace("$`", tText.Substring(0, m.Index));
}
if ((m.Index + m.Length) < tText.Length)
{
repl = repl.Replace("$'", tText.Substring(m.Index + m.Length));
}
repl = repl.Replace("$_", tText);
repl = repl.Replace("$$", "$");
}
if (!String.IsNullOrEmpty(repl))
InsertText(m.Index + m.Length, repl, trackChanges, newFormatting);
if (m.Length > 0)
RemoveText(m.Index, m.Length, trackChanges);
string repl = newValue;
//perform RegEx substitutions. Only named groups are not supported. Everything else is supported. However character escapes are not covered.
if (useRegExSubstitutions && !String.IsNullOrEmpty(repl))
{
repl = repl.Replace("$&", m.Value);
if (m.Groups.Count > 0)
{
int lastcap = 0;
for (int k = 0; k < m.Groups.Count; k++)
{
var g = m.Groups[k];
if ((g == null) || (g.Value == ""))
continue;
repl = repl.Replace("$" + k.ToString(), g.Value);
lastcap = k;
//cannot get named groups ATM
}
repl = repl.Replace("$+", m.Groups[lastcap].Value);
}
if (m.Index > 0)
{
repl = repl.Replace("$`", tText.Substring(0, m.Index));
}
if ((m.Index + m.Length) < tText.Length)
{
repl = repl.Replace("$'", tText.Substring(m.Index + m.Length));
}
repl = repl.Replace("$_", tText);
repl = repl.Replace("$$", "$");
}
if (!String.IsNullOrEmpty(repl))
InsertText(m.Index + m.Length, repl, trackChanges, newFormatting);
if (m.Length > 0)
RemoveText(m.Index, m.Length, trackChanges);
}
}
}
@@ -3956,7 +3967,7 @@ namespace Novacode
/// <param name="newFormatting"></param>
/// <param name="matchFormatting"></param>
/// <param name="fo"></param>
public void ReplaceText(string findPattern, Func<string,string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch)
public void ReplaceText(string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch)
{
var matchCollection = Regex.Matches(Text, findPattern, options);

+ 44
- 40
Examples/Program.cs Vedi File

@@ -1,20 +1,25 @@
using Novacode;
using System;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Threading.Tasks;
using Image = Novacode.Image;
using System.Xml.Linq;
using Novacode;
using WindowsBitmap = System.Drawing.Bitmap;
using WindowsBrushes = System.Drawing.Brushes;
using WindowsColor = System.Drawing.Color;
using WindowsFont = System.Drawing.Font;
using WindowsFontFamily = System.Drawing.FontFamily;
using WindowsGraphics = System.Drawing.Graphics;
using WindowsImageFormat = System.Drawing.Imaging.ImageFormat;
namespace Examples
{
class Program
{
private static Border BlankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, Color.White);
private static Border BlankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, WindowsColor.White);
static void Main(string[] args)
{
Setup();
@@ -124,7 +129,7 @@ namespace Examples
// Create and add series
Series s1 = new Series("Microsoft");
s1.Color = Color.GreenYellow;
s1.Color = WindowsColor.GreenYellow;
s1.Bind(company1, "Mounth", "Money");
c.AddSeries(s1);
Series s2 = new Series("Apple");
@@ -181,7 +186,7 @@ namespace Examples
// Create and add series
Series s1 = new Series("Microsoft");
s1.Color = Color.GreenYellow;
s1.Color = WindowsColor.GreenYellow;
s1.Bind(company1, "Mounth", "Money");
c.AddSeries(s1);
Series s2 = new Series("Apple");
@@ -211,7 +216,7 @@ namespace Examples
// Create and add series
Series s = new Series("Microsoft");
s.Color = Color.GreenYellow;
s.Color = WindowsColor.GreenYellow;
s.Bind(company1, "Mounth", "Money");
c.AddSeries(s);
@@ -224,6 +229,7 @@ namespace Examples
}
#endregion
/// <summary>
/// Load a document and set content controls.
/// </summary>
@@ -261,7 +267,7 @@ namespace Examples
document.SetContent(@"docs\elements.xml");
document.SaveAs(@"docs\ContentSetWithPath.docx");
}
}
@@ -279,7 +285,7 @@ namespace Examples
Paragraph pEquation1 = document.InsertEquation("x = y+z");
// Insert second Equation in this document and add formatting.
Paragraph pEquation2 = document.InsertEquation("x = (y+z)/t").FontSize(18).Color(Color.Blue);
Paragraph pEquation2 = document.InsertEquation("x = (y+z)/t").FontSize(18).Color(WindowsColor.Blue);
// Save this document to disk.
document.Save();
@@ -479,7 +485,7 @@ namespace Examples
picture.SetPictureShape(BasicShapes.cube);
// Insert a new Paragraph into the document.
Paragraph title = document.InsertParagraph().Append("Test").FontSize(20).Font(new FontFamily("Comic Sans MS"));
Paragraph title = document.InsertParagraph().Append("Test").FontSize(20).Font(new Font("Comic Sans MS"));
title.Alignment = Alignment.center;
// Insert a new Paragraph into the document.
@@ -559,7 +565,7 @@ namespace Examples
picture.SetPictureShape(BasicShapes.cube);
// Insert a new Paragraph into the document.
Paragraph title = document.InsertParagraph().Append("Test").FontSize(20).Font(new FontFamily("Comic Sans MS"));
Paragraph title = document.InsertParagraph().Append("Test").FontSize(20).Font(new Font("Comic Sans MS"));
title.Alignment = Alignment.center;
@@ -675,12 +681,10 @@ namespace Examples
// Create a document.
using (DocX document = DocX.Create(@"docs\DocumentsWithListsFontChange.docx"))
{
foreach (FontFamily oneFontFamily in FontFamily.Families)
foreach (var oneFontFamily in WindowsFontFamily.Families)
{
FontFamily fontFamily = oneFontFamily;
double fontSize = 15;
var fontFamily = new Font(oneFontFamily.Name);
var fontSize = 15.0;
// created numbered lists
var numberedList = document.AddList("First List Item.", 0, ListItemType.Numbered, 1);
@@ -700,8 +704,8 @@ namespace Examples
document.InsertList(bulletedList);
document.InsertList(numberedList, fontFamily, fontSize);
}
// Save this document.
document.Save();
@@ -716,14 +720,14 @@ namespace Examples
using (var document = DocX.Create(@"docs\Lists.docx"))
{
var numberedList = document.AddList("First List Item.", 0, ListItemType.Numbered);
//Add a numbered list starting at 2
//Add a numbered list starting at 2
document.AddListItem(numberedList, "Second List Item.");
document.AddListItem(numberedList, "Third list item.");
document.AddListItem(numberedList, "First sub list item", 1);
document.AddListItem(numberedList, "Nested item.", 2);
document.AddListItem(numberedList, "Fourth nested item.");
var bulletedList = document.AddList("First Bulleted Item.", 0, ListItemType.Bulleted);
document.AddListItem(bulletedList, "Second bullet item");
document.AddListItem(bulletedList, "Sub bullet item", 1);
@@ -1295,13 +1299,13 @@ namespace Examples
Formatting dark_formatting = new Formatting();
dark_formatting.Bold = true;
dark_formatting.Size = 12;
dark_formatting.FontColor = Color.FromArgb(31, 73, 125);
dark_formatting.FontColor = WindowsColor.FromArgb(31, 73, 125);
// Light formatting
Formatting light_formatting = new Formatting();
light_formatting.Italic = true;
light_formatting.Size = 11;
light_formatting.FontColor = Color.FromArgb(79, 129, 189);
light_formatting.FontColor = WindowsColor.FromArgb(79, 129, 189);
#region Company Name
// Get the upper left Paragraph in the layout_table.
@@ -1561,9 +1565,9 @@ namespace Examples
// Append some text and add formatting.
p.Append("Hello World!^011Hello World!")
.Font(new FontFamily("Times New Roman"))
.Font(new Font("Times New Roman"))
.FontSize(32)
.Color(Color.Blue)
.Color(WindowsColor.Blue)
.Bold();
@@ -1586,9 +1590,9 @@ namespace Examples
// Append some text and add formatting.
p.Append("Hello World!^011Hello World!")
.Font(new FontFamily("Times New Roman"))
.Font(new Font("Times New Roman"))
.FontSize(32)
.Color(Color.Blue)
.Color(WindowsColor.Blue)
.Bold();
p.InsertHorizontalLine("double", 6, 1, "auto");
@@ -1620,9 +1624,9 @@ namespace Examples
// Append some text and add formatting.
p.Append("Hello World!^011Hello World!")
.Font(new FontFamily("Times New Roman"))
.Font(new Font("Times New Roman"))
.FontSize(32)
.Color(Color.Blue)
.Color(WindowsColor.Blue)
.Bold();
@@ -1689,12 +1693,12 @@ namespace Examples
.Append("italic").Italic().Append(".")
.AppendLine("I am ")
.Append("Arial Black")
.Font(new FontFamily("Arial Black"))
.Font(new Font("Arial Black"))
.Append(" and I am not.")
.AppendLine("I am ")
.Append("BLUE").Color(Color.Blue)
.Append("BLUE").Color(WindowsColor.Blue)
.Append(" and I am")
.Append("Red").Color(Color.Red).Append(".");
.Append("Red").Color(WindowsColor.Red).Append(".");
// Save this document.
document.Save();
@@ -1720,25 +1724,25 @@ namespace Examples
Image img = document.Images[0];
// Write "Hello World" into this Image.
Bitmap b = new Bitmap(img.GetStream(FileMode.Open, FileAccess.ReadWrite));
var b = new WindowsBitmap(img.GetStream(FileMode.Open, FileAccess.ReadWrite));
/*
* Get the Graphics object for this Bitmap.
* The Graphics object provides functions for drawing.
*/
Graphics g = Graphics.FromImage(b);
var g = WindowsGraphics.FromImage(b);
// Draw the string "Hello World".
g.DrawString
(
str,
new Font("Tahoma", 20),
Brushes.Blue,
new PointF(0, 0)
new WindowsFont("Tahoma", 20),
WindowsBrushes.Blue,
0.0f, 0.0f
);
// Save this Bitmap back into the document using a Create\Write stream.
b.Save(img.GetStream(FileMode.Create, FileAccess.Write), ImageFormat.Png);
b.Save(img.GetStream(FileMode.Create, FileAccess.Write), WindowsImageFormat.Png);
}
else
Console.WriteLine("The provided document contains no Images.");
@@ -1981,7 +1985,7 @@ namespace Examples
picture.SetPictureShape(BasicShapes.cube);
// Insert a new Paragraph into the document.
Paragraph title = document.InsertParagraph().Append("This is a test for a picture").FontSize(20).Font(new FontFamily("Comic Sans MS"));
Paragraph title = document.InsertParagraph().Append("This is a test for a picture").FontSize(20).Font(new Font("Comic Sans MS"));
title.Alignment = Alignment.center;
// Insert a new Paragraph into the document.

+ 21
- 22
UnitTests/DocXUnitTests.cs Vedi File

@@ -1,17 +1,15 @@
using System;
using Novacode;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Drawing;
using System.Xml.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using NUnit.Framework;
using System.Collections.ObjectModel;
using System.Xml;
using Formatting = Novacode.Formatting;
using System.Xml.Linq;
using Novacode;
using NUnit.Framework;
using DocXFormatting = Novacode.Formatting;
using WindowsColor = System.Drawing.Color;
namespace UnitTests
{
@@ -21,10 +19,9 @@ namespace UnitTests
[TestFixture]
public class DocXUnitTests
{
private readonly string _directoryDocuments;
private readonly string _directoryWithFiles;
private static Border BlankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, Color.White);
private static Border BlankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, WindowsColor.White);
const string package_part_document = "/word/document.xml";
@@ -1058,10 +1055,10 @@ namespace UnitTests
using (DocX document = DocX.Load(Path.Combine(_directoryWithFiles, "VariousTextFormatting.docx")))
{
// Removing red text highlighted with yellow
var formatting = new Formatting();
formatting.FontColor = Color.Blue;
var formatting = new DocXFormatting();
formatting.FontColor = WindowsColor.Blue;
// IMPORTANT: default constructor of Formatting sets up language property - set it to NULL to be language independent
var desiredFormat = new Formatting() { Language = null, FontColor = Color.FromArgb(255, 0, 0), Highlight = Highlight.yellow };
var desiredFormat = new DocXFormatting() { Language = null, FontColor = WindowsColor.FromArgb(255, 0, 0), Highlight = Highlight.yellow };
var replaced = string.Empty;
foreach (var p in document.Paragraphs)
{
@@ -1075,11 +1072,13 @@ namespace UnitTests
Assert.AreEqual("New text highlighted with yellow", replaced);
// Removing red text with no other formatting (ExactMatch)
desiredFormat = new Formatting() { Language = null, FontColor = Color.FromArgb(255, 0, 0) };
desiredFormat = new DocXFormatting() { Language = null, FontColor = WindowsColor.FromArgb(255, 0, 0) };
var count = 0;
foreach (var p in document.Paragraphs)
{
p.ReplaceText("Text", "Replaced text", false, RegexOptions.None, null, desiredFormat, MatchFormattingOptions.ExactMatch);
if (p.Text.StartsWith("Replaced text"))
{
++count;
@@ -1089,7 +1088,7 @@ namespace UnitTests
Assert.AreEqual(1, count);
// Removing just red text with any other formatting (SubsetMatch)
desiredFormat = new Formatting() { Language = null, FontColor = Color.FromArgb(255, 0, 0) };
desiredFormat = new DocXFormatting() { Language = null, FontColor = WindowsColor.FromArgb(255, 0, 0) };
count = 0;
foreach (var p in document.Paragraphs)
{
@@ -1221,20 +1220,20 @@ namespace UnitTests
// Load a document.
using (DocX document = DocX.Load(Path.Combine(_directoryWithFiles, "VariousTextFormatting.docx")))
{
var formatting = new Formatting();
formatting.FontColor = Color.Blue;
var formatting = new DocXFormatting();
formatting.FontColor = WindowsColor.Blue;
// IMPORTANT: default constructor of Formatting sets up language property - set it to NULL to be language independent
formatting.Language = null;
var deletedCount = document.RemoveTextInGivenFormat(formatting);
Assert.AreEqual(2, deletedCount);
deletedCount = document.RemoveTextInGivenFormat(new Formatting() { Highlight = Highlight.yellow, Language = null });
deletedCount = document.RemoveTextInGivenFormat(new DocXFormatting() { Highlight = Highlight.yellow, Language = null });
Assert.AreEqual(2, deletedCount);
deletedCount = document.RemoveTextInGivenFormat(new Formatting() { Highlight = Highlight.blue, Language = null, FontColor = Color.FromArgb(0, 255, 0) });
deletedCount = document.RemoveTextInGivenFormat(new DocXFormatting() { Highlight = Highlight.blue, Language = null, FontColor = WindowsColor.FromArgb(0, 255, 0) });
Assert.AreEqual(1, deletedCount);
deletedCount = document.RemoveTextInGivenFormat(new Formatting() { Language = null, FontColor = Color.FromArgb(123, 123, 123) }, MatchFormattingOptions.ExactMatch);
deletedCount = document.RemoveTextInGivenFormat(new DocXFormatting() { Language = null, FontColor = WindowsColor.FromArgb(123, 123, 123) }, MatchFormattingOptions.ExactMatch);
Assert.AreEqual(2, deletedCount);
}
}
@@ -2074,7 +2073,7 @@ namespace UnitTests
{
Paragraph p = document.InsertParagraph();
var fontFamily = new FontFamily("Symbol");
var fontFamily = new Font("Symbol");
p.Append("Hello World").Font(fontFamily);

Loading…
Annulla
Salva