[Epydoc-commits] SF.net SVN: epydoc: [1466] trunk/epydoc/src/epydoc
Brought to you by:
edloper
|
From: <ed...@us...> - 2007-02-13 08:17:38
|
Revision: 1466
http://svn.sourceforge.net/epydoc/?rev=1466&view=rev
Author: edloper
Date: 2007-02-13 00:17:33 -0800 (Tue, 13 Feb 2007)
Log Message:
-----------
- Modified pyval_repr.py so now it generates a ParsedEpydocDocstring
as its output. This should make it possible to change
APIDoc.pyval_repr to return a ParsedDocstring instead of a str.
This ParsedDocstring would be the result of colorization via
pyval_repr, with the parsed repr as a fallback.
Modified Paths:
--------------
trunk/epydoc/src/epydoc/markup/epytext.py
trunk/epydoc/src/epydoc/markup/pyval_repr.py
trunk/epydoc/src/epydoc/test/pyval_repr.doctest
Modified: trunk/epydoc/src/epydoc/markup/epytext.py
===================================================================
--- trunk/epydoc/src/epydoc/markup/epytext.py 2007-02-12 06:54:25 UTC (rev 1465)
+++ trunk/epydoc/src/epydoc/markup/epytext.py 2007-02-13 08:17:33 UTC (rev 1466)
@@ -67,7 +67,7 @@
<!ELEMENT tag (#PCDATA)>
<!ELEMENT arg (#PCDATA)>
- <!ELEMENT literalblock (#PCDATA)>
+ <!ELEMENT literalblock (#PCDATA | %colorized;)*>
<!ELEMENT doctestblock (#PCDATA)>
<!ELEMENT ulist (li+)>
@@ -86,6 +86,7 @@
<!ELEMENT italic (#PCDATA | %colorized;)*>
<!ELEMENT bold (#PCDATA | %colorized;)*>
<!ELEMENT indexed (#PCDATA | %colorized;)>
+ <!ATTLIST code style CDATA #IMPLIED>
<!ELEMENT symbol (#PCDATA)>
@@ -1270,6 +1271,10 @@
return '%s{%s}' % (tag, childstr)
raise ValueError('Unknown DOM element %r' % tree.tag)
+SYMBOL_TO_PLAINTEXT = {
+ 'crarr': '\\',
+ }
+
def to_plaintext(tree, indent=0, seclevel=0):
"""
Convert a DOM document encoding epytext to a string representation.
@@ -1344,7 +1349,7 @@
# if child.count('\n') > 2: return childstr
return childstr.replace('\n\n', '\n')+'\n'
elif tree.tag == 'symbol':
- return '%s' % childstr
+ return '%s' % SYMBOL_TO_PLAINTEXT.get(childstr, childstr)
elif tree.tag == 'graph':
return '<<%s graph: %s>>' % (variables[0], ', '.join(variables[1:]))
else:
@@ -1606,47 +1611,47 @@
class ParsedEpytextDocstring(ParsedDocstring):
SYMBOL_TO_HTML = {
# Symbols
- '<-': 'larr', '->': 'rarr', '^': 'uarr', 'v': 'darr',
+ '<-': '←', '->': '→', '^': '↑', 'v': '↓',
# Greek letters
- 'alpha': 'alpha', 'beta': 'beta', 'gamma': 'gamma',
- 'delta': 'delta', 'epsilon': 'epsilon', 'zeta': 'zeta',
- 'eta': 'eta', 'theta': 'theta', 'iota': 'iota',
- 'kappa': 'kappa', 'lambda': 'lambda', 'mu': 'mu',
- 'nu': 'nu', 'xi': 'xi', 'omicron': 'omicron',
- 'pi': 'pi', 'rho': 'rho', 'sigma': 'sigma',
- 'tau': 'tau', 'upsilon': 'upsilon', 'phi': 'phi',
- 'chi': 'chi', 'psi': 'psi', 'omega': 'omega',
- 'Alpha': 'Alpha', 'Beta': 'Beta', 'Gamma': 'Gamma',
- 'Delta': 'Delta', 'Epsilon': 'Epsilon', 'Zeta': 'Zeta',
- 'Eta': 'Eta', 'Theta': 'Theta', 'Iota': 'Iota',
- 'Kappa': 'Kappa', 'Lambda': 'Lambda', 'Mu': 'Mu',
- 'Nu': 'Nu', 'Xi': 'Xi', 'Omicron': 'Omicron',
- 'Pi': 'Pi', 'Rho': 'Rho', 'Sigma': 'Sigma',
- 'Tau': 'Tau', 'Upsilon': 'Upsilon', 'Phi': 'Phi',
- 'Chi': 'Chi', 'Psi': 'Psi', 'Omega': 'Omega',
+ 'alpha': 'α', 'beta': 'β', 'gamma': 'γ',
+ 'delta': 'δ', 'epsilon': 'ε', 'zeta': 'ζ',
+ 'eta': 'η', 'theta': 'θ', 'iota': 'ι',
+ 'kappa': 'κ', 'lambda': 'λ', 'mu': 'μ',
+ 'nu': 'ν', 'xi': 'ξ', 'omicron': 'ο',
+ 'pi': 'π', 'rho': 'ρ', 'sigma': 'σ',
+ 'tau': 'τ', 'upsilon': 'υ', 'phi': 'φ',
+ 'chi': 'χ', 'psi': 'ψ', 'omega': 'ω',
+ 'Alpha': 'Α', 'Beta': 'Β', 'Gamma': 'Γ',
+ 'Delta': 'Δ', 'Epsilon': 'Ε', 'Zeta': 'Ζ',
+ 'Eta': 'Η', 'Theta': 'Θ', 'Iota': 'Ι',
+ 'Kappa': 'Κ', 'Lambda': 'Λ', 'Mu': 'Μ',
+ 'Nu': 'Ν', 'Xi': 'Ξ', 'Omicron': 'Ο',
+ 'Pi': 'Π', 'Rho': 'Ρ', 'Sigma': 'Σ',
+ 'Tau': 'Τ', 'Upsilon': 'Υ', 'Phi': 'Φ',
+ 'Chi': 'Χ', 'Psi': 'Ψ', 'Omega': 'Ω',
# HTML character entities
- 'larr': 'larr', 'rarr': 'rarr', 'uarr': 'uarr',
- 'darr': 'darr', 'harr': 'harr', 'crarr': 'crarr',
- 'lArr': 'lArr', 'rArr': 'rArr', 'uArr': 'uArr',
- 'dArr': 'dArr', 'hArr': 'hArr',
- 'copy': 'copy', 'times': 'times', 'forall': 'forall',
- 'exist': 'exist', 'part': 'part',
- 'empty': 'empty', 'isin': 'isin', 'notin': 'notin',
- 'ni': 'ni', 'prod': 'prod', 'sum': 'sum',
- 'prop': 'prop', 'infin': 'infin', 'ang': 'ang',
- 'and': 'and', 'or': 'or', 'cap': 'cap', 'cup': 'cup',
- 'int': 'int', 'there4': 'there4', 'sim': 'sim',
- 'cong': 'cong', 'asymp': 'asymp', 'ne': 'ne',
- 'equiv': 'equiv', 'le': 'le', 'ge': 'ge',
- 'sub': 'sub', 'sup': 'sup', 'nsub': 'nsub',
- 'sube': 'sube', 'supe': 'supe', 'oplus': 'oplus',
- 'otimes': 'otimes', 'perp': 'perp',
+ 'larr': '←', 'rarr': '→', 'uarr': '↑',
+ 'darr': '↓', 'harr': '↔', 'crarr': '↵',
+ 'lArr': '⇐', 'rArr': '⇒', 'uArr': '⇑',
+ 'dArr': '⇓', 'hArr': '⇔',
+ 'copy': '©', 'times': '×', 'forall': '∀',
+ 'exist': '∃', 'part': '∂',
+ 'empty': '∅', 'isin': '∈', 'notin': '∉',
+ 'ni': '∋', 'prod': '∏', 'sum': '∑',
+ 'prop': '∝', 'infin': '∞', 'ang': '∠',
+ 'and': '∧', 'or': '∨', 'cap': '∩', 'cup': '∪',
+ 'int': '∫', 'there4': '∴', 'sim': '∼',
+ 'cong': '≅', 'asymp': '≈', 'ne': '≠',
+ 'equiv': '≡', 'le': '≤', 'ge': '≥',
+ 'sub': '⊂', 'sup': '⊃', 'nsub': '⊄',
+ 'sube': '⊆', 'supe': '⊇', 'oplus': '⊕',
+ 'otimes': '⊗', 'perp': '⊥',
# Alternate (long) names
- 'infinity': 'infin', 'integral': 'int', 'product': 'prod',
- '<=': 'le', '>=': 'ge',
+ 'infinity': '∞', 'integral': '∫', 'product': '∏',
+ '<=': '≤', '>=': '≥',
}
SYMBOL_TO_LATEX = {
@@ -1709,6 +1714,9 @@
# Caching:
self._html = self._latex = self._plaintext = None
self._terms = None
+
+ def __str__(self):
+ return str(self._tree)
def to_html(self, docstring_linker, directory=None, docindex=None,
context=None, **options):
@@ -1776,7 +1784,11 @@
if tree.tag == 'para':
return wordwrap('<p>%s</p>' % childstr, indent)
elif tree.tag == 'code':
- return '<code>%s</code>' % childstr
+ style = tree.attribs.get('style')
+ if style:
+ return '<code class="%s">%s</code>' % (style, childstr)
+ else:
+ return '<code>%s</code>' % childstr
elif tree.tag == 'uri':
return ('<a href="%s" target="_top">%s</a>' %
(variables[1], variables[0]))
@@ -1815,10 +1827,7 @@
return childstr
elif tree.tag == 'symbol':
symbol = tree.children[0]
- if self.SYMBOL_TO_HTML.has_key(symbol):
- return '&%s;' % self.SYMBOL_TO_HTML[symbol]
- else:
- return '[??]'
+ return self.SYMBOL_TO_HTML.get(symbol, '[%s]' % symbol)
elif tree.tag == 'graph':
# Generate the graph.
graph = self._build_graph(variables[0], variables[1:], linker,
@@ -1940,10 +1949,7 @@
' '*indent + '\\end{itemize}\n\n')
elif tree.tag == 'symbol':
symbol = tree.children[0]
- if self.SYMBOL_TO_LATEX.has_key(symbol):
- return r'%s' % self.SYMBOL_TO_LATEX[symbol]
- else:
- return '[??]'
+ return self.SYMBOL_TO_LATEX.get(symbol, '[%s]' % symbol)
elif tree.tag == 'graph':
return '(GRAPH)'
#raise ValueError, 'graph not implemented yet for latex'
Modified: trunk/epydoc/src/epydoc/markup/pyval_repr.py
===================================================================
--- trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-12 06:54:25 UTC (rev 1465)
+++ trunk/epydoc/src/epydoc/markup/pyval_repr.py 2007-02-13 08:17:33 UTC (rev 1466)
@@ -20,6 +20,10 @@
number of lines (which should make it faster than pprint for large
values). It does I{not} bother to do automatic cycle detection,
because maxlines is typically around 5, so it's really not worth it.
+
+The syntax-highlighted output is encoded using a
+L{ParsedEpydocDocstring}, which can then be used to generate output in
+a variety of formats.
"""
# Implementation note: we use exact tests for classes (list, etc)
@@ -29,9 +33,12 @@
import types, re
import epydoc.apidoc
from epydoc.util import decode_with_backslashreplace
+from epydoc.util import plaintext_to_html, plaintext_to_latex
from epydoc.compat import *
import sre_parse, sre_constants
+from epydoc.markup.epytext import Element, ParsedEpytextDocstring
+
def is_re_pattern(pyval):
return type(pyval).__name__ == 'SRE_Pattern'
@@ -42,19 +49,25 @@
a backup point, and restore back to that backup point. This is
used by several colorization methods that first try colorizing
their object on a single line (setting linebreakok=False); and
- then fall back on a multi-line output if that fails.
+ then fall back on a multi-line output if that fails. The L{score}
+ variable is used to keep track of a 'score', reflecting how good
+ we think this repr is. E.g., unhelpful values like '<Foo instance
+ at 0x12345>' get low scores. If the score is too low, we'll use
+ the parse-derived repr instead.
"""
def __init__(self):
self.result = []
self.charpos = 0
self.lineno = 1
self.linebreakok = True
+ self.score = 0
def mark(self):
- return (len(self.result), self.charpos, self.lineno, self.linebreakok)
+ return (len(self.result), self.charpos,
+ self.lineno, self.linebreakok, self.score)
def restore(self, mark):
- n, self.charpos, self.lineno, self.linebreakok = mark
+ n, self.charpos, self.lineno, self.linebreakok, self.score = mark
del self.result[n:]
class _Maxlines(Exception):
@@ -78,40 +91,6 @@
self.sort = sort
#////////////////////////////////////////////////////////////
- # Subclassing Hooks
- #////////////////////////////////////////////////////////////
-
- PREFIX = None
- """A string sequence that should be added to the beginning of all
- colorized pyval outputs."""
-
- SUFFIX = None
- """A string sequence that should be added to the beginning of all
- colorized pyval outputs."""
-
- NEWLINE = '\n'
- """The string sequence that should be generated to encode newlines."""
-
- LINEWRAP = None
- """The string sequence that should be generated when linewrapping a
- string that is too long to fit on a single line. (The
- NEWLINE sequence will be added immediately after this sequence)"""
-
- ELLIPSIS = None
- """The string sequence that should be generated when omitting the
- rest of the repr because maxlines has been exceeded."""
-
- def markup(self, s, tag=None):
- """
- Apply syntax highlighting to a single substring from a Python
- value representation. C{s} is the substring, and C{tag} is
- the tag that should be applied to the substring. C{tag} will
- be one of the following strings:
-
- - (list under construction)
- """
-
- #////////////////////////////////////////////////////////////
# Colorization Tags
#////////////////////////////////////////////////////////////
@@ -128,30 +107,43 @@
RE_REF_TAG = 're-ref'
RE_OP_TAG = 're-op'
RE_FLAGS_TAG = 're-flags'
+
+ # Should these use symbols instead?
+ ELLIPSIS = Element('code', '...', style='ellipsis')
+ LINEWRAP = Element('symbol', 'crarr')
#////////////////////////////////////////////////////////////
# Entry Point
#////////////////////////////////////////////////////////////
- def colorize(self, pyval):
+ def colorize(self, pyval, min_score=None):
+ pds, score = self.colorize_and_score(pyval)
+ if min_score is None or score >= min_score:
+ return pds
+ else:
+ return None
+
+ def colorize_and_score(self, pyval):
+ """
+ @return: A tuple (parsed_docstring, score).
+ """
# Create an object to keep track of the colorization.
state = _ColorizerState()
- # Add the prefix string.
- state.result.append(self.PREFIX)
# Colorize the value. If we reach maxlines, then add on an
# ellipsis marker and call it a day.
try:
self._colorize(pyval, state)
except _Maxlines:
state.result.append(self.ELLIPSIS)
- # Add on the suffix string.
- state.result.append(self.SUFFIX)
# Put it all together.
- return ''.join(state.result)
+ tree = Element('epytext', Element('code', style='pyval',
+ *state.result))
+ return ParsedEpytextDocstring(tree), state.score
def _colorize(self, pyval, state):
pyval_type = type(pyval)
-
+ state.score += 1
+
if pyval is None or pyval is True or pyval is False:
self._output(str(pyval), self.CONST_TAG, state)
elif pyval_type in (int, float, long, types.ComplexType):
@@ -179,7 +171,19 @@
elif is_re_pattern(pyval):
self._colorize_re(pyval, state)
else:
- self._output(repr(pyval), None, state)
+ try:
+ pyval_repr = repr(pyval)
+ self._output(pyval_repr, None, state)
+ if self.GENERIC_OBJECT_RE.match(pyval_repr):
+ state.score -= 5
+ except KeyboardInterrupt:
+ raise
+ except:
+ pyval_repr = '...'
+ state.score -= 100
+
+ GENERIC_OBJECT_RE = re.compile(r'^<.* at 0x[0-9a-f]+>$',
+ re.IGNORECASE)
#////////////////////////////////////////////////////////////
# Object Colorization Functions
@@ -430,7 +434,7 @@
if i > 0:
if not state.linebreakok:
raise _Linebreak()
- state.result.append(self.NEWLINE)
+ state.result.append('\n')
state.lineno += 1
state.charpos = 0
if state.lineno > self.maxlines:
@@ -439,40 +443,21 @@
# If the segment fits on the current line, then just call
# markup to tag it, and store the result.
if state.charpos + len(segment) <= self.linelen:
- state.result.append(self.markup(segment, tag))
state.charpos += len(segment)
+ if tag:
+ segment = Element('code', segment, style=tag)
+ state.result.append(segment)
# If the segment doesn't fit on the current line, then
# line-wrap it, and insert the remainder of the line into
- # the segments list that we're iterating over.
+ # the segments list that we're iterating over. (We'll go
+ # the the beginning of the next line at the start of the
+ # next iteration through the loop.)
else:
split = self.linelen-state.charpos
- state.result += [self.markup(segment[:split], tag),
- self.LINEWRAP]
segments.insert(i+1, segment[split:])
+ segment = segment[:split]
+ if tag:
+ segment = Element('code', segment, style=tag)
+ state.result += [segment, self.LINEWRAP]
-class HTMLPyvalColorizer(PyvalColorizer):
- NEWLINE = '\n'
- PREFIX = SUFFIX = ''
- LINEWRAP = (r'<span class="variable-linewrap">'
- '<img src="crarr.png" alt="\" /></span>')
- ELLIPSIS = r'<span class="variable-ellipsis">...</span>'
- def markup(self, s, tag=None):
- s = s.replace('&', '&').replace('<', '<').replace('>', '>')
- if tag:
- return '<span class="variable-%s">%s</span>' % (tag, s)
- else:
- return s
-
-class XMLPyvalColorizer(PyvalColorizer):
- NEWLINE = '\n'
- PREFIX = '<pyval>'
- SUFFIX = '</pyval>'
- LINEWRAP = '<linewrap />'
- ELLIPSIS = '<ellipsis />'
- def markup(self, s, tag=None):
- s = s.replace('&', '&').replace('<', '<').replace('>', '>')
- if tag:
- return '<%s>%s</%s>' % (tag, s, tag)
- else:
- return s
Modified: trunk/epydoc/src/epydoc/test/pyval_repr.doctest
===================================================================
--- trunk/epydoc/src/epydoc/test/pyval_repr.doctest 2007-02-12 06:54:25 UTC (rev 1465)
+++ trunk/epydoc/src/epydoc/test/pyval_repr.doctest 2007-02-13 08:17:33 UTC (rev 1466)
@@ -2,32 +2,36 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> from epydoc.markup.pyval_repr import *
- >>> colorizer = XMLPyvalColorizer(linelen=40)
- >>> def color(s): print colorizer.colorize(s)
+ >>> colorizer = PyvalColorizer(linelen=40)
+ >>> def color(s): print colorizer.colorize(s).to_html(None).rstrip()
-
Simple Types
============
Integers, floats, None, and complex numbers get printed using str,
with no syntax highlighting:
>>> color(10)
- <pyval>10</pyval>
+ <code class="pyval">10</code>
>>> color(1./4)
- <pyval>0.25</pyval>
+ <code class="pyval">0.25</code>
>>> color(None)
- <pyval>None</pyval>
+ <code class="pyval">None</code>
>>> color(100)
- <pyval>100</pyval>
+ <code class="pyval">100</code>
Long ints will get wrapped if they're big enough:
>>> color(10000000)
- <pyval>10000000</pyval>
+ <code class="pyval">10000000</code>
>>> color(10**90)
- <pyval>1000000000000000000000000000000000000000<linewrap />
- 0000000000000000000000000000000000000000<linewrap />
- 00000000000</pyval>
+ <code class="pyval">1000000000000000000000000000000000000000↵
+ 0000000000000000000000000000000000000000↵
+ 00000000000</code>
+ >>> print '-'*40+'\n'+colorizer.colorize(10**90).to_plaintext(None)
+ ----------------------------------------
+ 1000000000000000000000000000000000000000\
+ 0000000000000000000000000000000000000000\
+ 00000000000
Strings
=======
@@ -35,37 +39,37 @@
escaped using the 'string-escape' encoding.
>>> color(''.join(chr(i) for i in range(256)))
- <pyval><val-quote>'''</val-quote><val-string>\x00\x01\x02\x03\x04\x05\x06\x07\x08\</val-string><linewrap />
- <val-string>t</val-string>
- <val-string>\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x</val-string><linewrap />
- <val-string>15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x</val-string><linewrap />
- <val-string>1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCD</val-string><linewrap />
- <ellipsis /></pyval>
+ <code class="pyval"><code class="val-quote">'''</code><code class="val-string">\x00\x01\x02\x03\x04\x05\x06\x07\x08\</code>↵
+ <code class="val-string">t</code>
+ <code class="val-string">\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x</code>↵
+ <code class="val-string">15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x</code>↵
+ <code class="val-string">1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCD</code>↵
+ <code class="ellipsis">...</code></code>
Currently, the "'" quote is always used, because that's what the
'string-escape' encoding expects.
>>> color('Hello')
- <pyval><val-quote>'</val-quote><val-string>Hello</val-string><val-quote>'</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">'</code><code class="val-string">Hello</code><code class="val-quote">'</code></code>
>>> color('"Hello"')
- <pyval><val-quote>'</val-quote><val-string>"Hello"</val-string><val-quote>'</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">'</code><code class="val-string">"Hello"</code><code class="val-quote">'</code></code>
>>> color("'Hello'")
- <pyval><val-quote>'</val-quote><val-string>\'Hello\'</val-string><val-quote>'</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">'</code><code class="val-string">\'Hello\'</code><code class="val-quote">'</code></code>
Strings containing newlines are automatically rendered as multiline
strings.
>>> color("This\n is a multiline\n string!")
- <pyval><val-quote>'''</val-quote><val-string>This</val-string>
- <val-string> is a multiline</val-string>
- <val-string> string!</val-string><val-quote>'''</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">'''</code><code class="val-string">This</code>
+ <code class="val-string"> is a multiline</code>
+ <code class="val-string"> string!</code><code class="val-quote">'''</code></code>
Unicode strings are handled properly.
>>> color(u"Hello world")
- <pyval><val-quote>u'</val-quote><val-string>Hello world</val-string><val-quote>'</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">u'</code><code class="val-string">Hello world</code><code class="val-quote">'</code></code>
>>> color(u"\uaaaa And \ubbbb")
- <pyval><val-quote>u'</val-quote><val-string>\uaaaa And \ubbbb</val-string><val-quote>'</val-quote></pyval>
+ <code class="pyval"><code class="val-quote">u'</code><code class="val-string">\uaaaa And \ubbbb</code><code class="val-quote">'</code></code>
Lists, Tuples, etc.
===================
@@ -75,28 +79,28 @@
listed on a separate line, indented by the size of the open-bracket.
>>> color(range(10))
- <pyval><val-group>[</val-group>0<val-op>, </val-op>1<val-op>, </val-op>2<val-op>, </val-op>3<val-op>, </val-op>4<val-op>, </val-op>5<val-op>, </val-op>6<val-op>, </val-op>7<val-op>, </val-op>8<val-op>, </val-op>9<val-group>]</val-group></pyval>
+ <code class="pyval"><code class="val-group">[</code>0<code class="val-op">, </code>1<code class="val-op">, </code>2<code class="val-op">, </code>3<code class="val-op">, </code>4<code class="val-op">, </code>5<code class="val-op">, </code>6<code class="val-op">, </code>7<code class="val-op">, </code>8<code class="val-op">, </code>9<code class="val-group">]</code></code>
>>> color(range(100))
- <pyval><val-group>[</val-group>0<val-op>,</val-op>
- 1<val-op>,</val-op>
- 2<val-op>,</val-op>
- 3<val-op>,</val-op>
- 4<val-op>,</val-op>
- <ellipsis /></pyval>
+ <code class="pyval"><code class="val-group">[</code>0<code class="val-op">,</code>
+ 1<code class="val-op">,</code>
+ 2<code class="val-op">,</code>
+ 3<code class="val-op">,</code>
+ 4<code class="val-op">,</code>
+ <code class="ellipsis">...</code></code>
>>> color([1,2,[5,6,[(11,22,33),9],10],11]+[99,98,97,96,95])
- <pyval><val-group>[</val-group>1<val-op>,</val-op>
- 2<val-op>,</val-op>
- <val-group>[</val-group>5<val-op>, </val-op>6<val-op>, </val-op><val-group>[</val-group><val-group>(</val-group>11<val-op>, </val-op>22<val-op>, </val-op>33<val-group>)</val-group><val-op>, </val-op>9<val-group>]</val-group><val-op>, </val-op>10<val-group>]</val-group><val-op>,</val-op>
- 11<val-op>,</val-op>
- 99<val-op>,</val-op>
- <ellipsis /></pyval>
+ <code class="pyval"><code class="val-group">[</code>1<code class="val-op">,</code>
+ 2<code class="val-op">,</code>
+ <code class="val-group">[</code>5<code class="val-op">, </code>6<code class="val-op">, </code><code class="val-group">[</code><code class="val-group">(</code>11<code class="val-op">, </code>22<code class="val-op">, </code>33<code class="val-group">)</code><code class="val-op">, </code>9<code class="val-group">]</code><code class="val-op">, </code>10<code class="val-group">]</code><code class="val-op">,</code>
+ 11<code class="val-op">,</code>
+ 99<code class="val-op">,</code>
+ <code class="ellipsis">...</code></code>
>>> color(set(range(20)))
- <pyval><val-group>set([</val-group>0<val-op>,</val-op>
- 1<val-op>,</val-op>
- 2<val-op>,</val-op>
- 3<val-op>,</val-op>
- 4<val-op>,</val-op>
- <ellipsis /></pyval>
+ <code class="pyval"><code class="val-group">set([</code>0<code class="val-op">,</code>
+ 1<code class="val-op">,</code>
+ 2<code class="val-op">,</code>
+ 3<code class="val-op">,</code>
+ 4<code class="val-op">,</code>
+ <code class="ellipsis">...</code></code>
Dictionaries
============
@@ -104,91 +108,137 @@
"op".
>>> color({1:33, 2:[1,2,3,{7:'oo'*20}]})
- <pyval><val-group>{</val-group>1<val-op>: </val-op>33<val-op>,</val-op>
- 2<val-op>: </val-op><val-group>[</val-group>1<val-op>,</val-op>
- 2<val-op>,</val-op>
- 3<val-op>,</val-op>
- <val-group>{</val-group>7<val-op>: </val-op><val-quote>'</val-quote><val-string>oooooooooooooooooooooooooooooo</val-string><linewrap />
- <ellipsis /></pyval>
+ <code class="pyval"><code class="val-group">{</code>1<code class="val-op">: </code>33<code class="val-op">,</code>
+ 2<code class="val-op">: </code><code class="val-group">[</code>1<code class="val-op">,</code>
+ 2<code class="val-op">,</code>
+ 3<code class="val-op">,</code>
+ <code class="val-group">{</code>7<code class="val-op">: </code><code class="val-quote">'</code><code class="val-string">oooooooooooooooooooooooooooooo</code>↵
+ <code class="ellipsis">...</code></code>
Regular Expressions
===================
+ >>> def textcontent(elt):
+ ... if isinstance(elt, basestring): return elt
+ ... else: return ''.join(textcontent(c) for c in elt.children)
+
>>> import re
>>> def color_re(s, check_roundtrip=True):
... val = colorizer.colorize(re.compile(s))
... if check_roundtrip:
- ... roundtrip_val = re.sub('</?[\w-]+>', '', val)
- ... roundtrip_val = roundtrip_val.replace('>', '>')
- ... roundtrip_val = roundtrip_val.replace('<', '<')
- ... roundtrip_val = roundtrip_val.replace('&', '&')
- ... assert roundtrip_val == s, roundtrip_val
- ... print val
+ ... assert textcontent(val._tree) == s, val._tree
+ ... print val.to_html(None).rstrip()
>>> # Literal characters
>>> color_re(u'abc \t\r\n\f\v \xff \uffff \U000fffff', False)
- <pyval>abc \t\r\n\f\v \xff \uffff \U000fffff</pyval>
+ <code class="pyval">abc \t\r\n\f\v \xff \uffff \U000fffff</code>
>>> color_re(r'\.\^\$\\\*\+\?\{\}\[\]\|\(\)')
- <pyval>\.\^\$\\\*\+\?\{\}\[\]\|\(\)</pyval>
+ <code class="pyval">\.\^\$\\\*\+\?\{\}\[\]\|\(\)</code>
>>> # Any character & character classes
>>> color_re(r".\d\D\s\S\w\W\A^$\b\B\Z")
- <pyval>.\d\D\s\S\w\W\A^$\b\B\Z</pyval>
+ <code class="pyval">.\d\D\s\S\w\W\A^$\b\B\Z</code>
>>> # Branching
>>> color_re(r"foo|bar")
- <pyval>foo<re-op>|</re-op>bar</pyval>
+ <code class="pyval">foo<code class="re-op">|</code>bar</code>
>>> # Character classes
>>> color_re(r"[abcd]")
- <pyval><re-group>[</re-group>abcd<re-group>]</re-group></pyval>
+ <code class="pyval"><code class="re-group">[</code>abcd<code class="re-group">]</code></code>
>>> # Repeats
>>> color_re(r"a*b+c{4,}d{,5}e{3,9}f?")
- <pyval>a<re-op>*</re-op>b<re-op>+</re-op>c<re-op>{4,}</re-op>d<re-op>{,5}</re-op>e<re-op>{3,9}</re-op>f<re-op>?</re-op></pyval>
+ <code class="pyval">a<code class="re-op">*</code>b<code class="re-op">+</code>c<code class="re-op">{4,}</code>d<code class="re-op">{,5}</code>e<code class="re-op">{3,9}</code>f<code class="re-op">?</code></code>
>>> color_re(r"a*?b+?c{4,}?d{,5}?e{3,9}?f??")
- <pyval>a<re-op>*?</re-op>b<re-op>+?</re-op>c<re-op>{4,}?</re-op>d<re-op>{,5}?</re-op>e<re-op>{3,9}?</re-op>f<re-op>??</re-op></pyval>
+ <code class="pyval">a<code class="re-op">*?</code>b<code class="re-op">+?</code>c<code class="re-op">{4,}?</code>d<code class="re-op">{,5}?</code>e<code class="re-op">{3,9}?</code>f<code class="re-op">??</code></code>
>>> # Subpatterns
>>> color_re(r"(foo (bar) | (baz))")
- <pyval><re-group>(</re-group>foo <re-group>(</re-group>bar<re-group>)</re-group> <re-op>|</re-op> <re-group>(</re-group>baz<re-group>)</re-group><re-group>)</re-group></pyval>
+ <code class="pyval"><code class="re-group">(</code>foo <code class="re-group">(</code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(</code>baz<code class="re-group">)</code><code class="re-group">)</code></code>
>>> color_re(r"(?:foo (?:bar) | (?:baz))")
- <pyval><re-group>(?:</re-group>foo <re-group>(?:</re-group>bar<re-group>)</re-group> <re-op>|</re-op> <re-group>(?:</re-group>baz<re-group>)</re-group><re-group>)</re-group></pyval>
+ <code class="pyval"><code class="re-group">(?:</code>foo <code class="re-group">(?:</code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(?:</code>baz<code class="re-group">)</code><code class="re-group">)</code></code>
>>> color_re("(foo (?P<a>bar) | (?P<boop>baz))")
- <pyval><re-group>(</re-group>foo <re-group>(?P<</re-group><re-ref>a</re-ref><re-group>></re-group>bar<re-group>)</re-group> <re-op>|</re-op> <re-group>(?P<</re-group><re-ref>boop</re-ref><re-group>></re-group>baz<re-group>)</re-group><re-group>)</re-group></pyval>
+ <code class="pyval"><code class="re-group">(</code>foo <code class="re-group">(?P<</code><code class="re-ref">a</code><code class="re-group">></code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(?P<</code><code class="re-ref">boop</code><code class="re-group">></code>baz<code class="re-group">)</code><code class="re-group">)</code></code>
>>> # Group References
>>> color_re(r"(...) and (\1)")
- <pyval><re-group>(</re-group>...<re-group>)</re-group> and <re-group>(</re-group><re-ref>\1</re-ref><re-group>)</re-group></pyval>
+ <code class="pyval"><code class="re-group">(</code>...<code class="re-group">)</code> and <code class="re-group">(</code><code class="re-ref">\1</code><code class="re-group">)</code></code>
>>> # Ranges
>>> color_re(r"[a-bp-z]")
- <pyval><re-group>[</re-group>a<re-op>-</re-op>bp<re-op>-</re-op>z<re-group>]</re-group></pyval>
+ <code class="pyval"><code class="re-group">[</code>a<code class="re-op">-</code>bp<code class="re-op">-</code>z<code class="re-group">]</code></code>
>>> color_re(r"[^a-bp-z]")
- <pyval><re-group>[</re-group><re-op>^</re-op>a<re-op>-</re-op>bp<re-op>-</re-op>z<re-group>]</re-group></pyval>
+ <code class="pyval"><code class="re-group">[</code><code class="re-op">^</code>a<code class="re-op">-</code>bp<code class="re-op">-</code>z<code class="re-group">]</code></code>
>>> color_re(r"[^abc]")
- <pyval><re-group>[</re-group><re-op>^</re-op>abc<re-group>]</re-group></pyval>
+ <code class="pyval"><code class="re-group">[</code><code class="re-op">^</code>abc<code class="re-group">]</code></code>
>>> # Lookahead/behinds
>>> color_re(r"foo(?=bar)")
- <pyval>foo<re-group>(?=</re-group>bar<re-group>)</re-group></pyval>
+ <code class="pyval">foo<code class="re-group">(?=</code>bar<code class="re-group">)</code></code>
>>> color_re(r"foo(?!bar)")
- <pyval>foo<re-group>(?!</re-group>bar<re-group>)</re-group></pyval>
+ <code class="pyval">foo<code class="re-group">(?!</code>bar<code class="re-group">)</code></code>
>>> color_re(r"(?<=bar)foo")
- <pyval><re-group>(?<=</re-group>bar<re-group>)</re-group>foo</pyval>
+ <code class="pyval"><code class="re-group">(?<=</code>bar<code class="re-group">)</code>foo</code>
>>> color_re(r"(?<!bar)foo")
- <pyval><re-group>(?<!</re-group>bar<re-group>)</re-group>foo</pyval>
+ <code class="pyval"><code class="re-group">(?<!</code>bar<code class="re-group">)</code>foo</code>
>>> # Flags
>>> color_re(r"(?im)^Food")
- <pyval><re-flags>(?im)</re-flags>^Food</pyval>
+ <code class="pyval"><code class="re-flags">(?im)</code>^Food</code>
>>> color_re(r"(?Limsx)^Food")
- <pyval><re-flags>(?Limsx)</re-flags>^Food</pyval>
+ <code class="pyval"><code class="re-flags">(?Limsx)</code>^Food</code>
>>> color_re(r"(?Limstux)^Food")
- <pyval><re-flags>(?Limstux)</re-flags>^Food</pyval>
+ <code class="pyval"><code class="re-flags">(?Limstux)</code>^Food</code>
>>> color_re(r"(?x)This is verbose", False)
- <pyval><re-flags>(?x)</re-flags>Thisisverbose</pyval>
+ <code class="pyval"><code class="re-flags">(?x)</code>Thisisverbose</code>
+Representation Scores
+=====================
+When colorized representations are built, a score is computed
+evaluating how helpful the repr is. E.g., unhelpful values like `<Foo
+instance at 0x12345>` get low scores. Currently, the scoring
+algorithm is:
+- [+1] for each object colorized. When the colorizer recurses into
+ a structure, this will add one for each element contained.
+- [-5] when repr(obj) looks like <xyz instance at ...>, for any
+ colorized object (including objects in structures).
+- [-100] if repr(obj) raises an exception, for any colorized object
+ (including objects in structures).
+The `min_score` arg to colorize can be used to set a cutoff-point for
+scores; if the score is too low, then `colorize` will return `None`.
+ >>> def color2(v):
+ ... pds, score = colorizer.colorize_and_score(v)
+ ... print 'repr: %s' % pds.to_plaintext(None)
+ ... print 'score: %s (%s)' % (score, score>0 and 'ok' or 'bad')
+
+ >>> class A: pass
+
+ >>> color2('hello')
+ repr: 'hello'
+ score: 1 (ok)
+
+ >>> color2(["hello", 123])
+ repr: ['hello', 123]
+ score: 3 (ok)
+
+ >>> color2(A())
+ repr: <__builtin__.A instance at ...>
+ score: -4 (bad)
+
+ >>> color2([A()])
+ repr: [<__builtin__.A instance at ...>]
+ score: -3 (bad)
+
+ >>> color2([A(),1,2,3,4,5,6])
+ repr: [<__builtin__.A instance at ...>,
+ 1,
+ 2,
+ 3,
+ 4,
+ ...
+ score: 1 (ok)
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|