Pārlūkot izejas kodu

Two issues fixed (#13437 and #13438).

In addition two new features: Table of contents and a way of validate if a document contains bookmarks with specified names. This is useful in applications where users can upload a template that will be populated based on form data. If this form data expects one or more bookmarks present in the document, one can now check this up front and use it to provide feedback to the user.

The following files have changes:

• DocX.cs
o Method: Addlist(string, int, ListItemType, in, bool) (I've added another paramter, bool)
o Method: AddListItem(List, string, level, ListItemType int, bool) (I've added another paramter, bool)
o All overloads of InsertList: removed adding of mainpart to list items (do this in AddListItem instead)
o New Method: InsertDefaultTableOfContents
o New Method: InsertTableOfContents(string, TableOfContentsSwitches, string, int, int?)
o New Method: InsertTableOfContents(Paragraph, string, TableOfContentsSwitches, string, int, int?)
• HelperFunctions.cs
o Method: CreateItemInList(List, string, int, ListItemType, int, bool) (I've added another paramter, bool)
• List.cs
o Method: CreateNewNumberNumId(int, ListItemType) (I've added two more paramteres, int, bool)
• ExtensionHeadings.cs
o New Method: HasFlag(this Enum, Enum)
• New File: TableOfContents.cs
• _Enumerations.cs:
o New Enum: TableOfContentsSwitches
• DocXUnitTests.cs
o Quite a few new tests. Tests for TableOfContents and new bookmark feature as well as hyper link bugfix for list items
• _BaseClasses.cs
o New class: XmlTemplateBases (holds constants)
• Program.cs: new examples, AddToc and AddTocByReference
• Paragraph.cs
o New Method: ValidateBookmark(string)
• Container.cs
o New Method: ValidateBookmarks(params string[])
master
MadBoy_cp pirms 10 gadiem
vecāks
revīzija
7c8ea586f2

+ 17
- 0
DocX/Container.cs Parādīt failu

@@ -486,6 +486,23 @@ namespace Novacode
paragraph.InsertAtBookmark(toInsert, bookmarkName);
}
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 nonMatching = new List<string>();
foreach (var bookmarkName in bookmarkNames)
{
if (headers.SelectMany(h => h.Paragraphs).Any(p => p.ValidateBookmark(bookmarkName))) return new string[0];
if (footers.SelectMany(h => h.Paragraphs).Any(p => p.ValidateBookmark(bookmarkName))) return new string[0];
if (Paragraphs.Any(p => p.ValidateBookmark(bookmarkName))) return new string[0];
nonMatching.Add(bookmarkName);
}
return nonMatching.ToArray();
}
public virtual Paragraph InsertParagraph(int index, string text, bool trackChanges)
{
return InsertParagraph(index, text, trackChanges, null);

+ 57
- 8
DocX/DocX.cs Parādīt failu

@@ -1834,14 +1834,15 @@ namespace Novacode
/// <param name="listType">The type of list to be created: Bulleted or Numbered.</param>
/// <param name="startNumber">The number start number for the list. </param>
/// <param name="trackChanges">Enable change tracking</param>
/// <param name="continueNumbering">Set to true if you want to continue numbering from the previous numbered list</param>
/// <returns>
/// The created List. Call AddListItem(...) to add more elements to the list.
/// Write the list to the Document with InsertList(...) once the list has all the desired
/// elements, otherwise the list will not be included in the working Document.
/// </returns>
public List AddList(string listText = null, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false)
public List AddList(string listText = null, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false, bool continueNumbering = false)
{
return AddListItem(new List(this, null), listText, level, listType, startNumber, trackChanges);
return AddListItem(new List(this, null), listText, level, listType, startNumber, trackChanges, continueNumbering);
}
/// <summary>
@@ -1853,15 +1854,23 @@ namespace Novacode
/// <param name="startNumber">The number start number for the list. </param>
/// <param name="trackChanges">Enable change tracking</param>
/// <param name="listType">Numbered or Bulleted list type. </param>
/// /// <param name="continueNumbering">Set to true if you want to continue numbering from the previous numbered list</param>
/// <returns>
/// The created List. Call AddListItem(...) to add more elements to the list.
/// Write the list to the Document with InsertList(...) once the list has all the desired
/// elements, otherwise the list will not be included in the working Document.
/// </returns>
public List AddListItem(List list, string listText, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false)
public List AddListItem(List list, string listText, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false, bool continueNumbering = false)
{
if(startNumber.HasValue && continueNumbering) throw new InvalidOperationException("Cannot specify a start number and at the same time continue numbering from another list");
var listToReturn = HelperFunctions.CreateItemInList(list, listText, level, listType, startNumber, trackChanges, continueNumbering);
var lastItem = listToReturn.Items.LastOrDefault();
if (lastItem != null)
{
lastItem.PackagePart = mainPart;
}
return listToReturn;
return HelperFunctions.CreateItemInList(list, listText, level, listType, startNumber, trackChanges);
}
/// <summary>
@@ -1872,19 +1881,16 @@ namespace Novacode
public new List InsertList(List list)
{
base.InsertList(list);
list.Items.ForEach(i => i.mainPart = mainPart);
return list;
}
public new List InsertList(List list, System.Drawing.FontFamily fontFamily, double fontSize)
{
base.InsertList(list, fontFamily, fontSize);
list.Items.ForEach(i => i.mainPart = mainPart);
return list;
}
public new List InsertList(List list, double fontSize)
{
base.InsertList(list, fontSize);
list.Items.ForEach(i => i.mainPart = mainPart);
return list;
}
@@ -1897,7 +1903,6 @@ namespace Novacode
public new List InsertList(int index, List list)
{
base.InsertList(index, list);
list.Items.ForEach(i => i.mainPart = mainPart);
return list;
}
@@ -4093,6 +4098,50 @@ namespace Novacode
p.Xml.Add(chartElement);
}
/// <summary>
/// Inserts a default TOC into the current document.
/// Title: Table of contents
/// Swithces will be: TOC \h \o '1-3' \u \z
/// </summary>
/// <returns>The inserted TableOfContents</returns>
public TableOfContents InsertDefaultTableOfContents()
{
return InsertTableOfContents("Table of contents", TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z | TableOfContentsSwitches.U);
}
/// <summary>
/// Inserts a TOC into the current document.
/// </summary>
/// <param name="title">The title of the TOC</param>
/// <param name="switches">Switches to be applied, see: http://officeopenxml.com/WPtableOfContents.php </param>
/// <param name="headerStyle">Lets you set the style name of the TOC header</param>
/// <param name="maxIncludeLevel">Lets you specify how many header levels should be included - default is 1-3</param>
/// <param name="rightTabPos">Lets you override the right tab position - this is not common</param>
/// <returns>The inserted TableOfContents</returns>
public TableOfContents InsertTableOfContents(string title, TableOfContentsSwitches switches, string headerStyle = null, int maxIncludeLevel = 3, int? rightTabPos = null)
{
var toc = TableOfContents.CreateTableOfContents(this, title, switches, headerStyle, maxIncludeLevel, rightTabPos);
Xml.Add(toc.Xml);
return toc;
}
/// <summary>
/// Inserts at TOC into the current document before the provided <see cref="reference"/>
/// </summary>
/// <param name="reference">The paragraph to use as reference</param>
/// <param name="title">The title of the TOC</param>
/// <param name="switches">Switches to be applied, see: http://officeopenxml.com/WPtableOfContents.php </param>
/// <param name="headerStyle">Lets you set the style name of the TOC header</param>
/// <param name="maxIncludeLevel">Lets you specify how many header levels should be included - default is 1-3</param>
/// <param name="rightTabPos">Lets you override the right tab position - this is not common</param>
/// <returns>The inserted TableOfContents</returns>
public TableOfContents InsertTableOfContents(Paragraph reference, string title, TableOfContentsSwitches switches, string headerStyle = null, int maxIncludeLevel = 3, int? rightTabPos = null)
{
var toc = TableOfContents.CreateTableOfContents(this, title, switches, headerStyle, maxIncludeLevel, rightTabPos);
reference.Xml.AddBeforeSelf(toc.Xml);
return toc;
}
#region IDisposable Members
/// <summary>

+ 1
- 0
DocX/DocX.csproj Parādīt failu

@@ -110,6 +110,7 @@
<Compile Include="List.cs" />
<Compile Include="PageLayout.cs" />
<Compile Include="Section.cs" />
<Compile Include="TableOfContents.cs" />
<Compile Include="_BaseClasses.cs" />
<Compile Include="Table.cs" />
<Compile Include="_Enumerations.cs" />

+ 28
- 0
DocX/ExtensionsHeadings.cs Parādīt failu

@@ -37,6 +37,34 @@ namespace Novacode
return enumValue.ToString();
}
}
/// <summary>
/// From: http://stackoverflow.com/questions/4108828/generic-extension-method-to-see-if-an-enum-contains-a-flag
/// Check to see if a flags enumeration has a specific flag set.
/// </summary>
/// <param name="variable">Flags enumeration to check</param>
/// <param name="value">Flag to check for</param>
/// <returns></returns>
public static bool HasFlag(this Enum variable, Enum value)
{
if (variable == null)
return false;
if (value == null)
throw new ArgumentNullException("value");
// Not as good as the .NET 4 version of this function, but should be good enough
if (!Enum.IsDefined(variable.GetType(), value))
{
throw new ArgumentException(string.Format(
"Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.",
value.GetType(), variable.GetType()));
}
ulong num = Convert.ToUInt64(value);
return ((Convert.ToUInt64(variable) & num) == num);
}
}
}

