Сравнение макросов не удалось

Сравнение макросов не удалось

Я новичок в 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}

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