summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--docs/src/tokens.txt8
-rw-r--r--pygments/filters/__init__.py169
-rw-r--r--pygments/formatters/terminal.py3
-rw-r--r--pygments/lexers/functional.py6
-rw-r--r--pygments/styles/autumn.py80
-rw-r--r--pygments/styles/borland.py4
-rw-r--r--pygments/styles/colorful.py4
-rw-r--r--pygments/styles/default.py3
-rw-r--r--pygments/styles/emacs.py3
-rw-r--r--pygments/styles/friendly.py3
-rw-r--r--pygments/styles/fruity.py3
-rw-r--r--pygments/styles/manni.py3
-rw-r--r--pygments/styles/murphy.py3
-rw-r--r--pygments/styles/native.py3
-rw-r--r--pygments/styles/pastie.py3
-rw-r--r--pygments/styles/perldoc.py3
-rw-r--r--pygments/styles/trac.py3
-rw-r--r--pygments/token.py2
-rw-r--r--tests/run.py4
-rw-r--r--tests/test_basic_api.py36
21 files changed, 262 insertions, 88 deletions
diff --git a/CHANGES b/CHANGES
index b3cbee21..b73bb71f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,10 @@ Version 0.8 (in development)
----------------------------
(codename to be selected, released May XX, 2007)
+- Added a `RaiseOnErrorTokenFilter` that raises an exception when the
+ lexer generates an error token, and a `VisibleWhitespaceFilter` that
+ converts whitespace (spaces, tabs, newlines) into visible characters.
+
- Fixed the `do_insertions()` helper function to yield correct indices.
- The ReST lexer now automatically highlights source code blocks in
diff --git a/docs/src/tokens.txt b/docs/src/tokens.txt
index f98b4d6e..3a1cd4af 100644
--- a/docs/src/tokens.txt
+++ b/docs/src/tokens.txt
@@ -57,8 +57,9 @@ For some tokens aliases are already defined:
Inside the `pygments.token` module the following aliases are defined:
-============= ============================ ==================================
+============= ============================ ====================================
`Text` `Token.Text` for any type of text data
+`Whitespace` `Token.Text.Whitespace` for specially highlighted whitespace
`Error` `Token.Error` represents lexer errors
`Other` `Token.Other` special token for data not
matched by a parser (e.g. HTML
@@ -73,7 +74,10 @@ Inside the `pygments.token` module the following aliases are defined:
`Comment` `Token.Comment` any kind of comments
`Generic` `Token.Generic` generic tokens (have a look at
the explanation below)
-============= ============================ ==================================
+============= ============================ ====================================
+
+The `Whitespace` token type is new in Pygments 0.8. It is used only by the
+`VisibleWhitespaceFilter` currently.
Normally you just create token types using the already defined aliases. For each
of those token aliases, a number of subtypes exists (excluding the special tokens
diff --git a/pygments/filters/__init__.py b/pygments/filters/__init__.py
index 4b4bd28d..3df10a4f 100644
--- a/pygments/filters/__init__.py
+++ b/pygments/filters/__init__.py
@@ -15,10 +15,11 @@ except NameError:
from sets import Set as set
import re
-from pygments.token import String, Comment, Keyword, Name, Error, \
+from pygments.token import String, Comment, Keyword, Name, Error, Whitespace, \
string_to_tokentype
from pygments.filter import Filter
-from pygments.util import get_list_opt, ClassNotFound
+from pygments.util import get_list_opt, get_int_opt, get_bool_opt, \
+ ClassNotFound, OptionError
from pygments.plugin import find_plugin_filters
@@ -56,14 +57,30 @@ def get_all_filters():
yield name
+def _replace_special(ttype, value, regex, specialttype,
+ replacefunc=lambda x: x):
+ last = 0
+ for match in regex.finditer(value):
+ start, end = match.start(), match.end()
+ if start != last:
+ yield ttype, value[last:start]
+ yield specialttype, replacefunc(value[start:end])
+ last = end
+ if last != len(value):
+ yield ttype, value[last:]
+
+
class CodeTagFilter(Filter):
"""
Highlight 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.
+ Options accepted:
+
+ `codetags` : list of strings
+ A list of strings that are flagged as code tags. The default is to
+ highlight ``XXX``, ``TODO``, ``BUG`` and ``NOTE``.
"""
+
def __init__(self, **options):
Filter.__init__(self, **options)
tags = get_list_opt(options, 'codetags',
@@ -73,39 +90,38 @@ class CodeTagFilter(Filter):
]))
def filter(self, lexer, stream):
+ regex = self.tag_re
for ttype, value in stream:
if ttype in String.Doc or \
ttype in Comment and \
ttype not in Comment.Preproc:
- last = 0
- for match in self.tag_re.finditer(value):
- start = match.start()
- end = match.end()
- if start != last:
- yield ttype, value[last:start]
- yield Comment.Special, value[start:end]
- last = end
- if last != len(value):
- yield ttype, value[last:]
- continue
- yield ttype, value
+ for sttype, svalue in _replace_special(ttype, value, regex,
+ Comment.Special):
+ yield sttype, svalue
+ else:
+ yield ttype, value
class KeywordCaseFilter(Filter):
"""
- Convert keywords to ``lower``, ``upper`` or ``capitalize`` which means
- first letter uppercase, rest lowercase.
+ Convert keywords to lowercase or uppercase or capitalize them, which
+ means first letter uppercase, rest lowercase.
This can be useful e.g. if you highlight Pascal code and want to adapt the
- code to your styleguide. The default is ``lower``, override that by
- providing the `case` parameter.
+ code to your styleguide.
+
+ Options accepted:
+
+ `case` : string
+ The casing to convert keywords to. Must be one of ``'lower'``,
+ ``'upper'`` or ``'capitalize'``. The default is ``'lower'``.
"""
def __init__(self, **options):
Filter.__init__(self, **options)
case = options.get('case', 'lower')
if case not in ('lower', 'upper', 'capitalize'):
- raise TypeError('unknown conversion method %r' % case)
+ raise OptionError('unknown conversion method %r' % case)
self.convert = getattr(unicode, case)
def filter(self, lexer, stream):
@@ -129,6 +145,16 @@ class NameHighlightFilter(Filter):
This would highlight the names "foo", "bar" and "baz"
as functions. `Name.Function` is the default token type.
+
+ Options accepted:
+
+ `names` : list of strings
+ A list of names that should be given the different token type.
+ There is no default.
+ `tokentype` : TokenType or string
+ A token type or a string containing a token type name that is
+ used for highlighting the strings in `names`. The default is
+ `Name.Function`.
"""
def __init__(self, **options):
@@ -153,22 +179,115 @@ class ErrorToken(Exception):
class RaiseOnErrorTokenFilter(Filter):
"""
- Raise an ``pygments.filters.ErrorToken`` exception when the lexer
- generates an error token.
+ Raise an exception when the lexer generates an error token.
+
+ Options accepted:
+
+ `excclass` : Exception class
+ The exception class to raise.
+ The default is `pygments.filters.ErrorToken`.
*New in Pygments 0.8.*
"""
+ def __init__(self, **options):
+ Filter.__init__(self, **options)
+ self.exception = options.get('excclass', ErrorToken)
+ try:
+ # issubclass() will raise TypeError if first argument is not a class
+ if not issubclass(self.exception, Exception):
+ raise TypeError
+ except TypeError:
+ raise OptionError('excclass option is not an exception class')
+
def filter(self, lexer, stream):
for ttype, value in stream:
if ttype is Error:
- raise ErrorToken(value)
+ raise self.exception(value)
yield ttype, value
+class VisibleWhitespaceFilter(Filter):
+ """
+ Convert tabs, newlines and/or spaces to visible characters.
+
+ Options accepted:
+
+ `spaces` : string or bool
+ If this is a one-character string, spaces will be replaces by this string.
+ If it is another true value, spaces will be replaced by ``·`` (unicode
+ MIDDLE DOT). If it is a false value, spaces will not be replaced. The
+ default is ``False``.
+ `tabs` : string or bool
+ The same as for `spaces`, but the default replacement character is ``»``
+ (unicode RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK). The default value
+ is ``False``. Note: this will not work if the `tabsize` option for the
+ lexer is nonzero, as tabs will already have been expanded then.
+ `tabsize` : int
+ If tabs are to be replaced by this filter, this is the total number of
+ characters that a tab should be expanded to. The default is ``8``.
+ `newlines` : string or bool
+ The same as for `spaces`, but the default replacement character is ``¶``
+ (unicode PILCROW SIGN). The default value is ``False``.
+ `wstokentype` : bool
+ If true, give whitespace the special `Whitespace` token type. This allows
+ styling the visible whitespace differently (e.g. greyed out), but it can
+ disrupt background colors. The default is ``True``
+
+ *New in Pygments 0.8.*
+ """
+
+ def __init__(self, **options):
+ Filter.__init__(self, **options)
+ for name, default in {'spaces': u'·', 'tabs': u'»', 'newlines': u'¶'}.items():
+ opt = options.get(name, False)
+ if isinstance(opt, basestring) and len(opt) == 1:
+ setattr(self, name, opt)
+ else:
+ setattr(self, name, (opt and default or ''))
+ tabsize = get_int_opt(options, 'tabsize', 8)
+ if self.tabs:
+ self.tabs += ' '*(tabsize-1)
+ if self.newlines:
+ self.newlines += '\n'
+ self.wstt = get_bool_opt(options, 'wstokentype', True)
+
+ def filter(self, lexer, stream):
+ if self.wstt:
+ spaces = self.spaces or ' '
+ tabs = self.tabs or '\t'
+ newlines = self.newlines or '\n'
+ regex = re.compile(r'\s')
+ def replacefunc(wschar):
+ if wschar == ' ':
+ return spaces
+ elif wschar == '\t':
+ return tabs
+ elif wschar == '\n':
+ return newlines
+ return wschar
+
+ for ttype, value in stream:
+ for sttype, svalue in _replace_special(ttype, value, regex,
+ Whitespace, replacefunc):
+ yield sttype, svalue
+ else:
+ spaces, tabs, newlines = self.spaces, self.tabs, self.newlines
+ # simpler processing
+ for ttype, value in stream:
+ if spaces:
+ value = value.replace(' ', spaces)
+ if tabs:
+ value = value.replace('\t', tabs)
+ if newlines:
+ value = value.replace('\n', newlines)
+ yield ttype, value
+
+
FILTERS = {
'codetagify': CodeTagFilter,
'keywordcase': KeywordCaseFilter,
'highlight': NameHighlightFilter,
'raiseonerror': RaiseOnErrorTokenFilter,
+ 'whitespace': VisibleWhitespaceFilter,
}
diff --git a/pygments/formatters/terminal.py b/pygments/formatters/terminal.py
index cad37c7d..adac90df 100644
--- a/pygments/formatters/terminal.py
+++ b/pygments/formatters/terminal.py
@@ -11,7 +11,7 @@
from pygments.formatter import Formatter
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic, Token
+ Number, Operator, Generic, Token, Whitespace
from pygments.console import ansiformat
@@ -23,6 +23,7 @@ __all__ = ['TerminalFormatter']
TERMINAL_COLORS = {
Token: ('', ''),
+ Whitespace: ('lightgray', 'darkgray'),
Comment: ('lightgray', 'darkgray'),
Keyword: ('darkblue', 'blue'),
Keyword.Type: ('teal', 'turquoise'),
diff --git a/pygments/lexers/functional.py b/pygments/lexers/functional.py
index e1e442e2..a248b476 100644
--- a/pygments/lexers/functional.py
+++ b/pygments/lexers/functional.py
@@ -16,9 +16,9 @@ try:
except NameError:
from sets import Set as set
-from pygments.lexer import Lexer, RegexLexer
-from pygments.token import Error, Text, \
- Comment, Operator, Keyword, Name, String, Number, Generic, Punctuation
+from pygments.lexer import RegexLexer
+from pygments.token import Text, Comment, Operator, Keyword, Name, \
+ String, Number, Punctuation
__all__ = ['SchemeLexer', 'HaskellLexer']
diff --git a/pygments/styles/autumn.py b/pygments/styles/autumn.py
index 4508db17..b0862e41 100644
--- a/pygments/styles/autumn.py
+++ b/pygments/styles/autumn.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class AutumnStyle(Style):
@@ -22,42 +22,44 @@ class AutumnStyle(Style):
default_style = ""
styles = {
- Comment: "italic #aaaaaa",
- Comment.Preproc: "noitalic #4c8317",
- Comment.Special: "italic #0000aa",
-
- Keyword: "#0000aa",
- Keyword.Type: "#00aaaa",
-
- Operator.Word: "#0000aa",
-
- Name.Builtin: "#00aaaa",
- Name.Function: "#00aa00",
- Name.Class: "underline #00aa00",
- Name.Namespace: "underline #00aaaa",
- Name.Variable: "#aa0000",
- Name.Constant: "#aa0000",
- Name.Entity: "bold #800",
- Name.Attribute: "#1e90ff",
- Name.Tag: "bold #1e90ff",
- Name.Decorator: "#888888",
-
- String: "#aa5500",
- String.Symbol: "#0000aa",
- String.Regex: "#009999",
-
- Number: "#009999",
-
- Generic.Heading: "bold #000080",
- Generic.Subheading: "bold #800080",
- Generic.Deleted: "#aa0000",
- Generic.Inserted: "#00aa00",
- Generic.Error: "#aa0000",
- Generic.Emph: "italic",
- Generic.Strong: "bold",
- Generic.Prompt: "#555555",
- Generic.Output: "#888888",
- Generic.Traceback: "#aa0000",
-
- Error: "#F00 bg:#FAA"
+ Whitespace: '#bbbbbb',
+
+ Comment: 'italic #aaaaaa',
+ Comment.Preproc: 'noitalic #4c8317',
+ Comment.Special: 'italic #0000aa',
+
+ Keyword: '#0000aa',
+ Keyword.Type: '#00aaaa',
+
+ Operator.Word: '#0000aa',
+
+ Name.Builtin: '#00aaaa',
+ Name.Function: '#00aa00',
+ Name.Class: 'underline #00aa00',
+ Name.Namespace: 'underline #00aaaa',
+ Name.Variable: '#aa0000',
+ Name.Constant: '#aa0000',
+ Name.Entity: 'bold #800',
+ Name.Attribute: '#1e90ff',
+ Name.Tag: 'bold #1e90ff',
+ Name.Decorator: '#888888',
+
+ String: '#aa5500',
+ String.Symbol: '#0000aa',
+ String.Regex: '#009999',
+
+ Number: '#009999',
+
+ Generic.Heading: 'bold #000080',
+ Generic.Subheading: 'bold #800080',
+ Generic.Deleted: '#aa0000',
+ Generic.Inserted: '#00aa00',
+ Generic.Error: '#aa0000',
+ Generic.Emph: 'italic',
+ Generic.Strong: 'bold',
+ Generic.Prompt: '#555555',
+ Generic.Output: '#888888',
+ Generic.Traceback: '#aa0000',
+
+ Error: '#F00 bg:#FAA'
}
diff --git a/pygments/styles/borland.py b/pygments/styles/borland.py
index 696178d3..5763073b 100644
--- a/pygments/styles/borland.py
+++ b/pygments/styles/borland.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class BorlandStyle(Style):
@@ -22,6 +22,8 @@ class BorlandStyle(Style):
default_style = ''
styles = {
+ Whitespace: '#bbbbbb',
+
Comment: 'italic #008800',
Comment.Preproc: 'noitalic',
Comment.Special: 'noitalic bold',
diff --git a/pygments/styles/colorful.py b/pygments/styles/colorful.py
index 16f084e6..83988291 100644
--- a/pygments/styles/colorful.py
+++ b/pygments/styles/colorful.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class ColorfulStyle(Style):
@@ -22,6 +22,8 @@ class ColorfulStyle(Style):
default_style = ""
styles = {
+ Whitespace: "#bbbbbb",
+
Comment: "#888",
Comment.Preproc: "#579",
Comment.Special: "bold #cc0000",
diff --git a/pygments/styles/default.py b/pygments/styles/default.py
index bfa40099..b66d4c95 100644
--- a/pygments/styles/default.py
+++ b/pygments/styles/default.py
@@ -12,7 +12,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class DefaultStyle(Style):
@@ -24,6 +24,7 @@ class DefaultStyle(Style):
default_style = ""
styles = {
+ Whitespace: "#bbbbbb",
Comment: "italic #408080",
Comment.Preproc: "noitalic #BC7A00",
diff --git a/pygments/styles/emacs.py b/pygments/styles/emacs.py
index cf7b2dc8..c27268b8 100644
--- a/pygments/styles/emacs.py
+++ b/pygments/styles/emacs.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class EmacsStyle(Style):
@@ -23,6 +23,7 @@ class EmacsStyle(Style):
default_style = ""
styles = {
+ Whitespace: "#bbbbbb",
Comment: "italic #008800",
Comment.Preproc: "noitalic",
Comment.Special: "noitalic bold",
diff --git a/pygments/styles/friendly.py b/pygments/styles/friendly.py
index b1e95037..95ee3b37 100644
--- a/pygments/styles/friendly.py
+++ b/pygments/styles/friendly.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class FriendlyStyle(Style):
@@ -23,6 +23,7 @@ class FriendlyStyle(Style):
default_style = ""
styles = {
+ Whitespace: "#bbbbbb",
Comment: "italic #60a0b0",
Comment.Preproc: "noitalic #007020",
Comment.Special: "noitalic bg:#fff0f0",
diff --git a/pygments/styles/fruity.py b/pygments/styles/fruity.py
index ba1f388a..95fbcc3e 100644
--- a/pygments/styles/fruity.py
+++ b/pygments/styles/fruity.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Token, Comment, Name, Keyword, \
- Generic, Number, String
+ Generic, Number, String, Whitespace
class FruityStyle(Style):
"""
@@ -21,6 +21,7 @@ class FruityStyle(Style):
background_color = '#111111'
styles = {
+ Whitespace: '#888888',
Token: '#ffffff',
Generic.Output: '#444444 bg:#222222',
Keyword: '#fb660a bold',
diff --git a/pygments/styles/manni.py b/pygments/styles/manni.py
index bdc979e2..c160f873 100644
--- a/pygments/styles/manni.py
+++ b/pygments/styles/manni.py
@@ -14,7 +14,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class ManniStyle(Style):
@@ -25,6 +25,7 @@ class ManniStyle(Style):
background_color = '#f0f3f3'
styles = {
+ Whitespace: '#bbbbbb',
Comment: 'italic #0099FF',
Comment.Preproc: 'noitalic #009999',
Comment.Special: 'bold',
diff --git a/pygments/styles/murphy.py b/pygments/styles/murphy.py
index 06cc795b..5152fe68 100644
--- a/pygments/styles/murphy.py
+++ b/pygments/styles/murphy.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class MurphyStyle(Style):
@@ -22,6 +22,7 @@ class MurphyStyle(Style):
default_style = ""
styles = {
+ Whitespace: "#bbbbbb",
Comment: "#666 italic",
Comment.Preproc: "#579 noitalic",
Comment.Special: "#c00 bold",
diff --git a/pygments/styles/native.py b/pygments/styles/native.py
index c9b290b0..76021a53 100644
--- a/pygments/styles/native.py
+++ b/pygments/styles/native.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic, Token
+ Number, Operator, Generic, Token, Whitespace
class NativeStyle(Style):
@@ -23,6 +23,7 @@ class NativeStyle(Style):
styles = {
Token: '#d0d0d0',
+ Whitespace: '#666666',
Comment: 'italic #999999',
Comment.Preproc: 'noitalic bold #cd2828',
diff --git a/pygments/styles/pastie.py b/pygments/styles/pastie.py
index 49ab9cee..b0332252 100644
--- a/pygments/styles/pastie.py
+++ b/pygments/styles/pastie.py
@@ -13,7 +13,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class PastieStyle(Style):
@@ -24,6 +24,7 @@ class PastieStyle(Style):
default_style = ''
styles = {
+ Whitespace: '#bbbbbb',
Comment: '#888888',
Comment.Preproc: 'bold #cc0000',
Comment.Special: 'bg:#fff0f0 bold #cc0000',
diff --git a/pygments/styles/perldoc.py b/pygments/styles/perldoc.py
index 6ce06624..91e63074 100644
--- a/pygments/styles/perldoc.py
+++ b/pygments/styles/perldoc.py
@@ -13,7 +13,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class PerldocStyle(Style):
@@ -25,6 +25,7 @@ class PerldocStyle(Style):
default_style = ''
styles = {
+ Whitespace: '#bbbbbb',
Comment: '#228B22',
Comment.Preproc: '#1e889b',
Comment.Special: '#8B008B bold',
diff --git a/pygments/styles/trac.py b/pygments/styles/trac.py
index 0e32986f..d6bd4cf1 100644
--- a/pygments/styles/trac.py
+++ b/pygments/styles/trac.py
@@ -11,7 +11,7 @@
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
- Number, Operator, Generic
+ Number, Operator, Generic, Whitespace
class TracStyle(Style):
@@ -22,6 +22,7 @@ class TracStyle(Style):
default_style = ''
styles = {
+ Whitespace: '#bbbbbb',
Comment: 'italic #999988',
Comment.Preproc: 'bold noitalic #999999',
Comment.Special: 'bold #999999',
diff --git a/pygments/token.py b/pygments/token.py
index e4b81e55..66183955 100644
--- a/pygments/token.py
+++ b/pygments/token.py
@@ -56,6 +56,7 @@ Token = _TokenType()
# Special token types
Text = Token.Text
+Whitespace = Text.Whitespace
Error = Token.Error
# Text that doesn't belong to this lexer (e.g. HTML in PHP)
Other = Token.Other
@@ -122,6 +123,7 @@ STANDARD_TYPES = {
Token: '',
Text: '',
+ Whitespace: 'w',
Error: 'err',
Other: 'x',
diff --git a/tests/run.py b/tests/run.py
index bd285c2b..8a78af5c 100644
--- a/tests/run.py
+++ b/tests/run.py
@@ -77,8 +77,8 @@ def run_tests(with_coverage=False):
WIDTH = 70
print >>sys.stderr, \
- ('Pygments Test Suite running %s, stand by...' %
- (with_coverage and "with coverage analysis" or "")).center(WIDTH)
+ ('Pygments Test Suite running%s, stand by...' %
+ (with_coverage and " with coverage analysis" or "")).center(WIDTH)
print >>sys.stderr, ('(using Python %s)' % sys.version.split()[0]).center(WIDTH)
print >>sys.stderr, '='*WIDTH
diff --git a/tests/test_basic_api.py b/tests/test_basic_api.py
index d05a29c5..805f3104 100644
--- a/tests/test_basic_api.py
+++ b/tests/test_basic_api.py
@@ -71,15 +71,43 @@ class LexersTest(unittest.TestCase):
a(isinstance(x, lexers.PythonLexer))
ae(x.options["opt"], "val")
- def test_filters(self):
+
+class FiltersTest(unittest.TestCase):
+
+ def test_basic(self):
+ filter_args = {
+ 'whitespace': {'spaces': True, 'tabs': True, 'newlines': True},
+ 'highlight': {'names': ['isinstance', 'lexers', 'x']},
+ }
for x in filters.FILTERS.keys():
lx = lexers.PythonLexer()
- lx.add_filter(x)
+ lx.add_filter(x, **filter_args.get(x, {}))
text = file(os.path.join(testdir, testfile)).read().decode('utf-8')
tokens = list(lx.get_tokens(text))
roundtext = ''.join([t[1] for t in tokens])
- self.assertEquals(roundtext, text,
- "lexer roundtrip with %s filter failed" % x)
+ if x not in ('whitespace', 'keywordcase'):
+ # these filters change the text
+ self.assertEquals(roundtext, text,
+ "lexer roundtrip with %s filter failed" % x)
+
+ def test_raiseonerror(self):
+ lx = lexers.PythonLexer()
+ lx.add_filter('raiseonerror', excclass=RuntimeError)
+ self.assertRaises(RuntimeError, list, lx.get_tokens('$'))
+
+ def test_whitespace(self):
+ lx = lexers.PythonLexer()
+ lx.add_filter('whitespace', spaces='%')
+ text = file(os.path.join(testdir, testfile)).read().decode('utf-8')
+ lxtext = ''.join([t[1] for t in list(lx.get_tokens(text))])
+ self.failIf(' ' in lxtext)
+
+ def test_keywordcase(self):
+ lx = lexers.PythonLexer()
+ lx.add_filter('keywordcase', case='capitalize')
+ text = file(os.path.join(testdir, testfile)).read().decode('utf-8')
+ lxtext = ''.join([t[1] for t in list(lx.get_tokens(text))])
+ self.assert_('Def' in lxtext and 'Class' in lxtext)
class FormattersTest(unittest.TestCase):