+ 3
- 3
DocX/HelperFunctions.cs Parādīt failu

@@ -478,14 +478,14 @@ namespace Novacode
);
}
internal static List CreateItemInList(List list, string listText, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false)
internal static List CreateItemInList(List list, string listText, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false, bool continueNumbering = false)
{
if (list.NumId == 0)
{
list.CreateNewNumberingNumId(level, listType);
list.CreateNewNumberingNumId(level, listType, startNumber, continueNumbering);
}
if (!string.IsNullOrEmpty(listText))
if (listText != null) //I see no reason why you shouldn't be able to insert an empty element. It simplifies tasks such as populating an item from html.
{
var newParagraphSection = new XElement
(

+ 22
- 6
DocX/List.cs Parādīt failu

@@ -99,9 +99,9 @@ namespace Novacode
public bool ContainsLevel(int ilvl)
{
return Items.Any(i => i.ParagraphNumberProperties.Descendants().First(el => el.Name.LocalName == "ilvl").Value == ilvl.ToString());
}
internal void CreateNewNumberingNumId(int level = 0, ListItemType listType = ListItemType.Numbered)
}
internal void CreateNewNumberingNumId(int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool continueNumbering = false)
{
ValidateDocXNumberingPartExists();
if (Document.numbering.Root == null)
@@ -126,9 +126,13 @@ namespace Novacode
default:
throw new InvalidOperationException(string.Format("Unable to deal with ListItemType: {0}.", listType.ToString()));
}
var abstractNumTemplate = listTemplate.Descendants().Single(d => d.Name.LocalName == "abstractNum");
abstractNumTemplate.SetAttributeValue(DocX.w + "abstractNumId", abstractNumId);
var abstractNumXml = new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), new XElement(XName.Get("abstractNumId", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", abstractNumId)));
var abstractNumTemplate = listTemplate.Descendants().Single(d => d.Name.LocalName == "abstractNum");
abstractNumTemplate.SetAttributeValue(DocX.w + "abstractNumId", abstractNumId);
//Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number.
//The override needs only be on level 0 as this will cascade to the rest of the list.
var abstractNumXml = GetAbstractNumXml(abstractNumId, numId, startNumber, continueNumbering);

var abstractNumNode = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "abstractNum");
var numXml = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "num");
@@ -147,6 +151,18 @@ namespace Novacode
}

