tcolorbox 文档:记录动态键路径

tcolorbox 文档:记录动态键路径

我正在记录一个具有某些动态创建的关键路径的包(通过某些命令或通过 pgfkeys 处理程序动态创建.unknown)。

我想用docKeytcolorbox 的环境记录这些键,但第一个参数(可选和强制)不适用于诸如 之类的宏\meta{}

有没有正确的方法可以做到这一点?

梅威瑟:

\documentclass{article}

\usepackage{tcolorbox}
\tcbuselibrary{documentation}

\begin{document}

\begin{docKey}
    [mypackage/keypath]
    {my key}
    {=value}
    {}
    The \texttt{keypath} part of the key path is dynamic. Using \meta{keypath} breaks.

    Putting both in the mandatory argument as \verb|{\meta{keypath}/my key}| also breaks.
    
    What is the best alternative?
\end{docKey}

\end{document}

答案1

tcolorbox假设环境的第一个可选参数的值docKey(也是 key 的值/tcb/doc keypath)是完全可扩展的,并在打印、标签名称和索引名称中使用它。由于\meta{...}不完全可扩展,因此会引发错误。

在下面的例子中,我将角色拆分doc keypath成四个:

  • 打印按键名称
  • 标签名称,可以通过doc keypath label
  • 打印索引名称,可以通过设置doc keypath index
  • 排序的索引名称,可以通过 设置doc keypath sort index

修改doc keypath后将设置所有这四个,而新键doc formatted keypath将设置第一个和第三个。

用法:

\begin{docKey}
    [keypath][doc formatted keypath=\meta{keypath}]
    {my key}
    {=value}
    {}
\end{docKey}

See \refKey{/keypath/my key}.

完整示例:

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{documentation}
\makeindex

\makeatletter
\newif\iftcb@doc@formatted@keypath

