Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Item] Embed item notes by note-tag #198

Closed
sjgknight opened this issue Oct 30, 2022 · 4 comments
Closed

[Item] Embed item notes by note-tag #198

sjgknight opened this issue Oct 30, 2022 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@sjgknight
Copy link

Template Type

Item

Desired Template Performance

As in #177 (comment) I am hoping to create a template where:

  1. User selects parent items or/and notes
  2. Dialogue asks for tags to select separated by ,
  3. Template is populated by ##Tag ## Parent item title; ## Note embed (including images and full quote text)

This could be similar to inserting the item-notes with metadata template into the [Item] collect annotations and notes by tag loop. My confusion with the [Item] collect annotations and notes by tag is that the screenshots seem to suggest that quoted text and images would be embedded, but actually I got the links.

Current Template

The [Item] collect annotations and notes by tag and item-notes with metadata get me part way. I'm not familiar with JS so there's a syntax error in this, but I think the broad structure should be right

// @beforeloop-begin
${(()=>{
sharedObj.tagRaw = prompt("Please input tags. Split with ',':", "");
return "";
})()}
// @beforeloop-end
// @default-begin
${await new Promise(async (r) => {
  async function getAnnotation(item) {
    try {
      if (!item || !item.isAnnotation()) {
        return null;
      }
      let json = await Zotero.Annotations.toJSON(item);
      json.id = item.key;
      delete json.key;
      for (let key in json) {
        json[key] = json[key] || "";
      }
      json.tags = json.tags || [];
      return json;
    } catch (e) {
      Zotero.logError(e);
      return null;
    }
  }
  async function getAnnotationsByTag(_item, tag) {
    let annots = _item.getAnnotations();
    annots = tag.length? 
      annots.filter((_annot) => _annot.getTags().map(_t=>_t.tag).includes(tag)) :
      annots;
    let annotations = [];
    for (let annot of annots) {
      const annotJson = await getAnnotation(annot);
      annotJson.attachmentItemID = _item.id;
      annotations.push(annotJson);
    }
    if (!editor) {
      alert("No active note editor detected. Please open workspace.");
      return r("");
    }
    await editor.importImages(annotations);
    return Zotero.EditorInstanceUtilities.serializeAnnotations(annotations);
  }
  const attachments = Zotero.Items.get(topItem.getAttachments()).filter((i) =>
    i.isPDFAttachment()
  );
  let res = "";
  if(!sharedObj.tagRaw){
    return;
  }
  res += `<h1>${topItem.getField('title')}</h1>`;
  for (let attachment of attachments) {
	res += `<h2>${attachment.attachmentFilename}</h2>`;
    for(tag of sharedObj.tagRaw.split(',').filter(t=>t.length)){
      res += `<h3>Tag: ${tag}</h3>`;
      const tags = (await getAnnotationsByTag(attachment, tag)).html
      res += tags ? tags : "<p>No result</p>";
    }
  }
  res += `<h2>Notes</h2>`;
  const notesWithTags = `${itemNotes.filter(noteItem=>{
    for(tag of sharedObj.tagRaw.split(',').filter(t=>t.length)){
      if(noteItem.getTags().map(_t=>_t.tag).includes(tag)){
        return true;
}
}
return false;
}).map((noteItem)=>{
const noteLine = `<p style="color:red; background-color: #efe3da;">📜 Article Note:  <a href="${Zotero.Knowledge4Zotero.knowledge.getNoteLink(noteItem)
}" rel="noopener noreferrer nofollow">${noteItem.getNoteTitle()?noteItem.getNoteTitle():Zotero.Knowledge4Zotero.knowledge.getNoteLink(noteItem)}</a></p>
<p>tags: ${noteItem.getTags().map(_t=>_t.tag).join(', ')}</p>
<p> </p>`;
<blockquote>
    ${noteItem.getNote()}
    <p style="background-color: pink;"><strong>Merge Date: </strong> ${new Date().toISOString().substr(0,10)+" "+ new Date().toTimeString()}</p>
</blockquote>
<p style="color:red; background-color: #efe3da;"><strong>📝 Comments</strong></p>
<blockquote>
    <p>Make your comments</p>
    <p></p>
</blockquote>`;
copyNoteImage(noteItem);
return noteLine;
}).join("\n")}`
res += notesWithTags  ? notesWithTags  : '<p>No result</p>'
  r(res);
})}
// @default-end
@sjgknight sjgknight added the help wanted Extra attention is needed label Oct 30, 2022
@windingwind
Copy link
Owner

I'm a little bit too busy... Please wait for several more days.

@sjgknight
Copy link
Author

@windingwind absolutely, no reasonable expectation of speedy (or, any) turnaround for a request for help :-). I will also try to look at it again

@sjgknight
Copy link
Author

I think this does what I wanted. It collects item notes and annotations (I think; all my annotations are already in notes) by tag. As you noticed before, to work, it does need to be run on top-level items so it won't work on the 'search' output where it lets you select the directly tagged notes.

I may now try to create two other versions (1) that outputs filtered data (so, if nothing is tagged, exclude the item); or/and (2) a mod of the 'collect annotations by tag separately' so I can collect all annotation and note content for a set of items by tag.

#[Item] collect annotations and note content by tag

// @beforeloop-begin
${(()=>{
sharedObj.tagRaw = prompt("Please input tags. Split with ',':", "");
return "";
})()}
// @beforeloop-end
// @default-begin
${await new Promise(async (r) => {
  async function getAnnotation(item) {
    try {
      if (!item || !item.isAnnotation()) {
        return null;
      }
      let json = await Zotero.Annotations.toJSON(item);
      json.id = item.key;
      delete json.key;
      for (let key in json) {
        json[key] = json[key] || "";
      }
      json.tags = json.tags || [];
      return json;
    } catch (e) {
      Zotero.logError(e);
      return null;
    }
  }
  async function getAnnotationsByTag(_item, tag) {
    let annots = _item.getAnnotations();
    annots = tag.length? 
      annots.filter((_annot) => _annot.getTags().map(_t=>_t.tag).includes(tag)) :
      annots;
    let annotations = [];
    for (let annot of annots) {
      const annotJson = await getAnnotation(annot);
      annotJson.attachmentItemID = _item.id;
      annotations.push(annotJson);
    }
    if (!editor) {
      alert("No active note editor detected. Please open workspace.");
      return r("");
    }
    await editor.importImages(annotations);
    return Zotero.EditorInstanceUtilities.serializeAnnotations(annotations);
  }
  const attachments = Zotero.Items.get(topItem.getAttachments()).filter((i) =>
    i.isPDFAttachment()
  );
  let res = "";
  if(!sharedObj.tagRaw){
    return;
  }
  res += `<h1>${topItem.getField('title')}</h1>`;
  for (let attachment of attachments) {
    res += `<h2>${attachment.getFilename()}</h2>`;
    for(tag of sharedObj.tagRaw.split(',').filter(t=>t.length)){
      res += `<h3>Tag: ${tag}</h3>`;
      const tags = (await getAnnotationsByTag(attachment, tag)).html
      res += tags ? tags : "<p>No result</p>";
    }
  }
  res += `<h2>Notes</h2>`;
  const notesWithTags = `${itemNotes.filter(noteItem=>{
    for(tag of sharedObj.tagRaw.split(',').filter(t=>t.length)){
      if(noteItem.getTags().map(_t=>_t.tag).includes(tag)){
        return true;
}
}
return false;
}).map((noteItem)=>{
const noteLine = `<p style="color:red; background-color: #efe3da;">📜 Article Note:  <a href="${Zotero.Knowledge4Zotero.knowledge.getNoteLink(noteItem)
}" rel="noopener noreferrer nofollow">${noteItem.getNoteTitle()?noteItem.getNoteTitle():Zotero.Knowledge4Zotero.knowledge.getNoteLink(noteItem)}</a></p>
<blockquote>
    ${noteItem.getNote()}
    <p style="background-color: pink;"><strong>Merge Date: </strong> ${new Date().toISOString().substr(0,10)+" "+ new Date().toTimeString()}</p>
</blockquote>
<p>tags: ${noteItem.getTags().map(_t=>_t.tag).join(', ')}</p>
<p> </p>`;
copyNoteImage(noteItem);
return noteLine;
}).join("\n")}`
res += notesWithTags  ? notesWithTags  : '<p>No result</p>'
  r(res);
})}
// @default-end

@windingwind
Copy link
Owner

Glad to know it works! Sorry for the late reply.
Please let me know if you need help anytime.

@windingwind windingwind changed the title [Note Template] Embed item notes by note-tag [Item] Embed item notes by note-tag Nov 28, 2022
Repository owner locked and limited conversation to collaborators Nov 28, 2022
@windingwind windingwind converted this issue into discussion #251 Nov 28, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants