diff --git a/bootstrap.js b/bootstrap.js index 3d15aa2..7886902 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -180,6 +180,7 @@ async function install() { async function startup({ id, version, resourceURI, rootURI = resourceURI.spec }) { await waitForZotero(); + log("Starting Ze-Notes"); initPreferences(rootURI); @@ -222,6 +223,7 @@ async function startup({ id, version, resourceURI, rootURI = resourceURI.spec }) Services.scriptloader.loadSubScript(rootURI + 'core/languages.js'); Services.scriptloader.loadSubScript(rootURI + 'lib/CryptoJS 3.1.2/aes.js'); + ZeNotes.init({ id, version, rootURI }); Zotero.ZeNotes = ZeNotes; ZeNotes.addToAllWindows(); diff --git a/content/notes/format.js b/content/notes/format.js new file mode 100644 index 0000000..ba842b7 --- /dev/null +++ b/content/notes/format.js @@ -0,0 +1,262 @@ +Format = { + init() + { + this.turndownService = new TurndownService(); + this.turndownPluginGfm = TurndownPluginGfmService; + this.initturndown(); + }, + + initturndown() + { + this.turndownServiceFull = new TurndownService(); + this.turndownPluginGfm.tables(this.turndownServiceFull); + + this.turndownServiceFull.keep(['div', 'hr', 'br', 'a', 'img']); + this.turndownServiceFull.addRule('divs', { + filter: ['div'], + replacement: function (content, node) { + if(content.replace(/\s/g, '')){ + Zotero.warn(node.outerHTML); + if(node.style.cssText) + { + return "
"+content+"
"; + } + else + { + return "
"+content+"
"; + } + } + else { + return ""; + } + } + }); + + this.turndownServiceFull.addRule('spans', { + filter: ['span'], + replacement: function (content, node) { + var td = node.closest("td"); + var annotation = node.closest(".annotation"); + if(node.className=="quotation-source") + { + var url = "https://zotero/open-pdf/library/items/"+annotation.dataset.attachmentkey+"?annotation="+annotation.dataset.annotationkey; + return "["+node.innerText+"]("+url+")"; + } + else + { + return node.innerText; + } + } + }); + + this.turndownServiceFull.addRule('hrs', { + filter: ['hr'], + replacement: function (content, node) { + return "---"; + } + }); + + this.turndownServiceMin = new TurndownService(); + this.turndownPluginGfm.tables(this.turndownServiceMin); + + this.turndownServiceMin.keep(['br']); + this.turndownServiceMin.addRule('links', { + filter: ['a'], + replacement: function (content, node) { + return "["+content+"]("+node.href+")"; + } + }); + + this.turndownServiceMin.addRule('divs', { + filter: ['div'], + replacement: function (content, node) { + if(content.replace(/\s/g, '').replace(/ /g , "")) { + return "
"+content+"
"; + } + else + { + return "" + } + } + }); + + this.turndownServiceMin.addRule('hrs', { + filter: ['hr'], + replacement: function (content, node) { + return "---"; + } + }); + }, + + async process(table, typedesc, foldername, callback) + { + var contents = ""; + + if(Zotero.ZeNotes.Prefs.get("notes-add-links", false)==true) + { + this.addlink(table); + } + + if(typedesc.includes("CSV")) + { + contents = this.csv(table); + } + else if(typedesc.includes("Document")) + { + contents = this.doc(table); + } + else if(typedesc.includes("Excel")) + { + contents = this.xls(table, foldername, callback); + } + else if(typedesc.includes("Web page")) + { + if(typedesc.includes("single file")) + { + contents = this.html(table); + } + else if(typedesc.includes("complete")) + { + contents = this.html(table, foldername, callback); + } + } + else if(typedesc.includes("Markdown")) + { + if(typedesc.includes("single file")) + { + contents = this.md(table); + } + else if(typedesc.includes("complete, with HTML")) + { + contents = this.md(table, html, foldername, callback); + } + else if(typedesc.includes("complete")) + { + contents = this.md(table, false, foldername, callback); + } + else if(typedesc.includes("with HTML")) + { + contents = this.md(table, true); + } + } + return contents; + }, + + csv(table, separator=",") + { + var rows = table.querySelectorAll('tr'); + var csv = []; + for (var i = 0; i < rows.length; i++) { + var row = [], cols = rows[i].querySelectorAll('td, th'); + for (var j = 0; j < cols.length; j++) { + var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ') + data = data.replace(/"/g, '""'); + row.push('"' + data + '"'); + } + csv.push(row.join(separator)); + } + return csv.join('\n'); + }, + + xls(table, foldername, callback) + { + var template = '{table}
'; + var format = function(s, c) + { + return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }); + } + + // Execute callback: normally assets creation + if(callback) + { + var files = this.splitassets(table, foldername); + callback(files); + } + + var ctx = {worksheet:"data" || 'Worksheet', table:table.outerHTML}; + contents = format(template, ctx); + return contents; + }, + + doc(table) + { + var html = table.outerHTML; + var style = ""; + + contents = ""+style+""+html+"" + contents = contents.replace(/(background-color:#.{6})(.{2});\"/g, "$1;\""); + return contents; + }, + + html(table, foldername=null, callback=null) + { + table.style = "width: 100%; border-spacing:0;"; + table.querySelectorAll('td').forEach(td=>{ + td.style = "border: solid 1px; padding: 0.3em;"; + }); + + table.querySelectorAll('hr').forEach(hr=>{ + hr.style = "border solid 1px #efefef; width: 75%;"; + }); + + // Execute callback: normally assets creation + if(callback) + { + var files = this.splitassets(table, foldername); + callback(files); + } + contents = table.outerHTML; + return contents; + }, + + md(table, html=false, foldername=null, callback=null) + { + if(callback) + { + var files = this.splitassets(table, foldername); + callback(files); + } + if(html) + { + contents = this.turndownServiceFull.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); + } + else + { + contents = this.turndownServiceMin.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); + } + return contents; + }, + + addlink(table) + { + table.querySelectorAll('.quotation-source').forEach(annotation=>{ + var div = annotation.closest("div.annotation"); + var lnk = document.createElement("a"); + lnk.innerHTML = "🔗"; + lnk.href= "zotero://open-pdf/library/items/"+div.dataset.attachmentkey+"?annotation="+div.dataset.annotationkey; + annotation.appendChild(lnk); + }); + }, + + splitassets(table, foldername) + { + var imgs = table.querySelectorAll('img'); + var i = 1; + var files = []; + for(img of imgs) + { + let ext = img.src.split(',')[0].replace("data:image/", "").replace(";base64", ""); + let filename = "image_"+String(i).padStart(3, '0')+"."+ext; + files.push({filename: filename, data: img.src}); + img.src = "./"+(foldername+"/"+filename).split(" ").join("%20"); + i++; + } + return files; + } +} + +window.addEventListener("load", function(e){ + Format.init(); +}) \ No newline at end of file diff --git a/content/notes/io.js b/content/notes/io.js index a17b571..db7e7b9 100644 --- a/content/notes/io.js +++ b/content/notes/io.js @@ -1,299 +1,72 @@ +var { OS } = ChromeUtils.importESModule("chrome://zotero/content/osfile.mjs"); +var { FilePicker } = ChromeUtils.importESModule('chrome://zotero/content/modules/filePicker.mjs'); + Io = { + filters:{ + "Web page, HTML single file (*.html; *.htm)": "*.html; *.htm", + "Web page, complete (*.html; *.htm)": "*.html; *.htm", + "Markdown, MD single file (*.md; *.MD)": "*.md; *.MD", + "Markdown, complete (*.md; *.MD)": "*.md; *.MD", + "Markdown, MD with HTML (*.md; *.MD)": "*.md; *.MD", + "Markdown, complete, with HTML (*.md; *.MD)": "*.md; *.MD", + "CSV (*.csv)": "*.csv", + "Document (*.doc)": "*.doc", + "Excel workbook (*.xls)": "*.xls", + }, + init() { + this.currentCollection = "All documents"; var collection = Zotero.getActiveZoteroPane().getSelectedCollection(); - this.turndownService = new TurndownService(); - this.turndownPluginGfm = TurndownPluginGfmService; - this.initmd(); - this.currentCollection = "All documents"; if(collection) { this.currentCollection = collection.name; } }, - export(){ - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - fp.defaultString = "ZeNotes - "+Io.currentCollection+"."+Zotero.ZeNotes.Prefs.get("export-default-ext", "html"); - var filters = { - "Documents (*.doc)": "*.doc", - "Web page, HTML single file (*.html; *.htm)": "*.html; *.htm", - "Web page, complete (*.html; *.htm)": "*.html; *.htm", - "Markdown, MD single file (*.md; *.MD)": "*.md; *.MD", - "Markdown, complete (*.md; *.MD)": "*.md; *.MD", - "Markdown, MD with HTML (*.md; *.MD)": "*.md; *.MD", - "Markdown, complete, with HTML (*.md; *.MD)": "*.md; *.MD", - "Documents (*.xls)": "*.xls", - "CSV (*.csv)": "*.csv", - } + async export() + { + this.init(); + var title = "Export as ... "; + var fp = new FilePicker(); - for(let idx in filters) - { - fp.appendFilter(idx, filters[idx]); - } + fp.init(window, title, fp.modeSave); - fp.defaultExtension=Zotero.ZeNotes.Prefs.get("export-default-ext", "html"); fp.filterIndex = Zotero.ZeNotes.Prefs.get("export-default-filter-index", 0); - fp.init(window, "Save to file", nsIFilePicker.modeSave); - fp.open(result=>{ - if (result == fp.returnOK || result == fp.returnReplace) { - let ext = filters[Object.keys(filters)[fp.filterIndex]].split(";")[0].replace("*.", ""); - var mode1 = ""; - var mode2 = ""; - let mode = Object.keys(filters)[fp.filterIndex].replace(/\(.*\)/, "").split(/[\,\(]/); - - if(mode.length==2 && mode[1]) - { - mode1 = mode[1].trim(); - } - else if(mode.length==3 && mode[2]) - { - mode1 = mode[1].trim(); - mode2 = mode[2].trim(); - } - - Zotero.ZeNotes.Prefs.set("export-default-ext", ext); - Zotero.ZeNotes.Prefs.set("export-default-filter-index", fp.filterIndex); - var table = document.getElementById("notes-table"); - - - if(mode1=="complete" || ext.toUpperCase()=="XLS" || ext.toUpperCase()=="CSV") - { - table = this.createfiles(fp, table, ext); - } - - if(fp.file.exists()) - { - fp.file.remove(true); - } - - if(ext.toUpperCase()=="MD") - { - let markdown = ""; - if(mode1.includes("HTML") || mode2.includes("HTML")) - { - markdown = Io.turndownServiceFull.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); - } - else - { - markdown = Io.turndownServiceMin.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); - } - Zotero.File.putContentsAsync(fp.file, markdown); - } - else if(ext.toUpperCase()=="HTML") - { - Zotero.File.putContentsAsync(fp.file, table.outerHTML); - } - else if(ext.toUpperCase()=="DOC") - { - var html = table.outerHTML; - var style = ""; - - html = ""+style+""+html+"" - html = html.replace(/(background-color:#.{6})(.{2});\"/g, "$1;\""); - Zotero.File.putContentsAsync(fp.file, html); - } - else if(ext.toUpperCase()=="XLS") - { - var template = '{table}
'; - var base64 = function(s) { - return window.btoa(unescape(encodeURIComponent(s))) - } - var format = function(s, c) { - return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) - } - var ctx = {worksheet:"data" || 'Worksheet', table:table.outerHTML}; - xls = format(template, ctx); - Zotero.File.putContentsAsync(fp.file, xls); - } - else if(ext.toUpperCase()=="CSV") - { - var rows = table.querySelectorAll('tr'); - var csv = []; - var separator = ","; - for (var i = 0; i < rows.length; i++) { - var row = [], cols = rows[i].querySelectorAll('td, th'); - for (var j = 0; j < cols.length; j++) { - var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ') - data = data.replace(/"/g, '""'); - row.push('"' + data + '"'); - } - csv.push(row.join(separator)); - } - var csv_string = csv.join('\n'); - Zotero.File.putContentsAsync(fp.file, csv_string); - } - } - }) - }, - - createfiles(fp, table, fext="MD") - { - var folder = fp.file.parent.clone(); - var filename = fp.file.leafName; - var foldername = filename.substring(0, filename.lastIndexOf('.'))+"_files"; - folder.append(foldername); - if(!folder.exists()) + fp.defaultExtension = Zotero.ZeNotes.Prefs.get("export-default-ext", "html"); + + for(let idx in this.filters) { - folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + fp.appendFilter(idx, this.filters[idx]); } - var i = 1; - table = table.cloneNode(true); - table.querySelectorAll("img").forEach(img=>{ - let fileparts = img.src.split(','); - let ext = fileparts[0].replace("data:image/", "").replace(";base64", ""); - let base64 = fileparts[1]; - let filename = foldername+"_"+String(i).padStart(3, '0')+"."+ext; - let src = foldername+"/"+filename; - let imagefile = folder.clone(); - imagefile.append(filename); - this.savebinary(imagefile, img.src); - img.src = src.split(" ").join("%20"); + fp.defaultString = "ZeNotes - "+Io.currentCollection; + + var rv = await fp.show(); + if(rv == fp.returnOK || rv == fp.returnReplace) + { + var typedesc = Object.keys(this.filters)[fp.filterIndex]; + var table = document.getElementById("notes-table").cloneNode(true); - if(fext.toUpperCase()=="CSV") + var parts = fp.file.split("."); + let outputFile = fp.file; + if(parts.length>1) { - let node = document.createTextNode(", image: "+src.split(" ").join("%20")+", "); - img.parentNode.insertBefore(node, img); + parts.pop(); } - }); - - if(fext.toUpperCase()=="HTML") - { - var stylefile = folder.clone(); - stylefile.append("styles.css"); - this.savebinary(stylefile, "chrome://ze-notes/content/notes/notes.css"); + var directory = parts.join("."); + var dir_comp = OS.Path.split(directory).components; + var foldername = dir_comp[dir_comp.length-1]; + var contents = await Format.process(table, typedesc, foldername, function(files){ + Io.assets(directory, files); + }); - var html = document.createElement("html"); - var head = document.createElement("head"); - var title = document.createElement("title"); - var body = document.createElement("body"); - body.style = "width:100%;overflow:auto!important;"; + Zotero.File.putContentsAsync(outputFile, contents); - var style = document.createElement("link"); - style.href = foldername+"/styles.css"; - style.rel = "stylesheet"; - title.innerText = foldername; - html.appendChild(head); - html.appendChild(body); - head.appendChild(title); - head.appendChild(style); - body.appendChild(table); - return html; + Zotero.ZeNotes.Prefs.set("export-default-filter-index", fp.filterIndex); + Zotero.ZeNotes.Prefs.set("export-default-ext", fp.defaultExtension); } - return table; }, - - initmd() - { - Io.turndownServiceFull = new TurndownService(); - Io.turndownPluginGfm.tables(Io.turndownServiceFull); - - Io.turndownServiceFull.keep(['div', 'hr', 'br', 'a', 'img']); - Io.turndownServiceFull.addRule('divs', { - filter: ['div'], - replacement: function (content, node) { - if(content.replace(/\s/g, '')){ - Zotero.warn(node.outerHTML); - if(node.style.cssText) - { - return "
"+content+"
"; - } - else - { - return "
"+content+"
"; - } - } - else { - return ""; - } - } - }); - - Io.turndownServiceFull.addRule('spans', { - filter: ['span'], - replacement: function (content, node) { - var td = node.closest("td"); - var annotation = node.closest(".annotation"); - if(node.className=="quotation-source") - { - var url = "https://zotero/open-pdf/library/items/"+annotation.dataset.attachmentkey+"?annotation="+annotation.dataset.annotationkey; - return "["+node.innerText+"]("+url+")"; - } - else - { - return node.innerText; - } - } - }); - - Io.turndownServiceFull.addRule('hrs', { - filter: ['hr'], - replacement: function (content, node) { - return "---"; - } - }); - - Io.turndownServiceMin = new TurndownService(); - Io.turndownPluginGfm.tables(Io.turndownServiceMin); - - Io.turndownServiceMin.keep(['br']); - Io.turndownServiceMin.addRule('links', { - filter: ['a'], - replacement: function (content, node) { - return "["+content+"]("+node.href+")"; - } - }); - - Io.turndownServiceMin.addRule('divs', { - filter: ['div'], - replacement: function (content, node) { - if(content.replace(/\s/g, '').replace(/ /g , "")) { - return "
"+content+"
"; - } - else - { - return "" - } - } - }); - - Io.turndownServiceMin.addRule('hrs', { - filter: ['hr'], - replacement: function (content, node) { - return "---"; - } - }); - }, - - download(type, options=[]) - { - - if(type=="doc" || type=="html" || type=="fullhtml") - { - var table = document.getElementById("notes-table"); - this.exporthtml(table, type); - } - else if(type=="csv") - { - var table = document.getElementById("notes-table"); - this.exportcsv(table); - } - else if(type=="markdown") - { - var table = document.getElementById("notes-table"); - this.exportmarkdown(table, options); - } - else - { - var data = document.getElementById("notes-table").outerHTML; - this.exportxls(data); - } - }, - savebinary(file, url) { fetch(url) @@ -302,334 +75,18 @@ Io = { Zotero.File.putContentsAsync(file, blob); }); }, - - fullexport(table, filter, extension, formatter) + assets(directory, files) { - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - fp.defaultString = "ZeNotes - "+Io.currentCollection+"."+extension; - fp.appendFilter(...filter); - fp.defaultExtension=extension; - fp.init(window, "Save to file", nsIFilePicker.modeSave); - fp.open(result=>{ - if (result == fp.returnOK || result == fp.returnReplace) { - var folder = fp.file.parent.clone(); - var filename = fp.file.leafName; - var foldername = filename.substring(0, filename.lastIndexOf('.'))+"_files"; - folder.append(foldername); - if(!folder.exists()) - { - folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + Zotero.File.createDirectoryIfMissingAsync(directory).then(()=>{ + files.forEach(file=>{ + try { + Io.savebinary(OS.Path.join(directory, file.filename), file.data); } - - var i = 1; - table = table.cloneNode(true); - - table.querySelectorAll("img").forEach(img=>{ - let fileparts = img.src.split(','); - let ext = fileparts[0].replace("data:image/", "").replace(";base64", ""); - let base64 = fileparts[1]; - let filename = foldername+"_"+String(i).padStart(3, '0')+"."+ext; - let src = foldername+"/"+filename; - let imagefile = folder.clone(); - imagefile.append(filename); - this.savebinary(imagefile, img.src); - img.src = src.split(" ").join("%20"); - }); - - if(fp.file.exists()) + catch(e) { - fp.file.remove(true); + alert(e); } - Zotero.File.putContentsAsync(fp.file, formatter(table)); - } - }) - }, - - formathtml(table) - { - return table.outerHTML; - }, - - formatmd(table, options) - { - if(options.includes("html")) - { - let markdown = Io.turndownServiceFull.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); - return markdown; - } - else - { - let markdown = Io.turndownServiceMin.turndown(this.cleantable(table, options)).replace(/https\:\/\/zotero\//g, "zotero://"); - return markdown; - } - }, - - fullmarkdown(table, options) - { - this.fullexport( - table, - ["Markdown (*.md; *.MD)", "*.md; *.MD"], - "MD", - function(t){return Io.formatmd(t, options)} - ) - }, - - fullhtml(table) - { - this.fullexport( - table, - ["Web page (*.html; *.htm)", "*.html; *.htm"], - "html", - this.formathtml - ) - }, - - exporthtml(table, type) - { - if(type=="fullhtml") - { - table = Io.fullhtml(table); - return; - } - - html = table.outerHTML; - var style = ""; - - html = ""+style+""+html+"" - - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - - /** - Parent window - window - */ - - fp.init(window, "Save to file", nsIFilePicker.modeSave); - if(type=="doc") - { - fp.defaultString = "ZeNotes - "+Io.currentCollection+".doc"; - fp.appendFilter("Documents (*.doc)", "*.doc"); - fp.defaultExtension="doc"; - - /** - clean HTML - */ - html = html.replace(/(background-color:#.{6})(.{2});\"/g, "$1;\""); - - } - - else if(type=="html") - { - fp.defaultString = "ZeNotes - "+Io.currentCollection+".html"; - fp.appendFilter("Web page (*.html; *.htm)", "*.html; *.htm"); - fp.defaultExtension="html"; - } - - fp.open(function() - { - var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); - outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); - var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); - converter.init(outputStream, "UTF-8", 0, 0); - converter.writeString(html); - converter.close(); - outputStream.close(); - }); - }, - - cleantable(table, options=[]) - { - var newtable = table.cloneNode(true); - var children = newtable.querySelectorAll("td"); - children.forEach(td=>{ - var data = ""; - td.childNodes.forEach(c=>{ - var value = ""; - if(c.innerText!=undefined) - { - if(c.tagName=="DIV") - { - if(options.includes("style")) - { - if(options.includes("link-icon")) - { - value = "
"+c.innerText+" 🔗

"; - } - else - { - value = "
"+c.innerText+"

"; - } - } - else - { - if(options.includes("link-icon")) - { - value = "
"+c.innerText+" 🔗

"; - } - else - { - value = "
"+c.innerText+"

"; - } - } - } - else - { - value = c.innerText; - } - } - else if(c.textContent!=undefined) - { - value = c.textContent; - } - data+=value; - }); - td.innerHTML = data; - }); - return newtable; - }, - - markdown(table, options=[]) - { - Io.turndownPluginGfm.tables(Io.turndownService); - var markdown = ""; - if(options.includes("html")) - { - Io.turndownService.keep(['div', 'hr', 'br', 'a', 'img']); - Io.turndownService.addRule('divs', { - filter: ['div'], - replacement: function (content, node) { - return "
"+content+"

"; - } - }); - } - else - { - Io.turndownService.keep(['br']); - Io.turndownService.addRule('links', { - filter: ['a'], - replacement: function (content, node) { - return "["+content+"]("+node.href+")"; - } - }); - Io.turndownService.addRule('divs', { - filter: ['div', 'hr'], - replacement: function (content, node) { - return "
**"+content+"**

"; - } - }); - } - - markdown = Io.turndownService.turndown(this.cleantable(table, options)).replace(/https\:\/\/zotero\//g, "zotero://"); - return markdown - }, - - exportmarkdown(table, options=[]) - { - if(options.includes("full")) - { - this.fullmarkdown(table, options); - return; - } - - var markdown = this.markdown(table, options) - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - - fp.defaultString = "ZeNotes - "+Io.currentCollection+".md"; - fp.init(window, "Save to file", nsIFilePicker.modeSave); - fp.appendFilter("Markdown (*.md; *.MD)", "*.md; *.MD"); - fp.defaultExtension="MD"; - - fp.open(function() - { - var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); - outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); - var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); - converter.init(outputStream, "UTF-8", 0, 0); - converter.writeString(markdown); - converter.close(); - outputStream.close(); - }); - }, - - exportcsv(table) - { - var rows = table.querySelectorAll('tr'); - var csv = []; - var separator = ","; - for (var i = 0; i < rows.length; i++) { - var row = [], cols = rows[i].querySelectorAll('td, th'); - for (var j = 0; j < cols.length; j++) { - var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ') - data = data.replace(/"/g, '""'); - row.push('"' + data + '"'); - } - csv.push(row.join(separator)); - } - var csv_string = csv.join('\n'); - - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - - fp.defaultString = "ZeNotes - "+Io.currentCollection+".csv"; - fp.init(window, "Save to file", nsIFilePicker.modeSave); - fp.appendFilter("CSV (*.csv; *.txt)", "*.csv; *.txt"); - fp.defaultExtension="csv"; - - fp.open(function() - { - var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); - outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); - var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); - converter.init(outputStream, "UTF-8", 0, 0); - converter.writeString(csv_string); - converter.close(); - outputStream.close(); - }); - - }, - - exportxls(xls) - { - var uri = 'data:application/vnd.ms-excel;base64,'; - var template = '{table}
'; - var base64 = function(s) { - return window.btoa(unescape(encodeURIComponent(s))) - } - var format = function(s, c) { - return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) - } - var ctx = {worksheet: "data" || 'Worksheet', table: xls} - // xls = base64(format(template, ctx)) - xls = format(template, ctx) - - var nsIFilePicker = Components.interfaces.nsIFilePicker; - var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - - fp.defaultString = "ZeNotes - "+Io.currentCollection+".xls"; - fp.init(window, "Save to file", nsIFilePicker.modeSave); - fp.appendFilter("Documents (*.xls)", "*.xls"); - fp.appendFilter("Web page (*.csv)", "*.csv"); - fp.defaultExtension="xls"; - - - fp.open(function() - { - var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); - outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); - var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); - converter.init(outputStream, "UTF-8", 0, 0); - converter.writeString(xls); - converter.close(); - outputStream.close(); - }); - } -} - -window.addEventListener("load", function(){ - Io.init(); -}) \ No newline at end of file + }); + }); + } +} \ No newline at end of file diff --git a/content/notes/io6.js b/content/notes/io6.js new file mode 100644 index 0000000..052b03d --- /dev/null +++ b/content/notes/io6.js @@ -0,0 +1,634 @@ +Io = { + init() + { + var collection = Zotero.getActiveZoteroPane().getSelectedCollection(); + this.turndownService = new TurndownService(); + this.turndownPluginGfm = TurndownPluginGfmService; + this.initmd(); + this.currentCollection = "All documents"; + if(collection) + { + this.currentCollection = collection.name; + } + }, + + export(){ + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + fp.defaultString = "ZeNotes - "+Io.currentCollection+"."+Zotero.ZeNotes.Prefs.get("export-default-ext", "html"); + var filters = { + "Documents (*.doc)": "*.doc", + "Web page, HTML single file (*.html; *.htm)": "*.html; *.htm", + "Web page, complete (*.html; *.htm)": "*.html; *.htm", + "Markdown, MD single file (*.md; *.MD)": "*.md; *.MD", + "Markdown, complete (*.md; *.MD)": "*.md; *.MD", + "Markdown, MD with HTML (*.md; *.MD)": "*.md; *.MD", + "Markdown, complete, with HTML (*.md; *.MD)": "*.md; *.MD", + "Documents (*.xls)": "*.xls", + "CSV (*.csv)": "*.csv", + } + + for(let idx in filters) + { + fp.appendFilter(idx, filters[idx]); + } + + fp.defaultExtension=Zotero.ZeNotes.Prefs.get("export-default-ext", "html"); + fp.filterIndex = Zotero.ZeNotes.Prefs.get("export-default-filter-index", 0); + fp.init(window, "Save to file", nsIFilePicker.modeSave); + fp.open(result=>{ + if (result == fp.returnOK || result == fp.returnReplace) { + let ext = filters[Object.keys(filters)[fp.filterIndex]].split(";")[0].replace("*.", ""); + var mode1 = ""; + var mode2 = ""; + let mode = Object.keys(filters)[fp.filterIndex].replace(/\(.*\)/, "").split(/[\,\(]/); + + if(mode.length==2 && mode[1]) + { + mode1 = mode[1].trim(); + } + else if(mode.length==3 && mode[2]) + { + mode1 = mode[1].trim(); + mode2 = mode[2].trim(); + } + + Zotero.ZeNotes.Prefs.set("export-default-ext", ext); + Zotero.ZeNotes.Prefs.set("export-default-filter-index", fp.filterIndex); + var table = document.getElementById("notes-table"); + + + if(mode1=="complete" || ext.toUpperCase()=="XLS" || ext.toUpperCase()=="CSV") + { + table = this.createfiles(fp, table, ext); + } + + if(fp.file.exists()) + { + fp.file.remove(true); + } + + if(ext.toUpperCase()=="MD") + { + let markdown = ""; + if(mode1.includes("HTML") || mode2.includes("HTML")) + { + markdown = Io.turndownServiceFull.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); + } + else + { + markdown = Io.turndownServiceMin.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); + } + Zotero.File.putContentsAsync(fp.file, markdown); + } + else if(ext.toUpperCase()=="HTML") + { + Zotero.File.putContentsAsync(fp.file, table.outerHTML); + } + else if(ext.toUpperCase()=="DOC") + { + var html = table.outerHTML; + var style = ""; + + html = ""+style+""+html+"" + html = html.replace(/(background-color:#.{6})(.{2});\"/g, "$1;\""); + Zotero.File.putContentsAsync(fp.file, html); + } + else if(ext.toUpperCase()=="XLS") + { + var template = '{table}
'; + var base64 = function(s) { + return window.btoa(unescape(encodeURIComponent(s))) + } + var format = function(s, c) { + return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) + } + var ctx = {worksheet:"data" || 'Worksheet', table:table.outerHTML}; + xls = format(template, ctx); + Zotero.File.putContentsAsync(fp.file, xls); + } + else if(ext.toUpperCase()=="CSV") + { + var rows = table.querySelectorAll('tr'); + var csv = []; + var separator = ","; + for (var i = 0; i < rows.length; i++) { + var row = [], cols = rows[i].querySelectorAll('td, th'); + for (var j = 0; j < cols.length; j++) { + var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ') + data = data.replace(/"/g, '""'); + row.push('"' + data + '"'); + } + csv.push(row.join(separator)); + } + var csv_string = csv.join('\n'); + Zotero.File.putContentsAsync(fp.file, csv_string); + } + } + }) + }, + + createfiles(fp, table, fext="MD") + { + var folder = fp.file.parent.clone(); + var filename = fp.file.leafName; + var foldername = filename.substring(0, filename.lastIndexOf('.'))+"_files"; + folder.append(foldername); + if(!folder.exists()) + { + folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + } + + var i = 1; + table = table.cloneNode(true); + table.querySelectorAll("img").forEach(img=>{ + let fileparts = img.src.split(','); + let ext = fileparts[0].replace("data:image/", "").replace(";base64", ""); + let base64 = fileparts[1]; + let filename = foldername+"_"+String(i).padStart(3, '0')+"."+ext; + let src = foldername+"/"+filename; + let imagefile = folder.clone(); + imagefile.append(filename); + this.savebinary(imagefile, img.src); + img.src = src.split(" ").join("%20"); + + if(fext.toUpperCase()=="CSV") + { + let node = document.createTextNode(", image: "+src.split(" ").join("%20")+", "); + img.parentNode.insertBefore(node, img); + } + }); + + if(fext.toUpperCase()=="HTML") + { + var stylefile = folder.clone(); + stylefile.append("styles.css"); + this.savebinary(stylefile, "chrome://ze-notes/content/notes/notes.css"); + + var html = document.createElement("html"); + var head = document.createElement("head"); + var title = document.createElement("title"); + var body = document.createElement("body"); + body.style = "width:100%;overflow:auto!important;"; + + var style = document.createElement("link"); + style.href = foldername+"/styles.css"; + style.rel = "stylesheet"; + title.innerText = foldername; + html.appendChild(head); + html.appendChild(body); + head.appendChild(title); + head.appendChild(style); + body.appendChild(table); + return html; + } + return table; + }, + + initmd() + { + Io.turndownServiceFull = new TurndownService(); + Io.turndownPluginGfm.tables(Io.turndownServiceFull); + + Io.turndownServiceFull.keep(['div', 'hr', 'br', 'a', 'img']); + Io.turndownServiceFull.addRule('divs', { + filter: ['div'], + replacement: function (content, node) { + if(content.replace(/\s/g, '')){ + Zotero.warn(node.outerHTML); + if(node.style.cssText) + { + return "
"+content+"
"; + } + else + { + return "
"+content+"
"; + } + } + else { + return ""; + } + } + }); + + Io.turndownServiceFull.addRule('spans', { + filter: ['span'], + replacement: function (content, node) { + var td = node.closest("td"); + var annotation = node.closest(".annotation"); + if(node.className=="quotation-source") + { + var url = "https://zotero/open-pdf/library/items/"+annotation.dataset.attachmentkey+"?annotation="+annotation.dataset.annotationkey; + return "["+node.innerText+"]("+url+")"; + } + else + { + return node.innerText; + } + } + }); + + Io.turndownServiceFull.addRule('hrs', { + filter: ['hr'], + replacement: function (content, node) { + return "---"; + } + }); + + Io.turndownServiceMin = new TurndownService(); + Io.turndownPluginGfm.tables(Io.turndownServiceMin); + + Io.turndownServiceMin.keep(['br']); + Io.turndownServiceMin.addRule('links', { + filter: ['a'], + replacement: function (content, node) { + return "["+content+"]("+node.href+")"; + } + }); + + Io.turndownServiceMin.addRule('divs', { + filter: ['div'], + replacement: function (content, node) { + if(content.replace(/\s/g, '').replace(/ /g , "")) { + return "
"+content+"
"; + } + else + { + return "" + } + } + }); + + Io.turndownServiceMin.addRule('hrs', { + filter: ['hr'], + replacement: function (content, node) { + return "---"; + } + }); + }, + + download(type, options=[]) + { + + if(type=="doc" || type=="html" || type=="fullhtml") + { + var table = document.getElementById("notes-table"); + this.exporthtml(table, type); + } + else if(type=="csv") + { + var table = document.getElementById("notes-table"); + this.exportcsv(table); + } + else if(type=="markdown") + { + var table = document.getElementById("notes-table"); + this.exportmarkdown(table, options); + } + else + { + var data = document.getElementById("notes-table").outerHTML; + this.exportxls(data); + } + }, + + savebinary(file, url) + { + fetch(url) + .then(res => res.blob()) + .then(blob=>{ + Zotero.File.putContentsAsync(file, blob); + }); + }, + + fullexport(table, filter, extension, formatter) + { + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + fp.defaultString = "ZeNotes - "+Io.currentCollection+"."+extension; + fp.appendFilter(...filter); + fp.defaultExtension=extension; + fp.init(window, "Save to file", nsIFilePicker.modeSave); + fp.open(result=>{ + if (result == fp.returnOK || result == fp.returnReplace) { + var folder = fp.file.parent.clone(); + var filename = fp.file.leafName; + var foldername = filename.substring(0, filename.lastIndexOf('.'))+"_files"; + folder.append(foldername); + if(!folder.exists()) + { + folder.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + } + + var i = 1; + table = table.cloneNode(true); + + table.querySelectorAll("img").forEach(img=>{ + let fileparts = img.src.split(','); + let ext = fileparts[0].replace("data:image/", "").replace(";base64", ""); + let base64 = fileparts[1]; + let filename = foldername+"_"+String(i).padStart(3, '0')+"."+ext; + let src = foldername+"/"+filename; + let imagefile = folder.clone(); + imagefile.append(filename); + this.savebinary(imagefile, img.src); + img.src = src.split(" ").join("%20"); + }); + + if(fp.file.exists()) + { + fp.file.remove(true); + } + Zotero.File.putContentsAsync(fp.file, formatter(table)); + } + }) + }, + + formathtml(table) + { + return table.outerHTML; + }, + + formatmd(table, options) + { + if(options.includes("html")) + { + let markdown = Io.turndownServiceFull.turndown(table.outerHTML).replace(/https\:\/\/zotero\//g, "zotero://"); + return markdown; + } + else + { + let markdown = Io.turndownServiceMin.turndown(this.cleantable(table, options)).replace(/https\:\/\/zotero\//g, "zotero://"); + return markdown; + } + }, + + fullmarkdown(table, options) + { + this.fullexport( + table, + ["Markdown (*.md; *.MD)", "*.md; *.MD"], + "MD", + function(t){return Io.formatmd(t, options)} + ) + }, + + fullhtml(table) + { + this.fullexport( + table, + ["Web page (*.html; *.htm)", "*.html; *.htm"], + "html", + this.formathtml + ) + }, + + exporthtml(table, type) + { + if(type=="fullhtml") + { + table = Io.fullhtml(table); + return; + } + + html = table.outerHTML; + var style = ""; + + html = ""+style+""+html+"" + + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + + /** + Parent window + window + */ + + fp.init(window, "Save to file", nsIFilePicker.modeSave); + if(type=="doc") + { + fp.defaultString = "ZeNotes - "+Io.currentCollection+".doc"; + fp.appendFilter("Documents (*.doc)", "*.doc"); + fp.defaultExtension="doc"; + + /** + clean HTML + */ + html = html.replace(/(background-color:#.{6})(.{2});\"/g, "$1;\""); + + } + + else if(type=="html") + { + fp.defaultString = "ZeNotes - "+Io.currentCollection+".html"; + fp.appendFilter("Web page (*.html; *.htm)", "*.html; *.htm"); + fp.defaultExtension="html"; + } + + fp.open(function() + { + var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); + outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); + var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); + converter.init(outputStream, "UTF-8", 0, 0); + converter.writeString(html); + converter.close(); + outputStream.close(); + }); + }, + + cleantable(table, options=[]) + { + var newtable = table.cloneNode(true); + var children = newtable.querySelectorAll("td"); + children.forEach(td=>{ + var data = ""; + td.childNodes.forEach(c=>{ + var value = ""; + if(c.innerText!=undefined) + { + if(c.tagName=="DIV") + { + if(options.includes("style")) + { + if(options.includes("link-icon")) + { + value = "
"+c.innerText+" 🔗

"; + } + else + { + value = "
"+c.innerText+"

"; + } + } + else + { + if(options.includes("link-icon")) + { + value = "
"+c.innerText+" 🔗

"; + } + else + { + value = "
"+c.innerText+"

"; + } + } + } + else + { + value = c.innerText; + } + } + else if(c.textContent!=undefined) + { + value = c.textContent; + } + data+=value; + }); + td.innerHTML = data; + }); + return newtable; + }, + + markdown(table, options=[]) + { + Io.turndownPluginGfm.tables(Io.turndownService); + var markdown = ""; + if(options.includes("html")) + { + Io.turndownService.keep(['div', 'hr', 'br', 'a', 'img']); + Io.turndownService.addRule('divs', { + filter: ['div'], + replacement: function (content, node) { + return "
"+content+"

"; + } + }); + } + else + { + Io.turndownService.keep(['br']); + Io.turndownService.addRule('links', { + filter: ['a'], + replacement: function (content, node) { + return "["+content+"]("+node.href+")"; + } + }); + Io.turndownService.addRule('divs', { + filter: ['div', 'hr'], + replacement: function (content, node) { + return "
**"+content+"**

"; + } + }); + } + + markdown = Io.turndownService.turndown(this.cleantable(table, options)).replace(/https\:\/\/zotero\//g, "zotero://"); + return markdown + }, + + exportmarkdown(table, options=[]) + { + if(options.includes("full")) + { + this.fullmarkdown(table, options); + return; + } + + var markdown = this.markdown(table, options) + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + + fp.defaultString = "ZeNotes - "+Io.currentCollection+".md"; + fp.init(window, "Save to file", nsIFilePicker.modeSave); + fp.appendFilter("Markdown (*.md; *.MD)", "*.md; *.MD"); + fp.defaultExtension="MD"; + + fp.open(function() + { + var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); + outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); + var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); + converter.init(outputStream, "UTF-8", 0, 0); + converter.writeString(markdown); + converter.close(); + outputStream.close(); + }); + }, + + exportcsv(table) + { + var rows = table.querySelectorAll('tr'); + var csv = []; + var separator = ","; + for (var i = 0; i < rows.length; i++) { + var row = [], cols = rows[i].querySelectorAll('td, th'); + for (var j = 0; j < cols.length; j++) { + var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ') + data = data.replace(/"/g, '""'); + row.push('"' + data + '"'); + } + csv.push(row.join(separator)); + } + var csv_string = csv.join('\n'); + + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + + fp.defaultString = "ZeNotes - "+Io.currentCollection+".csv"; + fp.init(window, "Save to file", nsIFilePicker.modeSave); + fp.appendFilter("CSV (*.csv; *.txt)", "*.csv; *.txt"); + fp.defaultExtension="csv"; + + fp.open(function() + { + var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); + outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0 ); + var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); + converter.init(outputStream, "UTF-8", 0, 0); + converter.writeString(csv_string); + converter.close(); + outputStream.close(); + }); + + }, + + exportxls(xls) + { + var uri = 'data:application/vnd.ms-excel;base64,'; + var template = '{table}
'; + var base64 = function(s) { + return window.btoa(unescape(encodeURIComponent(s))) + } + var format = function(s, c) { + return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) + } + var ctx = {worksheet: "data" || 'Worksheet', table: xls} + // xls = base64(format(template, ctx)) + xls = format(template, ctx) + + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp =Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + + fp.defaultString = "ZeNotes - "+Io.currentCollection+".xls"; + fp.init(window, "Save to file", nsIFilePicker.modeSave); + fp.appendFilter("Documents (*.xls)", "*.xls"); + fp.appendFilter("Web page (*.csv)", "*.csv"); + fp.defaultExtension="xls"; + + fp.open(function() + { + var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream); + outputStream.init(fp.file, 0x04 | 0x08 | 0x20, 420, 0); + var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream); + converter.init(outputStream, "UTF-8", 0, 0); + converter.writeString(xls); + converter.close(); + outputStream.close(); + }); + } +} + +window.addEventListener("load", function(){ + Io.init(); +}) \ No newline at end of file diff --git a/content/notes/loader.js b/content/notes/loader.js new file mode 100644 index 0000000..42a5c5f --- /dev/null +++ b/content/notes/loader.js @@ -0,0 +1,31 @@ +Loader = { + start() + { + if (Zotero.platformMajorVersion < 102) + { + this.load("io6.js", "Io"); + } + else + { + this.load("format.js", "Format"); + this.load("io.js"); + } + }, + + load(url, object=null) + { + const script = document.createElement('script'); + script.src = url; + if(object) + { + script.onload = () => { + window[object].init(); + }; + } + document.head.appendChild(script); + } +} + +window.addEventListener("load", function(){ + Loader.start(); +}) \ No newline at end of file diff --git a/content/notes/notes.xhtml b/content/notes/notes.xhtml index e722e7f..11fc240 100644 --- a/content/notes/notes.xhtml +++ b/content/notes/notes.xhtml @@ -9,6 +9,7 @@ + @@ -19,7 +20,7 @@ - + diff --git a/content/settings/export.xhtml b/content/settings/export.xhtml new file mode 100644 index 0000000..eb45a0d --- /dev/null +++ b/content/settings/export.xhtml @@ -0,0 +1,5 @@ +
+ + +
+
diff --git a/content/settings/preferences.js b/content/settings/preferences.js index 9c05299..f44802c 100644 --- a/content/settings/preferences.js +++ b/content/settings/preferences.js @@ -303,6 +303,11 @@ Zotero_Preferences.ZeNotes = { ["paraphrase-custom-prompt", "zn-paraphrase-custom-prompt"] ]; break; + case 'export': + args = [ + ["notes-add-links", "zn-notes-add-links"] + ]; + break; case 'performance': args = [ ["load-on-change", "zn-reload-on-change"], diff --git a/content/settings/preferences.xhtml b/content/settings/preferences.xhtml index fd5999e..b4c06a1 100644 --- a/content/settings/preferences.xhtml +++ b/content/settings/preferences.xhtml @@ -45,6 +45,11 @@
+
+ Export +
+
+
Advanced
diff --git a/core/format.js b/core/format.js index 07e5194..f933e6e 100644 --- a/core/format.js +++ b/core/format.js @@ -336,7 +336,8 @@ Format = { }, creatorshortlocale(item) { - return Zotero.Items.getFirstCreatorFromData(item.itemTypeID, item.getCreators()); + var creators = Zotero.Items.getFirstCreatorFromData(item.itemTypeID, item.getCreators()); + return creators.split("\u2068").join("").split("\u2069").join(""); }, getFirstCreatorFromData(itemTypeID, creatorsData, _and, _etal, options) { @@ -372,7 +373,8 @@ Format = { ? [a.lastName, b.lastName] // \u2068 FIRST STRONG ISOLATE: Isolates the directionality of characters that follow // \u2069 POP DIRECTIONAL ISOLATE: Pops the above isolation - : [`\u2068${a.lastName}\u2069`, `\u2068${b.lastName}\u2069`]; + : [`${a.lastName}`, `${b.lastName}`]; + // : [`\u2068${a.lastName}\u2069`, `\u2068${b.lastName}\u2069`]; return args.join(_and); } if (matches.length >= 3) { diff --git a/install.rdf b/install.rdf index a8007ee..da831b0 100644 --- a/install.rdf +++ b/install.rdf @@ -5,7 +5,7 @@ zenotes@alefa.net ZeNotes - 0.8.5 + 0.8.6 true https://raw.githubusercontent.com/frianasoa/zenotes/main/zenote-update.json https://github.com/frianasoa/zenotes diff --git a/manifest.json b/manifest.json index 1171dc4..65c45e3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Ze Notes", - "version": "0.8.5", + "version": "0.8.6", "description": "Advanced notes manager", "homepage_url": "https://github.com/frianasoa/zenotes", "author": "Fanantenana Rianasoa Andriariniaina", diff --git a/zenote-update.json b/zenote-update.json index 04cd8d9..a51ada1 100644 --- a/zenote-update.json +++ b/zenote-update.json @@ -3,9 +3,9 @@ "zenotes@alefa.net": { "updates": [ { - "version": "0.8.5", - "update_link": "https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.5/zenotes-v0.8.5.xpi", - "update_hash": "sha256:b4ddddfba03f1cdea9660ebe785a3824d164657aaa0bbe01376c892b14325f9b", + "version": "0.8.6", + "update_link": "https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.6/zenotes-v0.8.6.xpi", + "update_hash": "sha256:4e7ea16353b566369ea455cb97cc0663285dce684287f9eb43d63b24d4dc3e10", "applications": { "gecko": { "strict_min_version": "60.0" diff --git a/zenote-update.rdf b/zenote-update.rdf index fe6a7ef..c0ce128 100644 --- a/zenote-update.rdf +++ b/zenote-update.rdf @@ -5,13 +5,13 @@ - 0.8.5 + 0.8.6 zotero@chnm.gmu.edu 5.0.0 6.* - https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.5/zenotes-v0.8.5.xpi + https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.6/zenotes-v0.8.6.xpi @@ -20,7 +20,7 @@ juris-m@juris-m.github.io 4.999 6.* - https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.5/zenotes-v0.8.5.xpi + https://github.com/frianasoa/Ze-Notes/releases/download/v0.8.6/zenotes-v0.8.6.xpi