/
TagOptions.cs
150 lines (126 loc) · 5.31 KB
/
TagOptions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//===============================================================================================================
// System : HTML to MAML Converter
// File : TagOptions.cs
// Author : Eric Woodruff (Eric@EWoodruff.us)
// Updated : 04/08/2021
// Note : Copyright 2008-2021, Eric Woodruff, All rights reserved
//
// This file contains a class that is used to contain options for tag entries from the conversion rules file
//
// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
// distributed with the code and can be found at the project website: https://GitHub.com/EWSoftware/HtmlToMamlConverter. This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
// Date Who Comments
// ==============================================================================================================
// 09/17/2008 EFW Created the code
//===============================================================================================================
using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Text.RegularExpressions;
namespace HtmlToMamlConversion
{
/// <summary>
/// This is used to contain the options and state for a <c>Tag</c> entry from the conversion rules file
/// </summary>
public class TagOptions
{
#region Private data members
//=====================================================================
private readonly XPathNodeIterator matchRules;
private readonly Stack<string> endTags;
private readonly string startTag, endTag, tagAttributes;
private string tag, attributes, closing;
#endregion
#region Properties
//=====================================================================
/// <summary>
/// This returns the replacement tag to use based on the last
/// evaluation.
/// </summary>
public string Tag => tag;
/// <summary>
/// This returns the attributes to use based on the last evaluation
/// </summary>
public string Attributes => attributes;
/// <summary>
/// This returns the closing "/" if the element is an end tag
/// </summary>
public string Closing => closing;
#endregion
#region Constructor
//=====================================================================
/// <summary>
/// Constructor
/// </summary>
/// <param name="tag">The tag node</param>
public TagOptions(XPathNavigator tag)
{
startTag = tag.GetAttribute("startTag", String.Empty);
endTag = tag.GetAttribute("endTag", String.Empty);
tagAttributes = tag.GetAttribute("attributes", String.Empty);
matchRules = tag.Select("Match");
endTags = new Stack<string>();
}
#endregion
#region Methods, etc.
//=====================================================================
/// <summary>
/// Evaluate the match and determine the properties to use for the replacement
/// </summary>
/// <param name="match">The regular expression match to evaluate</param>
public void Evaluate(Match match)
{
Regex reRule;
string tagAttrs;
closing = match.Groups["Closing"].Value;
tagAttrs = match.Groups["Attributes"].Value;
tag = startTag;
attributes = tagAttributes;
// If it's a closing tag, process it
if(!String.IsNullOrEmpty(closing))
{
attributes = String.Empty;
if(endTags.Count != 0)
tag = endTags.Pop();
else
if(!String.IsNullOrEmpty(endTag))
tag = endTag;
return;
}
// It's an opening or self-closing tag. Check for a match rule.
if(matchRules.Count != 0)
foreach(XPathNavigator rule in matchRules)
{
reRule = new Regex(rule.GetAttribute("expression", String.Empty), RegexOptions.IgnoreCase |
RegexOptions.Singleline);
if(reRule.IsMatch(match.Value))
{
tag = rule.GetAttribute("startTag", String.Empty);
attributes = rule.GetAttribute("attributes", String.Empty);
if(!String.IsNullOrEmpty(rule.GetAttribute("endTag", String.Empty)))
endTags.Push(rule.GetAttribute("endTag", String.Empty));
else
endTags.Push(tag);
break;
}
}
if(attributes == "@Preserve")
{
if(!String.IsNullOrEmpty(tagAttrs))
attributes = " " + tagAttrs.Trim();
else
attributes = String.Empty;
}
else
if(tagAttrs == "/")
attributes = tagAttrs;
else
if(!String.IsNullOrEmpty(attributes))
attributes = " " + attributes;
}
#endregion
}
}