-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
/
AbstractMarkupText.java
166 lines (146 loc) · 5.16 KB
/
AbstractMarkupText.java
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
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson;
import hudson.MarkupText.SubText;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Common part between {@link MarkupText} and {@link MarkupText.SubText}.
*
* <p>
* See {@link MarkupText} for more discussion about what this class represents.
*
* @author Kohsuke Kawaguchi
* @since 1.250
*/
public abstract class AbstractMarkupText {
/*package*/ AbstractMarkupText() {} // limit who can subclass this type.
/**
* Returns the plain text portion of this {@link MarkupText} without
* any markup, nor any escape.
*/
public abstract String getText();
public char charAt(int idx) {
return getText().charAt(idx);
}
/**
* Length of the plain text.
*/
public final int length() {
return getText().length();
}
/**
* Returns a subtext.
*
* @param end
* If negative, -N means "trim the last N-1 chars". That is, (s,-1) is the same as (s,length)
*/
public abstract MarkupText.SubText subText(int start, int end);
/**
* Adds a start tag and end tag at the specified position.
*
* <p>
* For example, if the text was "abc", then {@code addMarkup(1,2,"<b>","</b>")}
* would generate {@code"a<b>b</b>c"}
*/
public abstract void addMarkup( int startPos, int endPos, String startTag, String endTag );
/**
* Inserts an A tag that surrounds the given position.
*
* @since 1.349
*/
public void addHyperlink( int startPos, int endPos, String url ) {
addMarkup(startPos,endPos,"<a href='"+url+"'>","</a>");
}
/**
* Inserts an A tag that surrounds the given position.
* But this hyperlink is less visible.
*
* @since 1.395
*/
public void addHyperlinkLowKey( int startPos, int endPos, String url ) {
addMarkup(startPos,endPos,"<a class='lowkey' href='"+url+"'>","</a>");
}
/**
* Hides the given text.
*/
public void hide( int startPos, int endPos ) {
addMarkup(startPos,endPos,"<span style='display:none'>","</span>");
}
/**
* Adds a start tag and end tag around the entire text
*/
public final void wrapBy(String startTag, String endTag) {
addMarkup(0,length(),startTag,endTag);
}
/**
* Find the first occurrence of the given pattern in this text, or null.
*
* @since 1.349
*/
public MarkupText.SubText findToken(Pattern pattern) {
String text = getText();
Matcher m = pattern.matcher(text);
if(m.find())
return createSubText(m);
return null;
}
/**
* Find all "tokens" that match the given pattern in this text.
*
* <p>
* A token is like a substring, except that it's aware of word boundaries.
* For example, while "bc" is a string of "abc", calling {@code findTokens}
* with "bc" as a pattern on string "abc" won't match anything.
*
* <p>
* This method is convenient for finding keywords that follow a certain syntax
* from natural text. You can then use {@link MarkupText.SubText#surroundWith(String,String)}
* to put mark up around such text.
*/
public List<MarkupText.SubText> findTokens(Pattern pattern) {
String text = getText();
Matcher m = pattern.matcher(text);
List<SubText> r = new ArrayList<>();
while(m.find()) {
int idx = m.start();
if(idx>0) {
char ch = text.charAt(idx-1);
if(Character.isLetter(ch) || Character.isDigit(ch))
continue; // not at a word boundary
}
idx = m.end();
if(idx<text.length()) {
char ch = text.charAt(idx);
if(Character.isLetter(ch) || Character.isDigit(ch))
continue; // not at a word boundary
}
r.add(createSubText(m));
}
return r;
}
protected abstract SubText createSubText(Matcher m);
}