1
from pygments.lexer import RegexLexer, bygroups, using
2
from pygments.token import Token
3
from pygments.filter import Filter
4
from pygments.filter import apply_filters
5
from pygments.lexers import PythonLexer, PythonConsoleLexer
6
from sphinx.highlighting import PygmentsBridge
7
from pygments.formatters import HtmlFormatter, LatexFormatter
12
def _strip_trailing_whitespace(iter_):
15
buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
20
class StripDocTestFilter(Filter):
21
def filter(self, lexer, stream):
22
for ttype, value in stream:
23
if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
27
class PyConWithSQLLexer(RegexLexer):
29
aliases = ['pycon+sql']
31
flags = re.IGNORECASE | re.DOTALL
35
(r'{sql}', Token.Sql.Link, 'sqlpopup'),
36
(r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
37
(r'.*?\n', using(PythonConsoleLexer))
41
r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|'
42
'COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA'
43
'|DESCRIBE).*?(?:{stop}\n?|$))',
44
bygroups(using(PythonConsoleLexer), Token.Sql.Popup),
50
r'.*?(?:{stop}\n*|$)',
58
class PythonWithSQLLexer(RegexLexer):
60
aliases = ['pycon+sql']
62
flags = re.IGNORECASE | re.DOTALL
66
(r'{sql}', Token.Sql.Link, 'sqlpopup'),
67
(r'{opensql}', Token.Sql.Open, 'opensqlpopup'),
68
(r'.*?\n', using(PythonLexer))
72
r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK'
73
'|COMMIT|ALTER|UPDATE|CREATE|DROP'
74
'|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))',
75
bygroups(using(PythonLexer), Token.Sql.Popup),
81
r'.*?(?:{stop}\n*|$)',
88
class PopupSQLFormatter(HtmlFormatter):
89
def _format_lines(self, tokensource):
91
for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
92
if ttype in Token.Sql:
93
for t, v in HtmlFormatter._format_lines(self, iter(buf)):
97
if ttype is Token.Sql:
98
yield 1, "<div class='show_sql'>%s</div>" % \
99
re.sub(r'(?:[{stop}|\n]*)$', '', value)
100
elif ttype is Token.Sql.Link:
101
yield 1, "<a href='#' class='sql_link'>sql</a>"
102
elif ttype is Token.Sql.Popup:
103
yield 1, "<div class='popup_sql'>%s</div>" % \
104
re.sub(r'(?:[{stop}|\n]*)$', '', value)
106
buf.append((ttype, value))
108
for t, v in _strip_trailing_whitespace(
109
HtmlFormatter._format_lines(self, iter(buf))):
112
class PopupLatexFormatter(LatexFormatter):
113
def _filter_tokens(self, tokensource):
114
for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]):
115
if ttype in Token.Sql:
116
if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open:
117
yield Token.Literal, re.sub(r'{stop}', '', value)
123
def format(self, tokensource, outfile):
124
LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
127
app.add_lexer('pycon+sql', PyConWithSQLLexer())
128
app.add_lexer('python+sql', PythonWithSQLLexer())
130
PygmentsBridge.html_formatter = PopupSQLFormatter
131
PygmentsBridge.latex_formatter = PopupLatexFormatter