1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
"""
HTML macros
Macros for generating snippets of HTML.
"""
import genshi
import pygments
import pygments.formatters
import pygments.lexers
import pygments.util
from genshi import builder
from genshi.filters import HTMLSanitizer
sanitizer = HTMLSanitizer()
def pre(macro, environ, *args, **kwargs):
"""
Return the raw text of body, rendered in a <pre> block.
**Arguments:** //None//
**Example:**
{{{
<<pre>>
def hello():
print "Hello World!"
hello()
<</pre>>
}}}
"""
if macro.body is None:
return None
return builder.tag.pre(macro.body)
def code(macro, environ, *args, **kwargs):
"""Render syntax highlighted code"""
if not macro.body:
return None
lang = kwargs.get('lang', None)
if lang is not None:
if not macro.isblock:
return None
try:
lexer = pygments.lexers.get_lexer_by_name(lang, stripall=True)
except pygments.util.ClassNotFound:
return None
else:
lexer = None
if lexer:
text = pygments.highlight(
macro.body,
lexer,
pygments.formatters.HtmlFormatter(),
)
output = genshi.core.Markup(text)
elif macro.isblock:
output = genshi.builder.tag.pre(macro.body)
else:
output = genshi.builder.tag.code(
macro.body,
style='white-space:pre-wrap',
class_='highlight',
)
return output
def source(macro, environ, *args, **kwargs):
"""Return the parsed text of body, rendered in a <pre> block."""
if macro.body is None:
return None
return builder.tag.pre(environ['parser'].render(macro.body, environ=environ).decode('utf-8'))
def div(macro, environ, cls=None, float=None, id=None, style=None, *args, **kwargs):
if macro.body is None:
return None
if float and float in ('left', 'right'):
style = f'float: {float}; {style}'
if style:
style = ';'.join(sanitizer.sanitize_css(style))
context = 'block' if macro.isblock else 'inline'
contents = environ['parser'].generate(
macro.body,
environ=environ,
context=context,
)
return builder.tag.div(contents, id=id, class_=cls, style=style)
def span(macro, environ, class_=None, id=None, style=None, *args, **kwargs):
"""..."""
if macro.body is None:
return None
if style:
style = ';'.join(sanitizer.sanitize_css(style))
contents = environ['parser'].generate(
macro.body,
environ=environ,
context='inline',
)
return builder.tag.span(contents, id=id, class_=class_, style=style)
|