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
|
package bjc.utils.ioutils.format.directives;
import java.io.*;
import java.util.regex.*;
import bjc.utils.ioutils.ReportWriter;
import bjc.utils.ioutils.format.*;
/**
* Implementation of the ( directive.
*
* This directive does case manipulation of the contained text.
*
* @author Ben Culkin
*/
public class CaseDirective implements Directive {
/**
* Compile a case directive.
*
* @param compCTX
* The context to use for compilation.
*/
@Override
public Edict compile(CompileContext compCTX) {
CLModifiers mods = compCTX.decr.modifiers;
GroupDecree condBody = compCTX.directives.nextGroup(compCTX.decr, ")");
CaseEdict.Mode mode;
if (mods.colonMod && mods.atMod) {
mode = CaseEdict.Mode.UPPERCASE;
} else if (mods.colonMod) {
mode = CaseEdict.Mode.WORD_UPPERCASE;
} else if (mods.atMod) {
mode = CaseEdict.Mode.FIRST_UPPERCASE;
} else {
mode = CaseEdict.Mode.LOWERCASE;
}
return new CaseEdict(condBody, mode, compCTX.formatter);
}
}
class CaseEdict implements Edict {
public static enum Mode {
UPPERCASE, WORD_UPPERCASE, FIRST_UPPERCASE, LOWERCASE
}
private static final Pattern wordPattern = Pattern.compile("(\\w+)(\\b*)");
private CLString body;
private Mode caseMode;
public CaseEdict(GroupDecree body, Mode caseMode, CLFormatter fmt) {
this.body = new CLString(fmt.compile(body.unwrap()));
this.caseMode = caseMode;
}
@Override
public void format(FormatContext formCTX) throws IOException {
try (ReportWriter nrw = formCTX.getScratchWriter()) {
String strang = body.format(nrw, formCTX.items);
switch (caseMode) {
case UPPERCASE:
strang = strang.toUpperCase();
break;
case WORD_UPPERCASE: {
Matcher mat = wordPattern.matcher(strang);
StringBuffer sb = new StringBuffer();
while (mat.find()) {
mat.appendReplacement(sb, "");
String word = mat.group(1);
String upperWord = word.substring(0, 1).toUpperCase()
+ word.substring(1);
sb.append(upperWord);
sb.append(mat.group(2));
}
mat.appendTail(sb);
strang = sb.toString();
}
break;
case FIRST_UPPERCASE: {
Matcher mat = wordPattern.matcher(strang);
StringBuffer sb = new StringBuffer();
boolean doCap = true;
while (mat.find()) {
mat.appendReplacement(sb, "");
String word = mat.group(1);
if (doCap) {
doCap = false;
word = word.substring(0, 1).toUpperCase()
+ word.substring(1);
}
sb.append(word);
sb.append(mat.group(2));
}
mat.appendTail(sb);
strang = sb.toString();
}
break;
case LOWERCASE:
strang = strang.toLowerCase();
break;
default:
String msg = String.format(
"INTERNAL ERROR: CaseEdict mode %s is not supported. This is a bug.",
caseMode);
throw new IllegalArgumentException(msg);
}
formCTX.writer.write(strang);
}
}
}
|