forked from fdorg/flashdevelop
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBBCodeTagMatcher.cs
More file actions
186 lines (143 loc) · 6.01 KB
/
Copy pathBBCodeTagMatcher.cs
File metadata and controls
186 lines (143 loc) · 6.01 KB
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
using System.Text.RegularExpressions;
namespace PluginCore.BBCode
{
public class BBCodeTagMatcher : IPairTagMatcher
{
public BBCodeTagMatcher()
{
_reOpener = _buildReOpenerFor(@"[\*\~]?\w[\w\d\-_]*");
}
protected string _input;
protected string _retplOpenerA = @"(?<slashA>\\*)(?<tagVal>\[(?<tagName>";
protected string _retplOpenerB = @")(\s*\=\s*(?<tagParam>[^\]\\]*))?(?<slashB>\\*)\])";
protected string _retplCloserA = @"(?<slashA>\\*)(?<tagVal>\[\/(?<tagName>";
protected string _retplCloserB = @")\])";
protected Regex _reOpener;
public string input
{
get => _input;
set => _input = value;
}
public IPairTagMatch searchOpener()
{
return searchOpener(0);
}
public IPairTagMatch searchOpener(uint startAt)
{
return _searchMatch(_reOpener, true, startAt);
}
public IPairTagMatch searchOpenerAs(IPairTagMatch opener)
{
return searchOpenerAs(opener, 0);
}
public IPairTagMatch searchOpenerAs(IPairTagMatch opener, uint startAt)
{
BBCodeTagMatch tm = opener as BBCodeTagMatch;
if (string.IsNullOrEmpty(tm?.tagName)) return null;
return searchOpenerByName(tm.tagName, startAt);
}
public IPairTagMatch searchOpenerByName(string tagName) => searchOpenerByName(tagName, 0);
public IPairTagMatch searchOpenerByName(string tagName, uint startAt)
{
if (string.IsNullOrEmpty(tagName))
return null;
return _searchMatch(_buildReOpenerFor(tagName), true, startAt);
}
public IPairTagMatch searchCloserFor(IPairTagMatch opener) => searchCloserFor(opener, 0);
public IPairTagMatch searchCloserFor(IPairTagMatch opener, uint startAt)
{
BBCodeTagMatch tm = opener as BBCodeTagMatch;
if (string.IsNullOrEmpty(tm?.tagName)) return null;
IPairTagMatch successMatch = null;
int j = 0xFFFFFF;
int i = tm.tagCloserInfos.Count;
while (i-- > 0)
{
var m = searchCloserByName(tm.tagCloserInfos[i].tagName, tm.tagCloserInfos[i].isTagOpener, startAt);
if (m != null && m.tagIndex < j)
{
j = m.tagIndex;
successMatch = m;
}
}
return successMatch;
}
public IPairTagMatch searchCloserByName(string tagName) => searchCloserByName(tagName, false);
public IPairTagMatch searchCloserByName(string tagName, bool isOpener) => searchCloserByName(tagName, isOpener, 0);
public IPairTagMatch searchCloserByName(string tagName, bool isOpener, uint startAt)
{
if (string.IsNullOrEmpty(tagName))
return null;
return _searchMatch(_buildReCloserFor(tagName), isOpener, startAt);
}
protected Regex _buildReOpenerFor() => _buildReOpenerFor("");
protected Regex _buildReOpenerFor(string tagName) => _buildReOpenerFor(tagName, RegexOptions.IgnoreCase);
protected Regex _buildReOpenerFor(string tagName, RegexOptions reFlags)
{
return new Regex(_retplOpenerA + tagName + _retplOpenerB, reFlags);
}
protected Regex _buildReCloserFor()
{
return _buildReCloserFor("");
}
protected Regex _buildReCloserFor(string tagName)
{
return _buildReCloserFor(tagName, RegexOptions.IgnoreCase);
}
protected Regex _buildReCloserFor(string tagName, RegexOptions reFlags)
{
return new Regex(_retplCloserA + tagName + _retplCloserB, reFlags);
}
protected BBCodeTagMatch _searchMatch(Regex regex, bool isOpener)
{
return _searchMatch(regex, isOpener, 0);
}
protected BBCodeTagMatch _searchMatch(Regex regex, bool isOpener, uint startAt)
{
if (regex is null) return null;
int idx = (int)startAt - 16;
if (idx < 0) idx = 0;
BBCodeTagMatch tm;
while (true)
{
var m = regex.Match(_input, idx);
if (!m.Success || m.Index < 0)
return null;
idx = m.Index + m.Length;
tm = _toTagMatch(isOpener, m);
if (tm.tagIndex < startAt
|| tm.numOpenBraceSlashes % 2 != 0
|| tm.numCloseBraceSlashes % 2 != 0)
continue;
break;
}
return tm;
}
protected BBCodeTagMatch _toTagMatch(bool isOpener, Match m)
{
if (m is null) return null;
Group mi = m.Groups["slashA"];
int numSlashA = (mi != null && mi.Success) ? mi.Length : 0;
mi = m.Groups["slashB"];
int numSlashB = (mi != null && mi.Success) ? mi.Length : 0;
mi = m.Groups["tagVal"];
string tagVal = (mi != null && mi.Success) ? mi.Value : "";
int tagIndex = (mi != null && mi.Success) ? mi.Index : -1;
mi = m.Groups["tagName"];
string tagName = (mi != null && mi.Success) ? mi.Value : "";
mi = m.Groups["tagParam"];
string tagParam = (mi != null && mi.Success) ? mi.Value : "";
BBCodeTagMatch tm = new BBCodeTagMatch(isOpener,
tagIndex,
tagVal,
tagName,
tagParam,
(uint)numSlashA,
(uint)numSlashB,
true);
if (isOpener)
tm.bbCodeStyle = new BBCodeStyle();
return tm;
}
}
}