Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust to breaking change in format_href in pybtex #16

Merged

Conversation

cpitclaudel
Copy link
Contributor

format_href gained an extra parameter in
https://bitbucket.org/pybtex-devs/pybtex/commits/a362ec5ca4052da459761c15e298d99a643a2413

Docutils doesn't support target="_blank" (https://stackoverflow.com/questions/11716781/open-a-link-in-a-new-window-in-restructuredtext), so just ignore the argument to restore compatibility.

@codecov
Copy link

codecov bot commented Sep 23, 2021

Codecov Report

Merging #16 (56d91df) into develop (14def3e) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##           develop       #16   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3         3           
  Lines          100       100           
=========================================
  Hits           100       100           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14def3e...56d91df. Read the comment docs.

@mcmtroffaes
Copy link
Owner

Thanks! Looks good for merging.

May I ask how you have tested this? E.g. sphinxcontrib-bibtex and pybtex from git? It would be great to also have something in the regression tests, and maybe add the pybtex git version to the CI workflow.

@cpitclaudel
Copy link
Contributor Author

May I ask how you have tested this? E.g. sphinxcontrib-bibtex and pybtex from git?

With Docutils directly (rst2html5.py), so pybtex-docutils directly with pybtex from git. Here's the code:

driver.py

#!/usr/bin/env python3
from docutils.parsers.rst import directives, Directive
from docutils.core import publish_cmdline, default_description

import pybtex.plugin
import pybtex.database
import pybtex_docutils

class Bibliography(Directive):
    required_arguments = 1
    final_argument_whitespace = False
    has_content = False

    name = "bibliography"

    def run(self):
        bibfile = self.arguments[0]
        bib = pybtex.database.parse_file(bibfile)
        style = pybtex.plugin.find_plugin('pybtex.style.formatting', 'plain')()
        fmt = style.format_bibliography(bib)
        backend = pybtex_docutils.Backend()
        document = self.state_machine.document
        return [backend.citation(e, document) for e in fmt]

description = ('Like rst2html5.py, but with support for a .. bibliography '
               + default_description)

if __name__ == '__main__':
    directives.register_directive("bibliography", Bibliography)
    publish_cmdline(writer_name='html5', description=description)

example.bib

@InProceedings{Example,
  author       = {Me},
  title        = {Example},
  booktitle    = {Proceedings},
  year         = 2021
}

example.rst

Some test [Example]_.

.. bibliography:: minimal.bib

And the output:

<body>
<div class="document">


<p>Some test <a class="citation-reference" href="#example" id="id1">[Example]</a>.</p>
<dl class="citation">
<dt class="label" id="example"><span class="brackets"><a class="fn-backref" href="#id1">Example</a></span></dt>
<dd><p>Me. Example. In <em>Proceedings</em>. 2021.</p>
</dd>
</dl>
</div>
</body>

@cpitclaudel
Copy link
Contributor Author

(It took me a while to figure the API out, btw. Maybe it would be worth adding a note to the pybtex-docutils readme about how this is mostly intended for use with Sphinx, but here's the way to use it with a custom Docutils driver?)

@cpitclaudel
Copy link
Contributor Author

In fact, it would be even better if pybtex-docutils had a directive like the bibliography above. Maybe it would be enough to move the non-Sphinx-specific parts of sphinxcontrib-bibtex to pybtex-docutils? That would make it much easier to use pybtex with plain Docutils (rst2html5, etc), which I imagine most users wouldn't know how to do at the moment.

@mcmtroffaes
Copy link
Owner

Well, sphinxcontrib-bibtex does expose a bibliography directive (and also a footbibliography directive, for when you want to generate citations as footnotes), however it's far more complex than what your example is doing, to the point where it wouldn't be possible to include in plain docutils. This said, I do like the example that you have, and it would make a nice addition. How should this directive be called? Maybe simplebibliography? Do you have other suggestions? I would try to avoid a name conflict with sphinxcontrib-bibtex.

Next, I'm honestly not familiar with extending docutils, but I'm keen to learn more about how that works. Is it customary for modules that extend docutils to register new roles and directives upon import? If so, do you know how that is meant to work, from plain docutils, and/or from sphinx? Is there for instance a setuptools entry point for this? Or are there other methods? I see that the driver code does the heavy lifting, but I've never seen anything like it, and I'm not sure how I'd need to use it. Does the driver.py file serve as a command? I apologize for the plethora of questions, however I'd really appreciate any guidance you could give.

@cpitclaudel
Copy link
Contributor Author

Well, sphinxcontrib-bibtex does expose a bibliography directive (and also a footbibliography directive, for when you want to generate citations as footnotes),

Yes, I love it :) We use it extensively in the documentation of the Coq proof assistant.

