site/node_modules/@citation-js/plugin-bibtex/lib-mjs/mapping/shared.js
2024-10-14 08:09:33 +02:00

316 lines
7.5 KiB
JavaScript

import { util } from '@citation-js/core';
import config from '../config.js';
const stopWords = new Set(['the', 'a', 'an']);
const unsafeChars = /(?:<\/?.*?>|[\u0020-\u002F\u003A-\u0040\u005B-\u005E\u0060\u007B-\u007F])+/g;
const unicode = /[^\u0020-\u007F]+/g;
function firstWord(text) {
if (!text) {
return '';
} else {
return text.normalize('NFKD').replace(unicode, '').split(unsafeChars).find(word => word.length && !stopWords.has(word.toLowerCase()));
}
}
const name = new util.Translator([{
source: 'given',
target: 'given'
}, {
source: 'family',
target: 'family'
}, {
source: 'suffix',
target: 'suffix'
}, {
source: 'prefix',
target: 'non-dropping-particle'
}, {
source: 'family',
target: 'literal',
when: {
source: false,
target: {
family: false,
given: false
}
}
}]);
const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
export const TYPE = 'BibTeX type';
export const LABEL = 'BibTeX label';
export const MONTHS = {
jan: 1,
feb: 2,
mar: 3,
apr: 4,
may: 5,
jun: 6,
jul: 7,
aug: 8,
sep: 9,
oct: 10,
nov: 11,
dec: 12,
january: 1,
february: 2,
march: 3,
april: 4,
may: 5,
june: 6,
july: 7,
august: 8,
september: 9,
october: 10,
november: 11,
december: 12
};
export const TYPE_KEYS = {
bathesis: 'Bachelor\'s thesis',
mathesis: 'Master\'s thesis',
phdthesis: 'PhD thesis',
candthesis: 'Candidate thesis',
techreport: 'technical report',
resreport: 'research report',
software: 'computer software',
datacd: 'data cd',
audiocd: 'audio cd',
patent: 'patent',
patentde: 'German patent',
patenteu: 'European patent',
patentfr: 'French patent',
patentuk: 'British patent',
patentus: 'U.S. patent',
patreq: 'patent request',
patreqde: 'German patent request',
patreqeu: 'European patent request',
patreqfr: 'French patent request',
patrequk: 'British patent request',
patrequs: 'U.S. patent request'
};
export const STANDARD_NUMBERS_PATTERN = /(^(?:ISAN )?(?:[0-9a-f]{4}-){4}[0-9a-z](?:-(?:[0-9a-f]{4}-){2}[0-9a-z])?$)|(^(?:979-?0-?|M-?)(?:\d{9}|(?=[\d-]{11}$)\d+-\d+-\d)$)|(^ISRN .{1,36}$)|(^(?:ISWC )?T-?\d{9}-?\d$)/i;
export function parseDate(date) {
const parts = date.split('T')[0].replace(/[?~%]$/, '').split('-');
const year = +parts[0].replace(/^Y(?=-?\d{4}\d+)/, '').replace(/X/g, '0');
const month = +parts[1];
const day = +parts[2];
if (!month || month > 20) {
return [year];
} else if (!day) {
return [year, month];
} else {
return [year, month, day];
}
}
export function parseMonth(value) {
if (value == null) {
return [];
}
if (+value) {
return [parseInt(value, 10)];
}
value = value.trim().toLowerCase();
if (value in MONTHS) {
return [MONTHS[value]];
}
const parts = value.split(/\s+/);
let month;
let day;
if (parts[0] in MONTHS) {
month = MONTHS[parts[0]];
day = parseInt(parts[1]);
} else if (parts[1] in MONTHS) {
month = MONTHS[parts[1]];
day = parseInt(parts[0]);
}
return day ? [month, day] : month ? [month] : [];
}
export function formatLabel(author, issued, suffix, title) {
let label = '';
if (author && author[0]) {
label += firstWord(author[0].family || author[0].literal);
}
if (issued && issued['date-parts'] && issued['date-parts'][0]) {
label += issued['date-parts'][0][0];
}
if (suffix) {
label += suffix;
} else if (title) {
label += firstWord(title);
}
return label;
}
export const Converters = {
PICK: {
toTarget(...args) {
return args.find(Boolean);
},
toSource(value) {
return [value];
}
},
DATE: {
toTarget(date) {
const parts = date.split('/').map(part => part && part !== '..' ? parseDate(part) : undefined);
return isNaN(parts[0][0]) ? {
literal: date
} : {
'date-parts': parts
};
},
toSource(date) {
if ('date-parts' in date) {
return date['date-parts'].map(datePart => datePart.map(datePart => datePart.toString().padStart(2, '0')).join('-')).join('/');
}
}
},
YEAR_MONTH: {
toTarget(year, month, day) {
if (isNaN(+year)) {
return {
literal: year
};
} else if (!isNaN(+day) && !isNaN(+month)) {
return {
'date-parts': [[+year, +month, +day]]
};
} else {
return {
'date-parts': [[+year, ...parseMonth(month)]]
};
}
},
toSource(date) {
if ('date-parts' in date) {
const [year, month, day] = date['date-parts'][0];
return [year.toString(), month ? day ? `${months[month - 1]} ${day}` : month : undefined];
} else {
return [];
}
}
},
EPRINT: {
toTarget(id, type) {
if (type === 'pubmed') {
return id;
}
},
toSource(id) {
return [id, 'pubmed'];
}
},
EVENT_TITLE: {
toTarget(title, addon) {
if (addon) {
title += ' (' + addon + ')';
}
return title;
},
toSource(title) {
return title.match(/^(.+)(?: \((.+)\))?$/).slice(1, 3);
}
},
HOW_PUBLISHED: {
toTarget(howPublished) {
if (howPublished.startsWith('http')) {
return howPublished;
}
}
},
KEYWORDS: {
toTarget(list) {
return list.join(',');
},
toSource(list) {
return list.split(',');
}
},
LABEL: {
toTarget(label) {
return [label, label];
},
toSource(id, label, author, issued, suffix, title) {
let safeId;
if (id === null) {
safeId = 'null';
} else if (id === undefined) {
safeId = 'undefined';
} else {
safeId = id.toString().replace(unsafeChars, '');
}
if (config.format.useIdAsLabel) {
return safeId;
}
if (label && !unsafeChars.test(label)) {
return label;
} else {
return formatLabel(author, issued, suffix, title) || safeId;
}
}
},
NAMES: {
toTarget(list) {
return list.map(name.convertToTarget);
},
toSource(list) {
return list.map(name.convertToSource);
}
},
NAMES_ORCID: {
toTarget(list, orcid) {
return list.map((inputName, i) => {
var _orcid$item;
const outputName = name.convertToTarget(inputName);
if (typeof (orcid === null || orcid === void 0 || (_orcid$item = orcid.item) === null || _orcid$item === void 0 ? void 0 : _orcid$item[i]) === 'string') {
outputName._orcid = orcid.item[i];
}
return outputName;
});
},
toSource(list) {
const names = [];
const orcid = [];
for (let i = 0; i < list.length; i++) {
names.push(name.convertToSource(list[i]));
if (list[i]._orcid) {
orcid[i] = list[i]._orcid;
}
}
return [names, orcid.length ? {
item: orcid
} : undefined];
}
},
PAGES: {
toTarget(pages) {
return pages.replace(/[–—]/, '-');
},
toSource(pages) {
return pages.replace('-', '--');
}
},
STANDARD_NUMBERS: {
toTarget(...args) {
return args.find(Boolean);
},
toSource(number) {
const match = number.toString().match(STANDARD_NUMBERS_PATTERN);
return match ? match.slice(1, 5) : [];
}
},
STATUS: {
toSource(state) {
if (/^(inpreparation|submitted|forthcoming|inpress|prepublished)$/i.test(state)) {
return state;
}
}
},
TITLE: {
toTarget(title, subtitle, addon) {
if (subtitle) {
title += ': ' + subtitle;
}
return title;
},
toSource(title) {
return [title];
}
}
};