83 lines
2.5 KiB
C#
83 lines
2.5 KiB
C#
using System.Collections.Generic;
|
|
using Aspose.Words;
|
|
using Aspose.Words.Replacing;
|
|
|
|
namespace Kreta.BusinessLogic.Utils
|
|
{
|
|
public class WordTextReplacer : IReplacingCallback
|
|
{
|
|
public List<Run> _nodes = new List<Run>();
|
|
|
|
ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
|
|
{
|
|
// This is a Run node that contains either the beginning or the complete match.
|
|
var currentNode = e.MatchNode;
|
|
|
|
// The first (and may be the only) run can contain text before the match,
|
|
// in this case it is necessary to split the run.
|
|
if (e.MatchOffset > 0)
|
|
{
|
|
currentNode = SplitRun((Run)currentNode, e.MatchOffset);
|
|
}
|
|
|
|
var runs = new System.Collections.ArrayList();
|
|
|
|
// Find all runs that contain parts of the match string.
|
|
var remainingLength = e.Match.Value.Length;
|
|
while (
|
|
|
|
(remainingLength > 0) &&
|
|
|
|
(currentNode != null) &&
|
|
|
|
(currentNode.GetText().Length <= remainingLength))
|
|
{
|
|
|
|
runs.Add(currentNode);
|
|
|
|
remainingLength -= currentNode.GetText().Length;
|
|
|
|
// Select the next Run node.
|
|
// Have to loop because there could be other nodes such as BookmarkStart etc.
|
|
do
|
|
{
|
|
currentNode = currentNode.NextSibling;
|
|
}
|
|
while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
|
|
}
|
|
|
|
// Split the last run that contains the match if there is any text left.
|
|
if ((currentNode != null) && (remainingLength > 0))
|
|
{
|
|
SplitRun((Run)currentNode, remainingLength);
|
|
runs.Add(currentNode);
|
|
}
|
|
|
|
var runText = "";
|
|
foreach (Run run in runs)
|
|
{
|
|
runText += run.Text;
|
|
}
|
|
|
|
((Run)runs[0]).Text = runText;
|
|
|
|
for (var i = 1; i < runs.Count; i++)
|
|
{
|
|
((Run)runs[i]).Remove();
|
|
}
|
|
|
|
_nodes.Add((Run)runs[0]);
|
|
|
|
return ReplaceAction.Replace;
|
|
}
|
|
|
|
private static Run SplitRun(Run run, int position)
|
|
{
|
|
var afterRun = (Run)run.Clone(true);
|
|
afterRun.Text = run.Text.Substring(position);
|
|
run.Text = run.Text.Substring(0, position);
|
|
run.ParentNode.InsertAfter(afterRun, run);
|
|
return afterRun;
|
|
}
|
|
}
|
|
}
|