Are functions allowed in the scripts? #370
-
Hey everybody, i have been using the "Open Link" script from here #115 (comment) to be able to copy links. But I need a slightly different behavior to make full use of it in LogSeq. I want the link to look something link: Therefore just two quick question to verify: 1. Are functions supported in the scripts? 2. Is there any additional debug information, like Stack Traces, lines of the scripts with the error, ... available? Here is the adopted script. I just indented the block, surrounded a function and added a // @author windingwind, garth74
// @link https://github.com/windingwind/zotero-actions-tags/discussions/115
// @usage Select an item in the library and press the assigned shortcut keys
// @update Mon, 22 Jan 2024 00:10:18 GMT (by new Date().toGMTString())
// EDIT THESE SETTINGS
/** @type {string} Name of the field to use as the link text. To use the citation key, set this to "citationKey". */
let linkTextField = "citationKey";
/** @type {'html' | 'md' | 'plain'} What type of link to create. */
let linkType = "md";
/** @type {boolean} If true, make the link specific to the currently selected collection. */
let useColl = false;
/** @type {boolean} If true, use Better Notes zotero://note link when the selected item is a note. */
let useNoteLink = false;
/** @type {'select' | 'open-pdf' | 'auto'} Action of link*/
let linkAction = "auto"; // auto = open-pdf for PDFs and annotations, select for everything else
// END OF EDITABLE SETTINGS
// For efficiency, only execute once for all selected items
if (item) return;
item = items[0];
if (!item && !collection) return "[Copy Zotero Link] item is empty";
if (collection) {
linkAction = "select";
useColl = true;
}
if (linkAction === "auto") {
if (item.isPDFAttachment() || item.isAnnotation()) {
linkAction = "open-pdf";
} else {
linkAction = "select";
}
}
function getUri(linkAction){
const uriParts = [];
let uriParams = "";
let targetItem = item;
if (linkAction === "open-pdf") {
uriParts.push("zotero://open-pdf");
if (item.isRegularItem()) {
targetItem = (await item.getBestAttachments()).find((att) =>
att.isPDFAttachment()
);
} else if (item.isAnnotation()) {
targetItem = item.parentItem;
// If the item is an annotation, we want to open the PDF at the page of the annotation
let pageIndex = 1;
try {
pageIndex = JSON.parse(item.annotationPosition).pageIndex + 1;
} catch (e) {
Zotero.warn(e);
}
uriParams = `?page=${pageIndex}&annotation=${item.key}`;
}
} else {
uriParts.push("zotero://select");
if (item?.isAnnotation()) {
targetItem = item.parentItem;
}
}
if (!targetItem && !collection) return "[Copy Zotero Link] item is invalid";
// Get the link text using the `link_text_field` argument
let linkText;
if (collection) {
// When `collection` is truthy, this script was triggered in the collection menu.
// Use collection name if this is a collection link
linkText = collection.name;
} else if (item.isAttachment()) {
// Try to use top-level item for link text
linkText = Zotero.Items.getTopLevel([item])[0].getField(linkTextField);
} else if (item.isAnnotation()) {
// Add the annotation text to the link text
linkText = `${targetItem.getField(linkTextField)}(${
item.annotationComment || item.annotationText || "annotation"
})`;
} else {
// Use the item's field
linkText = item.getField(linkTextField);
}
// Add the library or group URI part (collection must go first)
let libraryType = (collection || item).library.libraryType;
if (libraryType === "user") {
uriParts.push("library");
} else {
uriParts.push(
`groups/${Zotero.Libraries.get((collection || item).libraryID).groupID}`
);
}
// If useColl, make the link collection specific
if (useColl) {
// see https://forums.zotero.org/discussion/73893/zotero-select-for-collections
let coll = collection || Zotero.getActiveZoteroPane().getSelectedCollection();
// It's possible that a collection isn't selected. When that's the case,
// this will fall back to the typical library behavior.
// If a collection is selected, add the collections URI part
if (!!coll) uriParts.push(`collections/${coll.key}`);
}
if (!collection) {
// Add the item URI part
uriParts.push(`items/${targetItem.key}`);
}
// Join the parts together
let uri = uriParts.join("/");
// Add the URI parameters
if (uriParams) {
uri += uriParams;
}
if (useNoteLink && item?.isNote() && Zotero.BetterNotes) {
uri = Zotero.BetterNotes.api.convert.note2link(item);
}
return uri;
}
let uri = getUri(linkAction);
// Format the link and copy it to the clipboard
const clipboard = new Zotero.ActionsTags.api.utils.ClipboardHelper();
if (linkType == "html") {
clipboard.addText(`<a href="${uri}">${linkText}</a>`, "text/unicode");
} else if (linkType == "md") {
clipboard.addText(`[${linkText}](${uri})`, "text/unicode");
} else {
clipboard.addText(uri, "text/unicode");
}
clipboard.addText(`<a href="${uri}">${linkText}</a>`, "text/html");
clipboard.copy();
return `[Copy Zotero Link] link ${uri} copied.`; |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Yes. The error presumably comes from
You can log things to Import the console object using |
Beta Was this translation helpful? Give feedback.
-
In cases someone is interested in the solution find the script below. // @author windingwind, garth74
// @link https://github.com/windingwind/zotero-actions-tags/discussions/115
// @usage Select an item in the library and press the assigned shortcut keys
// @update Mon, 22 Jan 2024 00:10:18 GMT (by new Date().toGMTString())
// EDIT THESE SETTINGS
/** @type {string} Name of the field to use as the link text. To use the citation key, set this to "citationKey". */
let linkTextField = "citationKey";
/** @type {'html' | 'md' | 'plain' | 'logseq' } What type of link to create. */
let linkType = "logseq";
/** @type {boolean} If true, make the link specific to the currently selected collection. */
let useColl = false;
/** @type {boolean} If true, use Better Notes zotero://note link when the selected item is a note. */
let useNoteLink = false;
/** @type {'select' | 'open-pdf' | 'auto'} Action of link*/
let linkAction = "auto"; // auto = open-pdf for PDFs and annotations, select for everything else
// END OF EDITABLE SETTINGS
// For efficiency, only execute once for all selected items
if (item) return;
item = items[0];
if (!item && !collection) return "[Copy Zotero Link] item is empty";
if (collection) {
linkAction = "select";
useColl = true;
}
async function getTargetItem(linkAction){
let targetItem = item;
if (linkAction === "open-pdf") {
if (item.isRegularItem()) {
targetItem = (await item.getBestAttachments()).find((att) =>
att.isPDFAttachment()
);
} else if (item.isAnnotation()) {
targetItem = item.parentItem;
}
} else { // linkAction === "select"
if (item?.isAnnotation()) {
targetItem = item.parentItem;
} else {
targetItem = item
}
}
return targetItem
}
async function getUri(linkAction){
if (linkAction === "auto") {
if (item.isPDFAttachment() || item.isAnnotation()) {
linkAction = "open-pdf";
} else {
linkAction = "select";
}
}
const uriParts = [];
let uriParams = "";
let targetItem = await getTargetItem(linkAction)
if (linkAction === "open-pdf") {
uriParts.push("zotero://open-pdf");
if (item.isAnnotation()) {
// If the item is an annotation, we want to open the PDF at the page of the annotation
let pageIndex = 1;
try {
pageIndex = JSON.parse(item.annotationPosition).pageIndex + 1;
} catch (e) {
Zotero.warn(e);
}
uriParams = `?page=${pageIndex}&annotation=${item.key}`;
}
} else { // linkAction === "select"
uriParts.push("zotero://select");
}
if (!targetItem && !collection) return "[Copy Zotero Link] item is invalid";
// Add the library or group URI part (collection must go first)
let libraryType = (collection || item).library.libraryType;
if (libraryType === "user") {
uriParts.push("library");
} else {
uriParts.push(
`groups/${Zotero.Libraries.get((collection || item).libraryID).groupID}`
);
}
// If useColl, make the link collection specific
if (useColl) {
// see https://forums.zotero.org/discussion/73893/zotero-select-for-collections
let coll = collection || Zotero.getActiveZoteroPane().getSelectedCollection();
// It's possible that a collection isn't selected. When that's the case,
// this will fall back to the typical library behavior.
// If a collection is selected, add the collections URI part
if (!!coll) uriParts.push(`collections/${coll.key}`);
}
if (!collection) {
// Add the item URI part
uriParts.push(`items/${targetItem.key}`);
}
// Join the parts together
let uri = uriParts.join("/");
// Add the URI parameters
if (uriParams) {
uri += uriParams;
}
if (useNoteLink && item?.isNote() && Zotero.BetterNotes) {
uri = Zotero.BetterNotes.api.convert.note2link(item);
}
return uri;
}
let uriAuto = await getUri(linkAction);
let uriOpenPdf = await getUri('open-pdf');
let uriSelect = await getUri('select');
// Get the link text using the `link_text_field` argument
let linkText;
if (collection) {
// When `collection` is truthy, this script was triggered in the collection menu.
// Use collection name if this is a collection link
linkText = collection.name;
} else if (item.isAttachment()) {
// Try to use top-level item for link text
linkText = Zotero.Items.getTopLevel([item])[0].getField(linkTextField);
} else if (item.isAnnotation()) {
// Add the annotation text to the link text
let targetItem = item.parentItem;
linkText = `${targetItem.getField(linkTextField)}(${
item.annotationComment || item.annotationText || "annotation"
})`;
} else {
// Use the item's field
linkText = item.getField(linkTextField);
}
// Format the link and copy it to the clipboard
const clipboard = new Zotero.ActionsTags.api.utils.ClipboardHelper();
if (linkType == "html") {
clipboard.addText(`<a href="${uriAuto}">${linkText}</a>`, "text/unicode");
} else if (linkType == "md") {
clipboard.addText(`[${linkText}](${uriAuto})`, "text/unicode");
} else if (linkType == "logseq") {
if (item.isAnnotation()) {
// Try to use top-level item for link text
linkText = Zotero.Items.getTopLevel([item])[0].getField(linkTextField);
// Add the annotation text to the link text
let targetItem = item.parentItem;
annotationText = `#+BEGIN_QUOTE
*${
item.annotationComment || item.annotationText || "annotation"
}*\n`;
clipboard.addText(`${annotationText} — [[${linkText}]] [[item](${uriSelect})] [[pdf](${uriOpenPdf})]\n#+END_QUOTE`, "text/unicode");
} else {
clipboard.addText(`[[${linkText}]] [[item](${uriSelect})] [[pdf](${uriOpenPdf})]`, "text/unicode");
}
} else {
clipboard.addText(uriAuto, "text/unicode");
}
clipboard.copy();
return `[Copy Zotero Link] link copied.`; |
Beta Was this translation helpful? Give feedback.
Yes. The error presumably comes from
getUri
being a sync function while you use an async syntaxawait ...
inside it.You can log things to
console
(e.g. console.log or console.trace) as in browsers. Open console from Tools - Developer - Error Console.Import the console object using
const console = require("console")
.