Mobile citation autocompletion guide using QuickAdd and Various Complements

Since I use an iPad as my device of choice when working away from home, I have been looking to find a way to insert citations while writing in the iOS Obsidian app.

:warning: The problem

Unfortunately, none of the three plugins for Obsidian that can insert pandoc citekeys work on mobile:

  • Citations: Currently desktop only, and until recently, development had apparently stalled. There has been no update for 9 months, and a two-year-old issue about mobile support has been marked “Help wanted” for a year.
  • Zotero Integration: Used to be called Desktop connector (hint, hint)—it is not available on mobile. It needs to have Zotero running to work, so it is unlikely to ever be available on mobile.
  • Obsidian-Zotero: Has mobile support on @aidenlx’s Github roadmap, but it’s unclear how that will be implemented. Furthermore, updates have been slow lately, despite many bugs.

:white_check_mark: The solution

Enter Various Complements to the rescue!

:information_source: Various complements


This plugin enables you to complete words in Obsidian like the auto-completion of IDE.

The key feature of Various Complements that we will use is autocompletion based on Custom dictionaries.

I got this idea from these underappreciated iOS Shortcuts for Textastic from @somelingust on GitHub, which enable citation autocompletion in Textastic.

This was the most satisfactory way to insert citekeys that I could find for the iPad.

However, it required me to switch back and forth between Obsidian and Textastic. Furthermore, Textastic only autocompletes based on the start of the citekey, so I couldn’t search by title.

Various Complements is much more customizable in its autocompletion, offering fuzzy matching of both the prefix and partials of a string. And, it can match aliases you set, which will come in handy.

Demo

ezgif.com-gif-maker

Creating a citation dictionary

The starting point for this workflow is an exported reference library, in the form of a bibtex file.

Next, we need to convert the bibtex bibliography into a custom dictionary that Various Complements can read. The data should be in a format like this:

inserted text, description, alias

In our case, we want to insert the citekey, and use the title as both description and alias, like so:

citekey, title, title

Yes, title twice. Why? The first instance of title is only for display in the dropdown, while the second one is a searchable alias. With this format, we can search for and autocomplete citekeys using either the citekey or the title.

I’ve made a script in Javascript that handles the conversion from bibtex file to custom dictionary in the format above.

:floppy_disk: The script

Copy the script using the button in the upper right corner.

const fs = require('fs');

