매크로의 쉼표로 구분된 인수 목록에서 _(밑줄) 처리

매크로의 쉼표로 구분된 인수 목록에서 _(밑줄) 처리

문맥:" -like" 매크로를 만들었습니다 \citep. 나는 부록에 있는 일부 코드를 참조하기 위해 문서 본문에서 이 용어를 사용합니다.

내 매크로는 쉼표로 구분된 목록을 입력으로 사용하고 목록의 각 요소를 hyperref코드의 관련 부분에 대한 링크로 인쇄합니다. (쉽게 설명하자면 hyperref링크의 텍스트가 키 자체이고 링크 앵커의 구문은 입니다 code:<key>.)

\documentclass{article}
    \usepackage{etoolbox}
    \usepackage{hyperref}
    \usepackage{lipsum}

    \newcommand{\codecitep}[1]{% cf. https://tex.stackexchange.com/a/87423/64454
        [%
        \def\nextitem{\def\nextitem{, }}% Separator
        \renewcommand*{\do}[1]{\nextitem{\hyperref[code:##1]{##1}}}% How to process each item
        \docsvlist{#1}% Process list
        ]%
    }   
\begin{document}
    \section{Body}
        A sentence with one code-citation only \codecitep{key1}.
        Another sentence with two code-citations and followed by dummy text \codecitep{key1, key2}.
%       A sentence with one code-citation only \codecitep{a_123}.
%       Another sentence with two code-citations and followed by dummy text \codecitep{a_123, bb_456}.

        \lipsum[1-2]

    \section{Appendix}
        \lipsum[3]

        \subsection{key1}
        \label{code:key1}
        \label{code:a_123}
        \lipsum[4]

        \subsection{key2}
        \label{code:key2}
        \label{code:bb_456}
        \lipsum[5]
\end{document}

문제: 위의 MWE는 훌륭하게 작동합니다. 그러나 실제 키의 구조는 a_123, bb_456등입니다. (즉, 키 중간에 밑줄이 있고 그 앞의 문자 수를 알 수 없습니다.) 물론 밑줄이 둘 다 아니기 때문에 컴파일이 실패합니다. 탈출하거나 수학 환경에서.

질문:내 매크로의 쉼표로 구분된 인수 목록에서 밑줄이 있는 키를 처리하는 방법은 무엇입니까?

답변1

당신이 사용할 수있는 \detokenize; 하지만 당신이 원한다면인쇄된fontenc밑줄을 그으면 옵션을 로드해야 합니다 T1.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{lipsum}

\newcommand{\codecitep}[1]{% cf. https://tex.stackexchange.com/a/87423/64454
  [%
  \def\nextitem{\def\nextitem{, }}% Separator
  % How to process each item
  \renewcommand*{\do}[1]{%
    \nextitem\hyperref[code:##1]{\detokenize{##1}}%
  }%
  \docsvlist{#1}% Process list
  ]%
}   
\begin{document}

\section{Body}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by dummy text \codecitep{key1, key2}.
A sentence with one code-citation only \codecitep{a_123}.
Another sentence with two code-citations and followed by dummy text \codecitep{a_123, bb_456}.

\lipsum[1-2]

\section{Appendix}
\lipsum[3]

\subsection{key1}
\label{code:key1}
\label{code:a_123}
\lipsum[4]

\subsection{key2}
\label{code:key2}
\label{code:bb_456}
\lipsum[5]
\end{document}

여기에 이미지 설명을 입력하세요

expl3가 필요하지 않은 버전이 있습니다 fontenc.

\documentclass{article}
\usepackage{xparse}
\usepackage{hyperref}
\usepackage{lipsum}

\ExplSyntaxOn

% define a token list containing an underscore
\tl_const:Nx \c_ebo_codecite_us_tl { \char_generate:nn { `_ } { 8 } }

% the main macro
\NewDocumentCommand{\codecitep}{m}
 {
  \ebo_codecite:n { #1 }
 }

% variables and variants of kernel functions
\tl_new:N \l__ebo_codecite_key_print_tl
\seq_new:N \l__ebo_codecite_refs_seq

\cs_generate_variant:Nn \tl_replace_all:Nnn { NV }

% functions

\cs_new_protected:Nn \ebo_codecite:n
 {
  [
   % clear the sequence
   \seq_clear:N \l__ebo_codecite_refs_seq
   % loop through the input
   \clist_map_inline:nn { #1 }
    {
     % for the "print part", change _ into \_
     \tl_set:Nn \l__ebo_codecite_key_print_tl { ##1 }
     \tl_replace_all:NVn \l__ebo_codecite_key_print_tl \c_ebo_codecite_us_tl { \_ }
     % add to the sequence
     \__ebo_codecitep_add:nV { ##1 } \l__ebo_codecite_key_print_tl
    }
   % use the sequence, items separated by "comma space"
   \seq_use:Nn \l__ebo_codecite_refs_seq { ,~ }
  ]
 }

% an auxiliary function, for expanding the second argument
\cs_new_protected:Nn \__ebo_codecitep_add:nn
 {
  \seq_put_right:Nn \l__ebo_codecite_refs_seq { \hyperref[code:#1]{#2} }
 }
\cs_generate_variant:Nn \__ebo_codecitep_add:nn { nV }

\ExplSyntaxOff

\begin{document}

\section{Body}
A sentence with one code-citation only \codecitep{key1}.
Another sentence with two code-citations and followed by dummy text \codecitep{key1, key2}.
A sentence with one code-citation only \codecitep{a_123}.
Another sentence with two code-citations and followed by dummy text \codecitep{a_123, bb_456}.

\lipsum[1-2]

\section{Appendix}
\lipsum[3]

\subsection{key1}
\label{code:key1}
\label{code:a_123}
\lipsum[4]

\subsection{key2}
\label{code:key2}
\label{code:bb_456}
\lipsum[5]
\end{document}

여기에 이미지 설명을 입력하세요

답변2

이를 수행하는 가장 간단한 방법은 패키지를 로드 url하고 참조 이름 형식을 지정하는 url 명령을 정의하는 것입니다.

\usepackage{url}
\DeclareUrlCommand{\coderefname}{\urlstyle{rm}}

\newcommand{\codecitep}[1]{% cf. https://tex.stackexchange.com/a/87423/64454
    [%
    \def\nextitem{\def\nextitem{, }}% Separator
    \renewcommand*{\do}[1]{\nextitem{\hyperref[code:##1]{\coderefname{##1}}}}% How to process each item
    \docsvlist{#1}% Process list
    ]%
}

관련 정보