what javascript would I run to obtain the key for every note in my library?

edited April 23, 2021
Hi,

I've been working from the javascript API documentation and I haven't been able to find / understand how to get the key for every note in my library?

The docs detail how to get child notes for an item if I already have the parent key, but not how to check if a parent key has a note attached to it.

Apologies if this is a basic javascript question, I'm just starting to figure this stuff out. Happy to experiment with suggestions and report back when successful if you have time to reply with some ideas.

ultimately I'd like to automatically search every note in my library for instances of "[text]" containing specific keywords and print them as a new .tex file with some basic document template materials.

Thanks in advance,

Ezra
  • edited April 23, 2021
    I suspect I can modify some of the examples for the "advanced searching" from https://www.zotero.org/support/dev/client_coding/javascript_api - but, before I can even start to think of how the "Child Note" dropdown option is implemented, I am having issues just running the basic example:

    var s = new Zotero.Search();
    s.libraryID = Zotero.Libraries.userLibraryID;
    s.addCondition('joinMode', 'any');
    s.addCondition('recursive', 'true');
    s.addCondition('noChildren', 'true');
    s.addCondition('includeParentsAndChildren', 'true');
    var tagName = 'Finished';
    s.addCondition('tag', 'is', tagName);
    var results = await s.search();
    var items = await Zotero.Items.getAsync(results);

    ----
    all it returns is "===>undefined<=== (undefined)" even thought there are plenty of items with the "Finished" tag in my library.


  • Assuming you're running it in the javascript runner, this should work:

    return (await Zotero.Items.getAll(Zotero.Libraries.userLibraryID)).filter(item => item.isNote()).map(item => item.key)
  • Oh if you have "run as async function" checked you must return to see the value, otherwise the return value of the "function" is undefined, and that's what you're seeing.
  • edited April 23, 2021
    amazing, thank you so much! seems to work great.

    Ezra
  • I forgot to check for tags. My method can be made to work, search is going to be more efficient for large libraries. The key thing is the return I think.
  • No worries on the tag thing, that was mostly just me copying the example exactly to try to get it to work. since I'm trying to search all my notes for specific keywords, getting all noteIDs efficiently is the best place to start I think.

    Now I just have to search the content of the notes for those keywords and parse out the quotes they were imported within.
  • edited April 23, 2021
    Hi again,

    I tried to adapt the example in the docs to load all the note contents into a string and print that:

    var r = await Zotero.Items.getAll(Zotero.Libraries.userLibraryID).filter(item => item.isNote()).map(item => item.key)
    //return r

    for (let id of r) {
    let note = Zotero.Items.get(id);
    let noteHTML = note.getNote();
    }

    return noteHTML

    but the only output is: TypeError: note.getNote is not a function


  • edited April 23, 2021
    var noteHTML = await Zotero.Items.getAll(Zotero.Libraries.userLibraryID)
    .filter(item => item.isNote())
    .map(item => item.getNote());
    return noteHTML.join('\n\n------------------------\n\n');
  • Thank you!
  • I'm now trying to add a specific search term ("extracted," so that the runner only prints extracted annotations), and print each note with the parent item bibtex key right after the ------ separator.

    Unfortunately, even just trying to add a search parameter, eg:

    var noteHTML = await Zotero.Items.getAll(Zotero.Libraries.userLibraryID)
    .filter(item => item.isNote());
    s.addCondition(fieldName, 'has', "extracted");
    .map(item => item.getNote());
    return noteHTML.join('\n\n------------------------\n\n');

    returns:

    SyntaxError: expected expression, got '.'

    Is there a specific part of the source code I should be looking at to find the syntax for this kind of search? I've been looking at /chrome/content/zotero/xpcom/data/search.js but I can't find any instance of ".filter(item => [...]" there.
  • The part that starts with .map calls map on nothing. map must be called on an array.

    But in a more general sense you're mixing two approaches here. One just calls up all items in the library and uses regular javascript code to filter them. s.addCondition (with s undefined BTW) uses the Zotero search facilities.

    TBH it'd be easier for us to write the full code if you explain what you want rather than guide you through the Zotero internals. But even if you want to explore Zotero to get a better understanding it'd be best to have a clear idea on what you want to achieve first.

    Another aside: writing a .tex file is in itself not entirely trivial given that you are looking to write the note text (which is HTML), and you might be better off writing as HTML and let pandoc convert it to tex.
  • If you're going to run this more than once it might actually be easier to write an export-to-html translator and run pandoc on the results. Assuming you have BBT installed (otherwise you'd have to copy the cite key generation from the BibTeX.js translator), something like this should do the job (untested though):

    {
    "translatorID": "a10da689-df6d-4951-8f6d-add746611577",
    "label": "Notes",
    "creator": "",
    "target": ".html",
    "minVersion": "3.0",
    "maxVersion": "",
    "priority": 100,
    "inRepository": true,
    "translatorType": 2,
    "lastUpdated": "2021-04-27 18:28:36"
    }

    function escapeHtml(unsafe) {
    return unsafe
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
    }

    function doExport() {
    let item
    while (item = Zotero.nextItem()) {
    if (!item.notes) continue
    for (note of item.notes.filter(note => note.note.includes(Zotero.getHiddenPref('note-search.term')))) {
    Zotero.write(`<h1>${escapeHtml(item.citationKey)}</h1>\n`)
    Zotero.write(note.note)
    }
    }
    }
  • Wait -- when you say you want "the key", do you mean the technical key Zotero uses, or "the citation key"? Zotero itself does not yet have a concept of a citation key. If you use the regular BibTeX export, the keys are generated on the fly only for the duration of the export, so you can't search on those inside Zotero. If you have BBT installed, you do have stable citation keys that you could in principle search for using code.
  • edited April 28, 2021
    hi + thanks for the caring answer, as well as the solution!

    I do have BBT installed.

    I'm trying to code an annotation scanner that will compile all the quotes and comments in a note that are flagged by a # and will produce a .tex file that contains the corresponding quotes, proper \cite commands, and comments, ordered by year of publication.

    eg, if I have:
    ["In other words, the artists attempted a kind of "reverse engineering" of traditional conceptions of community formation." (Dewar 2009:127)

    #reverseeng a reverse engineering of community through the development of capital's folk music (note on p.127)]
    in one note, for the parent item with the bibkey "Dewar 2009," and, in another note for the parent item with the bibkey "Gell 1998"
    ["Style, I argue, is 'relations between relations' of forms." (Gell 1998:237)

    #reverseeng good definition of style
    (note on p.237)]
    I would like the desired code to, when running for "#reverseeng", return something like:
    \documentclass{article}
    \usepackage[utf8]{inputenc}
    \usepackage[english]{babel}

    \usepackage{biblatex}
    \addbibresource{library.bib}

    \begin{document}

    ``Style, I argue, is 'relations between relations' of forms.'' \cite[237]{gell1998}

    good definition of style

    ``In other words, the artists attempted a kind of ``reverse engineering"'' of traditional conceptions of community formation.'' \cite[127]{Dewar2009}

    a reverse engineering of community through the development of capital's folk music

    \printbibliography

    \end{document}]


    I did manage to get the runner to print to print the output of dstillman's code to a txt file that already exists, with:

    var noteHTML = await Zotero.Items.getAll(Zotero.Libraries.userLibraryID)
    .filter(item => item.isNote())
    .map(item => item.getNote());
    var data = noteHTML.join('\n\n------------------------\n\n');
    var path = 'targetfilepath';
    await Zotero.File.putContentsAsync(path, data);


    Hopefully this clarifies my objectives. I'm sure there's more than one approach for this, and I'm still trying to figure out the cleanest way to have it retrieve the bibkey along with the desired quotes. I'll work with the code you just provided (I think you're right that a translator for html to pandoc for tex is probably a good approach, thanks for pointing that out) and see if I have follow up questions.

    I can also start a new thread on the forum for this since the original question was not indicative of the overall objective.
  • edited April 27, 2021
    in other words, I think of this as an add-on that makes zotero a "quotations manager" when used with bbt, in addition to a database of publication references. It won't run very often, so it doesn't have to be super-efficient, or have any particularly convenient form. Thanks for all your help!
  • and of course if there is a translator / runner script / add on I should hack instead of trying to make one from scratch please feel free to point me in that direction
  • It's hard to tell what is what in your message since there is no separation. It'd help if you'd include the note samples in <code> or <blockquote> sections.

    Retrieving the citation key in a translator is trivial, see the translator I posted above. Retrieving the citation key from inside Zotero isn't hard, but it's more work, and I'd prefer to use https://github.com/retorquere/zotero-better-bibtex/discussions for discussing that, since these forums are not meant for dev questions, but mostly because discussing technical things is easier when markdown can be used.

    There is a fairly significant chance that the project you're planning is more ambitious than you had in mind. The notes are HTML (rich text), and html to tex conversion is not trivial, believe me.
  • edited April 28, 2021
    Hi - I've edited my long response above with some html to make it easier to read.

    I've also created a thread over in the bbt discussions so we can use md, with a follow up question regarding what would make the html to tex question easier

    https://github.com/retorquere/zotero-better-bibtex/discussions/1798
Sign In or Register to comment.