however it's far more complex than what your example is doing, to the point where it wouldn't be possible to include in plain docutils.

Indeed it does lots of fancy things. I wonder which ones couldn't be reproduced in Docutils, though.
(Of course, the multi-document aspects are Sphinx-specific)

This said, I do like the example that you have, and it would make a nice addition. How should this directive be called? Maybe simplebibliography? Do you have other suggestions? I would try to avoid a name conflict with sphinxcontrib-bibtex.

simplebibliography sounds good!

Next, I'm honestly not familiar with extending docutils, but I'm keen to learn more about how that works.

That was me a about a year ago :) I've used Sphinx extensively bu plain docutils, not so often. I'm using it a lot more these days because it excels at single-document pipelines (setting up Sphinx for a single document (think an academic publication, a blog post, etc.) is a pain.

Now, Docutils extension: it's great and it's terrible. On the one hand it's really easy to build applications that use the Docutils pipeline to compile documents, like all the blog engines, etc. On the other hand, Docutils doesn't really have a "no-code" way of doing extensions. So concretely, what you typically do is provide a single function to call to register your plugin — kinda like Sphinx' setup(app).

Most applications that extend docutils then have their own mechanisms to register plugins; for example Sphinx, but also Pelican.

Is it customary for modules that extend docutils to register new roles and directives upon import?

I think not; typically you require a function to be called. Different apps have different ways to do this though, like Sphinx' setup() or Pelican plugins.

If so, do you know how that is meant to work, from plain docutils, and/or from sphinx?

Usually I try to write most of my Docutils and Sphinx extensions pure Docutils, and then provide a small shim for Sphinx and other apps. In Alectryon for example I have almost all of the code on the Docutils side (https://github.com/cpitclaudel/alectryon/blob/master/alectryon/docutils.py) and a tiny shim on the Sphinx side (https://github.com/cpitclaudel/alectryon/blob/master/alectryon/sphinx.py), which covers places wherethe APIs differs, mainly ways to register directives and transforms, and configuration options.

And you often see me complaing on Github pages about incompatibilities :) sphinx-doc/sphinx#9632 executablebooks/MyST-Parser#426 executablebooks/MyST-Parser#420 etc.

Is there for instance a setuptools entry point for this? Or are there other methods?

Not that I know of; it's too bad. I've been pondering this for a while, and this discussion finally prompted passed the activation barrier ; see here: https://sourceforge.net/p/docutils/feature-requests/82/

I see that the driver code does the heavy lifting, but I've never seen anything like it, and I'm not sure how I'd need to use it. Does the driver.py file serve as a command?

Absolutely right! Check out the code of rst2html5.py, rst2latex,py, etc: they all use the publish_cmdline entry point of docutils. It's a really neat system. Check out https://docutils.sourceforge.io/docs/api/cmdline-tool.html and https://docutils.sourceforge.io/docs/api/publisher.html .

Cheers.

@mcmtroffaes
Copy link
Owner

Many thanks for the detailed response! I think that clears everything up. I've create a separate issue for this since this has gone slightly off track from the original href issue... 😄

@mcmtroffaes mcmtroffaes merged commit 86d7fee into mcmtroffaes:develop Sep 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants