diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 7525126e1..dab48b961 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -6,7 +6,7 @@ % \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{sphinx}[2008/05/01 LaTeX package (Sphinx markup)] +\ProvidesPackage{sphinx}[2010/01/15 LaTeX package (Sphinx markup)] \RequirePackage{textcomp} \RequirePackage{fancyhdr} @@ -193,7 +193,9 @@ \index{#4!#1 #2 #3} } -% support for the module index + +% Support for the module index. +% \newif\ifpy@UseModuleIndex \py@UseModuleIndexfalse @@ -207,7 +209,7 @@ \@input@{mod\jobname.ind} } -% Add the defining entry for a module +% Add the defining entry for a module. \newcommand{\py@modindex}[2]{% \renewcommand{\py@thismodule}{#1} \ifpy@UseModuleIndex% @@ -220,7 +222,6 @@ } % "Current" keys -\newcommand{\py@thisclass}{} \newcommand{\py@thismodule}{} \newcommand{\py@thismodulekey}{} \newcommand{\py@thismoduletype}{} @@ -238,7 +239,7 @@ %\label{module-\py@thismodulekey} } -% Record module platforms for the Module Index +% Record module platforms for the Module Index. \newif\ifpy@ModPlatformFileIsOpen \py@ModPlatformFileIsOpenfalse \long\def\py@writeModPlatformFile#1{% \protected@write\py@ModPlatformFile% @@ -270,7 +271,6 @@ % Reset "current" objects. \newcommand{\resetcurrentobjects}{ - \renewcommand{\py@thisclass}{} \renewcommand{\py@thismodule}{} \renewcommand{\py@thismodulekey}{} \renewcommand{\py@thismoduletype}{} @@ -287,14 +287,7 @@ \titleformat{\paragraph}{\large\py@HeaderFamily}% {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor} - -% Now for a lot of semantically-loaded environments that do a ton of magical -% things to get the right formatting and index entries for the stuff in -% Python modules and C API. - - -% {fulllineitems} is used in one place in libregex.tex, but is really for -% internal use in this file. +% {fulllineitems} is the main environment for object descriptions. % \newcommand{\py@itemnewline}[1]{% \@tempdima\linewidth% @@ -308,223 +301,22 @@ \let\makelabel=\py@itemnewline} }{\end{list}} -% \optional is mostly for use in the arguments parameters to the various -% {*desc} environments defined below, but may be used elsewhere. Known to -% be used in the debugger chapter. -% -% Typical usage: -% -% \begin{funcdesc}{myfunc}{reqparm\optional{, optparm}} -% ^^^ ^^^ -% No space here No space here -% -% When a function has multiple optional parameters, \optional should be -% nested, not chained. This is right: -% -% \begin{funcdesc}{myfunc}{\optional{parm1\optional{, parm2}}} -% \let\py@badkey=\@undefined +% \optional is used for ``[, arg]``, i.e. desc_optional nodes. \newcommand{\optional}[1]{% {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}} -% This can be used when a function or method accepts an varying number -% of arguments, such as by using the *args syntax in the parameter list. -\newcommand{\py@moreargs}{...} - -% This can be used when you don't want to document the parameters to a -% function or method, but simply state that it's an alias for -% something else. -\newcommand{\py@unspecified}{...} - -\newcommand{\py@varvars}[1]{{% - {\let\unspecified=\py@unspecified% - \let\moreargs=\py@moreargs% - \emph{#1}}}} - \newlength{\py@argswidth} \newcommand{\py@sigparams}[1]{% - \parbox[t]{\py@argswidth}{\py@varvars{#1}\code{)}}} -\newcommand{\py@sigline}[2]{% + \parbox[t]{\py@argswidth}{#1\code{)}}} +\newcommand{\pysigline}[1]{\item[#1]\nopagebreak} +\newcommand{\pysiglinewithargs}[2]{% \settowidth{\py@argswidth}{#1\code{(}}% \addtolength{\py@argswidth}{-2\py@argswidth}% \addtolength{\py@argswidth}{\textwidth}% \item[#1\code{(}\py@sigparams{#2}]} -% C functions ------------------------------------------------------------ -% \begin{cfuncdesc}[refcount]{type}{name}{arglist} -% Note that the [refcount] slot should only be filled in by -% tools/anno-api.py; it pulls the value from the refcounts database. -\newcommand{\cfuncline}[3]{ - \py@sigline{\code{#1 \bfcode{#2}}}{#3}% -} -\newenvironment{cfuncdesc}[3]{ - \begin{fulllineitems} - \cfuncline{#1}{#2}{#3} -}{\end{fulllineitems}} - -% C variables ------------------------------------------------------------ -% \begin{cvardesc}{type}{name} -\newenvironment{cvardesc}[2]{ - \begin{fulllineitems} - \item[\code{#1 \bfcode{#2}}] -}{\end{fulllineitems}} - -% C data types ----------------------------------------------------------- -% \begin{ctypedesc}[index name]{typedef name} -\newenvironment{ctypedesc}[2][\py@badkey]{ - \begin{fulllineitems} - \item[\bfcode{#2}] -}{\end{fulllineitems}} - -% C type fields ---------------------------------------------------------- -% \begin{cmemberdesc}{container type}{ctype}{membername} -\newcommand{\cmemberline}[3]{ - \item[\code{#2 \bfcode{#3}}] -} -\newenvironment{cmemberdesc}[3]{ - \begin{fulllineitems} - \cmemberline{#1}{#2}{#3} -}{\end{fulllineitems}} - -% Funky macros ----------------------------------------------------------- -% \begin{csimplemacrodesc}{name} -% -- "simple" because it has no args; NOT for constant definitions! -\newenvironment{csimplemacrodesc}[1]{ - \begin{fulllineitems} - \item[\bfcode{#1}] -}{\end{fulllineitems}} - -% simple functions (not methods) ----------------------------------------- -% \begin{funcdesc}{name}{args} -\newcommand{\funcline}[2]{% - \py@sigline{\bfcode{#1}}{#2}} -\newenvironment{funcdesc}[2]{ - \begin{fulllineitems} - \funcline{#1}{#2} -}{\end{fulllineitems}} - -% classes ---------------------------------------------------------------- -% \begin{classdesc}{name}{constructor args} -\newcommand{\classline}[2]{ - \py@sigline{\strong{class }\bfcode{#1}}{#2}} -\newenvironment{classdesc}[2]{ - % Using \renewcommand doesn't work for this, for unknown reasons: - \global\def\py@thisclass{#1} - \begin{fulllineitems} - \classline{#1}{#2} -}{\end{fulllineitems}} - -% \begin{excclassdesc}{name}{constructor args} -% but indexes as an exception -\newenvironment{excclassdesc}[2]{ - % Using \renewcommand doesn't work for this, for unknown reasons: - \global\def\py@thisclass{#1} - \begin{fulllineitems} - \py@sigline{\strong{exception }\bfcode{#1}}{#2}% -}{\end{fulllineitems}} - -% There is no corresponding {excclassdesc*} environment. To describe -% a class exception without parameters, use the {excdesc} environment. - - -\let\py@classbadkey=\@undefined - -% object method ---------------------------------------------------------- -% \begin{methoddesc}[classname]{methodname}{args} -\newcommand{\methodline}[3][\@undefined]{ - \py@sigline{\bfcode{#2}}{#3}} -\newenvironment{methoddesc}[3][\@undefined]{ - \begin{fulllineitems} - \ifx\@undefined#1\relax - \methodline{#2}{#3} - \else - \def\py@thisclass{#1} - \methodline{#2}{#3} - \fi -}{\end{fulllineitems}} - -% static method ---------------------------------------------------------- -% \begin{staticmethoddesc}[classname]{methodname}{args} -\newcommand{\staticmethodline}[3][\@undefined]{ - \py@sigline{static \bfcode{#2}}{#3}} -\newenvironment{staticmethoddesc}[3][\@undefined]{ - \begin{fulllineitems} - \ifx\@undefined#1\relax - \staticmethodline{#2}{#3} - \else - \def\py@thisclass{#1} - \staticmethodline{#2}{#3} - \fi -}{\end{fulllineitems}} - -% class method ---------------------------------------------------------- -% \begin{classmethoddesc}[classname]{methodname}{args} -\newcommand{\classmethodline}[3][\@undefined]{ - \py@sigline{class \bfcode{#2}}{#3}} -\newenvironment{classmethoddesc}[3][\@undefined]{ - \begin{fulllineitems} - \ifx\@undefined#1\relax - \classmethodline{#2}{#3} - \else - \def\py@thisclass{#1} - \classmethodline{#2}{#3} - \fi -}{\end{fulllineitems}} - -% object data attribute -------------------------------------------------- -% \begin{memberdesc}[classname]{membername} -\newcommand{\memberline}[2][\py@classbadkey]{% - \ifx\@undefined#1\relax - \item[\bfcode{#2}] - \else - \item[\bfcode{#2}] - \fi -} -\newenvironment{memberdesc}[2][\py@classbadkey]{ - \begin{fulllineitems} - \ifx\@undefined#1\relax - \memberline{#2} - \else - \def\py@thisclass{#1} - \memberline{#2} - \fi -}{\end{fulllineitems}} - -% For exceptions: -------------------------------------------------------- -% \begin{excdesc}{name} -% -- for constructor information, use excclassdesc instead -\newenvironment{excdesc}[1]{ - \begin{fulllineitems} - \item[\strong{exception }\bfcode{#1}] -}{\end{fulllineitems}} - -% Module data or constants: ---------------------------------------------- -% \begin{datadesc}{name} -\newcommand{\dataline}[1]{% - \item[\bfcode{#1}]\nopagebreak} -\newenvironment{datadesc}[1]{ - \begin{fulllineitems} - \dataline{#1} -}{\end{fulllineitems}} - -% bytecode instruction --------------------------------------------------- -% \begin{opcodedesc}{name}{var} -% -- {var} may be {} -\newenvironment{opcodedesc}[2]{ - \begin{fulllineitems} - \item[\bfcode{#1}\quad\emph{#2}] -}{\end{fulllineitems}} - -% generic description ---------------------------------------------------- -\newcommand{\descline}[1]{% - \item[\bfcode{#1}]\nopagebreak% -} -\newenvironment{describe}[1]{ - \begin{fulllineitems} - \descline{#1} -}{\end{fulllineitems}} - % This version is being checked in for the historical record; it shows % how I've managed to get some aspects of this to work. It will not % be used in practice, so a subsequent revision will change things @@ -535,7 +327,8 @@ \newcommand{\grammartoken}[1]{\texttt{#1}} \newenvironment{productionlist}[1][\py@badkey]{ \def\optional##1{{\Large[}##1{\Large]}} - \def\production##1##2{\code{##1}&::=&\code{##2}\\} + \def\production##1##2{\hypertarget{grammar-token-##1}{}% + \code{##1}&::=&\code{##2}\\} \def\productioncont##1{& &\code{##1}\\} \def\token##1{##1} \let\grammartoken=\token diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 86c819f27..44d8fc7ad 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -121,14 +121,6 @@ class Table(object): self.longtable = False -class Desc(object): - def __init__(self, node): - self.env = LaTeXTranslator.desc_map.get(node['objtype'], 'describe') - self.type = self.cls = self.name = self.params = \ - self.annotation = self.returns = '' - self.count = 0 - - class LaTeXTranslator(nodes.NodeVisitor): sectionnames = ["part", "chapter", "section", "subsection", "subsubsection", "paragraph", "subparagraph"] @@ -248,6 +240,7 @@ class LaTeXTranslator(nodes.NodeVisitor): self.literal_whitespace = 0 self.no_contractions = 0 self.compact_list = 0 + self.first_param = 0 def astext(self): return (HEADER % self.elements + self.highlighter.get_stylesheet() + @@ -434,139 +427,76 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_subtitle(self, node): self.body.append(self.context.pop()) - # XXX update this - desc_map = { - 'function' : 'funcdesc', - 'class': 'classdesc', - 'method': 'methoddesc', - 'classmethod': 'classmethoddesc', - 'staticmethod': 'staticmethoddesc', - 'exception': 'excdesc', - 'data': 'datadesc', - 'attribute': 'memberdesc', - 'opcode': 'opcodedesc', - - 'cfunction': 'cfuncdesc', - 'cmember': 'cmemberdesc', - 'cmacro': 'csimplemacrodesc', - 'ctype': 'ctypedesc', - 'cvar': 'cvardesc', - - 'describe': 'describe', - # and all others are 'describe' too - } - def visit_desc(self, node): - self.descstack.append(Desc(node)) + self.body.append('\n\n\\begin{fulllineitems}\n') def depart_desc(self, node): - d = self.descstack.pop() - self.body.append("\\end{%s}\n" % d.env) + self.body.append('\n\\end{fulllineitems}\n\n') def visit_desc_signature(self, node): - d = self.descstack[-1] - # reset these for every signature - d.type = d.cls = d.name = d.params = '' - def depart_desc_signature(self, node): - d = self.descstack[-1] - d.cls = d.cls.rstrip('.') if node.parent['objtype'] != 'describe' and node['ids']: hyper = '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) else: hyper = '' - if d.count == 0: - t1 = "\n\n%s\\begin{%s}" % (hyper, d.env) + self.body.append(hyper) + for child in node: + if isinstance(child, addnodes.desc_parameterlist): + self.body.append(r'\pysiglinewithargs{') + break else: - t1 = "\n%s\\%sline" % (hyper, d.env[:-4]) - d.count += 1 - if d.env in ('funcdesc', 'classdesc', 'excclassdesc'): - t2 = "{%s}{%s}" % (d.name, d.params) - elif d.env in ('datadesc', 'excdesc', 'csimplemacrodesc'): - t2 = "{%s}" % (d.name) - elif d.env in ('methoddesc', 'classmethoddesc', 'staticmethoddesc'): - if d.cls: - t2 = "[%s]{%s}{%s}" % (d.cls, d.name, d.params) - else: - t2 = "{%s}{%s}" % (d.name, d.params) - elif d.env == 'memberdesc': - if d.cls: - t2 = "[%s]{%s}" % (d.cls, d.name) - else: - t2 = "{%s}" % d.name - elif d.env == 'cfuncdesc': - if d.cls: - # C++ class names - d.name = '%s::%s' % (d.cls, d.name) - t2 = "{%s}{%s}{%s}" % (d.type, d.name, d.params) - elif d.env == 'cmemberdesc': - try: - type, container = d.type.rsplit(' ', 1) - container = container.rstrip('.') - except ValueError: - container = '' - type = d.type - t2 = "{%s}{%s}{%s}" % (container, type, d.name) - elif d.env == 'cvardesc': - t2 = "{%s}{%s}" % (d.type, d.name) - elif d.env == 'ctypedesc': - t2 = "{%s}" % (d.name) - elif d.env == 'opcodedesc': - t2 = "{%s}{%s}" % (d.name, d.params) - elif d.env == 'describe': - t2 = "{%s}" % d.name - self.body.append(t1 + t2) - - def visit_desc_type(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += self.encode(node.astext()) - else: - self.descstack[-1].type = self.encode(node.astext().strip()) - raise nodes.SkipNode - - def visit_desc_returns(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += ' $\\rightarrow$ ' + self.encode(node.astext()) - else: - self.descstack[-1].returns = self.encode(node.astext().strip()) - raise nodes.SkipNode - - def visit_desc_name(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += self.encode(node.astext()) - else: - self.descstack[-1].name = self.encode(node.astext().strip()) - raise nodes.SkipNode + self.body.append(r'\pysigline{') + def depart_desc_signature(self, node): + self.body.append('}') def visit_desc_addname(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += self.encode(node.astext()) - else: - self.descstack[-1].cls = self.encode(node.astext().strip()) - raise nodes.SkipNode + self.body.append(r'\code{') + self.literal_whitespace += 1 + def depart_desc_addname(self, node): + self.body.append('}') + self.literal_whitespace -= 1 + + def visit_desc_type(self, node): + pass + def depart_desc_type(self, node): + pass + + def visit_desc_returns(self, node): + self.body.append(r' $\rightarrow$ ') + def depart_desc_returns(self, node): + pass + + def visit_desc_name(self, node): + self.body.append(r'\bfcode{') + self.literal_whitespace += 1 + def depart_desc_name(self, node): + self.body.append('}') + self.literal_whitespace -= 1 def visit_desc_parameterlist(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += self.encode(node.astext()) + self.body.append('}{') + self.first_param = 1 + def depart_desc_parameterlist(self, node): + pass + + def visit_desc_parameter(self, node): + if not self.first_param: + self.body.append(', ') else: - self.descstack[-1].params = self.encode(node.astext().strip()) - raise nodes.SkipNode + self.first_param = 0 + if not node.hasattr('noemph'): + self.body.append(r'\emph{') + def depart_desc_parameter(self, node): + if not node.hasattr('noemph'): + self.body.append('}') + + def visit_desc_optional(self, node): + self.body.append(r'\optional{') + def depart_desc_optional(self, node): + self.body.append('}') def visit_desc_annotation(self, node): - d = self.descstack[-1] - if d.env == 'describe': - d.name += self.encode(node.astext()) - else: - self.descstack[-1].annotation = self.encode(node.astext().strip()) - raise nodes.SkipNode - - def visit_refcount(self, node): - self.body.append("\\emph{") - def depart_refcount(self, node): - self.body.append("}\\\\") + self.body.append(r'\strong{') + def depart_desc_annotation(self, node): + self.body.append('}') def visit_desc_content(self, node): if node.children and not isinstance(node.children[0], nodes.paragraph): @@ -575,6 +505,11 @@ class LaTeXTranslator(nodes.NodeVisitor): def depart_desc_content(self, node): pass + def visit_refcount(self, node): + self.body.append("\\emph{") + def depart_refcount(self, node): + self.body.append("}\\\\") + def visit_seealso(self, node): self.body.append("\n\n\\strong{%s:}\n\n" % admonitionlabels['seealso']) def depart_seealso(self, node): @@ -884,7 +819,7 @@ class LaTeXTranslator(nodes.NodeVisitor): pre.append(align_prepost[is_inline, attrs['align']][0]) post.append(align_prepost[is_inline, attrs['align']][1]) except KeyError: - pass # XXX complain here? + pass if not is_inline: pre.append('\n') post.append('\n') @@ -1194,9 +1129,9 @@ class LaTeXTranslator(nodes.NodeVisitor): * serif typeface """ self.body.append('{\\raggedright{}') - self.literal_whitespace = 1 + self.literal_whitespace += 1 def depart_line_block(self, node): - self.literal_whitespace = 0 + self.literal_whitespace -= 1 # remove the last \\ del self.body[-1] self.body.append('}\n')