We put much effort on improving the design and we made great progress. Currently, the design is the follwing (I hope, we can keep that).
citable.py
Contains all the meta-class-magic: CitationBase provides some basic functions, LoadableCitation can load the bib-file using pybtex, if the citation is needed. Then, it will change the class (!) of the element to Citation, which can print the citation using pybtex. We get a cache for free.
The class Citable: all classes representing cit-able elements in sage (citables.py) inherit from this class. They all have the (meta-)class LoadableCitation, when they are created. They can specify a type (default: software) and a filename to the bib-file (if it differs from the class' name).
citables.py
from citable import Citable
class singular(Citable):
pass
class magma(Citable):
pass
class slimgb(singular)
passNote, that the code only holds the dependencies of citations, the rest is done automatically. (There are more examples below.)citation.pyx
A cython-file containing the "ugly stuff". You can decorate your own function with @use_citation(citable). If the function is called, the citation will be added to the set of used citations. You can also manually add to this set by calling used_citations(citable). If you want to get all the used citations, simply call: print used_citations and it will give you back all you need (for this sage-session).
You can also refer to all formats supported by pybtex (bibtex, bibtexml, bibyaml, latex, html, plaintext) by calling used_citations.print_all(format).
>>> @use_citation(citables.magma)
... def simple_func():
... pass
>>> print used_citations
None
>>> simple_func()
>>> print used_citations
@article{
MR1484478,
author = "Bosma, Wieb and Cannon, John and Playoust, Catherine",
volume = "24",
doi = "10.1006/jsco.1996.0125",
title = "The {M}agma algebra system. {I}. {T}he user language",
url = "http://dx.doi.org/10.1006/jsco.1996.0125",
journal = "J. Symbolic Comput.",
issn = "0747-7171",
mrclass = "68Q40",
number = "3-4",
note = "Computational algebra and number theory (London, 1993)",
mrnumber = "MR1484478",
year = "1997",
pages = "235--265",
fjournal = "Journal of Symbolic Computation"
}
>>> print used_citations.print_all("latex")
\begin{thebibliography}{8}
\bibitem[1]{MR1484478}
Wieb Bosma, John Cannon, and Catherine Playoust.
\newblock The {M}agma algebra system. {I}. {T}he user language.
\newblock \emph{J. Symbolic Comput.}, 24:235--265, 1997.
\end{thebibliography}Dependencies of citations are also possible.
>>> used_citations.forget()
>>> used_citations(citables.slimgb)
>>> used_citations.format = "latex"
>>> print used_citations
\begin{thebibliography}{8}
\bibitem[1]{DGPS}
W.~Decker, G.-M. Greuel, G.~Pfister, and H.~Sch\"{o}nemann.
\newblock {\sc Singular} {3-1-3} --- {A} computer algebra system for polynomial computations.
\newblock 2011, http://www.singular.uni-kl.de.
\bibitem[2]{slimgbrevista}
Michael Brickenstein.
\newblock Slimgb: {G}r{\"o}bner bases with slim polynomials.
\newblock \emph{Revista Matemática Complutense}, 23, issue 2:453--466, 2010.
\end{thebibliography}There is a logging feature, which I'm not happy about yet. Furthermore, the documentation needs huge improvements.
It is very interesting to see, how the low-level stuff like cython-optimization, calling directly into Sets and Tuples, works so well together with high-level magic like metaclasses, changing a class' (meta-)class.