varia.website/venv/lib/python3.11/site-packages/pelican/rstdirectives.py
2024-11-19 14:01:39 +01:00

91 lines
2.9 KiB
Python

import re
from docutils import nodes, utils
from docutils.parsers.rst import Directive, directives, roles
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import TextLexer, get_lexer_by_name
import pelican.settings as pys
class Pygments(Directive):
""" Source code syntax highlighting.
"""
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {
'anchorlinenos': directives.flag,
'classprefix': directives.unchanged,
'hl_lines': directives.unchanged,
'lineanchors': directives.unchanged,
'linenos': directives.unchanged,
'linenospecial': directives.nonnegative_int,
'linenostart': directives.nonnegative_int,
'linenostep': directives.nonnegative_int,
'lineseparator': directives.unchanged,
'linespans': directives.unchanged,
'nobackground': directives.flag,
'nowrap': directives.flag,
'tagsfile': directives.unchanged,
'tagurlformat': directives.unchanged,
}
has_content = True
def run(self):
self.assert_has_content()
try:
lexer = get_lexer_by_name(self.arguments[0])
except ValueError:
# no lexer found - use the text one instead of an exception
lexer = TextLexer()
# Fetch the defaults
if pys.PYGMENTS_RST_OPTIONS is not None:
for k, v in pys.PYGMENTS_RST_OPTIONS.items():
# Locally set options overrides the defaults
if k not in self.options:
self.options[k] = v
if ('linenos' in self.options and
self.options['linenos'] not in ('table', 'inline')):
if self.options['linenos'] == 'none':
self.options.pop('linenos')
else:
self.options['linenos'] = 'table'
for flag in ('nowrap', 'nobackground', 'anchorlinenos'):
if flag in self.options:
self.options[flag] = True
# noclasses should already default to False, but just in case...
formatter = HtmlFormatter(noclasses=False, **self.options)
parsed = highlight('\n'.join(self.content), lexer, formatter)
return [nodes.raw('', parsed, format='html')]
directives.register_directive('code-block', Pygments)
directives.register_directive('sourcecode', Pygments)
_abbr_re = re.compile(r'\((.*)\)$', re.DOTALL)
class abbreviation(nodes.Inline, nodes.TextElement):
pass
def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
text = utils.unescape(text)
m = _abbr_re.search(text)
if m is None:
return [abbreviation(text, text)], []
abbr = text[:m.start()].strip()
expl = m.group(1)
return [abbreviation(abbr, abbr, explanation=expl)], []
roles.register_local_role('abbr', abbr_role)