1. Blue Goji
  2. Untitled project
  3. pygments-json-fix

Commits

blackbird  committed ca46061

[svn] implemented filters for pygments (first approach, api might change), it's impossible at the moment to add filters by using pygmentize

  • Participants
  • Parent commits dfde569
  • Branches trunk

Comments (0)

Files changed (24)

File docs/src/filterdevelopment.txt

View file
  • Ignore whitespace
+.. -*- mode: rst -*-
+
+=====================
+Write your own filter
+=====================
+
+*New in Pygments 0.7*
+
+Writing own filters is very easy. All you have to do is to subclass
+the `Filter` class and override the `filter` method. Additionally a
+filter is instanciated with some keyword arguments you can use to
+adjust the behavior of your filter.
+
+
+Subclassing Filters
+===================
+
+As an example we write a filter that converts all `Name.Function` tokens
+to normal `Name` tokens to make the output less colorful.
+
+.. sourcecode:: pycon
+
+    from pygments.util import get_bool_opt
+    from pygments.token import Name
+    from pygments.filter import Filter
+
+    class UncolorFilter(Filter):
+
+        def __init__(self, **options):
+            Filter.__init__(self, **options)
+            self.class_too = get_bool_opt(options, 'classtoo')
+
+        def filter(self, lexer, stream):
+            for ttype, value in stream:
+                if ttype == Name.Function or (self.class_too and
+                                              ttype == Name.Class):
+                    ttype = Name
+                yield ttype, value
+
+Some words on the `lexer` argument. That can be quite confusing since it
+must not be a lexer instance. If a filter was added by using the `add_filter`
+function of lexers that lexer is registered for the filter. In that case
+`lexer` will be point to the lexer that has registered the filter. It can
+be used (but must not) to access options passed to a lexer. Because it
+could be `None` you always have to check for that case if you access it.
+
+
+Using a Decorator
+=================
+
+You can also use the `simplefilter` decorator from the `pygments.filter`
+module:
+
+.. sourcecode:: pycon
+
+    from pygments.util import get_bool_opt
+    from pygments.token import Name
+    from pygments.filter import simplefilter
+
+
+    @simplefilter
+    def uncolor(lexer, stream, options):
+        class_too = get_bool_opt(options, 'classtoo')
+        for ttype, value in stream:
+            if ttype == Name.Function or (class_too and
+                                          ttype == Name.Class):
+                ttype = Name
+            yield ttype, value

File docs/src/filters.txt

View file
  • Ignore whitespace
+.. -*- mode: rst -*-
+
+=======
+Filters
+=======
+
+Since Pygments 0.7 you can filter token streams to improve the output. For
+example you can highlight special words in comments, convert keywords
+to upper or lowercase to enforce an styleguide etc.
+
+To apply an filter you can use the `add_filter` method of a lexer:
+
+.. sourcecode:: pycon
+
+    >>> from pygments.lexers import PythonLexer
+    >>> l = PythonLexer()
+    >>> # as string
+    >>> l.add_filter("codetagify")
+    >>> l.filters
+    [<pygments.filters.CodeTagFilter object at 0xb785decc>]
+    >>> from pygments.filters import KeywordRewriteFilter
+    >>> # or class
+    >>> l.add_filter(KeywordRewriteFilter(keywordcase='lower'))
+
+The `add_filter` method also takes keyword arguments which are forwarded
+to the constructor of the filter.
+
+To get a list of all registered filters by name you can use the
+`get_all_filters` function from the `pygments.filters` module that returns
+an iterable for all known filters.
+
+If you want to write your own lexer have a look at `Write your own filter`_.
+
+.. _Write your own filter: filterdevelopment.txt
+
+
+Builtin Filters
+===============
+
+`CodeTagFilter`
+
+    Highlights special code tags in comments and docstrings. Per
+    default the list of highlighted tags is ``XXX``, ``TODO``,
+    ``BUG`` and ``NOTE``. You can override this list by specifying
+    a ``codetags`` parameter that takes a list of words.
+
+    :Name:  ``codetagify``
+
+`KeywordCaseFilter`
+
+    Converts keywords to ``lower``, ``upper`` or ``capitalize`` which
+    means first letter uppercase, rest lowercase. This can be useful
+    if you highlight pascal code and want to adapt the code to your
+    styleguide. The default is ``lower``, override that by providing
+    the `keywordcase` parameter.
+
+    :Name:  ``keywordcase``

File docs/src/formatterdev.txt

  • Ignore whitespace
-.. -*- mode: rst -*-
-
-========================
-Write your own formatter
-========================
-
-As well as creating `your own lexer <lexerdevelopment.txt>`_, writing a new
-formatter for Pygments is easy and straightforward.
-
-A formatter is a class that is initialized with some keyword arguments (the
-formatter options) and that must provides a `format()` method.
-Additionally a formatter should provide a `get_style_defs()` method that
-returns the style definitions from the style in a form usable for the
-formatter's output format.
-
-
-Quickstart
-==========
-
-The most basic formatter shipped with Pygments is the `NullFormatter`. It just
-sends the value of a token to the output stream:
-
-.. sourcecode:: python
-
-    from pygments.formatter import Formatter
-
-    class NullFormatter(Formatter):
-        def format(self, tokensource, outfile):
-            for ttype, value in tokensource:
-                outfile.write(value)
-
-As you can see, the `format()` method is passed two parameters: `tokensource`
-and `outfile`. The first is an iterable of ``(token_type, value)`` tuples,
-the latter a file like object with a `write()` method.
-
-Because the formatter is that basic it doesn't overwrite the `get_style_defs()`
-method.
-
-
-Styles
-======
-
-Styles aren't instantiated but their metaclass provides some class functions
-so that you can access the style definitions easily.
-
-Styles are iterable and yield tuples in the form ``(ttype, d)`` where `ttype`
-is a token and `d` is a dict with the following keys:
-
-``'color'``
-    Hexadecimal color value (eg: ``'ff0000'`` for red) or `None` if not
-    defined.
-
-``'bold'``
-    `True` if the value should be bold
-
-``'italic'``
-    `True` if the value should be italic
-
-``'underline'``
-    `True` if the value should be underlined
-
-``'bgcolor'``
-    Hexadecimal color value for the background (eg: ``'eeeeeee'`` for light
-    gray) or `None` if not defined.
-
-``'border'``
-    Hexadecimal color value for the border (eg: ``'0000aa'`` for a dark
-    blue) or `None` for no border.
-
-Additional keys might appear in the future, formatters should ignore all keys
-they don't support.
-
-
-HTML 3.2 Formatter
-==================
-
-For an more complex example, let's implement a HTML 3.2 Formatter. We don't
-use CSS but inline markup (``<u>``, ``<font>``, etc). Because this isn't good
-style this formatter isn't in the standard library ;-)
-
-.. sourcecode:: python
-
-    from pygments.formatter import Formatter
-
-    class OldHtmlFormatter(Formatter):
-
-        def __init__(self, **options):
-            Formatter.__init__(self, **options)
-
-            # create a dict of (start, end) tuples that wrap the
-            # value of a token so that we can use it in the format
-            # method later
-            self.styles = {}
-
-            # we iterate over the `_styles` attribute of a style item
-            # that contains the parsed style values.
-            for token, style in self.style:
-                start = end = ''
-                # a style item is a tuple in the following form:
-                # colors are readily specified in hex: 'RRGGBB'
-                if style['color']:
-                    start += '<font color="#%s">' % color
-                    end += '</font>'
-                if style['bold']:
-                    start += '<b>'
-                    end += '</b>'
-                if style['italic']:
-                    start += '<i>'
-                    end += '</i>'
-                if style['underline']:
-                    start += '<u>'
-                    end += '</u>'
-                self.styles[token] = (start, end)
-
-        def format(self, tokensource, outfile):
-            # lastval is a string we use for caching
-            # because it's possible that an lexer yields a number
-            # of consecutive tokens with the same token type.
-            # to minimize the size of the generated html markup we
-            # try to join the values of same-type tokens here
-            lastval = ''
-            lasttype = None
-
-            # wrap the whole output with <pre>
-            outfile.write('<pre>')
-
-            for ttype, value in tokensource:
-                # if the token type doesn't exist in the stylemap
-                # we try it with the parent of the token type
-                # eg: parent of Token.Literal.String.Double is
-                # Token.Literal.String
-                while ttype not in self.styles:
-                    ttype = ttype.parent
-                if ttype == lasttype:
-                    # the current token type is the same of the last
-                    # iteration. cache it
-                    lastval += value
-                else:
-                    # not the same token as last iteration, but we
-                    # have some data in the buffer. wrap it with the
-                    # defined style and write it to the output file
-                    if lastval:
-                        stylebegin, styleend = self.styles[lasttype]
-                        outfile.write(stylebegin + lastval + styleend)
-                    # set lastval/lasttype to current values
-                    lastval = value
-                    lasttype = ttype
-
-            # if something is left in the buffer, write it to the
-            # output file, then close the opened <pre> tag
-            if lastval:
-                stylebegin, styleend = self.styles[lasttype]
-                outfile.write(stylebegin + lastval + styleend)
-            outfile.write('</pre>\n')
-
-The comments should explain it. Again, this formatter doesn't override the
-`get_style_defs()` method. If we would have used CSS classes instead of
-inline HTML markup, we would need to generate the CSS first. For that
-purpose the `get_style_defs()` method exists:
-
-
-Generating Style Definitions
-============================
-
-Some formatters like the `LatexFormatter` and the `HtmlFormatter` don't
-output inline markup but reference either macros or css classes. Because
-the definitions of those are not part of the output, the `get_style_defs()`
-method exists. It is passed one parameter (if it's used and how it's used
-is up to the formatter) and has to return a string or ``None``.

