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]; }); });