├── .gitignore ├── .gitmodules ├── ORCIDtoCSVtool.html ├── README.MD ├── citeproc-js ├── LICENSE.txt ├── README.md ├── citeproc.js ├── xmldom.js └── xmle4x.js ├── example.html ├── exampledownloadbibtex.html └── lib ├── orcid.js └── styles.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "swagger-js"] 2 | path = swagger-js 3 | url = https://github.com/swagger-api/swagger-js.git 4 | [submodule "citeproc-js"] 5 | path = citeproc-js 6 | url = https://bitbucket.org/fbennett/citeproc-js 7 | [submodule "styles"] 8 | path = styles 9 | url = https://github.com/citation-style-language/styles.git 10 | [submodule "locales"] 11 | path = locales 12 | url = https://github.com/citation-style-language/locales.git 13 | -------------------------------------------------------------------------------- /ORCIDtoCSVtool.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 113 | 114 | 115 | Enter some orcids here, one per line ( use an example):
116 | 117 | 118 |
119 | 121 | 122 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | ORCID-JS 2 | ======== 3 | 4 | A client side reference list generator for ORCID records 5 | -------------------------------------------------------- 6 | 7 | This library can be used to generate on the fly reference lists from ORCID records. It also exposes the entire [V2.0_rc1 Public ORCID API](https://pub.orcid.org/v2.0_rc1) via a swagger client (including the stats API). It can be used to generate any CSL style, Citeproc-JSON or bibtex. 8 | 9 | Hello world example 10 | ------------------- 11 | ```javascript 12 | //write a reference list to the page in the default style (chicago) 13 | //fetches citations asynchronously, so order is not guarenteed 14 | orcid.init(function(){ 15 | orcid.resolveCitations("0000-0003-0902-4386", function(citations, failures){ 16 | for (c in citations){ 17 | $("body").append(citations[c] +"
"); 18 | } 19 | for (f in failures){ 20 | $("body").append(failures[f].title + " (" + failures[f].citeprocURL+") FAILED to fetch metadata
"); 21 | } 22 | }); 23 | }); 24 | ``` 25 | 26 | Viewing the examples locally 27 | ---------------------------- 28 | Chrome and Firefox will prevent the browser from loading other resources from the file system. To test locally, you need to server the files from a webserver. This can easily be done using python. Run the following command: 29 | 30 | ``` 31 | python -m SimpleHTTPServer 32 | ``` 33 | 34 | Then access the example at http://localhost:8000/example.html 35 | 36 | Where does the metadata come from? 37 | ----- 38 | To generate citations, the library does the following: 39 | 40 | * Obtain a public list of activites from an ORCID record 41 | * For each work fetch authoritative citation metadata available using the **prefered source** 42 | * For works with DOIs, citeproc metadata is obtained directly from Crossref or Datacite 43 | * For other works, citeproc is obtained from the ORCID registry. If there is a BibTeX citation, this is transformed into Citeproc-JSON, otherwise ORCID work metadata is used 44 | * For each work, attempt to create a URL based on the idenfifier 45 | * Apply a [CSL citation style](http://citationstyles.org/) to generate reference list or BibTeX 46 | 47 | As other services add the ability to resolve citeproc metadata, this tool will be updated to use it. 48 | 49 | Usage 50 | ----- 51 | The most useful method has this signature: 52 | 53 | function resolveCitationsFromORCIDID(orcidID, callback, oneByOne, optionalCitationStyle, returnCiteprocObjects) 54 | 55 | There is also an [example.html](https://github.com/TomDemeranville/orcid-js/blob/master/example.html) page 56 | 57 | ```javascript 58 | orcid.init(callback); 59 | function callback(){ 60 | //to fetch asyncronously and have the callback called once for each citation (recommended) use: 61 | orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, true); 62 | //to get the citations an array of citation strings via a callback as a batch use: 63 | orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, false); 64 | // the default style is Chicago, we can ask for bibtex instead like this: 65 | orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, false, orcid.styleBibtex); 66 | // if you want an array of citeproc JSON objects instead, use this: 67 | orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, true, "", true); 68 | } 69 | 70 | //If all you need is a list of titles, identifiers and URLS, use simpleWorks 71 | //This also demonstrates how to access the API via swagger (full v2.0 api is supported) 72 | orcid.init(callback); 73 | function callback(){ 74 | orcid.client.apis["Public API v2.0_rc1"].viewActivities({orcid:"0000-0000-0000-0000"}, function(data) { 75 | var simpleWorks = orcid.activitiesToSimpleWorks(data); 76 | //do whatever with the simpleWorks 77 | }); 78 | } 79 | ``` 80 | 81 | If you would like to load a citation format that is not supplied by default (APA, Chicago, Bibtex) then use the styles.js helper to fetch it from the server. All the styles in the style repo should be available. Something like this: 82 | 83 | ```javascript 84 | CSLStyles.fetchStyleXML("academy-of-management-review", function(styleXML){ 85 | orcid.resolveCitations(orcidID, updatePage, true, styleXML); 86 | }); 87 | ``` 88 | 89 | Dependencies 90 | ------------ 91 | swagger-client.js, jquery, citeproc-js 92 | transitive: xmle4x.js,xmldom.js 93 | 94 | When cloning this repository, you must run 95 | ``` 96 | git submodule init 97 | git submodule update 98 | ``` 99 | To fetch the dependancies 100 | 101 | Issues 102 | ------ 103 | Chrome always logs the following to the console: 104 | 105 | xmle4x.js:11 Uncaught SyntaxError: Unexpected token default 106 | 107 | This is a citeproc dependency used by legacy browsers and does not affect function in Chrome/Firefox. 108 | -------------------------------------------------------------------------------- /citeproc-js/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2014 Frank G. Bennett 2 | 3 | Unless otherwise indicated, the files in this repository are subject 4 | to the Common Public Attribution License Version 1.0 (the “License”); 5 | you may not use this file except in compliance with the License. You 6 | may obtain a copy of the License at: 7 | 8 | http://bitbucket.org/fbennett/citeproc-js/src/tip/LICENSE. 9 | 10 | (See also the note on attribution information below) 11 | 12 | The License is based on the Mozilla Public License Version 1.1 but 13 | Sections 1.13, 14 and 15 have been added to cover use of software over a 14 | computer network and provide for limited attribution for the 15 | Original Developer. In addition, Exhibit A has been modified to be 16 | consistent with Exhibit B. 17 | 18 | Software distributed under the License is distributed on an “AS IS” 19 | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 20 | the License for the specific language governing rights and limitations 21 | under the License. 22 | 23 | The Original Code is the citation formatting software known as 24 | "citeproc-js" (an implementation of the Citation Style Language 25 | [CSL]), including the original test fixtures and software located 26 | under the ./tests subdirectory of the distribution archive. 27 | 28 | The Original Developer is not the Initial Developer and is 29 | __________. If left blank, the Original Developer is the Initial 30 | Developer. 31 | 32 | The Initial Developer of the Original Code is Frank Bennett. All 33 | portions of the code written by Frank Bennett are Copyright (c) 34 | 2009-2014 Frank Bennett. 35 | 36 | *** 37 | 38 | Alternatively, the files in this repository may be used under the 39 | terms of the GNU Affero General Public License (the [AGPLv3] License), 40 | in which case the provisions of [AGPLv3] License are applicable 41 | instead of those above. If you wish to allow use of your version of 42 | this file only under the terms of the [AGPLv3] License and not to 43 | allow others to use your version of this file under the CPAL, indicate 44 | your decision by deleting the provisions above and replace them with 45 | the notice and other provisions required by the [AGPLv3] License. If 46 | you do not delete the provisions above, a recipient may use your 47 | version of this file under either the CPAL or the [AGPLv3] License. 48 | 49 | *** 50 | 51 | Attribution Information (CPAL) 52 | 53 | Attribution Copyright Notice: [no separate attribution copyright notice is required] 54 | 55 | Attribution Phrase: "Citations by CSL (citeproc-js)" 56 | 57 | Attribution URL: http://citationstyles.org/ 58 | 59 | Graphic Image: [there is no requirement to display a Graphic Image] 60 | 61 | Display of Attribution Information is REQUIRED in Larger Works which 62 | are defined in the CPAL as a work which combines Covered Code or 63 | portions thereof with code not governed by the terms of the CPAL. 64 | 65 | Display of Attribution Information is also REQUIRED on Associated 66 | Websites. 67 | 68 | [ citeproc-js license :: version 1.1 :: 2012.06.30 ] 69 | -------------------------------------------------------------------------------- /citeproc-js/README.md: -------------------------------------------------------------------------------- 1 | Due to issues with mercurial subrepos in git repositories, these files have been copied from the following locations: 2 | v "1.1.59" 3 | 4 | https://bitbucket.org/fbennett/citeproc-js/raw/82d993dc0d13793822b854712c40fa9913b84032/citeproc.js 5 | https://bitbucket.org/fbennett/citeproc-js/raw/82d993dc0d13793822b854712c40fa9913b84032/xmldom.js 6 | https://bitbucket.org/fbennett/citeproc-js/raw/82d993dc0d13793822b854712c40fa9913b84032/xmle4x.js 7 | https://bitbucket.org/fbennett/citeproc-js/raw/82d993dc0d13793822b854712c40fa9913b84032/LICENSE 8 | -------------------------------------------------------------------------------- /citeproc-js/xmldom.js: -------------------------------------------------------------------------------- 1 | if ("undefined" === typeof CSL_IS_IE) { 2 | var CSL_IS_IE; 3 | }; 4 | var CSL_CHROME = function () { 5 | if ("undefined" == typeof DOMParser || CSL_IS_IE) { 6 | CSL_IS_IE = true; 7 | DOMParser = function() {}; 8 | DOMParser.prototype.parseFromString = function(str, contentType) { 9 | if ("undefined" != typeof ActiveXObject) { 10 | var xmldata = new ActiveXObject('MSXML.DomDocument'); 11 | xmldata.async = false; 12 | xmldata.loadXML(str); 13 | return xmldata; 14 | } else if ("undefined" != typeof XMLHttpRequest) { 15 | var xmldata = new XMLHttpRequest; 16 | if (!contentType) { 17 | contentType = 'text/xml'; 18 | } 19 | xmldata.open('GET', 'data:' + contentType + ';charset=utf-8,' + encodeURIComponent(str), false); 20 | if(xmldata.overrideMimeType) { 21 | xmldata.overrideMimeType(contentType); 22 | } 23 | xmldata.send(null); 24 | return xmldata.responseXML; 25 | } 26 | }; 27 | this.hasAttributes = function (node) { 28 | var ret; 29 | if (node.attributes && node.attributes.length) { 30 | ret = true; 31 | } else { 32 | ret = false; 33 | } 34 | return ret; 35 | }; 36 | } else { 37 | this.hasAttributes = function (node) { 38 | var ret; 39 | if (node.attributes && node.attributes.length) { 40 | ret = true; 41 | } else { 42 | ret = false; 43 | } 44 | return ret; 45 | }; 46 | } 47 | this.importNode = function (doc, srcElement) { 48 | if ("undefined" == typeof doc.importNode) { 49 | var ret = this._importNode(doc, srcElement, true); 50 | } else { 51 | var ret = doc.importNode(srcElement, true); 52 | } 53 | return ret; 54 | }; 55 | this._importNode = function(doc, node, allChildren) { 56 | switch (node.nodeType) { 57 | case 1: 58 | var newNode = doc.createElement(node.nodeName); 59 | if (node.attributes && node.attributes.length > 0) 60 | for (var i = 0, il = node.attributes.length; i < il;) 61 | newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName)); 62 | if (allChildren && node.childNodes && node.childNodes.length > 0) 63 | for (var i = 0, il = node.childNodes.length; i < il;) 64 | newNode.appendChild(this._importNode(doc, node.childNodes[i++], allChildren)); 65 | return newNode; 66 | break; 67 | case 3: 68 | case 4: 69 | case 8: 70 | } 71 | }; 72 | this.parser = new DOMParser(); 73 | var str = ""; 74 | var inst_doc = this.parser.parseFromString(str, "text/xml"); 75 | var inst_node = inst_doc.getElementsByTagName("institution"); 76 | this.institution = inst_node.item(0); 77 | var inst_part_node = inst_doc.getElementsByTagName("institution-part"); 78 | this.institutionpart = inst_part_node.item(0); 79 | this.ns = "http://purl.org/net/xbiblio/csl"; 80 | }; 81 | CSL_CHROME.prototype.clean = function (xml) { 82 | xml = xml.replace(/<\?[^?]+\?>/g, ""); 83 | xml = xml.replace(/]+>/g, ""); 84 | xml = xml.replace(/^\s+/, ""); 85 | xml = xml.replace(/\s+$/, ""); 86 | xml = xml.replace(/^\n*/, ""); 87 | return xml; 88 | }; 89 | CSL_CHROME.prototype.getStyleId = function (myxml) { 90 | var text = ""; 91 | var node = myxml.getElementsByTagName("id"); 92 | if (node && node.length) { 93 | node = node.item(0); 94 | } 95 | if (node) { 96 | text = node.textContent; 97 | } 98 | if (!text) { 99 | text = node.innerText; 100 | } 101 | if (!text) { 102 | text = node.innerHTML; 103 | } 104 | return text; 105 | }; 106 | CSL_CHROME.prototype.children = function (myxml) { 107 | var children, pos, len, ret; 108 | if (myxml) { 109 | ret = []; 110 | children = myxml.childNodes; 111 | for (pos = 0, len = children.length; pos < len; pos += 1) { 112 | if (children[pos].nodeName != "#text") { 113 | ret.push(children[pos]); 114 | } 115 | } 116 | return ret; 117 | } else { 118 | return []; 119 | } 120 | }; 121 | CSL_CHROME.prototype.nodename = function (myxml) { 122 | var ret = myxml.nodeName; 123 | return ret; 124 | }; 125 | CSL_CHROME.prototype.attributes = function (myxml) { 126 | var ret, attrs, attr, key, xml, pos, len; 127 | ret = new Object(); 128 | if (myxml && this.hasAttributes(myxml)) { 129 | attrs = myxml.attributes; 130 | for (pos = 0, len=attrs.length; pos < len; pos += 1) { 131 | attr = attrs[pos]; 132 | ret["@" + attr.name] = attr.value; 133 | } 134 | } 135 | return ret; 136 | }; 137 | CSL_CHROME.prototype.content = function (myxml) { 138 | var ret; 139 | if ("undefined" != typeof myxml.textContent) { 140 | ret = myxml.textContent; 141 | } else if ("undefined" != typeof myxml.innerText) { 142 | ret = myxml.innerText; 143 | } else { 144 | ret = myxml.txt; 145 | } 146 | return ret; 147 | }; 148 | CSL_CHROME.prototype.namespace = { 149 | "xml":"http://www.w3.org/XML/1998/namespace" 150 | } 151 | CSL_CHROME.prototype.numberofnodes = function (myxml) { 152 | if (myxml) { 153 | return myxml.length; 154 | } else { 155 | return 0; 156 | } 157 | }; 158 | CSL_CHROME.prototype.getAttributeName = function (attr) { 159 | var ret = attr.name; 160 | return ret; 161 | } 162 | CSL_CHROME.prototype.getAttributeValue = function (myxml,name,namespace) { 163 | var ret = false; 164 | if (namespace) { 165 | name = namespace+":"+name; 166 | } 167 | if (myxml && this.hasAttributes(myxml)) { 168 | if (myxml.getAttribute(name)) { 169 | ret = myxml.getAttribute(name); 170 | } 171 | } else { 172 | ret = ""; 173 | } 174 | return ret; 175 | } 176 | CSL_CHROME.prototype.getNodeValue = function (myxml,name) { 177 | var ret = ""; 178 | if (name){ 179 | var vals = myxml.getElementsByTagName(name); 180 | if (vals.length > 0) { 181 | if ("undefined" != typeof vals[0].textContent) { 182 | ret = vals[0].textContent; 183 | } else if ("undefined" != typeof vals[0].innerText) { 184 | ret = vals[0].innerText; 185 | } else { 186 | ret = vals[0].text; 187 | } 188 | } 189 | } else { 190 | ret = myxml; 191 | } 192 | if (ret && ret.childNodes && (ret.childNodes.length == 0 || (ret.childNodes.length == 1 && ret.firstChild.nodeName == "#text"))) { 193 | if ("undefined" != typeof ret.textContent) { 194 | ret = ret.textContent; 195 | } else if ("undefined" != typeof ret.innerText) { 196 | ret = ret.innerText; 197 | } else { 198 | ret = ret.text; 199 | } 200 | } 201 | return ret; 202 | } 203 | CSL_CHROME.prototype.setAttributeOnNodeIdentifiedByNameAttribute = function (myxml,nodename,partname,attrname,val) { 204 | var pos, len, xml, nodes, node; 205 | if (attrname.slice(0,1) === '@'){ 206 | attrname = attrname.slice(1); 207 | } 208 | nodes = myxml.getElementsByTagName(nodename); 209 | for (pos = 0, len = nodes.length; pos < len; pos += 1) { 210 | node = nodes[pos]; 211 | if (node.getAttribute("name") != partname) { 212 | continue; 213 | } 214 | node.setAttribute(attrname, val); 215 | } 216 | } 217 | CSL_CHROME.prototype.deleteNodeByNameAttribute = function (myxml,val) { 218 | var pos, len, node, nodes; 219 | nodes = myxml.childNodes; 220 | for (pos = 0, len = nodes.length; pos < len; pos += 1) { 221 | node = nodes[pos]; 222 | if (!node || node.nodeType == node.TEXT_NODE) { 223 | continue; 224 | } 225 | if (this.hasAttributes(node) && node.getAttribute("name") == val) { 226 | myxml.removeChild(nodes[pos]); 227 | } 228 | } 229 | } 230 | CSL_CHROME.prototype.deleteAttribute = function (myxml,attr) { 231 | myxml.removeAttribute(attr); 232 | } 233 | CSL_CHROME.prototype.setAttribute = function (myxml,attr,val) { 234 | if (!myxml.ownerDocument) { 235 | myxml = myxml.firstChild; 236 | } 237 | if (["function", "unknown"].indexOf(typeof myxml.setAttribute) > -1) { 238 | myxml.setAttribute(attr, val); 239 | } 240 | return false; 241 | } 242 | CSL_CHROME.prototype.nodeCopy = function (myxml) { 243 | var cloned_node = myxml.cloneNode(true); 244 | return cloned_node; 245 | } 246 | CSL_CHROME.prototype.getNodesByName = function (myxml,name,nameattrval) { 247 | var ret, nodes, node, pos, len; 248 | ret = []; 249 | nodes = myxml.getElementsByTagName(name); 250 | for (pos = 0, len = nodes.length; pos < len; pos += 1) { 251 | node = nodes.item(pos); 252 | if (nameattrval && !(this.hasAttributes(node) && node.getAttribute("name") == nameattrval)) { 253 | continue; 254 | } 255 | ret.push(node); 256 | } 257 | return ret; 258 | } 259 | CSL_CHROME.prototype.nodeNameIs = function (myxml,name) { 260 | if (name == myxml.nodeName) { 261 | return true; 262 | } 263 | return false; 264 | } 265 | CSL_CHROME.prototype.makeXml = function (myxml) { 266 | var ret, topnode; 267 | if (!myxml) { 268 | myxml = ""; 269 | } 270 | myxml = myxml.replace(/\s*<\?[^>]*\?>\s*\n*/g, ""); 271 | var nodetree = this.parser.parseFromString(myxml, "application/xml"); 272 | return nodetree.firstChild; 273 | }; 274 | CSL_CHROME.prototype.insertChildNodeAfter = function (parent,node,pos,datexml) { 275 | var myxml, xml; 276 | myxml = this.importNode(node.ownerDocument, datexml); 277 | parent.replaceChild(myxml, node); 278 | return parent; 279 | }; 280 | CSL_CHROME.prototype.insertPublisherAndPlace = function(myxml) { 281 | var group = myxml.getElementsByTagName("group"); 282 | for (var i = 0, ilen = group.length; i < ilen; i += 1) { 283 | var node = group.item(i); 284 | var skippers = []; 285 | for (var j = 0, jlen = node.childNodes.length; j < jlen; j += 1) { 286 | if (node.childNodes.item(j).nodeType !== 1) { 287 | skippers.push(j); 288 | } 289 | } 290 | if (node.childNodes.length - skippers.length === 2) { 291 | var twovars = []; 292 | for (var j = 0, jlen = 2; j < jlen; j += 1) { 293 | if (skippers.indexOf(j) > -1) { 294 | continue; 295 | } 296 | var child = node.childNodes.item(j); 297 | var subskippers = []; 298 | for (var k = 0, klen = child.childNodes.length; k < klen; k += 1) { 299 | if (child.childNodes.item(k).nodeType !== 1) { 300 | subskippers.push(k); 301 | } 302 | } 303 | if (child.childNodes.length - subskippers.length === 0) { 304 | twovars.push(child.getAttribute('variable')); 305 | if (child.getAttribute('suffix') 306 | || child.getAttribute('prefix')) { 307 | twovars = []; 308 | break; 309 | } 310 | } 311 | } 312 | if (twovars.indexOf("publisher") > -1 && twovars.indexOf("publisher-place") > -1) { 313 | node.setAttribute('has-publisher-and-publisher-place', true); 314 | } 315 | } 316 | } 317 | }; 318 | CSL_CHROME.prototype.addMissingNameNodes = function(myxml) { 319 | var nameslist = myxml.getElementsByTagName("names"); 320 | for (var i = 0, ilen = nameslist.length; i < ilen; i += 1) { 321 | var names = nameslist.item(i); 322 | var namelist = names.getElementsByTagName("name"); 323 | if ((!namelist || namelist.length === 0) 324 | && names.parentNode.tagName.toLowerCase() !== "substitute") { 325 | var doc = names.ownerDocument; 326 | var name = doc.createElement("name"); 327 | names.appendChild(name); 328 | } 329 | } 330 | }; 331 | CSL_CHROME.prototype.addInstitutionNodes = function(myxml) { 332 | var names, thenames, institution, theinstitution, name, thename, xml, pos, len; 333 | names = myxml.getElementsByTagName("names"); 334 | for (pos = 0, len = names.length; pos < len; pos += 1) { 335 | thenames = names.item(pos); 336 | name = thenames.getElementsByTagName("name"); 337 | if (name.length == 0) { 338 | continue; 339 | } 340 | institution = thenames.getElementsByTagName("institution"); 341 | if (institution.length == 0) { 342 | theinstitution = this.importNode(myxml.ownerDocument, this.institution); 343 | theinstitutionpart = theinstitution.getElementsByTagName("institution-part").item(0); 344 | thename = name.item(0); 345 | thenames.insertBefore(theinstitution, thename.nextSibling); 346 | for (var j = 0, jlen = CSL.INSTITUTION_KEYS.length; j < jlen; j += 1) { 347 | var attrname = CSL.INSTITUTION_KEYS[j]; 348 | var attrval = thename.getAttribute(attrname); 349 | if (attrval) { 350 | theinstitutionpart.setAttribute(attrname, attrval); 351 | } 352 | } 353 | var nameparts = thename.getElementsByTagName("name-part"); 354 | for (var j = 0, jlen = nameparts.length; j < jlen; j += 1) { 355 | if ('family' === nameparts[j].getAttribute('name')) { 356 | for (var k = 0, klen = CSL.INSTITUTION_KEYS.length; k < klen; k += 1) { 357 | var attrname = CSL.INSTITUTION_KEYS[k]; 358 | var attrval = nameparts[j].getAttribute(attrname); 359 | if (attrval) { 360 | theinstitutionpart.setAttribute(attrname, attrval); 361 | } 362 | } 363 | } 364 | } 365 | } 366 | } 367 | }; 368 | CSL_CHROME.prototype.flagDateMacros = function(myxml) { 369 | var pos, len, thenode, thedate; 370 | nodes = myxml.getElementsByTagName("macro"); 371 | for (pos = 0, len = nodes.length; pos < len; pos += 1) { 372 | thenode = nodes.item(pos); 373 | thedate = thenode.getElementsByTagName("date"); 374 | if (thedate.length) { 375 | thenode.setAttribute('macro-has-date', 'true'); 376 | } 377 | } 378 | }; 379 | -------------------------------------------------------------------------------- /citeproc-js/xmle4x.js: -------------------------------------------------------------------------------- 1 | var CSL_E4X = function () {}; 2 | CSL_E4X.prototype.clean = function (xml) { 3 | xml = xml.replace(/<\?[^?]+\?>/g, ""); 4 | xml = xml.replace(/]+>/g, ""); 5 | xml = xml.replace(/^\s+/g, ""); 6 | xml = xml.replace(/\s+$/g, ""); 7 | return xml; 8 | }; 9 | CSL_E4X.prototype.getStyleId = function (myxml) { 10 | var text = ""; 11 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 12 | var node = myxml..id; 13 | if (node && node.length()) { 14 | text = node[0].toString(); 15 | } 16 | return text; 17 | }; 18 | CSL_E4X.prototype.children = function (myxml) { 19 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 20 | return myxml.children(); 21 | }; 22 | CSL_E4X.prototype.nodename = function (myxml) { 23 | var ret = myxml.localName(); 24 | return ret; 25 | }; 26 | CSL_E4X.prototype.attributes = function (myxml) { 27 | var ret, attrs, attr, key, xml; 28 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 29 | ret = new Object(); 30 | attrs = myxml.attributes(); 31 | for each (attr in attrs) { 32 | key = "@" + attr.localName(); 33 | if (key.slice(0,5) == "@e4x_") { 34 | continue; 35 | } 36 | ret[key] = attr.toString(); 37 | } 38 | return ret; 39 | }; 40 | CSL_E4X.prototype.content = function (myxml) { 41 | return myxml.toString(); 42 | }; 43 | CSL_E4X.prototype.namespace = { 44 | "xml":"http://www.w3.org/XML/1998/namespace" 45 | } 46 | CSL_E4X.prototype.numberofnodes = function (myxml) { 47 | if (typeof myxml === "xml") { 48 | return myxml.length(); 49 | } else if (myxml) { 50 | return myxml.length; 51 | } else { 52 | return 0; 53 | } 54 | }; 55 | CSL_E4X.prototype.getAttributeName = function (attr) { 56 | var ret = attr.localName(); 57 | return ret; 58 | } 59 | CSL_E4X.prototype.getAttributeValue = function (myxml,name,namespace) { 60 | var xml; 61 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 62 | if (namespace) { 63 | var ns = new Namespace(this.namespace[namespace]); 64 | var ret = myxml.@ns::[name].toString(); 65 | } else { 66 | if (name) { 67 | var ret = myxml.attribute(name).toString(); 68 | } else { 69 | var ret = myxml.toString(); 70 | } 71 | } 72 | return ret; 73 | } 74 | CSL_E4X.prototype.getNodeValue = function (myxml,name) { 75 | var xml; 76 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 77 | if (name){ 78 | return myxml[name].toString(); 79 | } else { 80 | return myxml.toString(); 81 | } 82 | } 83 | CSL_E4X.prototype.setAttributeOnNodeIdentifiedByNameAttribute = function (myxml,nodename,attrname,attr,val) { 84 | var xml; 85 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 86 | if (attr[0] != '@'){ 87 | attr = '@'+attr; 88 | } 89 | myxml[nodename].(@name == attrname)[0][attr] = val; 90 | } 91 | CSL_E4X.prototype.deleteNodeByNameAttribute = function (myxml,val) { 92 | delete myxml.*.(@name==val)[0]; 93 | } 94 | CSL_E4X.prototype.deleteAttribute = function (myxml,attr) { 95 | delete myxml["@"+attr]; 96 | } 97 | CSL_E4X.prototype.setAttribute = function (myxml,attr,val) { 98 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 99 | myxml['@'+attr] = val; 100 | } 101 | CSL_E4X.prototype.nodeCopy = function (myxml) { 102 | return myxml.copy(); 103 | } 104 | CSL_E4X.prototype.getNodesByName = function (myxml,name,nameattrval) { 105 | var xml, ret, retnodes; 106 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 107 | retnodes = myxml.descendants(name); 108 | ret = []; 109 | if (nameattrval){ 110 | retnodes = retnodes.(@name == nameattrval); 111 | if (retnodes.toXMLString()) { 112 | ret.push(retnodes); 113 | } 114 | } else { 115 | for each(var retnode in retnodes) { 116 | ret.push(retnode); 117 | } 118 | } 119 | return ret; 120 | } 121 | CSL_E4X.prototype.nodeNameIs = function (myxml,name) { 122 | var xml; 123 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 124 | if (myxml.localName() && myxml.localName().toString() == name){ 125 | return true; 126 | } 127 | return false; 128 | } 129 | CSL_E4X.prototype.makeXml = function (myxml) { 130 | var xml; 131 | XML.ignoreComments = true; 132 | XML.ignoreProcessingInstructions = true; 133 | XML.ignoreWhitespace = true; 134 | XML.prettyPrinting = true; 135 | XML.prettyIndent = 2; 136 | if ("xml" == typeof myxml){ 137 | myxml = myxml.toXMLString(); 138 | }; 139 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 140 | xml = new Namespace("http://www.w3.org/XML/1998/namespace"); 141 | if (myxml){ 142 | myxml = myxml.replace(/\s*<\?[^>]*\?>\s*\n*/g, ""); 143 | myxml = new XML(myxml); 144 | } else { 145 | myxml = new XML(); 146 | } 147 | return myxml; 148 | }; 149 | CSL_E4X.prototype.insertChildNodeAfter = function (parent,node,pos,datexml) { 150 | var myxml, xml; 151 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 152 | myxml = XML(datexml.toXMLString()); 153 | parent.insertChildAfter(node,myxml); 154 | delete parent.*[pos]; 155 | return parent; 156 | }; 157 | CSL_E4X.prototype.insertPublisherAndPlace = function(myxml) { 158 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 159 | for each (var node in myxml..group) { 160 | if (node.children().length() === 2) { 161 | var twovars = []; 162 | for each (var child in node.children()) { 163 | if (child.children().length() === 0 164 | ) { 165 | twovars.push(child.@variable.toString()); 166 | if (child.@suffix.toString() 167 | || child.@prefix.toString()) { 168 | twovars = []; 169 | break; 170 | } 171 | } 172 | } 173 | if (twovars.indexOf("publisher") > -1 && twovars.indexOf("publisher-place") > -1) { 174 | node["@has-publisher-and-publisher-place"] = "true"; 175 | } 176 | } 177 | } 178 | }; 179 | CSL_E4X.prototype.addMissingNameNodes = function(myxml) { 180 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 181 | for each (node in myxml..names) { 182 | if ("xml" == typeof node && node.parent().localName() !== "substitute" && node.elements("name").length() === 0) { 183 | var name = ; 184 | node.appendChild(name); 185 | } 186 | } 187 | }; 188 | CSL_E4X.prototype.addInstitutionNodes = function(myxml) { 189 | var institution_long, institution_short, name_part, children, node, xml; 190 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 191 | for each (node in myxml..names) { 192 | if ("xml" == typeof node && node.elements("name").length() > 0) { 193 | var name = node.name[0]; 194 | if (node.institution.length() === 0) { 195 | institution_long = 199 | institution_part = ; 200 | node.insertChildAfter(name,institution_long); 201 | node.institution.@delimiter = node.name.@delimiter.toString(); 202 | if (node.name.@and.toString()) { 203 | node.institution.@and = "text"; 204 | } 205 | node.institution[0].appendChild(institution_part); 206 | for each (var attr in CSL.INSTITUTION_KEYS) { 207 | if (node.name.@[attr].toString()) { 208 | node.institution['institution-part'][0].@[attr] = node.name.@[attr].toString(); 209 | } 210 | } 211 | for each (var namepartnode in node.name['name-part']) { 212 | if (namepartnode.@name.toString() === 'family') { 213 | for each (var attr in CSL.INSTITUTION_KEYS) { 214 | if (namepartnode.@[attr].toString()) { 215 | node.institution['institution-part'][0].@[attr] = namepartnode.@[attr].toString(); 216 | } 217 | } 218 | } 219 | } 220 | } 221 | } 222 | } 223 | }; 224 | CSL_E4X.prototype.flagDateMacros = function(myxml) { 225 | default xml namespace = "http://purl.org/net/xbiblio/csl"; with({}); 226 | for each (node in myxml..macro) { 227 | if (node..date.length()) { 228 | node.@['macro-has-date'] = 'true'; 229 | } 230 | } 231 | }; 232 | -------------------------------------------------------------------------------- /example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 57 | 58 | 59 |

My works:

60 |
61 |

Failed to resolve:

62 |
63 | 64 | -------------------------------------------------------------------------------- /exampledownloadbibtex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 46 | 47 | 48 |

Building BibTeX, please wait...

49 | 50 | -------------------------------------------------------------------------------- /lib/orcid.js: -------------------------------------------------------------------------------- 1 | //Overview: simple library that transforms an ORCID record into a list of citations or citeproc objects 2 | // attempts to fetch authoritative metadata from DOI, otherwise uses ORCID metadata 3 | // 4 | //Licence: MIT 5 | //Author: @tomdemeranville 6 | //Usage: 7 | // orcid.init(callback); 8 | // function callback(){ 9 | // //to fetch asyncronously and have the callback called once for each citation (recommended) use: 10 | // orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, true); 11 | // //to get the citations an array of citation strings via a callback as a batch use: 12 | // orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, false); 13 | // // the default style is Chicago, we can ask for bibtex instead like this: 14 | // orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, false, orcid.styleBibtex); 15 | // // if you want an array of citeproc JSON objects instead, use this: 16 | // orcid.resolveCitations("0000-0000-0000-0000", onCompleteCallback, true, "", true); 17 | // } 18 | // 19 | // //If all you need is a list of titles, identifiers and URLS, use simpleWorks 20 | // //This also demonstrates how to access the API via swagger (full v2.0 api is supported) 21 | // var client = orcid.init(callback); 22 | // function callback(){ 23 | // client.apis["Public API v2.0"].viewActivities({orcid:orcidID}, function(data) { 24 | // var simpleWorks = orcid.activitiesToSimpleWorks(data); 25 | // //do whatever with the simpleWorks 26 | // }); 27 | // } 28 | // 29 | // Dependencies: swagger-client.js, jquery, citeproc-js [transitive xmle4x.js,xmldom.js] 30 | 31 | var orcid = function(){ 32 | 33 | var pubSwagger = "https://pub.orcid.org/resources/swagger.json"; 34 | //var pubSwagger = "https://localhost:8443/orcid-pub-web/resources/swagger.json"; 35 | //var pubAPI = "https://localhost:8443/orcid-pub-web/v2.0"; 36 | var pubAPI = "https://pub.orcid.org/v2.0"; 37 | var client = null; 38 | 39 | //initialises the swagger client. 40 | function createPublicV2ORCIDClient(onSuccess){ 41 | if (client == null){ 42 | client = new SwaggerClient({ 43 | url: pubSwagger, 44 | success: onSuccess 45 | }); 46 | } 47 | return client; 48 | } 49 | 50 | //transform ORCID activities into (title,ID,identifierType,originalOrder,URL,citeprocURL) 51 | function activitiesToSimpleWorks(activitiesObject){ 52 | var order = 0; 53 | var worksList = activitiesObject.obj.works.group.map(function(obj){ 54 | var rObj = {originalOrder:""+order}; 55 | order++; 56 | rObj.title = obj["work-summary"][0].title.title.value; 57 | if (obj["external-ids"] && obj["external-ids"]["external-id"] && obj["external-ids"]["external-id"][0]){ 58 | rObj.ID = obj["external-ids"]["external-id"][0]["external-id-value"]; 59 | rObj.identifierType = obj["external-ids"]["external-id"][0]["external-id-type"]; 60 | } 61 | var prefix = ""; 62 | if (rObj.identifierType == "doi" && rObj.ID && rObj.ID.match('^https?://')){ 63 | //due to bug in browser 303 redirect implemetations forgetting Accept headers, 64 | //we resolve directly at crossref and retry at datacite if we get a 404 65 | rObj.ID = rObj.ID.replace(/^https?:\/\/(dx\.)?doi\.org\//i, ''); //remove url 66 | prefix = "http://data.crossref.org/"; 67 | } else if (rObj.identifierType == "doi" && rObj.ID){ 68 | prefix = "http://data.crossref.org/"; 69 | } else if (rObj.identifierType == "isbn"){ 70 | prefix = "http://www.worldcat.org/isbn/"; 71 | } else if (rObj.identifierType == "arxiv"){ 72 | prefix = "http://arxiv.org/abs/"; 73 | } else if (rObj.identifierType == "asin"){ 74 | prefix = "http://www.amazon.com/dp/"; 75 | } else if (rObj.identifierType == "ethos"){ 76 | prefix = "http://ethos.bl.uk/OrderDetails.do?uin="; 77 | } else if (rObj.identifierType == "jstor"){ 78 | prefix = "http://www.jstor.org/stable/"; 79 | } else if (rObj.identifierType == "lccn"){ 80 | prefix = "http://lccn.loc.gov/"; 81 | } else if (rObj.identifierType == "mr"){ 82 | prefix = "http://www.ams.org/mathscinet-getitem?mr="; 83 | } else if (rObj.identifierType == "oclc"){ 84 | prefix = "http://www.worldcat.org/oclc/"; 85 | } else if (rObj.identifierType == "ol"){ 86 | prefix = "http://openlibrary.org/b/"; 87 | } else if (rObj.identifierType == "ol"){ 88 | prefix = "http://www.osti.gov/energycitations/product.biblio.jsp?osti_id="; 89 | } else if (rObj.identifierType == "pmc"){ 90 | prefix = "http://www.ncbi.nlm.nih.gov/pubmed/"; 91 | } else if (rObj.identifierType == "pmid"){ 92 | prefix = "http://europepmc.org/abstract/med/"; 93 | } else if (rObj.identifierType == "ssrn"){ 94 | prefix = "http://papers.ssrn.com/abstract_id="; 95 | } 96 | if ( prefix != "" || rObj.identifierType == "handle" || rObj.identifierType == "uri" || rObj.identifierType == "doi"){ 97 | rObj.URL = prefix + rObj.ID; 98 | } 99 | if (rObj.identifierType == "doi"){ 100 | rObj.citeprocURL = rObj.URL; 101 | }else{ 102 | rObj.citeprocURL = pubAPI+obj["work-summary"][0].path; 103 | } 104 | return rObj; 105 | }); 106 | return worksList; 107 | } 108 | 109 | //simple
  • generator for reference lists 110 | function appendSimpleWorksToElement(simpleWorks, elementID){ 111 | simpleWorks.forEach(function(obj){ 112 | if ( obj.URL ){ 113 | document.getElementById(elementID).innerHTML += "
  • "+ obj.title + " - (" + obj.identifierType +":"+ obj.ID +")
  • "; 114 | } else { 115 | document.getElementById(elementID).innerHTML += "
  • "+ obj.title + " - (" + obj.identifierType +":"+ obj.ID +")
  • "; 116 | } 117 | }); 118 | } 119 | 120 | // add some extra juice to jquery - one callback for multiple parallel ajax requests 121 | // see http://stackoverflow.com/questions/5627284/calling-multiple-ajax-requests-in-parallel-and-handling-responses-by-passing-an 122 | if (jQuery.when.all===undefined) { 123 | jQuery.when.all = function(deferreds) { 124 | var deferred = new jQuery.Deferred(); 125 | $.when.apply(jQuery, deferreds).then( 126 | function() { 127 | deferred.resolve(Array.prototype.slice.call(arguments)); 128 | }, 129 | function() { 130 | deferred.fail(Array.prototype.slice.call(arguments)); 131 | }); 132 | 133 | return deferred; 134 | } 135 | } 136 | 137 | //attempts to resolve citeproc metadata for all works 138 | //onDone is passed an array of Jquery ajax results (both successes and failiure) 139 | function fetchCiteprocJSONForSimpleWorks(simpleWorks, onDone){ 140 | var requests = []; 141 | simpleWorks.forEach(function(obj){ 142 | var d = fetchCiteprocJSONForSimpleWork(obj); 143 | requests.push(d); 144 | }); 145 | $.when.all(requests).done(onDone); 146 | } 147 | 148 | //attempts to resolve citeproc metadata for works and resolves the citation asynchronously 149 | //onEachWork is passed each Jquery ajax result as it arrives (both successes and failiure) 150 | function fetchCiteprocJSONForSimpleWorksOneByOne(simpleWorks, onEachWork){ 151 | simpleWorks.forEach(function(obj){ 152 | var d = fetchCiteprocJSONForSimpleWork(obj); 153 | var requests = []; 154 | requests.push(d); 155 | $.when.all(requests).done(onEachWork); 156 | }); 157 | } 158 | 159 | //returns a Deffered containing an ajax request. 160 | //retries failed crossref requests with datacite 161 | function fetchCiteprocJSONForSimpleWork(simpleWork){ 162 | var d = $.Deferred(); 163 | var r = 164 | $.ajax({ 165 | headers: { 166 | Accept : "application/vnd.citationstyles.csl+json" 167 | }, 168 | type: "GET", 169 | crossDomain: true, 170 | url: simpleWork.citeprocURL, 171 | dataType: 'json', 172 | cache: false, 173 | success: function (data, textStatus, jqXHR) { 174 | if (data){ 175 | if (!jqXHR.responseJSON){//fixes weird bug when working with angular and/or some versions of JQuery 176 | jqXHR.responseJSON = $.parseJSON(jqXHR.responseText); 177 | } 178 | jqXHR.responseJSON.originalOrder = simpleWork.originalOrder; 179 | } 180 | }, 181 | error: function (jqXHR, textStatus, errorThrown ){ 182 | jqXHR.failedWork = simpleWork; 183 | } 184 | }).done(d.resolve) 185 | .fail(function(jqXHR, textStatus, errorThrown){ 186 | if (jqXHR.status == 404 && simpleWork.citeprocURL.match('crossref')){ 187 | //if we tried crossref and failed, try datacite instead 188 | simpleWork.citeprocURL = simpleWork.citeprocURL.replace(/crossref/i, 'datacite'); 189 | $.ajax({ 190 | headers: { 191 | Accept : "application/vnd.citationstyles.csl+json" 192 | }, 193 | type: "GET", 194 | crossDomain: true, 195 | url: simpleWork.citeprocURL, 196 | dataType: 'json', 197 | cache: false, 198 | success: function (data, textStatus, jqXHR) { 199 | if (data){ 200 | if (!jqXHR.responseJSON){//fixes weird bug when working with angular and/or some versions of JQuery 201 | jqXHR.responseJSON = $.parseJSON(jqXHR.responseText); 202 | } 203 | jqXHR.responseJSON.originalOrder = simpleWork.originalOrder; 204 | jqXHR.failedWork = null; 205 | } 206 | }, 207 | error: function (jqXHR, textStatus, errorThrown ){ 208 | jqXHR.failedWork = simpleWork; 209 | } 210 | }).always(d.resolve); 211 | }else{ 212 | //propigate the error to the callback. 213 | d.resolve([jqXHR, textStatus, errorThrown]); 214 | } 215 | }); 216 | return d; 217 | } 218 | 219 | // source: https://gist.github.com/bdarcus/864632 220 | // default citeproc settings 221 | var defaultLocale = {"en-US":" No. Doc. U.N. Sales No. No. \u201c \u201d \u2018 \u2019 st nd rd th first second third fourth fifth sixth seventh eighth ninth tenth at in ibid accessed retrieved from forthcoming reference references ref refs n.d. and et al. interview letter anonymous anon. and others in press online cited internet presented at the AD BC Spring Summer Autumn Winter with anthropology astronomy biology botany chemistry engineering generic base geography geology history humanities literature math medicine philosophy physics psychology sociology science political science social science theology zoology book books chapter chapters column columns figure figures folio folios number numbers line lines note notes opus opera page pages paragraph paragraph part parts section sections volume volumes edition editions verse verses sub verbo s.vv bk. chap. col. fig. f. no. op. p. pp. para. pt. sec. s.v. s.vv. v. vv. vol. vols. edition ed. ¶¶ § §§ editor editors translator translators ed. eds. tran. trans. edited by translated by to interview by ed. trans. January February March April May June July August September October November December Jan. Feb. Mar. Apr. May Jun. Jul. Aug. Sep. Oct. Nov. Dec. "}; 222 | var styleChigcagoAD = "\r\n