import org.cacert.gigi.output.Outputable;
public class Template implements Outputable {
- static class TemplateBlock implements Outputable {
- String[] contents;
- Outputable[] vars;
-
- public TemplateBlock(String[] contents, Outputable[] vars) {
- this.contents = contents;
- this.vars = vars;
- }
-
- @Override
- public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- for (int i = 0; i < contents.length; i++) {
- out.print(contents[i]);
- if (i < this.vars.length) {
- this.vars[i].output(out, l, vars);
- }
- }
- }
-
- }
-
TemplateBlock data;
long lastLoaded;
File source;
- private static final Pattern IF_PATTERN = Pattern.compile(" ?if\\(\\$([^)]+)\\) ?\\{ ?");
+ private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-z]+)\\(\\$([^)]+)\\) ?\\{ ?");
public Template(URL u) {
try {
LinkedList<String> splitted = new LinkedList<String>();
LinkedList<Outputable> commands = new LinkedList<Outputable>();
StringBuffer buf = new StringBuffer();
- int ch = r.read();
outer: while (true) {
while (!endsWith(buf, "<?")) {
+ int ch = r.read();
if (ch == -1) {
break outer;
}
buf.append((char) ch);
- ch = r.read();
}
buf.delete(buf.length() - 2, buf.length());
splitted.add(buf.toString());
buf.delete(0, buf.length());
while (!endsWith(buf, "?>")) {
- buf.append((char) ch);
- ch = r.read();
+ int ch = r.read();
if (ch == -1) {
throw new EOFException();
}
+ buf.append((char) ch);
}
buf.delete(buf.length() - 2, buf.length());
String com = buf.toString().replace("\n", "");
buf.delete(0, buf.length());
- Matcher m = IF_PATTERN.matcher(com);
+ Matcher m = CONTROL_PATTERN.matcher(com);
if (m.matches()) {
- final String variable = m.group(1);
- final TemplateBlock body = parse(r);
- commands.add(new Outputable() {
-
- @Override
- public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- Object o = vars.get(variable);
- if (o instanceof Boolean && o == Boolean.TRUE) {
- body.output(out, l, vars);
- }
- }
- });
+ String type = m.group(1);
+ String variable = m.group(2);
+ TemplateBlock body = parse(r);
+ if (type.equals("if")) {
+ commands.add(new IfStatement(variable, body));
+ } else if (type.equals("foreach")) {
+ commands.add(new ForeachStatement(variable, body));
+ } else {
+ throw new IOException("Syntax error: unknown control structure: " + type);
+ }
continue;
}
if (com.matches(" ?\\} ?")) {
private Outputable parseCommand(String s2) {
if (s2.startsWith("=_")) {
final String raw = s2.substring(2);
- return new Outputable() {
-
- @Override
- public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- out.print(l.getTranslation(raw));
- }
- };
+ return new TranslateCommand(raw);
} else if (s2.startsWith("=$")) {
final String raw = s2.substring(2);
- return new Outputable() {
-
- @Override
- public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- outputVar(out, l, vars, raw);
- }
- };
+ return new OutputVariableCommand(raw);
} else if (s2.startsWith("=s,")) {
String command = s2.substring(3);
final LinkedList<String> store = new LinkedList<String>();
command = command.substring(idx + 1);
}
final String text = command;
- return new Outputable() {
-
- @Override
- public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- String[] parts = l.getTranslation(text).split("%s");
- String[] myvars = store.toArray(new String[store.size()]);
- out.print(parts[0]);
- for (int j = 1; j < parts.length; j++) {
- outputVar(out, l, vars, myvars[j - 1].substring(1));
- out.print(parts[j]);
- }
- }
- };
+ return new SprintfCommand(text, store);
} else {
System.out.println("Unknown processing instruction: " + s2);
}
try {
System.out.println("Reloading template.... " + source);
InputStreamReader r = new InputStreamReader(new FileInputStream(source), "UTF-8");
- parse(r);
+ data = parse(r);
r.close();
lastLoaded = source.lastModified() + 1000;
} catch (IOException e) {
data.output(out, l, vars);
}
- private void outputVar(PrintWriter out, Language l, Map<String, Object> vars, String varname) {
+ protected static void outputVar(PrintWriter out, Language l, Map<String, Object> vars, String varname) {
Object s = vars.get(varname);
if (s == null) {