File docs/src/formatterdevelopment.txt

View file
  • Ignore whitespace
+.. -*- mode: rst -*-
+
+========================
+Write your own formatter
+========================
+
+As well as creating `your own lexer <lexerdevelopment.txt>`_, writing a new
+formatter for Pygments is easy and straightforward.
+
+A formatter is a class that is initialized with some keyword arguments (the
+formatter options) and that must provides a `format()` method.
+Additionally a formatter should provide a `get_style_defs()` method that
+returns the style definitions from the style in a form usable for the
+formatter's output format.
+
+
+Quickstart
+==========
+
+The most basic formatter shipped with Pygments is the `NullFormatter`. It just
+sends the value of a token to the output stream:
+
+.. sourcecode:: python
+
+    from pygments.formatter import Formatter
+
+    class NullFormatter(Formatter):
+        def format(self, tokensource, outfile):
+            for ttype, value in tokensource:
+                outfile.write(value)
+
+As you can see, the `format()` method is passed two parameters: `tokensource`
+and `outfile`. The first is an iterable of ``(token_type, value)`` tuples,
+the latter a file like object with a `write()` method.
+
+Because the formatter is that basic it doesn't overwrite the `get_style_defs()`
+method.
+
+
+Styles
+======
+
+Styles aren't instantiated but their metaclass provides some class functions
+so that you can access the style definitions easily.
+
+Styles are iterable and yield tuples in the form ``(ttype, d)`` where `ttype`
+is a token and `d` is a dict with the following keys:
+
+``'color'``
+    Hexadecimal color value (eg: ``'ff0000'`` for red) or `None` if not
+    defined.
+
+``'bold'``
+    `True` if the value should be bold
+
+``'italic'``
+    `True` if the value should be italic
+
+``'underline'``
+    `True` if the value should be underlined
+
+``'bgcolor'``
+    Hexadecimal color value for the background (eg: ``'eeeeeee'`` for light
+    gray) or `None` if not defined.
+
+``'border'``
+    Hexadecimal color value for the border (eg: ``'0000aa'`` for a dark
+    blue) or `None` for no border.
+
+Additional keys might appear in the future, formatters should ignore all keys
+they don't support.
+
+
+HTML 3.2 Formatter
+==================
+
+For an more complex example, let's implement a HTML 3.2 Formatter. We don't
+use CSS but inline markup (``<u>``, ``<font>``, etc). Because this isn't good
+style this formatter isn't in the standard library ;-)
+
+.. sourcecode:: python
+
+    from pygments.formatter import Formatter
+
+    class OldHtmlFormatter(Formatter):
+
+        def __init__(self, **options):
+            Formatter.__init__(self, **options)
+
+            # create a dict of (start, end) tuples that wrap the
+            # value of a token so that we can use it in the format
+            # method later
+            self.styles = {}
+
+            # we iterate over the `_styles` attribute of a style item
+            # that contains the parsed style values.
+            for token, style in self.style:
+                start = end = ''
+                # a style item is a tuple in the following form:
+                # colors are readily specified in hex: 'RRGGBB'
+                if style['color']:
+                    start += '<font color="#%s">' % color
+                    end += '</font>'
+                if style['bold']:
+                    start += '<b>'
+                    end += '</b>'
+                if style['italic']:
+                    start += '<i>'
+                    end += '</i>'
+                if style['underline']:
+                    start += '<u>'
+                    end += '</u>'
+                self.styles[token] = (start, end)
+
+        def format(self, tokensource, outfile):
+            # lastval is a string we use for caching
+            # because it's possible that an lexer yields a number
+            # of consecutive tokens with the same token type.
+            # to minimize the size of the generated html markup we
+            # try to join the values of same-type tokens here
+            lastval = ''
+            lasttype = None
+
+            # wrap the whole output with <pre>
+            outfile.write('<pre>')
+
+            for ttype, value in tokensource:
+                # if the token type doesn't exist in the stylemap
+                # we try it with the parent of the token type
+                # eg: parent of Token.Literal.String.Double is
+                # Token.Literal.String
+                while ttype not in self.styles:
+                    ttype = ttype.parent
+                if ttype == lasttype:
+                    # the current token type is the same of the last
+                    # iteration. cache it
+                    lastval += value
+                else:
+                    # not the same token as last iteration, but we
+                    # have some data in the buffer. wrap it with the
+                    # defined style and write it to the output file
+                    if lastval:
+                        stylebegin, styleend = self.styles[lasttype]
+                        outfile.write(stylebegin + lastval + styleend)
+                    # set lastval/lasttype to current values
+                    lastval = value
+                    lasttype = ttype
+
+            # if something is left in the buffer, write it to the
+            # output file, then close the opened <pre> tag
+            if lastval:
+                stylebegin, styleend = self.styles[lasttype]
+                outfile.write(stylebegin + lastval + styleend)
+            outfile.write('</pre>\n')
+
+The comments should explain it. Again, this formatter doesn't override the
+`get_style_defs()` method. If we would have used CSS classes instead of
+inline HTML markup, we would need to generate the CSS first. For that
+purpose the `get_style_defs()` method exists:
+
+
+Generating Style Definitions
+============================
+
+Some formatters like the `LatexFormatter` and the `HtmlFormatter` don't
+output inline markup but reference either macros or css classes. Because
+the definitions of those are not part of the output, the `get_style_defs()`
+method exists. It is passed one parameter (if it's used and how it's used
+is up to the formatter) and has to return a string or ``None``.

File docs/src/index.txt

View file
  • Ignore whitespace
 
   - `Builtin formatters <formatters.txt>`_
 
+  - `Filters <filters.txt>`_
+
   - `Styles <styles.txt>`_
 
 - API and more
 
   - `Write your own lexer <lexerdevelopment.txt>`_
 
-  - `Write your own formatter <formatterdev.txt>`_
+  - `Write your own formatter <formatterdevelopment.txt>`_
+  
+  - `Write your own filter <filterdevelopment.txt>`_
 
   - `Register Plugins <plugins.txt>`_
 

File docs/src/lexerdevelopment.txt

View file
  • Ignore whitespace
                     yield index, token, value
 
 The `PhpLexer` and `LuaLexer` use this method to resolve builtin functions.
+
+**Note** Do not confuse this with the `filter`_ system.
+
+.. _filter: filters.txt

File docs/src/plugins.txt

View file
  • Ignore whitespace
         yourstyle = yourmodule:YourStyle
 
 
+`pygments.filters`
+
+    Use this entrypoint to register a new filter. The name of the
+    entrypoint is the name of the filter:
+
+    .. sourcecode:: ini
+
+        [pygments.filters]
+        yourfilter = yourmodule:YourFilter
+
+
 How To Use Entrypoints
 ======================
 

File docs/src/tokens.txt