NumId = numId;
}
private XElement GetAbstractNumXml(int abstractNumId, int numId, int? startNumber, bool continueNumbering)
{
//Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number.
//The override needs only be on level 0 as this will cascade to the rest of the list.
var startOverride = new XElement(XName.Get("startOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", startNumber ?? 1));
var lvlOverride = new XElement(XName.Get("lvlOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "ilvl", 0), startOverride);
var abstractNumIdElement = new XElement(XName.Get("abstractNumId", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", abstractNumId));
return continueNumbering
? new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement)
: new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement, lvlOverride);
}

/// <summary>

+ 5
- 0
DocX/Paragraph.cs Parādīt failu

@@ -2258,6 +2258,11 @@ namespace Novacode
return this;
}
public bool ValidateBookmark(string bookmarkName)
{
return GetBookmarks().Any(b => b.Name.Equals(bookmarkName));
}
public Paragraph AppendBookmark(String bookmarkName)
{
XElement wBookmarkStart = new XElement(

+ 2
- 2
DocX/Properties/AssemblyInfo.cs Parādīt failu

@@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.14")]
[assembly: AssemblyFileVersion("1.0.0.14")]
[assembly: AssemblyVersion("1.0.0.16")]
[assembly: AssemblyFileVersion("1.0.0.16")]

+ 103
- 0
DocX/TableOfContents.cs Parādīt failu

@@ -0,0 +1,103 @@
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace Novacode
{
/// <summary>
/// Represents a table of contents in the document
/// </summary>
public class TableOfContents : DocXElement
{
#region TocBaseValues
private const string HeaderStyle = "TOCHeading";
private const int RightTabPos = 9350;
#endregion
private TableOfContents(DocX document, XElement xml, string headerStyle) : base(document, xml)
{
AssureUpdateField(document);
AssureStyles(document, headerStyle);
}
internal static TableOfContents CreateTableOfContents(DocX document, string title, TableOfContentsSwitches switches, string headerStyle = null, int lastIncludeLevel = 3, int? rightTabPos = null)
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocXmlBase, headerStyle ?? HeaderStyle, title, rightTabPos ?? RightTabPos, BuildSwitchString(switches, lastIncludeLevel))));
var xml = XElement.Load(reader);
return new TableOfContents(document, xml, headerStyle);
}
private void AssureUpdateField(DocX document)
{
if (document.settings.Descendants().Any(x => x.Name.Equals(DocX.w + "updateFields"))) return;
var element = new XElement(XName.Get("updateFields", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", true));
document.settings.Root.Add(element);
}
private void AssureStyles(DocX document, string headerStyle)
{
if (!HasStyle(document, headerStyle, "paragraph"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHeadingStyleBase, headerStyle ?? HeaderStyle)));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
if (!HasStyle(document, "TOC1", "paragraph"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC1", "toc 1")));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
if (!HasStyle(document, "TOC2", "paragraph"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC2", "toc 2")));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
if (!HasStyle(document, "TOC3", "paragraph"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC3", "toc 3")));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
if (!HasStyle(document, "TOC4", "paragraph"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC4", "toc 4")));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
if (!HasStyle(document, "Hyperlink", "character"))
{
var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHyperLinkStyleBase)));
var xml = XElement.Load(reader);
document.styles.Root.Add(xml);
}
}
private bool HasStyle(DocX document, string value, string type)
{
return document.styles.Descendants().Any(x => x.Name.Equals(DocX.w + "style")&& (x.Attribute(DocX.w + "type") == null || x.Attribute(DocX.w + "type").Value.Equals(type)) && x.Attribute(DocX.w + "styleId") != null && x.Attribute(DocX.w + "styleId").Value.Equals(value));
}
private static string BuildSwitchString(TableOfContentsSwitches switches, int lastIncludeLevel)
{
var allSwitches = Enum.GetValues(typeof (TableOfContentsSwitches)).Cast<TableOfContentsSwitches>();
var switchString = "TOC";
foreach (var s in allSwitches.Where(s => s != TableOfContentsSwitches.None && switches.HasFlag(s)))
{
switchString += " " + s.EnumDescription();
if (s == TableOfContentsSwitches.O)
{
switchString += string.Format(" '{0}-{1}'", 1, lastIncludeLevel);
}
}
return switchString;
}
}
}

+ 105
- 0
DocX/_BaseClasses.cs Parādīt failu

@@ -207,4 +207,109 @@ namespace Novacode
//return t;
}
}
public static class XmlTemplateBases
{
#region TocXml
public const string TocXmlBase = @"<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:sdtPr>
<w:docPartObj>
<w:docPartGallery w:val='Table of Contents'/>
<w:docPartUnique/>
</w:docPartObj>\
</w:sdtPr>
<w:sdtEndPr>
<w:rPr>
<w:rFonts w:asciiTheme='minorHAnsi' w:cstheme='minorBidi' w:eastAsiaTheme='minorHAnsi' w:hAnsiTheme='minorHAnsi'/>
<w:color w:val='auto'/>
<w:sz w:val='22'/>
<w:szCs w:val='22'/>
<w:lang w:eastAsia='en-US'/>
</w:rPr>
</w:sdtEndPr>
<w:sdtContent>
<w:p>
<w:pPr>
<w:pStyle w:val='{0}'/>
</w:pPr>
<w:r>
<w:t>{1}</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val='TOC1'/>
<w:tabs>
<w:tab w:val='right' w:leader='dot' w:pos='{2}'/>
</w:tabs>
<w:rPr>
<w:noProof/>
</w:rPr>
</w:pPr>
<w:r>
<w:fldChar w:fldCharType='begin' w:dirty='true'/>
</w:r>
<w:r>
<w:instrText xml:space='preserve'> {3} </w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType='separate'/>
</w:r>
</w:p>
<w:p>
<w:r>
<w:rPr>
<w:b/>
<w:bCs/>
<w:noProof/>
</w:rPr>
<w:fldChar w:fldCharType='end'/>
</w:r>
</w:p>
</w:sdtContent>
</w:sdt>
";
public const string TocHeadingStyleBase = @"<w:style w:type='paragraph' w:styleId='{0}' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:name w:val='TOC Heading'/>
<w:basedOn w:val='Heading1'/>
<w:next w:val='Normal'/>
<w:uiPriority w:val='39'/>
<w:semiHidden/>
<w:unhideWhenUsed/>
<w:qFormat/>
<w:rsid w:val='00E67AA6'/>
<w:pPr>
<w:outlineLvl w:val='9'/>
</w:pPr>
<w:rPr>
<w:lang w:eastAsia='nb-NO'/>
</w:rPr>
</w:style>
";
public const string TocElementStyleBase = @" <w:style w:type='paragraph' w:styleId='{0}' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:name w:val='{1}' />
<w:basedOn w:val='Normal' />
<w:next w:val='Normal' />
<w:autoRedefine />
<w:uiPriority w:val='39' />
<w:unhideWhenUsed />
<w:pPr>
<w:spacing w:after='100' />
<w:ind w:left='440' />
</w:pPr>
</w:style>
";
public const string TocHyperLinkStyleBase = @" <w:style w:type='character' w:styleId='Hyperlink' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:name w:val='Hyperlink' />
<w:basedOn w:val='Normal' />
<w:uiPriority w:val='99' />
<w:unhideWhenUsed />
<w:rPr>
<w:color w:val='0000FF' w:themeColor='hyperlink' />
<w:u w:val='single' />
</w:rPr>
</w:style>
";
#endregion
}
}

+ 41
- 4
DocX/_Enumerations.cs Parādīt failu

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace Novacode
{
@@ -743,4 +739,45 @@ namespace Novacode
right
};
/// <summary>
/// Represents the switches set on a TOC.
/// </summary>
[Flags]
public enum TableOfContentsSwitches
{
None = 0 << 0,
[Description("\\a")]
A = 1 << 0,
[Description("\\b")]
B = 1 << 1,
[Description("\\c")]
C = 1 << 2,
[Description("\\d")]
D = 1 << 3,
[Description("\\f")]
F = 1 << 4,
[Description("\\h")]
H = 1 << 5,
[Description("\\l")]
L = 1 << 6,
[Description("\\n")]
N = 1 << 7,
[Description("\\o")]
O = 1 << 8,
[Description("\\p")]
P = 1 << 9,
[Description("\\s")]
S = 1 << 10,
[Description("\\t")]
T = 1 << 11,
[Description("\\u")]
U = 1 << 12,
[Description("\\w")]
W = 1 << 13,
[Description("\\x")]
X = 1 << 14,
[Description("\\z")]
Z = 1 << 15,
}
}

+ 3
- 6
Examples/Examples.csproj Parādīt failu

@@ -48,6 +48,9 @@
<OutputPath>bin\Release\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocX">
<HintPath>..\DocX\bin\Release\DocX.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
@@ -62,12 +65,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RelativeDirectory.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DocX\DocX.csproj">
<Project>{E863D072-AA8B-4108-B5F1-785241B37F67}</Project>
<Name>DocX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Input.docx">

+ 57
- 16
Examples/Program.cs Parādīt failu

@@ -7,14 +7,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Novacode;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using Image = Novacode.Image;
namespace Examples
{
@@ -39,6 +32,8 @@ namespace Examples
Chart3D();
DocumentMargins();
CreateTableWithTextDirection();
AddToc();
AddTocByReference();
// Intermediate
Console.WriteLine("\nRunning Intermediate Examples");
@@ -339,7 +334,7 @@ namespace Examples
// Add an image into the document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image image = document.AddImage(rd.Path + @"\images\logo_template.png");
Image image = document.AddImage(rd.Path + @"\images\logo_template.png");
// Create a picture (A custom view of an Image).
Picture picture = image.CreatePicture();
@@ -419,7 +414,7 @@ namespace Examples
// Add an image into the document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image image = document.AddImage(rd.Path + @"\images\logo_template.png");
Image image = document.AddImage(rd.Path + @"\images\logo_template.png");
// Create a picture (A custom view of an Image).
Picture picture = image.CreatePicture();
@@ -546,7 +541,7 @@ namespace Examples
foreach ( FontFamily oneFontFamily in FontFamily.Families ) {
System.Drawing.FontFamily fontFamily = oneFontFamily;
FontFamily fontFamily = oneFontFamily;
double fontSize = 15;
// created numbered lists
@@ -575,6 +570,7 @@ namespace Examples
Console.WriteLine("\tCreated: docs\\DocumentsWithListsFontChange.docx\n");
}
}
private static void AddList()
{
Console.WriteLine("\tAddList()");
@@ -700,7 +696,7 @@ namespace Examples
// Add a template logo image to this document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image logo = document.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
Image logo = document.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
// Add Headers and Footers to this document.
document.AddHeaders();
@@ -867,7 +863,7 @@ namespace Examples
// Add a template logo image to this document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image logo = document.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
Image logo = document.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
// Add Headers and Footers to this document.
document.AddHeaders();
@@ -1102,7 +1098,7 @@ namespace Examples
// Add the Happy Builders logo to this document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image logo = template.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
Image logo = template.AddImage(rd.Path + @"\images\logo_the_happy_builder.png");
// Insert the Happy Builders logo into this Paragraph.
logo_paragraph.InsertPicture(logo.CreatePicture());
@@ -1196,7 +1192,7 @@ namespace Examples
// Add a template logo image to this document.
RelativeDirectory rd = new RelativeDirectory(); // prepares the files for testing
rd.Up(2);
Novacode.Image logo = document.AddImage(rd.Path + @"\images\logo_template.png");
Image logo = document.AddImage(rd.Path + @"\images\logo_template.png");
// Insert this template logo into the upper right Paragraph.
upper_right_paragraph.InsertPicture(logo.CreatePicture());
@@ -1453,7 +1449,7 @@ namespace Examples
// Make sure this document has at least one Image.
if (document.Images.Count() > 0)
{
Novacode.Image img = document.Images[0];
Image img = document.Images[0];
// Write "Hello World" into this Image.
Bitmap b = new Bitmap(img.GetStream(FileMode.Open, FileAccess.ReadWrite));
@@ -1518,5 +1514,50 @@ namespace Examples
);
Console.WriteLine("\tCreated: None\n");
}
static void AddToc()
{
Console.WriteLine("\tAddToc()");
using (var document = DocX.Create(@"docs\Toc.docx"))
{
document.InsertTableOfContents("I can haz table of contentz", TableOfContentsSwitches.O | TableOfContentsSwitches.U | TableOfContentsSwitches.Z | TableOfContentsSwitches.H, "Heading2");
var h1 = document.InsertParagraph("Heading 1");
h1.StyleName = "Heading1";
document.InsertParagraph("Some very interesting content here");
var h2 = document.InsertParagraph("Heading 2");
document.InsertSectionPageBreak();
h2.StyleName = "Heading1";
document.InsertParagraph("Some very interesting content here as well");
var h3 = document.InsertParagraph("Heading 2.1");
h3.StyleName = "Heading2";
document.InsertParagraph("Not so very interesting....");
document.Save();
}
}
static void AddTocByReference()
{
Console.WriteLine("\tAddTocByReference()");
using (var document = DocX.Create(@"docs\TocByReference.docx"))
{
var h1 = document.InsertParagraph("Heading 1");
h1.StyleName = "Heading1";
document.InsertParagraph("Some very interesting content here");
var h2 = document.InsertParagraph("Heading 2");
document.InsertSectionPageBreak();
h2.StyleName = "Heading1";
document.InsertParagraph("Some very interesting content here as well");
var h3 = document.InsertParagraph("Heading 2.1");
h3.StyleName = "Heading2";
document.InsertParagraph("Not so very interesting....");
document.InsertTableOfContents(h2, "I can haz table of contentz", TableOfContentsSwitches.O | TableOfContentsSwitches.U | TableOfContentsSwitches.Z | TableOfContentsSwitches.H, "Heading2");
document.Save();
}
}
}
}

