Initial Commit
This commit is contained in:
324
translators/Wikidata QuickStatements.js
Normal file
324
translators/Wikidata QuickStatements.js
Normal file
@@ -0,0 +1,324 @@
|
||||
{
|
||||
"translatorID": "51e5355d-9974-484f-80b9-f84d2b55782e",
|
||||
"label": "Wikidata QuickStatements",
|
||||
"creator": "Philipp Zumstein with contributors",
|
||||
"target": "txt",
|
||||
"minVersion": "3.0",
|
||||
"maxVersion": "",
|
||||
"priority": 100,
|
||||
"inRepository": true,
|
||||
"translatorType": 2,
|
||||
"lastUpdated": "2025-08-11 00:00:00"
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2017-2025 Philipp Zumstein with contributors
|
||||
|
||||
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",
|
||||
OpenAlex: "P10283",
|
||||
CorpusID: "P8299",
|
||||
WOS: "P8372",
|
||||
MAG: "P6366"
|
||||
};
|
||||
|
||||
|
||||
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.proceedingsTitle && (itemType == "conferencePaper")) {
|
||||
description = description + ' from \'' + item.proceedingsTitle + '\'';
|
||||
}
|
||||
if (item.bookTitle && (itemType == "bookSection")) {
|
||||
description = description + ' from \'' + item.bookTitle + '\'';
|
||||
}
|
||||
if (item.encyclopediaTitle && (itemType == "encyclopediaArticle")) {
|
||||
description = description + ' from \'' + item.encyclopediaTitle + '\'';
|
||||
}
|
||||
if (item.university && (itemType == "thesis")) {
|
||||
description = description + ' from \'' + item.university + '\'';
|
||||
}
|
||||
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 + '"');
|
||||
}
|
||||
}
|
||||
|
||||
addStatement('Lmul', '"' + item.title + '"');
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user