package net.sf.jabref.bst; import java.util.Stack; import net.sf.jabref.bst.VM.BstEntry; import net.sf.jabref.bst.VM.BstFunction; /** * From the Bibtex manual: * * Pops the top two (string) literals; it changes the case of the second * according to the specifications of the first, as follows. (Note: The word * `letters' in the next sentence refers only to those at brace-level 0, the * top-most brace level; no other characters are changed, except perhaps for * \special characters", described in Section 4.) If the first literal is the * string `t', it converts to lower case all letters except the very first * character in the string, which it leaves alone, and except the first * character following any colon and then nonnull white space, which it also * leaves alone; if it's the string `l', it converts all letters to lower case; * and if it's the string `u', it converts all letters to upper case. It then * pushes this resulting string. If either type is incorrect, it complains and * pushes the null string; however, if both types are correct but the * specification string (i.e., the first string) isn't one of the legal ones, it * merely pushes the second back onto the stack, after complaining. (Another * note: It ignores case differences in the specification string; for example, * the strings t and T are equivalent for the purposes of this built-in * function.) * * Christopher: I think this should be another grammar! This parser is horrible. * */ public class ChangeCaseFunction implements BstFunction { VM vm; public ChangeCaseFunction(VM vm) { this.vm = vm; } public void execute(BstEntry context) { Stack<Object> stack = vm.getStack(); if (stack.size() < 2) { throw new VMException("Not enough operands on stack for operation change.case$"); } Object o1 = stack.pop(); Object o2 = stack.pop(); if (!(o1 instanceof String && ((String) o1).length() == 1)) { throw new VMException("A format string of length 1 is needed for change.case$"); } if (!(o2 instanceof String)) { throw new VMException("A string is needed as second parameter for change.case$"); } char format = (((String) o1).toLowerCase().charAt(0)); String s = (String) o2; stack.push(BibtexCaseChanger.changeCase(s, format, vm)); } }