forked from I2P_Developers/i2p.www
Added a formatter for textual dataspecs
This commit is contained in:
@@ -17,7 +17,7 @@ except ImportError:
|
|||||||
|
|
||||||
from flask import g
|
from flask import g
|
||||||
|
|
||||||
from i2p2www.formatters import I2PHtmlFormatter
|
from i2p2www.formatters import I2PHtmlFormatter, TextSpecFormatter
|
||||||
from i2p2www.lexers import DataSpecLexer
|
from i2p2www.lexers import DataSpecLexer
|
||||||
|
|
||||||
|
|
||||||
@@ -55,13 +55,14 @@ class HighlightExtension(Extension):
|
|||||||
# extract the language if available
|
# extract the language if available
|
||||||
# Any additional parameters are passed to HtmlFormatter
|
# Any additional parameters are passed to HtmlFormatter
|
||||||
lang = None
|
lang = None
|
||||||
|
formatter = None
|
||||||
parameters = []
|
parameters = []
|
||||||
while parser.stream.current.type != 'block_end':
|
while parser.stream.current.type != 'block_end':
|
||||||
if lang or parameters:
|
if lang or parameters:
|
||||||
parser.stream.expect('comma')
|
parser.stream.expect('comma')
|
||||||
|
|
||||||
name = parser.stream.expect('name')
|
name = parser.stream.expect('name')
|
||||||
if name.value in parameters or (name.value == 'lang' and lang):
|
if name.value in parameters or (name.value == 'lang' and lang) or (name.value == 'formatter' and formatter):
|
||||||
parser.fail('parameter %r defined twice.' %
|
parser.fail('parameter %r defined twice.' %
|
||||||
name.value, name.lineno,
|
name.value, name.lineno,
|
||||||
exc=TemplateAssertionError)
|
exc=TemplateAssertionError)
|
||||||
@@ -70,20 +71,24 @@ class HighlightExtension(Extension):
|
|||||||
next(parser.stream)
|
next(parser.stream)
|
||||||
if name.value == 'lang':
|
if name.value == 'lang':
|
||||||
lang = parser.parse_expression()
|
lang = parser.parse_expression()
|
||||||
|
elif name.value == 'formatter':
|
||||||
|
formatter = parser.parse_expression()
|
||||||
else:
|
else:
|
||||||
parameters.append(nodes.Pair(nodes.Const(name.value), parser.parse_expression()))
|
parameters.append(nodes.Pair(nodes.Const(name.value), parser.parse_expression()))
|
||||||
|
|
||||||
if lang == None:
|
if lang == None:
|
||||||
lang = nodes.Const(None)
|
lang = nodes.Const(None)
|
||||||
|
if formatter == None:
|
||||||
|
formatter = nodes.Const('html')
|
||||||
parameters = nodes.Dict(parameters)
|
parameters = nodes.Dict(parameters)
|
||||||
|
|
||||||
# body of the block
|
# body of the block
|
||||||
body = parser.parse_statements(['name:endhighlight'], drop_needle=True)
|
body = parser.parse_statements(['name:endhighlight'], drop_needle=True)
|
||||||
|
|
||||||
return nodes.CallBlock(self.call_method('_highlight', [lang, parameters]),
|
return nodes.CallBlock(self.call_method('_highlight', [lang, formatter, parameters]),
|
||||||
[], [], body).set_lineno(lineno)
|
[], [], body).set_lineno(lineno)
|
||||||
|
|
||||||
def _highlight(self, lang, parameters, caller=None):
|
def _highlight(self, lang, formatter, parameters, caller=None):
|
||||||
# highlight code using Pygments
|
# highlight code using Pygments
|
||||||
body = caller()
|
body = caller()
|
||||||
try:
|
try:
|
||||||
@@ -108,6 +113,9 @@ class HighlightExtension(Extension):
|
|||||||
lang = g.lang
|
lang = g.lang
|
||||||
parameters['tagurlformat'] = '/' + lang + '/%(path)s%(fname)s'
|
parameters['tagurlformat'] = '/' + lang + '/%(path)s%(fname)s'
|
||||||
|
|
||||||
formatter = I2PHtmlFormatter(**parameters)
|
if formatter == 'textspec':
|
||||||
|
formatter = TextSpecFormatter(**parameters)
|
||||||
|
else:
|
||||||
|
formatter = I2PHtmlFormatter(**parameters)
|
||||||
code = highlight(Markup(body).unescape(), lexer, formatter)
|
code = highlight(Markup(body).unescape(), lexer, formatter)
|
||||||
return code
|
return code
|
||||||
|
@@ -23,7 +23,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
ctags = None
|
ctags = None
|
||||||
|
|
||||||
__all__ = ['I2PHtmlFormatter']
|
__all__ = ['I2PHtmlFormatter', 'TextSpecFormatter']
|
||||||
|
|
||||||
|
|
||||||
_escape_html_table = {
|
_escape_html_table = {
|
||||||
@@ -829,3 +829,70 @@ class I2PHtmlFormatter(Formatter):
|
|||||||
|
|
||||||
for t, piece in source:
|
for t, piece in source:
|
||||||
outfile.write(piece)
|
outfile.write(piece)
|
||||||
|
|
||||||
|
|
||||||
|
class TextSpecFormatter(Formatter):
|
||||||
|
"""
|
||||||
|
Output the text unchanged without any formatting.
|
||||||
|
"""
|
||||||
|
name = 'Text spec'
|
||||||
|
aliases = ['textspec']
|
||||||
|
filenames = ['*.txt']
|
||||||
|
|
||||||
|
def __init__(self, **options):
|
||||||
|
Formatter.__init__(self, **options)
|
||||||
|
self.tagsfile = self._decodeifneeded(options.get('tagsfile', ''))
|
||||||
|
self.tagurlformat = self._decodeifneeded(options.get('tagurlformat', ''))
|
||||||
|
|
||||||
|
if self.tagsfile:
|
||||||
|
if not ctags:
|
||||||
|
raise RuntimeError('The "ctags" package must to be installed '
|
||||||
|
'to be able to use the "tagsfile" feature.')
|
||||||
|
self._ctags = ctags.CTags(self.tagsfile)
|
||||||
|
|
||||||
|
def _decodeifneeded(self, value):
|
||||||
|
if isinstance(value, bytes):
|
||||||
|
if self.encoding:
|
||||||
|
return value.decode(self.encoding)
|
||||||
|
return value.decode()
|
||||||
|
return value
|
||||||
|
|
||||||
|
def format(self, tokensource, outfile):
|
||||||
|
enc = self.encoding
|
||||||
|
tagsfile = self.tagsfile
|
||||||
|
refs = {}
|
||||||
|
|
||||||
|
for ttype, value in tokensource:
|
||||||
|
if tagsfile and ttype in Token.Name.Class:
|
||||||
|
filename, kind = self._lookup_ctag(value)
|
||||||
|
# Handle message types
|
||||||
|
if not kind and value.endswith('Message'):
|
||||||
|
value = value[:-7]
|
||||||
|
filename, kind = self._lookup_ctag(value)
|
||||||
|
if kind:
|
||||||
|
base, filename = os.path.split(filename)
|
||||||
|
if base:
|
||||||
|
base += '/'
|
||||||
|
filename, extension = os.path.splitext(filename)
|
||||||
|
url = self.tagurlformat % {'path': base, 'fname': filename,
|
||||||
|
'fext': extension}
|
||||||
|
refs[value] = '\n[%s]: %s#%s_%s' % (value, url, kinds[kind], value)
|
||||||
|
value = '[%s]' % value
|
||||||
|
|
||||||
|
if enc:
|
||||||
|
outfile.write(value.encode(enc))
|
||||||
|
else:
|
||||||
|
outfile.write(value)
|
||||||
|
|
||||||
|
for ref in refs.values():
|
||||||
|
if enc:
|
||||||
|
outfile.write(ref.encode(enc))
|
||||||
|
else:
|
||||||
|
outfile.write(ref)
|
||||||
|
|
||||||
|
def _lookup_ctag(self, token):
|
||||||
|
entry = ctags.TagEntry()
|
||||||
|
if self._ctags.find(entry, token, 0):
|
||||||
|
return entry['file'], entry['kind']
|
||||||
|
else:
|
||||||
|
return None, None
|
||||||
|
Reference in New Issue
Block a user