diff --git a/CHANGES b/CHANGES index c728c9845..7326aa7e9 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,27 @@ Release 0.5 (in development) 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: - 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 ``PickleHTMLBuilder`` is a concrete subclass of it that uses pickle as serialization implementation. - + - ``JSONHTMLBuilder`` was added as another ``SerializingHTMLBuilder`` subclass that dumps the generated HTML into JSON files for further processing. @@ -35,7 +56,7 @@ New features added definition links. * New and changed config values: - + - Added support for internationalization in generated text with the ``language`` and ``locale_dirs`` config values. Many thanks to language contributors: @@ -91,19 +112,6 @@ New features added * 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, you can call ``python setup.py build_sphinx`` for projects that have 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 project, complain and abort. - - Added ``cmember`` role for consistency. - Bugs fixed ---------- diff --git a/doc/rest.rst b/doc/rest.rst index 9820aea28..6040c72ef 100644 --- a/doc/rest.rst +++ b/doc/rest.rst @@ -240,17 +240,34 @@ the former, while the HTML builder would prefer the latter. Footnotes --------- -For footnotes, use ``[#]_`` to mark the footnote location, and add the footnote -body at the bottom of the document after a "Footnotes" rubric heading, like so:: +For footnotes, use ``[#name]_`` to mark the footnote location, and add the +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 - .. [#] Text of the first footnote. - .. [#] Text of the second footnote. + .. [#f1] Text of the first 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 diff --git a/sphinx/environment.py b/sphinx/environment.py index 6d32ba4d7..b51c60fd8 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -138,12 +138,27 @@ class HandleCodeBlocks(Transform): nodes.doctest_block): 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): """ Add our own transforms. """ - transforms = [DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks] + transforms = [CitationReferences, DefaultSubstitutions, MoveModuleTargets, + HandleCodeBlocks] def get_transforms(self): return standalone.Reader.get_transforms(self) + self.transforms @@ -259,7 +274,7 @@ class BuildEnvironment: self.labels = {} # labelname -> docname, labelid, sectionname self.anonlabels = {} # labelname -> 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 self.indexentries = {} # docname -> list of @@ -530,6 +545,7 @@ class BuildEnvironment: self.create_title_from(docname, doctree) self.note_labels_from(docname, doctree) self.note_indexentries_from(docname, doctree) + self.note_citations_from(docname, doctree) self.build_toc_from(docname, doctree) # store time of reading, used to find outdated files @@ -714,6 +730,15 @@ class BuildEnvironment: for node in document.traverse(addnodes.index): 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): """Note a TOC tree directive in a document and gather information about file relations from it.""" @@ -943,7 +968,7 @@ class BuildEnvironment: 'meth', 'cfunc', 'cmember', 'cdata', 'ctype', 'cmacro')) 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 reftarget_roles.update(i[0] for i in additional_xref_types.values()) @@ -1009,6 +1034,9 @@ class BuildEnvironment: if typ == 'term': self.warn(fromdocname, 'term not in glossary: %s' % target, node.line) + elif typ == 'citation': + self.warn(fromdocname, 'citation not found: %s' % target, + node.line) newnode = contnode else: newnode = nodes.reference('', '') diff --git a/sphinx/texinputs/howto.cls b/sphinx/texinputs/howto.cls index 2f74c66fc..87d207d17 100644 --- a/sphinx/texinputs/howto.cls +++ b/sphinx/texinputs/howto.cls @@ -58,18 +58,6 @@ \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}{ \pagestyle{plain}}{ \pagestyle{normal}} % start this way; change for diff --git a/sphinx/texinputs/manual.cls b/sphinx/texinputs/manual.cls index 9a4c76062..f94ee6d62 100644 --- a/sphinx/texinputs/manual.cls +++ b/sphinx/texinputs/manual.cls @@ -101,15 +101,3 @@ % \renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}} \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} -} diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index f83bae06a..209c35f9d 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -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. \RequirePackage[colorlinks,breaklinks, linkcolor=InnerLinkColor,filecolor=OuterLinkColor, diff --git a/sphinx/textwriter.py b/sphinx/textwriter.py index 6afc28adc..0a418e6cd 100644 --- a/sphinx/textwriter.py +++ b/sphinx/textwriter.py @@ -252,6 +252,15 @@ class TextTranslator(nodes.NodeVisitor): def depart_footnote(self, node): 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): raise nodes.SkipNode @@ -584,6 +593,10 @@ class TextTranslator(nodes.NodeVisitor): self.add_text('[%s]' % node.astext()) raise nodes.SkipNode + def visit_citation_reference(self, node): + self.add_text('[%s]' % node.astext()) + raise nodes.SkipNode + def visit_Text(self, node): self.add_text(node.astext()) def depart_Text(self, node): diff --git a/tests/root/contents.txt b/tests/root/contents.txt index db6284819..e8e6a5644 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -23,3 +23,8 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` + +References +========== + +.. [Ref1] Reference target. diff --git a/tests/root/markup.txt b/tests/root/markup.txt index 8e74d5ef0..d16e57ef9 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -57,6 +57,8 @@ Misc stuff Stuff [#]_ +Reference lookup: [Ref1]_ (defined in another file). + .. seealso:: `Google `_ diff --git a/tests/test_build.py b/tests/test_build.py index 147d99fb9..21757e2c7 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -57,12 +57,16 @@ HTML_XPATH = { 'markup.html': { ".//meta[@name='author'][@content='Me']": '', ".//meta[@name='keywords'][@content='docs, sphinx']": '', + ".//a[@href='contents.html#ref1']": '', }, 'desc.html': { ".//dt[@id='mod.Cls.meth1']": '', ".//dt[@id='errmod.Error']": '', ".//a[@href='#mod.Cls']": '', }, + 'contents.html': { + ".//td[@class='label']": '[Ref1]', + }, } class NslessParser(ET.XMLParser):