4

I want to take a file of one or more bibtex entries and output it as an html-formatted string. The specific style is not so important, but let's just say APA. Basically, I want the functionality of bibtex2html but with a Python API since I'm working in Django. A few people have asked similar questions here and here. I also found someone who provided a possible solution here.

The first issue I'm having is pretty basic, which is that I can't even get the above solutions to run. I keep getting errors similar to ModuleNotFoundError: No module named 'pybtex.database'; 'pybtex' is not a package. I definitely have pybtex installed and can make basic API calls in the shell no problem, but whenever I try to import pybtex.database.whatever or pybtex.plugin I keep getting ModuleNotFound errors. Is it maybe a python 2 vs python 3 thing? I'm using the latter.

The second issue is that I'm having trouble understanding the pybtex python API documentation. Specifically, from what I can tell it looks like the format_from_string and format_from_file calls are designed specifically for what I want to do, but I can't seem to get the syntax correct. Specifically, when I do

pybtex.format_from_file('foo.bib',style='html')

I get pybtex.plugin.PluginNotFound: plugin pybtex.style.formatting.html not found. I think I'm just not understanding how the call is supposed to work, and I can't find any examples of how to do it properly.

Ender
  • 95
  • 9

1 Answers1

2

Here's a function I wrote for a similar use case--incorporating bibliographies into a website generated by Pelican.

from pybtex.plugin import find_plugin
from pybtex.database import parse_string
APA = find_plugin('pybtex.style.formatting', 'apa')()
HTML = find_plugin('pybtex.backends', 'html')()

def bib2html(bibliography, exclude_fields=None):
    exclude_fields = exclude_fields or []
    if exclude_fields:
        bibliography = parse_string(bibliography.to_string('bibtex'), 'bibtex')
        for entry in bibliography.entries.values():
            for ef in exclude_fields:
                if ef in entry.fields.__dict__['_dict']:
                    del entry.fields.__dict__['_dict'][ef]
    formattedBib = APA.format_bibliography(bibliography)
    return "<br>".join(entry.text.render(HTML) for entry in formattedBib)

Make sure you've installed the following:

pybtex==0.22.2
pybtex-apa-style==1.3
cproctor
  • 175
  • 8
  • Your script works very nicely. exclude_fields seems to be requiring a list variable - and it is indeed very handy to feed a list of "unwanted" keys to that def. It is a very fast and effective way of controlling the output style of a bibliography to HTML, without the need of modifying the style, per se, in some cases. – jaggedjava Nov 27 '21 at 18:11
  • By the way, to get a numbered list in HTML, the following worked at least for me. Suppose your bibliography variable is called _data_. `newdata = bib2html(data)` `newdata = newdata.replace("
    ","
  • ")` `newdata = '
    1. ' + newdata + '
    '`
  • – jaggedjava Nov 27 '21 at 18:38