view MoinMoin/support/pygments/formatters/ @ 6009:b48a69886ca4

upgrade bundled pygments to 1.6
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 05 Jan 2014 02:49:41 +0100
parents 74fa6f714526
children 815981fad7fd
line wrap: on
line source

# -*- coding: utf-8 -*-

    A formatter that generates RTF files.

    :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.

from pygments.formatter import Formatter

__all__ = ['RtfFormatter']

class RtfFormatter(Formatter):
    Format tokens as RTF markup. This formatter automatically outputs full RTF
    documents with color information and other useful stuff. Perfect for Copy and
    Paste into Microsoft® Word® documents.

    *New in Pygments 0.6.*

    Additional options accepted:

        The style to use, can be a string or a Style subclass (default:

        The used font famliy, for example ``Bitstream Vera Sans``. Defaults to
        some generic font which is supposed to have fixed width.
    name = 'RTF'
    aliases = ['rtf']
    filenames = ['*.rtf']

    unicodeoutput = False

    def __init__(self, **options):
        Additional options accepted:

            Name of the font used. Could for example be ``'Courier New'``
            to further specify the default which is ``'\fmodern'``. The RTF
            specification claims that ``\fmodern`` are "Fixed-pitch serif
            and sans serif fonts". Hope every RTF implementation thinks
            the same about modern...
        Formatter.__init__(self, **options)
        self.fontface = options.get('fontface') or ''

    def _escape(self, text):
        return text.replace('\\', '\\\\') \
                   .replace('{', '\\{') \
                   .replace('}', '\\}')

    def _escape_text(self, text):
        # empty strings, should give a small performance improvment
        if not text:
            return ''

        # escape text
        text = self._escape(text)
        if self.encoding in ('utf-8', 'utf-16', 'utf-32'):
            encoding = 'iso-8859-15'
            encoding = self.encoding or 'iso-8859-15'

        buf = []
        for c in text:
            if ord(c) > 128:
                ansic = c.encode(encoding, 'ignore') or '?'
                if ord(ansic) > 128:
                    ansic = '\\\'%x' % ord(ansic)
                    ansic = c
                buf.append(r'\ud{\u%d%s}' % (ord(c), ansic))

        return ''.join(buf).replace('\n', '\\par\n')

    def format_unencoded(self, tokensource, outfile):
        # rtf 1.8 header
                      r'{\colortbl;' % (self.fontface and
                                        ' ' + self._escape(self.fontface) or

        # convert colors and save them in a mapping to access them later.
        color_mapping = {}
        offset = 1
        for _, style in
            for color in style['color'], style['bgcolor'], style['border']:
                if color and color not in color_mapping:
                    color_mapping[color] = offset
                    outfile.write(r'\red%d\green%d\blue%d;' % (
                        int(color[0:2], 16),
                        int(color[2:4], 16),
                        int(color[4:6], 16)
                    offset += 1

        # highlight stream
        for ttype, value in tokensource:
            while not and ttype.parent:
                ttype = ttype.parent
            style =
            buf = []
            if style['bgcolor']:
                buf.append(r'\cb%d' % color_mapping[style['bgcolor']])
            if style['color']:
                buf.append(r'\cf%d' % color_mapping[style['color']])
            if style['bold']:
            if style['italic']:
            if style['underline']:
            if style['border']:
                buf.append(r'\chbrdr\chcfpat%d' %
            start = ''.join(buf)
            if start:
                outfile.write('{%s ' % start)
            if start: