kreta/Kreta.BusinessLogic/Utils/WordTextReplacer.cs
2024-03-13 00:33:46 +01:00

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;
}
}
}