Add global citations. #1.

This commit is contained in:
Georg Brandl
2008-10-25 15:54:34 +00:00
parent bcd1a78d83
commit 29a3a86cef
10 changed files with 121 additions and 50 deletions

40
CHANGES
View File

@@ -4,6 +4,27 @@ Release 0.5 (in development)
New features added New features added
------------------ ------------------
* Markup features:
- Citations are now global: all citation defined in any file can be
referenced from any file. Citations are collected in a bibliography
for LaTeX output.
- Footnotes are now properly handled in the LaTeX builder: they appear
at the location of the footnote reference in text, not at the end of
a section. Thanks to Andrew McNamara for the initial patch.
- "System Message" warnings are now automatically removed from the
built documentation, and only written to stderr. If you want the
old behavior, set the new config value ``keep_warnings`` to True.
- Glossary entries are now automatically added to the index.
- Figures with captions can now be referred to like section titles,
using the ``:ref:`` role without an explicit link text.
- Added ``cmember`` role for consistency.
* HTML output and templates: * HTML output and templates:
- Incompatible change: The "root" relation link (top left in the - Incompatible change: The "root" relation link (top left in the
@@ -22,7 +43,7 @@ New features added
can be subclassed to serialize build HTML in a specific format. The can be subclassed to serialize build HTML in a specific format. The
``PickleHTMLBuilder`` is a concrete subclass of it that uses pickle ``PickleHTMLBuilder`` is a concrete subclass of it that uses pickle
as serialization implementation. as serialization implementation.
- ``JSONHTMLBuilder`` was added as another ``SerializingHTMLBuilder`` - ``JSONHTMLBuilder`` was added as another ``SerializingHTMLBuilder``
subclass that dumps the generated HTML into JSON files for further subclass that dumps the generated HTML into JSON files for further
processing. processing.
@@ -35,7 +56,7 @@ New features added
definition links. definition links.
* New and changed config values: * New and changed config values:
- Added support for internationalization in generated text with the - Added support for internationalization in generated text with the
``language`` and ``locale_dirs`` config values. Many thanks to ``language`` and ``locale_dirs`` config values. Many thanks to
language contributors: language contributors:
@@ -91,19 +112,6 @@ New features added
* Other changes: * Other changes:
- Footnotes are now properly handled in the LaTeX builder: they appear
at the location of the footnote reference in text, not at the end of
a section. Thanks to Andrew McNamara for the initial patch.
- "System Message" warnings are now automatically removed from the
built documentation, and only written to stderr. If you want the
old behavior, set the new config value ``keep_warnings`` to True.
- Glossary entries are now automatically added to the index.
- Figures with captions can now be referred to like section titles,
using the ``:ref:`` role without an explicit link text.
- Added a distutils command `build_sphinx`: When Sphinx is installed, - Added a distutils command `build_sphinx`: When Sphinx is installed,
you can call ``python setup.py build_sphinx`` for projects that have you can call ``python setup.py build_sphinx`` for projects that have
Sphinx documentation, which will build the docs and place them in Sphinx documentation, which will build the docs and place them in
@@ -112,8 +120,6 @@ New features added
- In quickstart, if the selected root path already contains a Sphinx - In quickstart, if the selected root path already contains a Sphinx
project, complain and abort. project, complain and abort.
- Added ``cmember`` role for consistency.
Bugs fixed Bugs fixed
---------- ----------

View File

@@ -240,17 +240,34 @@ the former, while the HTML builder would prefer the latter.
Footnotes Footnotes
--------- ---------
For footnotes, use ``[#]_`` to mark the footnote location, and add the footnote For footnotes, use ``[#name]_`` to mark the footnote location, and add the
body at the bottom of the document after a "Footnotes" rubric heading, like so:: footnote body at the bottom of the document after a "Footnotes" rubric heading,
like so::
Lorem ipsum [#]_ dolor sit amet ... [#]_ Lorem ipsum [#f1]_ dolor sit amet ... [#f2]_
.. rubric:: Footnotes .. rubric:: Footnotes
.. [#] Text of the first footnote. .. [#f1] Text of the first footnote.
.. [#] Text of the second footnote. .. [#f2] Text of the second footnote.
You can also explicitly number the footnotes for better context. You can also explicitly number the footnotes (``[1]_``) or use auto-numbered
footnotes without names (``[#]_``).
Citations
---------
Standard reST citations are supported, with the additional feature that they are
"global", i.e. all citations can be referenced from all files. Use them like
so::
Lorem ipsum [Ref]_ dolor sit amet.
.. [Ref] Book or article reference, URL or whatever.
Citation usage is similar to footnote usage, but with a label that is not
numeric or begins with ``#``.
Comments Comments

View File

@@ -138,12 +138,27 @@ class HandleCodeBlocks(Transform):
nodes.doctest_block): nodes.doctest_block):
node.replace_self(node.children[0]) node.replace_self(node.children[0])
class CitationReferences(Transform):
"""
Handle citation references before the default docutils transform does.
"""
default_priority = 619
def apply(self):
for citnode in self.document.traverse(nodes.citation_reference):
cittext = citnode.astext()
refnode = addnodes.pending_xref(cittext, reftype='citation',
reftarget=cittext)
refnode += nodes.Text('[' + cittext + ']')
citnode.parent.replace(citnode, refnode)
class SphinxStandaloneReader(standalone.Reader): class SphinxStandaloneReader(standalone.Reader):
""" """
Add our own transforms. Add our own transforms.
""" """
transforms = [DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks] transforms = [CitationReferences, DefaultSubstitutions, MoveModuleTargets,
HandleCodeBlocks]
def get_transforms(self): def get_transforms(self):
return standalone.Reader.get_transforms(self) + self.transforms return standalone.Reader.get_transforms(self) + self.transforms
@@ -259,7 +274,7 @@ class BuildEnvironment:
self.labels = {} # labelname -> docname, labelid, sectionname self.labels = {} # labelname -> docname, labelid, sectionname
self.anonlabels = {} # labelname -> docname, labelid self.anonlabels = {} # labelname -> docname, labelid
self.reftargets = {} # (type, name) -> docname, labelid self.reftargets = {} # (type, name) -> docname, labelid
# where type is term, token, option, envvar # where type is term, token, option, envvar, citation
# Other inventories # Other inventories
self.indexentries = {} # docname -> list of self.indexentries = {} # docname -> list of
@@ -530,6 +545,7 @@ class BuildEnvironment:
self.create_title_from(docname, doctree) self.create_title_from(docname, doctree)
self.note_labels_from(docname, doctree) self.note_labels_from(docname, doctree)
self.note_indexentries_from(docname, doctree) self.note_indexentries_from(docname, doctree)
self.note_citations_from(docname, doctree)
self.build_toc_from(docname, doctree) self.build_toc_from(docname, doctree)
# store time of reading, used to find outdated files # store time of reading, used to find outdated files
@@ -714,6 +730,15 @@ class BuildEnvironment:
for node in document.traverse(addnodes.index): for node in document.traverse(addnodes.index):
entries.extend(node['entries']) entries.extend(node['entries'])
def note_citations_from(self, docname, document):
for node in document.traverse(nodes.citation):
label = node[0].astext()
if ('citation', label) in self.reftargets:
self.warn(docname, 'duplicate citation %s, ' % label +
'other instance in %s' % self.doc2path(
self.reftargets['citation', label][0]), node.line)
self.reftargets['citation', label] = (docname, node['ids'][0])
def note_toctree(self, docname, toctreenode): def note_toctree(self, docname, toctreenode):
"""Note a TOC tree directive in a document and gather information about """Note a TOC tree directive in a document and gather information about
file relations from it.""" file relations from it."""
@@ -943,7 +968,7 @@ class BuildEnvironment:
'meth', 'cfunc', 'cmember', 'cdata', 'ctype', 'cmacro')) 'meth', 'cfunc', 'cmember', 'cdata', 'ctype', 'cmacro'))
def resolve_references(self, doctree, fromdocname, builder): def resolve_references(self, doctree, fromdocname, builder):
reftarget_roles = set(('token', 'term', 'option')) reftarget_roles = set(('token', 'term', 'option', 'citation'))
# add all custom xref types too # add all custom xref types too
reftarget_roles.update(i[0] for i in additional_xref_types.values()) reftarget_roles.update(i[0] for i in additional_xref_types.values())
@@ -1009,6 +1034,9 @@ class BuildEnvironment:
if typ == 'term': if typ == 'term':
self.warn(fromdocname, 'term not in glossary: %s' % target, self.warn(fromdocname, 'term not in glossary: %s' % target,
node.line) node.line)
elif typ == 'citation':
self.warn(fromdocname, 'citation not found: %s' % target,
node.line)
newnode = contnode newnode = contnode
else: else:
newnode = nodes.reference('', '') newnode = nodes.reference('', '')

View File

@@ -58,18 +58,6 @@
\vspace{12pt} \vspace{12pt}
} }
% Fix the theindex environment to add an entry to the Table of Contents; this is
% much nicer than just having to jump to the end of the book and flip around,
% especially with multiple indexes.
%
\let\py@OldTheindex=\theindex
\renewcommand{\theindex}{
\clearpage
\phantomsection
\py@OldTheindex
\addcontentsline{toc}{section}{\indexname}
}
\@ifundefined{fancyhf}{ \@ifundefined{fancyhf}{
\pagestyle{plain}}{ \pagestyle{plain}}{
\pagestyle{normal}} % start this way; change for \pagestyle{normal}} % start this way; change for

