summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeorg.brandl <devnull@localhost>2007-12-16 19:36:23 +0000
committergeorg.brandl <devnull@localhost>2007-12-16 19:36:23 +0000
commitda99b69d74c741be960d0b473d65ae6609a0971c (patch)
treeb9c495469266078507093c08dd2833c9d5cd6688
parent8e2c44dc4bdb59dfb03f6b94776a91c1da797f2d (diff)
downloadsphinx-da99b69d74c741be960d0b473d65ae6609a0971c.tar.gz
Several improvements to the latex builder.
-rw-r--r--sphinx/addnodes.py5
-rw-r--r--sphinx/builder.py15
-rw-r--r--sphinx/directives.py7
-rw-r--r--sphinx/environment.py25
-rw-r--r--sphinx/htmlwriter.py7
-rw-r--r--sphinx/latexwriter.py44
-rw-r--r--sphinx/texinputs/Makefile50
-rw-r--r--sphinx/texinputs/python.sty4
8 files changed, 130 insertions, 27 deletions
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index 6fecb92f..1a49a682 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -64,10 +64,13 @@ class literal_emphasis(nodes.emphasis): pass
# glossary
class glossary(nodes.Element): pass
+# module declaration
+class module(nodes.Element): pass
+
# make them known to docutils. this is needed, because the HTMl writer
# will choke at some point if these are not added
nodes._add_node_class_names("""index desc desc_content desc_signature desc_type
desc_classname desc_name desc_parameterlist desc_parameter desc_optional
centered versionmodified seealso productionlist production toctree
pending_xref compact_paragraph highlightlang literal_emphasis
- glossary acks""".split())
+ glossary acks module""".split())
diff --git a/sphinx/builder.py b/sphinx/builder.py
index a864db21..1de29d64 100644
--- a/sphinx/builder.py
+++ b/sphinx/builder.py
@@ -223,8 +223,6 @@ class Builder(object):
# global actions
self.msg('checking consistency...')
self.env.check_consistency()
- self.msg('creating index...')
- self.env.create_index(self)
# another indirection to support methods which don't build files
# individually
@@ -236,6 +234,8 @@ class Builder(object):
self.msg('done!')
def write(self, filenames):
+ self.msg('creating index...')
+ self.env.create_index(self)
if filenames:
# add all TOC files that may have changed
filenames_set = set(filenames)
@@ -314,7 +314,7 @@ class StandaloneHTMLBuilder(Builder):
# format the "last updated on" string, only once is enough since it
# typically doesn't include the time of day
- lufmt = self.config.get('last_updated_format')
+ lufmt = self.config.get('html_last_updated_fmt')
if lufmt:
self.last_updated = time.strftime(lufmt)
else:
@@ -446,7 +446,7 @@ class StandaloneHTMLBuilder(Builder):
downloadcontext = dict(
pathto = relpath_to(self, self.get_target_uri('download.rst')),
current_page_name = 'download',
- download_base_url = self.config['download_base_url'],
+ download_base_url = self.config['html_download_base_url'],
)
self.handle_file('download.rst', downloadcontext, 'download')
@@ -490,8 +490,8 @@ class StandaloneHTMLBuilder(Builder):
for filename in get_matching_files(
self.srcdir, '*.rst', exclude=set(self.config.get('unused_files', ()))):
try:
- targetmtime = path.getmtime(path.join(self.outdir,
- os_path(filename)[:-4] + '.html'))
+ rstname = path.join(self.outdir, os_path(filename))
+ targetmtime = path.getmtime(rstname[:-4] + '.html')
except:
targetmtime = 0
if filename not in self.env.all_files:
@@ -652,7 +652,7 @@ class LaTeXBuilder(Builder):
def get_outdated_files(self):
# XXX always rebuild everything for now
- return self.env.all_files
+ return ['dummy']
def get_target_uri(self, source_filename, typ=None):
if typ == 'token':
@@ -665,6 +665,7 @@ class LaTeXBuilder(Builder):
return ''
def get_document_data(self):
+ # Python specific...
for toplevel in ["c-api", "distutils", "documenting", "extending",
"install", "reference", "tutorial", "using", "library"]:
yield (toplevel + SEP + 'index.rst', toplevel+'.tex', 'manual')
diff --git a/sphinx/directives.py b/sphinx/directives.py
index ca9cf856..d89b170f 100644
--- a/sphinx/directives.py
+++ b/sphinx/directives.py
@@ -518,11 +518,14 @@ def module_directive(name, arguments, options, content, lineno,
env.note_module(modname, options.get('synopsis', ''),
options.get('platform', ''),
'deprecated' in options)
- ret = []
+ modulenode = addnodes.module()
+ modulenode['modname'] = modname
+ modulenode['synopsis'] = options.get('synopsis', '')
targetnode = nodes.target('', '', ids=['module-' + modname])
state.document.note_explicit_target(targetnode)
- ret.append(targetnode)
+ ret = [modulenode, targetnode]
if 'platform' in options:
+ modulenode['platform'] = options['platform']
node = nodes.paragraph()
node += nodes.emphasis('Platforms: ', 'Platforms: ')
node += nodes.Text(options['platform'], options['platform'])
diff --git a/sphinx/environment.py b/sphinx/environment.py
index ac95feab..1d34fc18 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -260,7 +260,7 @@ class BuildEnvironment:
new = [change for change in changes if change[1] != filename]
changes[:] = new
- def get_outdated_files(self, config):
+ def get_outdated_files(self, config, config_changed):
"""
Return (added, changed, removed) iterables.
"""
@@ -273,7 +273,7 @@ class BuildEnvironment:
added = []
changed = []
- if config != self.config:
+ if config_changed:
# config values affect e.g. substitutions
added = all_source_files
else:
@@ -298,6 +298,11 @@ class BuildEnvironment:
return added, changed, removed
+ # If one of these config values changes, all files need to be re-read.
+ influential_config_values = [
+ 'version', 'release', 'today', 'today_fmt', 'unused_files'
+ ]
+
def update(self, config):
"""
(Re-)read all files new or changed since last update.
@@ -305,11 +310,17 @@ class BuildEnvironment:
Store all environment filenames in the canonical format
(ie using SEP as a separator in place of os.path.sep).
"""
- added, changed, removed = self.get_outdated_files(config)
- msg = '%s added, %s changed, %s removed' % (len(added), len(changed),
- len(removed))
- if self.config != config:
- msg = '[config changed] ' + msg
+ config_changed = False
+ for val in self.influential_config_values:
+ if self.config.get(val) != config.get(val):
+ msg = '[config changed] '
+ config_changed = True
+ break
+ else:
+ msg = ''
+ added, changed, removed = self.get_outdated_files(config, config_changed)
+ msg += '%s added, %s changed, %s removed' % (len(added), len(changed),
+ len(removed))
yield msg
self.config = config
diff --git a/sphinx/htmlwriter.py b/sphinx/htmlwriter.py
index 8468e7af..f6a60b9e 100644
--- a/sphinx/htmlwriter.py
+++ b/sphinx/htmlwriter.py
@@ -232,6 +232,11 @@ def translator_class(config, buildername):
def depart_acks(self, node):
pass
+ def visit_module(self, node):
+ pass
+ def depart_module(self, node):
+ pass
+
# these are only handled specially in the SmartyPantsHTMLTranslator
def visit_literal_emphasis(self, node):
return self.visit_emphasis(node)
@@ -297,7 +302,7 @@ def translator_class(config, buildername):
text = sphinx_smarty_pants(text)
return text
- if config.get('use_smartypants', False):
+ if config.get('html_use_smartypants', False):
return SmartyPantsHTMLTranslator
else:
return HTMLTranslator
diff --git a/sphinx/latexwriter.py b/sphinx/latexwriter.py
index efc0a346..63afd286 100644
--- a/sphinx/latexwriter.py
+++ b/sphinx/latexwriter.py
@@ -36,10 +36,11 @@ HEADER = r'''%% Generated by Sphinx.
Email: \email{docs@python.org}
}
\makeindex
-
+\makemodindex
'''
FOOTER = r'''
+\printmodindex
\printindex
\end{document}
'''
@@ -93,9 +94,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
nodes.NodeVisitor.__init__(self, document)
self.body = []
docclass = document.settings.docclass
+ paper = config.get('latex_paper_size', 'letter') + 'paper'
+ if paper == 'paper': # e.g. command line "-D latex_paper_size="
+ paper = 'letterpaper'
self.options = {'docclass': docclass,
- 'papersize': 'a4paper', # XXX
- 'pointsize': '12pt',
+ 'papersize': paper,
+ 'pointsize': config.get('latex_font_size', '10pt'),
'filename': document.settings.filename,
'title': None, # is determined later
'release': config['release'],
@@ -150,6 +154,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_section(self, node):
self.sectionlevel -= 1
+ def visit_problematic(self, node):
+ self.body.append('{\\color{red}\\bfseries{}')
+ def depart_problematic(self, node):
+ self.body.append('}')
+
def visit_topic(self, node):
raise nodes.SkipNode # XXX
@@ -425,11 +434,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
pass
def visit_term(self, node):
+ ctx = ']'
if node.has_key('ids') and node['ids']:
- self.body.append('\\hypertarget{%s}{}' % node['ids'][0])
+ ctx += '\\hypertarget{%s}{}' % node['ids'][0]
self.body.append('\\item[')
+ self.context.append(ctx)
def depart_term(self, node):
- self.body.append(']\n')
+ self.body.append(self.context.pop())
def visit_classifier(self, node):
self.body.append('{[}')
@@ -451,6 +462,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_centered(self, node):
self.body.append('\n\\end{centering}')
+ def visit_module(self, node):
+ modname = node['modname']
+ self.body.append('\\declaremodule[%s]{}{%s}' % (modname.replace('_', ''),
+ self.encode(modname)))
+ self.body.append('\\modulesynopsis{%s}' % self.encode(node['synopsis']))
+ if node.has_key('platform'):
+ self.body.append('\\platform{%s}' % self.encode(node['platform']))
+ def depart_module(self, node):
+ pass
+
def visit_note(self, node):
self.body.append('\n\\begin{notice}[note]')
def depart_note(self, node):
@@ -485,9 +506,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
return '}'
return ''
- # XXX specialcase 'module-' targets: add \declaremodule
- # XXX where to put \makemodindex
-
if not (node.has_key('refuri') or node.has_key('refid')
or node.has_key('refname')):
ctx = ''
@@ -505,7 +523,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append(self.context.pop())
indextype_map = {
- 'module': 'refmodindex', # XXX: key?
'keyword': 'kwindex',
'operator': 'opindex',
'object': 'obindex',
@@ -525,6 +542,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
elif type == 'triple':
parts = tuple(self.encode(x.strip()) for x in string.split(';', 2))
self.body.append(r'\indexiii{%s}{%s}{%s}' % parts)
+ elif type == 'module':
+ self.body.append(r'\refmodindex[%s]{%s}' % (string.replace('_', ''),
+ self.encode(string)))
elif type in self.indextype_map:
self.body.append(r'\%s{%s}' % (self.indextype_map[type],
self.encode(string)))
@@ -656,7 +676,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
(u"]", ur"{]}"),
(u"¶", ur"\P{}"),
(u"§", ur"\S{}"),
+ (u"∞", ur"$\infinity$"),
+ (u"±", ur"$\pm$"),
+ (u"‣", ur"$\rightarrow$"),
+ (u"Ω", ur"$\Omega$"),
+ (u"Ω", ur"$\Omega$"),
(u"~", ur"\textasciitilde{}"),
+ (u"€", ur"\texteuro{}"),
(u"<", ur"\textless{}"),
(u">", ur"\textgreater{}"),
(u"^", ur"\textasciicircum{}"),
diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile
new file mode 100644
index 00000000..c01faa47
--- /dev/null
+++ b/sphinx/texinputs/Makefile
@@ -0,0 +1,50 @@
+# Makefile for Sphinx LaTeX output
+
+ALLDOCS = $(basename $(wildcard *.tex))
+ALLPDF = $(addsuffix .pdf,$(ALLDOCS))
+ALLDVI = $(addsuffix .dvi,$(ALLDOCS))
+
+# Prefix for archive names
+ARCHIVEPRREFIX =
+
+all: $(ALLPDF)
+all-pdf: $(ALLPDF)
+all-dvi: $(ALLDVI)
+all-ps: all-dvi
+ for f in *.dvi; do dvips $f; done
+
+zip: all-$(FMT)
+ mkdir $(ARCHIVEPREFIX)docs-$(FMT)
+ cp $(ALLPDF) $(ARCHIVEPREFIX)docs-$(FMT)
+ zip -q -r -9 $(ARCHIVEPREFIX)docs-$(FMT).zip $(ARCHIVEPREFIX)docs-$(FMT)
+ rm -r $(ARCHIVEPREFIX)docs-$(FMT)
+
+tar: all-$(FMT)
+ mkdir $(ARCHIVEPREFIX)docs-$(FMT)
+ cp $(ALLPDF) $(ARCHIVEPREFIX)docs-$(FMT)
+ tar cf $(ARCHIVEPREFIX)docs-$(FMT).tar
+ rm -r $(ARCHIVEPREFIX)docs-$(FMT)
+
+bz2: tar-$(FMT)
+ bzip2 -9 -k $(ARCHIVEPREFIX)docs-$(FMT).tar
+
+%.dvi: %.tex
+ latex $<
+ latex $<
+ latex $<
+ -makeindex -s python.ist $(basename $<).idx
+ -makeindex -s python.ist $(basename mod$<).idx
+ latex $<
+ latex $<
+
+%.pdf: %.tex
+ pdflatex $<
+ pdflatex $<
+ pdflatex $<
+ -makeindex -s python.ist $(basename $<).idx
+ -makeindex -s python.ist $(basename mod$<).idx
+ pdflatex $<
+ pdflatex $<
+
+.PHONY: all all-pdf all-dvi all-ps
+
diff --git a/sphinx/texinputs/python.sty b/sphinx/texinputs/python.sty
index 9ae7dd57..572a6fbc 100644
--- a/sphinx/texinputs/python.sty
+++ b/sphinx/texinputs/python.sty
@@ -330,6 +330,10 @@
\py@UseModuleIndextrue
}
+\newcommand{\printmodindex}{
+ \@input@{mod\jobname.ind}
+}
+
% Add the defining entry for a module
\newcommand{\py@modindex}[2]{%
\renewcommand{\py@thismodule}{#1}