"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.format = format; exports.formatAnnotation = formatAnnotation; var _config = _interopRequireDefault(require("../config.js")); var _constants = require("../input/constants.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const unicode = {}; for (const command in _constants.commands) { unicode[_constants.commands[command]] = command; } for (const diacritic in _constants.diacritics) { unicode[_constants.diacritics[diacritic]] = diacritic; } for (const ligature in _constants.ligatures) { unicode[_constants.ligatures[ligature]] = ligature; } const mathUnicode = {}; for (const command in _constants.mathCommands) { mathUnicode[_constants.mathCommands[command]] = command; } const UNSAFE_UNICODE = /[^a-zA-Z0-9\s!"#%&'()*+,\-./:;=?@[\]{}\u0300-\u0308\u030a-\u030c\u0332\u0323\u0327\u0328\u0361\u0326]/g; const DIACRITIC_PATTERN = /.[\u0300-\u0308\u030a-\u030c\u0332\u0323\u0327\u0328\u0361\u0326]+/g; const LONE_DIACRITIC_PATTERN = /[\u0300-\u0308\u030a-\u030c\u0332\u0323\u0327\u0328\u0361\u0326]/g; const listDelimiters = { separated: ',', list: ' and ' }; const richTextMappings = { i: '\\textit{', b: '\\textbf{', sc: '\\textsc{', sup: '\\textsuperscript{', sub: '\\textsubscript{', 'span style="font-variant:small-caps;"': '\\textsc{', 'span class="nocase"': '{' }; function escapeCharacter(char) { if (char in unicode) { return unicode[char] in _constants.ligatures ? unicode[char] : `\\${unicode[char]}{}`; } else if (char in mathUnicode) { return `$\\${mathUnicode[char]}$`; } else { return ''; } } function escapeValue(value) { if (!_config.default.format.asciiOnly) { return value; } return value.normalize('NFKD').replace(UNSAFE_UNICODE, char => escapeCharacter(char)).replace(DIACRITIC_PATTERN, match => Array.from(match).reduce((subject, diacritic) => `{\\${unicode[diacritic]} ${subject}}`)).replace(LONE_DIACRITIC_PATTERN, ''); } function formatRichText(value) { const closingTags = []; let tokens = value.split(/<(\/?(?:i|b|sc|sup|sub|span)|span .*?)>/g); tokens = tokens.map((token, index) => { if (index % 2 === 0) { return escapeValue(token); } else if (token in richTextMappings) { closingTags.push('/' + token.split(' ')[0]); return richTextMappings[token]; } else if (token === closingTags[closingTags.length - 1]) { closingTags.pop(); return '}'; } else { return ''; } }); return tokens.join(''); } function formatName(name) { if (name.family && !name.prefix && !name.given & !name.suffix) { return name.family.includes(listDelimiters.list) ? name.family : `{${name.family}}`; } const parts = ['']; if (name.prefix && name.family) { parts[0] += name.prefix + ' '; } if (name.family) { parts[0] += name.family; } if (name.suffix) { parts.push(name.suffix); parts.push(name.given || ''); } else { parts.push(name.given); } return escapeValue(parts.join(', ').trim()); } function formatTitle(title) { return formatRichText(title).split(/(:\s*)/).map((part, i) => i % 2 ? part : part.replace(/([^\\])\b([a-z]*[A-Z].*?)\b/g, '$1{$2}')).join(''); } function formatSingleValue(value, valueType) { switch (valueType) { case 'title': return formatTitle(value); case 'literal': return formatRichText(value.toString()); case 'name': return formatName(value); case 'verbatim': case 'uri': return value.toString(); default: return escapeValue(value.toString()); } } function formatList(values, valueType, listType) { const delimiter = listDelimiters[listType]; return values.map(value => { const formatted = formatSingleValue(value, valueType); return formatted.includes(delimiter) ? `{${formatted}}` : formatted; }).join(delimiter); } function formatAnnotationValue(values) { if (Array.isArray(values)) { return values.map(value => escapeValue(value).replace(/([;,"])/g, '{$1}')).join(', '); } else { return '"' + escapeValue(values).replace(/(["])/g, '{$1}') + '"'; } } function format(field, value) { if (!(field in _constants.fieldTypes)) { return formatSingleValue(value, 'verbatim'); } const [listType, valueType] = _constants.fieldTypes[field]; if (listType in listDelimiters) { return formatList(value, valueType, listType); } else { return formatSingleValue(value, valueType); } } function formatAnnotation(value) { const annotations = []; if (value.field) { annotations.push('=' + formatAnnotationValue(value.field)); } if (value.item) { for (const [itemCount, itemValue] of Object.entries(value.item)) { if (!itemValue) { continue; } const i = parseInt(itemCount) + 1; annotations.push(i + '=' + formatAnnotationValue(itemValue)); } } if (value.part) { for (const [itemCount, itemValue] of Object.entries(value.part)) { if (!itemValue) { continue; } const i = parseInt(itemCount) + 1; for (const part in itemValue) { if (!itemValue[part]) { continue; } annotations.push(i + ':' + part + '=' + formatAnnotationValue(itemValue[part])); } } } return annotations.join('; '); }