%20%E3%81%AE%E5%87%A6%E7%90%86.png)
コンテクスト:「\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
パッケージをロードし、refnames をフォーマットする 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
]%
}