~ubuntu-branches/ubuntu/raring/wxwidgets2.8/raring

« back to all changes in this revision

Viewing changes to wxPython/wx/tools/Editra/src/extern/pygments/formatters/html.py

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2012-01-07 13:59:25 UTC
  • mfrom: (1.1.9) (5.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120107135925-2601miy9ullcon9j
Tags: 2.8.12.1-6ubuntu1
* Resync from Debian, changes that were kept:
  - debian/rules: re-enable mediactrl. This allows libwx_gtk2u_media-2.8 to be
    built, as this is required by some applications (LP: #632984)
  - debian/control: Build-dep on libxt-dev for mediactrl.
  - Patches
    + fix-bashism-in-example
* Add conflict on python-wxgtk2.8 (<< 2.8.12.1-6ubuntu1~) to python-wxversion
  to guarantee upgrade ordering when moving from pycentral to dh_python2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
    Formatter for HTML output.
7
7
 
8
 
    :copyright: 2006-2008 by Georg Brandl, Armin Ronacher.
9
 
    :license: BSD, see LICENSE for more details.
 
8
    :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
 
9
    :license: BSD, see LICENSE for details.
10
10
"""
11
 
import sys, os
 
11
 
 
12
import os
 
13
import sys
12
14
import StringIO
13
15
 
14
 
try:
15
 
    set
16
 
except NameError:
17
 
    from sets import Set as set
18
 
 
19
16
from pygments.formatter import Formatter
20
17
from pygments.token import Token, Text, STANDARD_TYPES
21
 
from pygments.util import get_bool_opt, get_int_opt, get_list_opt
 
18
from pygments.util import get_bool_opt, get_int_opt, get_list_opt, bytes
22
19
 
23
20
 
24
21
__all__ = ['HtmlFormatter']
25
22
 
26
23
 
27
 
def escape_html(text):
 
24
_escape_html_table = {
 
25
    ord('&'): u'&amp;',
 
26
    ord('<'): u'&lt;',
 
27
    ord('>'): u'&gt;',
 
28
    ord('"'): u'&quot;',
 
29
    ord("'"): u'&#39;',
 
30
}
 
31
 
 
32
def escape_html(text, table=_escape_html_table):
28
33
    """Escape &, <, > as well as single and double quotes for HTML."""
29
 
    return text.replace('&', '&amp;').  \
30
 
                replace('<', '&lt;').   \
31
 
                replace('>', '&gt;').   \
32
 
                replace('"', '&quot;'). \
33
 
                replace("'", '&#39;')
34
 
 
 
34
    return text.translate(table)
35
35
 
36
36
def get_random_id():
37
37
    """Return a random id for javascript fields."""
186
186
 
187
187
    `style`
188
188
        The style to use, can be a string or a Style subclass (default:
189
 
        ``'default'``).
 
189
        ``'default'``). This option has no effect if the `cssfile`
 
190
        and `noclobber_cssfile` option are given and the file specified in
 
191
        `cssfile` exists.
190
192
 
191
193
    `noclasses`
192
194
        If set to true, token ``<span>`` tags will not use CSS classes, but
223
225
        file's path, if the latter can be found. The stylesheet is then written
224
226
        to this file instead of the HTML file. *New in Pygments 0.6.*
225
227
 
 
228
    `noclobber_cssfile`
 
229
        If `cssfile` is given and the specified file exists, the css file will
 
230
        not be overwritten. This allows the use of the `full` option in
 
231
        combination with a user specified css file. Default is ``False``.
 
232
        *New in Pygments 1.1.*
 
233
 
226
234
    `linenos`
227
235
        If set to ``'table'``, output line numbers as a table with two cells,
228
236
        one containing the line numbers, the other the whole code.  This is
274
282
        output line in an anchor tag with a ``name`` of ``foo-linenumber``.
275
283
        This allows easy linking to certain lines. *New in Pygments 0.9.*
276
284
 
 
285
    `anchorlinenos`
 
286
        If set to `True`, will wrap line numbers in <a> tags. Used in
 
287
        combination with `linenos` and `lineanchors`.
 
288
 
277
289
 
278
290
    **Subclassing the HTML formatter**
279
291
 
330
342
 
331
343
    def __init__(self, **options):
332
344
        Formatter.__init__(self, **options)
333
 
        self.title = self._encodeifneeded(self.title)
 
345
        self.title = self._decodeifneeded(self.title)
334
346
        self.nowrap = get_bool_opt(options, 'nowrap', False)
335
347
        self.noclasses = get_bool_opt(options, 'noclasses', False)
336
348
        self.classprefix = options.get('classprefix', '')
337
 
        self.cssclass = self._encodeifneeded(options.get('cssclass', 'highlight'))
338
 
        self.cssstyles = self._encodeifneeded(options.get('cssstyles', ''))
339
 
        self.prestyles = self._encodeifneeded(options.get('prestyles', ''))
340
 
        self.cssfile = self._encodeifneeded(options.get('cssfile', ''))
 
349
        self.cssclass = self._decodeifneeded(options.get('cssclass', 'highlight'))
 
350
        self.cssstyles = self._decodeifneeded(options.get('cssstyles', ''))
 
351
        self.prestyles = self._decodeifneeded(options.get('prestyles', ''))
 
352
        self.cssfile = self._decodeifneeded(options.get('cssfile', ''))
 
353
        self.noclobber_cssfile = get_bool_opt(options, 'noclobber_cssfile', False)
 
354
 
341
355
        linenos = options.get('linenos', False)
342
356
        if linenos == 'inline':
343
357
            self.linenos = 2
352
366
        self.nobackground = get_bool_opt(options, 'nobackground', False)
353
367
        self.lineseparator = options.get('lineseparator', '\n')
354
368
        self.lineanchors = options.get('lineanchors', '')
 
369
        self.anchorlinenos = options.get('anchorlinenos', False)
355
370
        self.hl_lines = set()
356
371
        for lineno in get_list_opt(options, 'hl_lines', []):
357
372
            try:
359
374
            except ValueError:
360
375
                pass
361
376
 
362
 
        self._class_cache = {}
363
377
        self._create_stylesheet()
364
378
 
365
379
    def _get_css_class(self, ttype):
366
380
        """Return the css class of this token type prefixed with
367
381
        the classprefix option."""
368
 
        if ttype in self._class_cache:
369
 
            return self._class_cache[ttype]
370
 
        return self.classprefix + _get_ttype_class(ttype)
 
382
        ttypeclass = _get_ttype_class(ttype)
 
383
        if ttypeclass:
 
384
            return self.classprefix + ttypeclass
 
385
        return ''
371
386
 
372
387
    def _create_stylesheet(self):
373
388
        t2c = self.ttype2class = {Token: ''}
374
389
        c2s = self.class2style = {}
375
 
        cp = self.classprefix
376
390
        for ttype, ndef in self.style:
377
 
            name = cp + _get_ttype_class(ttype)
 
391
            name = self._get_css_class(ttype)
378
392
            style = ''
379
393
            if ndef['color']:
380
394
                style += 'color: #%s; ' % ndef['color']
433
447
                         (prefix(''), self.style.highlight_color))
434
448
        return '\n'.join(lines)
435
449
 
436
 
    def _encodeifneeded(self, value):
437
 
        if not self.encoding or isinstance(value, str):
438
 
            return value
439
 
        return value.encode(self.encoding)
 
450
    def _decodeifneeded(self, value):
 
451
        if isinstance(value, bytes):
 
452
            if self.encoding:
 
453
                return value.decode(self.encoding)
 
454
            return value.decode()
 
455
        return value
440
456
 
441
457
    def _wrap_full(self, inner, outfile):
442
458
        if self.cssfile:
449
465
                    if not filename or filename[0] == '<':
450
466
                        # pseudo files, e.g. name == '<fdopen>'
451
467
                        raise AttributeError
452
 
                    cssfilename = os.path.join(os.path.dirname(filename), self.cssfile)
 
468
                    cssfilename = os.path.join(os.path.dirname(filename),
 
469
                                               self.cssfile)
453
470
                except AttributeError:
454
471
                    print >>sys.stderr, 'Note: Cannot determine output file name, ' \
455
472
                          'using current directory as base for the CSS file name'
456
473
                    cssfilename = self.cssfile
457
 
            # write CSS file
 
474
            # write CSS file only if noclobber_cssfile isn't given as an option.
458
475
            try:
459
 
                cf = open(cssfilename, "w")
460
 
                cf.write(CSSFILE_TEMPLATE %
461
 
                         {'styledefs': self.get_style_defs('body')})
462
 
                cf.close()
 
476
                if not os.path.exists(cssfilename) or not self.noclobber_cssfile:
 
477
                    cf = open(cssfilename, "w")
 
478
                    cf.write(CSSFILE_TEMPLATE %
 
479
                            {'styledefs': self.get_style_defs('body')})
 
480
                    cf.close()
463
481
            except IOError, err:
464
482
                err.strerror = 'Error writing CSS file: ' + err.strerror
465
483
                raise
490
508
        mw = len(str(lncount + fl - 1))
491
509
        sp = self.linenospecial
492
510
        st = self.linenostep
 
511
        la = self.lineanchors
 
512
        aln = self.anchorlinenos
 
513
        nocls = self.noclasses
493
514
        if sp:
494
 
            ls = '\n'.join([(i%st == 0 and
495
 
                             (i%sp == 0 and '<span class="special">%*d</span>'
496
 
                              or '%*d') % (mw, i)
497
 
                             or '')
498
 
                            for i in range(fl, fl + lncount)])
499
 
        else:
500
 
            ls = '\n'.join([(i%st == 0 and ('%*d' % (mw, i)) or '')
501
 
                            for i in range(fl, fl + lncount)])
502
 
 
503
 
        yield 0, ('<table class="%stable">' % self.cssclass +
504
 
                  '<tr><td class="linenos"><pre>' +
505
 
                  ls + '</pre></td><td class="code">')
 
515
            lines = []
 
516
 
 
517
            for i in range(fl, fl+lncount):
 
518
                if i % st == 0:
 
519
                    if i % sp == 0:
 
520
                        if aln:
 
521
                            lines.append('<a href="#%s-%d" class="special">%*d</a>' %
 
522
                                         (la, i, mw, i))
 
523
                        else:
 
524
                            lines.append('<span class="special">%*d</span>' % (mw, i))
 
525
                    else:
 
526
                        if aln:
 
527
                            lines.append('<a href="#%s-%d">%*d</a>' % (la, i, mw, i))
 
528
                        else:
 
529
                            lines.append('%*d' % (mw, i))
 
530
                else:
 
531
                    lines.append('')
 
532
            ls = '\n'.join(lines)
 
533
        else:
 
534
            lines = []
 
535
            for i in range(fl, fl+lncount):
 
536
                if i % st == 0:
 
537
                    if aln:
 
538
                        lines.append('<a href="#%s-%d">%*d</a>' % (la, i, mw, i))
 
539
                    else:
 
540
                        lines.append('%*d' % (mw, i))
 
541
                else:
 
542
                    lines.append('')
 
543
            ls = '\n'.join(lines)
 
544
 
 
545
        # in case you wonder about the seemingly redundant <div> here: since the
 
546
        # content in the other cell also is wrapped in a div, some browsers in
 
547
        # some configurations seem to mess up the formatting...
 
548
        if nocls:
 
549
            yield 0, ('<table class="%stable">' % self.cssclass +
 
550
                      '<tr><td><div class="linenodiv" '
 
551
                      'style="background-color: #f0f0f0; padding-right: 10px">'
 
552
                      '<pre style="line-height: 125%">' +
 
553
                      ls + '</pre></div></td><td class="code">')
 
554
        else:
 
555
            yield 0, ('<table class="%stable">' % self.cssclass +
 
556
                      '<tr><td class="linenos"><div class="linenodiv"><pre>' +
 
557
                      ls + '</pre></div></td><td class="code">')
506
558
        yield 0, dummyoutfile.getvalue()
507
559
        yield 0, '</td></tr></table>'
508
560
 
514
566
        num = self.linenostart
515
567
        mw = len(str(len(lines) + num - 1))
516
568
 
517
 
        if sp:
 
569
        if self.noclasses:
 
570
            if sp:
 
571
                for t, line in lines:
 
572
                    if num%sp == 0:
 
573
                        style = 'background-color: #ffffc0; padding: 0 5px 0 5px'
 
574
                    else:
 
575
                        style = 'background-color: #f0f0f0; padding: 0 5px 0 5px'
 
576
                    yield 1, '<span style="%s">%*s</span> ' % (
 
577
                        style, mw, (num%st and ' ' or num)) + line
 
578
                    num += 1
 
579
            else:
 
580
                for t, line in lines:
 
581
                    yield 1, ('<span style="background-color: #f0f0f0; '
 
582
                              'padding: 0 5px 0 5px">%*s</span> ' % (
 
583
                              mw, (num%st and ' ' or num)) + line)
 
584
                    num += 1
 
585
        elif sp:
518
586
            for t, line in lines:
519
587
                yield 1, '<span class="lineno%s">%*s</span> ' % (
520
 
                    num%sp == 0 and ' special' or '', mw, (num%st and ' ' or num)) + line
 
588
                    num%sp == 0 and ' special' or '', mw,
 
589
                    (num%st and ' ' or num)) + line
521
590
                num += 1
522
591
        else:
523
592
            for t, line in lines:
536
605
                yield 0, line
537
606
 
538
607
    def _wrap_div(self, inner):
 
608
        style = []
 
609
        if (self.noclasses and not self.nobackground and
 
610
            self.style.background_color is not None):
 
611
            style.append('background: %s' % (self.style.background_color,))
 
612
        if self.cssstyles:
 
613
            style.append(self.cssstyles)
 
614
        style = '; '.join(style)
 
615
 
539
616
        yield 0, ('<div' + (self.cssclass and ' class="%s"' % self.cssclass)
540
 
                  + (self.cssstyles and ' style="%s"' % self.cssstyles) + '>')
 
617
                  + (style and (' style="%s"' % style)) + '>')
541
618
        for tup in inner:
542
619
            yield tup
543
620
        yield 0, '</div>\n'
544
621
 
545
622
    def _wrap_pre(self, inner):
546
 
        yield 0, ('<pre'
547
 
                  + (self.prestyles and ' style="%s"' % self.prestyles) + '>')
 
623
        style = []
 
624
        if self.prestyles:
 
625
            style.append(self.prestyles)
 
626
        if self.noclasses:
 
627
            style.append('line-height: 125%')
 
628
        style = '; '.join(style)
 
629
 
 
630
        yield 0, ('<pre' + (style and ' style="%s"' % style) + '>')
548
631
        for tup in inner:
549
632
            yield tup
550
633
        yield 0, '</pre>'
555
638
        Yield individual lines.
556
639
        """
557
640
        nocls = self.noclasses
558
 
        enc = self.encoding
559
641
        lsep = self.lineseparator
560
642
        # for <span style=""> lookup only
561
643
        getcls = self.ttype2class.get
562
644
        c2s = self.class2style
 
645
        escape_table = _escape_html_table
563
646
 
564
647
        lspan = ''
565
648
        line = ''
574
657
                cls = self._get_css_class(ttype)
575
658
                cspan = cls and '<span class="%s">' % cls or ''
576
659
 
577
 
            if enc:
578
 
                value = value.encode(enc)
579
 
 
580
 
            parts = escape_html(value).split('\n')
 
660
            parts = value.translate(escape_table).split('\n')
581
661
 
582
662
            # for all but the last line
583
663
            for part in parts[:-1]:
619
699
            if t != 1:
620
700
                yield t, value
621
701
            if i + 1 in hls: # i + 1 because Python indexes start at 0
622
 
                yield 1, '<span class="hll">%s</span>' % value
 
702
                if self.noclasses:
 
703
                    style = ''
 
704
                    if self.style.highlight_color is not None:
 
705
                        style = (' style="background-color: %s"' %
 
706
                                 (self.style.highlight_color,))
 
707
                    yield 1, '<span%s>%s</span>' % (style, value)
 
708
                else:
 
709
                    yield 1, '<span class="hll">%s</span>' % value
623
710
            else:
624
711
                yield 1, value
625
712
 
631
718
        """
632
719
        return self._wrap_div(self._wrap_pre(source))
633
720
 
634
 
    def format(self, tokensource, outfile):
 
721
    def format_unencoded(self, tokensource, outfile):
635
722
        """
636
723
        The formatting process uses several nested generators; which of
637
724
        them are used is determined by the user's options.