zotero/translators/Note HTML.js

207 lines
6.8 KiB
JavaScript
Raw Normal View History

2024-08-27 21:48:20 -05:00
{
"translatorID": "897a81c2-9f60-4bec-ae6b-85a5030b8be5",
"translatorType": 2,
"label": "Note HTML",
"creator": "Martynas Bagdonas",
"target": "html",
"minVersion": "5.0.97",
"maxVersion": null,
"priority": 50,
"inRepository": true,
"configOptions": {
"noteTranslator": true
},
"displayOptions": {
"includeAppLinks": false
},
"lastUpdated": "2024-07-11 09:05:00"
}
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2021 Corporation for Digital Scholarship
Vienna, Virginia, USA
http://digitalscholar.org/
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 *****
*/
// Based on https://github.com/zotero/zotero/blob/32a5826a1fdcb8095e0ff6789d06dcb190212de9/chrome/content/zotero/xpcom/quickCopy.js#L266-L419
function doExport() {
Zotero.setCharacterSet('utf-8');
let item;
let doc = new DOMParser().parseFromString('<div class="zotero-notes"/>', 'text/html');
let container = doc.body.firstChild;
while ((item = Zotero.nextItem())) {
if (item.itemType === 'note' || item.itemType === 'attachment') {
let div = doc.createElement('div');
div.className = 'zotero-note';
div.innerHTML = item.note || '';
// Skip empty notes
if (!div.textContent.trim()) {
continue;
}
// Unwrap ProseMirror note metadata container
let inner = div.firstElementChild;
if (inner && inner.getAttribute('data-schema-version')) {
inner.replaceWith(...inner.childNodes);
}
container.append(div);
}
}
if (Zotero.getOption("includeAppLinks")) {
// Insert a PDF link for highlight, underline and image annotation nodes
doc.querySelectorAll('span[class="highlight"], span[class="underline"], img[data-annotation]').forEach(function (node) {
try {
var annotation = JSON.parse(decodeURIComponent(node.getAttribute('data-annotation')));
}
catch (e) {
}
if (annotation) {
// annotation.uri was used before note-editor v4
let uri = annotation.attachmentURI || annotation.uri;
let position = annotation.position;
if (typeof uri === 'string' && typeof position === 'object') {
let openURI;
let uriParts = uri.split('/');
let libraryType = uriParts[3];
let key = uriParts[uriParts.length - 1];
if (libraryType === 'users') {
openURI = 'zotero://open-pdf/library/items/' + key;
}
// groups
else {
let groupID = uriParts[4];
openURI = 'zotero://open-pdf/groups/' + groupID + '/items/' + key;
}
let linkText;
if (position.type === 'FragmentSelector') {
openURI += '?cfi=' + encodeURIComponent(position.value);
linkText = 'epub';
}
else if (position.type === 'CssSelector') {
openURI += '?sel=' + encodeURIComponent(position.value);
linkText = 'snapshot';
}
else {
openURI += '?page=' + (position.pageIndex + 1);
linkText = 'pdf';
}
if (annotation.annotationKey) {
openURI += '&annotation=' + annotation.annotationKey;
}
let a = doc.createElement('a');
a.href = openURI;
a.append(linkText);
let fragment = doc.createDocumentFragment();
fragment.append(' (', a, ') ');
let nextNode = node.nextElementSibling;
if (nextNode && nextNode.classList.contains('citation')) {
nextNode.parentNode.insertBefore(fragment, nextNode.nextSibling);
}
else {
node.parentNode.insertBefore(fragment, node.nextSibling);
}
}
}
});
// Transform citations to links
doc.querySelectorAll('span[class="citation"]').forEach(function (span) {
try {
var citation = JSON.parse(decodeURIComponent(span.getAttribute('data-citation')));
}
catch (e) {
}
if (citation && citation.citationItems && citation.citationItems.length) {
let uris = [];
for (let citationItem of citation.citationItems) {
let uri = citationItem.uris[0];
if (typeof uri === 'string') {
let uriParts = uri.split('/');
let libraryType = uriParts[3];
let key = uriParts[uriParts.length - 1];
if (libraryType === 'users') {
uris.push('zotero://select/library/items/' + key);
}
// groups
else {
let groupID = uriParts[4];
uris.push('zotero://select/groups/' + groupID + '/items/' + key);
}
}
}
let items = Array.from(span.querySelectorAll('.citation-item')).map(x => x.textContent);
// Fallback to pre v5 note-editor schema that was serializing citations as plain text i.e.:
// <span class="citation" data-citation="...">(Jang et al., 2005, p. 14; Kongsgaard et al., 2009, p. 790)</span>
if (!items.length) {
items = span.textContent.slice(1, -1).split('; ');
}
span.innerHTML = '(' + items.map((item, i) => `<a href="${uris[i]}">${item}</a>`).join('; ') + ')';
}
});
}
// Remove annotation and citation data
ZU.xpath(doc, '//span[@data-citation]').forEach(span => span.removeAttribute('data-citation'));
ZU.xpath(doc, '//span[@data-annotation]').forEach(span => span.removeAttribute('data-annotation'));
ZU.xpath(doc, '//img[@data-annotation]').forEach(img => img.removeAttribute('data-annotation'));
// Add horizontal rules between notes
Array.from(container.children).slice(1).forEach((element) => {
container.insertBefore(doc.createElement('hr'), element);
});
// Add quotes around blockquote paragraphs
// Open quote
ZU.xpath(doc, '//blockquote/p[1]').forEach((element) => {
element.insertBefore(doc.createTextNode('\u201c'), element.firstChild);
});
// End quote
ZU.xpath(doc, '//blockquote/p[last()]').forEach((element) => {
element.appendChild(doc.createTextNode('\u201d'));
});
// Everything seems to like margin-left better than padding-left
Zotero.Utilities.xpath(doc, 'p').forEach((p) => {
if (p.style.paddingLeft) {
p.style.marginLeft = p.style.paddingLeft;
p.style.paddingLeft = '';
}
});
// Word and TextEdit don't indent blockquotes on their own and need this
// OO gets it right, so this results in an extra indent
ZU.xpath(doc, '//blockquote/p').forEach(p => p.style.marginLeft = '30px');
let charsetMeta = doc.createElement('meta');
charsetMeta.setAttribute('charset', 'utf-8');
doc.head.append(charsetMeta);
Zotero.write('<!DOCTYPE html>' + doc.documentElement.outerHTML);
}