~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/support/pygments/formatters/rtf.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080622211713-inlv5k4eifxckelr
Import upstream version 1.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
"""
3
 
    pygments.formatters.rtf
4
 
    ~~~~~~~~~~~~~~~~~~~~~~~
5
 
 
6
 
    A formatter that generates RTF files.
7
 
 
8
 
    :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
9
 
    :license: BSD, see LICENSE for details.
10
 
"""
11
 
 
12
 
from pygments.formatter import Formatter
13
 
 
14
 
 
15
 
__all__ = ['RtfFormatter']
16
 
 
17
 
 
18
 
class RtfFormatter(Formatter):
19
 
    """
20
 
    Format tokens as RTF markup. This formatter automatically outputs full RTF
21
 
    documents with color information and other useful stuff. Perfect for Copy and
22
 
    Paste into Microsoft® Word® documents.
23
 
 
24
 
    *New in Pygments 0.6.*
25
 
 
26
 
    Additional options accepted:
27
 
 
28
 
    `style`
29
 
        The style to use, can be a string or a Style subclass (default:
30
 
        ``'default'``).
31
 
 
32
 
    `fontface`
33
 
        The used font famliy, for example ``Bitstream Vera Sans``. Defaults to
34
 
        some generic font which is supposed to have fixed width.
35
 
    """
36
 
    name = 'RTF'
37
 
    aliases = ['rtf']
38
 
    filenames = ['*.rtf']
39
 
 
40
 
    unicodeoutput = False
41
 
 
42
 
    def __init__(self, **options):
43
 
        """
44
 
        Additional options accepted:
45
 
 
46
 
        ``fontface``
47
 
            Name of the font used. Could for example be ``'Courier New'``
48
 
            to further specify the default which is ``'\fmodern'``. The RTF
49
 
            specification claims that ``\fmodern`` are "Fixed-pitch serif
50
 
            and sans serif fonts". Hope every RTF implementation thinks
51
 
            the same about modern...
52
 
        """
53
 
        Formatter.__init__(self, **options)
54
 
        self.fontface = options.get('fontface') or ''
55
 
 
56
 
    def _escape(self, text):
57
 
        return text.replace('\\', '\\\\') \
58
 
                   .replace('{', '\\{') \
59
 
                   .replace('}', '\\}')
60
 
 
61
 
    def _escape_text(self, text):
62
 
        # empty strings, should give a small performance improvment
63
 
        if not text:
64
 
            return ''
65
 
 
66
 
        # escape text
67
 
        text = self._escape(text)
68
 
        if self.encoding in ('utf-8', 'utf-16', 'utf-32'):
69
 
            encoding = 'iso-8859-15'
70
 
        else:
71
 
            encoding = self.encoding or 'iso-8859-15'
72
 
 
73
 
        buf = []
74
 
        for c in text:
75
 
            if ord(c) > 128:
76
 
                ansic = c.encode(encoding, 'ignore') or '?'
77
 
                if ord(ansic) > 128:
78
 
                    ansic = '\\\'%x' % ord(ansic)
79
 
                else:
80
 
                    ansic = c
81
 
                buf.append(r'\ud{\u%d%s}' % (ord(c), ansic))
82
 
            else:
83
 
                buf.append(str(c))
84
 
 
85
 
        return ''.join(buf).replace('\n', '\\par\n')
86
 
 
87
 
    def format_unencoded(self, tokensource, outfile):
88
 
        # rtf 1.8 header
89
 
        outfile.write(r'{\rtf1\ansi\deff0'
90
 
                      r'{\fonttbl{\f0\fmodern\fprq1\fcharset0%s;}}'
91
 
                      r'{\colortbl;' % (self.fontface and
92
 
                                        ' ' + self._escape(self.fontface) or
93
 
                                        ''))
94
 
 
95
 
        # convert colors and save them in a mapping to access them later.
96
 
        color_mapping = {}
97
 
        offset = 1
98
 
        for _, style in self.style:
99
 
            for color in style['color'], style['bgcolor'], style['border']:
100
 
                if color and color not in color_mapping:
101
 
                    color_mapping[color] = offset
102
 
                    outfile.write(r'\red%d\green%d\blue%d;' % (
103
 
                        int(color[0:2], 16),
104
 
                        int(color[2:4], 16),
105
 
                        int(color[4:6], 16)
106
 
                    ))
107
 
                    offset += 1
108
 
        outfile.write(r'}\f0')
109
 
 
110
 
        # highlight stream
111
 
        for ttype, value in tokensource:
112
 
            while not self.style.styles_token(ttype) and ttype.parent:
113
 
                ttype = ttype.parent
114
 
            style = self.style.style_for_token(ttype)
115
 
            buf = []
116
 
            if style['bgcolor']:
117
 
                buf.append(r'\cb%d' % color_mapping[style['bgcolor']])
118
 
            if style['color']:
119
 
                buf.append(r'\cf%d' % color_mapping[style['color']])
120
 
            if style['bold']:
121
 
                buf.append(r'\b')
122
 
            if style['italic']:
123
 
                buf.append(r'\i')
124
 
            if style['underline']:
125
 
                buf.append(r'\ul')
126
 
            if style['border']:
127
 
                buf.append(r'\chbrdr\chcfpat%d' %
128
 
                           color_mapping[style['border']])
129
 
            start = ''.join(buf)
130
 
            if start:
131
 
                outfile.write('{%s ' % start)
132
 
            outfile.write(self._escape_text(value))
133
 
            if start:
134
 
                outfile.write('}')
135
 
 
136
 
        outfile.write('}')