/* Copyright (C) 2003-2011 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package net.sf.jabref.bst;
import java.util.Stack;
import net.sf.jabref.AuthorList;
import net.sf.jabref.AuthorList.Author;
import net.sf.jabref.bst.VM.BstEntry;
import net.sf.jabref.bst.VM.BstFunction;
/**
* From Bibtex:
*
* "The |built_in| function {\.{format.name\$}} pops the
* top three literals (they are a string, an integer, and a string
* literal, in that order). The last string literal represents a
* name list (each name corresponding to a person), the integer
* literal specifies which name to pick from this list, and the
* first string literal specifies how to format this name, as
* described in the \BibTeX\ documentation. Finally, this function
* pushes the formatted name. If any of the types is incorrect, it
* complains and pushes the null string."
*
* All the pain is encapsulated in BibtexNameFormatter. :-)
*
*/
public class FormatNameFunction implements BstFunction {
VM vm;
public FormatNameFunction(VM vm) {
this.vm = vm;
}
public void execute(BstEntry context) {
Stack<Object> stack = vm.getStack();
if (stack.size() < 3) {
throw new VMException("Not enough operands on stack for operation format.name$");
}
Object o1 = stack.pop();
Object o2 = stack.pop();
Object o3 = stack.pop();
if (!(o1 instanceof String) && !(o2 instanceof Integer) && !(o3 instanceof String)) {
// warning("A string is needed for change.case$");
stack.push("");
return;
}
String format = (String) o1;
Integer name = (Integer) o2;
String names = (String) o3;
if (names != null){
AuthorList a = AuthorList.getAuthorList(names);
if (name.intValue() > a.size()){
throw new VMException("Author Out of Bounds. Number " + name + " invalid for " + names);
}
Author author = a.getAuthor(name.intValue() - 1);
stack.push(BibtexNameFormatter.formatName(author, format, vm));
} else {
stack.push("");
}
}
}