retorquere / zotero-better-bibtex

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

Help for Custom Export #940

Closed marquistj13 closed 6 years ago

marquistj13 commented 6 years ago

I want to know how to customize the export of BetterBibLaTeX. Specially, I want the following features(or changes) in my export:

I have read the guide here: https://retorque.re/zotero-better-bibtex/scripting/ But I still can't do it , because I don't know much about how to write the JavaScript snippet.

Can anybody give me some hints to achieve this task? Or, better, give me the solution.

Thanks in advance for your help.

retorquere commented 6 years ago

You can already achieve the first by setting the type field in Zotero to phdthesis. If you want to change all thesis references to phdthesis, and then set institution to school:

if (Translator.BetterBibLaTeX) {
  if (this.referencetype == 'thesis' && !item.type) this.referencetype = 'phdthesis'; // see note 1 below
  if (this.referencetype == 'phdthesis' && this.has.institution) this.add(Object.assign(this.remove('institution'), { name: 'school' })); // see note 2 below
}

note 1: if item.type is set explicitly, I assume you will want BBT to behave as usual. This way you can still set type to mastersthesis if you want the specific reference to come out as @mastersthesis, but if nothing is set in the type field, it will assume phdthesis.

note 2: the biblatex manual says:

institution list (literal)

The name of a university or some other institution, depending on the entry type. Traditional BibTeX uses the field name school for theses, which is supported as an alias.

but since you're using BibLaTeX, I'm not sure why you'd want to output something that targets "traditional BibTeX".

marquistj13 commented 6 years ago

I should use Traditional BibTeX, because Traditional BibTeX already has the above two features. Sorry for my lack of BibTeX knowledge.

BTW, I still have other needs, such as, change the language field according to the entry type. Your above answer serves as a good guide for me to achieve this task, and I will try to do that myself.

Thank you again for your help.

retorquere commented 6 years ago

If you want traditional BibTeX, then why not use the Better BibTeX exporter rather than the Better BibLaTeX exporter?

I don't exactly understand what you mean by "change the language according to entry type", can you elaborate?

retorquere commented 6 years ago

(I think you've gathered by now end-users can't close issues. Only repo owners can on this repo)

retorquere commented 6 years ago

As a matter of fact, if you export using "Better BibTeX" rather than "Better BibLaTeX", you get @phdthesis and school without the use of a postscript. I really think you're just using the wrong translator for your case.

marquistj13 commented 6 years ago

Yes, I'm using the wrong translator for my case.

As to " change the language field according to the entry type", I mean,whether we can set the language field automatically accoriding to the title or other information in the bib item.

For example, if some bib item already has the language field in the generated bib file:language = {chinese}, So we can change it to be language = {zh},, as I want. (My real need is to change from language = {中文}, to language = {zh},. To simply the case, let's forget this.)

More generally, when we have no language field, can we detect the language of the title and then set the language field thereby? It maybe not trivial to detect all the languages in the world. Fourtunately, I only need to deal with two kinds of language in my database, i.e., chinese and english.

Here is the code I use:

if (Translator.BetterBibTeX && this.has.title) {
    // check if there is a chinese character
    // the range `\u4E00-\u9FA5` contains all common chinese characters
    var pattern = new RegExp("[\u4E00-\u9FA5]+");
    var str = item.title;
    var language_value= '';
    if(pattern.test(str))
        language_value='cn';
    else
        language_value='en';

    if(this.has.language)
        this.add({name: 'language', replace: true, value: language_value})
    else
        this.add({name: 'language',  value: language_value})
}   

It works. :smile:

retorquere commented 6 years ago

Ah, I understand. You can shorten this to

if (Translator.BetterBibTeX && this.has.title) {
  this.add({name: 'language', replace: true, value: this.title.match(/[\u4E00-\u9FA5]/) ? 'cn' : 'en'})
}
marquistj13 commented 6 years ago

Hello, I have to change this.title to item.title to make your script work. i.e.,

if (Translator.BetterBibTeX && this.has.title) {
  this.add({name: 'language', replace: true, value:item.title.match(/[\u4E00-\u9FA5]/) ? 'cn' : 'en'})
}

Is this a bug? Actually, I splent a lot of time to find this bug when I write my own script. I'm using the latest version of zotero-better-bibtex, i.e., v5.0.108, and my zotero version is 5.0.42.

retorquere commented 6 years ago

No, that was an error on my part. It's either this.item.title or item.title.

retorquere commented 6 years ago

I'd recommend one more tweak, more for conceptual reasons than practical reasons:

if (Translator.BetterBibTeX && item.title) {
  this.add({name: 'language', replace: true, value:item.title.match(/[\u4E00-\u9FA5]/) ? 'cn' : 'en'})
}
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.