Files
2022-01-24 10:00:02 +08:00

78 lines
2.6 KiB
C#

using System.Xml;
namespace PDFPatcher.Processor
{
internal abstract class BookmarkMatcher
{
internal enum MatcherType
{
Normal, Regex, XPath
}
internal abstract bool Match(XmlElement item);
internal abstract IUndoAction Replace(XmlElement item, string replacement);
internal static BookmarkMatcher Create(string pattern, MatcherType type, bool matchCase, bool fullMatch) {
return type == MatcherType.XPath
? new XPathMatcher(pattern)
: new RegexMatcher(pattern, matchCase, type == MatcherType.Regex, fullMatch);
}
sealed class RegexMatcher : BookmarkMatcher
{
readonly Model.MatchPattern.IMatcher _matcher;
internal RegexMatcher(string pattern, bool matchCase, bool regexSearch, bool fullMatch) {
_matcher = new Model.MatchPattern(pattern, matchCase, fullMatch, regexSearch).CreateMatcher();
}
internal override bool Match(XmlElement item) {
return _matcher.Matches(item.GetAttribute(Constants.BookmarkAttributes.Title));
}
internal override IUndoAction Replace(XmlElement item, string replacement) {
var a = item.GetAttributeNode(Constants.BookmarkAttributes.Title);
if (a == null) {
return null;
}
var t = a.Value;
if (_matcher.Matches(t)) {
var r = _matcher.Replace(t, replacement);
return r == t ? null : (IUndoAction)UndoAttributeAction.GetUndoAction(item, Constants.BookmarkAttributes.Title, r);
}
return null;
}
}
sealed class XPathMatcher : BookmarkMatcher
{
readonly System.Xml.XPath.XPathExpression _xpath;
internal XPathMatcher(string pattern) {
_xpath = System.Xml.XPath.XPathExpression.Compile("*[" + pattern + "]");
}
internal override bool Match(XmlElement item) {
return item.CreateNavigator().Matches(_xpath);
}
internal override IUndoAction Replace(XmlElement item, string replacement) {
var a = item.GetAttributeNode(Constants.BookmarkAttributes.Title);
if (a == null) {
return null;
}
var n = item.CreateNavigator().SelectSingleNode(_xpath);
return n == null || a.Value == replacement
? null
: (IUndoAction)UndoAttributeAction.GetUndoAction(item, Constants.BookmarkAttributes.Title, replacement);
}
}
internal sealed class SimpleReplacer : BookmarkMatcher
{
internal override bool Match(XmlElement item) {
return true;
}
internal override IUndoAction Replace(XmlElement item, string replacement) {
var a = item.GetAttributeNode(Constants.BookmarkAttributes.Title);
if (a == null) {
return null;
}
return a.Value != replacement
? UndoAttributeAction.GetUndoAction(item, Constants.BookmarkAttributes.Title, replacement)
: (IUndoAction)null;
}
}
}
}