I've written (with the help of Claude) a custom web component for searching and selecting entries from a BibTeX bibliography database which can be used in floating menus. You can try out a version of it here, which is preloaded with my bibliography database. You can also download the javascript defining the web component. Search can be either space-separated tokens or simple regular expressions. For example, searching for "game theory" will match any entry with both "game" and "theory" in it, but searching for "game theor(y|etical)" will match any entry with both "game" and "theory" OR "game" and "theoretical".
Entries can be selected by clicking / tapping on them, and there's an action button which can be set to a JavaScript function to do something. On the demo web page above, the action button simply inserts the content in a display panel beneath the component, but in my BTT Mobile setup, the action button pastes the content into the current app with focus.
Here's a screenshot showing what it looks like in BTT Mobile on an iPad Mini:
Here's the HTML I used to set it up in the floating menu:
<bib-search
src="bibliography.html"
action-label="Insert"
height='350px'
placeholder="Search (supports regex)...">
</bib-search>
<script>
const bibSearch = document.querySelector('bib-search');
let text = '';
bibSearch.onAction = async (entries, mode) => {
if (mode === 'bibkey') {
text = entries.map(e => e.bibKey).join(',');
}
else if (mode === 'markdown') {
text = entries.map(e => e.markdown).join('\n\n');
}
else {
text = entries.map((e, i) => `${e.html}`).join('<br><br>');
}
await paste_text({ text: `${text}`, format: 'NSPasteboardTypeHTML', insert_by_pasting: true });
};
function setBibSearch(search) {
if (search.includes(',')) {
bibSearch.setSearch("(" + search.replaceAll(',', '|') + ")");
}
else {
bibSearch.setSearch(search);
}
}
</script>
The reason I defined the function setBibSearch() is because it's possible to do "inverse searches" in the web component by selecting text on the Mac and invoking a BTT action. Here's how I have the action configured on my laptop:
(You will, of course, need to change the UUID to refer to the UUID in your setup.)
As defined above, the inverse search behaves in two ways. Suppose you select the argument enclosed in the \citet{} macro:
\citet{Alexander:2024,Alexander/Morley:2021,Alexander:2007}
This gets converted to the search string (spaces added for clarity)
(Alexander:2024 | Alexander/Morley:2021 | Alexander:2007)
So those three entries will be displayed in the web component, since that is the syntax for a regular expression search using the OR-operator "|".
However, if the selected text doesn't contain a comma (since that is used as a separator in BibTeX macros), then the inverse search will just pass all the selected text to the web component.
You first need to convert your bibtex database to HTML using pandoc, but that's easy. You can do that via the following command line:
echo '---\nnocite: "@*"\n---\n' | pandoc --citeproc --bibliography=Bibliography.bib -o bibliography.html

