소스 검색

Fixed some minor bugs. Added the ability to create .docx files on the fly, and to insert text with custom formatting.

master
coffeycathal_cp 17 년 전
부모
커밋
f25cfc2ef9
10개의 변경된 파일517개의 추가작업 그리고 79개의 파일을 삭제
  1. 6
    4
      CustomPropertyTestApp/CustomPropertyTestApp.csproj
  2. 6
    0
      DocX.sln
  3. 79
    1
      DocX/DocX.cs
  4. 6
    0
      DocX/DocX.csproj
  5. 32
    0
      DocX/Extensions.cs
  6. 272
    0
      DocX/Formatting.cs
  7. 102
    67
      DocX/Paragraph.cs
  8. 7
    3
      DocX/Run.cs
  9. 1
    0
      StringReplaceTestApp/Program.cs
  10. 6
    4
      StringReplaceTestApp/StringReplaceTestApp.csproj

+ 6
- 4
CustomPropertyTestApp/CustomPropertyTestApp.csproj 파일 보기

<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DocX, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\DocX\bin\Debug\DocX.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DocX\DocX.csproj">
<Project>{E863D072-AA8B-4108-B5F1-785241B37F67}</Project>
<Name>DocX</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

+ 6
- 0
DocX.sln 파일 보기

EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomPropertyTestApp", "CustomPropertyTestApp\CustomPropertyTestApp.csproj", "{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomPropertyTestApp", "CustomPropertyTestApp\CustomPropertyTestApp.csproj", "{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateDocumentOnTheFly", "CreateDocumentOnTheFly\CreateDocumentOnTheFly.csproj", "{40E089B2-BFE4-4E47-83CC-36A4D43269C4}"
EndProject
Global Global
GlobalSection(TeamFoundationVersionControl) = preSolution GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 5 SccNumberOfProjects = 5
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Debug|Any CPU.Build.0 = Debug|Any CPU {9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.ActiveCfg = Release|Any CPU {9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.Build.0 = Release|Any CPU {9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.Build.0 = Release|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

+ 79
- 1
DocX/DocX.cs 파일 보기

get { return customProperties; } get { return customProperties; }
} }
public Paragraph AddParagraph()
{
XElement newParagraph = new XElement(w + "p");
mainDoc.Descendants(XName.Get("body", "http://schemas.openxmlformats.org/wordprocessingml/2006/main")).Single().Add(newParagraph);
// Get all of the paragraphs in this document
DocX.paragraphs = from p in mainDoc.Descendants(XName.Get("p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"))
select new Paragraph(p);
return new Paragraph(newParagraph);
}
public static DocX Create(string uri)
{
FileInfo fi = new FileInfo(uri);
if (fi.Extension != ".docx")
throw new Exception(string.Format("The input file {0} is not a .docx file", fi.FullName));
DocX.uri = uri;
// Create the docx package
wdDoc = WordprocessingDocument.Create(uri, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
#region MainDocumentPart
// Create the main document part for this package
mainDocumentPart = wdDoc.AddMainDocumentPart();
// Load the document part into a XDocument object
using (TextReader tr = new StreamReader(mainDocumentPart.GetStream(FileMode.Create, FileAccess.ReadWrite)))
{
mainDoc = XDocument.Parse
(@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<w:document xmlns:ve=""http://schemas.openxmlformats.org/markup-compatibility/2006"" xmlns:o=""urn:schemas-microsoft-com:office:office"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:m=""http://schemas.openxmlformats.org/officeDocument/2006/math"" xmlns:v=""urn:schemas-microsoft-com:vml"" xmlns:wp=""http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"" xmlns:w10=""urn:schemas-microsoft-com:office:word"" xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"" xmlns:wne=""http://schemas.microsoft.com/office/word/2006/wordml"">
<w:body>
<w:sectPr w:rsidR=""003E25F4"" w:rsidSect=""00FC3028"">
<w:pgSz w:w=""11906"" w:h=""16838""/>
<w:pgMar w:top=""1440"" w:right=""1440"" w:bottom=""1440"" w:left=""1440"" w:header=""708"" w:footer=""708"" w:gutter=""0""/>
<w:cols w:space=""708""/>
<w:docGrid w:linePitch=""360""/>
</w:sectPr>
</w:body>
</w:document>"
);
}
// Get all of the paragraphs in this document
DocX.paragraphs = from p in mainDoc.Descendants(XName.Get("p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"))
select new Paragraph(p);
#endregion
#region CustomFilePropertiesPart
// Get the custom file properties part from the package
customPropertiesPart = wdDoc.CustomFilePropertiesPart;
// This docx contains a customFilePropertyPart
if (customPropertiesPart != null)
{
// Load the customFilePropertyPart
using (TextReader tr = new StreamReader(customPropertiesPart.GetStream(FileMode.Open, FileAccess.Read)))
{
customPropDoc = XDocument.Load(tr, LoadOptions.PreserveWhitespace);
}
// Get all of the custom properties in this document
DocX.customProperties = from cp in customPropDoc.Descendants(XName.Get("property", customPropertiesSchema.NamespaceName))
select new CustomProperty(cp);
}
#endregion
// Save the new docx file to disk and return
DocX created = new DocX();
created.Save();
return created;
}
/// <summary> /// <summary>
/// Loads a .docx file into a DocX object. /// Loads a .docx file into a DocX object.
/// </summary> /// </summary>
/// <summary> /// <summary>
/// Renumber all ins and del ids in this .docx file. /// Renumber all ins and del ids in this .docx file.
/// </summary> /// </summary>
private static void RenumberIDs()
internal static void RenumberIDs()
{ {
IEnumerable<XAttribute> trackerIDs = IEnumerable<XAttribute> trackerIDs =
(from d in mainDoc.Descendants() (from d in mainDoc.Descendants()

+ 6
- 0
DocX/DocX.csproj 파일 보기

<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.XML" /> <Reference Include="System.XML" />
<Reference Include="System.Xml.Linq"> <Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CustomProperty.cs" /> <Compile Include="CustomProperty.cs" />
<Compile Include="Enumerations.cs" /> <Compile Include="Enumerations.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Formatting.cs" />
<Compile Include="Paragraph.cs" /> <Compile Include="Paragraph.cs" />
<Compile Include="DocX.cs" /> <Compile Include="DocX.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />

+ 32
- 0
DocX/Extensions.cs 파일 보기

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Novacode
{
public static class Extensions
{
public static string ToHex(this Color source)
{
byte red = source.R;
byte green = source.G;
byte blue = source.B;
string redHex = red.ToString("X");
if (redHex.Length < 2)
redHex = "0" + redHex;
string blueHex = blue.ToString("X");
if (blueHex.Length < 2)
blueHex = "0" + blueHex;
string greenHex = green.ToString("X");
if (greenHex.Length < 2)
greenHex = "0" + greenHex;
return string.Format("{0}{1}{2}", redHex, greenHex, blueHex);
}
}
}

+ 272
- 0
DocX/Formatting.cs 파일 보기

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
namespace Novacode
{
public enum Script { superscript, subscript, none }
public enum Highlight { yellow, green, cyan, magenta, blue, red, darkBlue, darkCyan, darkGreen, darkMagenta, darkRed, darkYellow, darkGray, lightGray, black, none};
public enum UnderlineStyle { none, singleLine, doubleLine, thick, dotted, dottedHeavy, dash, dashedHeavy, dashLong, dashLongHeavy, dotDash, dashDotHeavy, dotDotDash, dashDotDotHeavy, wave, wavyHeavy, wavyDouble, words};
public enum StrickThrough { none, strike, doubleStrike };
public enum Misc { none, shadow, outline, outlineShadow, emboss, engrave};
public enum CapsStyle { none, caps, smallCaps };
public class Formatting
{
private XElement rPr;
private bool hidden;
private bool bold;
private bool italic;
private StrickThrough strikethrough;
private Script script;
private Highlight highlight;
private double? size;
private Color? fontColor;
private Color? underlineColor;
private UnderlineStyle underlineStyle;
private Misc misc;
private CapsStyle capsStyle;
private FontFamily fontFamily;
private int? percentageScale;
private int? kerning;
private int? position;
private double? spacing;
public Formatting()
{
capsStyle = CapsStyle.none;
strikethrough = StrickThrough.none;
script = Script.none;
highlight = Highlight.none;
underlineStyle = UnderlineStyle.none;
misc = Misc.none;
rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName));
}
public XElement Xml
{
get
{
if(spacing.HasValue)
rPr.Add(new XElement(XName.Get("spacing", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), spacing.Value * 20)));
if(position.HasValue)
rPr.Add(new XElement(XName.Get("position", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), position.Value * 2)));
if (kerning.HasValue)
rPr.Add(new XElement(XName.Get("kern", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), kerning.Value * 2)));
if (percentageScale.HasValue)
rPr.Add(new XElement(XName.Get("w", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), percentageScale)));
if(fontFamily != null)
rPr.Add(new XElement(XName.Get("rFonts", DocX.w.NamespaceName), new XAttribute(XName.Get("ascii", DocX.w.NamespaceName), fontFamily.Name)));
if(hidden)
rPr.Add(new XElement(XName.Get("vanish", DocX.w.NamespaceName)));
if (bold)
rPr.Add(new XElement(XName.Get("b", DocX.w.NamespaceName)));
if (italic)
rPr.Add(new XElement(XName.Get("i", DocX.w.NamespaceName)));
switch (underlineStyle)
{
case UnderlineStyle.none:
break;
case UnderlineStyle.singleLine:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
break;
case UnderlineStyle.doubleLine:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "double")));
break;
default:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), underlineStyle.ToString())));
break;
}
if(underlineColor.HasValue)
{
// If an underlineColor has been set but no underlineStyle has been set
if (underlineStyle == UnderlineStyle.none)
{
// Set the underlineStyle to the default
underlineStyle = UnderlineStyle.singleLine;
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
}
rPr.Element(XName.Get("u", DocX.w.NamespaceName)).Add(new XAttribute(XName.Get("color", DocX.w.NamespaceName), underlineColor.Value.ToHex()));
}
switch (strikethrough)
{
case StrickThrough.none:
break;
case StrickThrough.strike:
rPr.Add(new XElement(XName.Get("strike", DocX.w.NamespaceName)));
break;
case StrickThrough.doubleStrike:
rPr.Add(new XElement(XName.Get("dstrike", DocX.w.NamespaceName)));
break;
default:
break;
}
switch (script)
{
case Script.none:
break;
default:
rPr.Add(new XElement(XName.Get("vertAlign", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), script.ToString())));
break;
}
if (size.HasValue)
{
rPr.Add(new XElement(XName.Get("sz", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
rPr.Add(new XElement(XName.Get("szCs", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
}
if(fontColor.HasValue)
rPr.Add(new XElement(XName.Get("color", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontColor.Value.ToHex())));
switch (highlight)
{
case Highlight.none:
break;
default:
rPr.Add(new XElement(XName.Get("highlight", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), highlight.ToString())));
break;
}
switch (capsStyle)
{
case CapsStyle.none:
break;
default:
rPr.Add(new XElement(XName.Get(capsStyle.ToString(), DocX.w.NamespaceName)));
break;
}
switch (misc)
{
case Misc.none:
break;
case Misc.outlineShadow:
rPr.Add(new XElement(XName.Get("outline", DocX.w.NamespaceName)));
rPr.Add(new XElement(XName.Get("shadow", DocX.w.NamespaceName)));
break;
case Misc.engrave:
rPr.Add(new XElement(XName.Get("imprint", DocX.w.NamespaceName)));
break;
default:
rPr.Add(new XElement(XName.Get(misc.ToString(), DocX.w.NamespaceName)));
break;
}
return rPr;
}
}
public bool Bold { get { return bold; } set { bold = value;} }
public bool Italic { get { return Italic; } set { italic = value; } }
public StrickThrough StrikeThrough { get { return strikethrough; } set { strikethrough = value; } }
public Script Script { get { return script; } set { script = value; } }
public double? Size
{
get { return size; }
set
{
double? temp = value * 2;
if (temp - (int)temp == 0)
{
if(value > 0 && value < 1639)
size = value;
else
throw new ArgumentException("Size", "Value must be in the range 0 - 1638");
}
else
throw new ArgumentException("Size", "Value must be either a whole or half number, examples: 32, 32.5");
}
}
public int? PercentageScale
{
get { return percentageScale; }
set
{
if ((new int?[] { 200, 150, 100, 90, 80, 66, 50, 33 }).Contains(value))
percentageScale = value;
else
throw new ArgumentOutOfRangeException("PercentageScale", "Value must be one of the following: 200, 150, 100, 90, 80, 66, 50 or 33");
}
}
public int? Kerning
{
get { return kerning; }
set
{
if(new int?[] {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}.Contains(value))
kerning = value;
else
throw new ArgumentOutOfRangeException("Kerning", "Value must be one of the following: 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 or 72");
}
}
public int? Position
{
get { return position; }
set
{
if (value > -1585 && value < 1585)
position = value;
else
throw new ArgumentOutOfRangeException("Position", "Value must be in the range -1585 - 1585");
}
}
public double? Spacing
{
get { return spacing; }
set
{
double? temp = value * 20;
if (temp - (int)temp == 0)
{
if (value > -1585 && value < 1585)
spacing = value;
else
throw new ArgumentException("Spacing", "Value must be in the range: -1584 - 1584");
}
else
throw new ArgumentException("Spacing", "Value must be either a whole or acurate to one decimal, examples: 32, 32.1, 32.2, 32.9");
}
}
public Color? FontColor { get { return fontColor; } set { fontColor = value; } }
public Highlight Highlight { get { return highlight; } set { highlight = value; } }
public UnderlineStyle UnderlineStyle { get { return underlineStyle; } set { underlineStyle = value; } }
public Color? UnderlineColor { get { return underlineColor; } set { underlineColor = value; } }
public Misc Misc { get { return misc; } set { misc = value; } }
public bool Hidden { get { return hidden; } set { hidden = value; } }
public CapsStyle CapsStyle { get { return capsStyle; } set { capsStyle = value; } }
public FontFamily FontFamily { get { return FontFamily; } set { fontFamily = value; } }
}
}

+ 102
- 67
DocX/Paragraph.cs 파일 보기

// Loop through each run in this paragraph // Loop through each run in this paragraph
foreach (XElement run in runs) foreach (XElement run in runs)
{ {
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
// Only add runs which contain text
if (GetElementTextLength(run) > 0)
{
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
}
} }
} }
/// <returns>The first Run that will be effected</returns> /// <returns>The first Run that will be effected</returns>
public Run GetFirstRunEffectedByInsert(int index) public 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) foreach (int runEndIndex in runLookup.Keys)
{ {
if (runEndIndex >= index) if (runEndIndex >= index)
); );
} }
public void Insert(int index, string value, bool trackChanges)
{
Insert(index, value, null, trackChanges);
}
/// <summary> /// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position. /// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary> /// </summary>
/// <param name="index">The index position of the insertion.</param> /// <param name="index">The index position of the insertion.</param>
/// <param name="value">The System.String to insert.</param> /// <param name="value">The System.String to insert.</param>
/// <param name="trackChanges">Flag this insert as a change</param> /// <param name="trackChanges">Flag this insert as a change</param>
public void Insert(int index, string value, bool trackChanges)
public void Insert(int index, string value, Formatting formatting, bool trackChanges)
{ {
// Timestamp to mark the start of insert // Timestamp to mark the start of insert
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
// Get the first run effected by this Insert // Get the first run effected by this Insert
Run run = GetFirstRunEffectedByInsert(index); Run run = GetFirstRunEffectedByInsert(index);
// Convert value into a List of XElement's
List<XElement> newRuns = formatInput(value, run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName)));
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);
p.Add(insert);
}
// The parent of this Run
XElement parentElement = run.Xml.Parent;
switch (parentElement.Name.LocalName)
else
{ {
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)
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;
}
/* /*
* Inserting into a non edit and this special case, is the same procedure.
* If not the special case above,
* then inserting into an ins or a del, is the same procedure.
*/ */
goto default;
goto case "del";
} }
/*
* 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);
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;
}
// Split this Edit at the point you want to insert
XElement[] splitEdit = SplitEdit(parentElement, index, EditType.ins);
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;
}
// 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 // Rebuild the run lookup for this paragraph
runLookup.Clear(); runLookup.Clear();
BuildRunLookup(p); BuildRunLookup(p);
DocX.RenumberIDs();
} }
/// <summary> /// <summary>
int min = Math.Min(count - processed, run.Xml.ElementsAfterSelf().Sum(e => GetElementTextLength(e))); int min = Math.Min(count - processed, run.Xml.ElementsAfterSelf().Sum(e => GetElementTextLength(e)));
XElement[] splitEditAfter = SplitEdit(parentElement, index + processed + min, EditType.del); XElement[] splitEditAfter = SplitEdit(parentElement, index + processed + min, EditType.del);
object middle = CreateEdit(EditType.del, remove_datetime, SplitEdit(splitEditBefore[1], min, EditType.del)[0].Descendants());
XElement temp = SplitEdit(splitEditBefore[1], index + processed + min, EditType.del)[0];
object middle = CreateEdit(EditType.del, remove_datetime, temp.Elements().ToArray());
processed += GetElementTextLength(middle as XElement); processed += GetElementTextLength(middle as XElement);
if (!trackChanges) if (!trackChanges)
// Rebuild the run lookup // Rebuild the run lookup
runLookup.Clear(); runLookup.Clear();
BuildRunLookup(p); BuildRunLookup(p);
DocX.RenumberIDs();
} }
/// <summary> /// <summary>

+ 7
- 3
DocX/Run.cs 파일 보기

case "t": goto case "delText"; case "t": goto case "delText";
case "delText": case "delText":
{ {
textLookup.Add(start + text.Value.Length, new Text(start, text));
Value += text.Value;
start += text.Value.Length;
// Only add strings which are not empty
if (text.Value.Length > 0)
{
textLookup.Add(start + text.Value.Length, new Text(start, text));
Value += text.Value;
start += text.Value.Length;
}
break; break;
} }
default: break; default: break;

+ 1
- 0
StringReplaceTestApp/Program.cs 파일 보기

using Novacode; using Novacode;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.IO; using System.IO;
using System.Xml.Linq;
namespace StringReplaceTestApp namespace StringReplaceTestApp
{ {

+ 6
- 4
StringReplaceTestApp/StringReplaceTestApp.csproj 파일 보기

<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DocX, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\DocX\bin\Debug\DocX.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DocX\DocX.csproj">
<Project>{E863D072-AA8B-4108-B5F1-785241B37F67}</Project>
<Name>DocX</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

Loading…
취소
저장