2022-05-23 00:16:32 +04:00

104 lines
3.1 KiB
Python

"""This preprocessor detect cells using a different language through
magic extensions such as `%%R` or `%%octave`. Cell's metadata is marked
so that the appropriate highlighter can be used in the `highlight`
filter.
"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import re
from traitlets import Dict
from .base import Preprocessor
class HighlightMagicsPreprocessor(Preprocessor):
"""
Detects and tags code cells that use a different languages than Python.
"""
# list of magic language extensions and their associated pygment lexers
default_languages = Dict(
{
"%%R": "r",
"%%bash": "bash",
"%%cython": "cython",
"%%javascript": "javascript",
"%%julia": "julia",
"%%latex": "latex",
"%%octave": "octave",
"%%perl": "perl",
"%%ruby": "ruby",
"%%sh": "sh",
"%%sql": "sql",
}
)
# user defined language extensions
languages = Dict(
help=(
"Syntax highlighting for magic's extension languages. "
"Each item associates a language magic extension such as %%R, "
"with a pygments lexer such as r."
)
).tag(config=True)
def __init__(self, config=None, **kw):
"""Public constructor"""
super().__init__(config=config, **kw)
# Update the default languages dict with the user configured ones
self.default_languages.update(self.languages)
# build a regular expression to catch language extensions and choose
# an adequate pygments lexer
any_language = "|".join(self.default_languages.keys())
self.re_magic_language = re.compile(rf"^\s*({any_language})\s+")
def which_magic_language(self, source):
"""
When a cell uses another language through a magic extension,
the other language is returned.
If no language magic is detected, this function returns None.
Parameters
----------
source: str
Source code of the cell to highlight
"""
m = self.re_magic_language.match(source)
if m:
# By construction of the re, the matched language must be in the
# languages dictionary
return self.default_languages[m.group(1)]
else:
return None
def preprocess_cell(self, cell, resources, cell_index):
"""
Tags cells using a magic extension language
Parameters
----------
cell : NotebookNode cell
Notebook cell being processed
resources : dictionary
Additional resources used in the conversion process. Allows
preprocessors to pass variables into the Jinja engine.
cell_index : int
Index of the cell being processed (see base.py)
"""
# Only tag code cells
if cell.cell_type == "code":
magic_language = self.which_magic_language(cell.source)
if magic_language:
cell["metadata"]["magics_language"] = magic_language
return cell, resources