aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/markdown/extensions/fenced_code.py
diff options
context:
space:
mode:
Diffstat (limited to 'libs/markdown/extensions/fenced_code.py')
-rw-r--r--libs/markdown/extensions/fenced_code.py62
1 files changed, 37 insertions, 25 deletions
diff --git a/libs/markdown/extensions/fenced_code.py b/libs/markdown/extensions/fenced_code.py
index 409166ad8..da1a9be1e 100644
--- a/libs/markdown/extensions/fenced_code.py
+++ b/libs/markdown/extensions/fenced_code.py
@@ -1,20 +1,25 @@
-"""
-Fenced Code Extension for Python Markdown
-=========================================
+# Fenced Code Extension for Python Markdown
+# =========================================
-This extension adds Fenced Code Blocks to Python-Markdown.
+# This extension adds Fenced Code Blocks to Python-Markdown.
-See <https://Python-Markdown.github.io/extensions/fenced_code_blocks>
-for documentation.
+# See https://Python-Markdown.github.io/extensions/fenced_code_blocks
+# for documentation.
-Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
+# Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
+# All changes Copyright 2008-2014 The Python Markdown Project
-All changes Copyright 2008-2014 The Python Markdown Project
+# License: [BSD](https://opensource.org/licenses/bsd-license.php)
-License: [BSD](https://opensource.org/licenses/bsd-license.php)
"""
+This extension adds Fenced Code Blocks to Python-Markdown.
+See the [documentation](https://Python-Markdown.github.io/extensions/fenced_code_blocks)
+for details.
+"""
+
+from __future__ import annotations
from textwrap import dedent
from . import Extension
@@ -24,6 +29,10 @@ from .attr_list import get_attrs, AttrListExtension
from ..util import parseBoolValue
from ..serializers import _escape_attrib_html
import re
+from typing import TYPE_CHECKING, Any, Iterable
+
+if TYPE_CHECKING: # pragma: no cover
+ from markdown import Markdown
class FencedCodeExtension(Extension):
@@ -31,16 +40,19 @@ class FencedCodeExtension(Extension):
self.config = {
'lang_prefix': ['language-', 'Prefix prepended to the language. Default: "language-"']
}
+ """ Default configuration options. """
super().__init__(**kwargs)
def extendMarkdown(self, md):
- """ Add FencedBlockPreprocessor to the Markdown instance. """
+ """ Add `FencedBlockPreprocessor` to the Markdown instance. """
md.registerExtension(self)
md.preprocessors.register(FencedBlockPreprocessor(md, self.getConfigs()), 'fenced_code_block', 25)
class FencedBlockPreprocessor(Preprocessor):
+ """ Find and extract fenced code blocks. """
+
FENCED_BLOCK_RE = re.compile(
dedent(r'''
(?P<fence>^(?:~{3,}|`{3,}))[ ]* # opening fence
@@ -54,13 +66,13 @@ class FencedBlockPreprocessor(Preprocessor):
re.MULTILINE | re.DOTALL | re.VERBOSE
)
- def __init__(self, md, config):
+ def __init__(self, md: Markdown, config: dict[str, Any]):
super().__init__(md)
self.config = config
self.checked_for_deps = False
- self.codehilite_conf = {}
+ self.codehilite_conf: dict[str, Any] = {}
self.use_attr_list = False
- # List of options to convert to bool values
+ # List of options to convert to boolean values
self.bool_options = [
'linenums',
'guess_lang',
@@ -68,8 +80,8 @@ class FencedBlockPreprocessor(Preprocessor):
'use_pygments'
]
- def run(self, lines):
- """ Match and store Fenced Code Blocks in the HtmlStash. """
+ def run(self, lines: list[str]) -> list[str]:
+ """ Match and store Fenced Code Blocks in the `HtmlStash`. """
# Check for dependent extensions
if not self.checked_for_deps:
@@ -94,16 +106,16 @@ class FencedBlockPreprocessor(Preprocessor):
if m.group('lang'):
lang = m.group('lang')
if m.group('hl_lines'):
- # Support hl_lines outside of attrs for backward-compatibility
+ # Support `hl_lines` outside of `attrs` for backward-compatibility
config['hl_lines'] = parse_hl_lines(m.group('hl_lines'))
- # If config is not empty, then the codehighlite extension
+ # If `config` is not empty, then the `codehighlite` extension
# is enabled, so we call it to highlight the code
if self.codehilite_conf and self.codehilite_conf['use_pygments'] and config.get('use_pygments', True):
local_config = self.codehilite_conf.copy()
local_config.update(config)
- # Combine classes with cssclass. Ensure cssclass is at end
- # as pygments appends a suffix under certain circumstances.
+ # Combine classes with `cssclass`. Ensure `cssclass` is at end
+ # as Pygments appends a suffix under certain circumstances.
# Ignore ID as Pygments does not offer an option to set it.
if classes:
local_config['css_class'] = '{} {}'.format(
@@ -128,9 +140,9 @@ class FencedBlockPreprocessor(Preprocessor):
if id:
id_attr = f' id="{_escape_attrib_html(id)}"'
if self.use_attr_list and config and not config.get('use_pygments', False):
- # Only assign key/value pairs to code element if attr_list ext is enabled, key/value pairs
- # were defined on the code block, and the `use_pygments` key was not set to True. The
- # `use_pygments` key could be either set to False or not defined. It is omitted from output.
+ # Only assign key/value pairs to code element if `attr_list` extension is enabled, key/value
+ # pairs were defined on the code block, and the `use_pygments` key was not set to `True`. The
+ # `use_pygments` key could be either set to `False` or not defined. It is omitted from output.
kv_pairs = ''.join(
f' {k}="{_escape_attrib_html(v)}"' for k, v in config.items() if k != 'use_pygments'
)
@@ -143,8 +155,8 @@ class FencedBlockPreprocessor(Preprocessor):
break
return text.split("\n")
- def handle_attrs(self, attrs):
- """ Return tuple: (id, [list, of, classes], {configs}) """
+ def handle_attrs(self, attrs: Iterable[tuple[str, str]]) -> tuple[str, list[str], dict[str, Any]]:
+ """ Return tuple: `(id, [list, of, classes], {configs})` """
id = ''
classes = []
configs = {}
@@ -161,7 +173,7 @@ class FencedBlockPreprocessor(Preprocessor):
configs[k] = v
return id, classes, configs
- def _escape(self, txt):
+ def _escape(self, txt: str) -> str:
""" basic html escaping """
txt = txt.replace('&', '&amp;')
txt = txt.replace('<', '&lt;')