替换 \label 内的 #

替换 \label 内的 #

我们目前在文档中使用唯一 ID,可以通过添加一个或多个标签来扩展。标签始终以井号开头,例如 MY.REQ.ID.42#TAG1#TAG2

以下代码是我们用来生成“美观”需求的宏的一部分:

\textbf{#1}\def\@currentlabel{#1}\label{req:#1}

连同列出所有要求的列表,\label 中的 # 字符存在问题。因此,我正在寻找一种方法来摆脱该字符,方法是将其替换为其他字符,例如“..”或“HASH”。

任何想法都将不胜感激...

谢谢,再见,aronadaal

\documentclass[a4paper]{scrartcl}
\usepackage[left=2cm,right=2cm,top=2.5cm,bottom=2cm]{geometry}
\setlength\parindent{0pt}

\makeatletter
\newcommand{\req}[2]{%
  \begingroup%
    \textbf{#1}\def\@currentlabel{#1}\label{req:#1}~#2\newline
  \endgroup%
  \addcontentsline{lor}{requirement}{#1}%
} %

\DeclareNewTOC[%
  type=requirement, %
  types=requirements, %
  name=Anforderung, %
  listname={List of Requirements} %
]{lor}
\setuptoc{lor}{chapteratlist}

\begin{document}
\section{Test}
\req{MY.REQ.ID.42}{Lorem ipsum dolor sit amet,...}

\req{MY.REQ.ID.43\#BROKEN}{this requirement is broken,...}

Please have a look at \ref{req:MY.REQ.ID.42} on page~\pageref{req:MY.REQ.ID.42}

\listofrequirements

\end{document}

日志文件的一部分:

(./req_test.aux
! Missing \endcsname inserted.
<to be read again> 
\#
l.5 ...REQ.ID.43\#BROKEN}{{MY.REQ.ID.43\#BROKEN}{1}}

The control sequence marked <to be read again> should
not appear between \csname and \endcsname.


LaTeX Warning: Label `req:MY.REQ.ID.43\#BROKEN' multiply defined.

! Missing \endcsname inserted.
<to be read again> 
\#
l.5 ...REQ.ID.43\#BROKEN}{{MY.REQ.ID.43\#BROKEN}{1}}

The control sequence marked <to be read again> should
not appear between \csname and \endcsname.

)

答案1

在您的示例中,您使用了\#参数\req。如果这不是问题,您可以在生成标签时简单地在本地重新定义其含义。例如,您可以用\label{req:#1}替换{\def\#{REPLACEMENT}\xdef\lbl{req:#1}}\label{\lbl}

例子:

\documentclass[a4paper]{scrartcl}
\usepackage[left=2cm,right=2cm,top=2.5cm,bottom=2cm]{geometry}
\setlength\parindent{0pt}

\makeatletter
\newcommand{\hashtag}{\#}
\newcommand{\req}[2]{%

\begingroup%
\textbf{#1}{\def\@currentlabel{#1}{\def\#{::}\xdef\lbl{req:#1}}\label{\lbl}}~#2\newline%
\endgroup%
\addcontentsline{lor}{requirement}{#1}%
} %

\DeclareNewTOC[%
type=requirement, %
types=requirements, %
name=Anforderung, %
listname={List of Requirements} %
]{lor}
\setuptoc{lor}{chapteratlist}

\begin{document}
\section{Test}
\req{MY.REQ.ID.42}{Lorem ipsum dolor sit amet,...}%
\req{MY.REQ.ID.42\#WORKING}{this requirement is broken,...}

Please have a look at \ref{req:MY.REQ.ID.42} on page~\pageref{req:MY.REQ.ID.42}

Please have a look at \ref{req:MY.REQ.ID.42::WORKING} on page~\pageref{req:MY.REQ.ID.42::WORKING}

\listofrequirements

\end{document}

答案2

因为到现在还没有简单的解决方案,所以我把它放在:

\protected\edef\#{\string#}

答案3

好吧,这确实有效,但这是一个非常卑鄙的伎俩。我希望我稍后能设法注释代码。有一件事是肯定的:它极其脆弱(并且不可能增强)。

\documentclass[a4paper]{scrartcl}
\usepackage[left=2cm,right=2cm,top=2.5cm,bottom=2cm]{geometry}
\setlength\parindent{0pt}

\makeatletter
\def\req#1#2{%
  \begingroup
    \catcode`\#=13
    \makehashexcl
    \edef\aron@do@label{\noexpand\label{req:\scantokens{#1\noexpand}}}%
    \makehashhash
    {\bfseries\scantokens{#1\noexpand}}%
    \edef\@currentlabel{\scantokens{#1\noexpand}}%
    \aron@do@label
    ~#2\newline
    \edef\aron@do@lor{\noexpand\addcontentsline{lor}{requirement}{\scantokens{#1\noexpand}}}%
    \aron@do@lor
  \endgroup%
}

\def\refreq#1#2{%
  \begingroup
    \catcode`\#=13
    \makehashexcl
    \edef\aron@do@{\noexpand#1{req:\scantokens{#2\noexpand}}}%
    \aron@do@
  \endgroup
}

\catcode`\#=13
\def\makehashexcl{\def##{!}}
\def\makehashhash{\def##{\char35 }}
\makehashhash
\catcode`\#=6

\DeclareRobustCommand\HASH{\char35 }

\makeatother


\DeclareNewTOC[
  type=requirement,
  types=requirements,
  name=Anforderung,
  listname={List of Requirements}
]{lor}
\setuptoc{lor}{chapteratlist}

\begin{document}

\section{Test}

\req{MY.REQ.ID.42}{Lorem ipsum dolor sit amet,...}

\req{MY.REQ.ID.43#BROKEN}{this requirement is broken,...}

Please have a look at \ref{req:MY.REQ.ID.42} on page~\pageref{req:MY.REQ.ID.42}

Please have a look at \refreq\ref{MY.REQ.ID.43#BROKEN} on page~\refreq\pageref{MY.REQ.ID.43#BROKEN}

\listofrequirements

\end{document}

答案4

这里我利用包\convertchar的宏stringstrings来改变全部出现到\#?,并在标签中使用它。

\documentclass[a4paper]{scrartcl}
\usepackage[left=2cm,right=2cm,top=2.5cm,bottom=2cm]{geometry}
\usepackage{stringstrings}
\setlength\parindent{0pt}

\makeatletter
\newcommand{\req}[2]{%
  \convertchar[q]{#1}{\#}{?}%
  \begingroup%
    \textbf{#1}\def\@currentlabel{#1}\label{req:\thestring}~#2\newline
  \endgroup%
  \addcontentsline{lor}{requirement}{#1}%
} %

\DeclareNewTOC[%
  type=requirement, %
  types=requirements, %
  name=Anforderung, %
  listname={List of Requirements} %
]{lor}
\setuptoc{lor}{chapteratlist}

\begin{document}
\section{Test}
\req{MY.REQ.ID.42}{Lorem ipsum dolor sit amet,...}

\req{MY.REQ.ID.43\#BROKEN\#}{this requirement is broken,...}

Please have a look at \ref{req:MY.REQ.ID.42} on page~\pageref{req:MY.REQ.ID.42}

Please have a look at \ref{req:MY.REQ.ID.43?BROKEN?} on 
  page~\pageref{req:MY.REQ.ID.43?BROKEN?}

\listofrequirements

\end{document}

在此处输入图片描述

相关内容