documentation de tcolorbox: documentation des chemins d'accès dynamiques
Je documente un package qui a certains chemins clés qui sont créés dynamiquement (soit par une commande ou à la volée via le .unknowngestionnaire pgfkeys ).
Je souhaite documenter ces clés avec l' docKeyenvironnement de tcolorbox, mais les premiers arguments (facultatifs et obligatoires) ne fonctionnent pas avec des macros telles que \meta{}.
Existe-t-il une bonne façon de procéder?
MWE:
\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}
Réponses
tcolorboxsuppose que la valeur du premier argument facultatif de l' docKeyenvironnement (également la valeur de la clé /tcb/doc keypath) est entièrement extensible et l'utilise pour l'impression, le nom de l'étiquette et le nom de l'index. Étant donné qu'il \meta{...}n'est pas entièrement extensible, des erreurs sont générées.
Dans l'exemple suivant, j'ai divisé le rôle de doc keypathen quatre:
- nom de la clé imprimé
- nom de l'étiquette, peut être défini par
doc keypath label - nom d'index imprimé, peut être défini par
doc keypath index - nom d'index trié, peut être défini par
doc keypath sort index.
Modifié doc keypathdéfinira les quatre d'entre eux et une nouvelle clé doc formatted keypathdéfinira à la fois le premier et le troisième.
Usage:
\begin{docKey}
[keypath][doc formatted keypath=\meta{keypath}]
{my key}
{=value}
{}
\end{docKey}
See \refKey{/keypath/my key}.
Exemple complet:
\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}
Merci pour les réponses détaillées, @Marijn & @mushimushiZ! Je les étudie pour des idées et des techniques.
Quant à ce problème spécifique, il s'avère qu'il est possible de faire avec les options fournies par tcolorbox lui-même, via la doc labelclé, si les macros sont conservées dans la clé elle-même (et non dans l'argument de chemin optionnel):
\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}
Le problème est que les arguments optionnel et obligatoire sont tous deux utilisés pour créer une étiquette pour référencer avec \refKey, c'est-à-dire \refKey{/mypackage/keypath/my key}. Dans la valeur d'une étiquette, les commandes telles que \metane sont pas autorisées.
Vous pouvez modifier docKeylégèrement la définition de pour contourner le problème, en définissant l'étiquette comme étant simplement le nom sans le préfixe facultatif. Une façon de faire est de copier la définition de la tcolorboxsource et de l'utiliser \RenewDocumentEnvironmentpour apporter les modifications.
MWE:
\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}
Résultat:
Remarque: c'est peut \textit{<keypath>}- être mieux que \meta{keypath}: