Zotero Integration – Import Templates?

No, I don’t have any special CSS going on. I think there are three factors, which may be at play:

  1. Each highlight has a preceding comment in that screenshot. That makes it more separated.
  2. I think the theme makes a big difference. When I test out my template with different themes, the spacing changes a lot. Minimal and AnuPpuccin seem particularly condensed.
  3. Live-preview has less spacing than Reading mode.

Here’s a comparison between Polka, AnuPpuccin and Minimal, in that order:



You can isolate the CSS change to your Zotero imports by using a cssclass and putting it into the yaml of your Literature note template: cssclass: literature-note (for example).

And in the css file, the css should start with .literature-note .theactualcss {

Could you share your css to add spacing between list items?

Yeah, same here, but thanks for sharing. I see many of the same dilemmas myself.

OMG! I’ve been trying to solve this forever, so thanks a lot for informing me. I was so excited that I rushed to share it in the #academia Discord channel as well, crediting you (forum user tophee) and the github user.

Oh, well, I’m learning a lot here. So it’s just a parameter :slight_smile:

Seems like a nice fix. I assume it matches the first option first, so there won’t be conflicts?

Well, if you decide not to have comments as bullets, then I guess it’s not necessary to indent the highlight anymore?

Yeah, it was just a quick test. Since you’re already modifying the plugin, maybe you could trigger it with > instead :wink:

I think it is not recommended to use two spaces for indentation: Markdown indentation | New Relic Documentation

You could request this as an option on Github.

As far as I can see I have figured out how to have persistent annotations. In the latest version you can import from zotero, edit the annotations, and they will not get overwritten (unless you edit them in zotero, obviously)

Caveat, the template must make the initial checkout from zotero, so you must remove / rename the previous checkout (once).

zotero template gist

1 Like

Sorry for not understanding, but how is this different from basic persistent annotations?
Can you append individual new annotations using your template?

Every annotation is separate, the order is correct, it removes annotations that get removed on zotero
You can add notes to individual annotations.
It is still a work in progress, but seems to work

Okay, sounds quite interesting. But what I don’t understand is how this can work, if it requires that you rename or remove your previous import. How can you persist your notes that way? Or does this just apply if the note was made with another template before?

Does this mean that every annotation has persist fields surrounding it?

I guess the main advantage of your approach is the ability to insert new annotations under the right heading, without duplicating the heading?

My confusion was in your macro (and in my head), not Line Callouts. Your symbols were arbitrary given the headings which threw me (e.g., @ for questions instead of ?, #ff6666 matched to £ instead of !, etc). Which, given what I say below about DV, it’s probably a better idea not to use common symbols.

But, any streamlining of Zotero/Obsidian process is appreciated given the formatting decisions that have to be made in addition to all the fiddling.

Oh, the Line Callout plugin’s icon picker is tiresome, isn’t it?

As @Feralflora suggested for spacing between list items in literature notes, you can put cssclass: literature-note in the YAML of the template. Then add this CSS snippet:

.literature-note {
  --list-spacing: 0.3em; /* default 0.075em; */
}

or you can add the list item spacing across your entire vault with:

:root body {
  --list-spacing: 0.3em; /* default 0.075em; */
}

I use the Minimal theme and these both work for me.

By the way, something to consider if you’re thinking about not using list items and using callouts instead is Dataview usage. In fact, list items, tasks, and headings are the reason why I found @Feralflora’s template so useful.

Using DV, you can:

  • show all list items under a specific heading across research papers (e.g., to examine methods across papers)
  • show all list items with a certain word (e.g., to see all annotations with the same reference)
  • show all list items with a certain tag? Yep.
  • with the line callouts plugin symbols - show all list items of type with a certain word.

All of this without specifying any inline metadata.

Example - show all method-type list items with a phrase:

LIST L.text
FROM "in/papers"
FLATTEN file.lists AS L
WHERE icontains(L.text, "@") and icontains(L.text, "hierarchical cluster analysis")

With all annotations and notes as normal text, you can’t do any of this so easily.

5 Likes

Sorry, bad explanation, you need to remove the old page once, then the template takes over, it only updates annotations, but annotations made with a previous template will not be persistent.

Yes, it every annotation has persistent fields. Combined with static block-ids, it’s possible to really use the annotations in other notes, which is the goal of the template

If I re-import the notes from zotero to obsidian, the previously imported notes will lose the reference (block id) and all other notes created in obsidian will also lose the reference to the notes imported from zotero. Is this solved with your template?
My purpose is not to lose the references to the notes that I import from zotero (highlights and notes) even when I import them again.
I have tried your template and it doesn’t work for that purpose. I know absolutely nothing about coding. However, I have an idea to fix this. I have noticed that when one references a note or a note title, the format ([[name#title]]) is not altered unlike referencing a block ([[name^12345 ]]). So what I would like to do is create a title for each highlight and note that imports from zotero and the title is identified by the first 10 (or any number) letters of the highlight in case it was a text highlight or the first 10 letters of the note of the highlighted image. Obviously, the coding for this must allow generating the title with that pattern automatically. In this way, each note imported from zotero will have an identification that will be preserved even if you delete or import them again, since the references to those notes will be maintained ([[name#abcde]])
image

image
I was wondering if you could help me with the coding of the template the way I’m setting it up.
I don’t speak english so I’m using google translate

i got this. This way I can keep references to zotero highlights being imported into obsidian no matter they are removed and updated:
{% for entry in annotations -%}
{%- if entry.annotatedText -%} # {{entry.annotatedText | truncate(15, true,“”)}}
{{entry.annotatedText}}
{%- if entry.id %} ^{{entry.id | replace(entry.id, entry.annotatedText | replace(" “,”“) | truncate(15, true,”"))}}
{% endif %}
{%- endif %}
{% endfor -%}

It’s not clear who you were replying to, since you didn’t make the comment as a reply to anyone in particular. I assume you were testing @Qwxlea’s template?

Yeah, i was testing @Qwxlea template.

Hey there Frealflora

Thank you so much for a wonderful template, which I like to use. Unfortunately I don’t have much programming expirience and there is one question, that bothers me though, and that I can’t get around with: How do you edit the template, so you can set the order of colors? For example: I would like to have my blue higlights coming first, then my yellow ones etc.etc…

I tried to set that order in the begining, but it doesn’t really work that way :see_no_evil:

Hey @bilderer,
Thanks for the feedback, I am glad you are liking my template! As is, you can’t change the order of the colors.
They will be in order of appearance. As I’ve written under “Planned enhancements”, I am going to incorporate this at some point, but it requires some modification:

Btw, if you tag me with an @FeralFlora, I will get notified, so you might get a quicker response (although this time, I happened to see it quickly).

1 Like

Thank you so much! This has been so useful for me.

Perhaps not a query you have needed to consider but I have found myself importing notes/highlights etc. from book pdfs. The challenge I am facing is on each import my hard work of separating annotations into their respective chapters is undone and needed again.

I have tried to search the forums and web for a work around but I am unsure I will be able to?

Hello everyone! Figured I would share my template after I spent maybe a little toooooo long on it! Shout out to @Feralflora @Qwxlea @apfelstrudelig as I mainly referenced their templates as a jumping off point.
Template:

---
aliases: 
- {{title | upper}}
- "@{{citekey}}"
year: {{date | format("YYYY")}}
related: 
{%- for r in relations %}
- {{r.citekey}}
{%- endfor %}
---
{#- This is the order in which the annotations are ordered -#}
{%-
   set categoryHeading = {
        "yellow":  "Summary, Definitions, Concepts",
        "red":     "Purpose, Hypothesis, Aim, Conclusion",
        "green":   "Methodology",
        "blue":    "Results",
        "purple":  "Connections, Agree, Disagree",
        "magenta": "Future Implications & Research Ideas",
		"orange":  "Misc Thoughts & Info to Follow Up",
		"gray":    "References to Follow Up"
   }
-%}
{%-
    set zoteroColors = {
        "#ffd400": "yellow",
        "#ff6666": "red",
        "#5fb236": "green",
        "#2ea8e5": "blue",
        "#a28ae5": "purple",
        "#e56eee": "magenta",
        "#f19837": "orange",
        "#aaaaaa": "gray"
    }
-%}
{%-
    set zoteroStrings = {
        "sm": "sm",
        "df": "&df",
        "pr": "!pr",
        "am": "!am",
        "hp": "!hp",
        "cg": "!cg",
        "cb": "!cb",
        "sb": "$sb",
        "pt": "$pt",
        "in": "$in",
        "ms": "$ms",
        "sa": "$sa",
        "ot": "$ot",
        "rs": "@rs",
        "lc": "~lc",
        "la": "~la",
        "ld": "~ld",
        "pc": "~pc",
        "pa": "~pa",
        "pd": "~pd",
        "fi": ";fi",
        "ri": ";ri",
        "mt": "?mt",
        "fu": "?fu",
        "rf": "%rf"
    }
-%}
{#- handle | characters in zotero strings used in MD -#}
{%- macro formatCell(cellText) -%}
	{{ cellText | replace("|","❕")}}
{%- endmacro -%}

{#- Macros for handling annotations -#}
{%- macro formatAnnotation(annotation, calloutString) -%}
	{%- if annotation.imageRelativePath -%}
- {{calloutString}} ![[{{annotation.imageRelativePath}}]] [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(2) | trim | length > 0 %}
	- {{annotation.comment.substring(2) | trim}}
{% else %}
{% endif -%}
	{%- elif annotation.comment.substring(2, 3) === "-" -%}
- {{calloutString}} {{annotation.annotatedText}} 
	{%- elif annotation.comment.substring(2, 3) === "+" %} {{annotation.annotatedText}} [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(3) | trim | length > 0 %}
	- {{annotation.comment.substring(3) | trim}}
{% else %}
{% endif -%}
	{%- elif annotation.annotatedText -%}
- {{calloutString}} {{annotation.annotatedText}} [Zotero, p. {{annotation.pageLabel}}](zotero://open-pdf/library/items/{{annotation.attachment.itemKey}}?page={{annotation.page}}&annotation={{annotation.id}}){% if annotation.hashTags %} {{annotation.hashTags}}{% endif %} ^{{annotation.id-}}
{% if annotation.comment.substring(2) | trim | length > 0 %}
	- {{annotation.comment.substring(2) | trim}}
{% else %}
{% endif -%}
	{%- endif -%}
{%- endmacro %}
# {{title}}

> [!info]+ Info [Zotero]({{desktopURI}}) | {%- for attachment in attachments | filterby("path", "endswith", ".pdf") %} [PDF](zotero://open-pdf/library/items/{{attachment.itemKey}}){%- endfor %}{% if DOI %} | [DOI:{{DOI}}](http://doi.org/{{DOI}}){% elif ISBN %} | ISBN: {{ISBN}}{% endif %}{%if url %} | [URL]({{url}}){% endif %}
> 
> **Bibiography:** {{bibliography}}
> 
> **Authors::** {% for a in creators %} [[{{a.firstName}} {{a.lastName}}]]{% if not loop.last %}, {% endif %}{% endfor %}
> 
> **Journal::** {{publicationTitle}}
> 
> **Ztags::**{% for t in tags %} [[{{t.tag}}]]{% if not loop.last %}, {% endif %}{% endfor %}
> 
> **First-page**: {% for annotation in annotations %}{% if loop.first %}{{annotation.pageLabel}}{% endif %}{% endfor %}

{%- if relations.length > 0 %}
{{ "" }}
> [!summary]+ Related Zotero items ({{ relations.length}}):  
>
> | title | Literature Note | Links |
> | --- | --- | --- |
{%- for r in relations %}
> | {{formatCell(r.title)}} | [[{{r.citekey}}]] | [Zotero]({{r.desktopURI}}){%- for rAttachment in r.attachments | filterby("path", "endswith", ".pdf") %} [PDF](zotero://open-pdf/library/items/{{rAttachment.itemKey}}){% endfor %} |
{%- endfor -%}
{{ "" }}
{%- endif %}

> [!tldr]+ Non-Zotero Links to This Note
> ```dataview
> TABLE tags as Tags
> FROM [[{{citekey}}]]
> WHERE !contains(file.path, "ZI LiteratureNotes")
> ```

> [!abstract]-{% if abstractNote %}
> {{abstractNote | striptags(true) | replace("BACKGROUND:","**BACKGROUND:**") | replace("CONCLUSIONS:","**CONCLUSIONS:**") | replace("CONCLUSION:","**CONCLUSION:**") | replace("DESIGN:", "**DESIGN:**") | replace("EXPOSURES:","**EXPOSURES:**") | replace("IMPORTANCE:","**IMPORTANCE:**") | replace("INTERVENTIONS:","**INTERVENTIONS:**") | replace("INTRODUCTION:","**INTRODUCTION:**") | replace("METHODS:","**METHODS:**") | replace("OBJECTIVE:", "**OBJECTIVE:**") | replace("PARTICIPANTS:","**PARTICIPANTS:**") | replace("PURPOSE:","**PURPOSE:**") | replace("RECOMMENDATIONS:","**RECOMMENDATIONS:**") | replace("RESULTS:","**RESULTS**:") | replace("SETTING:","**SETTING:**") | replace("CONCLUSIONS AND RELEVANCE:","**CONCLUSIONS AND RELEVANCE:**") | replace("DATA SOURCES:","**DATA SOURCES:**") | replace("DESIGN, SETTING, AND PARTICIPANTS:","**DESIGN, SETTING, AND PARTICIPANTS:**") | replace("ELIGIBILITY CRITERIA:","**ELIGIBILITY CRITERIA:**") | replace("ELIGIBILITY CRITERIA FOR SELECTING STUDIES:","**ELIGIBILITY CRITERIA FOR SELECTING STUDIES:**") | replace("MAIN OUTCOME MEASURES:","**MAIN OUTCOME MEASURES:**") | replace("MAIN OUTCOMES AND MEASURES:","**MAIN OUTCOMES AND MEASURES:**") | replace("PROCESS AND EVIDENCE SYNTHESIS:","**PROCESS AND EVIDENCE SYNTHESIS:**") | replace("RESEARCH DESIGN AND METHODS:","**RESEARCH DESIGN AND METHODS:**") | replace("STUDY DESIGN AND SETTING:","**STUDY DESIGN AND SETTING:**")}}{% endif %}

# Persistent Notes
{% persist "notes" %}


{% endpersist %}
# Annotations (Exported: [[{{exportDate | format("YYYY-MM-DD")}}]])
{% for colorHex, colorCategory in zoteroColors %}
## {{categoryHeading[colorCategory]}}

{% for beginString, calloutString in zoteroStrings %}
{%- for annotation in annotations | filterby("color", "startswith", colorHex) | filterby("comment", "startswith", beginString) %}
{%- if annotation -%}
{%- if annotation.comment.substring(0,2) === "sm" -%}
> [!summary] Summary
> {{annotation.comment.substring(2) | trim}}
> ^{{annotation.id}}
{% else -%}
{{formatAnnotation(annotation, calloutString)}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- endfor -%}

Literature Note in Editing View:

This template was created with the aim of synthesizing a literature matrix from literature notes exported from Zotero Integration. As such, I wanted to have all annotated text, embedded images, and comments appear in a list format, as it is possible to TABLE query list content under sections (headers) using dataview. It was also important for me to have colored highlights be grouped together AND types of information highlighted sorted as well. For example, under the “Methodology” section, it would be important to have all information about subjects together, then information about the study protocol, then about instrumentation used, so on and so forth.

To achieve this, I used the List Callouts plugin (thank you @mgmeyers!) and, after using a for loop to go through the Zotero colors in the order I wanted, use a for loop to go through the callout characters used for List Callouts in the order I wanted as well! To make this work, I comment every annotation I make in Zotero with the callout characters, regardless if I need to make an actual comment or not. Example below:

With every string of callout characters having a length of 2, I then have the template substring the callout characters from the comment and then place them in the beginning of a image or text annotation with a special character appended to the beginning. I do this because I am admittedly quite lazy and don’t want to always be typing the special characters while annotating or even try to remember them. The section of the template I define the callout characters is near the beginning, “zoteroStrings”. List Callout plugin recognizes the characters and then decorates the literature note accordingly.

A novel thing I implemented in the template is the ability to append same-color annotations together, when there is a different-color annotation between them. To exemplify this, refer to the figure below:


As you can see, I started the magenta annotation right at the tail end of page 5, where it continues onto page 6. However, I also wanted to annotate the table at the end of page 5 with a blue highlight (for results). To append the annotations together, I place a “-” sign at the end of the callout characters for the annotation that is cutoff and don’t make any further comments. The next magenta annotation, I place a “+” sign at the end of the callout characters to append the annotated text to the previous magenta annotation, as well as comment whatever else I want. This is how it looks in the literature note:

So far, this works for cut-off annotations of the same color, with a different colored annotation between them and without any annotation between them. It does not work if the between annotation is the same color as the cut-off annotations. So in the above example, if I wanted to highlight the table with magenta, it would not work :frowning: . Only way I can see solving that is having all image annotations go last or go first by having callout characters for image comments be the same.

Thats pretty much it for the template. There was quite a bit of setting up to do in the List Callout plugin settings, which I am happy to post my settings if people are interested. I figure what people may be more interested in and adapt from this template is

  • the procedure of commenting every annotation in zotero with unqiue callout characters so that they can then be sorted in a manner you prefer
  • appending same colored cut-off annotations with a different colored annotation between them and without any annotation between them

If you have any questions feel free to holler. Thanks!

12 Likes

Thank you for this, it looks incredible! Is it possible to change the bibliography section of your code so that it instead spits out APA-style references?

1 Like

Do you mind sharing (I would prefer all, but if not, a few) Dataview queries you use with this template? I’m new to Dataview and I don’t yet understand all the features of Dataview and how I can structure my notes to be querri-able (if that’s even a word) by Dataview. Thanks for such detailed explanation of your template. I like it a lot. Using List Callouts instead of embedding the colors in HTML for sure make the md files much more readable.

Hey @aberjohn, thanks, glad you like it!

Yes, you can do that when you set up the import in Zotero Integration’s settings:

I have a note called Literature processing that gives me an overview of the following in my literature notes: tasks, annotations with certain tags, and the reading status and priority (although I also use the Projects plugin for that, following this guide).

Here’s what the Literature processing note looks like:

# Reading status

```dataview
TABLE 
without ID link(file.link, aliases) as Article,
priority as Priority,
status as Status,
date-created as Created
FROM "03 - Source notes/Zotero" AND -#MOC
SORT priority DESC
```

# Literature tasks

```dataview
task
from "03 - Source notes/Zotero" and #literature-note
group by meta(section).subpath
```

# Analysis annotations

```dataview
TABLE without ID link(file.link, aliases) as Article,
L.text AS "Sections"
FROM "03 - Source notes/Zotero"
FLATTEN file.lists AS L
WHERE contains(L.tags, "#analysis")
```

## Inspiration

```dataview
TABLE without ID link(file.link, aliases) as Article,
L.text AS "Sections"
FROM "03 - Source notes/Zotero"
FLATTEN file.lists AS L
WHERE contains(L.tags, "#inspiration")
```

and some screenshots:



You could also use this query to see all list items under a certain heading:

TABLE L.text AS "Bullets"
FROM "03 - Source notes/Zotero"
FLATTEN file.lists AS L
WHERE meta(L.section).subpath = "Research"

This will display all list items under a Research heading in the given path. There’s more options, like grouping by file as well, in the guide @jujumartini shared.

7 Likes

Yes, it’s possible. Look in my gist , lines 154 and 161 create a persistent block. Those will not be overwritten. I must add that having persistent blocks is both a blessing and a curse, it is a bit finecky.