epydoc-commits Mailing List for Python API documentation generation tool
Brought to you by:
edloper
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
(77) |
May
|
Jun
(6) |
Jul
(8) |
Aug
(91) |
Sep
(67) |
Oct
(4) |
Nov
|
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(17) |
Feb
(135) |
Mar
(25) |
Apr
|
May
(1) |
Jun
(1) |
Jul
(7) |
Aug
|
Sep
(62) |
Oct
(1) |
Nov
(3) |
Dec
|
2008 |
Jan
(40) |
Feb
(102) |
Mar
(5) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <ed...@us...> - 2009-02-03 22:11:41
|
Revision: 1812 http://epydoc.svn.sourceforge.net/epydoc/?rev=1812&view=rev Author: edloper Date: 2009-02-03 21:31:04 +0000 (Tue, 03 Feb 2009) Log Message: ----------- increased robustness vs random exceptions Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/html.py trunk/epydoc/src/epydoc/docwriter/plaintext.py Modified: trunk/epydoc/src/epydoc/docwriter/html.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/html.py 2009-02-03 21:29:51 UTC (rev 1811) +++ trunk/epydoc/src/epydoc/docwriter/html.py 2009-02-03 21:31:04 UTC (rev 1812) @@ -3468,11 +3468,12 @@ if label is None: label = plaintext_to_html(identifier) # Find the APIDoc for it (if it's available). - doc = self.docindex.find(identifier, self.container) + try: doc = self.docindex.find(identifier, self.container, True) + except: doc = 'notfound' # If we didn't find a target, then try checking in the contexts # of the ancestor classes. - if doc is None and isinstance(self.container, RoutineDoc): + if doc == 'notfound' and isinstance(self.container, RoutineDoc): container = self.docindex.get_vardoc( self.container.canonical_name) while (doc is None and container not in (None, UNKNOWN) @@ -3481,8 +3482,9 @@ doc = self.docindex.find(identifier, container) # Translate it into HTML. - if doc is None: - self._failed_xref(identifier) + if doc in (None, 'notfound'): + if doc == 'notfound': + self._failed_xref(identifier) return '<code class="link">%s</code>' % label else: return self.htmlwriter.href(doc, label, 'link') Modified: trunk/epydoc/src/epydoc/docwriter/plaintext.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/plaintext.py 2009-02-03 21:29:51 UTC (rev 1811) +++ trunk/epydoc/src/epydoc/docwriter/plaintext.py 2009-02-03 21:31:04 UTC (rev 1812) @@ -72,7 +72,7 @@ s += str(base.canonical_name[-1]) else: s += str(base.canonical_name) - if i < len(class_doc.bases)-1: out(', ') + if i < len(class_doc.bases)-1: s += ', ' return s+')' def write_class(self, out, class_doc, name=None, prefix='', verbose=True): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2009-02-03 21:29:59
|
Revision: 1811 http://epydoc.svn.sourceforge.net/epydoc/?rev=1811&view=rev Author: edloper Date: 2009-02-03 21:29:51 +0000 (Tue, 03 Feb 2009) Log Message: ----------- added not_found_exception parameter for find method Modified Paths: -------------- trunk/epydoc/src/epydoc/apidoc.py Modified: trunk/epydoc/src/epydoc/apidoc.py =================================================================== --- trunk/epydoc/src/epydoc/apidoc.py 2008-03-31 03:22:51 UTC (rev 1810) +++ trunk/epydoc/src/epydoc/apidoc.py 2009-02-03 21:29:51 UTC (rev 1811) @@ -1859,7 +1859,7 @@ return None, None - def find(self, name, context): + def find(self, name, context, not_found_exception=False): """ Look for an C{APIDoc} named C{name}, relative to C{context}. Return the C{APIDoc} if one is found; otherwise, return @@ -1874,12 +1874,17 @@ @type name: C{str} or L{DottedName} @type context: L{APIDoc} + + @param not_found_exception: If true, then raise an exception + if the name is not found anywhere (including builtins, + function parameters, etc.) """ if isinstance(name, basestring): name = re.sub(r'\(.*\)$', '', name.strip()) if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name): name = DottedName(name) else: + if not_found_exception: raise ValueError(name) return None elif not isinstance(name, DottedName): raise TypeError("'name' should be a string or DottedName") @@ -1931,6 +1936,9 @@ # Drop this item so that the warning is reported only once. # fail() will fail anyway. del self.mlclasses[name[-1]] + else: + if not_found_exception: raise ValueError(name) + return None def _get_module_classes(self, docs): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-03-31 03:22:54
|
Revision: 1810 http://epydoc.svn.sourceforge.net/epydoc/?rev=1810&view=rev Author: edloper Date: 2008-03-30 20:22:51 -0700 (Sun, 30 Mar 2008) Log Message: ----------- - When introspecting the variables in a module, assume that all variables whose values are modules are imported. Modified Paths: -------------- trunk/epydoc/src/epydoc/docintrospecter.py Modified: trunk/epydoc/src/epydoc/docintrospecter.py =================================================================== --- trunk/epydoc/src/epydoc/docintrospecter.py 2008-03-05 18:40:49 UTC (rev 1809) +++ trunk/epydoc/src/epydoc/docintrospecter.py 2008-03-31 03:22:51 UTC (rev 1810) @@ -267,10 +267,11 @@ # Create a VariableDoc for the child, and introspect its # value if it's defined in this module. container = get_containing_module(child) - if ((container is not None and - container == name_without_primes) or - (public_names is not None and - child_name in public_names)): + if (((container is not None and + container == name_without_primes) or + (public_names is not None and + child_name in public_names)) + and not inspect.ismodule(child)): # Local variable. child_val_doc = introspect_docs(child, context=module_doc, module_name=dotted_name) @@ -279,7 +280,8 @@ is_imported=False, container=module_doc, docs_extracted_by='introspecter') - elif container is None or module_doc.canonical_name is UNKNOWN: + elif ((container is None or module_doc.canonical_name is UNKNOWN) + and not inspect.ismodule(child)): # Don't introspect stuff "from __future__" if is_future_feature(child): continue This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-03-05 18:40:52
|
Revision: 1809 http://epydoc.svn.sourceforge.net/epydoc/?rev=1809&view=rev Author: edloper Date: 2008-03-05 10:40:49 -0800 (Wed, 05 Mar 2008) Log Message: ----------- - Use \raggedright for the subclass list - Use utf8x encoding, instead of utf8 - \EpydocDottedName now expects its argument to use escaped characters (underscore in particular.) E.g., \EpydocDottedName{foo\_bar}. It no longer uses the latex url package. This makes it work better with the hyperref package. - Misc changes to show_latex_warnings(). Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex.py Modified: trunk/epydoc/src/epydoc/docwriter/latex.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex.py 2008-03-05 18:40:33 UTC (rev 1808) +++ trunk/epydoc/src/epydoc/docwriter/latex.py 2008-03-05 18:40:49 UTC (rev 1809) @@ -405,7 +405,9 @@ len(doc.subclasses) > 0): sc_items = [_hyperlink(sc, '%s' % sc.canonical_name) for sc in doc.subclasses] + out('{\\raggedright%\n') out(self._descrlist(sc_items, 'Known Subclasses', short=1)) + out('}%\n') # The class's description. if doc.descr not in (None, UNKNOWN): @@ -1161,7 +1163,7 @@ #: Map the Python encoding representation into mismatching LaTeX ones. latex_encodings = { - 'utf-8': 'utf8', + 'utf-8': 'utf8x', } def get_latex_encoding(self): @@ -1202,20 +1204,17 @@ def _dotted(name): if not name: return '' - name = '%s' % name - # There are a couple of characters that even \\EpydocDottedName - # can't cope with; so filter them out. - name = re.sub('[%#]|\^\^+|\n', '?', name) - return '\\EpydocDottedName{%s}' % name + return '\\EpydocDottedName{%s}' % plaintext_to_latex('%s' % name) LATEX_WARNING_RE = re.compile('|'.join([ - r'(?P<file>\([\.a-zA-Z_\-/\\ \n0-9]+[.\n][a-z]{2,3}\b)', + r'(?P<file>\([\.a-zA-Z_\-/\\0-9]+[.\n][a-z]{2,3}\b)', (r'(?P<pkgwarn>^(Package|Latex) (?P<pkgname>[\w-]+) '+ r'Warning:[^\n]*\n(\((?P=pkgname)\)[^\n]*\n)*)'), r'(?P<overfull>^(Overfull|Underfull)[^\n]*\n[^\n]*)', r'(?P<latexwarn>^LaTeX\s+Warning:\s+[^\n]*)', r'(?P<otherwarn>^[^\n]*Warning:[^\n]*)', - r'(?P<paren>[()])']), + r'(?P<paren>[()])', + r'(?P<pageno>\[\d+({[^\}]+})?\])']), re.MULTILINE+re.IGNORECASE) OVERFULL_RE = re.compile( @@ -1235,7 +1234,11 @@ #[xx] we should probably pay special attention to overfull \vboxes. overfull = underfull = 0 filestack = ['latex'] + block = None + BLOCK = 'LaTeX Warnings: %s' + pageno = 1 for m in LATEX_WARNING_RE.finditer(s): + #log.debug(m.group()) # Check if it's something we don't care about. for regexp in IGNORE_WARNING_REGEXPS: if regexp.match(m.group()): @@ -1245,47 +1248,66 @@ if m.group('file'): filename = ''.join(m.group('file')[1:].split()) filename = re.sub(r'^\./', '', filename) + if filename == 'api.toc': filename = 'Table of contents (api.toc)' + if filename == 'api.ind': filename = 'Index (api.ind)' filestack.append(filename) - # Latex reported an overfull/underfull warning: + if block is not None: epydoc.log.end_block() + epydoc.log.start_block(BLOCK % filename) + block = filename + # LaTeX started writing a new page + elif m.group('pageno'): + if pageno == int(m.group()[1:-1].split('{')[0]): + pageno += 1 + # LateX reported an overfull/underfull warning: elif m.group('overfull'): msg = m.group('overfull').strip().split('\n')[0] + msg = re.sub(r'(\d+)\.\d+', r'\1', msg) + msg = re.sub(r'(lines \d+)--(\d+)', r'\1-\2', msg) if msg.lower().startswith('overfull'): overfull += 1 else: underfull += 1 - m2 = OVERFULL_RE.match(msg) - if m2: - if m2.group('boxtype') == 'vbox': - log.warning('%s: %s' % (filestack[-1], msg)) - elif (m2.group('typ').lower()=='overfull' and - int(m2.group('size')) > 50): - log.warning('%s: %s' % (filestack[-1], msg)) - else: - log.debug('%s: %s' % (filestack[-1], msg)) - else: - log.debug('%s: %s' % (filestack[-1], msg)) + log.warning(msg)#+' (page %d)' % pageno) +# m2 = OVERFULL_RE.match(msg) +# if m2: +# if m2.group('boxtype') == 'vbox': +# log.warning(msg) +# elif (m2.group('typ').lower()=='overfull' and +# int(m2.group('size')) > 50): +# log.warning(msg) +# else: +# log.debug(msg) +# else: +# log.debug(msg) # Latex reported a warning: elif m.group('latexwarn'): - msg = m.group('latexwarn').strip() - log.warning('%s: %s' % (filestack[-1], msg)) + log.warning(m.group('latexwarn').strip()+' (page %d)' % pageno) # A package reported a warning: elif m.group('pkgwarn'): - msg = m.group('pkgwarn').strip() - log.warning('%s:\n%s' % (filestack[-1], msg)) + log.warning(m.group('pkgwarn').strip()) else: # Display anything else that looks like a warning: if m.group('otherwarn'): - msg = m.group('otherwarn').strip() - log.warning('%s: %s' % (filestack[-1], msg)) + log.warning(m.group('otherwarn').strip()) # Update to account for parens. n = m.group().count('(') - m.group().count(')') if n > 0: filestack += [None] * n if n < 0: del filestack[n:] - if overfull or underfull: - msgs = [] - if overfull == 1: msgs.append('1 overfull box') - elif overfull: msgs.append('%d overfull boxes' % overfull) - if underfull == 1: msgs.append('1 underfull box') - elif underfull: msgs.append('%d underfull boxes' % underfull) - log.warning('LaTeX reported %s' % ' and '.join(msgs)) + # Don't let filestack become empty: + if not filestack: filestack.append('latex') + if (filestack[-1] is not None and + block is not None and block != filestack[-1]): + epydoc.log.end_block() + epydoc.log.start_block(BLOCK % filestack[-1]) + if block: + epydoc.log.end_block() + +# if overfull or underfull: +# msgs = [] +# if overfull == 1: msgs.append('1 overfull box') +# elif overfull: msgs.append('%d overfull boxes' % overfull) +# if underfull == 1: msgs.append('1 underfull box') +# elif underfull: msgs.append('%d underfull boxes' % underfull) +# log.warning('LaTeX reported %s' % ' and '.join(msgs)) + #log.register_logger(log.SimpleLogger(log.DEBUG)) #show_latex_warnings(open('/tmp/po.test').read()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-03-05 18:40:36
|
Revision: 1808 http://epydoc.svn.sourceforge.net/epydoc/?rev=1808&view=rev Author: edloper Date: 2008-03-05 10:40:33 -0800 (Wed, 05 Mar 2008) Log Message: ----------- - Use \raggedright for the subclass list - Use utf8x encoding, instead of utf8 - \EpydocDottedName now expects its argument to use escaped characters (underscore in particular.) E.g., \EpydocDottedName{foo\_bar}. It no longer uses the latex url package. This makes it work better with the hyperref package. - Misc changes to show_latex_warnings(). Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex_sty.py Modified: trunk/epydoc/src/epydoc/docwriter/latex_sty.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-03-04 02:32:58 UTC (rev 1807) +++ trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-03-05 18:40:33 UTC (rev 1808) @@ -75,7 +75,6 @@ \RequirePackage[headings]{fullpage} \RequirePackage[usenames]{color} \RequirePackage{graphicx} -\RequirePackage{url} \@ifclassloaded{memoir}{% \RequirePackage[other,notbib]{tocbibind} @@ -107,6 +106,9 @@ % ====================================================================== % General Formatting +% Setting this will make us less likely to get overfull hboxes: +%\setlength{\emergencystretch}{1in} + % Separate paragraphs by a blank line (do not indent them). We define % a new length variable. \EpydocParskip, for the paragraph-skip length. % This needs to be assigned to \parskip here as well as inside several @@ -566,23 +568,28 @@ % This section defines the EpydocDottedName command, which is used to % display the names of Python objects. -% The \EpydocDottedName command is used to escape dotted names. In -% particular, it escapes all characters except '#', '%', and newlines, -% and allows non-hyphenated wrapping at '.' separator characters. -% [xx] this generates a warning for names containing _ -- we need -% to somehow strip that out of the second argument. -\newcommand\EpydocDottedName[1]{% - \texorpdfstring{\protect\Epydoc@DottedName{#1}}{#1}} +% The \EpydocDottedName command adds a possible break-point after every +% period in the given string. It no longer escapes characters such as +% underscore, since this interfered with the hyperref package; instead, +% epydoc is responsible for escaping them. E.g., correct usage for a +% name with an underscore is \EpydocDottedName{some\_name}. +\newcommand\EpydocDottedName[1]{ + \Epydoc@DottedName #1.@} -\DeclareUrlCommand\Epydoc@DottedName{% - \urlstyle{rm}% - \def\UrlBigBreaks{\do\.}% - % We should never see most of these chars in a name, but handle - % them if they happen to show up (eg script names) - \def\UrlOrds{\do\@\do\#\do\%\do\^\do\&\do\(\do\)\do\-\do\_% - \do\|\do\\\do\"\do\/\do\?\do\>\do\<\do\{\do\}% - \do\`\do\~} -} +% This helper function performs the work of \EpydocDottedName. It +% scans forward, looking for a period, and putting all text up to the +% period into #1. The single character after the period is put in +% #2. This function then checks if #2 is '@', indicating that we're +% done, or some other character, indicating that we should continue. +% Note that \ifx tests character codes; and that when '@' appears +% in user code, it gets the character code 'other', but when it +% appears here, it gets the character code 'letter'. +\def\Epydoc@DottedName#1.#2{% + \ifx#2@\relax #1\else + #1\discretionary{.}{}{.}% + \expandafter\expandafter\expandafter\Epydoc@DottedName + \expandafter #2\fi% + } """+NIST_DISCLAIMER ###################################################################### This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-03-04 02:33:17
|
Revision: 1807 http://epydoc.svn.sourceforge.net/epydoc/?rev=1807&view=rev Author: edloper Date: 2008-03-03 18:32:58 -0800 (Mon, 03 Mar 2008) Log Message: ----------- - When latex is run with --debug or --v, display the latex warnings. - Fixed bug in determining whether to re-run latex Modified Paths: -------------- trunk/epydoc/src/epydoc/cli.py Modified: trunk/epydoc/src/epydoc/cli.py =================================================================== --- trunk/epydoc/src/epydoc/cli.py 2008-03-04 02:31:57 UTC (rev 1806) +++ trunk/epydoc/src/epydoc/cli.py 2008-03-04 02:32:58 UTC (rev 1807) @@ -1056,9 +1056,16 @@ options.pdfdriver = 'latex' log.info('%r pdfdriver selected' % options.pdfdriver) - from epydoc.docwriter.latex import LatexWriter + from epydoc.docwriter.latex import LatexWriter, show_latex_warnings latex_writer = LatexWriter(docindex, **options.__dict__) - latex_writer.write(latex_target) + try: + latex_writer.write(latex_target) + except IOError, e: + log.error(e) + log.end_progress() + log.start_progress() + log.end_progress() + return log.end_progress() # Decide how many steps we need to go through. @@ -1119,17 +1126,21 @@ # The third pass is only necessary if the second pass # changed what page some things are on. running = latex_command - if _RERUN_LATEX_RE.match(out): + if _RERUN_LATEX_RE.search(out): log.progress(step/steps, '%s (Third pass)' % LaTeX) out, err = run_subprocess('%s api.tex' % latex_command) # A fourth path should (almost?) never be necessary. running = latex_command - if _RERUN_LATEX_RE.match(out): + if _RERUN_LATEX_RE.search(out): log.progress(step/steps, '%s (Fourth pass)' % LaTeX) - run_subprocess('%s api.tex' % latex_command) + out, err = run_subprocess('%s api.tex' % latex_command) step += 1 + # Show the output, if verbosity is high: + if options.verbosity > 2 or epydoc.DEBUG: + show_latex_warnings(out) + # If requested, convert to postscript. if ('ps' in options.actions or ('pdf' in options.actions and options.pdfdriver=='latex')): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-03-04 02:31:58
|
Revision: 1806 http://epydoc.svn.sourceforge.net/epydoc/?rev=1806&view=rev Author: edloper Date: 2008-03-03 18:31:57 -0800 (Mon, 03 Mar 2008) Log Message: ----------- - Assorted improvements to latex output - EpydocFunction, EpydocVariable, and EpydocProperty commands now use xkeyval to pass arguments in a more readable and extensible manner. - Adjusted the output to fix indentation, and make the generated latex easier to read - Always write classes to separate files; and use \input to read them in. - Added function to parse latex output & look for warnings Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex.py trunk/epydoc/src/epydoc/docwriter/latex_sty.py Modified: trunk/epydoc/src/epydoc/docwriter/latex.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-27 20:24:06 UTC (rev 1805) +++ trunk/epydoc/src/epydoc/docwriter/latex.py 2008-03-04 02:31:57 UTC (rev 1806) @@ -45,7 +45,7 @@ self.docindex = docindex # Process keyword arguments self._show_private = kwargs.get('show_private', 0) - self._prj_name = kwargs.get('prj_name', None) or 'API Documentation' + self._prj_name = kwargs.get('prj_name', None) self._show_crossrefs = kwargs.get('crossref', 1) self._index = kwargs.get('index', 1) self._hyperlink = kwargs.get('hyperlink', True) @@ -124,8 +124,7 @@ if isinstance(val_doc, ModuleDoc): filename = '%s-module.tex' % val_doc.canonical_name self._write(self.write_module, directory, filename, val_doc) - elif (isinstance(val_doc, ClassDoc) and - self._list_classes_separately): + elif isinstance(val_doc, ClassDoc): filename = '%s-class.tex' % val_doc.canonical_name self._write(self.write_class, directory, filename, val_doc) @@ -204,12 +203,8 @@ generate. @rtype: C{int} """ - n = 1 - for doc in self.valdocs: - if isinstance(doc, ModuleDoc): n += 1 - if isinstance(doc, ClassDoc) and self._list_classes_separately: - n += 1 - return n + return 1 + len([doc for doc in self.valdocs + if isinstance(doc, (ClassDoc, ModuleDoc))]) def _mkdir(self, directory): """ @@ -229,22 +224,23 @@ self.write_header(out, 'Include File') self.write_preamble(out) out('\n\\begin{document}\n\n') - self.write_start_of(out, 'Header') + out(self.start_of('Header')) # Write the title. - self.write_start_of(out, 'Title') - out('\\title{%s}\n' % plaintext_to_latex(self._prj_name, 1)) + out(self.start_of('Title')) + out('\\title{%s}\n' % plaintext_to_latex( + self._prj_name or 'API Documentation', 1)) out('\\author{API Documentation}\n') out('\\maketitle\n') # Add a table of contents. - self.write_start_of(out, 'Table of Contents') + out(self.start_of('Table of Contents')) out('\\addtolength{\\parskip}{-1ex}\n') out('\\tableofcontents\n') out('\\addtolength{\\parskip}{1ex}\n') # Include documentation files. - self.write_start_of(out, 'Includes') + out(self.start_of('Includes')) for val_doc in self.valdocs: if isinstance(val_doc, ModuleDoc): out('\\include{%s-module}\n' % val_doc.canonical_name) @@ -258,11 +254,11 @@ # Add the index, if requested. if self._index: - self.write_start_of(out, 'Index') + out(self.start_of('Index')) out('\\printindex\n\n') # Add the footer. - self.write_start_of(out, 'Footer') + out(self.start_of('Footer')) out('\\end{document}\n\n') def write_preamble(self, out): @@ -307,10 +303,10 @@ def write_module(self, out, doc): self.write_header(out, doc) - self.write_start_of(out, 'Module Description') + out(self.start_of('Section Heading', doc)) # Add this module to the index. - out(' ' + self.indexterm(doc, 'start')) + out(self.indexterm(doc, 'start')) # Add a section marker. out(self.section('%s %s' % (self.doc_kind(doc), @@ -319,12 +315,13 @@ # Add the module's description. if doc.descr not in (None, UNKNOWN): - out(' '*4 + '\\begin{EpydocModuleDescription}%\n') + out(self.start_of('Description', doc)) + out('\\begin{EpydocModuleDescription}%\n') out(self.docstring_to_latex(doc.descr, doc, 4)) - out(' '*4 + '\\end{EpydocModuleDescription}\n') + out('\\end{EpydocModuleDescription}\n') # Add version, author, warnings, requirements, notes, etc. - self.write_standard_fields(out, doc) + out(self.metadata(doc)) # If it's a package, list the sub-modules. if (self._list_submodules and self._show_submodule_list and @@ -342,39 +339,49 @@ if not self._list_classes_separately: classes = doc.select_variables(imported=False, value_type='class', public=self._public_filter) - for var_doc in classes: - self.write_class(out, var_doc.value) + if classes: + out(self.start_of('Classes', doc)) + for var_doc in classes: + # don't use \include -- can't be nested. + out('\\input{%s-class}\n' % var_doc.value.canonical_name) # Mark the end of the module (for the index) - out(' ' + self.indexterm(doc, 'end')) + out(self.start_of('Footer', doc)) + out(self.indexterm(doc, 'end')) def render_graph(self, graph): if graph is None: return '' graph.caption = graph.title = None return graph.to_latex(self._directory) or '' - def write_class(self, out, doc, short_name=None): - if short_name is None: short_name = doc.canonical_name[-1] - - if self._list_classes_separately: - self.write_header(out, doc) - self.write_start_of(out, 'Class Description') + def write_class(self, out, doc): + self.write_header(out, doc) + out(self.start_of('Section Heading', doc)) # Add this class to the index. - out(' ' + self.indexterm(doc, 'start')) + out(self.indexterm(doc, 'start')) - # Add a section marker. + # Decide on our short (contextualized) name. if self._list_classes_separately: + short_name = doc.canonical_name + if doc.defining_module not in (None, UNKNOWN): + short_name = doc.canonical_name.contextualize( + doc.defining_module.canonical_name) + else: + short_name = doc.canonical_name[-1] + + # Decidie on our initial section level. + if self._list_classes_separately: seclevel = 0 - out(self.section('%s %s' % (self.doc_kind(doc), - _dotted(doc.canonical_name)), - seclevel, ref=doc)) else: seclevel = 1 - out(self.section('%s %s' % (self.doc_kind(doc), - _dotted(short_name)), - seclevel, ref=doc)) + # Add a section marker. + out(self.section('%s %s' % (self.doc_kind(doc), _dotted(short_name)), + seclevel, ref=doc)) + + # Display our base classes & subclasses + out(self.start_of('Class Tree', doc)) if ((doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0) or (doc.subclasses not in (UNKNOWN,None) and len(doc.subclasses)>0)): # Display bases graphically, if requested. @@ -402,12 +409,13 @@ # The class's description. if doc.descr not in (None, UNKNOWN): - out(' '*4 + '\\begin{EpydocClassDescription}\n') - out(self.docstring_to_latex(doc.descr, doc)) - out(' '*4 + '\\end{EpydocClassDescription}\n') + out(self.start_of('Description', doc)) + out('\\begin{EpydocClassDescription}%\n') + out(self.docstring_to_latex(doc.descr, doc, 4)) + out('\\end{EpydocClassDescription}\n') # Version, author, warnings, requirements, notes, etc. - self.write_standard_fields(out, doc) + out(self.metadata(doc)) # Contents. self.write_list(out, 'Methods', doc, 'EpydocFunctionList', @@ -422,19 +430,24 @@ 'instancevariable', seclevel+1) # Mark the end of the class (for the index) - out(' ' + self.indexterm(doc, 'end')) + out(self.start_of('Footer', doc)) + out(self.indexterm(doc, 'end')) # Write any nested classes. These will have their own # section (at the same level as this section) - for nested_class in doc.select_variables(imported=False, - value_type='class', - public=self._public_filter): - if (nested_class.value.canonical_name != UNKNOWN and - (nested_class.value.canonical_name[:-1] == - doc.canonical_name)): - self.write_class(out, nested_class.value, - DottedName(short_name, - nested_class.canonical_name[-1])) + if not self._list_classes_separately: + nested_classes = doc.select_variables( + imported=False, value_type='class', + public=self._public_filter) + if nested_classes: + out(self.start_of('Nested Classes', doc)) + for nested_class in nested_classes: + if (nested_class.value.canonical_name != UNKNOWN and + (nested_class.value.canonical_name[:-1] == + doc.canonical_name)): + # don't use \include -- can't be nested. + out('\\input{%s-class}\n' % + nested_class.value.canonical_name) #//////////////////////////////////////////////////////////// #{ Module hierarchy trees @@ -456,7 +469,7 @@ def write_module_list(self, out, doc): if len(doc.submodules) == 0: return - self.write_start_of(out, 'Submodules') + out(self.start_of('Submodules', doc)) out(self.section('Submodules', 1)) out('\\begin{EpydocModuleList}\n') @@ -479,10 +492,11 @@ @rtype: C{string} """ - out(' '*depth + '\\item[%s]' % _hyperlink(doc, doc.canonical_name[-1])) + out(' '*depth + '\\item[%s]\n' % + _hyperlink(doc, doc.canonical_name[-1])) if doc.summary not in (None, UNKNOWN): - out(' %s\n' % self.docstring_to_latex(doc.summary, doc)) + out(self.docstring_to_latex(doc.summary, doc, depth+2)) out(self.crossref(doc) + '\n\n') if doc.submodules != UNKNOWN and doc.submodules: out(' '*depth + ' \\begin{EpydocModuleList}\n') @@ -498,7 +512,9 @@ if width is None: width = self._find_tree_width(doc)+2 linespec = [] - s = ('&'*(width-4)+'\\multicolumn{2}{l}{\\textbf{%s}}\n' % + s = (' %% Class tree line for this class (%s)\n ' % + doc.canonical_name + '&'*(width-4) + + '\\multicolumn{2}{l}{\\textbf{%s}}\n' % _dotted('%s'%self._base_name(doc))) s += '\\end{tabular}\n\n' top = 1 @@ -534,36 +550,36 @@ return width def _base_tree_line(self, doc, width, linespec): + # linespec is a list of booleans. base_name = _dotted(self._base_name(doc)) - # linespec is a list of booleans. - s = '%% Line for %s, linespec=%s\n' % (base_name, linespec) - + s = ' %% Class tree line for base "%s"\n' % self._base_name(doc) labelwidth = width-2*len(linespec)-2 # The base class name. - s += ('\\multicolumn{%s}{r}{' % labelwidth) - s += '\\settowidth{\\EpydocBCL}{%s}' % base_name - s += ('\\multirow{2}{\\EpydocBCL}{%s}}\n' % - _hyperlink(doc, self._base_name(doc))) + s += ' \\multicolumn{%s}{r}{\n' % labelwidth + s += ' \\settowidth{\\EpydocBCL}{%s}\n' % base_name + s += ' \\multirow{2}{\\EpydocBCL}{\n' + s += ' %s}}\n' % _hyperlink(doc, self._base_name(doc)) # The vertical bars for other base classes (top half) for vbar in linespec: - if vbar: s += '&&\\multicolumn{1}{|c}{}\n' - else: s += '&&\n' + if vbar: s += ' &&\\multicolumn{1}{|c}{}\n' + else: s += ' &&\n' # The horizontal line. - s += ' \\\\\\cline{%s-%s}\n' % (labelwidth+1, labelwidth+1) + s += ' \\\\\\cline{%s-%s}\n' % (labelwidth+1, labelwidth+1) # The vertical bar for this base class. - s += ' ' + '&'*labelwidth + s += ' ' + '&'*labelwidth s += '\\multicolumn{1}{c|}{}\n' # The vertical bars for other base classes (bottom half) for vbar in linespec: - if vbar: s += '&\\multicolumn{1}{|c}{}&\n' - else: s += '&&\n' - s += ' \\\\\n' + if vbar: s += ' &\\multicolumn{1}{|c}{}&\n' + else: s += ' &&\n' + + s += ' \\\\\n' return s @@ -583,7 +599,7 @@ if not groups: return # Write a header. - self.write_start_of(out, 'Classes') + out(self.start_of('Classes', doc)) out(self.section('Classes', 1)) out('\\begin{EpydocClassList}\n') @@ -605,8 +621,8 @@ out(' ' + '\\item[%s]' % _hyperlink(var_doc.target, var_doc.name)) if doc.summary not in (None, UNKNOWN): - out(': %s\n' % self.docstring_to_latex(doc.summary, doc)) - out(self.crossref(doc) + '\n\n') + out(': %\n' + self.docstring_to_latex(doc.summary, doc)) + out(self.crossref(doc)) #//////////////////////////////////////////////////////////// #{ Details Lists @@ -627,8 +643,8 @@ if not groups: return # Write a header. - self.write_start_of(out, heading) - out(' '+self.section(heading, seclevel)) + out(self.start_of(heading, doc)) + out(self.section(heading, seclevel)) out('\\begin{%s}\n' % list_type) @@ -718,6 +734,15 @@ #//////////////////////////////////////////////////////////// #{ Function Details #//////////////////////////////////////////////////////////// + + def replace_par(self, out): + def new_out(s): + s = re.sub('(?m)\n([ \t]*\n)+', '\\par\n', s) + s = re.sub(r'\\par\b', r'\\EpydocPar', s) + s = re.sub(r'(?m)^([ \t]*)([^ \t].*)\\EpydocPar\n', + r'\1\2\n\1\\EpydocPar\n', s) + out(s) + return new_out def write_function(self, out, var_doc): func_doc = var_doc.value @@ -727,63 +752,73 @@ # select the containing section, and won't give a reference # directly to the function. if not is_inherited: - out(' %s%%\n' % self.indexterm(func_doc)) + out(' %s' % self.indexterm(func_doc)) - # This latex command takes 8 arguments. - out('\\EpydocFunction{%\n') + out(' \\EpydocFunction{%% <<< %s >>>\n' % var_doc.name) + # We're passing arguments using xkeyval, which is unhappy if + # the arguments contain \par. So replace every occurence of + # \par with \EpydocPar (which is defined to just return \par). + out = self.replace_par(out) + # Argument 1: the function signature - out(self.function_signature(var_doc)) - out('}{%\n') + out(' signature={%%\n%s }' % + self.function_signature(var_doc)) # Argument 2: the function description if func_doc.descr not in (None, UNKNOWN): - out(self.docstring_to_latex(func_doc.descr, func_doc, 4)) - out('}{%\n') + out(',\n description={%\n') + out(self.docstring_to_latex(func_doc.descr, func_doc, 6)) + out(' }') # Argument 3: the function parameter descriptions if func_doc.arg_descrs or func_doc.arg_types: + out(',\n parameters={%\n') self.write_function_parameters(out, var_doc) - out('}{%\n') + out(' }') # Argument 4: The return description if func_doc.return_descr not in (None, UNKNOWN): - out(self.docstring_to_latex(func_doc.return_descr, - func_doc, 6)) - out('}{%\n') + out(',\n returndescr={%\n') + out(self.docstring_to_latex(func_doc.return_descr, func_doc, 6)) + out(' }') # Argument 5: The return type if func_doc.return_type not in (None, UNKNOWN): - out(self.docstring_to_latex(func_doc.return_type, - func_doc, 6).strip()) - out('}{%\n') + out(',\n returntype={%\n') + out(self.docstring_to_latex(func_doc.return_type, func_doc, 6)) + out(' }') # Argument 6: The raises section if func_doc.exception_descrs not in (None, UNKNOWN, [], ()): + out(',\n raises={%\n') out(' '*6+'\\begin{EpydocFunctionRaises}\n') for name, descr in func_doc.exception_descrs: out(' '*10+'\\item[%s]\n\n' % plaintext_to_latex('%s' % name)) out(self.docstring_to_latex(descr, func_doc, 10)) - out(' '*6+'\\end{EpydocFunctionRaises}\n\n') - out('}{%\n') + out(' '*6+'\\end{EpydocFunctionRaises}\n') + out(' }') # Argument 7: The overrides section if var_doc.overrides not in (None, UNKNOWN): + out(',\n overrides={%\n') out('\\EpydocFunctionOverrides') if (func_doc.docstring in (None, UNKNOWN) and var_doc.overrides.value.docstring not in (None, UNKNOWN)): out('[1]') - out('{%s}\n\n' + out('{%s}\n' % _hyperlink(var_doc.overrides, '%s' % var_doc.overrides.canonical_name)) - out('}{%\n') + out(' }') # Argument 8: The metadata section - self.write_standard_fields(out, func_doc) - out('}\n') - + metadata = self.metadata(func_doc, 6) + if metadata: + out(',\n metadata={%%\n%s }' % metadata) + out('}%\n') + def write_function_parameters(self, out, var_doc): func_doc = var_doc.value # Find the longest name. @@ -803,7 +838,7 @@ # Display params for (arg_names, arg_descr) in arg_descrs: arg_name = plaintext_to_latex(', '.join(arg_names)) - out('%s\\item[%s]\n\n' % (' '*10, arg_name)) + out('%s\\item[%s]\n' % (' '*8, arg_name)) if arg_descr: out(self.docstring_to_latex(arg_descr, func_doc, 10)) # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -816,16 +851,17 @@ lhs = 'type' else: lhs = 'type of %s' % arg_name - rhs = self.docstring_to_latex(arg_typ, func_doc).strip() - out('%s{\\it (%s=%s)}\n\n' % (' '*12, lhs, rhs)) - out(' '*6+'\\end{EpydocFunctionParameters}\n\n') + rhs = self.docstring_to_latex(arg_typ, func_doc, 14) + out('%s\\textit{ (%s=%%\n%s%s)}\n' % (' '*12, lhs, + rhs, ' '*12)) + out(' '*6+'\\end{EpydocFunctionParameters}\n') - def function_signature(self, var_doc): + def function_signature(self, var_doc, indent=6): func_doc = var_doc.value func_name = var_doc.name - s = ('\\begin{EpydocFunctionSignature}{%s}%%\n' % - _hypertarget(var_doc, func_name)) + s = ('%s\\begin{EpydocFunctionSignature}%%\n%s {%s}%%\n' % + (indent*' ', indent*' ', _hypertarget(var_doc, func_name))) # This should never happen, but just in case: if func_doc not in (None, UNKNOWN): @@ -842,9 +878,10 @@ plaintext_to_latex(func_doc.vararg)) if func_doc.kwarg: args.append('\\KWArg{%s}' % plaintext_to_latex(func_doc.kwarg)) - - s += ' '+'%\n \\and'.join(args)+'%\n' - s += '\\end{EpydocFunctionSignature}%\n' + + argindent = (indent*' '+' ') + s += argindent+('%%\n%s\\and' % argindent).join(args)+'%\n' + s += indent*' '+'\\end{EpydocFunctionSignature}%\n' return s @@ -869,66 +906,80 @@ #//////////////////////////////////////////////////////////// def write_var(self, out, var_doc): + # We're passing arguments using xkeyval, which is unhappy if + # the arguments contain \par. So replace every occurence of + # \par with \EpydocPar (which is defined to just return \par). + out = self.replace_par(out) + has_descr = var_doc.descr not in (None, UNKNOWN) has_type = var_doc.type_descr not in (None, UNKNOWN) has_repr = (var_doc.value not in (None, UNKNOWN) and (var_doc.value.parse_repr is not UNKNOWN or var_doc.value.pyval_repr() is not UNKNOWN)) - - out('\\EpydocVariable{%s}{' % _hypertarget(var_doc, var_doc.name)) + + out(' \\EpydocVariable{%% <<< %s >>>\n' % var_doc.name) + out(' name={%s}' % _hypertarget(var_doc, var_doc.name)) if has_descr: - out(self.docstring_to_latex(var_doc.descr, var_doc, 10).strip()) - out('}{') + out(',\n description={%%\n%s }' % + self.docstring_to_latex(var_doc.descr, var_doc, 6)) if has_type: - out(self.docstring_to_latex(var_doc.type_descr, - var_doc, 12).strip()) - out('}{') + out(',\n type={%%\n%s }' % + self.docstring_to_latex(var_doc.type_descr, var_doc, 6)) if has_repr: - out(var_doc.value.summary_pyval_repr().to_latex(None)) - out('}\n') + out(',\n value={%s}' % + var_doc.value.summary_pyval_repr().to_latex(None)) + metadata = self.metadata(var_doc, 6) + if metadata: + out(',\n metadata={%%\n%s }' % metadata) + out('}%\n') #//////////////////////////////////////////////////////////// #{ Property Details #//////////////////////////////////////////////////////////// def write_property(self, out, var_doc): + # We're passing arguments using xkeyval, which is unhappy if + # the arguments contain \par. So replace every occurence of + # \par with \EpydocPar (which is defined to just return \par). + out = self.replace_par(out) + prop_doc = var_doc.value has_descr = prop_doc.descr not in (None, UNKNOWN) has_type = prop_doc.type_descr not in (None, UNKNOWN) - out('\\EpydocProperty{%s}{' % _hypertarget(var_doc, var_doc.name)) + + out(' \\EpydocProperty{%% <<< %s >>>\n' % var_doc.name) + out(' name={%s}' % _hypertarget(var_doc, var_doc.name)) if has_descr: - out(self.docstring_to_latex(prop_doc.descr, - prop_doc, 10).strip()) - out('}{') + out(',\n description={%%\n%s }' % + self.docstring_to_latex(prop_doc.descr, prop_doc, 6)) if has_type: - out(self.docstring_to_latex(prop_doc.type_descr, - prop_doc, 12).strip()) - out('}{') + out(',\n type={%%\n%s }' % + self.docstring_to_latex(prop_doc.type_descr, prop_doc, 6)) # [xx] What if the accessor is private and show_private=False? - if (prop_doc.fget not in (None, UNKNOWN) and - not prop_doc.fget.canonical_name[0].startswith('??')): - out(_dotted(prop_doc.fget.canonical_name)) - out('}{') - if (prop_doc.fset not in (None, UNKNOWN) and - not prop_doc.fset.canonical_name[0].startswith('??')): - out(_dotted(prop_doc.fset.canonical_name)) - out('}{') - if (prop_doc.fdel not in (None, UNKNOWN) and - not prop_doc.fdel.canonical_name[0].startswith('??')): - out(_dotted(prop_doc.fdel.canonical_name)) - out('}\n') + for accessor in ('fget', 'fset', 'fdel'): + accessor_func = getattr(prop_doc, accessor) + if (accessor_func not in (None, UNKNOWN) and + not accessor_func.canonical_name[0].startswith('??')): + if isinstance(accessor_func, RoutineDoc): + suffix = '()' + else: + suffix = '' + out(',\n %s={%s%s}' % + (accessor, _dotted(accessor_func.canonical_name), suffix)) + metadata = self.metadata(prop_doc, 6) + if metadata: + out(',\n metadata={%%\n%s }' % metadata) + out('}%\n') #//////////////////////////////////////////////////////////// #{ Standard Fields #//////////////////////////////////////////////////////////// - # Copied from HTMLWriter: - def write_standard_fields(self, out, doc): + def metadata(self, doc, indent=0): fields = [] field_values = {} + s = '' - #if _sort_fields: fields = STANDARD_FIELD_NAMES [XX] - for (field, arg, descr) in doc.metadata: if field not in field_values: fields.append(field) @@ -938,38 +989,49 @@ else: field_values.setdefault(field,[]).append(descr) + if fields and indent == 0: + s += self.start_of('Metadata', doc) + for field in fields: if field.takes_arg: for arg, descrs in field_values[field].items(): - self.write_standard_field(out, doc, field, descrs, arg) - + s += self.meatadata_field(doc, field, descrs, + indent, arg) else: - self.write_standard_field(out, doc, field, field_values[field]) + s += self.meatadata_field(doc, field, field_values[field], + indent) + return s + - def write_standard_field(self, out, doc, field, descrs, arg=''): + def meatadata_field(self, doc, field, descrs, indent, arg=''): singular = field.singular plural = field.plural if arg: singular += ' (%s)' % arg plural += ' (%s)' % arg - out(self._descrlist([self.docstring_to_latex(d, doc) for d in descrs], - field.singular, field.plural, field.short)) - - def _descrlist(self, items, singular, plural=None, short=0): + return (' '*indent + '%% %s:\n' % field.singular + + self._descrlist([self.docstring_to_latex(d, doc, indent+2) + for d in descrs], + field.singular, field.plural, field.short, + indent)) + + # [xx] ignores indent for now + def _descrlist(self, items, singular, plural=None, short=0, indent=0): + ind = indent*' ' if plural is None: plural = singular if len(items) == 0: return '' if len(items) == 1 and singular is not None: - return ('\\EpydocMetadataSingleValue{%s}{%s}\n\n' % - (singular, items[0])) + return ('%s\\EpydocMetadataSingleValue{%s}{\n%s%s}\n' % + (ind, singular, items[0], ind)) if short: - s = '\\begin{EpydocMetadataShortList}{%s}%%\n ' % plural - s += '%\n \\and '.join([item.strip() for item in items]) - s += '%\n\\end{EpydocMetadataShortList}\n\n' + s = '%s\\begin{EpydocMetadataShortList}{%s}\n' % (ind, plural) + s += ('%s\\and\n' % ind).join(items) + s += '%s\\end{EpydocMetadataShortList}\n' % ind return s else: - s = '\\begin{EpydocMetadataLongList}{%s}%%\n' % plural - s += '\n\n'.join([' \item %s%%' % item for item in items]) - s += '\n\\end{EpydocMetadataLongList}\n\n' + s = '%s\\begin{EpydocMetadataLongList}{%s}\n' % (ind, plural) + s += ''.join(['%s \item\n%s' % (ind,item) for item in items]) + s += '%s\\end{EpydocMetadataLongList}\n' % ind return s @@ -989,15 +1051,20 @@ _docstring_linker = _LatexDocstringLinker() def docstring_to_latex(self, docstring, where, indent=0, breakany=0): + """ + Return a latex string that renders the given docstring. This + string expects to start at the beginning of a line; and ends + with a newline. + """ if docstring is None: return '' - s = docstring.to_latex(self._docstring_linker, indent=indent, + s = docstring.to_latex(self._docstring_linker, indent=indent+2, directory=self._directory, docindex=self.docindex, context=where, hyperref=self._hyperref) - return (' '*indent + '\\begin{EpydocDescription}%\n' + - s.strip() + '%\n' + - ' '*indent + '\\end{EpydocDescription}\n\n') + return (' '*indent + '\\begin{EpydocDescription}\n' + + ' '*indent + ' ' + s.strip() + '%\n' + + ' '*indent + '\\end{EpydocDescription}\n') #//////////////////////////////////////////////////////////// #{ Helpers @@ -1013,10 +1080,10 @@ out('\n%%\n%% Generated by epydoc %s\n' % epydoc.__version__) out('%% [%s]\n%%\n' % time.asctime(time.localtime(time.time()))) - def write_start_of(self, out, section_name): - out('\n' + 75*'%' + '\n') - out('%%' + section_name.center(71) + '%%\n') - out(75*'%' + '\n\n') + def start_of(self, section_name, doc=None): + return ('\n' + 75*'%' + '\n' + + '%%' + section_name.center(71) + '%%\n' + + 75*'%' + '\n\n') def section(self, title, depth=0, ref=None): sec = self.SECTIONS[depth+self._top_section] @@ -1058,8 +1125,9 @@ # [xx] list modules, classes, and functions as top-level index # items. Methods are listed under their classes. Nested classes # are listed under their classes. - def indexterm(self, doc, pos='only'): - """Mark a term or section for inclusion in the index.""" + def indexterm(self, doc, pos='only', indent=0): + """Return a latex string that marks the given term or section + for inclusion in the index. This string ends with a newline.""" if not self._index: return '' if isinstance(doc, RoutineDoc) and not self._index_functions: return '' @@ -1078,8 +1146,10 @@ pieces.reverse() kinds.reverse() for i in range(1, len(pieces)): - pieces[i] = '%s.%s' % (pieces[i-1], pieces[i]) - pieces = ['\\EpydocIndex{%s}{%s}{%s}' % (piece.lower(), piece, kind) + if not kinds[i].endswith('method'): + pieces[i] = '%s.%s' % (pieces[i-1], pieces[i]) + pieces = ['\\EpydocIndex{%s}{%s}{%s}' % + (_dotted(piece.lower()), _dotted(piece), kind) for (piece, kind) in zip (pieces, kinds)] if pos == 'only': modifier = '' @@ -1087,9 +1157,7 @@ elif pos == 'end': modifier = '|)' else: raise AssertionError('Bad index position %s' % pos) - term = '\\index{%s%s}\n' % ('!'.join(pieces), modifier) - - return term + return '%s\\index{%s%s}%%\n' % (' '*indent, '!'.join(pieces), modifier) #: Map the Python encoding representation into mismatching LaTeX ones. latex_encodings = { @@ -1104,16 +1172,26 @@ enc = self._encoding.lower() return self.latex_encodings.get(enc, enc) - def crossref(self, doc): + def crossref(self, doc, indent=0): if (self._show_crossrefs and ((isinstance(doc, ModuleDoc) and doc in self.module_set) or (isinstance(doc, ClassDoc) and doc in self.class_set))): - return '\\CrossRef{%s}' % (_label(doc),) + return '%s\\CrossRef{%s}%%\n' % (' '*indent, _label(doc),) else: return '' def _label(doc): - return ':'.join(doc.canonical_name) + # Convert to a string & replace . and _. + s = '%s' % doc.canonical_name + s = s.replace('.', ':').replace('_','-') + + # Get rid of any other characters. This is necessary only if + # we're processing a script (whose name can be just about + # anything), an unreachable value, or an object whose name has + # been mangled with black magic. + s = re.sub('[^\w:-]', '-', s) + + return s # [xx] this should get used more often than it does, I think: def _hyperlink(target, name): @@ -1124,5 +1202,90 @@ def _dotted(name): if not name: return '' + name = '%s' % name + # There are a couple of characters that even \\EpydocDottedName + # can't cope with; so filter them out. + name = re.sub('[%#]|\^\^+|\n', '?', name) return '\\EpydocDottedName{%s}' % name +LATEX_WARNING_RE = re.compile('|'.join([ + r'(?P<file>\([\.a-zA-Z_\-/\\ \n0-9]+[.\n][a-z]{2,3}\b)', + (r'(?P<pkgwarn>^(Package|Latex) (?P<pkgname>[\w-]+) '+ + r'Warning:[^\n]*\n(\((?P=pkgname)\)[^\n]*\n)*)'), + r'(?P<overfull>^(Overfull|Underfull)[^\n]*\n[^\n]*)', + r'(?P<latexwarn>^LaTeX\s+Warning:\s+[^\n]*)', + r'(?P<otherwarn>^[^\n]*Warning:[^\n]*)', + r'(?P<paren>[()])']), + re.MULTILINE+re.IGNORECASE) + +OVERFULL_RE = re.compile( + r'(?P<typ>Underfull|Overfull)\s+\\(?P<boxtype>[vh]box)\s+' + r'\((?P<size>\d+)[^\n\)]+\)[^\n]+\s+lines\s+' + r'(?P<start>\d+)') + +IGNORE_WARNING_REGEXPS = [ + re.compile(r'LaTeX\s+Font\s+Warning:\s+.*\n\(Font\)\s*using.*instead'), + re.compile(r'LaTeX\s+Font\s+Warning:\s+Some\s+font\s+shapes\s+' + r'were\s+not\s+available,\s+defaults\s+substituted.'), + ] + +def show_latex_warnings(s): + s = re.sub('(.{79,79})\n', r'\1', s) + + #[xx] we should probably pay special attention to overfull \vboxes. + overfull = underfull = 0 + filestack = ['latex'] + for m in LATEX_WARNING_RE.finditer(s): + # Check if it's something we don't care about. + for regexp in IGNORE_WARNING_REGEXPS: + if regexp.match(m.group()): + m = None; break + if m is None: continue + # LaTeX started reading a new file: + if m.group('file'): + filename = ''.join(m.group('file')[1:].split()) + filename = re.sub(r'^\./', '', filename) + filestack.append(filename) + # Latex reported an overfull/underfull warning: + elif m.group('overfull'): + msg = m.group('overfull').strip().split('\n')[0] + if msg.lower().startswith('overfull'): overfull += 1 + else: underfull += 1 + m2 = OVERFULL_RE.match(msg) + if m2: + if m2.group('boxtype') == 'vbox': + log.warning('%s: %s' % (filestack[-1], msg)) + elif (m2.group('typ').lower()=='overfull' and + int(m2.group('size')) > 50): + log.warning('%s: %s' % (filestack[-1], msg)) + else: + log.debug('%s: %s' % (filestack[-1], msg)) + else: + log.debug('%s: %s' % (filestack[-1], msg)) + # Latex reported a warning: + elif m.group('latexwarn'): + msg = m.group('latexwarn').strip() + log.warning('%s: %s' % (filestack[-1], msg)) + # A package reported a warning: + elif m.group('pkgwarn'): + msg = m.group('pkgwarn').strip() + log.warning('%s:\n%s' % (filestack[-1], msg)) + else: + # Display anything else that looks like a warning: + if m.group('otherwarn'): + msg = m.group('otherwarn').strip() + log.warning('%s: %s' % (filestack[-1], msg)) + # Update to account for parens. + n = m.group().count('(') - m.group().count(')') + if n > 0: filestack += [None] * n + if n < 0: del filestack[n:] + if overfull or underfull: + msgs = [] + if overfull == 1: msgs.append('1 overfull box') + elif overfull: msgs.append('%d overfull boxes' % overfull) + if underfull == 1: msgs.append('1 underfull box') + elif underfull: msgs.append('%d underfull boxes' % underfull) + log.warning('LaTeX reported %s' % ' and '.join(msgs)) + +#log.register_logger(log.SimpleLogger(log.DEBUG)) +#show_latex_warnings(open('/tmp/po.test').read()) Modified: trunk/epydoc/src/epydoc/docwriter/latex_sty.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-27 20:24:06 UTC (rev 1805) +++ trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-03-04 02:31:57 UTC (rev 1806) @@ -75,6 +75,7 @@ \RequirePackage[headings]{fullpage} \RequirePackage[usenames]{color} \RequirePackage{graphicx} +\RequirePackage{url} \@ifclassloaded{memoir}{% \RequirePackage[other,notbib]{tocbibind} @@ -130,6 +131,11 @@ % Create a 'base class' length named EpydocBCL for use in base trees. \newlength{\EpydocBCL} % base class length, for base trees. +% In xkeyval arguments, we're not allowed to use \par. But we *are* +% allowed to use a command that evaluates to \par, so define such a +% command. +\newcommand{\EpydocPar}{\par} + % ====================================================================== % Sections inside docstring @@ -192,17 +198,17 @@ % it to its default value). \newenvironment{EpydocDescription}{% \setlength{\parskip}{\EpydocParskip}% - }{} + \ignorespaces}{\ignorespacesafterend} % This environment is used to mark the description for a class % (which comes from the function's docstring). \newenvironment{EpydocClassDescription}{% - }{} + \ignorespaces}{\ignorespacesafterend} % This environment is used to mark the description for a module % (which comes from the function's docstring). \newenvironment{EpydocModuleDescription}{% - }{} + \ignorespaces}{\ignorespacesafterend} % ====================================================================== % Python Source Code Syntax Highlighting. @@ -323,36 +329,31 @@ % % All arguments except for the first (the signature) may be empty. % +\define@cmdkeys[Epydoc]{function}{signature,description,parameters, + returndescr,returntype,raises, + overrides,metadata} \newenvironment{EpydocFunctionList}{% - \newcommand{\EpydocFunction}[8]{ - \gdef\@EpydocFunctionSignature{##1}% - \gdef\@EpydocFunctionDescription{##2}% - \gdef\@EpydocFunctionParameters{##3}% - \gdef\@EpydocFunctionReturnDescr{##4}% - \gdef\@EpydocFunctionReturnType{##5}% - \gdef\@EpydocFunctionRaises{##6}% - \gdef\@EpydocFunctionOverrides{##7}% - \gdef\@EpydocFunctionMetadata{##8}% - {\Large\raggedright\@EpydocFunctionSignature\par} - \begin{quote}% - \setlength{\parskip}{\EpydocParskip}% - \ifx\@EpydocFunctionDescription\empty\else - \par\@EpydocFunctionDescription\fi% - \ifx\@EpydocFunctionParameters\empty\else - \par\@EpydocFunctionParameters\fi% - \ifx\@EpydocFunctionReturnDescr\empty - \par\@EpydocFunctionReturnDescr\fi% - \ifx\@EpydocFunctionReturnType\empty - \par\@EpydocFunctionReturnType\fi% - \ifx\@EpydocFunctionRaises\empty\else - \par\@EpydocFunctionRaises\fi% - \ifx\@EpydocFunctionOverrides\empty\else - \par\@EpydocFunctionOverrides\fi% - \ifx\@EpydocFunctionMetadata\empty\else - \par\@EpydocFunctionMetadata\fi% - \end{quote} - - }} + \newcommand{\EpydocFunction}[1]{{% + \setkeys[Epydoc]{function}{##1}% + {\Large\raggedright\cmdEpydoc@function@signature\par} + \begin{quote}% + \setlength{\parskip}{\EpydocParskip}% + \@ifundefined{cmdEpydoc@function@description}{}{ + \par\cmdEpydoc@function@description} + \@ifundefined{cmdEpydoc@function@parameters}{}{ + \par\cmdEpydoc@function@parameters} + \@ifundefined{cmdEpydoc@function@returndescr}{}{ + \par \textbf{Returns:} \cmdEpydoc@function@returndescr} + \@ifundefined{cmdEpydoc@function@returntype}{}{ + \par \textbf{Return Type:} \cmdEpydoc@function@returntype} + \@ifundefined{cmdEpydoc@function@raises}{}{ + \par\cmdEpydoc@function@raises} + \@ifundefined{cmdEpydoc@function@overrides}{}{ + \par\cmdEpydoc@function@overrides} + \@ifundefined{cmdEpydoc@function@metadata}{}{ + \ifx\cmdEpydoc@function@metadata\empty\else + \par\cmdEpydoc@function@metadata\fi} + \end{quote}\par}}} {} % The EpydocFunctionSignature environment is used to display a @@ -382,7 +383,7 @@ \textit{##2}% \ifthenelse{\equal{##1}{}}{}{=\texttt{##1}}}% \@hangfrom{\textbf{#1}(}% - }{)\par} + }{)} % The EpydocFunctionParameters environment is used to display % descriptions for the parameters that a function can take. @@ -439,23 +440,23 @@ % % If any of these arguments is not available, then the empty % string will be used. +\define@cmdkeys[Epydoc]{variable}{name,description,type,value,metadata} \newenvironment{EpydocVariableList}{% - \newcommand{\EpydocVariable}[4]{% - \gdef\@EpydocVariableName{##1}% - \gdef\@EpydocVariableDescription{##2}% - \gdef\@EpydocVariableType{##3}% - \gdef\@EpydocVariableValue{##4}% - {\Large\raggedright\@EpydocVariableName\par} - \begin{quote} - \setlength{\parskip}{\EpydocParskip}% - \ifx\@EpydocVariableDescription\empty\else - \par\@EpydocVariableDescription\fi% - \ifx\@EpydocVariableType\empty\else - \par\textbf{Type:} \@EpydocVariableType\fi% - \ifx\@EpydocVariableValue\empty - \par\textbf{Value:} \texttt{\@EpydocVariableValue}\fi% - \end{quote} - }} + \newcommand{\EpydocVariable}[1]{{% + \setkeys[Epydoc]{variable}{##1}% + {\Large\raggedright\cmdEpydoc@variable@name\par} + \begin{quote} + \setlength{\parskip}{\EpydocParskip}% + \@ifundefined{cmdEpydoc@variable@description}{}{% + \par\cmdEpydoc@variable@description}% + \@ifundefined{cmdEpydoc@variable@type}{}{% + \par\textbf{Type:} \cmdEpydoc@variable@type}% + \@ifundefined{cmdEpydoc@variable@value}{}{% + \par\textbf{Value:} \cmdEpydoc@variable@value}% + \@ifundefined{cmdEpydoc@variable@metadata}{}{% + \ifx\cmdEpydoc@variable@metadata\empty\else + \par\cmdEpydoc@variable@metadata\fi}% + \end{quote}\par}}} {} % The EpydocClassVariableList environment is used the same way as @@ -486,29 +487,28 @@ % % If any of these arguments is not available, then the empty % string will be used. +\define@cmdkeys[Epydoc]{property}{name,description,type,fget, + fset,fdel,metadata} \newenvironment{EpydocPropertyList}{% - \newcommand{\EpydocProperty}[6]{% - \gdef\@EpydocPropertyName{##1}% - \gdef\@EpydocPropertyDescription{##2}% - \gdef\@EpydocPropertyType{##3}% - \gdef\@EpydocPropertyGet{##4}% - \gdef\@EpydocPropertySet{##5}% - \gdef\@EpydocPropertyDel{##6}% - {\Large\raggedright\@EpydocPropertyName\par} - \begin{quote} - \setlength{\parskip}{\EpydocParskip}% - \ifx\@EpydocPropertyDescription\empty\else - \par\@EpydocPropertyDescription\fi% - \ifx\@EpydocPropertyType\empty\else - \par\textbf{Type:} \@EpydocPropertyType\fi% - \ifx\@EpydocPropertyGet\empty - \par\textbf{Get:} \texttt{\@EpydocPropertyGet}\fi% - \ifx\@EpydocPropertySet\empty - \par\textbf{Set:} \texttt{\@EpydocPropertySet}\fi% - \ifx\@EpydocPropertyDel\empty - \par\textbf{Delete:} \texttt{\@EpydocPropertyDel}\fi% - \end{quote} - }} + \newcommand{\EpydocProperty}[1]{{% + \setkeys[Epydoc]{property}{##1}% + {\Large\raggedright\cmdEpydoc@property@name\par} + \begin{quote} + \setlength{\parskip}{\EpydocParskip}% + \@ifundefined{cmdEpydoc@property@description}{}{ + \par\cmdEpydoc@property@description} + \@ifundefined{cmdEpydoc@property@type}{}{ + \par\textbf{Type:} \cmdEpydoc@property@type} + \@ifundefined{cmdEpydoc@property@fget}{}{ + \par\textbf{Get:} \cmdEpydoc@property@fget} + \@ifundefined{cmdEpydoc@property@fset}{}{ + \par\textbf{Set:} \cmdEpydoc@property@fset} + \@ifundefined{cmdEpydoc@property@fdel}{}{ + \par\textbf{Delete:} \cmdEpydoc@property@fdel} + \@ifundefined{cmdEpydoc@property@metadata}{}{ + \ifx\cmdEpydoc@property@metadata\empty\else + \par\cmdEpydoc@property@metadata\fi} + \end{quote}\par}}} {} % ====================================================================== @@ -516,28 +516,32 @@ % This command is used to display a metadata field with a single value \newcommand{\EpydocMetadataSingleValue}[2]{% + \par \begin{list}{}{\itemindent-\leftmargin} \item \textbf{#1:} #2 - \end{list} - } + \end{list}\par\ignorespaces} % This environment is used to display a metadata field with multiple % values when the field declares that short=True; i.e., that multiple % values should be combined into a single comma-delimited list. \newenvironment{EpydocMetadataShortList}[1]{% \newcommand{\and}{, }% - \textbf{#1: }} - {} + \par + \begin{list}{}{\itemindent-\leftmargin} + \item \textbf{#1:} \ignorespaces} + {\end{list}\ignorespacesafterend\par} % This list environment is used to display a metadata field with % multiple values when the field declares that short=False; i.e., that % multiple values should be listed separately in a bulleted list. \newenvironment{EpydocMetadataLongList}[1]{% + \par \textbf{#1:} \setlength{\parskip}{0ex} \begin{itemize} - \setlength{\parskip}{\EpydocMetadataLongListParskip}} - {\end{itemize}} + \setlength{\parskip}{\EpydocMetadataLongListParskip} + \ignorespaces} + {\end{itemize}\ignorespacesafterend\par} % ====================================================================== % reStructuredText Admonitions @@ -545,19 +549,16 @@ % This environment is used to display reStructuredText admonitions, % such as ``..warning::'' and ``..note::''. \newenvironment{reSTadmonition}[1][]{% - \begin{center}\begin{sffamily} - \begin{lrbox}{\@tempboxa} - \begin{minipage}{\admonitionwidth} - \textbf{\large #1} - \vspace{2mm} - } - { - \end{minipage} - \end{lrbox} - \fbox{\usebox{\@tempboxa}} - \end{sffamily} - \end{center} - } + \begin{center}\begin{sffamily}% + \begin{lrbox}{\@tempboxa}% + \begin{minipage}{\admonitionwidth}% + \textbf{\large #1}% + \vspace{2mm}}% + {\end{minipage}% + \end{lrbox}% + \fbox{\usebox{\@tempboxa}}% + \end{sffamily}% + \end{center}} % ====================================================================== % Name Formatting @@ -565,27 +566,24 @@ % This section defines the EpydocDottedName command, which is used to % display the names of Python objects. -% Allows non-hyphenated wrapping at the '.' module separators. The -% rest is a simplified version of url.sty's tt style. -\RequirePackage{url} -\def\Url@pydo{% style assignments for tt fonts or T1 encoding -\def\UrlBreaks{\do\]\do\)\do\_}% -\def\UrlBigBreaks{\do@url@hyp\do\.}% -% \def\UrlNoBreaks{\do\(\do\[\do\{\do\<\do\_}% (unnecessary) -\def\UrlNoBreaks{\do\(\do\[\do\{\do\<}% (unnecessary) -\def\UrlSpecials{\do\ {\ }}% -\def\UrlOrds{\do\*\do\-\do\~}% any ordinary characters that aren't usually -} +% The \EpydocDottedName command is used to escape dotted names. In +% particular, it escapes all characters except '#', '%', and newlines, +% and allows non-hyphenated wrapping at '.' separator characters. +% [xx] this generates a warning for names containing _ -- we need +% to somehow strip that out of the second argument. +\newcommand\EpydocDottedName[1]{% + \texorpdfstring{\protect\Epydoc@DottedName{#1}}{#1}} -\def\url@pystyle{% -\@ifundefined{selectfont}{\def\UrlFont{\rm}}{\def\UrlFont{\rmfamily}}\Url@pydo +\DeclareUrlCommand\Epydoc@DottedName{% + \urlstyle{rm}% + \def\UrlBigBreaks{\do\.}% + % We should never see most of these chars in a name, but handle + % them if they happen to show up (eg script names) + \def\UrlOrds{\do\@\do\#\do\%\do\^\do\&\do\(\do\)\do\-\do\_% + \do\|\do\\\do\"\do\/\do\?\do\>\do\<\do\{\do\}% + \do\`\do\~} } -\newcommand\pymodule{\begingroup \urlstyle{py}\Url} -% The \EpydocDottedName command is used to escape dotted names. In -% particular, it escapes underscores (_) and allows non-hyphenated -% wrapping at '.' separator characters. -\newcommand\EpydocDottedName[1]{\texorpdfstring{\protect\pymodule{#1}}{#1}} """+NIST_DISCLAIMER ###################################################################### ###################################################################### @@ -607,15 +605,14 @@ % $Id:$ \NeedsTeXFormat{LaTeX2e} \ProvidesClass{epydoc-boxes}[2008/02/26 v3.0.1 Epydoc Python Documentation] - +% Pass options to the epydoc base package. \RequirePackage{xkeyval} -\DeclareOptionX{index}{\PassOptionsToPackage{index}{epydoc-base}} -\DeclareOptionX{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} -\DeclareOptionX{title}[]{\PassOptionsToPackage{title={#1}}{epydoc-base}} -\DeclareOptionX{creator}[]{\PassOptionsToPackage{creator={#1}}{epydoc-base}} +\DeclareOptionX*{\PassOptionsToPackage{\CurrentOption}{epydoc-base}} \ProcessOptionsX\relax - +% Load the base epydoc package \RequirePackage{epydoc-base} + +% Use longtable for variable & property lists. \RequirePackage{longtable} % Double the standard size boxedminipage outlines. @@ -636,60 +633,50 @@ \renewenvironment{EpydocFunctionList}{% \def\@EpydocSeparator{% \vspace{-2\EpydocParskip} - \rule{\dimexpr \textwidth-2\fboxsep \relax}{0.5\fboxrule} + \rule{\dimexpr \textwidth-2\fboxsep}{0.5\fboxrule} \aftergroup\def\aftergroup\@EpydocSeparator% \aftergroup{\aftergroup}}% - \newcommand{\EpydocFunction}[8]{ - \gdef\@EpydocFunctionSignature{##1}% - \gdef\@EpydocFunctionDescription{##2}% - \gdef\@EpydocFunctionParameters{##3}% - \gdef\@EpydocFunctionReturnDescr{##4}% - \gdef\@EpydocFunctionReturnType{##5}% - \gdef\@EpydocFunctionRaises{##6}% - \gdef\@EpydocFunctionOverrides{##7}% - \gdef\@EpydocFunctionMetadata{##8}% - \begin{boxedminipage}{\dimexpr \textwidth-2\fboxsep \relax} - {\Large\raggedright\@EpydocFunctionSignature\par} - \setlength{\parskip}{\EpydocParskip} - \ifx\@EpydocFunctionDescription\empty\else% - {\@EpydocSeparator}% - \@EpydocFunctionDescription % - \fi% - \ifx\@EpydocFunctionParameters\empty\else% - {\@EpydocSeparator}% - \@EpydocFunctionParameters % - \fi% - \ifx\@EpydocFunctionReturnType\empty% - \ifx\@EpydocFunctionReturnDescr\empty\else% + \newcommand{\EpydocFunction}[1]{{% + \setkeys[Epydoc]{function}{##1}% + \begin{boxedminipage}{\dimexpr \textwidth-2\fboxsep} + {\Large\raggedright\cmdEpydoc@function@signature\par} + \setlength{\parskip}{\EpydocParskip} + \@ifundefined{cmdEpydoc@function@description}{}{% {\@EpydocSeparator}% - \textbf{Return Value}% - \vspace{-\EpydocParskip}% - \begin{quote}\@EpydocFunctionReturnDescr\end{quote}% - \fi% - \else% - {\@EpydocSeparator}% - \textbf{Return Value}% - \vspace{-\EpydocParskip}% - \ifx\@EpydocFunctionReturnDescr\empty% - \begin{quote}\it \@EpydocFunctionReturnType\end{quote}% - \else% - \begin{quote}\@EpydocFunctionReturnDescr% - \textit{(type=\@EpydocFunctionReturnType)}\end{quote}% - \fi% - \fi% - \ifx\@EpydocFunctionRaises\empty\else% - {\@EpydocSeparator}% - \@EpydocFunctionRaises % - \fi% - \ifx\@EpydocFunctionOverrides\empty\else% - {\@EpydocSeparator}% - \@EpydocFunctionOverrides % - \fi% - \ifx\@EpydocFunctionMetadata\empty\else% - {\@EpydocSeparator}% - \@EpydocFunctionMetadata % - \fi% - \end{boxedminipage}\par}} + \par\cmdEpydoc@function@description}% + \@ifundefined{cmdEpydoc@function@parameters}{}{% + {\@EpydocSeparator}% + \par\cmdEpydoc@function@parameters}% + \@ifundefined{cmdEpydoc@function@returntype}{ + \@ifundefined{cmdEpydoc@function@returndescr}{}{ + {\@EpydocSeparator}% + \par\textbf{Return Value}% + \par\vspace{-\EpydocParskip}% + \begin{quote}\cmdEpydoc@function@returndescr\end{quote}}% + }{ + {\@EpydocSeparator}% + \par\textbf{Return Value}% + \par\vspace{-\EpydocParskip}% + \begin{quote}% + \@ifundefined{cmdEpydoc@function@returndescr}{ + \textit{\cmdEpydoc@function@returntype}% + }{% + \cmdEpydoc@function@returndescr% + \textit{(type=\cmdEpydoc@function@returntype)}}% + \end{quote}% + } + \@ifundefined{cmdEpydoc@function@raises}{}{% + {\@EpydocSeparator}% + \par\cmdEpydoc@function@raises}% + \@ifundefined{cmdEpydoc@function@overrides}{}{% + {\@EpydocSeparator}% + \par\cmdEpydoc@function@overrides}% + \@ifundefined{cmdEpydoc@function@metadata}{}{% + \ifx\cmdEpydoc@property@metadata\empty\else + {\@EpydocSeparator}% + \par\cmdEpydoc@function@metadata% + \fi}% + \end{boxedminipage}\par}}} {} % ====================================================================== @@ -718,7 +705,7 @@ p{\EpydocVariableWidth}| p{\dimexpr \textwidth% -4\tabcolsep-7pt - -\EpydocVariableWidth \relax} + -\EpydocVariableWidth} @{\hspace \tabcolsep \vrule width \fboxrule}} % Set up the headers & footer (this makes the table span % multiple pages in a happy way). @@ -738,28 +725,22 @@ % Variable Lists \renewenvironment{EpydocVariableList}{% - \newcommand{\EpydocVariable}[4]{% - \gdef\@EpydocVariableName{##1}% - \gdef\@EpydocVariableDescription{##2}% - \gdef\@EpydocVariableType{##3}% - \gdef\@EpydocVariableValue{##4}% - \raggedright\@EpydocVariableName & % + \newcommand{\EpydocVariable}[1]{{% + \setkeys[Epydoc]{variable}{##1}% + \raggedright\cmdEpydoc@variable@name &% + \setkeys[Epydoc]{variable}{##1}% \setlength{\parskip}{\EpydocParskip}\raggedright% - \@EpydocVariableDescription % - \ifx\@EpydocVariableValue\empty\relax% - \ifx\@EpydocVariableType\empty\else% - \ifx\@EpydocVariableDescription\empty\else\par\fi% - \textit{(type=\texttt{\@EpydocVariableType})}% - \fi% - \else\relax% - \ifx\@EpydocVariableDescription\empty\else\par\fi% - \textbf{Value:} \texttt{\@EpydocVariableValue}% - \ifx\@EpydocVariableType\empty\else% - \textit{(type=\texttt{\@EpydocVariableType})}% - \fi% - \fi% + \@ifundefined{cmdEpydoc@variable@description}{}{% + \cmdEpydoc@variable@description\relax}% + \@ifundefined{cmdEpydoc@variable@value}{}{% + \@ifundefined{cmdEpydoc@variable@description}{}{\par}% + \textbf{Value:} \texttt{\cmdEpydoc@variable@value}}% + \@ifundefined{cmdEpydoc@variable@type}{}{% + \@ifundefined{cmdEpydoc@variable@description}{% + \@ifundefined{cmdEpydoc@variable@value}{}{ }}{ }% + \textit{(type=\texttt{\cmdEpydoc@variable@type})}}% \tabularnewline - \hline}% + \hline}}% \begin{@EpydocGeneralList}% } {\end{@EpydocGeneralList}} @@ -775,39 +756,30 @@ \renewenvironment{EpydocPropertyList}{% \def\@EpydocSeparator{% \aftergroup\def\aftergroup\@EpydocSeparator\aftergroup{% - \aftergroup\\\aftergroup[\aftergroup\EpydocParskip\aftergroup]% + \aftergroup\par% \aftergroup}}% - \newcommand{\EpydocProperty}[6]{% - \gdef\@EpydocPropertyName{##1}% - \gdef\@EpydocPropertyDescription{##2}% - \gdef\@EpydocPropertyType{##3}% - \gdef\@EpydocPropertyGet{##4}% - \gdef\@EpydocPropertySet{##5}% - \gdef\@EpydocPropertyDel{##6}% - \raggedright\@EpydocPropertyName & % + \newcommand{\EpydocProperty}[1]{{% + \setkeys[Epydoc]{property}{##1}% + \raggedright\cmdEpydoc@property@name & % + \setkeys[Epydoc]{property}{##1}% \setlength{\parskip}{\EpydocParskip}\raggedright% - \ifx\@EpydocPropertyDescription\empty\else% + \@ifundefined{cmdEpydoc@property@description}{}{% {\@EpydocSeparator}% - \@EpydocPropertyDescription % - \fi% - \ifx\@EpydocPropertyType\empty\else% + \cmdEpydoc@property@description\relax}% + \@ifundefined{cmdEpydoc@property@type}{}{% {\@EpydocSeparator}% - \textbf{Type:} \@EpydocPropertyType - \fi% - \ifx\@EpydocPropertyGet\empty\else% + \textbf{Type:} \cmdEpydoc@property@type\relax}% + \@ifundefined{cmdEpydoc@property@fget}{}{% {\@EpydocSeparator}% - \textbf{Get:} \@EpydocPropertyGet% - \fi% - \ifx\@EpydocPropertySet\empty\else% + \textbf{Get:} \cmdEpydoc@property@fget\relax}% + \@ifundefined{cmdEpydoc@property@fset}{}{% {\@EpydocSeparator}% - \textbf{Set:} \@EpydocPropertySet% - \fi% - \ifx\@EpydocPropertyDel\empty\else% + \te... [truncated message content] |
From: <ed...@us...> - 2008-02-27 20:24:13
|
Revision: 1805 http://epydoc.svn.sourceforge.net/epydoc/?rev=1805&view=rev Author: edloper Date: 2008-02-27 12:24:06 -0800 (Wed, 27 Feb 2008) Log Message: ----------- - If the dot executable is not found, issue an error, and don't try to generate further graphs. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/dotgraph.py Modified: trunk/epydoc/src/epydoc/docwriter/dotgraph.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-27 19:54:39 UTC (rev 1804) +++ trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-27 20:24:06 UTC (rev 1805) @@ -357,6 +357,7 @@ return self._run_dot('-T%s' % language, size=size) def _run_dot(self, *options, **kwparam): + if get_dot_version() == (0,): return None try: result, err = run_subprocess((DOT_COMMAND,)+options, self.to_dotfile(**kwparam)) @@ -1507,6 +1508,10 @@ else: _dot_version = (0,) except OSError, e: + log.error('dot executable not found; graphs will not be ' + 'generated. Adjust your shell\'s path, or use ' + '--dotpath to specify the path to the dot ' + 'executable.' % DOT_COMMAND) _dot_version = (0,) log.info('Detected dot version %s' % _dot_version) return _dot_version This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 19:54:45
|
Revision: 1804 http://epydoc.svn.sourceforge.net/epydoc/?rev=1804&view=rev Author: edloper Date: 2008-02-27 11:54:39 -0800 (Wed, 27 Feb 2008) Log Message: ----------- - Fixed bug that causes crash when we can't determine the canonical name for a metaclass. - Fixed bug in callgraph rendering. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/html.py Modified: trunk/epydoc/src/epydoc/docwriter/html.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/html.py 2008-02-27 00:32:35 UTC (rev 1803) +++ trunk/epydoc/src/epydoc/docwriter/html.py 2008-02-27 19:54:39 UTC (rev 1804) @@ -848,7 +848,7 @@ # Write the name of the class we're describing. if (doc.metaclass is not UNKNOWN and - doc.metaclass.canonical_name is not UNKNOWN and + doc.metaclass.canonical_name not in (None, UNKNOWN) and doc.metaclass.canonical_name != 'type'): typ = self.href(doc.metaclass, doc.metaclass.canonical_name[-1]) elif doc.is_type(): typ = 'Type' @@ -1667,28 +1667,25 @@ if isinstance(callgraph, basestring): uid = callgraph - rv = self._callgraph_cache.get(callgraph, "") - + graph_html = self._callgraph_cache.get(callgraph, "") + elif callgraph.uid in self._callgraph_cache: + uid = callgraph.uid + graph_html = self._callgraph_cache.get(callgraph, "") else: uid = callgraph.uid graph_html = self.render_graph(callgraph) - if graph_html == '': - rv = "" - else: - rv = ('<div style="display:none" id="%%s-div"><center>\n' - '<table border="0" cellpadding="0" cellspacing="0">\n' - ' <tr><td>%s</td></tr>\n' - ' <tr><th>Call Graph</th></tr>\n' - '</table><br />\n</center></div>\n' % graph_html) + self._callgraph_cache[uid] = graph_html - # Store in the cache the complete HTML chunk without the - # div id, which may be made unambiguous by the token - self._callgraph_cache[uid] = rv + if graph_html: + return ('<div style="display:none" id="%s-div"><center>\n' + '<table border="0" cellpadding="0" cellspacing="0">\n' + ' <tr><td>%s</td></tr>\n' + ' <tr><th>Call Graph</th></tr>\n' + '</table><br />\n</center></div>\n' % + (uid+token, graph_html)) + else: + return '' - # Mangle with the graph - if rv: rv = rv % (uid + token) - return rv - def callgraph_link(self, callgraph, token=""): """Render the HTML chunk of a callgraph link. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 01:01:31
|
Revision: 1803 http://epydoc.svn.sourceforge.net/epydoc/?rev=1803&view=rev Author: edloper Date: 2008-02-26 16:32:35 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Added missing global SCRWIDTH Modified Paths: -------------- trunk/epydoc/src/epydoc/markup/epytext.py Modified: trunk/epydoc/src/epydoc/markup/epytext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/epytext.py 2008-02-27 00:28:32 UTC (rev 1802) +++ trunk/epydoc/src/epydoc/markup/epytext.py 2008-02-27 00:32:35 UTC (rev 1803) @@ -1502,6 +1502,7 @@ ################################################## ## Top-Level Wrapper function ################################################## +SCRWIDTH = 75 def pparse(str, show_warnings=1, show_errors=1, stream=sys.stderr): """ Pretty-parse the string. This parses the string, and catches any This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 00:29:04
|
Revision: 1802 http://epydoc.svn.sourceforge.net/epydoc/?rev=1802&view=rev Author: edloper Date: 2008-02-26 16:28:32 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Fixed silly typo Modified Paths: -------------- trunk/epydoc/src/epydoc/markup/restructuredtext.py Modified: trunk/epydoc/src/epydoc/markup/restructuredtext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/restructuredtext.py 2008-02-27 00:20:24 UTC (rev 1801) +++ trunk/epydoc/src/epydoc/markup/restructuredtext.py 2008-02-27 00:28:32 UTC (rev 1802) @@ -601,7 +601,7 @@ if graph is None: raise SkipNode() # Write the graph. - self.body.append(graph.to_latex(self._directory) + self.body.append(graph.to_latex(self._directory)) raise SkipNode() def visit_doctest_block(self, node): @@ -707,7 +707,7 @@ if graph is None: raise SkipNode() # Write the graph. - self.body.append(graph.to_html(self._directory) + self.body.append(graph.to_html(self._directory)) raise SkipNode() def visit_doctest_block(self, node): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 00:20:29
|
Revision: 1801 http://epydoc.svn.sourceforge.net/epydoc/?rev=1801&view=rev Author: edloper Date: 2008-02-26 16:20:24 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Fixed silly typo Modified Paths: -------------- trunk/epydoc/src/epydoc/cli.py Modified: trunk/epydoc/src/epydoc/cli.py =================================================================== --- trunk/epydoc/src/epydoc/cli.py 2008-02-27 00:02:34 UTC (rev 1800) +++ trunk/epydoc/src/epydoc/cli.py 2008-02-27 00:20:24 UTC (rev 1801) @@ -776,6 +776,12 @@ ###################################################################### def main(options): + """ + Perform all actions indicated by the given set of options. + + @return: the L{epydoc.apidoc.DocIndex} object created while + running epydoc (or None). + """ # Set the debug flag, if '--debug' was specified. if options.debug: epydoc.DEBUG = True @@ -982,6 +988,9 @@ # Deregister our logger(s). for logger in loggers: log.remove_logger(logger) + + # Return the docindex, in case someone wants to use it programatically. + return docindex def write_html(docindex, options): from epydoc.docwriter.html import HTMLWriter @@ -1191,6 +1200,12 @@ DocChecker(docindex).check() def cli(): + """ + Perform all actions indicated by the options in sys.argv. + + @return: the L{epydoc.apidoc.DocIndex} object created while + running epydoc (or None). + """ # Parse command-line arguments. options = parse_arguments() @@ -1199,7 +1214,7 @@ if options.profile: _profile() else: - main(options) + return main(options) finally: log.close() except SystemExit: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 00:02:36
|
Revision: 1800 http://epydoc.svn.sourceforge.net/epydoc/?rev=1800&view=rev Author: edloper Date: 2008-02-26 16:02:34 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Added --graph-image-format option Modified Paths: -------------- trunk/epydoc/src/epydoc/cli.py Modified: trunk/epydoc/src/epydoc/cli.py =================================================================== --- trunk/epydoc/src/epydoc/cli.py 2008-02-27 00:01:42 UTC (rev 1799) +++ trunk/epydoc/src/epydoc/cli.py 2008-02-27 00:02:34 UTC (rev 1800) @@ -462,6 +462,12 @@ "be a string of the form \"w,h\", specifying the maximum width " "and height in inches. Default=%r" % DotGraph.DEFAULT_LATEX_SIZE) + graph_group.add_option('--graph-image-format', + dest='graph_image_format', metavar='FORMAT', + help="Specify the file format used for graph images in the HTML " + "output. Can be one of gif, png, jpg. Default=%r" % + DotGraph.DEFAULT_HTML_IMAGE_FORMAT) + # this option is for developers, not users. graph_group.add_option("--profile-epydoc", action="store_true", dest="profile", @@ -577,7 +583,7 @@ optparser.error("Use of the pdflatex driver is incompatible " "with generating dvi or ps output.") - # Set max graph sizes + # Set graph defaults if options.max_html_graph_size: if not re.match(r'^\d+\s*,\s*\d+$', options.max_html_graph_size): optparser.error("Bad max-html-graph-size value: %r" % @@ -588,6 +594,11 @@ optparser.error("Bad max-latex-graph-size value: %r" % options.max_latex_graph_size) DotGraph.DEFAULT_LATEX_SIZE = options.max_latex_graph_size + if options.graph_image_format: + if options.graph_image_format not in ('jpg', 'png', 'gif'): + optparser.error("Bad graph-image-format %r; expected one of: " + "jpg, png, gif." % options.graph_image_format) + DotGraph.DEFAULT_HTML_IMAGE_FORMAT = options.graph_image_format # Calculate verbosity. verbosity = getattr(options, 'verbosity', 0) @@ -715,6 +726,8 @@ options.max_html_graph_size = val elif optname in ('max-latex-graph-size', 'max_latex_graph_size'): options.max_latex_graph_size = val + elif optname in ('graph-image-format', 'graph_image_format'): + options.graph_image_format = val elif optname.startswith('graph-'): color = optname[6:].upper().strip() color = color.replace('-', '_') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-27 00:01:45
|
Revision: 1799 http://epydoc.svn.sourceforge.net/epydoc/?rev=1799&view=rev Author: edloper Date: 2008-02-26 16:01:42 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Changed the usage for to_html() and to_latex() methods -- they now accept a directory, rather than an image filename (and a url in the case of to_html). This is in preparation for adding an option to specify the image format for graphs in html output. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/html.py trunk/epydoc/src/epydoc/docwriter/latex.py trunk/epydoc/src/epydoc/markup/epytext.py trunk/epydoc/src/epydoc/markup/restructuredtext.py Modified: trunk/epydoc/src/epydoc/docwriter/html.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/html.py 2008-02-26 23:54:44 UTC (rev 1798) +++ trunk/epydoc/src/epydoc/docwriter/html.py 2008-02-27 00:01:42 UTC (rev 1799) @@ -1643,9 +1643,7 @@ def render_graph(self, graph): if graph is None: return '' graph.caption = graph.title = None - image_url = '%s.gif' % graph.uid - image_file = os.path.join(self._directory, image_url) - return graph.to_html(image_file, image_url) + return graph.to_html(self._directory) or '' RE_CALLGRAPH_ID = re.compile(r"""["'](.+-div)['"]""") Modified: trunk/epydoc/src/epydoc/docwriter/latex.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-26 23:54:44 UTC (rev 1798) +++ trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-27 00:01:42 UTC (rev 1799) @@ -351,9 +351,7 @@ def render_graph(self, graph): if graph is None: return '' graph.caption = graph.title = None - image_url = '%s' % graph.uid - image_file = os.path.join(self._directory, image_url) - return graph.to_latex(image_file) or '' + return graph.to_latex(self._directory) or '' def write_class(self, out, doc, short_name=None): if short_name is None: short_name = doc.canonical_name[-1] Modified: trunk/epydoc/src/epydoc/markup/epytext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/epytext.py 2008-02-26 23:54:44 UTC (rev 1798) +++ trunk/epydoc/src/epydoc/markup/epytext.py 2008-02-27 00:01:42 UTC (rev 1799) @@ -1882,9 +1882,7 @@ docindex, context) if not graph: return '' # Write the graph. - image_url = '%s.gif' % graph.uid - image_file = os.path.join(directory, image_url) - return graph.to_html(image_file, image_url) + return graph.to_html(directory) else: raise ValueError('Unknown epytext DOM element %r' % tree.tag) @@ -2015,8 +2013,7 @@ docindex, context) if not graph: return '' # Write the graph. - image_file = os.path.join(directory, graph.uid) - return graph.to_latex(image_file) + return graph.to_latex(directory) else: # Assume that anything else can be passed through. return childstr Modified: trunk/epydoc/src/epydoc/markup/restructuredtext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/restructuredtext.py 2008-02-26 23:54:44 UTC (rev 1798) +++ trunk/epydoc/src/epydoc/markup/restructuredtext.py 2008-02-27 00:01:42 UTC (rev 1799) @@ -601,8 +601,7 @@ if graph is None: raise SkipNode() # Write the graph. - image_file = os.path.join(self._directory, graph.uid) - self.body.append(graph.to_latex(image_file)) + self.body.append(graph.to_latex(self._directory) raise SkipNode() def visit_doctest_block(self, node): @@ -708,9 +707,7 @@ if graph is None: raise SkipNode() # Write the graph. - image_url = '%s.gif' % graph.uid - image_file = os.path.join(self._directory, image_url) - self.body.append(graph.to_html(image_file, image_url)) + self.body.append(graph.to_html(self._directory) raise SkipNode() def visit_doctest_block(self, node): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 23:54:51
|
Revision: 1798 http://epydoc.svn.sourceforge.net/epydoc/?rev=1798&view=rev Author: edloper Date: 2008-02-26 15:54:44 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Changed the usage for to_html() and to_latex() methods -- they now accept a directory, rather than an image filename (and a url in the case of to_html). This is in preparation for adding an option to specify the image format for graphs in html output. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/dotgraph.py Modified: trunk/epydoc/src/epydoc/docwriter/dotgraph.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 23:37:17 UTC (rev 1797) +++ trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 23:54:44 UTC (rev 1798) @@ -93,6 +93,9 @@ """The default minimum size in inches (width,height) for graphs when rendering with `to_html()`""" + DEFAULT_HTML_IMAGE_FORMAT = 'gif' + """The default format used to generate images by `to_html()`""" + def __init__(self, title, body='', node_defaults=None, edge_defaults=None, caption=None): """ @@ -145,7 +148,7 @@ self.uid = '%s_%s' % (self.uid, n) self._uids.add(self.uid) - def to_latex(self, image_file, center=True, size=None): + def to_latex(self, directory, center=True, size=None): """ Return the LaTeX code that should be used to display this graph. Two image files will be written: image_file+'.eps' @@ -157,6 +160,8 @@ Defaults to `DEFAULT_LATEX_SIZE`. :type size: ``str`` """ + eps_file = os.path.join(directory, self.uid+'.eps') + pdf_file = os.path.join(directory, self.uid+'.pdf') size = size or self.DEFAULT_LATEX_SIZE # Use dot2tex if requested (and if it's available). # Otherwise, render it to an image file & use \includgraphics. @@ -170,21 +175,19 @@ # Render the graph in postscript. ps = self._run_dot('-Tps', size=size) # Write the postscript output. - psfile = open(image_file+'.eps', 'wb') + psfile = open(eps_file, 'wb') psfile.write('%!PS-Adobe-2.0 EPSF-1.2\n') psfile.write(ps) psfile.close() # Use ps2pdf to generate the pdf output. - try: run_subprocess(('ps2pdf', '-dEPSCrop', image_file+'.eps', - image_file+'.pdf')) + try: run_subprocess(('ps2pdf', '-dEPSCrop', eps_file, pdf_file)) except RunSubprocessError, e: log.warning("Unable to render Graphviz dot graph (%s):\n" "ps2pdf failed." % self.title) return None # Generate the latex code to display the graph. - name = os.path.splitext(os.path.split(image_file)[-1])[0] - s = ' \\includegraphics{%s}\n' % name + s = ' \\includegraphics{%s}\n' % self.uid if center: s = '\\begin{center}\n%s\\end{center}\n' % s return s @@ -206,8 +209,8 @@ s = conv.convert(s) if center: s = '\\begin{center}\n%s\\end{center}\n' % s return s - - def to_html(self, image_file, image_url, center=True, size=None): + + def to_html(self, directory, center=True, size=None): """ Return the HTML code that should be uesd to display this graph (including a client-side image map). @@ -220,6 +223,8 @@ Defaults to `DEFAULT_HTML_SIZE`. :type size: ``str`` """ + image_url = '%s.%s' % (self.uid, self.DEFAULT_HTML_IMAGE_FORMAT) + image_file = os.path.join(directory, image_url) size = size or self.DEFAULT_HTML_SIZE # If dotversion >1.8.10, then we can generate the image and # the cmapx with a single call to dot. Otherwise, we need to This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 23:37:27
|
Revision: 1797 http://epydoc.svn.sourceforge.net/epydoc/?rev=1797&view=rev Author: edloper Date: 2008-02-26 15:37:17 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - DotGraph's write() render() and html() methods now auto-select the output format (gif, png, etc) based on the filename. Default=gif. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/dotgraph.py Modified: trunk/epydoc/src/epydoc/docwriter/dotgraph.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 17:16:49 UTC (rev 1796) +++ trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 23:37:17 UTC (rev 1797) @@ -225,7 +225,8 @@ # the cmapx with a single call to dot. Otherwise, we need to # run dot twice. if get_dot_version() > [1,8,10]: - cmapx = self._run_dot('-Tgif', '-o%s' % image_file, + cmapx = self._run_dot('-T%s' % self._pick_language(image_file), + '-o%s' % image_file, '-Tcmapx', size=size) if cmapx is None: return '' # failed to render else: @@ -307,8 +308,8 @@ except NotImplementedError: url = '' if url: attribs['href'] = url else: del attribs['href'] - - def write(self, filename, language='gif', size=None): + + def write(self, filename, language=None, size=None): """ Render the graph using the output format `language`, and write the result to `filename`. @@ -320,6 +321,7 @@ If not specified, no size line will be added. :type size: ``str`` """ + if language is None: language = self._pick_language(filename) result = self._run_dot('-T%s' % language, '-o%s' % filename, size=size) @@ -328,7 +330,14 @@ result = result.decode('utf-8') return (result is not None) - def render(self, language='gif', size=None): + def _pick_language(self, filename): + ext = os.path.splitext(filename)[1] + if ext in ('.gif', '.png', '.jpg', '.jpeg'): + return ext[1:] + else: + return 'gif' + + def render(self, language=None, size=None): """ Use the ``dot`` command to render this graph, using the output format `language`. Return the result as a string, or ``None`` This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 17:16:50
|
Revision: 1796 http://epydoc.svn.sourceforge.net/epydoc/?rev=1796&view=rev Author: edloper Date: 2008-02-26 09:16:49 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Moved PYTHONPATH statement up Modified Paths: -------------- trunk/epydoc/Makefile Modified: trunk/epydoc/Makefile =================================================================== --- trunk/epydoc/Makefile 2008-02-26 17:13:33 UTC (rev 1795) +++ trunk/epydoc/Makefile 2008-02-26 17:16:49 UTC (rev 1796) @@ -19,6 +19,7 @@ # What version of python to use? PYTHON = python2.5 +export PYTHONPATH=src/ # The location of the webpage. HOST = shell.sf.net @@ -42,7 +43,6 @@ LATEX_STDLIB = $(LATEX)/stdlib.pdf EPYDOC = $(PYTHON) src/epydoc/cli.py -export PYTHONPATH=src/ RST2HTML = $(PYTHON) src/tools/rst2html.py MKDISPATCH = $(PYTHON) src/tools/mkdispatch.py This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 17:13:35
|
Revision: 1795 http://epydoc.svn.sourceforge.net/epydoc/?rev=1795&view=rev Author: edloper Date: 2008-02-26 09:13:33 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Updated description of \EpydocIndex command Modified Paths: -------------- trunk/epydoc/doc/epydoc-latex-demo.tex Modified: trunk/epydoc/doc/epydoc-latex-demo.tex =================================================================== --- trunk/epydoc/doc/epydoc-latex-demo.tex 2008-02-26 17:12:17 UTC (rev 1794) +++ trunk/epydoc/doc/epydoc-latex-demo.tex 2008-02-26 17:13:33 UTC (rev 1795) @@ -62,12 +62,25 @@ \subsection{Indexing} % The \EpydocIndex command is used to mark items that should be included -% in the index. It takes one optional argument, specifying the 'kind' -% of the object, and one required argument, the term that should be -% included in the index. (This command is used inside the \index -% command.) kind can be Package, Script, Module, Class, Class Method, -% Static Method, Method, Function, or Variable. -\index{\EpydocIndex[Script]{\EpydocDottedName{fooble}}} +% in the index. It takes three arguments. The first argument is the +% item's case-normalized name; this is typically discarded, and is +% simply used to ensure the proper (i.e., case-insensitive) sort order +% in the index. The second argument is the item's name; and the +% third item is the item's "kind". "kind" can be Package, Script, Module, +% Class, Class Method, Static Method, Method, Function, or Variable. +% This command is used inside of the \index{...} command. +% +% For modules and classes, the \index formatting strings "|(" and +% "|)" are appended to mark the beginning and end of the object's +% documentation. For methods, variables, and nested classes, the +% index formatting string "!" is used to create nested index entries. +% See the docs for the latex \index command for more information. +\index{\EpydocIndex{mymodule}{mymodule}{module}|(} +\index{\EpydocIndex{foo}{Foo}{class}|(} +\index{\EpydocIndex{foo}{Foo}{class}!\EpydocIndex{foo.f}{Foo.f}{method}} +\index{\EpydocIndex{foo}{Foo}{class}!\EpydocIndex{foo.f}{Foo.g}{method}} +\index{\EpydocIndex{foo}{Foo}{class}|)} +\index{\EpydocIndex{mymodule}{mymodule}{module}|)} \subsection{Source Code Syntax Highlighting} @@ -181,7 +194,7 @@ \subsection{Classes} \begin{EpydocClassList} \item[\EpydocHyperlink{my_module:Zip} - {\EpydocDottedName{my_module.Zipasdkfjsdflsd}}] + {\EpydocDottedName{my_module.Zip}}] Description of my\_module.Zip. \item[\EpydocHyperlink{my_module:Zap} {\EpydocDottedName{my_module.Zap}}] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 17:12:22
|
Revision: 1794 http://epydoc.svn.sourceforge.net/epydoc/?rev=1794&view=rev Author: edloper Date: 2008-02-26 09:12:17 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Changes to make graph colors user-customizable. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/dotgraph.py Modified: trunk/epydoc/src/epydoc/docwriter/dotgraph.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 17:11:38 UTC (rev 1793) +++ trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2008-02-26 17:12:17 UTC (rev 1794) @@ -33,15 +33,17 @@ #: so it should be left False for now. USE_DOT2TEX = False -# colors for graphs of APIDocs -MODULE_BG = '#d8e8ff' -CLASS_BG = '#d8ffe8' -SELECTED_BG = '#ffd0d0' -BASECLASS_BG = '#e0b0a0' -SUBCLASS_BG = '#e0b0a0' -UNDOCUMENTED_BG = '#c0c0c0' -ROUTINE_BG = '#e8d0b0' # maybe? -INH_LINK_COLOR = '#800000' +#: colors for graphs of APIDocs +COLOR = dict( + MODULE_BG = '#d8e8ff', + CLASS_BG = '#d8ffe8', + SELECTED_BG = '#ffd0d0', + BASECLASS_BG = '#e0b0a0', + SUBCLASS_BG = '#e0b0a0', + UNDOCUMENTED_BG = '#c0c0c0', + ROUTINE_BG = '#e8d0b0', # not used + INH_LINK = '#800000', + ) ###################################################################### #{ Dot Graphs @@ -500,7 +502,7 @@ - use qualifiers """ def __init__(self, class_doc, linker, context, collapsed=False, - bgcolor=CLASS_BG, **options): + bgcolor=COLOR['CLASS_BG'], **options): """ Create a new `DotGraphUmlClassNode` based on the class `class_doc`. @@ -1059,11 +1061,11 @@ _COLOR_DIFF = 24 def _color(self, package, depth): - if package == self.context: return SELECTED_BG + if package == self.context: return COLOR['SELECTED_BG'] else: # Parse the base color. - if re.match(MODULE_BG, 'r#[0-9a-fA-F]{6}$'): - base = int(MODULE_BG[1:], 16) + if re.match(COLOR['MODULE_BG'], 'r#[0-9a-fA-F]{6}$'): + base = int(COLOR['MODULE_BG'][1:], 16) else: base = int('d8e8ff', 16) red = (base & 0xff0000) >> 16 @@ -1354,11 +1356,11 @@ if nodetype == 'subclass': return DotGraphUmlClassNode( cls, linker, context, collapsed=True, - bgcolor=SUBCLASS_BG, **options) + bgcolor=COLOR['SUBCLASS_BG'], **options) elif nodetype in ('selected', 'superclass', 'undocumented'): - if nodetype == 'selected': bgcolor = SELECTED_BG - if nodetype == 'superclass': bgcolor = BASECLASS_BG - if nodetype == 'undocumented': bgcolor = UNDOCUMENTED_BG + if nodetype == 'selected': bgcolor = COLOR['SELECTED_BG'] + if nodetype == 'superclass': bgcolor = COLOR['BASECLASS_BG'] + if nodetype == 'undocumented': bgcolor = COLOR['UNDOCUMENTED_BG'] return DotGraphUmlClassNode( cls, linker, context, show_inherited_vars=False, collapsed=False, bgcolor=bgcolor, **options) @@ -1369,12 +1371,12 @@ if edgetype == 'subclass': return DotGraphEdge( start, end, dir='back', arrowtail='empty', - headport='body', tailport='body', color=INH_LINK_COLOR, + headport='body', tailport='body', color=COLOR['INH_LINK'], weight=100, style='bold') if edgetype == 'truncate-subclass': return DotGraphEdge( start, end, dir='back', arrowtail='empty', - tailport='body', color=INH_LINK_COLOR, + tailport='body', color=COLOR['INH_LINK'], weight=100, style='bold') assert 0, 'bad edgetype' @@ -1550,13 +1552,13 @@ if (url is None and hasattr(linker, 'docindex') and linker.docindex.find(identifier, self.container) is None): - node['fillcolor'] = UNDOCUMENTED_BG + node['fillcolor'] = COLOR['UNDOCUMENTED_BG'] node['style'] = 'filled' if isinstance(val_doc, ModuleDoc) and dot_version >= [2]: node['shape'] = 'plaintext' - if val_doc == context: color = SELECTED_BG - else: color = MODULE_BG + if val_doc == context: color = COLOR['SELECTED_BG'] + else: color = COLOR['MODULE_BG'] node['tooltip'] = node['label'] node['html_label'] = MODULE_NODE_HTML % (color, color, url, val_doc.canonical_name, @@ -1572,7 +1574,7 @@ node['label'] = '%s()' % node['label'] node['tooltip'] = node['label'] if val_doc == context: - node['fillcolor'] = SELECTED_BG + node['fillcolor'] = COLOR['SELECTED_BG'] node['style'] = 'filled,rounded,bold' else: @@ -1581,7 +1583,7 @@ node['height'] = 0 node['tooltip'] = node['label'] if val_doc == context: - node['fillcolor'] = SELECTED_BG + node['fillcolor'] = COLOR['SELECTED_BG'] node['style'] = 'filled,bold' def name_list(api_docs, context=None): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 17:11:41
|
Revision: 1793 http://epydoc.svn.sourceforge.net/epydoc/?rev=1793&view=rev Author: edloper Date: 2008-02-26 09:11:38 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Use the xkeyval package to add two new keyword options to the epydoc sty file (title and creator), which are used to set the hyperref options pdftitle and pdfcreator. - Use conditional test to decide whether the dvips or pdftex option should be pased to the hyperref package. The generated latex output no longer hard-codes information about the driver (so the same latex output can be used by both latex and pdflatex). - The preamble in the generated api.tex now *just* uses the selected epydoc sty package. (the \uepackage statements for the hyperref and graphicx packages were changed to \RequirePackage statements in epydoc-base.sty.) - Fixed bug where nested classes were not being documented. - Fixed several bugs with index generation - Fixed \ProvidesClass statements in epydoc-*.sty files Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex.py trunk/epydoc/src/epydoc/docwriter/latex_sty.py Modified: trunk/epydoc/src/epydoc/docwriter/latex.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-26 03:13:30 UTC (rev 1792) +++ trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-26 17:11:38 UTC (rev 1793) @@ -31,7 +31,6 @@ PREAMBLE = [ "\\documentclass{article}", "\\usepackage[%s]{%s}", - "\\usepackage{graphicx}", ] SECTIONS = ['\\part{%s}', '\\chapter{%s}', '\\section{%s}', @@ -55,7 +54,6 @@ self._exclude = kwargs.get('exclude', 1) self._list_submodules = kwargs.get('list_submodules', 1) self._sty = kwargs.get('sty') - self._pdfdriver = kwargs.get('pdfdriver', 'latex') self._top_section = 2 self._index_functions = 1 self._hyperref = 1 @@ -270,6 +268,8 @@ def write_preamble(self, out): # If we're generating an index, add it to the preamble. options = [] + options.append('creator={epydoc %s}' % epydoc.__version__) + options.append('title={%s}' % plaintext_to_latex(self._prj_name or '')) if self._index: options.append('index') if self._hyperlink: options.append('hyperlink') out('\n'.join(self.PREAMBLE) % (','.join(options), @@ -283,21 +283,6 @@ if self._hyperref: out('\\definecolor{UrlColor}{rgb}{0,0.08,0.45}\n') - if self._pdfdriver == 'pdflatex': - driver = 'pdftex' - elif self._pdfdriver == 'latex': - driver = 'dvips' - else: - raise ValueError('bad pdfdriver: %s' % self._pdfdriver) - - out('\\usepackage[%s, pagebackref, pdftitle={%s}, ' - 'pdfcreator={epydoc %s}, bookmarks=true, ' - 'bookmarksopen=false, pdfpagemode=UseOutlines, ' - 'colorlinks=true, linkcolor=black, anchorcolor=black, ' - 'citecolor=black, filecolor=black, menucolor=black, ' - 'pagecolor=black, urlcolor=UrlColor]{hyperref}\n' % - (driver, self._prj_name or '', epydoc.__version__)) - # If restructuredtext was used, then we need to extend # the prefix to include LatexTranslator.head_prefix. if 'restructuredtext' in epydoc.markup.MARKUP_LANGUAGES_USED: @@ -370,7 +355,9 @@ image_file = os.path.join(self._directory, image_url) return graph.to_latex(image_file) or '' - def write_class(self, out, doc): + def write_class(self, out, doc, short_name=None): + if short_name is None: short_name = doc.canonical_name[-1] + if self._list_classes_separately: self.write_header(out, doc) self.write_start_of(out, 'Class Description') @@ -387,7 +374,7 @@ else: seclevel = 1 out(self.section('%s %s' % (self.doc_kind(doc), - _dotted(doc.canonical_name[-1])), + _dotted(short_name)), seclevel, ref=doc)) if ((doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0) or @@ -439,6 +426,18 @@ # Mark the end of the class (for the index) out(' ' + self.indexterm(doc, 'end')) + # Write any nested classes. These will have their own + # section (at the same level as this section) + for nested_class in doc.select_variables(imported=False, + value_type='class', + public=self._public_filter): + if (nested_class.value.canonical_name != UNKNOWN and + (nested_class.value.canonical_name[:-1] == + doc.canonical_name)): + self.write_class(out, nested_class.value, + DottedName(short_name, + nested_class.canonical_name[-1])) + #//////////////////////////////////////////////////////////// #{ Module hierarchy trees #//////////////////////////////////////////////////////////// @@ -1058,6 +1057,9 @@ else: return 'Variable' + # [xx] list modules, classes, and functions as top-level index + # items. Methods are listed under their classes. Nested classes + # are listed under their classes. def indexterm(self, doc, pos='only'): """Mark a term or section for inclusion in the index.""" if not self._index: return '' @@ -1065,39 +1067,30 @@ return '' pieces = [] - - if isinstance(doc, ClassDoc): - classCrossRef = '\\index{\\EpydocIndex[%s]{%s}|see{%%s}}\n' \ - % (self.doc_kind(doc).lower(), - _dotted('%s' % doc.canonical_name)) - else: - classCrossRef = None - - while isinstance(doc, ClassDoc) or isinstance(doc, RoutineDoc): - if doc.canonical_name == UNKNOWN: - return '' # Give up. - pieces.append('\\EpydocIndex[%s]{%s}' % - (self.doc_kind(doc).lower(), - _dotted('%s' % doc.canonical_name))) + kinds = [] + while True: + if doc.canonical_name in (None, UNKNOWN): return '' # Give up. + pieces.append(doc.canonical_name[-1]) + kinds.append(self.doc_kind(doc).lower()) doc = self.docindex.container(doc) - if doc == UNKNOWN: - return '' # Give up. + if isinstance(doc, ModuleDoc): break + if doc is None: break + if doc == UNKNOWN: return '' # give up. pieces.reverse() - if pos == 'only': - term = '\\index{%s}\n' % '!'.join(pieces) - elif pos == 'start': - term = '\\index{%s|(}\n' % '!'.join(pieces) - elif pos == 'end': - term = '\\index{%s|)}\n' % '!'.join(pieces) - else: - raise AssertionError('Bad index position %s' % pos) + kinds.reverse() + for i in range(1, len(pieces)): + pieces[i] = '%s.%s' % (pieces[i-1], pieces[i]) + pieces = ['\\EpydocIndex{%s}{%s}{%s}' % (piece.lower(), piece, kind) + for (piece, kind) in zip (pieces, kinds)] + + if pos == 'only': modifier = '' + elif pos == 'start': modifier = '|(' + elif pos == 'end': modifier = '|)' + else: raise AssertionError('Bad index position %s' % pos) + + term = '\\index{%s%s}\n' % ('!'.join(pieces), modifier) - if pos in ['only', 'start'] and classCrossRef is not None: - term += classCrossRef % ('\\EpydocIndex[%s]{%s}' % - (self.doc_kind(doc).lower(), - _dotted('%s'%doc.canonical_name))) - return term #: Map the Python encoding representation into mismatching LaTeX ones. Modified: trunk/epydoc/src/epydoc/docwriter/latex_sty.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-26 03:13:30 UTC (rev 1792) +++ trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-26 17:11:38 UTC (rev 1793) @@ -41,30 +41,41 @@ % $Id:$ \NeedsTeXFormat{LaTeX2e}% -\ProvidesClass{epydoc}[2007/04/06 v3.0beta1 Epydoc Python Documentation] +\ProvidesClass{epydoc-base}[2008/02/26 v3.0.1 Epydoc Python Documentation] % ====================================================================== -% Basic Package Requirements +% Options -\RequirePackage{alltt, boxedminipage} -\RequirePackage{multirow, amssymb} -\RequirePackage[headings]{fullpage} -\RequirePackage[usenames]{color} +% These two packages are used to process options: \RequirePackage{ifthen} +\RequirePackage{xkeyval} -% ====================================================================== -% Options - +% Define an option 'index' that sets the boolean value \@doIndex \newif\if@doIndex \@doIndexfalse -\DeclareOption{index}{\@doIndextrue} +\DeclareOptionX{index}{\@doIndextrue} +% Define an option 'hyperlink' that sets the boolean value \@docHyperlink \newif\if@doHyperlink \@doHyperlinkfalse -\DeclareOption{hyperlink}{\@doHyperlinktrue} +\DeclareOptionX{hyperlink}{\@doHyperlinktrue} -\ProcessOptions\relax +% Pass the 'title' & 'creator' options to the hyperref package. +\DeclareOptionX{title}[]{\PassOptionsToPackage{pdftitle={#1}}{hyperref}} +\DeclareOptionX{creator}[]{\PassOptionsToPackage{pdfcreator={#1}}{hyperref}} +% Process the options list. +\ProcessOptionsX\relax + +% ====================================================================== +% Package Requirements + +\RequirePackage{alltt, boxedminipage} +\RequirePackage{multirow, amssymb} +\RequirePackage[headings]{fullpage} +\RequirePackage[usenames]{color} +\RequirePackage{graphicx} + \@ifclassloaded{memoir}{% \RequirePackage[other,notbib]{tocbibind} }{% @@ -81,6 +92,17 @@ \makeindex \fi +\ifx\pdfoutput\undefined\newcommand{\driver}{dvips} +\else\ifnum\pdfoutput=1\newcommand{\driver}{pdftex} +\else\newcommand{\driver}{dvips}\fi\fi + +\RequirePackage[\driver, pagebackref, + bookmarks=true, bookmarksopen=false, pdfpagemode=UseOutlines, + colorlinks=true, linkcolor=black, anchorcolor=black, citecolor=black, + filecolor=black, menucolor=black, pagecolor=black, urlcolor=UrlColor] + {hyperref} + + % ====================================================================== % General Formatting @@ -150,14 +172,16 @@ % Index Terms % The \EpydocIndex command is used to mark items that should be included -% in the index. It takes one optional argument, specifying the 'kind' -% of the object, and one required argument, the term that should be -% included in the index. (This command is used inside the \index -% command.) kind can be Package, Script, Module, Class, Class Method, -% Static Method, Method, Function, or Variable. -\newcommand{\EpydocIndex}[2][]{% +% in the index. It takes three arguments. The first argument is the +% item's case-normalized name; this is typically discarded, and is +% simply used to ensure the proper (i.e., case-insensitive) sort order +% in the index. The second argument is the item's name; and the +% third item is the item's "kind". "kind" can be Package, Script, Module, +% Class, Class Method, Static Method, Method, Function, or Variable. +% This command is used inside of the \index{...} command. +\newcommand{\EpydocIndex}[3]{% #2 % - \ifthenelse{\equal{#1}{}}{}{\textit{(\MakeLowercase{#1})}}} + \ifthenelse{\equal{#3}{}}{}{\textit{(#3)}}} % ====================================================================== % Descriptions (docstring contents) @@ -582,11 +606,15 @@ % % $Id:$ \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{epydoc}[2007/04/06 v3.0beta1 Epydoc Python Documentation] -\DeclareOption{index}{\PassOptionsToPackage{index}{epydoc-base}} -\DeclareOption{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} -\ProcessOptions\relax +\ProvidesClass{epydoc-boxes}[2008/02/26 v3.0.1 Epydoc Python Documentation] +\RequirePackage{xkeyval} +\DeclareOptionX{index}{\PassOptionsToPackage{index}{epydoc-base}} +\DeclareOptionX{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} +\DeclareOptionX{title}[]{\PassOptionsToPackage{title={#1}}{epydoc-base}} +\DeclareOptionX{creator}[]{\PassOptionsToPackage{creator={#1}}{epydoc-base}} +\ProcessOptionsX\relax + \RequirePackage{epydoc-base} \RequirePackage{longtable} @@ -810,11 +838,15 @@ % % $Id:$ \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{epydoc}[2007/04/06 v3.0beta1 Epydoc Python Documentation] -\DeclareOption{index}{\PassOptionsToPackage{index}{epydoc-base}} -\DeclareOption{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} -\ProcessOptions\relax +\ProvidesClass{epydoc-shaded}[2008/02/26 v3.0.1 Epydoc Python Documentation] +\RequirePackage{xkeyval} +\DeclareOptionX{index}{\PassOptionsToPackage{index}{epydoc-base}} +\DeclareOptionX{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} +\DeclareOptionX{title}[]{\PassOptionsToPackage{title={#1}}{epydoc-base}} +\DeclareOptionX{creator}[]{\PassOptionsToPackage{creator={#1}}{epydoc-base}} +\ProcessOptionsX\relax + \RequirePackage{epydoc-base} \definecolor{gray95}{gray}{0.95} @@ -1032,11 +1064,18 @@ % how different pieces of the documentation are displayed. % \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{epydoc}[2007/04/06 v3.0beta1 Epydoc Python Documentation] -\DeclareOption{index}{\PassOptionsToPackage{index}{epydoc-base}} -\DeclareOption{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} -\ProcessOptions\relax +% Replace 'XXX' with a new name: +\ProvidesClass{epydoc-XXX}[2008/02/26 v3.0.1 Epydoc Python Documentation] + +% Pass options to the epydoc base package. +\RequirePackage{xkeyval} +\DeclareOptionX{index}{\PassOptionsToPackage{index}{epydoc-base}} +\DeclareOptionX{hyperlink}{\PassOptionsToPackage{hyperlink}{epydoc-base}} +\DeclareOptionX{title}[]{\PassOptionsToPackage{title={#1}}{epydoc-base}} +\DeclareOptionX{creator}[]{\PassOptionsToPackage{creator={#1}}{epydoc-base}} +\ProcessOptionsX\relax + \RequirePackage{epydoc-base} % Add \renewcommand and \renewenvironment commands here. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 03:13:32
|
Revision: 1792 http://epydoc.svn.sourceforge.net/epydoc/?rev=1792&view=rev Author: edloper Date: 2008-02-25 19:13:30 -0800 (Mon, 25 Feb 2008) Log Message: ----------- - Allow dotgraph colors to be customized via config files. Modified Paths: -------------- trunk/epydoc/src/epydoc/cli.py Modified: trunk/epydoc/src/epydoc/cli.py =================================================================== --- trunk/epydoc/src/epydoc/cli.py 2008-02-26 02:52:04 UTC (rev 1791) +++ trunk/epydoc/src/epydoc/cli.py 2008-02-26 03:13:30 UTC (rev 1792) @@ -77,6 +77,7 @@ from epydoc.docwriter.html_css import STYLESHEETS as CSS_STYLESHEETS from epydoc.docwriter.latex_sty import STYLESHEETS as STY_STYLESHEETS from epydoc.docwriter.dotgraph import DotGraph +from epydoc.docwriter.dotgraph import COLOR as GRAPH_COLOR # This module is only available if Docutils are in the system try: @@ -714,6 +715,16 @@ options.max_html_graph_size = val elif optname in ('max-latex-graph-size', 'max_latex_graph_size'): options.max_latex_graph_size = val + elif optname.startswith('graph-'): + color = optname[6:].upper().strip() + color = color.replace('-', '_') + color = color.replace('_BACKGROUND', '_BG') + if color in GRAPH_COLOR: + if not re.match(r'#[a-fA-F0-9]+|\w+', val): + raise ValueError('Bad color %r for %r' % (val, color)) + GRAPH_COLOR[color] = val + else: + raise ValueError('Unknown option %s' % optname) # Return value options elif optname in ('failon', 'fail-on', 'fail_on'): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-26 02:52:05
|
Revision: 1791 http://epydoc.svn.sourceforge.net/epydoc/?rev=1791&view=rev Author: edloper Date: 2008-02-25 18:52:04 -0800 (Mon, 25 Feb 2008) Log Message: ----------- - Fixed bug in selecting pdfdriver when pdfdriver=auto. Modified Paths: -------------- trunk/epydoc/src/epydoc/cli.py Modified: trunk/epydoc/src/epydoc/cli.py =================================================================== --- trunk/epydoc/src/epydoc/cli.py 2008-02-25 00:37:58 UTC (rev 1790) +++ trunk/epydoc/src/epydoc/cli.py 2008-02-26 02:52:04 UTC (rev 1791) @@ -1009,7 +1009,10 @@ log.start_progress('Writing LaTeX docs') # Choose a pdfdriver if we're generating pdf output. - if 'pdf' in options.actions and options.pdfdriver=='auto': + if options.pdfdriver=='auto' and ('latex' in options.actions or + 'dvi' in options.actions or + 'ps' in options.actions or + 'pdf' in options.actions): if 'dvi' in options.actions or 'ps' in options.actions: options.pdfdriver = 'latex' else: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-25 00:38:00
|
Revision: 1790 http://epydoc.svn.sourceforge.net/epydoc/?rev=1790&view=rev Author: edloper Date: 2008-02-24 16:37:58 -0800 (Sun, 24 Feb 2008) Log Message: ----------- - When wrapping function signatures, align the wrapped args with the function's open paren. Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex_sty.py Modified: trunk/epydoc/src/epydoc/docwriter/latex_sty.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-25 00:09:24 UTC (rev 1789) +++ trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-25 00:37:58 UTC (rev 1790) @@ -357,8 +357,8 @@ \newcommand{\Param}[2][]{% \textit{##2}% \ifthenelse{\equal{##1}{}}{}{=\texttt{##1}}}% - \textbf{#1}(% - }{)} + \@hangfrom{\textbf{#1}(}% + }{)\par} % The EpydocFunctionParameters environment is used to display % descriptions for the parameters that a function can take. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-25 00:09:27
|
Revision: 1789 http://epydoc.svn.sourceforge.net/epydoc/?rev=1789&view=rev Author: edloper Date: 2008-02-24 16:09:24 -0800 (Sun, 24 Feb 2008) Log Message: ----------- - Added \raggedright to function signatures in shaded style Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex_sty.py Modified: trunk/epydoc/src/epydoc/docwriter/latex_sty.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-24 20:04:18 UTC (rev 1788) +++ trunk/epydoc/src/epydoc/docwriter/latex_sty.py 2008-02-25 00:09:24 UTC (rev 1789) @@ -309,7 +309,7 @@ \gdef\@EpydocFunctionRaises{##6}% \gdef\@EpydocFunctionOverrides{##7}% \gdef\@EpydocFunctionMetadata{##8}% - {\Large\raggedright\@EpydocFunctionSignature}\par + {\Large\raggedright\@EpydocFunctionSignature\par} \begin{quote}% \setlength{\parskip}{\EpydocParskip}% \ifx\@EpydocFunctionDescription\empty\else @@ -421,7 +421,7 @@ \gdef\@EpydocVariableDescription{##2}% \gdef\@EpydocVariableType{##3}% \gdef\@EpydocVariableValue{##4}% - {\Large\raggedright\@EpydocVariableName}\par + {\Large\raggedright\@EpydocVariableName\par} \begin{quote} \setlength{\parskip}{\EpydocParskip}% \ifx\@EpydocVariableDescription\empty\else @@ -470,7 +470,7 @@ \gdef\@EpydocPropertyGet{##4}% \gdef\@EpydocPropertySet{##5}% \gdef\@EpydocPropertyDel{##6}% - {\Large\raggedright\@EpydocPropertyName}\par + {\Large\raggedright\@EpydocPropertyName\par} \begin{quote} \setlength{\parskip}{\EpydocParskip}% \ifx\@EpydocPropertyDescription\empty\else @@ -621,8 +621,8 @@ \gdef\@EpydocFunctionOverrides{##7}% \gdef\@EpydocFunctionMetadata{##8}% \begin{boxedminipage}{\dimexpr \textwidth-2\fboxsep \relax} - {\Large \@EpydocFunctionSignature} - \setlength{\parskip}{\EpydocParskip}\par + {\Large\raggedright\@EpydocFunctionSignature\par} + \setlength{\parskip}{\EpydocParskip} \ifx\@EpydocFunctionDescription\empty\else% {\@EpydocSeparator}% \@EpydocFunctionDescription % @@ -661,9 +661,7 @@ {\@EpydocSeparator}% \@EpydocFunctionMetadata % \fi% - \end{boxedminipage} - - }} + \end{boxedminipage}\par}} {} % ====================================================================== @@ -717,7 +715,7 @@ \gdef\@EpydocVariableDescription{##2}% \gdef\@EpydocVariableType{##3}% \gdef\@EpydocVariableValue{##4}% - \raggedright \@EpydocVariableName & % + \raggedright\@EpydocVariableName & % \setlength{\parskip}{\EpydocParskip}\raggedright% \@EpydocVariableDescription % \ifx\@EpydocVariableValue\empty\relax% @@ -758,7 +756,7 @@ \gdef\@EpydocPropertyGet{##4}% \gdef\@EpydocPropertySet{##5}% \gdef\@EpydocPropertyDel{##6}% - \raggedright \@EpydocPropertyName & % + \raggedright\@EpydocPropertyName & % \setlength{\parskip}{\EpydocParskip}\raggedright% \ifx\@EpydocPropertyDescription\empty\else% {\@EpydocSeparator}% @@ -861,7 +859,7 @@ \begin{minipage}{\textwidth}% \raggedleft% \begin{cminipage}[gray95]{\dimexpr \textwidth-2\fboxsep \relax} - {\Large \@EpydocFunctionSignature} + \Large\raggedright\@EpydocFunctionSignature \end{cminipage}% \if@EpydocFunctionDetails \begin{cminipage}{\dimexpr 0.95\linewidth-2\fboxsep \relax}% This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2008-02-24 20:04:21
|
Revision: 1788 http://epydoc.svn.sourceforge.net/epydoc/?rev=1788&view=rev Author: edloper Date: 2008-02-24 12:04:18 -0800 (Sun, 24 Feb 2008) Log Message: ----------- - Pass context to ParsedDocstring.to_latex() Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/latex.py Modified: trunk/epydoc/src/epydoc/docwriter/latex.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-24 19:43:45 UTC (rev 1787) +++ trunk/epydoc/src/epydoc/docwriter/latex.py 2008-02-24 20:04:18 UTC (rev 1788) @@ -996,6 +996,7 @@ s = docstring.to_latex(self._docstring_linker, indent=indent, directory=self._directory, docindex=self.docindex, + context=where, hyperref=self._hyperref) return (' '*indent + '\\begin{EpydocDescription}%\n' + s.strip() + '%\n' + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |