import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.cacert.gigi.DevelLauncher;
import org.cacert.gigi.localisation.Language;
-import org.cacert.gigi.output.Outputable;
import org.cacert.gigi.util.HTMLEncoder;
public class Template implements Outputable {
+ class ParseResult {
+
+ TemplateBlock block;
+
+ String endType;
+
+ public ParseResult(TemplateBlock block, String endType) {
+ this.block = block;
+ this.endType = endType;
+ }
+
+ public String getEndType() {
+ return endType;
+ }
+
+ public TemplateBlock getBlock(String reqType) {
+ if (endType == null && reqType == null) {
+ return block;
+ }
+ if (endType == null || reqType == null) {
+ throw new Error("Invalid block type: " + endType);
+ }
+ if (endType.equals(reqType)) {
+ return block;
+ }
+ throw new Error("Invalid block type: " + endType);
+ }
+ }
+
private TemplateBlock data;
private long lastLoaded;
private File source;
- private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-z]+)\\(\\$([^)]+)\\) ?\\{ ?");
+ private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-zA-Z]+)\\(\\$([^)]+)\\) ?\\{ ?");
+
+ private static final Pattern ELSE_PATTERN = Pattern.compile(" ?\\} ?else ?\\{ ?");
public Template(URL u) {
try {
Reader r = new InputStreamReader(u.openStream(), "UTF-8");
try {
- if (u.getProtocol().equals("file") && DevelLauncher.DEVEL) {
+ if (u.getProtocol().equals("file")) {
source = new File(u.toURI());
lastLoaded = source.lastModified() + 1000;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
- data = parse(r);
+ data = parse(r).getBlock(null);
r.close();
} catch (IOException e) {
throw new Error(e);
public Template(Reader r) {
try {
- data = parse(r);
+ data = parse(r).getBlock(null);
r.close();
} catch (IOException e) {
throw new Error(e);
}
}
- private TemplateBlock parse(Reader r) throws IOException {
+ private ParseResult parse(Reader r) throws IOException {
LinkedList<String> splitted = new LinkedList<String>();
LinkedList<Outputable> commands = new LinkedList<Outputable>();
StringBuffer buf = new StringBuffer();
+ String blockType = null;
outer:
while (true) {
while ( !endsWith(buf, "<?")) {
if (m.matches()) {
String type = m.group(1);
String variable = m.group(2);
- TemplateBlock body = parse(r);
+ ParseResult body = parse(r);
if (type.equals("if")) {
- commands.add(new IfStatement(variable, body));
+ if ("else".equals(body.getEndType())) {
+ commands.add(new IfStatement(variable, body.getBlock("else"), parse(r).getBlock("}")));
+ } else {
+ commands.add(new IfStatement(variable, body.getBlock("}")));
+ }
} else if (type.equals("foreach")) {
- commands.add(new ForeachStatement(variable, body));
+ commands.add(new ForeachStatement(variable, body.getBlock("}")));
} else {
throw new IOException("Syntax error: unknown control structure: " + type);
}
continue;
- }
- if (com.matches(" ?\\} ?")) {
+ } else if ((m = ELSE_PATTERN.matcher(com)).matches()) {
+ blockType = "else";
break;
+ } else if (com.matches(" ?\\} ?")) {
+ blockType = "}";
+ break;
+ } else {
+ commands.add(parseCommand(com));
}
- commands.add(parseCommand(com));
}
splitted.add(buf.toString());
- String[] contents = splitted.toArray(new String[splitted.size()]);
- Outputable[] vars = commands.toArray(new Outputable[commands.size()]);
- return new TemplateBlock(contents, vars);
+ return new ParseResult(new TemplateBlock(splitted.toArray(new String[splitted.size()]), commands.toArray(new Outputable[commands.size()])), blockType);
}
private boolean endsWith(StringBuffer buf, String string) {
private Outputable parseCommand(String s2) {
if (s2.startsWith("=_")) {
final String raw = s2.substring(2);
- return new TranslateCommand(raw);
+ if ( !s2.contains("$") && !s2.contains("!'")) {
+ return new TranslateCommand(raw);
+ } else {
+ return new SprintfCommand(raw);
+ }
} else if (s2.startsWith("=$")) {
final String raw = s2.substring(2);
return new OutputVariableCommand(raw);
- } else if (s2.startsWith("=s,")) {
- String command = s2.substring(3);
- final LinkedList<String> store = new LinkedList<String>();
- while (command.startsWith("$") || command.startsWith("\"")) {
- int idx;
- if (command.startsWith("\"")) {
- idx = command.indexOf("\"", 1) + 1;
- store.add(command.substring(0, idx - 1));
- } else {
- idx = command.indexOf(",");
- store.add(command.substring(0, idx));
- }
- command = command.substring(idx + 1);
- }
- final String text = command;
- return new SprintfCommand(text, store);
} else {
- System.out.println("Unknown processing instruction: " + s2);
+ throw new Error("Unknown processing instruction: " + s2);
}
- return null;
}
@Override
public void output(PrintWriter out, Language l, Map<String, Object> vars) {
- if (source != null && DevelLauncher.DEVEL) {
- if (lastLoaded < source.lastModified()) {
- try {
- System.out.println("Reloading template.... " + source);
- InputStreamReader r = new InputStreamReader(new FileInputStream(source), "UTF-8");
- data = parse(r);
- r.close();
- lastLoaded = source.lastModified() + 1000;
- } catch (IOException e) {
- e.printStackTrace();
- }
+ if (source != null && lastLoaded < source.lastModified()) {
+ try {
+ System.out.println("Reloading template.... " + source);
+ InputStreamReader r = new InputStreamReader(new FileInputStream(source), "UTF-8");
+ data = parse(r).getBlock(null);
+ r.close();
+ lastLoaded = source.lastModified() + 1000;
+ } catch (IOException e) {
+ e.printStackTrace();
}
}
data.output(out, l, vars);