zotero/translators/Wikidata QuickStatements.js

307 lines
7.9 KiB
JavaScript
Raw Normal View History

2024-08-27 21:48:20 -05:00
{
"translatorID": "51e5355d-9974-484f-80b9-f84d2b55782e",
"label": "Wikidata QuickStatements",
"creator": "Philipp Zumstein",
"target": "txt",
"minVersion": "3.0",
"maxVersion": "",
"priority": 100,
"inRepository": true,
"translatorType": 2,
"lastUpdated": "2022-12-08 23:00:00"
}
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2017 Philipp Zumstein
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
*/
var typeMapping = {
// Zotero types
artwork: "Q838948",
// "attachment" : "Q17709279",
audioRecording: "Q30070318",
bill: "Q686822",
blogPost: "Q17928402",
book: "Q3331189", // changed from Q571 (work level) to edition level as we want to export maximal amount of properties
bookSection: "Q1980247",
case: "Q2334719",
computerProgram: "Q40056",
conferencePaper: "Q23927052",
dictionaryEntry: "Q30070414",
document: "Q49848",
email: "Q30070439",
encyclopediaArticle: "Q17329259",
film: "Q11424",
forumPost: "Q7216866",
hearing: "Q30070550",
instantMessage: "Q30070565",
interview: "Q178651",
journalArticle: "Q13442814",
letter: "Q133492",
magazineArticle: "Q30070590",
manuscript: "Q87167",
map: "Q4006",
newspaperArticle: "Q5707594",
// note
patent: "Q253623",
podcast: "Q24634210",
presentation: "Q604733",
radioBroadcast: "Q1555508",
report: "Q10870555",
statute: "Q820655",
thesis: "Q1266946",
tvBroadcast: "Q15416",
videoRecording: "Q30070675",
webpage: "Q36774",
// additional CSL types (can be used in Zotero with a hack)
dataset: "Q1172284",
// entry
figure: "Q30070753",
musical_score: "Q187947", // eslint-disable-line camelcase
pamphlet: "Q190399",
review: "Q265158",
"review-book": "Q637866",
treaty: "Q131569"
};
// simple properties with string values can be simply mapped here
var propertyMapping = {
P356: "DOI",
P953: "url",
P478: "volume",
P433: "issue",
P304: "pages",
P1104: "numPages",
P393: "edition"
};
// properties which needs no quotes around their values (e.g. ones for numbers)
var nonStringProperties = ["P1104"];
// it is important to use here the language codes in the form
// as they are also used in Wikidata for monolingual text
var languageMapping = {
en: "Q1860",
zh: "Q7850",
ru: "Q7737",
fr: "Q150",
ja: "Q5287",
de: "Q188",
es: "Q1321",
sr: "Q9299",
pl: "Q809",
cs: "Q9056",
it: "Q652",
cy: "Q9309",
pt: "Q5146",
nl: "Q7411",
sv: "Q9027",
ar: "Q13955",
ko: "Q9176",
hu: "Q9067",
da: "Q9035",
fi: "Q1412",
eu: "Q8752",
he: "Q9288",
la: "Q397",
nb: "Q25167",
no: "Q9043",
el: "Q9129",
tr: "Q256",
ca: "Q7026",
sl: "Q9063",
ro: "Q7913",
is: "Q294",
grc: "Q35497",
uk: "Q8798",
fa: "Q9168",
hy: "Q8785",
ta: "Q5885"
};
var identifierMapping = {
PMID: "P698",
PMCID: "P932",
"JSTOR ID": "P888",
arXiv: "P818",
"Open Library ID": "P648",
OCLC: "P243",
"IMDb ID": "P345",
"Google-Books-ID": "P675"
};
function zoteroItemToQuickStatements(item) {
// add numPages if only page range is given
if (item.pages && !item.numPages) {
let pagesMatch = item.pages.match(/^(\d+)[-](\d+)$/);
if (pagesMatch) {
item.numPages = parseInt(pagesMatch[2]) - parseInt(pagesMatch[1]) + 1;
}
}
// cleanup edition before to export
if (item.edition) {
item.edition = parseInt(item.edition);
if (item.edition == 1) {
delete item.edition;
}
}
var statements = ['CREATE'];
var addStatement = function () {
var args = Array.prototype.slice.call(arguments);
statements.push('LAST\t' + args.join('\t'));
};
var itemType = item.itemType;
// check whether a special itemType is defined in the extra fields
if (item.extra) {
var matchItemType = item.extra.match(/itemType: ([\w-]+)($|\n)/);
if (matchItemType) {
itemType = matchItemType[1];
}
}
if (typeMapping[itemType]) {
addStatement('P31', typeMapping[itemType]);
}
var description = itemType.replace(/([A-Z])/, function (match, firstLetter) {
return ' ' + firstLetter.toLowerCase();
});
if (item.publicationTitle && (itemType == "journalArticle" || itemType == "magazineArticle" || itemType == "newspaperArticle")) {
description = description + ' from \'' + item.publicationTitle + '\'';
}
if (item.date) {
var year = ZU.strToDate(item.date).year;
if (year) {
description = description + ' published in ' + year;
}
}
addStatement('Den', '"' + description + '"');
for (var pnumber in propertyMapping) {
var zfield = propertyMapping[pnumber];
if (item[zfield]) {
if (nonStringProperties.includes(pnumber)) {
addStatement(pnumber, item[zfield]);
}
else {
addStatement(pnumber, '"' + item[zfield] + '"');
}
}
}
var index = 1;
for (var i = 0; i < item.creators.length; i++) {
var creatorValue = item.creators[i].lastName;
var creatorType = item.creators[i].creatorType;
if (item.creators[i].firstName) {
creatorValue = item.creators[i].firstName + ' ' + creatorValue;
}
if (creatorType == "author") {
addStatement('P2093', '"' + creatorValue + '"', 'P1545', '"' + index + '"');
index++;
}
// other creatorTypes are ignored, because they would need to point an item, rather than just writing the string value
}
if (item.date) {
// e.g. +1967-01-17T00:00:00Z/11
var formatedDate = ZU.strToISO(item.date);
switch (formatedDate.length) {
case 4:
formatedDate += "-00-00T00:00:00Z/9";
break;
case 7:
formatedDate += "-00T00:00:00Z/10";
break;
case 10:
formatedDate += "T00:00:00Z/11";
break;
default:
formatedDate += "/11";
}
addStatement('P577', '+' + formatedDate);
}
// determining depending entries where the ISBN is part of the larger work
var dependingWork = ["bookSection", "conferencePaper", "dictionaryEntry", "encyclopediaArticle", "journalArticle", "magazineArticle", "newspaperArticle"].includes(itemType);
if (item.ISBN && !dependingWork) {
var isbnDigits = item.ISBN.replace(/-/g, '');
if (isbnDigits.length == 13) {
addStatement('P212', '"' + item.ISBN + '"');
}
if (isbnDigits.length == 10) {
addStatement('P957', '"' + item.ISBN + '"');
}
}
if (item.language && (item.language.toLowerCase() in languageMapping)) {
let lang = item.language.toLowerCase();
addStatement('L' + lang, '"' + item.title + '"');
addStatement('P1476', lang + ':"' + item.title + '"');
addStatement('P407', languageMapping[lang]);
}
else {
// otherwise use "und" for undetermined language and add the label in english by default
addStatement('Len', '"' + item.title + '"');
addStatement('P1476', 'und:"' + item.title + '"');
}
if (item.extra) {
var extraLines = item.extra.split('\n');
for (var j = 0; j < extraLines.length; j++) {
var colon = extraLines[j].indexOf(':');
if (colon > -1) {
var label = extraLines[j].substr(0, colon);
var value = extraLines[j].substr(colon + 1);
if (identifierMapping[label]) {
addStatement(identifierMapping[label], '"' + value.trim() + '"');
}
if (label.match(/^P\d+$/)) {
if (value.trim().match(/^Q\d+$/)) {
addStatement(label, value.trim());
}
else {
addStatement(label, '"' + value.trim() + '"');
}
}
}
}
}
return statements.join('\n') + '\n';
}
function doExport() {
var item;
while ((item = Zotero.nextItem())) {
// skipping items with a QID saved in extra
if (item.extra && item.extra.match(/^QID: /m)) continue;
// write the statements
Zotero.write(zoteroItemToQuickStatements(item));
}
}