View file
  • Ignore whitespace
 `Comment.Single`
     Token type for comments that end at the end of a line (e.g. ``# foo``).
 
+`Comment.Special`
+    Special data in comments. For example code tags, author and license
+    informations etc.
+
 
 Generic Tokens
 ==============

File pygments/__init__.py

View file
  • Ignore whitespace
 def highlight(code, lexer, formatter, outfile=None):
     """
     Lex ``code`` with ``lexer`` and format it with the formatter
-    ``formatter``.
+    ``formatter``. If ``filters`` are given they will be applied
+    on the token stream.
 
     If ``outfile`` is given and a valid file object (an object
     with a ``write`` method), the result will be written to it, otherwise

File pygments/lexer.py

View file
  • Ignore whitespace
 except NameError:
     from sets import Set as set
 
+from pygments.filter import apply_filters, Filter
+from pygments.filters import find_filter
 from pygments.token import Error, Text, Other, _TokenType
-from pygments.util import get_bool_opt, get_int_opt, make_analysator
+from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \
+     make_analysator
 
 
 __all__ = ['Lexer', 'RegexLexer', 'ExtendedRegexLexer', 'DelegatingLexer',
         self.stripall = get_bool_opt(options, 'stripall', False)
         self.tabsize = get_int_opt(options, 'tabsize', 0)
         self.encoding = options.get('encoding', 'latin1')
+        self.filters = []
+        for filter in get_list_opt(options, 'filters', ()):
+            self.add_filter(filter)
 
     def __repr__(self):
         if self.options:
         else:
             return '<pygments.lexers.%s>' % self.__class__.__name__
 
+    def add_filter(self, filter, **options):
+        """
+        Add a new stream filter to this lexer.
+        """
+        if not isinstance(filter, Filter):
+            filter = find_filter(filter, **options)
+        self.filters.append(filter)
+
     def analyse_text(text):
         """
         Has to return a float between ``0`` and ``1`` that indicates
         it's the same as if the return values was ``0.0``.
         """
 
-    def get_tokens(self, text):
+    def get_tokens(self, text, unfiltered=False):
         """
-        Return an iterable of (tokentype, value) pairs generated from ``text``.
+        Return an iterable of (tokentype, value) pairs generated from
+        `text`. If `unfiltered` is set to `True` the filtering mechanism
+        is bypassed, even if filters are defined.
 
-        Also preprocess the text, i.e. expand tabs and strip it if wanted.
+        Also preprocess the text, i.e. expand tabs and strip it if
+        wanted and applies registered filters.
         """
         if isinstance(text, unicode):
             text = u'\n'.join(text.splitlines())
                 try:
                     import chardet
                 except ImportError:
-                    raise ImportError('To enable chardet encoding guessing, please '
-                                      'install the chardet library from '
-                                      'http://chardet.feedparser.org/')
+                    raise ImportError('To enable chardet encoding guessing, '
+                                      'please install the chardet library '
+                                      'from http://chardet.feedparser.org/')
                 enc = chardet.detect(text)
                 text = text.decode(enc['encoding'])
             else:
         if not text.endswith('\n'):
             text += '\n'
 
-        for i, t, v in self.get_tokens_unprocessed(text):
-            yield t, v
+        def streamer():
+            for i, t, v in self.get_tokens_unprocessed(text):
+                yield t, v
+        stream = streamer()
+        if not unfiltered:
+            stream = apply_filters(stream, self.filters, self)
+        return stream
 
     def get_tokens_unprocessed(self, text):
         """

File pygments/plugin.py

View file
  • Ignore whitespace
         [pygments.styles]
         yourstyle = yourstyle:YourStyle
 
+    filter plugin::
+
+        [pygments.filter]
+        yourfilter = yourfilter:YourFilter
+
 
     :copyright: 2006 by Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 LEXER_ENTRY_POINT = 'pygments.lexers'
 FORMATTER_ENTRY_POINT = 'pygments.formatters'
 STYLE_ENTRY_POINT = 'pygments.styles'
+FILTER_ENTRY_POINT = 'pygments.filters'
 
 
 def find_plugin_lexers():
         return
     for entrypoint in pkg_resources.iter_entry_points(STYLE_ENTRY_POINT):
         yield entrypoint.name, entrypoint.load()
+
+
+def find_plugin_filters():
+    if pkg_recources is None:
+        return
+    for entrypoint in pkg_resources.iter_entry_points(FILTER_ENTRY_POINT):
+        yield entrypoint.name, entrypoint.load()

File pygments/styles/autumn.py

View file
  • Ignore whitespace
     styles = {
         Comment:                    "italic #aaaaaa",
         Comment.Preproc:            "noitalic #4c8317",
+        Comment.Special:            "italic #0000aa",
 
         Keyword:                    "#0000aa",
         Keyword.Type:               "#00aaaa",

File pygments/styles/borland.py

View file
  • Ignore whitespace
     styles = {
         Comment:                'italic #008800',
         Comment.Preproc:        'noitalic',
+        Comment.Special:        'noitalic bold',
 
         String:                 '#0000FF',
         Number:                 '#0000FF',

File pygments/styles/colorful.py

View file
  • Ignore whitespace
     styles = {
         Comment:                   "#888",
         Comment.Preproc:           "#579",
+        Comment.Special:           "bold #cc0000",
 
         Keyword:                   "bold #080",
         Keyword.Pseudo:            "#038",

File pygments/styles/default.py

View file
  • Ignore whitespace
     styles = {
         Comment:                   "italic #008800",
         Comment.Preproc:           "noitalic",
+        Comment.Special:           "noitalic bold",
 
         Keyword:                   "bold #AA22FF",
         Keyword.Pseudo:            "nobold",

File pygments/styles/friendly.py

View file
  • Ignore whitespace
     styles = {
         Comment:                   "italic #60a0b0",
         Comment.Preproc:           "noitalic #007020",
+        Comment.Special:           "noitalic bg:#fff0f0",
 
         Keyword:                   "bold #007020",
         Keyword.Pseudo:            "nobold",

File pygments/styles/manni.py

View file
  • Ignore whitespace
     styles = {
         Comment:            'italic #0099FF',
         Comment.Preproc:    'noitalic #009999',
+        Comment.Special:    'bold',
 
         Keyword:            'bold #006699',
         Keyword.Pseudo:     'nobold',

File pygments/styles/murphy.py

View file
  • Ignore whitespace
     styles = {
         Comment:                   "#666 italic",
         Comment.Preproc:           "#579 noitalic",
+        Comment.Special:           "#c00 bold",
 
         Keyword:                   "bold #289",
         Keyword.Pseudo:            "#08f",

File pygments/styles/native.py

View file
  • Ignore whitespace
 
         Comment:            'italic #999999',
         Comment.Preproc:    'noitalic bold #cd2828',
+        Comment.Special:    'noitalic bold #e50808 bg:#520000',
 
         Keyword:            'bold #6ab825',
         Keyword.Pseudo:     'nobold',

File pygments/styles/pastie.py

View file
  • Ignore whitespace
     styles = {
         Comment:                '#888888',
         Comment.Preproc:        'bold #cc0000',
+        Comment.Special:        'bg:#fff0f0 bold #cc0000',
 
         String:                 'bg:#fff0f0 #dd2200',
         String.Regex:           'bg:#fff0ff #008800',
         Name.Exception:         'bold #bb0066',
         Name.Function:          'bold #0066bb',
         Name.Property:          'bold #336699',
-        Name.Module:            'bold #bb0066',
+        Name.Namespace:         'bold #bb0066',
         Name.Builtin:           '#003388',
         Name.Variable:          '#336699',
         Name.Variable.Class:    '#336699',

File pygments/styles/perldoc.py

View file
  • Ignore whitespace
     styles = {
         Comment:                '#228B22',
         Comment.Preproc:        '#1e889b',
+        Comment.Special:        '#8B008B bold',
 
         String:                 '#CD5555',
         String.Heredoc:         '#1c7e71 italic',

File pygments/styles/trac.py

View file
  • Ignore whitespace
     styles = {
         Comment:                'italic #999988',
         Comment.Preproc:        'bold noitalic #999999',
+        Comment.Special:        'bold #999999',
 
         Operator:               'bold',
 
         Name.Class:             'bold #445588',
         Name.Exception:         'bold #990000',
         Name.Namespace:         '#555555',
-        Name.Variable:          '#ff99ff',
-        Name.Constant:          '#ff99ff',
+        Name.Variable:          '#008080',
+        Name.Constant:          '#008080',
         Name.Tag:               '#000080',
         Name.Attribute:         '#008080',
         Name.Entity:            '#800080',

File pygments/token.py

View file
  • Ignore whitespace
         buf.reverse()
         return buf
 
+    def __contains__(self, val):
+        return self is val or (
+            type(val) is self.__class__ and
+            val[:len(self)] == self
+        )
+
     def __getattr__(self, val):
         if not val or not val[0].isupper():
             return tuple.__getattr__(self, val)

File pygments/util.py

View file
  • Ignore whitespace
         return False
     else:
         raise OptionError('Invalid value %r for option %s; use '
-                          '1/0, yes/no, true/false, on/off' %
-                          string, optname)
+                          '1/0, yes/no, true/false, on/off' % (
+                          string, optname))
 
 
 def get_int_opt(options, optname, default=None):
         return int(string)
     except ValueError:
         raise OptionError('Invalid value %r for option %s; you '
-                          'must give an integer value' %
-                          string, optname)
+                          'must give an integer value' % (
+                          string, optname))
 
 
 def get_list_opt(options, optname, default=None):
         return list(val)
     else:
         raise OptionError('Invalid value %r for option %s; you '
-                          'must give a list value' %
-                          val, optname)
+                          'must give a list value' % (
+                          val, optname))
 
 
 def make_analysator(f):