Script to copy quotes from Zotero to Obsidian

I wrote this Bash script that copies a selected, highlighted quote in Zotero (a source manager), and copies that quote into Obsidian (a markdown editor), finds the note, titled $citekey.md and pastes the quote at the bottom at the note:

#!/bin/bash

# Under Zotero Settings > Advanced > Config Editor, search for "extensions.zotero.annotations.noteTemplates.highlight" and edit template to 
# <p>{{citation}} <br> &gt; {{highlight}} {{comment}}</p>

# Copy the citation key using Ctrl+Shift+C 
# must set Quick Copy settings in Zotero (under Export) to "Better BibTeX Citation Key Quick Copy"
sleep 0.2
xdotool key ctrl+shift+c
sleep 0.2
# Save the citation key from the clipboard to a variable using xclip, copies citation to clipboard, looking like cite{citekey}
TeXcitekey=$(xclip -o -selection clipboard)

# removes TeX command, leaving only citekey itself
citekey=$(echo $TeXcitekey | sed -E 's/\cite{([^}]*)}/1/')


# copies selected text or highlight in Zotero to clipboard
xdotool key ctrl+c

# Save citation as a variable
raw_citation="$(xclip -o -selection clipboard)"

# Ensure the ">" (greater than) character isn't escaped with a backslash
citation=$(echo "$raw_citation" | sed 's/\>/>/g')

# Combine the sed commands
formatted_citation=$(echo "$citation" | sed -E '
    # Reduce to just the page number from (author, year, p. 5) to just 5
    s/([^)]* ([0-9a-z]+))[[:space:]]{2,}/1/g;
    # Remove quotation marks around the whole blockquote
    s/^> ?["“]([^"“”]+.*[^"“”]*)["”]$/> 1/;
    s/^> ?[‘47]([^’47]+.*[^’47]*)[’47]$/> 1/'
)

# Print the formatted citation or send it back to the clipboard
echo -n "$formatted_citation" | xclip -selection clipboard

sleep 0.1

# set your vault's directory in your system
directory="/home/Obsidian/vault"

# set location for Zotero's BetterBibTeX .bib file
bibfile="/home/Zotero/Library.bib"

# set vault
vault="?vault=vaultname&file"

# if the vault already contains a note called $citekey it switches to that file
if find "$directory" -type f  | grep "$citekey"; then
   
    new_file=$(find "$directory" -xdev -name "$citekey.md")    
    xdg-open "obsidian://open$vault=$citekey.md"
   
else
     # Extract details from the .bib file
    author=$(awk -v key="$citekey" '
        $0 ~ "@" && $0 ~ key {found=1} 
        found && $0 ~ /author[[:space:]]*=/ {sub(/.*author[[:space:]]*=[[:space:]]*[{"]/, ""); sub(/[}"].*/, ""); print; found=0}
    ' "$bibfile")


# Extract title, handling nested braces
    title=$(grep -A1 "@.*{$citekey," "$bibfile" | grep 'title =' | sed -E 's/.*title = {(.+)},/1/;s/[{}]+//g')


    year=$(awk -v key="$citekey" '
        $0 ~ "@" && $0 ~ key {found=1} 
        found && $0 ~ /year[[:space:]]*=/ {sub(/.*year[[:space:]]*=[[:space:]]*[{"]/, ""); sub(/[}"].*/, ""); print; found=0}
    ' "$bibfile")

    # Handle cases where the information is not found
    author=${author:-"Unknown"}
    title=${title:-"Untitled"}
    year=${year:-"Unknown"}
    
sleep 0.1

# If it does NOT find that note called citekey.md, it creates it
    xdg-open "obsidian://new$vault=03%20Sources%2F$citekey.md"
    sleep 0.3
    new_file=$(find "$directory" -xdev -name "$citekey.md")

    sleep 0.1
# and then inputs a literature note template with authors, title, year, and MOC (for links)    
    echo -e "---nAuthors: $authornTitle: "$title"nYear: $yearnMOC: n---nn" > "$new_file"
    sleep 0.5

fi


sleep 0.3

# Finally! Jump to end of the note, 3 Returns (to make sure we've escaped previous blockquotes)


# Delete duplicate newlines to maintain order
#sed -i '/./,/^$/!d' "$directory/03 Sources/$citekey.md"


    xdotool key ctrl+End
sleep 0.2
    xdotool key Return
  #  xdotool key Return
    xdotool key Return



# using ctrl+v is pasting because it plops the text down all at once instead of one letter at a time
xdotool key ctrl+v

#sleep 1
# Delete duplicate newlines to maintain order - working
sed -i '/./,/^$/!d' "$directory/03 Sources/$citekey.md"

This was working reasonably well, and I don’t know if something changed with an update in the last few days or if I’m just using it more so I notice errors.

The intended use is that I trigger a hotkey for this script when I’ve selected a quote in Zotero, and it takes the citekey from the .bib file, looks for a markdown file with that name and pastes it there.

However, this is the problem I’ve been having. With longer quotes (I haven’t determined if there’s a maximum length) it can’t seem to deal anymore and it then tries to find a file with the name of the entire quote instead of just the citekey, which of course doesn’t exist, and I get the error in Obsidian ENAMETOOLONG followed by the quote.

I can’t narrow down the problem because sometimes it works, even with long quotes. It’s not consistent on when it finds the citekey and when it doesn’t. I don’t know if there’s a problem with xclip or my use of it.

Example of what is supposed to happen, from Ted Chiang’s 2005 What’s expected of us:
This is what is copied from Zotero:

(Chiang, 2005, p. 150)  
> “By now you’ve probably seen a Predictor; millions of them have been sold by the time you’re reading this.”

And this is what Obsidian gets:

150  
> “By now you’ve probably seen a Predictor; millions of them have been sold by the time you’re reading this.”

What happens in the background is that it also hits Ctrl+Shift+C which copies the citekey (here Chiang2005What), which is then used to find the note (here Chiang2005What.md) or if that doesn’t exist create it.

I’ve also just noticed that this

TeXcitekey=$(xclip -o -selection clipboard)

# removes TeX command, leaving only citekey itself
citekey=$(echo $TeXcitekey | sed -E 's/\cite{([^}]*)}/1/')

should be redundant because somehow Ctrl+Shift+C is copying just the citekey, not as assumed here cite{citkey} however, when I try simplifying this by just having
citekey=$(xclip -o -selection clipboard) and removing the rest it no longer works, which adds to my confusion.

Any advice on how to improve this or make it more consistent is appreciated!!

Thanks