+ 566
- 0
UnitTests/DocXUnitTests.cs Parādīt failu

@@ -9,6 +9,8 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.ObjectModel;
using System.Xml;
using Formatting = Novacode.Formatting;
namespace UnitTests
{
@@ -1839,6 +1841,30 @@ namespace UnitTests
}
}
[TestMethod]
public void ParagraphAppendHyperLink_ParagraphIsListItem_ShouldNotThrow()
{
using (var document = DocX.Create("HyperlinkList.docx"))
{
var list = document.AddList("Item 1", listType: ListItemType.Numbered);
document.AddListItem(list, "Item 2");
document.AddListItem(list, "Item 3");
Uri uri;
Uri.TryCreate("http://www.google.com", UriKind.RelativeOrAbsolute, out uri);
var hLink = document.AddHyperlink("Google", uri);
var item2 = list.Items[1];
item2.InsertText("\nMore text\n");
item2.AppendHyperlink(hLink);
item2.InsertText("\nEven more text");
document.InsertList(list);
document.Save();
}
}
[TestMethod]
public void WhileReadingWhenTextIsBoldItalicUnderlineItShouldReadTheProperFormatting()
@@ -2038,7 +2064,547 @@ namespace UnitTests
}
}
[TestMethod]
public void CreateTableOfContents_WithTitleAndSwitches_SetsExpectedXml()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const int rightPos = 9350;
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var toc = TableOfContents.CreateTableOfContents(document, title, switches);
const string switchString = @"TOC \h \o '1-3' \u \z";
var expectedString = string.Format(XmlTemplateBases.TocXmlBase, "TOCHeading", title, rightPos, switchString);
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
Assert.IsTrue(XNode.DeepEquals(expected, toc.Xml));
}
}
[TestMethod]
public void CreateTableOfContents_WithTitleSwitchesHeaderStyleLastIncludeLevelRightTabPos_SetsExpectedXml()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const int rightPos = 1337;
const string style = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var toc = TableOfContents.CreateTableOfContents(document, title, switches, style, 6, rightPos);
const string switchString = @"TOC \h \o '1-6' \u \z";
var expectedString = string.Format(XmlTemplateBases.TocXmlBase, style, title, rightPos, switchString);
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
Assert.IsTrue(XNode.DeepEquals(expected, toc.Xml));
}
}
[TestMethod]
public void CreateTableOfContents_WhenCalled_AddsUpdateFieldsWithValueTrueToSettings()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var updateField = document.settings.Descendants().FirstOrDefault(x => x.Name == DocX.w + "updateFields");
Assert.IsNotNull(updateField);
Assert.AreEqual("true", updateField.Attribute(DocX.w + "val").Value);
}
}
[TestMethod]
public void CreateTableOfContents_WhenCalledSettingsAlreadyHasUpdateFields_DoesNotAddUpdateFields()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
var element = new XElement(XName.Get("updateFields", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", true));
document.settings.Root.Add(element);
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var updateFields = document.settings.Descendants().Single(x => x.Name == DocX.w + "updateFields");
Assert.AreSame(element, updateFields);
}
}
[TestMethod]
public void CreteTableOfContents_TocHeadingStyleIsNotPresent_AddsTocHeaderStyle()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var expectedString = string.Format(XmlTemplateBases.TocHeadingStyleBase, headerStyle);
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals(headerStyle));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_Toc1StyleIsNotPresent_AddsToc1Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var expectedString = string.Format(XmlTemplateBases.TocElementStyleBase, "TOC1", "toc 1");
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC1"));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_Toc2StyleIsNotPresent_AddsToc2Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var expectedString = string.Format(XmlTemplateBases.TocElementStyleBase, "TOC2", "toc 2");
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC2"));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_Toc3StyleIsNotPresent_AddsToc3tyle()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var expectedString = string.Format(XmlTemplateBases.TocElementStyleBase, "TOC3", "toc 3");
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC3"));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_Toc4StyleIsNotPresent_AddsToc4Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var expectedString = string.Format(XmlTemplateBases.TocElementStyleBase, "TOC4", "toc 4");
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC4"));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_HyperlinkStyleIsNotPresent_AddsHyperlinkStyle()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
TableOfContents.CreateTableOfContents(document, title, switches);
var expectedString = XmlTemplateBases.TocHyperLinkStyleBase;
var expectedReader = XmlReader.Create(new StringReader(expectedString));
var expected = XElement.Load(expectedReader);
var actual = document.styles.Root.Descendants().FirstOrDefault(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("character") &&
x.Attribute(DocX.w + "styleId").Value.Equals("Hyperlink"));
Assert.IsTrue(XNode.DeepEquals(expected, actual));
}
}
[TestMethod]
public void CreteTableOfContents_TocHeadingStyleIsPresent_DoesNotAddTocHeaderStyle()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHeadingStyleBase, headerStyle))));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals(headerStyle));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void CreteTableOfContents_Toc1StyleIsPresent_DoesNotAddToc1Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC1", "toc 1"))));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC1"));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void CreteTableOfContents_Toc2StyleIsPresent_DoesNotAddToc2Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC2", "toc 2"))));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC2"));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void CreteTableOfContents_Toc3StyleIsPresent_DoesNotAddToc3Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC3", "toc 3"))));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC3"));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void CreteTableOfContents_Toc4StyleIsPresent_DoesNotAddToc4Style()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const string headerStyle = "TestStyle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC4", "toc 4"))));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches, headerStyle);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("paragraph") &&
x.Attribute(DocX.w + "styleId").Value.Equals("TOC4"));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void CreteTableOfContents_HyperlinkStyleIsPresent_DoesNotAddHyperlinkStyle()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string title = "TestTitle";
const TableOfContentsSwitches switches =
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U;
var xElement = XElement.Load(XmlReader.Create(new StringReader(XmlTemplateBases.TocHyperLinkStyleBase)));
document.styles.Root.Add(xElement);
TableOfContents.CreateTableOfContents(document, title, switches);
var actual = document.styles.Root.Descendants().Single(x =>
x.Name.Equals(DocX.w + "style") &&
x.Attribute(DocX.w + "type").Value.Equals("character") &&
x.Attribute(DocX.w + "styleId").Value.Equals("Hyperlink"));
Assert.AreSame(xElement, actual);
}
}
[TestMethod]
public void InsertDefaultTableOfContents_WhenCalled_AddsTocToDocument()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
document.InsertDefaultTableOfContents();
var toc = TableOfContents.CreateTableOfContents(document, "Table of contents",
TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z |
TableOfContentsSwitches.U);
Assert.IsTrue(document.Xml.Descendants().FirstOrDefault(x => XNode.DeepEquals(toc.Xml, x)) != null);
}
}
[TestMethod]
public void InsertTableOfContents_WhenCalledWithTitleSwitchesHeaderStyleMaxIncludeLevelAndRightTabPos_AddsTocToDocument()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string tableOfContentsTitle = "Table of contents";
const TableOfContentsSwitches tableOfContentsSwitches = TableOfContentsSwitches.O | TableOfContentsSwitches.A;
const string headerStyle = "HeaderStyle";
const int lastIncludeLevel = 4;
const int rightTabPos = 1337;
document.InsertTableOfContents(tableOfContentsTitle, tableOfContentsSwitches, headerStyle, lastIncludeLevel, rightTabPos);
var toc = TableOfContents.CreateTableOfContents(document, tableOfContentsTitle, tableOfContentsSwitches, headerStyle, lastIncludeLevel, rightTabPos);
Assert.IsTrue(document.Xml.Descendants().FirstOrDefault(x => XNode.DeepEquals(toc.Xml, x)) != null);
}
}
[TestMethod]
public void InsertTableOfContents_WhenCalledWithReferenceTitleSwitchesHeaderStyleMaxIncludeLevelAndRightTabPos_AddsTocToDocumentAtExpectedLocation()
{
using (var document = DocX.Create("TableOfContents Test.docx"))
{
const string tableOfContentsTitle = "Table of contents";
const TableOfContentsSwitches tableOfContentsSwitches = TableOfContentsSwitches.O | TableOfContentsSwitches.A;
const string headerStyle = "HeaderStyle";
const int lastIncludeLevel = 4;
const int rightTabPos = 1337;
document.InsertParagraph("Paragraph1");
var p2 = document.InsertParagraph("Paragraph2");
var p3 = document.InsertParagraph("Paragraph3");
document.InsertTableOfContents(p3, tableOfContentsTitle, tableOfContentsSwitches, headerStyle, lastIncludeLevel, rightTabPos);
var toc = TableOfContents.CreateTableOfContents(document, tableOfContentsTitle, tableOfContentsSwitches, headerStyle, lastIncludeLevel, rightTabPos);
var tocElement = document.Xml.Descendants().FirstOrDefault(x => XNode.DeepEquals(toc.Xml, x));
Assert.IsTrue(p2.Xml.IsBefore(tocElement));
Assert.IsTrue(tocElement.IsAfter(p2.Xml));
Assert.IsTrue(tocElement.IsBefore(p3.Xml));
Assert.IsTrue(p3.Xml.IsAfter(tocElement));
}
}
[TestMethod]
public void ValidateBookmark_WhenCalledWithNameOfNonMatchingBookmark_ReturnsFalse()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
var p = document.InsertParagraph("No bookmark here");
Assert.IsFalse(p.ValidateBookmark("Team Rubberduck"));
}
}
[TestMethod]
public void ValidateBookmark_WhenCalledWithNameOfMatchingBookmark_ReturnsTrue()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
var p = document.InsertParagraph("Here's a bookmark!");
const string bookmarkName = "Team Rubberduck";
p.AppendBookmark(bookmarkName);
Assert.IsTrue(p.ValidateBookmark("Team Rubberduck"));
}
}
[TestMethod]
public void ValidateBookmarks_WhenCalledWithMatchingBookmarkNameInHeader_ReturnsEmpty()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
document.AddHeaders();
var p = document.Headers.first.InsertParagraph("Here's a bookmark!");
const string bookmarkName = "Team Rubberduck";
p.AppendBookmark(bookmarkName);
Assert.IsTrue(document.ValidateBookmarks("Team Rubberduck").Length == 0);
}
}
[TestMethod]
public void ValidateBookmarks_WhenCalledWithMatchingBookmarkNameInMainDocument_ReturnsEmpty()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
var p = document.InsertParagraph("Here's a bookmark!");
const string bookmarkName = "Team Rubberduck";
p.AppendBookmark(bookmarkName);
Assert.IsTrue(document.ValidateBookmarks("Team Rubberduck").Length == 0);
}
}
[TestMethod]
public void ValidateBookmarks_WhenCalledWithMatchingBookmarkNameInFooters_ReturnsEmpty()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
document.AddFooters();
var p = document.Footers.first.InsertParagraph("Here's a bookmark!");
const string bookmarkName = "Team Rubberduck";
p.AppendBookmark(bookmarkName);
Assert.IsTrue(document.ValidateBookmarks("Team Rubberduck").Length == 0);
}
}
[TestMethod]
public void ValidateBookmarks_WhenCalledWithNoMatchingBookmarkNames_ReturnsExpected()
{
using (var document = DocX.Create("Bookmark validate.docx"))
{
document.AddHeaders();
var p = document.Headers.first.InsertParagraph("Here's a bookmark!");
p.AppendBookmark("Not in search");
var bookmarkNames = new[] {"Team Rubberduck", "is", "the most", "awesome people"};
var result = document.ValidateBookmarks(bookmarkNames);
for (var i = 0; i < bookmarkNames.Length; i++)
{
Assert.AreEqual(bookmarkNames[i], result[i]);
}
}
}
}
}

Notiek ielāde…
Atcelt
Saglabāt