pygmentize 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/lib/pygments.rb +23 -0
- data/pygmentize.gemspec +11 -0
- data/test/pygments.rb +19 -0
- data/vendor/pygmentize.py +7 -0
- data/vendor/pygments/AUTHORS +73 -0
- data/vendor/pygments/LICENSE +25 -0
- data/vendor/pygments/__init__.py +91 -0
- data/vendor/pygments/__init__.pyc +0 -0
- data/vendor/pygments/cmdline.py +430 -0
- data/vendor/pygments/cmdline.pyc +0 -0
- data/vendor/pygments/console.py +74 -0
- data/vendor/pygments/console.pyc +0 -0
- data/vendor/pygments/filter.py +74 -0
- data/vendor/pygments/filter.pyc +0 -0
- data/vendor/pygments/filters/__init__.py +357 -0
- data/vendor/pygments/filters/__init__.pyc +0 -0
- data/vendor/pygments/formatter.py +92 -0
- data/vendor/pygments/formatter.pyc +0 -0
- data/vendor/pygments/formatters/__init__.py +68 -0
- data/vendor/pygments/formatters/__init__.pyc +0 -0
- data/vendor/pygments/formatters/_mapping.py +92 -0
- data/vendor/pygments/formatters/_mapping.pyc +0 -0
- data/vendor/pygments/formatters/bbcode.py +109 -0
- data/vendor/pygments/formatters/bbcode.pyc +0 -0
- data/vendor/pygments/formatters/html.py +723 -0
- data/vendor/pygments/formatters/html.pyc +0 -0
- data/vendor/pygments/formatters/img.py +553 -0
- data/vendor/pygments/formatters/img.pyc +0 -0
- data/vendor/pygments/formatters/latex.py +354 -0
- data/vendor/pygments/formatters/latex.pyc +0 -0
- data/vendor/pygments/formatters/other.py +117 -0
- data/vendor/pygments/formatters/other.pyc +0 -0
- data/vendor/pygments/formatters/rtf.py +136 -0
- data/vendor/pygments/formatters/rtf.pyc +0 -0
- data/vendor/pygments/formatters/svg.py +154 -0
- data/vendor/pygments/formatters/svg.pyc +0 -0
- data/vendor/pygments/formatters/terminal.py +109 -0
- data/vendor/pygments/formatters/terminal.pyc +0 -0
- data/vendor/pygments/formatters/terminal256.py +219 -0
- data/vendor/pygments/formatters/terminal256.pyc +0 -0
- data/vendor/pygments/lexer.py +660 -0
- data/vendor/pygments/lexer.pyc +0 -0
- data/vendor/pygments/lexers/__init__.py +226 -0
- data/vendor/pygments/lexers/__init__.pyc +0 -0
- data/vendor/pygments/lexers/_asybuiltins.py +1645 -0
- data/vendor/pygments/lexers/_clbuiltins.py +232 -0
- data/vendor/pygments/lexers/_luabuiltins.py +256 -0
- data/vendor/pygments/lexers/_mapping.py +234 -0
- data/vendor/pygments/lexers/_mapping.pyc +0 -0
- data/vendor/pygments/lexers/_phpbuiltins.py +3389 -0
- data/vendor/pygments/lexers/_vimbuiltins.py +3 -0
- data/vendor/pygments/lexers/agile.py +1485 -0
- data/vendor/pygments/lexers/agile.pyc +0 -0
- data/vendor/pygments/lexers/asm.py +353 -0
- data/vendor/pygments/lexers/compiled.py +2365 -0
- data/vendor/pygments/lexers/dotnet.py +355 -0
- data/vendor/pygments/lexers/functional.py +756 -0
- data/vendor/pygments/lexers/functional.pyc +0 -0
- data/vendor/pygments/lexers/math.py +461 -0
- data/vendor/pygments/lexers/other.py +2297 -0
- data/vendor/pygments/lexers/parsers.py +695 -0
- data/vendor/pygments/lexers/special.py +100 -0
- data/vendor/pygments/lexers/special.pyc +0 -0
- data/vendor/pygments/lexers/templates.py +1387 -0
- data/vendor/pygments/lexers/text.py +1586 -0
- data/vendor/pygments/lexers/web.py +1619 -0
- data/vendor/pygments/lexers/web.pyc +0 -0
- data/vendor/pygments/plugin.py +74 -0
- data/vendor/pygments/plugin.pyc +0 -0
- data/vendor/pygments/scanner.py +104 -0
- data/vendor/pygments/style.py +117 -0
- data/vendor/pygments/style.pyc +0 -0
- data/vendor/pygments/styles/__init__.py +68 -0
- data/vendor/pygments/styles/__init__.pyc +0 -0
- data/vendor/pygments/styles/autumn.py +65 -0
- data/vendor/pygments/styles/borland.py +51 -0
- data/vendor/pygments/styles/bw.py +49 -0
- data/vendor/pygments/styles/colorful.py +81 -0
- data/vendor/pygments/styles/default.py +73 -0
- data/vendor/pygments/styles/default.pyc +0 -0
- data/vendor/pygments/styles/emacs.py +72 -0
- data/vendor/pygments/styles/friendly.py +72 -0
- data/vendor/pygments/styles/fruity.py +43 -0
- data/vendor/pygments/styles/manni.py +75 -0
- data/vendor/pygments/styles/monokai.py +106 -0
- data/vendor/pygments/styles/murphy.py +80 -0
- data/vendor/pygments/styles/native.py +65 -0
- data/vendor/pygments/styles/pastie.py +75 -0
- data/vendor/pygments/styles/perldoc.py +69 -0
- data/vendor/pygments/styles/tango.py +141 -0
- data/vendor/pygments/styles/trac.py +63 -0
- data/vendor/pygments/styles/vim.py +63 -0
- data/vendor/pygments/styles/vs.py +38 -0
- data/vendor/pygments/token.py +198 -0
- data/vendor/pygments/token.pyc +0 -0
- data/vendor/pygments/unistring.py +130 -0
- data/vendor/pygments/unistring.pyc +0 -0
- data/vendor/pygments/util.py +226 -0
- data/vendor/pygments/util.pyc +0 -0
- metadata +166 -0
Binary file
|
@@ -0,0 +1,553 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
pygments.formatters.img
|
4
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
5
|
+
|
6
|
+
Formatter for Pixmap output.
|
7
|
+
|
8
|
+
:copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
|
9
|
+
:license: BSD, see LICENSE for details.
|
10
|
+
"""
|
11
|
+
|
12
|
+
import sys
|
13
|
+
from commands import getstatusoutput
|
14
|
+
|
15
|
+
from pygments.formatter import Formatter
|
16
|
+
from pygments.util import get_bool_opt, get_int_opt, \
|
17
|
+
get_list_opt, get_choice_opt
|
18
|
+
|
19
|
+
# Import this carefully
|
20
|
+
try:
|
21
|
+
import Image, ImageDraw, ImageFont
|
22
|
+
pil_available = True
|
23
|
+
except ImportError:
|
24
|
+
pil_available = False
|
25
|
+
|
26
|
+
try:
|
27
|
+
import _winreg
|
28
|
+
except ImportError:
|
29
|
+
_winreg = None
|
30
|
+
|
31
|
+
__all__ = ['ImageFormatter', 'GifImageFormatter', 'JpgImageFormatter',
|
32
|
+
'BmpImageFormatter']
|
33
|
+
|
34
|
+
|
35
|
+
# For some unknown reason every font calls it something different
|
36
|
+
STYLES = {
|
37
|
+
'NORMAL': ['', 'Roman', 'Book', 'Normal', 'Regular', 'Medium'],
|
38
|
+
'ITALIC': ['Oblique', 'Italic'],
|
39
|
+
'BOLD': ['Bold'],
|
40
|
+
'BOLDITALIC': ['Bold Oblique', 'Bold Italic'],
|
41
|
+
}
|
42
|
+
|
43
|
+
# A sane default for modern systems
|
44
|
+
DEFAULT_FONT_NAME_NIX = 'Bitstream Vera Sans Mono'
|
45
|
+
DEFAULT_FONT_NAME_WIN = 'Courier New'
|
46
|
+
|
47
|
+
|
48
|
+
class PilNotAvailable(ImportError):
|
49
|
+
"""When Python imaging library is not available"""
|
50
|
+
|
51
|
+
|
52
|
+
class FontNotFound(Exception):
|
53
|
+
"""When there are no usable fonts specified"""
|
54
|
+
|
55
|
+
|
56
|
+
class FontManager(object):
|
57
|
+
"""
|
58
|
+
Manages a set of fonts: normal, italic, bold, etc...
|
59
|
+
"""
|
60
|
+
|
61
|
+
def __init__(self, font_name, font_size=14):
|
62
|
+
self.font_name = font_name
|
63
|
+
self.font_size = font_size
|
64
|
+
self.fonts = {}
|
65
|
+
self.encoding = None
|
66
|
+
if sys.platform.startswith('win'):
|
67
|
+
if not font_name:
|
68
|
+
self.font_name = DEFAULT_FONT_NAME_WIN
|
69
|
+
self._create_win()
|
70
|
+
else:
|
71
|
+
if not font_name:
|
72
|
+
self.font_name = DEFAULT_FONT_NAME_NIX
|
73
|
+
self._create_nix()
|
74
|
+
|
75
|
+
def _get_nix_font_path(self, name, style):
|
76
|
+
exit, out = getstatusoutput('fc-list "%s:style=%s" file' %
|
77
|
+
(name, style))
|
78
|
+
if not exit:
|
79
|
+
lines = out.splitlines()
|
80
|
+
if lines:
|
81
|
+
path = lines[0].strip().strip(':')
|
82
|
+
return path
|
83
|
+
|
84
|
+
def _create_nix(self):
|
85
|
+
for name in STYLES['NORMAL']:
|
86
|
+
path = self._get_nix_font_path(self.font_name, name)
|
87
|
+
if path is not None:
|
88
|
+
self.fonts['NORMAL'] = ImageFont.truetype(path, self.font_size)
|
89
|
+
break
|
90
|
+
else:
|
91
|
+
raise FontNotFound('No usable fonts named: "%s"' %
|
92
|
+
self.font_name)
|
93
|
+
for style in ('ITALIC', 'BOLD', 'BOLDITALIC'):
|
94
|
+
for stylename in STYLES[style]:
|
95
|
+
path = self._get_nix_font_path(self.font_name, stylename)
|
96
|
+
if path is not None:
|
97
|
+
self.fonts[style] = ImageFont.truetype(path, self.font_size)
|
98
|
+
break
|
99
|
+
else:
|
100
|
+
if style == 'BOLDITALIC':
|
101
|
+
self.fonts[style] = self.fonts['BOLD']
|
102
|
+
else:
|
103
|
+
self.fonts[style] = self.fonts['NORMAL']
|
104
|
+
|
105
|
+
def _lookup_win(self, key, basename, styles, fail=False):
|
106
|
+
for suffix in ('', ' (TrueType)'):
|
107
|
+
for style in styles:
|
108
|
+
try:
|
109
|
+
valname = '%s%s%s' % (basename, style and ' '+style, suffix)
|
110
|
+
val, _ = _winreg.QueryValueEx(key, valname)
|
111
|
+
return val
|
112
|
+
except EnvironmentError:
|
113
|
+
continue
|
114
|
+
else:
|
115
|
+
if fail:
|
116
|
+
raise FontNotFound('Font %s (%s) not found in registry' %
|
117
|
+
(basename, styles[0]))
|
118
|
+
return None
|
119
|
+
|
120
|
+
def _create_win(self):
|
121
|
+
try:
|
122
|
+
key = _winreg.OpenKey(
|
123
|
+
_winreg.HKEY_LOCAL_MACHINE,
|
124
|
+
r'Software\Microsoft\Windows NT\CurrentVersion\Fonts')
|
125
|
+
except EnvironmentError:
|
126
|
+
try:
|
127
|
+
key = _winreg.OpenKey(
|
128
|
+
_winreg.HKEY_LOCAL_MACHINE,
|
129
|
+
r'Software\Microsoft\Windows\CurrentVersion\Fonts')
|
130
|
+
except EnvironmentError:
|
131
|
+
raise FontNotFound('Can\'t open Windows font registry key')
|
132
|
+
try:
|
133
|
+
path = self._lookup_win(key, self.font_name, STYLES['NORMAL'], True)
|
134
|
+
self.fonts['NORMAL'] = ImageFont.truetype(path, self.font_size)
|
135
|
+
for style in ('ITALIC', 'BOLD', 'BOLDITALIC'):
|
136
|
+
path = self._lookup_win(key, self.font_name, STYLES[style])
|
137
|
+
if path:
|
138
|
+
self.fonts[style] = ImageFont.truetype(path, self.font_size)
|
139
|
+
else:
|
140
|
+
if style == 'BOLDITALIC':
|
141
|
+
self.fonts[style] = self.fonts['BOLD']
|
142
|
+
else:
|
143
|
+
self.fonts[style] = self.fonts['NORMAL']
|
144
|
+
finally:
|
145
|
+
_winreg.CloseKey(key)
|
146
|
+
|
147
|
+
def get_char_size(self):
|
148
|
+
"""
|
149
|
+
Get the character size.
|
150
|
+
"""
|
151
|
+
return self.fonts['NORMAL'].getsize('M')
|
152
|
+
|
153
|
+
def get_font(self, bold, oblique):
|
154
|
+
"""
|
155
|
+
Get the font based on bold and italic flags.
|
156
|
+
"""
|
157
|
+
if bold and oblique:
|
158
|
+
return self.fonts['BOLDITALIC']
|
159
|
+
elif bold:
|
160
|
+
return self.fonts['BOLD']
|
161
|
+
elif oblique:
|
162
|
+
return self.fonts['ITALIC']
|
163
|
+
else:
|
164
|
+
return self.fonts['NORMAL']
|
165
|
+
|
166
|
+
|
167
|
+
class ImageFormatter(Formatter):
|
168
|
+
"""
|
169
|
+
Create a PNG image from source code. This uses the Python Imaging Library to
|
170
|
+
generate a pixmap from the source code.
|
171
|
+
|
172
|
+
*New in Pygments 0.10.*
|
173
|
+
|
174
|
+
Additional options accepted:
|
175
|
+
|
176
|
+
`image_format`
|
177
|
+
An image format to output to that is recognised by PIL, these include:
|
178
|
+
|
179
|
+
* "PNG" (default)
|
180
|
+
* "JPEG"
|
181
|
+
* "BMP"
|
182
|
+
* "GIF"
|
183
|
+
|
184
|
+
`line_pad`
|
185
|
+
The extra spacing (in pixels) between each line of text.
|
186
|
+
|
187
|
+
Default: 2
|
188
|
+
|
189
|
+
`font_name`
|
190
|
+
The font name to be used as the base font from which others, such as
|
191
|
+
bold and italic fonts will be generated. This really should be a
|
192
|
+
monospace font to look sane.
|
193
|
+
|
194
|
+
Default: "Bitstream Vera Sans Mono"
|
195
|
+
|
196
|
+
`font_size`
|
197
|
+
The font size in points to be used.
|
198
|
+
|
199
|
+
Default: 14
|
200
|
+
|
201
|
+
`image_pad`
|
202
|
+
The padding, in pixels to be used at each edge of the resulting image.
|
203
|
+
|
204
|
+
Default: 10
|
205
|
+
|
206
|
+
`line_numbers`
|
207
|
+
Whether line numbers should be shown: True/False
|
208
|
+
|
209
|
+
Default: True
|
210
|
+
|
211
|
+
`line_number_start`
|
212
|
+
The line number of the first line.
|
213
|
+
|
214
|
+
Default: 1
|
215
|
+
|
216
|
+
`line_number_step`
|
217
|
+
The step used when printing line numbers.
|
218
|
+
|
219
|
+
Default: 1
|
220
|
+
|
221
|
+
`line_number_bg`
|
222
|
+
The background colour (in "#123456" format) of the line number bar, or
|
223
|
+
None to use the style background color.
|
224
|
+
|
225
|
+
Default: "#eed"
|
226
|
+
|
227
|
+
`line_number_fg`
|
228
|
+
The text color of the line numbers (in "#123456"-like format).
|
229
|
+
|
230
|
+
Default: "#886"
|
231
|
+
|
232
|
+
`line_number_chars`
|
233
|
+
The number of columns of line numbers allowable in the line number
|
234
|
+
margin.
|
235
|
+
|
236
|
+
Default: 2
|
237
|
+
|
238
|
+
`line_number_bold`
|
239
|
+
Whether line numbers will be bold: True/False
|
240
|
+
|
241
|
+
Default: False
|
242
|
+
|
243
|
+
`line_number_italic`
|
244
|
+
Whether line numbers will be italicized: True/False
|
245
|
+
|
246
|
+
Default: False
|
247
|
+
|
248
|
+
`line_number_separator`
|
249
|
+
Whether a line will be drawn between the line number area and the
|
250
|
+
source code area: True/False
|
251
|
+
|
252
|
+
Default: True
|
253
|
+
|
254
|
+
`line_number_pad`
|
255
|
+
The horizontal padding (in pixels) between the line number margin, and
|
256
|
+
the source code area.
|
257
|
+
|
258
|
+
Default: 6
|
259
|
+
|
260
|
+
`hl_lines`
|
261
|
+
Specify a list of lines to be highlighted. *New in Pygments 1.2.*
|
262
|
+
|
263
|
+
Default: empty list
|
264
|
+
|
265
|
+
`hl_color`
|
266
|
+
Specify the color for highlighting lines. *New in Pygments 1.2.*
|
267
|
+
|
268
|
+
Default: highlight color of the selected style
|
269
|
+
"""
|
270
|
+
|
271
|
+
# Required by the pygments mapper
|
272
|
+
name = 'img'
|
273
|
+
aliases = ['img', 'IMG', 'png']
|
274
|
+
filenames = ['*.png']
|
275
|
+
|
276
|
+
unicodeoutput = False
|
277
|
+
|
278
|
+
default_image_format = 'png'
|
279
|
+
|
280
|
+
def __init__(self, **options):
|
281
|
+
"""
|
282
|
+
See the class docstring for explanation of options.
|
283
|
+
"""
|
284
|
+
if not pil_available:
|
285
|
+
raise PilNotAvailable(
|
286
|
+
'Python Imaging Library is required for this formatter')
|
287
|
+
Formatter.__init__(self, **options)
|
288
|
+
# Read the style
|
289
|
+
self.styles = dict(self.style)
|
290
|
+
if self.style.background_color is None:
|
291
|
+
self.background_color = '#fff'
|
292
|
+
else:
|
293
|
+
self.background_color = self.style.background_color
|
294
|
+
# Image options
|
295
|
+
self.image_format = get_choice_opt(
|
296
|
+
options, 'image_format', ['png', 'jpeg', 'gif', 'bmp'],
|
297
|
+
self.default_image_format, normcase=True)
|
298
|
+
self.image_pad = get_int_opt(options, 'image_pad', 10)
|
299
|
+
self.line_pad = get_int_opt(options, 'line_pad', 2)
|
300
|
+
# The fonts
|
301
|
+
fontsize = get_int_opt(options, 'font_size', 14)
|
302
|
+
self.fonts = FontManager(options.get('font_name', ''), fontsize)
|
303
|
+
self.fontw, self.fonth = self.fonts.get_char_size()
|
304
|
+
# Line number options
|
305
|
+
self.line_number_fg = options.get('line_number_fg', '#886')
|
306
|
+
self.line_number_bg = options.get('line_number_bg', '#eed')
|
307
|
+
self.line_number_chars = get_int_opt(options,
|
308
|
+
'line_number_chars', 2)
|
309
|
+
self.line_number_bold = get_bool_opt(options,
|
310
|
+
'line_number_bold', False)
|
311
|
+
self.line_number_italic = get_bool_opt(options,
|
312
|
+
'line_number_italic', False)
|
313
|
+
self.line_number_pad = get_int_opt(options, 'line_number_pad', 6)
|
314
|
+
self.line_numbers = get_bool_opt(options, 'line_numbers', True)
|
315
|
+
self.line_number_separator = get_bool_opt(options,
|
316
|
+
'line_number_separator', True)
|
317
|
+
self.line_number_step = get_int_opt(options, 'line_number_step', 1)
|
318
|
+
self.line_number_start = get_int_opt(options, 'line_number_start', 1)
|
319
|
+
if self.line_numbers:
|
320
|
+
self.line_number_width = (self.fontw * self.line_number_chars +
|
321
|
+
self.line_number_pad * 2)
|
322
|
+
else:
|
323
|
+
self.line_number_width = 0
|
324
|
+
self.hl_lines = []
|
325
|
+
hl_lines_str = get_list_opt(options, 'hl_lines', [])
|
326
|
+
for line in hl_lines_str:
|
327
|
+
try:
|
328
|
+
self.hl_lines.append(int(line))
|
329
|
+
except ValueError:
|
330
|
+
pass
|
331
|
+
self.hl_color = options.get('hl_color',
|
332
|
+
self.style.highlight_color) or '#f90'
|
333
|
+
self.drawables = []
|
334
|
+
|
335
|
+
def get_style_defs(self, arg=''):
|
336
|
+
raise NotImplementedError('The -S option is meaningless for the image '
|
337
|
+
'formatter. Use -O style=<stylename> instead.')
|
338
|
+
|
339
|
+
def _get_line_height(self):
|
340
|
+
"""
|
341
|
+
Get the height of a line.
|
342
|
+
"""
|
343
|
+
return self.fonth + self.line_pad
|
344
|
+
|
345
|
+
def _get_line_y(self, lineno):
|
346
|
+
"""
|
347
|
+
Get the Y coordinate of a line number.
|
348
|
+
"""
|
349
|
+
return lineno * self._get_line_height() + self.image_pad
|
350
|
+
|
351
|
+
def _get_char_width(self):
|
352
|
+
"""
|
353
|
+
Get the width of a character.
|
354
|
+
"""
|
355
|
+
return self.fontw
|
356
|
+
|
357
|
+
def _get_char_x(self, charno):
|
358
|
+
"""
|
359
|
+
Get the X coordinate of a character position.
|
360
|
+
"""
|
361
|
+
return charno * self.fontw + self.image_pad + self.line_number_width
|
362
|
+
|
363
|
+
def _get_text_pos(self, charno, lineno):
|
364
|
+
"""
|
365
|
+
Get the actual position for a character and line position.
|
366
|
+
"""
|
367
|
+
return self._get_char_x(charno), self._get_line_y(lineno)
|
368
|
+
|
369
|
+
def _get_linenumber_pos(self, lineno):
|
370
|
+
"""
|
371
|
+
Get the actual position for the start of a line number.
|
372
|
+
"""
|
373
|
+
return (self.image_pad, self._get_line_y(lineno))
|
374
|
+
|
375
|
+
def _get_text_color(self, style):
|
376
|
+
"""
|
377
|
+
Get the correct color for the token from the style.
|
378
|
+
"""
|
379
|
+
if style['color'] is not None:
|
380
|
+
fill = '#' + style['color']
|
381
|
+
else:
|
382
|
+
fill = '#000'
|
383
|
+
return fill
|
384
|
+
|
385
|
+
def _get_style_font(self, style):
|
386
|
+
"""
|
387
|
+
Get the correct font for the style.
|
388
|
+
"""
|
389
|
+
return self.fonts.get_font(style['bold'], style['italic'])
|
390
|
+
|
391
|
+
def _get_image_size(self, maxcharno, maxlineno):
|
392
|
+
"""
|
393
|
+
Get the required image size.
|
394
|
+
"""
|
395
|
+
return (self._get_char_x(maxcharno) + self.image_pad,
|
396
|
+
self._get_line_y(maxlineno + 0) + self.image_pad)
|
397
|
+
|
398
|
+
def _draw_linenumber(self, posno, lineno):
|
399
|
+
"""
|
400
|
+
Remember a line number drawable to paint later.
|
401
|
+
"""
|
402
|
+
self._draw_text(
|
403
|
+
self._get_linenumber_pos(posno),
|
404
|
+
str(lineno).rjust(self.line_number_chars),
|
405
|
+
font=self.fonts.get_font(self.line_number_bold,
|
406
|
+
self.line_number_italic),
|
407
|
+
fill=self.line_number_fg,
|
408
|
+
)
|
409
|
+
|
410
|
+
def _draw_text(self, pos, text, font, **kw):
|
411
|
+
"""
|
412
|
+
Remember a single drawable tuple to paint later.
|
413
|
+
"""
|
414
|
+
self.drawables.append((pos, text, font, kw))
|
415
|
+
|
416
|
+
def _create_drawables(self, tokensource):
|
417
|
+
"""
|
418
|
+
Create drawables for the token content.
|
419
|
+
"""
|
420
|
+
lineno = charno = maxcharno = 0
|
421
|
+
for ttype, value in tokensource:
|
422
|
+
while ttype not in self.styles:
|
423
|
+
ttype = ttype.parent
|
424
|
+
style = self.styles[ttype]
|
425
|
+
# TODO: make sure tab expansion happens earlier in the chain. It
|
426
|
+
# really ought to be done on the input, as to do it right here is
|
427
|
+
# quite complex.
|
428
|
+
value = value.expandtabs(4)
|
429
|
+
lines = value.splitlines(True)
|
430
|
+
#print lines
|
431
|
+
for i, line in enumerate(lines):
|
432
|
+
temp = line.rstrip('\n')
|
433
|
+
if temp:
|
434
|
+
self._draw_text(
|
435
|
+
self._get_text_pos(charno, lineno),
|
436
|
+
temp,
|
437
|
+
font = self._get_style_font(style),
|
438
|
+
fill = self._get_text_color(style)
|
439
|
+
)
|
440
|
+
charno += len(temp)
|
441
|
+
maxcharno = max(maxcharno, charno)
|
442
|
+
if line.endswith('\n'):
|
443
|
+
# add a line for each extra line in the value
|
444
|
+
charno = 0
|
445
|
+
lineno += 1
|
446
|
+
self.maxcharno = maxcharno
|
447
|
+
self.maxlineno = lineno
|
448
|
+
|
449
|
+
def _draw_line_numbers(self):
|
450
|
+
"""
|
451
|
+
Create drawables for the line numbers.
|
452
|
+
"""
|
453
|
+
if not self.line_numbers:
|
454
|
+
return
|
455
|
+
for p in xrange(self.maxlineno):
|
456
|
+
n = p + self.line_number_start
|
457
|
+
if (n % self.line_number_step) == 0:
|
458
|
+
self._draw_linenumber(p, n)
|
459
|
+
|
460
|
+
def _paint_line_number_bg(self, im):
|
461
|
+
"""
|
462
|
+
Paint the line number background on the image.
|
463
|
+
"""
|
464
|
+
if not self.line_numbers:
|
465
|
+
return
|
466
|
+
if self.line_number_fg is None:
|
467
|
+
return
|
468
|
+
draw = ImageDraw.Draw(im)
|
469
|
+
recth = im.size[-1]
|
470
|
+
rectw = self.image_pad + self.line_number_width - self.line_number_pad
|
471
|
+
draw.rectangle([(0, 0),
|
472
|
+
(rectw, recth)],
|
473
|
+
fill=self.line_number_bg)
|
474
|
+
draw.line([(rectw, 0), (rectw, recth)], fill=self.line_number_fg)
|
475
|
+
del draw
|
476
|
+
|
477
|
+
def format(self, tokensource, outfile):
|
478
|
+
"""
|
479
|
+
Format ``tokensource``, an iterable of ``(tokentype, tokenstring)``
|
480
|
+
tuples and write it into ``outfile``.
|
481
|
+
|
482
|
+
This implementation calculates where it should draw each token on the
|
483
|
+
pixmap, then calculates the required pixmap size and draws the items.
|
484
|
+
"""
|
485
|
+
self._create_drawables(tokensource)
|
486
|
+
self._draw_line_numbers()
|
487
|
+
im = Image.new(
|
488
|
+
'RGB',
|
489
|
+
self._get_image_size(self.maxcharno, self.maxlineno),
|
490
|
+
self.background_color
|
491
|
+
)
|
492
|
+
self._paint_line_number_bg(im)
|
493
|
+
draw = ImageDraw.Draw(im)
|
494
|
+
# Highlight
|
495
|
+
if self.hl_lines:
|
496
|
+
x = self.image_pad + self.line_number_width - self.line_number_pad + 1
|
497
|
+
recth = self._get_line_height()
|
498
|
+
rectw = im.size[0] - x
|
499
|
+
for linenumber in self.hl_lines:
|
500
|
+
y = self._get_line_y(linenumber - 1)
|
501
|
+
draw.rectangle([(x, y), (x + rectw, y + recth)],
|
502
|
+
fill=self.hl_color)
|
503
|
+
for pos, value, font, kw in self.drawables:
|
504
|
+
draw.text(pos, value, font=font, **kw)
|
505
|
+
im.save(outfile, self.image_format.upper())
|
506
|
+
|
507
|
+
|
508
|
+
# Add one formatter per format, so that the "-f gif" option gives the correct result
|
509
|
+
# when used in pygmentize.
|
510
|
+
|
511
|
+
class GifImageFormatter(ImageFormatter):
|
512
|
+
"""
|
513
|
+
Create a GIF image from source code. This uses the Python Imaging Library to
|
514
|
+
generate a pixmap from the source code.
|
515
|
+
|
516
|
+
*New in Pygments 1.0.* (You could create GIF images before by passing a
|
517
|
+
suitable `image_format` option to the `ImageFormatter`.)
|
518
|
+
"""
|
519
|
+
|
520
|
+
name = 'img_gif'
|
521
|
+
aliases = ['gif']
|
522
|
+
filenames = ['*.gif']
|
523
|
+
default_image_format = 'gif'
|
524
|
+
|
525
|
+
|
526
|
+
class JpgImageFormatter(ImageFormatter):
|
527
|
+
"""
|
528
|
+
Create a JPEG image from source code. This uses the Python Imaging Library to
|
529
|
+
generate a pixmap from the source code.
|
530
|
+
|
531
|
+
*New in Pygments 1.0.* (You could create JPEG images before by passing a
|
532
|
+
suitable `image_format` option to the `ImageFormatter`.)
|
533
|
+
"""
|
534
|
+
|
535
|
+
name = 'img_jpg'
|
536
|
+
aliases = ['jpg', 'jpeg']
|
537
|
+
filenames = ['*.jpg']
|
538
|
+
default_image_format = 'jpeg'
|
539
|
+
|
540
|
+
|
541
|
+
class BmpImageFormatter(ImageFormatter):
|
542
|
+
"""
|
543
|
+
Create a bitmap image from source code. This uses the Python Imaging Library to
|
544
|
+
generate a pixmap from the source code.
|
545
|
+
|
546
|
+
*New in Pygments 1.0.* (You could create bitmap images before by passing a
|
547
|
+
suitable `image_format` option to the `ImageFormatter`.)
|
548
|
+
"""
|
549
|
+
|
550
|
+
name = 'img_bmp'
|
551
|
+
aliases = ['bmp', 'bitmap']
|
552
|
+
filenames = ['*.bmp']
|
553
|
+
default_image_format = 'bmp'
|