kopetri's picture
tpami
d736789
const warnings = (function () {
const fieldCrossRefMap = {
doi: function (result) { return result.DOI },
journal: function (result) { return result['container-title'][0] },
pages: function (result) { return result.page },
title: function (result) { return result.title[0] }
}
return {
expectedFields: {
inproceedings: ['author', 'booktitle', 'pages', 'publisher', 'title', 'year', 'doi'],
article: ['author', 'journal', 'number', 'pages', 'title', 'volume', 'year', 'doi'],
techreport: ['author', 'institution', 'title', 'year'],
incollection: ['author', 'booktitle', 'pages', 'publisher', 'title', 'year'],
book: ['author', 'publisher', 'title', 'year'],
inbook: ['author', 'booktitle', 'pages', 'publisher', 'title', 'year'],
proceedings: ['editor', 'publisher', 'title', 'year'],
phdthesis: ['author', 'school', 'title', 'year'],
mastersthesis: ['author', 'school', 'title', 'year'],
bachelorsthesis: ['author', 'school', 'title', 'year'],
electronic: ['author', 'title', 'url', 'year'],
misc: ['author', 'howpublished', 'title', 'year']
},
computeAllWarnings: function (entries) {
var that = this;
var warnings = {};
$.each(entries, function (id, entry) {
warnings[id] = that.computeWarnings(entry);
});
return warnings;
},
computeWarnings: function (entry) {
var warningsList = [];
if (editable) {
warningsList = warningsList.concat(warnings.computeMissingFieldWarning(entry));
warningsList = warningsList.concat(warnings.computeTitleCapitalizationWarning(entry));
warningsList = warningsList.concat(warnings.computeProtectedIdentifierCapitalizationWarning(entry));
$.each(entry, function (field, value) {
computeFirstNameUnknown(warningsList, field, value);
computeWholeFieldCapitalizationProtected(warningsList, field, value);
});
}
return warningsList;
},
computeMissingFieldWarning: function (entry) {
function condenseTitle(title) {
return title.toLowerCase().replace(/\W+/g, '');
}
var warningsList = [];
if (entry) {
var expected = warnings.expectedFields[entry['type']];
if (expected) {
$.each(expected, function (i, field) {
if (!entry[field] || entry[field].trim() === '') {
warningsList.push({
type: `missing or empty field '${field}'`,
fix: {
description: 'try to load from CrossRef', 'function': function (onFix) {
page.notify('Loading data from CrossRef...');
const searchString = (entry.doi ? `/${entry.doi}` : `?query=${entry.title.replace(/\W+/g, '+')}`);
fetch(`https://api.crossref.org/works${searchString}`).then(response => {
return response.json()
}).then(data => {
if (!data.message) {
throw 'No return message';
}
const result = (entry.doi ? data.message : data.message.items[0]);
if (!entry.doi && condenseTitle(entry.title) != condenseTitle(result.title[0])) {
throw `Titles do not match: "${entry.title}" and "${result.title[0]}"`;
}
page.notify(`Paper found on CrossRef titled '${result.title}'`);
let value = (fieldCrossRefMap[field] ? fieldCrossRefMap[field](result) : result[field]);
if (!value) {
page.notify(`However, field '${field}' not available in the CrossRef record.`, 'error')
} else {
if (field === 'pages') {
value = value.replace('-', '--');
}
entry[field] = value;
page.notify(`Updated field '${field}' with value '${value}'.`)
onFix(entry);
}
}).catch(error => {
console.error(error);
page.notify(`Could not find a publication with this ${(entry.doi ? 'DOI' : 'title')} on CrossRef.`, 'error');
});
}
}
});
}
});
}
}
return warningsList;
},
computeTitleCapitalizationWarning: function (entry) {
if (!entry) {
return [];
}
var warningsList = [];
$.each(['booktitle', 'journal'], function (i, field) {
if (entry[field]) {
var value = entry[field];
var capitalizationCorrect = true;
var correctedValue = '';
$.each(value.split(' '), function (i, word) {
var capitalizedWord = word;
if (!word.match(/\d.*/)) {
if ((word.length >= 5 || i == 0) && word.toLowerCase() == word) {
capitalizationCorrect = false;
capitalizedWord = word.charAt(0).toUpperCase() + word.substring(1);
}
}
correctedValue += (correctedValue ? ' ' : '') + capitalizedWord;
});
if (!capitalizationCorrect) {
warningsList.push({
type: 'capitalization in field "' + field + '"',
fix: {
description: 'capitalize longer words', 'function': function (onFix) {
entry[field] = correctedValue;
onFix(entry);
}
}
});
}
}
});
return warningsList;
},
computeProtectedIdentifierCapitalizationWarning: function (entry) {
if (!entry) {
return [];
}
var warningsList = [];
$.each(['title'], function (i, field) {
if (entry[field]) {
var value = entry[field];
var capitalizationCorrect = true;
var correctedValue = value;
if (value.indexOf('{') < 0) {
$.each(value.split(/[\s,:\-()\/]+/), function (i, word) {
if (!word.startsWith('{')) {
var subword = word.substring(1);
if (subword.length > 0 && subword.toLowerCase() != subword) {
capitalizationCorrect = false;
var re = new RegExp('\{?' + word + '\}?', 'g');
correctedValue = correctedValue.replace(re, '{' + word + '}');
}
}
});
if (!capitalizationCorrect) {
warningsList.push({
type: 'non-protected capitalization of identifier in field "' + field + '"',
fix: {
description: 'protect identifiers', 'function': function (onFix) {
entry[field] = correctedValue;
onFix(entry);
}
}
});
}
}
}
});
return warningsList;
}
};
function computeFirstNameUnknown(warningsList, field, value) {
if (field === 'author' || field === 'editor') {
var firstNameKnown = true;
$.each(value.split(' and '), function (i, name) {
var parsedName = name.trim().split(',');
if (parsedName.length > 1) {
var firstName = parsedName[1].trim().split(' ')[0].trim();
if (firstName.indexOf('.') > 0 || firstName.length < 2) {
firstNameKnown = false;
}
} else {
firstNameKnown = false;
}
});
if (!firstNameKnown) {
warningsList.push('unknown or abbreviated first name in field "' + field + '"');
}
}
}
function computeWholeFieldCapitalizationProtected(warningsList, field, value) {
if (value.indexOf('{') === 0 && value.lastIndexOf('}') === value.length - 1 && value.length > 10 && (value.split("{").length - 1 === 1)) {
warningsList.push('whole field "' + field + '" with protected capitalization');
}
}
})();