eric6/ThirdParty/Pygments/pygments/formatters/rtf.py

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

eric ide

mercurial