
情境:我創建了一個“ \citep
-like”巨集。我在文件正文中使用它來引用附錄中的一些程式碼。
我的巨集採用逗號分隔的清單作為輸入,並將清單的每個元素列印為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
]%
}