function extractCiteKeysAndTitles(bibtexFile) {
  const bibtexData = fs.readFileSync(bibtexFile, 'utf-8');
  const regex = /@([a-zA-Z]*)\s*\{\s*([a-zA-Z0-9_:.#$%&-+?<>~/]*),.*?^\s*title\s*=\s*[\{"](.*?)[\\}"],$/gmis;
  let match;
  let markdownContent = '';

  while ((match = regex.exec(bibtexData))) {
    const citeKey = match[2].trim();
    const title = match[3].trim().replace(/[\{\}]/g, "");
    const formattedTitle = convertTextendash(title);
    markdownContent += `@${citeKey}, ${formattedTitle}, ${formattedTitle}\n\n`;
  }

  return markdownContent;
}

function convertTextendash(title) {
  // Convert "\textendash" to en-dash symbol
  const enDashSymbol = "–";
  return title.replace(/\\textendash/g, enDashSymbol);
}

// Usage
const bibtexFile = "Path/to/bibtex-bibliography.bib";
const markdownContent = extractCiteKeysAndTitles(bibtexFile);
return markdownContent;

:man_technologist: Running the script

To run the script inside Obsidian, we will use Quickadd’s inline scripts.

Ironically, the first part of generating the citation dictionary using Quickadd must be done on a desktop computer. The setup of Various Complements is done on the mobile device.

In the future, I hope to refactor the script, so it can be run on mobile devices (see the section below on improvements). Anyway, here’s what you need to do:

  1. As mentioned, you need to export a bibtex bibliography (preferably into your Obsidian vault) first.

    1. If using Zotero, right-click a Zotero collection → Export Collection.
    2. Note: I used the BetterBibtex format when testing, which requires the Better Bibtex addon for Zotero. Regular bibtex might work too, but I haven’t tested it.
  2. If you haven’t already, create a folder for all your templates. Then supply this path in QuickAdd’s Template folder path setting.

  3. Copy and paste the script above into a new markdown file in the Template folder of your vault.

    1. Name the file something like “citation-dictionary-creator.md
    2. The code should be pasted inside a code-block that starts with js quickadd like so:
  4. Replace "Path/to/bibtex-bibliography.bib" in the bibtexFile constant of the script with the actual path where you exported your .bib file.

  5. Add a Quickadd template choice and call it something like “Create citation dictionary”

    1. See Quickadd’s first steps for help, if necessary.
  6. Click the gear icon next to the newly created template choice:
    1.

  7. Set up the template choice in Quickadd as follows:
    1.

    1. Make sure to pick the “citation-dictionary-creater.md” template, which contains the script.
  8. Run the new Quickadd template choice called Create citation dictionary

    1. Command palette → Run QuickAdd → Create citation dictionary
    2. For me, the script runs very quickly, converting a bibtex file with 1800 references into a custom dictionary in just a few seconds.
  9. On the mobile device, enable the Custom dictionary complement setting in Various complements.

    1. Make sure that the citation-dictionary.md file has been synced to your mobile device using your syncing method.
  10. Put the relative path of the citation dictionary created by the script into the Custom dictionary paths text box:
    1.

    1. Make sure that the column delimiter is set to “comma”.

Now, you should be ready to cite on your mobile device :tada:

:information_source: How to cite


Simply type @ and then either the citekey or title of the item you are looking to cite. This will trigger a dropdown tooltip from by Various complements, giving you a list of matches.

:repeat: Automation

Automating the process of updating the citation dictionary every time Obsidian opens is simple. Just configure a macro in QuickAdd’s settings:

  1. Press
    Pasted image 20230922100334
  2. Name the macro and add it:
    image
  3. Enable Run on plugin load:
    image
  4. Press Configure and add the previously created QuickAdd template choice to the macro:
    image

Done! Now the citation dictionary will always be up-to-date once you’ve opened Obsidian on your desktop device.

Citation dictionary example

Here’s an example of what the resulting citation dictionary looks like. It goes on for another 1800 entries in my case.

:gear: Customization

Citation format

If you want to customize the script, let’s say, to change the autocompleted citekey format to be surrounded by square brackets, you can do that by changing the following line in the script:

markdownContent += `@${citeKey}, ${formattedTitle}, ${formattedTitle}\n\n`;

to this:

markdownContent += `[@${citeKey}], ${formattedTitle}, ${formattedTitle}\n\n`;

Recommended Various complements settings

  • Increase Max number of suggestions to see more suggestions without having to scroll.
  • If you are not interested in the other types of autocompletion that Various complements enables, you can disable those under the settings.

:exclamation: Limitations

Conflict with other citation autocompleters on desktop

In case you use Pandoc Reference List, the autocompletion of Various complements will interfere with its citekey autocompletion, if both are enabled.

:information_source: Feature migration notice


@mgmeyers recently moved the citation autocompletion feature from Zotero Integration to Pandoc Reference List. He is the maintainer of both plugins.

That’s why you’ll want to create a settings profile for mobile using the SettingsAboutOverride config folder setting and set it to something like .obsidian-mobile.

This way, you can have a Various complements installation and configuration that only affects your Vault on the mobile device, without interfering with Pandoc Reference List on your desktop device.

No modifier key for alternative citation formats

Another limitation is that I haven’t figured out a way to easily insert an alternative citekey format, for example when pressing a modifier key.

One option would be to create two entries in the bibliography dictionary, one in each format. Then, you could insert the one you wanted from the tooltip drop-down. However, this might not work as intended, so I’m sticking with manually adding square brackets, until I figure something out.

One way to make this easier is to use the Smarter Markdown Hotkeys plugin, which has a Smarter Square Brackets command. It adds square brackets to your selection, which doesn’t have to be precise (you can select part of a word, and it nevertheless applies the formatting to the whole thing).

:seedling: Planned improvements and feedback request

I plan to change the script so that it uses the Quickadd API / Obsidian API to read the bibtex file, rather than using the file system module (‘fs’) from Node.js.

This way, it should be possible to run the script on the iPad. This would be more convenient and less ironic than a mobile workflow that requires a desktop computer. Nevertheless, a desktop computer would still be required to export the library from Zotero, so it shouldn’t be too inconvenient to also run the script on a desktop computer.


I would appreciate any feedback and ideas on how to improve this workflow and the script. Especially regarding how to refactor the script to use the Quickadd/Obsidian API, and on how to implement a convenient way to insert an alternative citation format.

Also, please report back if you encounter any issues.

5 Likes

Hi, this is great, thank you! One potential issue with this workflow: how would you enter items without a title (interview, letter, etc.)?

Thanks for the feedback, glad you like it!

Well, since the description and alias are optional, the simplest solution would be to remove the title from the custom dictionary (see the Customization section).

A more involved and perhaps more useful solution would be to insert another field as description and alias, based on item type.

I am not used to working with interviews and letters. Which field(s) would be suitable replacements for the title?

Btw, I just checked, and both interviews and letters do have a title field in Zotero. Is it just that you don’t use this field? Or are you not using Zotero?

I am using Zotero, but titles for letters and interviews are optional, and usually not included in citations. Zotero displays “letter to [Recipient]” or “interview” in title. Replacing empty title with “letter” or “interview” should work in most cases I think.

2 Likes

Is it possible to create a new page from the citation automatically like with the Citations plugin?

I assume you mean creating literature notes about items in your bibliography, including metadata and possibly annotations? As is, that is beyond the scope of this workflow, as it is only for inserting citations into your writing.

The script only extract the citekey and title for each item from your bibliography, so those are the only pieces of information available. In theory, you could modify it to extract any notes present and other metadata, but that is not something I intend to do.

This looks perfect for me but I am having some problems running QuickAdd. Can you help?

I have followed all the instructions but when I try to run the QuickAdd command I get the following errors:

QuickAdd: (ERROR) Could not create file with template:
ENOENT: no such file or directory, open ‘Library/Library.bib’

QuickAdd: (ERROR) Could not create file ‘Library/citation-dictionary.md’

Do you have any idea how I should troubleshoot this?

Many thanks

Hey, I’m glad you found it useful!

Let’s see, did you provide the full path to the bibliography file inside the script?
Next, does the folder you specified as the output folder for the citation dictionary exist within your vault?

Please provide a screenshot of your Quickadd settings for further debugging.

Thanks for the quick reply! Yes, all the folders exist and I provided the full path to the bibliography, as far as I can tell. The line in the script is

const bibtexFile = “Library/Library.bib”;

I have attached a screenshot of my Vault structure and the QuickAdd settings.

That’s a relative path, not the full path. You need to include all the parent directories, not just the part inside the vault.

This worked perfectly, thank you! So amazing to have autocomplete citations on iPad, I have been wanting this for years!

I have set up Better Bibtex to automatically export my library, so all I will do is need to remember to rerun QuickAdd. However, doing this did make me think - wouldn’t it be great if your code could be incorporated as an additional Better Bibtex output? Then the whole process would be automated entirely. The BB author seems quite active so they might consider this as a feature request?

1 Like

I have added a feature request to the Better Bibtex GitHub page.

I have added instructions on how to automate the process of updating the citation dictionary every time Obsidian opens. This was actually fairly simple, and didn’t require any changes to the script. Basically, you just have to add your template choice to a QuickAdd macro, and enable the toggle that says Run on plugin load. See the edited post above for details.

This doesn’t eliminate the need to open Obsidian on your desktop device for the updating to occur, but then again, you need to open Zotero on a desktop device for Better Bibtex to auto-export changes anyway.

2 Likes

Thank you this is very helpful!

1 Like