Skip to content

Instantly share code, notes, and snippets.

@williamhogman
Created September 12, 2013 11:12
Show Gist options
  • Save williamhogman/6535878 to your computer and use it in GitHub Desktop.
Save williamhogman/6535878 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Template {
private List<String> tokens;
private String simple;
public Template(String template) {
this.tokens = tokenize(template);
// If the length is zero, it can only be the empty string.
// If the length is one, it cannot be a variable.
// Hence, if the is lesser than 2, we return the template.
if(template.length() < 2) {
simple = template;
}
}
private String expandToken(String token, Map<String, String> variables) {
if(token.charAt(0) == '$') {
return variables.get(token.substring(1));
} else {
return token;
}
}
private int findWhitespace(String in, int start) {
for(int i = start; i < in.length(); i++) {
char c = in.charAt(i);
if(c == ' ' || c == '\n' || c == '\t') {
return i;
}
}
return -1;
}
private List<String> tokenize(String template) {
List<String> tokens = new ArrayList<String>();
int start = 0;
int end = -1;
while((end = template.indexOf("$", start)) != -1 && start <= template.length()) {
// If there is something before the $-sign then add it
if (start != end) {
tokens.add(template.substring(start, end));
}
// find the end of the variable name
//int endOfVar = template.indexOf(" ", end);
int endOfVar = findWhitespace(template, end);
// If we can't find a space that means that the variable is at the end of the input string
if(endOfVar == -1) {
tokens.add(template.substring(end));
return tokens;
}
// Add the variable token
tokens.add(template.substring(end, endOfVar));
// Move forward
start = endOfVar;
}
// If there is anything left then add that
if(end < template.length()) {
tokens.add(template.substring(start));
}
return tokens;
}
public String evaluate(Map<String, String> variables) {
if(simple != null) {
return simple;
}
StringBuffer buffer = new StringBuffer();
for(String token : tokens) {
buffer.append(expandToken(token, variables));
}
return buffer.toString();
}
}
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Assert;
import org.junit.Test;
public class TemplateTest {
private Map<String, String> emptyMap = new HashMap<String, String>();
@Test
public void testStaticString() {
Template t = new Template("hej");
String s = t.evaluate(emptyMap);
assertEquals("Should return the exacty same string", "hej", s);
}
@Test
public void testEmptyString() {
Template t = new Template("");
String s = t.evaluate(emptyMap);
assertEquals("Should return the empty string", "", s);
}
@Test
public void testOneVariable() {
Template t = new Template("$x");
Map<String, String> map = new HashMap<String, String>();
map.put("x", "foo");
String s = t.evaluate(map);
assertEquals("Should insert the correct value", "foo", s);
}
@Test
public void testTwoVariables() {
Template t = new Template("$x $y");
Map<String, String> map = new HashMap<String, String>();
map.put("x", "foo");
map.put("y", "bar");
String s = t.evaluate(map);
assertEquals("Should insert the correct value", "foo bar", s);
}
@Test
public void testSpace(){
Template t = new Template(" ");
String s = t.evaluate(emptyMap);
assertEquals("Should return a string with just a space", " ", s);
}
@Test
public void testMixed() {
Template t = new Template("Foo $x lol");
Map<String, String> map = new HashMap<String, String>();
map.put("x", "bar");
String s = t.evaluate(map);
assertEquals("Foo bar lol", s);
}
@Test
public void testTwoSpaces() {
Template t = new Template(" ");
String s = t.evaluate(emptyMap);
assertEquals(" ", s);
}
@Test
public void testNewLineVars() {
Template t = new Template("$x\n$x");
Map<String, String> map = new HashMap<String, String>();
map.put("x", "bar");
String s = t.evaluate(map);
assertEquals("bar\nbar", s);
}
@Test
public void testTabVars(){
Template t = new Template("$x\t$x");
Map<String, String> map = new HashMap<String, String>();
map.put("x", "bar");
String s = t.evaluate(map);
assertEquals("bar\tbar", s);
}
@Test
public void testDollahDollahBillYall() {
Template t = new Template("$$x $$x");
Map<String, String> map = new HashMap<String, String>();
map.put("$x", "foo");
String s = t.evaluate(map);
assertEquals("foo foo", s);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment