1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.gshell.ansi;
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class AnsiRenderer
35 {
36 public static final String BEGIN_TOKEN = "@|";
37
38 private static final int BEGIN_TOKEN_SIZE = BEGIN_TOKEN.length();
39
40 public static final String END_TOKEN = "|";
41
42 private static final int END_TOKEN_SIZE = END_TOKEN.length();
43
44 public static final String CODE_TEXT_SEPARATOR = " ";
45
46 public static final String CODE_LIST_SEPARATOR = ",";
47
48 private final AnsiBuffer buff = new AnsiBuffer();
49
50 public String render(final String input) throws RenderException {
51 assert input != null;
52
53
54 int c = 0, p, s;
55
56 while (c < input.length()) {
57 p = input.indexOf(BEGIN_TOKEN, c);
58 if (p < 0) { break; }
59
60 s = input.indexOf(END_TOKEN, p + BEGIN_TOKEN_SIZE);
61 if (s < 0) {
62 throw new RenderException("Missing '" + END_TOKEN + "': " + input);
63 }
64
65 String expr = input.substring(p + BEGIN_TOKEN_SIZE, s);
66
67 buff.append(input.substring(c, p));
68
69 evaluate(expr);
70
71 c = s + END_TOKEN_SIZE;
72 }
73
74 buff.append(input.substring(c));
75
76 return buff.toString();
77 }
78
79 private void evaluate(final String input) throws RenderException {
80 assert input != null;
81
82 int i = input.indexOf(CODE_TEXT_SEPARATOR);
83 if (i < 0) {
84 throw new RenderException("Missing ANSI code/text separator '" + CODE_TEXT_SEPARATOR + "': " + input);
85 }
86
87 String tmp = input.substring(0, i);
88 String[] codes = tmp.split(CODE_LIST_SEPARATOR);
89 String text = input.substring(i + 1, input.length());
90
91 for (String name : codes) {
92 AnsiCode code = AnsiCode.valueOf(name.toUpperCase());
93 buff.attrib(code);
94 }
95
96 buff.append(text);
97
98 buff.attrib(AnsiCode.OFF);
99 }
100
101
102
103
104
105 public static class RenderException
106 extends RuntimeException
107 {
108 public RenderException(final String msg) {
109 super(msg);
110 }
111 }
112
113
114
115
116
117 public static boolean test(final String text) {
118 return text != null && text.indexOf(BEGIN_TOKEN) >= 0;
119 }
120
121 public static String encode(final Object text, final AnsiCode code) {
122 return new StringBuilder(BEGIN_TOKEN).
123 append(code.name()).
124 append(CODE_TEXT_SEPARATOR).
125 append(text).
126 append(END_TOKEN).
127 toString();
128 }
129 }