Thread: [Epydoc-commits] SF.net SVN: epydoc: [1210] trunk/epydoc/src/epydoc/markup
Brought to you by:
edloper
From: <ed...@us...> - 2006-04-10 13:25:55
|
Revision: 1210 Author: edloper Date: 2006-04-10 06:25:50 -0700 (Mon, 10 Apr 2006) ViewCVS: http://svn.sourceforge.net/epydoc/?rev=1210&view=rev Log Message: ----------- - DotGraph.to_html() now takes an extra argument, the image filename, and is responsible for writing the image file. This lets me use a single call to dot generate both the image and the client image map when dotversion>1.8.10 Modified Paths: -------------- trunk/epydoc/src/epydoc/docwriter/dotgraph.py trunk/epydoc/src/epydoc/docwriter/html.py trunk/epydoc/src/epydoc/markup/epytext.py trunk/epydoc/src/epydoc/markup/restructuredtext.py Modified: trunk/epydoc/src/epydoc/docwriter/dotgraph.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2006-04-10 13:23:24 UTC (rev 1209) +++ trunk/epydoc/src/epydoc/docwriter/dotgraph.py 2006-04-10 13:25:50 UTC (rev 1210) @@ -128,7 +128,7 @@ self.uid = '%s_%s' % (self.uid, n) self._uids.add(self.uid) - def to_html(self, image_url, center=True): + def to_html(self, image_file, image_url, center=True): """ Return the HTML code that should be uesd to display this graph (including a client-side image map). @@ -136,7 +136,17 @@ :param image_url: The URL of the image file for this graph; this should be generated separately with the `write()` method. """ - cmapx = self.render('cmapx') or '' + # If dotversion >1.8.10, then we can generate the image and + # 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, '-Tcmapx') + if cmapx is None: return '' # failed to render + else: + if not self.write(image_file): + return '' # failed to render + cmapx = self.render('cmapx') or '' + title = plaintext_to_html(self.title or '') caption = plaintext_to_html(self.caption or '') if title or caption: @@ -209,14 +219,12 @@ :return: True if rendering was successful. """ - s = self.render(language) - if s is not None: - out = open(filename, 'wb') - out.write(s) - out.close() - return True - else: - return False + result = self._run_dot('-T%s' % language, + '-o%s' % filename) + # Decode into unicode, if necessary. + if language == 'cmapx' and result is not None: + result = result.decode('utf-8') + return (result is not None) def render(self, language='gif'): """ @@ -224,14 +232,13 @@ format `language`. Return the result as a string, or `None` if the rendering failed. """ + return self._run_dot('-T%s' % language) + + def _run_dot(self, *options): try: - result, err = run_subprocess([DOT_COMMAND, '-T%s' % language], + result, err = run_subprocess((DOT_COMMAND,)+options, self.to_dotfile()) - # Decode into unicode, if necessary. - if language == 'cmapx' and result is not None: - result = result.decode('utf-8') - if err: - log.warning("Graphviz dot warning(s):\n%s" % err) + if err: log.warning("Graphviz dot warning(s):\n%s" % err) except OSError, e: log.warning("Unable to render Graphviz dot graph:\n%s" % e) #log.debug(self.to_dotfile()) Modified: trunk/epydoc/src/epydoc/docwriter/html.py =================================================================== --- trunk/epydoc/src/epydoc/docwriter/html.py 2006-04-10 13:23:24 UTC (rev 1209) +++ trunk/epydoc/src/epydoc/docwriter/html.py 2006-04-10 13:25:50 UTC (rev 1210) @@ -1334,18 +1334,13 @@ #{ 2.10. Graphs #//////////////////////////////////////////////////////////// + # [xx] use DotGraph.to_html?? def render_graph(self, graph, css='graph-without-title'): if graph is None: return '' - # Write the graph's image to a file - path = os.path.join(self._directory, graph.uid) - if not graph.write('%s.gif' % path, 'gif'): - return '' - # Generate the image map. - cmapx = graph.render('cmapx') or '' - # Display the graph. - uid = graph.uid - return ('%s\n<img src="%s.gif" alt="%s" usemap="#%s" ismap="ismap" ' - 'class="%s"/>\n' % (cmapx, uid, uid, uid, css)) + 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) def render_callgraph(self, callgraph): graph_html = self.render_graph(callgraph, css='graph-with-title') Modified: trunk/epydoc/src/epydoc/markup/epytext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/epytext.py 2006-04-10 13:23:24 UTC (rev 1209) +++ trunk/epydoc/src/epydoc/markup/epytext.py 2006-04-10 13:25:50 UTC (rev 1210) @@ -1831,14 +1831,14 @@ else: return '[??]' elif tree.tagName == 'graph': + # Generate the graph. graph = self._build_graph(variables[0], variables[1:], linker, docindex, context) if not graph: return '' - # Write the graph's image to a file - path = os.path.join(directory, graph.uid) - if not graph.write('%s.gif' % path, 'gif'): - return '' - return graph.to_html('%s.gif' % graph.uid) + # 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) else: raise ValueError('Unknown epytext DOM element %r' % tree.tagName) Modified: trunk/epydoc/src/epydoc/markup/restructuredtext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/restructuredtext.py 2006-04-10 13:23:24 UTC (rev 1209) +++ trunk/epydoc/src/epydoc/markup/restructuredtext.py 2006-04-10 13:25:50 UTC (rev 1210) @@ -533,11 +533,11 @@ # Generate the graph. graph = node.graph(self._docindex, self._context, self._linker) if graph is None: return - # Write the graph's image to a file - path = os.path.join(self._directory, graph.uid) - if not graph.write('%s.gif' % path, 'gif'): - return - self.body.append(graph.to_html('%s.gif' % graph.uid)) + + # 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)) def depart_dotgraph(self, node): pass # Nothing to do. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2006-04-19 00:30:46
|
Revision: 1231 Author: edloper Date: 2006-04-18 17:30:37 -0700 (Tue, 18 Apr 2006) ViewCVS: http://svn.sourceforge.net/epydoc/?rev=1231&view=rev Log Message: ----------- - Doctest colorization moved to epydoc.markup.doctest - Do doctest colorization for rst - Fixed the overridden starttag method for rendering rst as html Modified Paths: -------------- trunk/epydoc/src/epydoc/markup/epytext.py trunk/epydoc/src/epydoc/markup/restructuredtext.py Added Paths: ----------- trunk/epydoc/src/epydoc/markup/doctest.py Added: trunk/epydoc/src/epydoc/markup/doctest.py =================================================================== --- trunk/epydoc/src/epydoc/markup/doctest.py (rev 0) +++ trunk/epydoc/src/epydoc/markup/doctest.py 2006-04-19 00:30:37 UTC (rev 1231) @@ -0,0 +1,151 @@ +# +# doctest.py: Syntax Highlighting for doctest blocks +# Edward Loper +# +# Created [06/28/03 02:52 AM] +# $Id: restructuredtext.py 1210 2006-04-10 13:25:50Z edloper $ +# + +""" +Syntax highlighting for doctest blocks. This module defines two +functions, L{doctest_to_html()} and L{doctest_to_latex()}, which can +be used to perform syntax highlighting on doctest blocks. It also +defines the more general L{colorize_doctest()}, which could be used to +do syntac highlighting on doctest blocks with other output formats. +(Both C{doctest_to_html()} and C{doctest_to_latex()} are defined using +C{colorize_doctest()}.) +""" + +import re +from epydoc.util import plaintext_to_html, plaintext_to_latex + +def doctest_to_html(s): + """ + Perform syntax highlighting on the given doctest string, and + return the resulting HTML code. This code consists of a C{<pre>} + block with class=py-doctest. Syntax highlighting is performed + using the following css classes: 'py-prompt', 'py-keyword', + 'py-string', 'py-comment', and 'py-output'. + """ + return ('<pre class="py-doctest">\n%s\n</pre>\n' % + colorize_doctest(s, _tag_span_html).strip()) + +def doctest_to_latex(s): + """ + Perform syntax highlighting on the given doctest string, and + return the resulting LaTeX code. This code consists of an + C{alltt} environment. Syntax highlighting is performed using five + new latex commands, which must be defined externally: + '\pysrcprompt', '\pysrckeyword', '\pysrcstring', '\pysrccomment', + and '\pysrcoutput'. + """ + return ('\\begin{alltt}\n%s\n\\end{alltt}\n' % + colorize_doctest(s, _tag_span_latex).strip()) + +def _tag_span_html(s, tag): + return '<span class="py-%s">%s</span>' % (tag, plaintext_to_html(s)) + +def _tag_span_latex(s, tag): + return '\\pysrc%s{%s}' % (tag, plaintext_to_latex(s)) + +# Regular expressions for colorize_doctestblock +_KEYWORDS = ["del", "from", "lambda", "return", "and", "or", "is", + "global", "not", "try", "break", "else", "if", "elif", + "while", "class", "except", "import", "pass", "raise", + "continue", "finally", "in", "print", "def", "for"] +_KEYWORD = '|'.join([r'(\b%s\b)' % _KW for _KW in _KEYWORDS]) +_STRING = (r""" +[uU]?[rR]? + (?: # Single-quote (') strings + '''(?: # Tripple-quoted can contain... + [^'] | # a non-quote + \\' | # a backslashed quote + '{1,2}(?!') # one or two quotes + )*''' | + '(?: # Non-tripple quoted can contain... + [^'] | # a non-quote + \\' # a backslashded quote + )*'(?!') | """+ +r''' # Double-quote (") strings + """(?: # Tripple-quoted can contain... + [^"] | # a non-quote + \\" | # a backslashed single + "{1,2}(?!") # one or two quotes + )*""" | + "(?: # Non-tripple quoted can contain... + [^"] | # a non-quote + \\" # a backslashded quote + )*"(?!") +)''') +_COMMENT = '(#.*?$)' +_PROMPT = r'^\s*(?:>>>|\.\.\.)(?:\s|$)' + +PROMPT_RE = re.compile('(%s)' % _PROMPT, re.MULTILINE | re.DOTALL) +'''The regular expression used to find Python prompts (">>>" and +"...") in doctest blocks.''' + +DOCTEST_RE = re.compile( + '(?P<STRING>%s)|(?P<COMMENT>%s)|(?P<KEYWORD>%s)|(?P<PROMPT>%s)|.+?' % + (_STRING, _COMMENT, _KEYWORD, _PROMPT), re.MULTILINE | re.DOTALL) +'''The regular expression used by L{_doctest_sub} to colorize doctest +blocks.''' + +def colorize_doctest(s, markup_func): + """ + Colorize the given doctest string C{s} using C{markup_func()}. + C{markup_func()} should be a function that takes a substring and a + tag, and returns a colorized version of the substring. E.g.: + + >>> def html_markup_func(s, tag): + ... return '<span class="%s">%s</span>' % (tag, s) + + The tags that will be passed to the markup function are: + - C{prompt} -- a Python prompt (>>> or ...) + - C{keyword} -- a Python keyword (for, if, etc.) + - C{string} -- a string literal + - C{comment} -- a comment + - C{output} -- the output from a doctest block. + - C{other} -- anything else (does *not* include output.) + """ + pysrc = [] # the source code part of a docstest block (lines) + pyout = [] # the output part of a doctest block (lines) + result = [] + out = result.append + + def subfunc(match): + if match.group('PROMPT'): + return markup_func(match.group(), 'prompt') + if match.group('KEYWORD'): + return markup_func(match.group(), 'keyword') + if match.group('COMMENT'): + return markup_func(match.group(), 'comment') + if match.group('STRING') and '\n' not in match.group(): + return markup_func(match.group(), 'string') + elif match.group('STRING'): + # It's a multiline string; colorize the string & prompt + # portion of each line. + pieces = [markup_func(s, ['string','prompt'][i%2]) + for i, s in enumerate(PROMPT_RE.split(match.group()))] + return ''.join(pieces) + else: + return markup_func(match.group(), 'other') + + for line in s.split('\n')+['\n']: + if PROMPT_RE.match(line): + pysrc.append(line) + if pyout: + result.append(markup_func('\n'.join(pyout).strip(), 'output')) + pyout = [] + else: + pyout.append(line) + if pysrc: + pysrc = DOCTEST_RE.sub(subfunc, '\n'.join(pysrc)) + result.append(pysrc.strip()) + #result.append(markup_func(pysrc.strip(), 'python')) + pysrc = [] + + remainder = '\n'.join(pyout).strip() + if remainder: + result.append(markup_func(remainder, 'output')) + + return '\n'.join(result) Modified: trunk/epydoc/src/epydoc/markup/epytext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/epytext.py 2006-04-13 07:24:22 UTC (rev 1230) +++ trunk/epydoc/src/epydoc/markup/epytext.py 2006-04-19 00:30:37 UTC (rev 1231) @@ -109,7 +109,7 @@ import xml.dom.minidom from epydoc.markup import * from epydoc.util import wordwrap, plaintext_to_html, plaintext_to_latex -from epydoc.docwriter.html_colorize import colorize_doctestblock +from epydoc.markup.doctest import doctest_to_html, doctest_to_latex ################################################## ## Constants @@ -1817,8 +1817,7 @@ elif tree.tagName == 'literalblock': return '<pre class="literalblock">\n%s\n</pre>\n' % childstr elif tree.tagName == 'doctestblock': - dtb = colorize_doctestblock(childstr.strip()) - return '<pre class="doctestblock">\n%s</pre>\n' % dtb + return doctest_to_html(tree.childNodes[0].data.strip()) elif tree.tagName == 'fieldlist': raise AssertionError("There should not be any field lists left") elif tree.tagName in ('epytext', 'section', 'tag', 'arg', @@ -1935,7 +1934,7 @@ elif tree.tagName == 'heading': return ' '*(indent-2) + '(section) %s\n\n' % childstr elif tree.tagName == 'doctestblock': - return '\\begin{alltt}\n%s\\end{alltt}\n\n' % childstr + return doctest_to_latex(tree.childNodes[0].data.strip()) elif tree.tagName == 'literalblock': return '\\begin{alltt}\n%s\\end{alltt}\n\n' % childstr elif tree.tagName == 'fieldlist': Modified: trunk/epydoc/src/epydoc/markup/restructuredtext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/restructuredtext.py 2006-04-13 07:24:22 UTC (rev 1230) +++ trunk/epydoc/src/epydoc/markup/restructuredtext.py 2006-04-19 00:30:37 UTC (rev 1231) @@ -84,6 +84,7 @@ from epydoc.markup import * from epydoc.apidoc import ModuleDoc, ClassDoc from epydoc.docwriter.dotgraph import * +from epydoc.markup.doctest import doctest_to_html, doctest_to_latex #: A dictionary whose keys are the "consolidated fields" that are #: recognized by epydoc; and whose values are the corresponding epydoc @@ -455,15 +456,21 @@ target = self.encode(node.astext()) xref = self._linker.translate_identifier_xref(target, target) self.body.append(xref) - raise SkipNode + raise SkipNode() def visit_document(self, node): pass def depart_document(self, node): pass # For now, just ignore dotgraphs. [XXX] - def visit_dotgraph(self, node): pass - def depart_dotgraph(self, node): pass + def visit_dotgraph(self, node): + log.warning("Ignoring dotgraph in latex output (dotgraph " + "rendering for latex not implemented yet).") + raise SkipNode() + def visit_doctest_block(self, node): + self.body.append(doctest_to_latex(str(node[0]))) + raise SkipNode() + class _EpydocHTMLTranslator(HTMLTranslator): def __init__(self, document, docstring_linker, directory, docindex, context): @@ -484,7 +491,7 @@ target = self.encode(node.astext()) xref = self._linker.translate_identifier_xref(target, target) self.body.append(xref) - raise SkipNode + raise SkipNode() def should_be_compact_paragraph(self, node): if self.document.children == [node]: @@ -505,24 +512,35 @@ - hrefs not starting with C{'#'} are given target='_top' - all headings (C{<hM{n}>}) are given the css class C{'heading'} """ - # Prefix all CSS classes with "rst-" - if attributes.has_key('class'): - attributes['class'] = 'rst-%s' % attributes['class'] + # Get the list of all attribute dictionaries we need to munge. + attr_dicts = [attributes] + if isinstance(node, docutils.nodes.Node): + attr_dicts.append(node.attributes) + if isinstance(node, dict): + attr_dicts.append(node) + # Munge each attribute dictionary. Unfortunately, we need to + # iterate through attributes one at a time because some + # versions of docutils don't case-normalize attributes. + for attr_dict in attr_dicts: + for (key, val) in attr_dict.items(): + # Prefix all CSS classes with "rst-"; and prefix all + # names with "rst-" to avoid conflicts. + if key.lower() in ('class', 'id', 'name'): + attr_dict[key] = 'rst-%s' % val + elif key.lower() in ('classes', 'ids', 'names'): + attr_dict[key] = ['rst-%s' % cls for cls in val] + elif key.lower() == 'href': + if attr_dict[key][:1]=='#': + attr_dict[key] = '#rst-%s' % attr_dict[key][1:] + else: + # If it's an external link, open it in a new + # page. + attr_dict['target'] = '_top' - # Prefix all names with "rst-", to avoid conflicts - if attributes.has_key('id'): - attributes['id'] = 'rst-%s' % attributes['id'] - if attributes.has_key('name'): - attributes['name'] = 'rst-%s' % attributes['name'] - if attributes.has_key('href'): - if attributes['href'][:1]=='#': - attributes['href'] = '#rst-%s' % attributes['href'][1:] - else: - attributes['target'] = '_top' - # For headings, use class="heading" if re.match(r'^h\d+$', tagname): - attributes['class'] = 'heading' + attributes['class'] = ' '.join([attributes.get('class',''), + 'heading']).strip() return HTMLTranslator.starttag(self, node, tagname, suffix, **attributes) @@ -538,9 +556,11 @@ 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)) + raise SkipNode() - def depart_dotgraph(self, node): - pass # Nothing to do. + def visit_doctest_block(self, node): + self.body.append(doctest_to_html(str(node[0]))) + raise SkipNode() ###################################################################### #{ Graph Generation Directives This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ed...@us...> - 2007-02-14 05:44:15
|
Revision: 1498 http://svn.sourceforge.net/epydoc/?rev=1498&view=rev Author: edloper Date: 2007-02-13 21:43:46 -0800 (Tue, 13 Feb 2007) Log Message: ----------- - Set __docformat__ Modified Paths: -------------- trunk/epydoc/src/epydoc/markup/doctest.py trunk/epydoc/src/epydoc/markup/pyval_repr.py Modified: trunk/epydoc/src/epydoc/markup/doctest.py =================================================================== --- trunk/epydoc/src/epydoc/markup/doctest.py 2007-02-14 05:43:07 UTC (rev 1497) +++ trunk/epydoc/src/epydoc/markup/doctest.py 2007-02-14 05:43:46 UTC (rev 1498) @@ -15,6 +15,7 @@ (Both C{doctest_to_html()} and C{doctest_to_latex()} are defined using C{colorize_doctest()}.) """ +__docformat__ = 'epytext en' import re from epydoc.util import plaintext_to_html, plaintext_to_latex Modified: trunk/epydoc/src/epydoc/markup/pyval_repr.py =================================================================== --- trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-14 05:43:07 UTC (rev 1497) +++ trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-14 05:43:46 UTC (rev 1498) @@ -25,6 +25,7 @@ L{ParsedEpydocDocstring}, which can then be used to generate output in a variety of formats. """ +__docformat__ = 'epytext en' # Implementation note: we use exact tests for classes (list, etc) # rather than using isinstance, because subclasses might override This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dva...@us...> - 2007-02-16 23:23:09
|
Revision: 1522 http://svn.sourceforge.net/epydoc/?rev=1522&view=rev Author: dvarrazzo Date: 2007-02-16 15:22:33 -0800 (Fri, 16 Feb 2007) Log Message: ----------- - All the markup error solved. Modified Paths: -------------- trunk/epydoc/src/epydoc/markup/doctest.py trunk/epydoc/src/epydoc/markup/pyval_repr.py trunk/epydoc/src/epydoc/markup/restructuredtext.py Modified: trunk/epydoc/src/epydoc/markup/doctest.py =================================================================== --- trunk/epydoc/src/epydoc/markup/doctest.py 2007-02-16 17:38:35 UTC (rev 1521) +++ trunk/epydoc/src/epydoc/markup/doctest.py 2007-02-16 23:22:33 UTC (rev 1522) @@ -10,7 +10,7 @@ Syntax highlighting for doctest blocks. This module defines two functions, L{doctest_to_html()} and L{doctest_to_latex()}, which can be used to perform syntax highlighting on doctest blocks. It also -defines the more general L{colorize_doctest()}, which could be used to +defines the more general C{colorize_doctest()}, which could be used to do syntac highlighting on doctest blocks with other output formats. (Both C{doctest_to_html()} and C{doctest_to_latex()} are defined using C{colorize_doctest()}.) Modified: trunk/epydoc/src/epydoc/markup/pyval_repr.py =================================================================== --- trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-16 17:38:35 UTC (rev 1521) +++ trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-16 23:22:33 UTC (rev 1522) @@ -61,6 +61,8 @@ self.charpos = 0 self.lineno = 1 self.linebreakok = True + + #: How good this represention is? self.score = 0 def mark(self): Modified: trunk/epydoc/src/epydoc/markup/restructuredtext.py =================================================================== --- trunk/epydoc/src/epydoc/markup/restructuredtext.py 2007-02-16 17:38:35 UTC (rev 1521) +++ trunk/epydoc/src/epydoc/markup/restructuredtext.py 2007-02-16 23:22:33 UTC (rev 1522) @@ -14,12 +14,13 @@ defined by L{ParsedDocstring}. L{ParsedRstDocstring} is basically just a L{ParsedDocstring} wrapper -for the L{docutils.nodes.document} class. +for the C{docutils.nodes.document} class. Creating C{ParsedRstDocstring}s =============================== + C{ParsedRstDocstring}s are created by the C{parse_document} function, -using the L{docutils.core.publish_string()} method, with the following +using the C{docutils.core.publish_string()} method, with the following helpers: - An L{_EpydocReader} is used to capture all error messages as it @@ -27,7 +28,7 @@ - A L{_DocumentPseudoWriter} is used to extract the document itself, without actually writing any output. The document is saved for further processing. The settings for the writer are copied from - L{docutils.writers.html4css1.Writer}, since those settings will + C{docutils.writers.html4css1.Writer}, since those settings will be used when we actually write the docstring to html. Using C{ParsedRstDocstring}s @@ -147,11 +148,11 @@ @ivar _document: A ReStructuredText document, encoding the docstring. - @type _document: L{docutils.nodes.document} + @type _document: C{docutils.nodes.document} """ def __init__(self, document): """ - @type document: L{docutils.nodes.document} + @type document: C{docutils.nodes.document} """ self._document = document @@ -261,7 +262,7 @@ recently processed document is available as the instance variable C{document} - @type document: L{docutils.nodes.document} + @type document: C{docutils.nodes.document} @ivar document: The most recently processed document. """ def __init__(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |