Я новичок в LaTex, и мои коллеги дали мне задачу. Они определяют тип документа в файле TeX (например, 'svvr', 'srs', ...). Это внешнее определение соответствует строкам 4 и 5 в моем примере кода (MWE 2).
Теперь я должен использовать это внешнее определение в моем файле TeX, чтобы решить, какая обработка, зависящая от документа, должна иметь место. Для этого я написал MWE для проверки выбора.
Мой тестовый код изначально взят из Интернета и сравнивает имя задания с заданной строкой (например, "{\detokenize{svvr}"). Я назвал свой TeX-файл "svvr.tex", чтобы иметь возможность сравнивать с \jobname.
Моя проблема теперь в том, что когда я сравниваю с \jobname (MWE 1), выбор работает правильно.
\documentclass{article}
% Own TeX file:
\begin{document}
\edef\docTypeExt{\jobname}
% Specify which document type is to be handled: 'svvr', 'srs', ...
\edef\docTypeSvvr{\detokenize{svvr}}
\edef\docTypeSrs{\detokenize{srs}}
\textbf{\jobname}
\textbf{\docShortcut}
\textbf{\docTypeSvvr}
\textbf{\docTypeSrs}
\newline
\ifx\docTypeExt\docTypeSvvr
true
\else
false: \\
\jobname \\
\docShortcut \\
\docTypeSvvr
\fi
\newline
\ifx\docTypeExt\docTypeSrs
true
\else
false: \\
\jobname \\
\docShortcut \\
\docTypeSrs
\fi
\end{document}
Но если я сравню это с внешним определением моих коллег (MWE 2), то сравнение окажется неверным.
\documentclass{article}
% Given code, defined in included TeX file: 'svvr', 'srs', ...
\newcommand { \docpropPTdocShortcut } {svvr} % Define document type here!
\gdef\docShortcut{\docpropPTdocShortcut}
% Own TeX file:
\begin{document}
\edef\docTypeExt{\docShortcut}
% Specify which document type is to be handled: 'svvr', 'srs', ...
\edef\docTypeSvvr{\detokenize{svvr}}
\edef\docTypeSrs{\detokenize{srs}}
\textbf{\jobname}
\textbf{\docShortcut}
\textbf{\docTypeSvvr}
\textbf{\docTypeSrs}
\newline
\ifx\docTypeExt\docTypeSvvr
true
\else
false: \\
\jobname \\
\docShortcut \\
\docTypeSvvr
\fi
\newline
\ifx\docTypeExt\docTypeSrs
true
\else
false: \\
\jobname \\
\docShortcut \\
\docTypeSrs
\fi
\end{document}
Как должен быть структурирован выбор, чтобы он также работал с внешним определением?
Я изменил определения, но все попытки пока не увенчались успехом.
решение1
Каждый токен символа, доставленный , \jobname
относится к категории 12 (другое). Исключение: пробелы (кодовая точка номер 32 как в ASCII, так и в Unicode) относятся к категории 10 (пробел). То же самое с токенами символа, доставленными \detokenize
.
Однако токены символов, которые в вашем втором примере попадают в текст замены, \docpropPTdocShortcut
не доставляются \jobname
или \detokenize
, а возникают из-за чтения TeX и токенизации вещей из файла .tex-input. При этом применяется другой режим кодирования категорий, так что многие токены символов, которые возникают таким образом, имеют категорию, отличную от 12(другие). Например, токены символов, обозначающие буквы алфавита, возникающие таким образом, обычно имеют категорию 11(буква).
Таким образом, токен управляющей последовательности \docTypeSvvr
или \docTypeSrs
, текст замены которого состоит только из токенов символов, которые происходят из \jobname
или \detokenize
и, следовательно, являются токенами символов категории 12(другие) или пробелами категории 10(пробел), имеет значение, которое отличается от значения управляющей последовательности, \docTypeExt
где те же символы были токенизированы категорией 11(буква).
Таким образом \ifx
, сравнение - с вашим вторым примером направляет к \else
-ветви.
Во втором примере вы можете либо опустить \detokenize
при определении \docTypeSvvr
/ \docTypeSrs
, либо применить \detokenize
, либо \@onelevel@sanitize
при определении \docTypeExt
.
\newline
, что заставляет LaTeX продолжать набор абзаца , но начинать другую строку абзаца, заканчивая ее пустой строкой, что заставляет LaTeX заканчивать текущий абзац, мне кажется излишним: Вы получаете вертикаль \baselineskip
из \newline
и вертикаль, \parskip
если она не равна нулю. Если вертикаль \parskip
равна нулю и в некоторых местах вы хотите сделать вертикальный пропуск между абзацами, не злоупотребляйте \newline
этим, а используйте \vspace
или \addvspave
или \vskip
или \smallskip
или \medskip
или \bigskip
.
\newcommand { \docpropPTdocShortcut } {svvr}
, где \docpropPTdocShortcut
после токенизации предшествует пробельный токен, не является хорошей практикой. Если нет в ExplSyntax, где пробелы будут игнорироваться уже во время токенизации, сделайте:
\newcommand{\docpropPTdocShortcut}{svvr}
.
В примере ниже \detokenize
выбран -маршрут, поэтому вы можете смело сравнивать его с макросами, текст замены которых составлен путем расширения, \jobname
если хотите.
\documentclass{article}
% Given code, defined in included TeX file: 'svvr', 'srs', ...
%% (In case the TeX file in question does not produce text/a chapter of the document,
%% \input might be a better choice than \include ...)
\newcommand{\docpropPTdocShortcut}{svvr}% Define document type here!
\gdef\docShortcut{\docpropPTdocShortcut}
% Own TeX file:
\begin{document}
\edef\docTypeExt{\docShortcut}%%
\edef\docTypeExt{\detokenize\expandafter{\docTypeExt}}%%
%\csname @onelevel@sanitize\endcsname\docTypeExt
%-----------------------------------------------------------------
% Specify which document type is to be handled: 'svvr', 'srs', ...
\edef\docTypeSvvr{\detokenize{svvr}}%%
\edef\docTypeSrs{\detokenize{srs}}%%
\noindent
\verb|\jobname|: \texttt{\jobname}\\
\verb|\docShortcut|: \texttt{\meaning\docShortcut}\\
\verb|\docTypeExt|: \texttt{\meaning\docTypeExt}\\
\verb|\docTypeSvvr|: \texttt{\meaning\docTypeSvvr}\\
\verb|\docTypeSrs|: \texttt{\meaning\docTypeSrs}
\vskip\baselineskip
\noindent
\ifx\docTypeExt\docTypeSvvr
true
\else
false:\\
\jobname\\
\docShortcut\\
\docTypeSvvr
\fi
\vskip\baselineskip
\noindent
\ifx\docTypeExt\docTypeSrs
true
\else
false:\\
\jobname\\
\docShortcut\\
\docTypeSrs
\fi
\end{document}