Thank you @scholarInTraining!
It was indeed the this.app
, which needed to be changed to app
. Actually, I was so sure that I’ve tried this earlier, but apparently I got confused with the error messages…
Below I post my templater user scripts. They will change in future, but already now they can handle already quite a few use cases. Also they should be fairly easy to modify.
Currently I run the scripts via the literature note content template of the citations plugin. This approach, unfortunately, has the downside that tp.user
can only be triggered on file creation. However, since the function argument is simply the citekey, it should be easy to integrate the functions in a normal Templater-template, as you suggested. (In this case, the citekey could be read e.g. from the note title). Like so it should be possible to load the Strings into a pre-existing file, too.
So thank you very much for the nice co-working on this feature! If you happen to write an implementation for QuickAdd, I’ll be very interested, since I might shift from Templater to QuickAdd in future.
EDIT: I may edit the functions below in future.
Literature note content template:
<% `${tp.user.authorsString("{{citekey}}", true, true)} (${tp.user.yearString("{{citekey}}")})`%>
<% `${tp.user.authorsString("{{citekey}}", false, true)} (${tp.user.yearString("{{citekey}}")})`%>
<% `${tp.user.authorsString("{{citekey}}", true, false)} (${tp.user.yearString("{{citekey}}")})`%>
<% `${tp.user.authorsString("{{citekey}}", false, false)} (${tp.user.yearString("{{citekey}}")})`%>
Sample output 1:
te Heesen, A.; Spary, E. C. (2001)
te Heesen, Anke; Spary, Emma C. (2001)
te Heesen, A. and Spary, E. C. (2001)
te Heesen, Anke and Spary, Emma C. (2001)
Sample output 2:
Adler, C.; Hirsch Hadorn, G.; Breu, T.; Wiesmann, U.; Pohl, C. (2018)
Adler, Carolina; Hirsch Hadorn, Gertrude; Breu, Thomas; Wiesmann, Urs; Pohl, Christian (2018)
Adler, C. et al. (2018)
Adler, Carolina et al. (2018)
yearString.js
function yearString(citekey) {
// Input:
// - citekey (string)
// Output:
// - String with year of publication
let data = app.plugins.plugins['obsidian-citation-plugin'].library.entries[citekey].data;
// extract Year
let yearString = data.fields.date[0].split("-")[0];
return yearString
}
module.exports = yearString;
authorsString.js
function authorsString(citekey, printFirstAsInitials=false,
printAllAuthors=false) {
// Input:
// - citekey (string)
// - printFirstAsInitials (boolean)
// - printAllAuthors (boolean)
// Output:
// - String of authors
let fullAuthorList = [];
// check .bib for author entry
let data = app.plugins.plugins['obsidian-citation-plugin'].library.entries[citekey].data;
let authors = [];
if (data.creators.author)
authors = data.creators.author;
else
authors = [{literal: "NaN"}];
// for each author
authors.forEach(author => {
const [firstNamesArray, lastNamesString] = findFirstLast(author);
let str = [];
str.push(lastNamesString)
str.push(",");
firstNamesArray.forEach(name => {
// print firstname(s) as initials or full names
if (printFirstAsInitials)
str.push(` ${name[0]}.`);
else
str.push(` ${name}`);
});
fullAuthorList.push(str.join(""));
});
// join Authors, clean and return
const authorString = joinAuthors(fullAuthorList, printAllAuthors);
return replaceIllegalFileNameCharactersInString(authorString);
}
module.exports = authorsString;
//-----------------------------------
// Helper functions
//-----------------------------------
function joinAuthors(fullAuthorList, printAllAuthors) {
/* Join Authors: This will either
- print all authors (separated by ";")
- print "the author"
- print "first and second author"
- print "first author et al."
*/
if (printAllAuthors == true) {
return fullAuthorList.join("; ");
}
else {
const len = fullAuthorList.length;
if (len == 1)
return fullAuthorList[0];
else if (len == 2)
return fullAuthorList.join("\ and ");
else if (len >= 3)
return fullAuthorList[0] + " et al.";
}
}
function findFirstLast(author) {
/* Note, that literal names need to be worked around. This means that if lastnames consist of multiple names, they will be mixed with first names. To avoid this you should modify the .bib-file (i.e. switch to "two fields" in Zotero).
For example
author: Array(2)
0: {literal: 'Anke te Heesen'}
1: {lastName: 'Spary', firstName: 'Emma C.'}
will be rendered as
"Heesen, Anke te and Spary, Emma C."
instead of
"te Heesen, Anke and Spray, Emma C."
*/
let lastNamesString = "";
let firstNamesArray = [];
if (author.lastName) {
firstNamesArray = author.firstName.split(" ");
lastNamesString = author.lastName;
}
// Workaround for literal names
else {
let parts = author.literal.split(" ");
firstNamesArray = parts.slice(0,parts.length-1);
lastNamesString = parts[parts.length-1];
}
return [firstNamesArray, lastNamesString];
}
function replaceIllegalFileNameCharactersInString(string) {
/* This may be important if the authorString is e.g. used for aliasing.*/
return string.replace(/[\\\/@]*/g, ''); // less strict for Linux/MacOS
// return string.replace(/[\\#%&\{\}\/*<>$\'\":@,]*/g, ''); // very strict for Windows
}