Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

nickfrez / api-browser   python

Repository URL to install this package:

/ api_browser / pygments_formatters.py

# -*- coding: utf-8 -*-
"""
###################
Pygments Formatters
###################

Modified Pygments formatters.


"""


from __future__ import print_function

import os
import os.path

from pygments.token import Token
from pygments.formatters.html import HtmlFormatter, _escape_html_table

from django.core.validators import URLValidator, ValidationError


url_validator = URLValidator()


class HtmlLinkifyFormatter(HtmlFormatter):
    """Add anchor tags to hyperlinks in code."""

    def _format_lines(self, tokensource):
        """
        Just format the tokens, without any wrapping tags.
        Yield individual lines.
        """
        nocls = self.noclasses
        lsep = self.lineseparator
        # for <span style=""> lookup only
        getcls = self.ttype2class.get
        c2s = self.class2style
        escape_table = _escape_html_table
        tagsfile = self.tagsfile

        lspan = ''
        line = []
        for ttype, value in tokensource:
            if nocls:
                cclass = getcls(ttype)
                while cclass is None:
                    ttype = ttype.parent
                    cclass = getcls(ttype)
                cspan = cclass and '<span style="%s">' % c2s[cclass][0] or ''
            else:
                cls = self._get_css_classes(ttype)
                cspan = cls and '<span class="%s">' % cls or ''

            parts = value.translate(escape_table).split('\n')

            # ================================================================
            #                         MODIFIED
            # ================================================================
            # Make URLs clickable
            # ====================
            #
            # Converts valid urls to::
            #
            #     <a href="{{ url }}">
            #         "<span class="hyperlink">{{ url }}</span>"
            #     </a>
            #
            if ttype == Token.Literal.String.Double:
                v = value.strip('"')
                try:
                    url_validator(v)
                    parts = [('<a href=\'%s\'>'
                              '&quot;<span class="hyperlink">%s</span>&quot;'
                              '</a>') % (v, v.translate(escape_table))]
                except ValidationError:
                    pass
            # ================================================================

            if tagsfile and ttype in Token.Name:
                filename, linenumber = self._lookup_ctag(value)
                if linenumber:
                    base, filename = os.path.split(filename)
                    if base:
                        base += '/'
                    filename, extension = os.path.splitext(filename)
                    url = self.tagurlformat % {'path': base, 'fname': filename,
                                               'fext': extension}
                    parts[0] = "<a href=\"%s#%s-%d\">%s" % \
                        (url, self.lineanchors, linenumber, parts[0])
                    parts[-1] = parts[-1] + "</a>"

            # for all but the last line
            for part in parts[:-1]:
                if line:
                    # print(line)
                    if lspan != cspan:
                        line.extend(((lspan and '</span>'), cspan, part,
                                     (cspan and '</span>'), lsep))
                    else:  # both are the same
                        line.extend((part, (lspan and '</span>'), lsep))
                    # out = 1, ''.join(line)
                    yield 1, ''.join(line)
                    line = []
                elif part:
                    yield 1, ''.join((cspan, part, (cspan and '</span>'),
                                      lsep))
                else:
                    yield 1, lsep
            # for the last line
            if line and parts[-1]:
                if lspan != cspan:
                    line.extend(((lspan and '</span>'), cspan, parts[-1]))
                    lspan = cspan
                else:
                    line.append(parts[-1])
            elif parts[-1]:
                line = [cspan, parts[-1]]
                lspan = cspan
            # else we neither have to open a new span nor set lspan

        if line:
            line.extend(((lspan and '</span>'), lsep))
            yield 1, ''.join(line)