Как обрабатывать активные символы Babel при написании пакета?

Как обрабатывать активные символы Babel при написании пакета?

В bodeplotпакете я определил новые среды, используя (определил так, чтобы избежать проблем с экстернализацией tikzграфики)

\documentclass{standalone}
\usepackage{pgfplots,xparse}
\pgfplotsset{compat=1.18}
\NewDocumentEnvironment{MyEnv}{O{}mm+b}{
  \begin{tikzpicture}
    \begin{semilogxaxis}[xmin={#2},xmax={#3},ymin=0,ymax=1]
      #4
    \end{semilogxaxis}
  \end{tikzpicture}
}{}

Я хочу, чтобы пользователи могли использовать новую среду для выполнения таких задач.

\begin{document}
  \begin{MyEnv}[]{1e-1}{1e4}
    \draw[thick,blue,dashed] (axis cs:1,0) -- (axis cs:100,1);
    \addplot[variable=t,domain=1e-1:1e4] gnuplot {(t>100)?0.2:0.5};
  \end{MyEnv}
\end{document}

Все это работает для документов на английском языке. Однако, если пользователь использует babelлюбой язык, который делает некоторые символы #4активными, документ не может быть скомпилирован. Например, если я добавлю

\usepackage[french]{babel}
\usetikzlibrary{babel}

к преамбуле, я получаю ошибки компиляции.

Мне удалось заставить это работать для работы на французском языке, проверив frenchbsetupи используя

\AddToHook{env/MyEnv/begin}{\shorthandoff{;:!?}}

если он обнаружен. Однако делать что-то подобное для каждого активного символа в каждом языке кажется неправильным подходом к решению этой проблемы.

Существует ли лучший способ обнаружения и управления активными символами в макросах, подобных этому, который будет работать со всеми языками, поддерживаемыми babel?

решение1

Я не уверен, как tikzобстоит дело с catcodes, но предполагаю, что их нужно как-то изменить на значения по умолчанию, обычно 12 ('other'). И единственный способ — с \shorthandoff(или с низким уровнем \catcode).

Однако, возможно, следующая идея подойдет вам: есть макрос с именем, \dospecialsхранящий «специальные» символы, и babelдобавляющий к нему сокращения. Поскольку они хранятся как макросы (т. е. ;хранятся как \;), нам нужен какой-то трюк, чтобы получить фактический символ. Тогда мы можем использовать \ifbabelshorthand:

\documentclass{article}

\usepackage[french]{babel}

\makeatletter
\let\shorthandlist\@empty
\def\do#1{%
  \begingroup
    \lccode`\~=`#1\relax
    \lowercase{\ifbabelshorthand~{\g@addto@macro\shorthandlist{~}}{}}
  \endgroup}
\dospecials
\makeatother

\show\shorthandlist

Это покажет ->~:;!?., который, если мы удалим символы, добавленные \show, будет ~:;!?. Это может не сработать для вас, но по крайней мере я попытался

Связанный контент