joostkremers / parsebib

Elisp library for reading .bib files
BSD 3-Clause "New" or "Revised" License
35 stars 9 forks source link

support string replacements #5

Closed malb closed 7 years ago

malb commented 7 years ago

Hi there, over at https://github.com/tmalsburg/helm-bibtex/pull/161 (which uses parsebib) we are discussing how to deal with bibtex @string. @tmalsburg points out that replacing strings in bibtex entries should be handled in parsebib, which to me seems right. My PR has some code for attempting this but at the helm-bibtex level. Would code like this be a good addition to parsebib?

joostkremers commented 7 years ago

Hi, I'm not sure exactly what it is you're trying to achieve. I'm not a helm user, so it would probably help if you could explain it a bit. Thanks. :smile:

malb commented 7 years ago

Sorry, for lack of explaining. Helm is completely orthogonal. In my field - cryptography - the goto bibtex database https://cryptobib.di.ens.fr provides entries like these:

@string{acisp15 =               "ACISP15"}
@string{acisp15key =            "ACISP 2015"}
@string{acisp15name =           "ACISP 15" # acispname}
@string{acisp15ed =             "Ernest Foo and Douglas Stebila"}
@string{acisp15vol =            "9144"}
@string{acisp15addr =           ""}
@string{acisp15month =          jun # "~/~" # jul}

@InProceedings{ACISP:SunWanZha15,
  author =       "Zhelei Sun and
                  Peng Wang and
                  Liting Zhang",
  title =        "Weak-Key and Related-Key Analysis of Hash-Counter-Hash Tweakable Enciphering Schemes",
  pages =        "3--19",
  doi =          "10.1007/978-3-319-19962-7_1",
  crossref =     acisp15,
}

@Proceedings{ACISP15,
  title =        acisp15name,
  editor =       acisp15ed,
  booktitle =    acisp15name,
  volume =       acisp15vol,
  address =      acisp15addr,
  month =        acisp15month,
  publisher =    acisppub,
  series =       mylncs,
  year =         2015,
  key =          acisp15key,
}

note that BibTeX's @string are used extensively here: to crossreference the proceedings and to populate other fields. It would thus be great if parsebib could support performing the relevant string replacements. Otherwise, the result lacks cross references etc.

joostkremers commented 7 years ago

Thanks for the explanation. I'm afraid, though, that given the way parsebib works, it's not even possible to implement such string replacements.

parsebib just reads a single entry (or @preamble or @string) at a time, returns it to the caller and then forgets about it. So when an entry is read that uses a string abbreviation, parsebib only has access to the entry itself, not to the @string definition that would be needed to replace the abbreviation.

The goal of parsebib is simply to read the contents of a .bib file and make it available to the caller. (Admittedly, a better name for the library might have been readbib...) Any operations on said contents are, IMHO, up to the caller.

I wrote parsebib that way because I needed a set of low-level functions for reading .bib files that provided a clear and consistent interface. bibtex.el, which I also considered using, is much more sophisticated, but also very much geared toward bibtex-mode.

I not against adding more high-level functionality to parsebib, but I can't make any promises. Pull requests would certainly be welcome. :wink:

tmalsburg commented 7 years ago

Thanks for the explanation, Joost. I suppose that string resolution is something that most or all users of parsebib eventually need. So perhaps it makes more sense to add it in parsebib than in helm-bibtex. Is there code in Ebib that might be relevant?

malb commented 7 years ago

How about something in between: extend the API of parsebib to accept an optional hashtable with @string, value pairs. This table is used to perform replacement if provided. However, maintaining/building such a hash table is the job of the user, this is case helm-bibtex.

tmalsburg commented 7 years ago

I like that idea because it's minimally invasive. But why not add the function for constructing the hash table to parsebib. This way it would also be useful for others.

joostkremers commented 7 years ago

I had the same idea initially, but it raises a few questions. For parsebib to maintain the hash table of @string definitions, it would need to know about all relevant .bib files, because @string definitions do not have to be defined in the same .bib file in which they are used, as long as the file with the definitions is passed to BibTeX first. Furthermore, there would have to be some mechanism for parsebib to determine whether to reread the .bib files, because the user may edit them and so the @string definitions may change.

Right now, this functionality is part of helm-bibtex and also of Ebib, though each does it in its own way. As it stands, then, it would probably make more sense for helm-bibtex / Ebib to maintain the hash table of @strings and pass that to parsebib-read-entry if they want string expansion to take place. parsebib would then be responsible for the actual string expansion.

As long as @string definitions appear in the .bib file before they are used (which I think is a prerequisite for BibTeX anyway), this should work.

We could of course move all that functionality into parsebib, but since Ebib and helm-bibtex each have their own way of doing these things, we would have to find some way that works for both of us. It would probably be easier and quicker to have helm-bibtex maintain a hash table of @strings itself. :smile:

tmalsburg commented 7 years ago

It would probably be easier and quicker to have helm-bibtex maintain a hash table of @strings itself.

Hm, there is probably one correct way to do this and both ebib and helm-bibtex should implement that, but tbh I don't know what the correct way is. So agree that this issue should not be handled in parsebib entirely (at least not at this time).

However, It might still make sense to (i) have a function in parsebib for extracting the string definitions from a specific file, and (ii) have the ability to pass a hash-table with string definitions to parsebib when reading entries as suggested by @malb. Do you agree?

joostkremers commented 7 years ago

Yes, I agree those would be good to have. If either of you want to give it a shot, I'll be happy to accept a PR. If not, I'll see if I have some time to implement it myself.

In fact, I think implementing (i) would actually be a first step towards a slightly higher-level API, because right now, all parsebib functions rely on the position of point, which a function to collect all @strings wouldn't. Given such a function, it would make sense to have similar functions for the other elements in a .bib file, and also a function that returns all data in the .bib file in one go.

Anyway, we (I :smile:) can worry about that later.

tmalsburg commented 7 years ago

Sounds good, but I should say that I wont have the time to work on this anytime soon. My emacs-related todo list is long enough as it is, and I'm not using string variables in my bibliography, so it's not pressing for me.

joostkremers commented 7 years ago

Sure, no worries. Don't have much time myself, but I've put it on my to do list.

malb commented 7 years ago

This can be closed to. Thank you!