diff options
| author | georg.brandl <devnull@localhost> | 2007-12-16 12:20:41 +0000 |
|---|---|---|
| committer | georg.brandl <devnull@localhost> | 2007-12-16 12:20:41 +0000 |
| commit | 8e2c44dc4bdb59dfb03f6b94776a91c1da797f2d (patch) | |
| tree | aa5cd23469ca20c26370312874a531010be2b554 | |
| parent | 823edf09970730a133bd7c58ccfa695fc0c09b40 (diff) | |
| download | sphinx-8e2c44dc4bdb59dfb03f6b94776a91c1da797f2d.tar.gz | |
Implement index entries, production lists and the glossary.
| -rw-r--r-- | sphinx/builder.py | 26 | ||||
| -rw-r--r-- | sphinx/directives.py | 4 | ||||
| -rw-r--r-- | sphinx/environment.py | 4 | ||||
| -rw-r--r-- | sphinx/latexwriter.py | 77 | ||||
| -rw-r--r-- | sphinx/texinputs/python.sty | 40 |
5 files changed, 107 insertions, 44 deletions
diff --git a/sphinx/builder.py b/sphinx/builder.py index d7bacad2..a864db21 100644 --- a/sphinx/builder.py +++ b/sphinx/builder.py @@ -143,14 +143,14 @@ class Builder(object): """Load necessary templates and perform initialization.""" raise NotImplementedError - def get_target_uri(self, source_filename): + def get_target_uri(self, source_filename, typ=None): """Return the target URI for a source filename.""" raise NotImplementedError - def get_relative_uri(self, from_, to): + def get_relative_uri(self, from_, to, typ=None): """Return a relative URI between two source filenames.""" return relative_uri(self.get_target_uri(from_), - self.get_target_uri(to)) + self.get_target_uri(to, typ)) def get_outdated_files(self): """Return a list of output files that are outdated.""" @@ -195,10 +195,11 @@ class Builder(object): self.load_env() to_build = list(self.get_outdated_files()) if not to_build: - self.msg('no files are out of date, exiting.') + self.msg('no target files are out of date, exiting.') return self.build(to_build, - summary='%d source files that are out of date' % len(to_build)) + summary='targets for %d source files that are ' + 'out of date' % len(to_build)) def build(self, filenames, summary=None): if summary: @@ -482,7 +483,7 @@ class StandaloneHTMLBuilder(Builder): # --------- these are overwritten by the Web builder - def get_target_uri(self, source_filename): + def get_target_uri(self, source_filename, typ=None): return source_filename[:-4] + '.html' def get_outdated_files(self): @@ -561,7 +562,7 @@ class WebHTMLBuilder(StandaloneHTMLBuilder): os_path(filename))) > targetmtime: yield filename - def get_target_uri(self, source_filename): + def get_target_uri(self, source_filename, typ=None): if source_filename == 'index.rst': return '' if source_filename.endswith(SEP+'index.rst'): @@ -650,10 +651,14 @@ class LaTeXBuilder(Builder): self.filenames = [] def get_outdated_files(self): - # always rebuild everything for now + # XXX always rebuild everything for now return self.env.all_files - def get_target_uri(self, source_filename): + def get_target_uri(self, source_filename, typ=None): + if typ == 'token': + # token references are always inside production lists and must be + # replaced by \token{} in LaTeX + return '@token' if source_filename not in self.filenames: raise NoUri else: @@ -661,7 +666,7 @@ class LaTeXBuilder(Builder): def get_document_data(self): for toplevel in ["c-api", "distutils", "documenting", "extending", - "install", "reference", "tutorial", "using", "library"]: + "install", "reference", "tutorial", "using", "library"]: yield (toplevel + SEP + 'index.rst', toplevel+'.tex', 'manual') yield ('whatsnew' + SEP + self.config['version'] + '.rst', 'whatsnew.tex', 'howto') @@ -722,6 +727,7 @@ class LaTeXBuilder(Builder): largetree.extend(specials) print print "resolving references..." + # XXX problem here: :ref:s to distant PDF self.env.resolve_references(largetree, indexfile, self) return largetree diff --git a/sphinx/directives.py b/sphinx/directives.py index eec39556..ca9cf856 100644 --- a/sphinx/directives.py +++ b/sphinx/directives.py @@ -37,18 +37,20 @@ def index_directive(name, arguments, options, content, lineno, targetnode = nodes.target('', '', ids=[targetid]) state.document.note_explicit_target(targetnode) indexnode = addnodes.index() - indexnode['entries'] = arguments + indexnode['entries'] = ne = [] for entry in arguments: entry = entry.strip() for type in entrytypes: if entry.startswith(type+':'): value = entry[len(type)+1:].strip() env.note_index_entry(type, value, targetid, value) + ne.append((type, value, targetid, value)) break # shorthand notation for single entries else: for value in entry.split(','): env.note_index_entry('single', value.strip(), targetid, value.strip()) + ne.append(('single', value.strip(), targetid, value.strip())) return [indexnode, targetnode] index_directive.arguments = (1, 0, 1) diff --git a/sphinx/environment.py b/sphinx/environment.py index 53631886..ac95feab 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -52,7 +52,7 @@ default_settings = { # This is increased every time a new environment attribute is added # to properly invalidate pickle files. -ENV_VERSION = 12 +ENV_VERSION = 13 def walk_depth(node, depth, maxdepth): @@ -620,7 +620,7 @@ class BuildEnvironment: newnode['refid'] = labelid else: newnode['refuri'] = builder.get_relative_uri( - docfilename, filename) + '#' + labelid + docfilename, filename, typ) + '#' + labelid newnode.append(contnode) elif typ == 'mod': filename, synopsis, platform, deprecated = \ diff --git a/sphinx/latexwriter.py b/sphinx/latexwriter.py index e6bdaebf..efc0a346 100644 --- a/sphinx/latexwriter.py +++ b/sphinx/latexwriter.py @@ -97,7 +97,7 @@ class LaTeXTranslator(nodes.NodeVisitor): 'papersize': 'a4paper', # XXX 'pointsize': '12pt', 'filename': document.settings.filename, - 'title': None, # comes later + 'title': None, # is determined later 'release': config['release'], 'date': time.strftime(config.get('today_fmt', '%B %d, %Y')), } @@ -109,6 +109,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # flags self.verbatim = None self.in_title = 0 + self.in_production_list = 0 self.first_document = 1 self.this_is_the_title = 1 self.literal_whitespace = 0 @@ -156,10 +157,24 @@ class LaTeXTranslator(nodes.NodeVisitor): raise nodes.SkipNode # XXX def visit_glossary(self, node): - raise nodes.SkipNode # XXX + pass + def depart_glossary(self, node): + pass def visit_productionlist(self, node): - raise nodes.SkipNode # XXX + self.body.append('\n\n\\begin{productionlist}\n') + self.in_production_list = 1 + def depart_productionlist(self, node): + self.body.append('\\end{productionlist}\n\n') + self.in_production_list = 0 + + def visit_production(self, node): + if node['tokenname']: + self.body.append('\\production{%s}{' % self.encode(node['tokenname'])) + else: + self.body.append('\\productioncont{') + def depart_production(self, node): + self.body.append('}\n') def visit_transition(self, node): self.body.append('\n\n\\bigskip\\hrule{}\\bigskip\n\n') @@ -410,9 +425,10 @@ class LaTeXTranslator(nodes.NodeVisitor): pass def visit_term(self, node): + if node.has_key('ids') and node['ids']: + self.body.append('\\hypertarget{%s}{}' % node['ids'][0]) self.body.append('\\item[') def depart_term(self, node): - # definition list term. self.body.append(']\n') def visit_classifier(self, node): @@ -461,27 +477,60 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append(self.context.pop()) def visit_target(self, node): - # XXX: no "index-" targets + def add_target(id): + # indexing uses standard LaTeX index markup, so the targets + # will be generated differently + if not id.startswith('index-'): + self.body.append(r'\hypertarget{%s}{' % id) + 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 = '' for id in node['ids']: if id not in self.written_ids: - self.body.append(r'\hypertarget{%s}{' % id) self.written_ids.add(id) - ctx += '}' + ctx += add_target(id) self.context.append(ctx) elif node.has_key('refid') and node['refid'] not in self.written_ids: - self.body.append(r'\hypertarget{%s}{' % node['refid']) + self.context.append(add_target(node['refid'])) self.written_ids.add(node['refid']) - self.context.append('}') else: self.context.append('') def depart_target(self, node): self.body.append(self.context.pop()) - def visit_index(self, node): - raise nodes.SkipNode # XXX + indextype_map = { + 'module': 'refmodindex', # XXX: key? + 'keyword': 'kwindex', + 'operator': 'opindex', + 'object': 'obindex', + 'exception': 'exindex', + 'statement': 'stindex', + 'builtin': 'bifuncindex', + } + + def visit_index(self, node, scre=re.compile(r';\s*')): + entries = node['entries'] + for type, string, tid, _ in entries: + if type == 'single': + self.body.append(r'\index{%s}' % scre.sub('!', self.encode(string))) + elif type == 'pair': + parts = tuple(self.encode(x.strip()) for x in string.split(';', 1)) + self.body.append(r'\indexii{%s}{%s}' % parts) + 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 in self.indextype_map: + self.body.append(r'\%s{%s}' % (self.indextype_map[type], + self.encode(string))) + else: + raise RuntimeError('XXX unknown index entry type') + raise nodes.SkipNode def visit_reference(self, node): uri = node.get('refuri', '') @@ -493,6 +542,12 @@ class LaTeXTranslator(nodes.NodeVisitor): elif uri.startswith('#'): self.body.append('\\hyperlink{%s}{' % uri[1:]) self.context.append('}') + elif uri.startswith('@token'): + if self.in_production_list: + self.body.append('\\token{') + else: + self.body.append('\\grammartoken{') + self.context.append('}') else: raise RuntimeError('XXX malformed reference target %s' % uri) def depart_reference(self, node): diff --git a/sphinx/texinputs/python.sty b/sphinx/texinputs/python.sty index e3ee51a2..9ae7dd57 100644 --- a/sphinx/texinputs/python.sty +++ b/sphinx/texinputs/python.sty @@ -855,26 +855,26 @@ % Use this def/redef approach for \url{} since hyperref defined this already, % but only if we actually used hyperref: -\ifpdf - \newcommand{\url}[1]{{% - \py@pdfstartlink% - attr{ /Border [0 0 0] }% - user{% - /Subtype/Link% - /A<<% - /Type/Action% - /S/URI% - /URI(#1)% - >>% - }% - \py@LinkColor% color of the link text - \py@smallsize\sf #1% - \py@NormalColor% Turn it back off; these are declarative - \pdfendlink}% and don't appear bound to the current - }% formatting "box". -\else - \newcommand{\url}[1]{\mbox{\py@smallsize\textsf{#1}}} -\fi +%\ifpdf +% \newcommand{\url}[1]{{% +% \py@pdfstartlink% +% attr{ /Border [0 0 0] }% +% user{% +% /Subtype/Link% +% /A<<% +% /Type/Action% +% /S/URI% +% /URI(#1)% +% >>% +% }% +% \py@LinkColor% color of the link text +% \py@smallsize\sf #1% +% \py@NormalColor% Turn it back off; these are declarative +% \pdfendlink}% and don't appear bound to the current +% }% formatting "box". +%\else +% \newcommand{\url}[1]{\mbox{\py@smallsize\textsf{#1}}} +%\fi \newcommand{\email}[1]{{\py@smallsize\textsf{#1}}} \newcommand{\newsgroup}[1]{{\py@smallsize\textsf{#1}}} |