\tcbset{
  doc keypath/.style={%
    doc@keypath={#1},
    doc keypath label={#1},
    doc keypath index={#1},doc keypath sort index={#1},
  },
  doc@keypath/.store in=\kvtcb@doc@keypath,
  doc formatted keypath/.code=%
    \tcb@doc@formatted@keypathtrue
    \pgfkeysalso{doc@keypath=#1,doc keypath index=#1},
%  doc keypath name/.store in=\kvtcb@doc@keypath,
  doc keypath label/.store in=\kvtcb@doc@keypath@label,
  doc keypath index/.store in=\kvtcb@doc@keypath@index,
  doc keypath sort index/.store in=\kvtcb@doc@keypath@sortindex,
}

\ExplSyntaxOn
\cs_set_nopar:Npn \__tcobox_print_key:
  {
    \textcolor{\kvtcb@col@key}{\tcb@doc@bfseries\ttfamily
    \tl_if_empty:NF \kvtcb@doc@keypath
      {
        \iftcb@doc@formatted@keypath
          /\kvtcb@doc@keypath/
        \else
          /\__tcobox_sanitize_tl:V\kvtcb@doc@keypath/
        \fi
      }
    \__tcobox_sanitize_tl:V\kvtcb@doc@name}
  }

\cs_set_nopar:Npn \__tcobox_index_key:
  {
    \iftcb@doc@toindex
      \kvtcb@index@command{\kvtcb@doc@sortindex\idx@actual\tcbIndexPrintKeyCA{\kvtcb@doc@index}}
      \tl_if_empty:NTF \kvtcb@doc@keypath@index
        {
          \kvtcb@index@command{\kvtcb@text@keys\idx@level\kvtcb@doc@sortindex\idx@actual\tcbIndexPrintKeyC{\kvtcb@doc@index}}
        }
        {
          \kvtcb@index@command{\kvtcb@text@keys\idx@level\kvtcb@doc@keypath@sortindex\idx@actual\tcbIndexPrintKeyC{/\kvtcb@doc@keypath@index/}
            \idx@level\kvtcb@doc@sortindex\idx@actual\tcbIndexPrintKeyC{\kvtcb@doc@index}}
        }
    \fi
  }

\cs_set:Npn \__tcobox_doc_head_key:
  {
    \__tcobox_print_key:
    \__tcobox_index_key:
    \tl_if_empty:NTF \kvtcb@doc@keypath@label
      {
        \seq_if_in:NVF \g__tcobox_label_seq \kvtcb@doc@label
          {
            \protected@edef\@currentlabel{\kvtcb@doc@name}
            \label{key:\kvtcb@doc@label}
            \seq_gput_left:NV \g__tcobox_label_seq \kvtcb@doc@label
          }
      }
      {
        \tl_set:Nx \l_tmpa_tl {/\kvtcb@doc@keypath@label/\kvtcb@doc@label}
        \seq_if_in:NVF \g__tcobox_label_seq \l_tmpa_tl
          {
            \protected@edef\@currentlabel{/\kvtcb@doc@keypath/\kvtcb@doc@name}
            \label{key:/\kvtcb@doc@keypath@label/\kvtcb@doc@label}
            \seq_gput_left:NV \g__tcobox_label_seq \l_tmpa_tl
          }
      }
    {\ttfamily\kvtcb@doc@parameter}
    \tcb@doc@do@description
  }
\ExplSyntaxOff
\makeatother


\begin{document}

\begin{docKey}
    [keypath][doc formatted keypath=\meta{keypath}]
    {my key}
    {=value}
    {}
    The \texttt{keypath} part of the key path is dynamic. Using \meta{keypath} breaks.

    Putting both in the mandatory argument as \verb|{\meta{keypath}/my key}| also breaks.
    
    What is the best alternative?
\end{docKey}

See \refKey{/keypath/my key}.

\printindex

\end{document}

在此处输入图片描述 在此处输入图片描述

答案2

感谢@Marijn 和@mushimushiZ 的详细回答!我正在研究它们,以寻找思路和技巧。

至于这个特定问题,事实证明,可以使用 tcolorbox 本身提供的选项来解决,通过doc label键,如果宏保留在键本身中(而不是在可选路径参数中):

\documentclass{article}

\usepackage{tcolorbox}
\tcbuselibrary{documentation}

\makeindex

\begin{document}

\begin{docKey}
    [mypackage]
    [doc label=keypath/mykey]
    {\meta{keypath}/my key}
    {=value}
    {}
    The \texttt{keypath} part of the key path is dynamic and corresponds to ...
\end{docKey}

Can be referenced: \refKey{/mypackage/keypath/mykey}

\printindex

\end{document}

文档

指数

答案3

问题在于,可选参数和强制参数都用于创建用于引用的标签\refKey,即\refKey{/mypackage/keypath/my key}。标签值中\meta不允许使用诸如这样的命令。

您可以稍微修改 的定义docKey以规避此问题,方法是将标签定义为名称,不带可选前缀。一种方法是从源复制定义tcolorbox并使用\RenewDocumentEnvironment它进行更改。

梅威瑟:

\documentclass{article}

\usepackage{tcolorbox}
\tcbuselibrary{documentation}
\makeatletter
\RenewDocumentEnvironment{docKey}{ O{} +O{} m m +m }{\tcbset{#2,doc description={#5}}%
  \begin{tcb@manual@entry}%
  \begin{tcb@doc@head}{doc@head@key}%
  \ifblank{#1}{%
    \tcb@Print@Key{#3}\tcb@index@Key{#3}\protected@edef\@currentlabel{#3}\label{key:#3}{\ttfamily #4}%
  }{%
    \tcb@Print@Key{/#1/#3}%
    % CHANGE OF LABEL IN FOLLOWING LINE %
    \tcb@index@KeyPath{#1}{#3}\protected@edef\@currentlabel{/#1/#3}\label{key:#3}{\ttfamily #4}%
  }%
  \tcb@doc@do@description%
  \end{tcb@doc@head}\nobreak\tcbset{before upper=}\kvtcb@doc@body@key@before\ignorespaces}%
  {\ifvmode\else\unskip\fi\kvtcb@doc@body@key@after\end{tcb@manual@entry}}
\makeatother


\begin{document}
\begin{docKey}
    [mypackage/\meta{keypath}]
    {my key}
    {=value}
    {}
    The \texttt{keypath} part of the key path is dynamic. Using \meta{keypath} breaks.

    Putting both in the mandatory argument as \verb|{\meta{keypath}/my key}| also breaks.
    
    What is the best alternative?
\end{docKey}

See \refKey{my key}.

\end{document}

结果:

在此处输入图片描述

备注:可能\textit{<keypath>}比以下更好\meta{keypath}

在此处输入图片描述

相关内容