我正在为课程撰写讲义,并使用宏将周数插入到章节标题中,如下所示:
乳胶代码如下
\subsection{Finite fields\weektag}
周数存储在计数器中
\newcounter{weekcounter}
我现在希望在内容表中出现以下两种行为之一或两种行为:
Contents
...
3.3 Topic before
3.4 Week 7: Finite fields
3.5 Topic after
...
或者实际上每个小节(因此不仅仅是那些在小节标题中使用宏的小节)都会附加周数
Contents
...
3.3 Week 6: Topic before
3.4 Week 7: Finite fields
3.5 Week 7: Topic after
...
其中小节标题行为
\subsection{Topic before}
...
\subsection{Finite fields\weektag}
...
\subsection{Topic after}
我的第一个问题是
如何在宏内部确定我是在目录中还是在文本主体中,以根据情况改变宏的行为?
我的第二个问题是
我如何使用上述计数器将某些内容写入所有子部分目录条目中?
非常感谢!
我目前拥有的 MWE 是
\documentclass{article}
\usepackage{amsmath}
\usepackage{todonotes}
\newcounter{weekcounter}
\DeclareRobustCommand{\weektag}{
\stepcounter{weekcounter}
\todo[size=\tiny,color=red!10]{\hfil\textbf{week \theweekcounter}\hfil}
}
\begin{document}
\tableofcontents
\section{Section 1}
some text
\section[Section 2]{\weektag Section 2}
some text
\section{Section 3}
some text
\end{document}
生产
那里的目录现在应该看起来像
或者类似
答案1
我会使用不同的命令来完成这项工作。
\documentclass{article}
\usepackage{amsmath}
\usepackage{todonotes}
\newcounter{weekcounter}
% \weektag might print the tag in the right margin
\DeclareRobustCommand{\weektag}{%
\todo[size=\tiny,color=red!10]{\hfil\textbf{week \theweekcounter}\hfil}%
}
% the main command wraps \section
\newcommand{\lecture}[1]{%
\section[\protect\printweek #1]{#1\perhapschangeweek}%
}
% conditionally print the tag
\newcommand{\perhapschangeweek}{%
% the current value of week
\edef\thisweek{\theweekcounter}%
% compare with the previously set value; if different, print the tag
\ifx\thisweek\currentweek\else\weektag\fi
% set the current week value
\global\let\currentweek\thisweek
}
% change week: step the counter and do the same in the toc
\newcommand{\newweek}{%
\stepcounter{weekcounter}%
\addtocontents{toc}{\protect\stepcounter{weekcounter}}%
}
% a conditional to see whether we're in the toc
\newif\ifintoc
% \printweek does nothing outside of the tok
\newcommand{\printweek}{\ifintoc Week \theweekcounter: \fi}
% before starting \tableofcontents set the conditional to true
\AddToHook{cmd/tableofcontents/before}{\intoctrue}
% after \tableofcontents set the conditional to false and reset weekcounter
\AddToHook{cmd/tableofcontents/after}{\intocfalse\setcounter{weekcounter}{0}}
\begin{document}
\tableofcontents
\lecture{Section 1}
some text
\newweek
\lecture{Section 2}
some text
\lecture{Section 3}
some text
\newweek
\lecture{Section 4}
\end{document}
你可能想从 1 开始计算周数:更改
\AddToHook{cmd/tableofcontents/after}{\intocfalse\setcounter{weekcounter}{0}}
进入
\AddToHook{cmd/tableofcontents/after}{\intocfalse\setcounter{weekcounter}{0}\newweek}
答案2
如何在宏内部确定我是在目录中还是在文本主体中,以根据情况改变宏的行为?
可能检查一下定义\protect
就足够了。
\texorpdfstring
可用于检测 TeX 是否处于创建 pdf 字符串(例如书签)的情况,该字符串不会出现在文档的页面内,而是单独显示。
我如何使用上述计数器将某些内容写入所有子部分目录条目中?
如果你查看.toc 文件,你会发现条目\contentsline{subsection}...
。
也许您可以引入一个\if..
-switch(通常为 false),然后对其进行修补,\contentsline
以便在其第二个参数(表示目录条目的文本短语)中,如果开关为“true”,则会在前面添加周计数器等的值。
如果这样做,您仍然需要一种机制来传输周计数器的值并将开关设置\if..
到 toc 文件中。以下示例通过 执行此操作\addtocontents
。
\weektagstepped
用于增加weekcounter
和显示周标签并将周添加到目录和书签中(如果加载了 hyperref)。
\weektag
用于显示周标签(不增加计数器weektag
)并将周添加到目录和书签中(如果加载了 hyperref)。
\weektoc
用于将周数添加到目录和书签中(如果已加载 hyperref)。(不显示周数标签,也不增加计数器weektag
。)
\documentclass{article}
\usepackage{amsmath}
\usepackage{todonotes}
%\usepackage{hyperref}
%\usepackage{nameref}
\newcounter{weekcounter}
\makeatletter
\newcommand\weekcountervalue{}%
\newcommand\pdfweeknum{}%
%-------- Can't do \begin{NoHyper}...\end{NoHyper} as that
% yields unknown-destination-errors with the
% `\todo`-command. It would also break the list of todo notes -------
\newcommand\saved@currentHref{}%
\newcommand\saved@currentlabelname{}%
\newcommand\saved@currentlabel{}%
\newcommand\savecurrentref{%
\global\let\saved@currentHref\@currentHref
\global\let\saved@currentlabelname\@currentlabelname
\global\let\saved@currentlabel\@currentlabel
}%
\newcommand\restorecurrentref{%
\global\let\@currentHref\saved@currentHref
\global\let\@currentlabelname\saved@currentlabelname
\global\let\@currentlabel\saved@currentlabel
}%
%----------------------------------------------------------------------------
% This is used to prepend "Week \theweekcounter: " to pdf-bookmarks:
% Probably some of the things should not be done in terms of global
% but only in the group-level where the sectioning-command occurs:
\newcommand\savedpdfstringdefPostHook{}%
\newcommand\patchpdfstringdefposthook{%
\@ifundefined{pdfstringdef}{}{%
\pdfstringdef\pdfweeknum{Week \theweekcounter: }%
\global\let\savedpdfstringdefPostHook=\pdfstringdefPostHook
\gdef\pdfstringdefPostHook##1{%
\expandafter\expandafter\expandafter\gdef
\expandafter\expandafter\expandafter##1%
\expandafter\expandafter\expandafter{\expandafter\pdfweeknum##1}%
\global\let\pdfstringdefPostHook=\savedpdfstringdefPostHook
\gdef\pdfweeknum{}%
\pdfstringdefPostHook##1%
}%
}%
}%
%----------------------------------------------------------------------------
\newcommand{\weektagstepped}{%
\@ifundefined{texorpdfstring}{\@firstoftwo}{\texorpdfstring}%
{%
\ifx\protect\relax % Probably in main document, not toc or the like
\ifx\label\@gobble\else % Probably not in \nameref
\stepcounter{weekcounter}%
\addtocontents{toc}{%
\string\def\string\weekcountervalue{\theweekcounter}%
\string\InsertWeekcountertrue
}%
\savecurrentref
\todo[size=\tiny,color=red!10]{\hfil\textbf{week \theweekcounter}\hfil}%
% Restore referencing-data. Otherwise referencing-labels
% denote the place where \todo started drawing the line
% and pdf-bookmarks and cross-referencing-links won't lead
% to scrolling to the left end of the sectioning heading -
% wrapping \todo between \begin{NoHyper}..\end{NoHyper}
% leads to unknown-destination-errors:
\restorecurrentref
\patchpdfstringdefposthook
\fi
\fi
}{}%
}%
\newcommand{\weektag}{%
\@ifundefined{texorpdfstring}{\@firstoftwo}{\texorpdfstring}%
{%
\ifx\protect\relax % Probably in main document, not toc or the like
\ifx\label\@gobble\else % Probably not in \nameref
\addtocontents{toc}{\string\InsertWeekcountertrue}%
\savecurrentref
\todo[size=\tiny,color=red!10]{\hfil\textbf{week \theweekcounter}\hfil}%
% Restore referencing-data. Otherwise referencing-labels
% denote the place where \todo started drawing the line
% and pdf-bookmarks and cross-referencing-links won't lead
% to scrolling to the left end of the sectioning heading -
% wrapping \todo between \begin{NoHyper}..\end{NoHyper}
% leads to unknown-destination-errors:
\restorecurrentref
\patchpdfstringdefposthook
\fi
\fi
}{}%
}%
\newcommand{\weektoc}{%
\@ifundefined{texorpdfstring}{\@firstoftwo}{\texorpdfstring}%
{%
\ifx\protect\relax % Probably in main document, not toc or the like
\ifx\label\@gobble\else % Probably not in \nameref
\addtocontents{toc}{\string\InsertWeekcountertrue}%
\patchpdfstringdefposthook
\fi
\fi
}{}%
}%
\newif\ifInsertWeekcounter
\@ifdefinable\contentslinecopy{\let\contentslinecopy\contentsline}%
\newcommand\behindnumberline[3]{#2{#3}#1}%
\renewcommand\contentsline[2]{%
\contentslinecopy{#1}{%
\ifInsertWeekcounter\global\InsertWeekcounterfalse\expandafter\@firstofone\else\expandafter\@gobble\fi
{%
\@ifnextchar\numberline{\behindnumberline{Week \weekcountervalue: }}{Week \weekcountervalue: }%
}%
#2%
}%
}%
\makeatother
\pagestyle{headings}
\begin{document}
\tableofcontents
\section{A section}
\verb|\ref{Firstlecturesecondweek}|: \ref{Firstlecturesecondweek}
% \noindent\verb|\nameref{Firstlecturesecondweek}|: \nameref{Firstlecturesecondweek}
\subsection{Only one lecture in the first week\weektagstepped}
some text \hfill some text \hfill some text
\subsection{First lecture in the second week\weektagstepped}
\label{Firstlecturesecondweek}%
\subsection{Second lecture in the 2nd week\weektag}
\subsection{Third lecture in the 2nd week\weektag}
\subsection{Fourth lecture in the 2nd week\weektoc}
\subsection{Something probably in the 2nd week}
some text
\end{document}
如果 hyperref 已加载,则添加书签: