define(['showdown', 'citation'], function (showdown, citation) {
return showdown.extension('showdown-citation', function() {
const Cite = citationRequire('citation-js');
var allCites = new Cite();
// set up a custom CSL template so that we can use apa style without the url at the end.
// for DOI's, we add this url manually so that it can have a tag (not supported in CSL)
let templateName = 'apa-no-url'
// the docs for citation.js indicate that the CSL should go right into the doc as so.
// TODO: figure out a better way to import this.
let template = ''+
''
let config = Cite.plugins.config.get('csl');
config.templates.add(templateName, template);
var subbib = function(bibobj, keyarr) {
let filtered = _.filter(bibobj.data, function(item) {
return keyarr.includes(item['citation-label']);
});
return Cite(filtered);
};
var not_in_bib = function(bibobj, keyarr) {
// Return an array containing the elements of `keyarr` that are not
// matched by entries in `bibobj`
let labels = bibobj.data.map(d => d['citation-label']);
let filtered = _.filter(keyarr, function(item) {
return !labels.includes(item);
});
return filtered;
};
var read_bibli = {
// This sub-extension will look for bibtex, wrapped in tags.
// When found, they'll be added to the cite object.
type: "lang",
filter: function (text, converter, options) {
var left = '',
right = '',
flags = 'g',
replacement = function (wholeMatch, match, left, right) {
let citeInfo = new Cite(wholeMatch.replace(/<\/*bibtex>/g, ''));
// add citation data to "master list" of references
// (automatically sorts and removes duplicates)
allCites.add(citeInfo.data);
};
return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
}
};
var print_bibli = {
type: "output",
filter: function(text){
if(allCites.data.length > 0){
// make bibliography
var citeBib = allCites.format('bibliography', {
format: 'html',
template: templateName,
lang: 'en-US',
append: function (entry) {
var doi = entry.DOI;
if (typeof doi === 'undefined' || doi === null){
return ""
} else {
return " doi:" + doi + ""
}
}
})
// add in id attributes so we can hack in a link from the inline cite
citeBib = citeBib.replace(/(data-csl-entry-id="([^"]+)")/g, 'id="$2" $1');
return ( text + "
Bibliography
" + citeBib );
} else {
return ( text );
}
}
};
var print_inline_cites = {
type: "lang",
filter: function(text) {
var left = '\\[(@[^\\]]+)',
right = '\\]',
flags = 'g',
replacement = function(wholeMatch, match, left, right) {
// let keys = wholeMatch.replace(/<\/*inlinecite>/g, '').split(";");
let keys = wholeMatch.replace(/[@\[\]\s]*/g, '').split(",");
let subcites = subbib(allCites, keys);
let citestring = subcites.format('citation', {
format: 'html',
template: templateName,
lang: 'en-US',
});
if (subcites.data.length == 0) {
// none of the keys handed in matched anything in the bib.
// We'll just hand back the keys in parentheses
citestring = "(" + keys.join("; ").replace(/_/g, "\\_") + ")";
} else if (subcites.data.length < keys.length) {
// At least one of the keys found a match, but not all keys
// We'll insert the not found keys into the citation
let nope = not_in_bib(allCites, keys).join("; ").replace(/_/g, "\\_");
citestring = citestring.replace(/([^)]*)\)/g, "$1; " + nope + ")");
}
// Now we have to deal with a hacky work around to get links to the bibliography
citestring = citestring.replace(/labelisinhere([^@]*)@labelisinhere/g, '');
citestring = citestring.replace(/endtheanchortaghere/g, '');
return citestring;
}
return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
},
};
return [read_bibli, print_inline_cites, print_bibli];
});
});