Processors are the core of Typus. Multiple processors are nested and chained in one single function to do things which may depend on the result returned by inner processors. Say, we set EscapeHtml and MyTrimProcessor, this is how it works:

extract html tags
    pass text further if condition is true
        do something and return
    return the text
put tags back and return

In python:

from typus.core import TypusCore
from typus.processors import BaseProcessor, EscapeHtml

class MyTrimProcessor(BaseProcessor):
    def __call__(self, func):
        def inner(text, *args, **kwargs):
            # When processor is initiated it gets typus instance
            # as the first argument so you can access to it's configuration
            # any time
            if self.typus.trim:
                trimmed = text.strip()
                trimmed = text
            return func(trimmed, *args, **kwargs)
        return inner

class MyTypus(TypusCore):
    # This becomes a single function. EscapeHtml goes first
    processors = (EscapeHtml, MyTrimProcessor)

    # Set it `False` to disable trimming
    trim = True

my_typus = MyTypus()
assert my_typus('    test    ') == 'test'

Processors can be configured with Mixins.

Built-in processors

class typus.processors.EscapePhrases(typus)

Escapes phrases which should never be processed.

>>> en_typus('Typus turns `(c)` into "(c)"', escape_phrases=['`(c)`'])
'Typus turns `(c)` into “©”'

Also there is a little helper typus.utils.splinter() which should help you to split string into the phrases.

class typus.processors.EscapeHtml(typus)

Extracts html tags and puts them back after.

>>> en_typus('Typus turns <code>(c)</code> into "(c)"')
'Typus turns <code>(c)</code> into “©”'


Doesn’t support nested <code> tags.

class typus.processors.Quotes(*args, **kwargs)

Replaces regular quotes with typographic ones. Supports any level nesting, but doesn’t work well with minutes 1' and inches 1" within the quotes, that kind of cases are ignored. Use it with typus.mixins.RuQuotes or typus.mixins.EnQuotes or provide Typus attributes loq, roq, leq, req with custom quotes.

>>> en_typus('Say "what" again!')
'Say “what” again!'
class typus.processors.Expressions(*args, **kwargs)

Provides regular expressions support. Looks for expressions list attribute in Typus with expressions name, compiles and runs them on every Typus call.

>>> from typus.core import TypusCore
>>> from typus.processors import Expressions
>>> class MyExpressionsMixin:
...     def expr_bold_price(self):
...         expr = (
...             (r'(\$\d+)', r'<b>\1</b>'),
...         )
...         return expr
>>> class MyTypus(MyExpressionsMixin, TypusCore):
...     expressions = ('bold_price', )  # no prefix `expr_`!
...     processors = (Expressions, )
>>> my_typus = MyTypus()  # `expr_bold_price` is compiled and stored
>>> my_typus('Get now just for $1000!')
'Get now just for <b>$1000</b>!'


Expression is a pair of regex and replace strings. Regex strings are compiled with typus.utils.re_compile() with a bunch of flags: unicode, case-insensitive, etc. If that doesn’t suit for you pass your own flags as a third member of the tuple: (regex, replace, re.I).