Я пытаюсь написать собственный лексер Pygments для LaTeX, начиная с лексера по умолчанию.Пока у меня есть
from pygments.lexer import RegexLexer, include
from pygments.token import *
# We rip off the default styles.
Normaltext = Generic.Inserted
Mathtext = Generic.Deleted
Controlsequence = Keyword
Controlword = Controlsequence
Controlsymbol = Keyword.Pseudo
Specialchar = Name.Builtin
class MyTexLexer(RegexLexer):
"""
Custom lexer for the TeX and LaTeX typesetting languages.
"""
tokens = {
'general': [
(r'%.*?\n', Comment),
(r'\\[a-zA-Z]+', Controlword),
(r'\\.', Controlsymbol),
(r'\\$', Controlsymbol),
(r'[&_^{}]', Specialchar),
],
'root': [
(r'\$\$', Specialchar, 'displaymath'),
(r'\\\(', Controlsymbol, 'inlinemath'),
(r'\$', Specialchar, 'inlinemath'),
(r'\\\[', Controlsymbol, 'displaymath'),
include('general'),
(r'[^\\$%&_^{}]+', Normaltext),
],
'math': [
include('general'),
(r'[^\\$%&_^{}]+', Mathtext),
],
'inlinemath': [
(r'\\\)', Controlsymbol, '#pop'),
(r'\$', Specialchar, '#pop'),
include('math'),
],
'displaymath': [
(r'\\\]', Controlsymbol, '#pop'),
(r'\$\$', Specialchar, '#pop'),
include('math'),
],
}
Теперь TeX немного своеобразен в кодах этой категории, и, следовательно, язык может быть изменен во время компиляции.Мне не нужна поддержка для всего этого.
Одна вещь, которая встречается довольно часто, и я хотел бы поддержать, это использование \makeatletter
и \makeatother
, которые в основном позволяют илизапретить использование @
в именах управляющих слов.Я хотел бы эффективно изменить регулярное выражение для контрольных слов на r'\\[a-zA-Z@]+'
всякий раз, когда найден \makeatletter
, и обратно на r'\\[a-zA-Z]+'
, когда найден \makeatother
.
Есть ли способ динамически изменить поведениекласс таким образом?
Я не уверен, нужен ли пример TeX, но чтобы быть уверенным, это должно прояснить желаемое поведение:
% Here, \relax is a macro name and @or@do@something is just text:
\relax@or@do@something
\makeatletter
% Here, \relax@or@do@something is the macro name:
\relax@or@do@something
\makeatother
% Here, it's like in the first case:
\relax@or@do@something