View File

@@ -101,15 +101,3 @@
% %
\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}} \renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}
\renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}} \renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}
% Fix the theindex environment to add an entry to the Table of Contents; this is
% much nicer than just having to jump to the end of the book and flip around,
% especially with multiple indexes.
%
\let\py@OldTheindex=\theindex
\renewcommand{\theindex}{
\cleardoublepage
\phantomsection
\py@OldTheindex
\addcontentsline{toc}{chapter}{\indexname}
}

View File

@@ -682,6 +682,26 @@
} }
% Fix the index and bibliography environments to add an entry to the Table of
% Contents; this is much nicer than just having to jump to the end of the book
% and flip around, especially with multiple indexes.
%
\let\py@OldTheindex=\theindex
\renewcommand{\theindex}{
\cleardoublepage
\phantomsection
\py@OldTheindex
\addcontentsline{toc}{chapter}{\indexname}
}
\let\py@OldThebibliography=\thebibliography
\renewcommand{\thebibliography}[1]{
\cleardoublepage
\phantomsection
\py@OldThebibliography{1}
\addcontentsline{toc}{chapter}{\bibname}
}
% Include hyperref last. % Include hyperref last.
\RequirePackage[colorlinks,breaklinks, \RequirePackage[colorlinks,breaklinks,
linkcolor=InnerLinkColor,filecolor=OuterLinkColor, linkcolor=InnerLinkColor,filecolor=OuterLinkColor,

View File

@@ -252,6 +252,15 @@ class TextTranslator(nodes.NodeVisitor):
def depart_footnote(self, node): def depart_footnote(self, node):
self.end_state(first='[%s] ' % self._footnote) self.end_state(first='[%s] ' % self._footnote)
def visit_citation(self, node):
if len(node) and isinstance(node[0], nodes.label):
self._citlabel = node[0].astext()
else:
self._citlabel = ''
self.new_state(len(self._citlabel) + 3)
def depart_citation(self, node):
self.end_state(first='[%s] ' % self._citlabel)
def visit_label(self, node): def visit_label(self, node):
raise nodes.SkipNode raise nodes.SkipNode
@@ -584,6 +593,10 @@ class TextTranslator(nodes.NodeVisitor):
self.add_text('[%s]' % node.astext()) self.add_text('[%s]' % node.astext())
raise nodes.SkipNode raise nodes.SkipNode
def visit_citation_reference(self, node):
self.add_text('[%s]' % node.astext())
raise nodes.SkipNode
def visit_Text(self, node): def visit_Text(self, node):
self.add_text(node.astext()) self.add_text(node.astext())
def depart_Text(self, node): def depart_Text(self, node):

View File

@@ -23,3 +23,8 @@ Indices and tables
* :ref:`genindex` * :ref:`genindex`
* :ref:`modindex` * :ref:`modindex`
* :ref:`search` * :ref:`search`
References
==========
.. [Ref1] Reference target.

View File

@@ -57,6 +57,8 @@ Misc stuff
Stuff [#]_ Stuff [#]_
Reference lookup: [Ref1]_ (defined in another file).
.. seealso:: .. seealso::
`Google <http://www.google.com>`_ `Google <http://www.google.com>`_

View File

@@ -57,12 +57,16 @@ HTML_XPATH = {
'markup.html': { 'markup.html': {
".//meta[@name='author'][@content='Me']": '', ".//meta[@name='author'][@content='Me']": '',
".//meta[@name='keywords'][@content='docs, sphinx']": '', ".//meta[@name='keywords'][@content='docs, sphinx']": '',
".//a[@href='contents.html#ref1']": '',
}, },
'desc.html': { 'desc.html': {
".//dt[@id='mod.Cls.meth1']": '', ".//dt[@id='mod.Cls.meth1']": '',
".//dt[@id='errmod.Error']": '', ".//dt[@id='errmod.Error']": '',
".//a[@href='#mod.Cls']": '', ".//a[@href='#mod.Cls']": '',
}, },
'contents.html': {
".//td[@class='label']": '[Ref1]',
},
} }
class NslessParser(ET.XMLParser): class NslessParser(ET.XMLParser):