retorquere / zotero-better-bibtex

Make Zotero effective for us LaTeX holdouts
https://retorque.re/zotero-better-bibtex/
MIT License
5.21k stars 285 forks source link

Post Script to remove certain entries from extra field #1423

Closed stefanct closed 4 years ago

stefanct commented 4 years ago

I was struggling to remove the ZSCC key: value pairs (left over) in the extra field of some of my entries preserving possible other extras. The filter that BBT offers does not work for contents of the extra field - one can just prohibit the export of the whole field (note) there. Thus I created my first post script... which was also not trivial in the beginning

In case anybody wonders, the following two scripts seem to be equivalent.

if (Translator.BetterTeX && item.extra) {
    reference.add({ name: 'note', duplicate: true, value: item.extra.replace(/(^ZSCC: .*$)/gm, '') });
}

if (Translator.BetterTeX && item.extra) {
    reference.remove('note');
    reference.add({ name: 'note', value: item.extra.replace(/(^ZSCC: .*$)/gm, '') });
}

Feel free to copy them to the example page.

  1. Wouldn't it make sense to filter ZSCC extras out by default?
  2. I have seen there exists some code that parses extraFields already (e.g, csl)... What do you think about enabling the filtering of such "subfields" within the extra field? I mean by adding some code or even another text box to the export filter settings?
retorquere commented 4 years ago

Postscripts are not really well documented, and users are not necessarily expected to become javascript gurus -- most samples on that page came about because someone requested a postscript and I wrote it. It's always OK to ask.

reference.remove removes fields from the bibtex entry. Since extra is not a bibtex entry, reference.remove won't do much useful.

The duplicate: parameter was a holdover from the early days of postscripts, it doesn't do anything now (but neither will it hurt to have it there). I've updated the sample in the docs, but that will take anywhere between 5 and 30 minutes to show up.

The two scripts are equivalent (and you don't need the replace marker anymore -- replace in postscripts is implied now. ^ZSCC will only work if that appears at the start of the extra field, I'd suggest

if (Translator.BetterTeX && item.extra) {
    reference.add({ name: 'note', value: item.extra.split('\n').filter(line => !line.startsWith('ZSCC:').join('\n') })
}

instead.

WRT filtering out -- I currently remove known Zotero fields, known CSL variables, and anything that starts with tex./bibtex./biblatex., but I don't think ZSCC falls under one of these categories. People do also use the extra field as a note field so I want to be conservative about what I remove. What does ZSCC stand for?

the code that parses extraFields is special because it knows about the type of the fields it parses (such as creator-type and date-type CSL variables), I wouldn't know any special type handling for generic fields, and then extraFields parsing is literally just what you see above -- split into lines, look for line starts, and filter them out.

stefanct commented 4 years ago

Hm, right... it works without the duplicate parameter and without the remove call - I did not test it well enough in that respect I guess. But I think you missed the m (multiline) flag I was using in the replace regex(?). With that it works fine no matter in which line the ZSCC is written (as long as it starts at the beginning of a line). Do I miss something else?

The ZSCC entries come from the ZSC plugin: https://github.com/MaxKuehn/zotero-scholar-citations I am currently not using it anymore because it has too many problems for the benefits I perceive.

retorquere commented 4 years ago

You are right, I missed that. But I can't actively track what all Zotero plugins put there -- the tex fields are my own, and Zotero already parses out it's own and CSL fields, and I follow those.

stefanct commented 4 years ago

I understand... chasing after such things is almost always a lost race. That's why I was thinking that allowing to filter them manually in the settings like already possible for whole fields would make sense. I am happy with the script solution though - feel free to close this issue. Thanks!

retorquere commented 4 years ago

Welcome.

stefanct commented 4 years ago

After some more testing, I think the remove is actually required in case the extra field would become empty. I presume this is because the add call to change it would silently fail with an empty value(?) but I havent checked the code or tried to really understand it (or why I thought it worked before...). Eventually, I ended up with, which also removes the trailing line break itself if need be:

if (Translator.BetterTeX && item.extra) {
    reference.remove('note');
    reference.add({ name: 'note', value: item.extra.replace(/^ZSCC:\s+\S+[\s]*/mg, '') });
}
blip-bloop commented 4 years ago

:robot: this is your friendly neighborhood build bot announcing test build 5.2.16.5888 ("clear field in postscript when adding an empty value")

Install in Zotero by downloading test build 5.2.16.5888, opening the Zotero "Tools" menu, selecting "Add-ons", open the gear menu in the top right, and select "Install Add-on From File...".

retorquere commented 4 years ago

Good point. I'm of two minds on this; usually I prefer to have .add just do nothing if the value is empty, but maybe in the postscript an unconditional overwrite is more appropriate. 5888 adds this behavior, but I'm still not sure.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.