环境是否可以检测其处于哪个分段级别?
我正在创建一个包,该包定义了一个带编号的问题/答案对环境,我想提供一个选项来自定义在哪个节级别重置数字,以及问题/答案对是否应包含在目录中。这个想法是让这些问答对形成一组平行的类似节的环境,不会干扰正常的节命令。
编辑也许多一点背景信息会很有用。我一直在使用与下面复制的宏类似的宏来在我的作业中创建问答环境,其功能与部分类似,但有自己的计数器。这是非常有用的代码,我试图将其拆分成一个我可以重复使用的包,但我需要想出一种方法来让环境question
确定它是否在某个部分内,以便正确设置其编号,以及可选地将其放在目录和 PDF 大纲/索引中。
% vim: ft=tex
% arara: lualatex
% arara: lualatex
\documentclass{scrartcl}
\usepackage{etoolbox}
\usepackage{fontspec}
\defaultfontfeatures{Ligatures=TeX}
\newlength{\questionbeforeskip}
\newlength{\questionafterskip}
\setlength{\questionbeforeskip}{1.0ex plus -1ex minus -0.25ex}
\setlength{\questionafterskip}{1ex plus 0.25ex}
\newlength{\answerskip}
\setlength{\answerskip}{0.25ex plus -0.125ex minus -0.125ex}
\addtotoclist{loq}
\newcommand{\listofloqname}{List of Questions}
\newcommand{\listofquestions}{\listoftoc{loq}}
\setuptoc{loq}{leveldown}
\newcounter{question}[section]
\newcommand{\questionautorefname}{question}
\newenvironment{question}
{
\refstepcounter{question}%
\addxcontentsline{loq}{subsection}{Question~\thequestion}
\pdfbookmark[2]{Question~\thequestion}{question:\thesection.\thequestion}
{{\par\vspace\questionbeforeskip \large Question~\thequestion.}\par}
\begin{itshape}
}
{\end{itshape}\par\vspace\questionafterskip}
\usepackage[inline]{enumitem}
\setlist[enumerate]{label=(\alph*)}
% Sub-questions are represented as an enumerate
\newlist{subquestions}{enumerate}{3}
\setlist[subquestions]{leftmargin=*}
\setlist[subquestions,1]{label=\textup{\textbf{(\alph*)}}}
% Inline subquestions
\newlist{subquestions*}{enumerate*}{3}
\setlist[subquestions*]{itemjoin*={{, and }}}
\setlist[subquestions*,1]{label=\textup{\textbf{(\alph*)}}}
\newcommand{\qitem}[1]{\item{\textit{#1}}}
\newcommand{\qitemp}[1]{\qitem{#1}\\[0.5\parskip]}
\newcommand{\qitemq}[1]{\qitem{#1}\quad}
%% Penalties
\hyphenpenalty=2500
\tolerance=500
\widowpenalty=1500
\clubpenalty=1500
\usepackage{hyperref}
\hypersetup{
colorlinks=false,
hidelinks}
\usepackage[all]{hypcap}
\usepackage[noabbrev,capitalise]{cleveref}
\labelcrefformat{subfigure}{\textbf{(#2#1#3)}}
\begin{document}
\section{Osmosis and kinetics}
\begin{question}
What is reverse osmosis? Describe a process which involves the use of reverse
osmosis (use a diagram in your answer).
\end{question}
Answer blah
\begin{question}
What are colloidal particles? What are the main processes that are used to
remove colloidal particles from aqueous solutions?
\end{question}
Some other answer
\section{Organic chemistry / Natural gas processing}
\begin{question}
What are four ways of representing organic molecules such as alkanes?
\end{question}
\begin{question}
Draw structural formula for the following compounds:
\begin{subquestions}
\item 3-methylnonane
\item 3-ethylheptane
\item 2-methyloctane
\end{subquestions}
\end{question}
\begin{subquestions}
\item Answer 1
\item Answer 2
\item Answer 3
\end{subquestions}
\end{document}
到目前为止,我设法提取到包中的是以下内容。用于选择在哪个部分级别重置问题编号的 PGFKeys 开关有点笨拙,所以我可能会用更简单的东西(也许是 xkeyval?)替换它。我利用这个练习来尝试学习创建一个功能包的诀窍,这个包可能对我以外的人有用。要在上一个示例中使用此包,您必须加载它\usepackage{questions}
并删除重复的代码。
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{questions}
[2017/11/17 v0.1 Assignment Questions]
\RequirePackage{etoolbox}
\RequirePackage{pgfopts}
\RequirePackage{chngcntr}
\RequirePackage[inline]{enumitem}
% Question counter
\newcounter{question}
% Define option keys with PGFKeys
\pgfkeys{/questions/.cd}
\pgfkeys{/questions/reset/.cd,
.is choice,
part/.code={%
\counterwithin*{question}{part}
},
chapter/.code={%
\counterwithin*{question}{chapter}
},
section/.code={%
\counterwithin*{question}{section}
},
subsection/.code={%
\counterwithin*{question}{subsection}
},
subsubsection/.code={%
\counterwithin*{question}{subsubsection}
},
paragraph/.code={%
\counterwithin*{question}{paragraph}
},
subparagraph/.code={%
\counterwithin*{question}{subparagraph}
},
none/.code={%
\counterwithout*{question}{section}
},
}
% \pgfkeys{/questions/reset/.default = paragraph}
\newcommand{\questions@setdefaults}{
\pgfkeys{/questions/.cd,
reset=section,
}
}
\newcommand{\questionset}[1]{\pgfkeys{/questions/.cd,#1}}
\questions@setdefaults
\ProcessPgfOptions{/questions}
\newlength{\questionbeforeskip}
\newlength{\questionafterskip}
\setlength{\questionbeforeskip}{1.0ex plus -1ex minus -0.25ex}
\setlength{\questionafterskip}{1ex plus 0.25ex}
\newlength{\answerskip}
\setlength{\answerskip}{0.25ex plus -0.125ex minus -0.125ex}
\addtotoclist{loq}
% \newcommand{\listofloqname}{List of Questions}
% \newcommand{\listofquestions}{\listoftoc{loq}}
% \setuptoc{loq}{sectionatlist}
\newenvironment{questionenv}
{
\refstepcounter{question}%
% \addxcontentsline{loq}{subsection}{Question~\thequestion}
% \pdfbookmark{Question~\thequestion}{question:\thequestion}
{{\par\vspace\questionbeforeskip Question~\thequestion.}\par}
\begin{itshape}
}
{\end{itshape}\par\vspace\questionafterskip}
\newlist{subquestions}{enumerate}{3}
\setlist[subquestions]{leftmargin=*}
\setlist[subquestions,1]{label=\textup{\textbf{(\alph*)}}}
% Inline subquestions
\newlist{subquestions*}{enumerate*}{3}
\setlist[subquestions*]{itemjoin*={{, and }}}
\setlist[subquestions*,1]{label=\textup{\textbf{(\alph*)}}}
\endinput
下一个 MWE 说明了如何questions
使用该包。设置选项restart
会更改问题的编号来源(默认为section
)。
% vim: ft=tex
% arara: lualatex
% arara: lualatex
\documentclass{scrartcl}
%% KOMA options
\KOMAoption{cleardoublepage}{empty}
\KOMAoption{DIV}{10}
\KOMAoption{draft}{false}
\KOMAoption{fontsize}{10pt}
\KOMAoption{headings}{small}
\KOMAoption{paper}{a4}
\KOMAoption{parskip}{half}
\KOMAoption{twoside}{false}
\KOMAoption{captions}{signature}
\KOMAoption{titlepage}{false}
\KOMAoption{abstract}{false}
\usepackage{etoolbox}
\usepackage{fontspec}
\defaultfontfeatures{Ligatures=TeX}
\usepackage[reset=none]{questions}
%% Penalties
\hyphenpenalty=2500
\tolerance=500
\widowpenalty=1500
\clubpenalty=1500
\usepackage{hyperref}
\hypersetup{
colorlinks=false,
hidelinks}
\usepackage[all]{hypcap}
\usepackage[noabbrev,capitalise]{cleveref}
\labelcrefformat{subfigure}{\textbf{(#2#1#3)}}
\begin{document}
\section{A section}
\begin{questionenv}
The question in a section
\end{questionenv}
\subsection{A subsection}
\begin{questionenv}
The question in a subsection
\end{questionenv}
\begin{questionenv}
Another question in a subsection
\end{questionenv}
\subsubsection{A subsubsection}
\begin{questionenv}
The question in a subsubsection
\end{questionenv}
\begin{questionenv}
Another question in a subsubsection
\end{questionenv}
\subsubsection{A subsubsection}
\begin{questionenv}
The question in a subsubsection
\end{questionenv}
\begin{questionenv}
Another question in a subsubsection
\end{questionenv}
\subsection{Another subsection}
\begin{questionenv}
Another question in a subsection
\end{questionenv}
\begin{questionenv}
What is this question?
\end{questionenv}
\section{Another section}
\begin{questionenv}
Another question in another section
\end{questionenv}
\begin{questionenv}
Another question in another section
\end{questionenv}
\subsection{A subsection}
\begin{questionenv}
The question in a subsection
\end{questionenv}
\begin{questionenv}
Another question in a subsection
\end{questionenv}
\begin{questionenv}
Another question in a subsection
\end{questionenv}
\subsubsection{A subsubsection}
\begin{questionenv}
The question in a subsubsection
\end{questionenv}
\begin{questionenv}
Another question in a subsubsection
\end{questionenv}
\subsubsection{A subsubsection}
\begin{questionenv}
The question in a subsubsection
\end{questionenv}
\begin{questionenv}
Another question in a subsubsection
\end{questionenv}
\end{document}
答案1
我不认为 LaTeX 提供了一种自动执行此操作的方法,但是,您可以很容易地破解它。所有章节、小节等都是使用创建的\@startsection
。此宏需要 6 个参数,其中第二个是章节深度的“索引”(\@startsection
将其与进行比较以secnumdepth
决定是否添加目录条目等)。使用\pretocmd
来自电子工具箱您可以\@startsection
“保存”此索引以供将来使用:
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\def\currentsection{0}% initialise
\pretocmd\@startsection{\def\currentsection{Current section index: #2}}{}{}
\makeatother
\begin{document}
\section{A section}
\currentsection
\subsection{A subsection}
\currentsection
\subsubsection{A subsubsection}
\currentsection
\section*{A starred section}
\currentsection
\subsection*{A starred subsection}
\currentsection
\subsubsection*{A starred subsubsection}
\currentsection
\end{document}
得出的结果为:
对于其他文档类,您可能需要稍微更改一下,但想法应该是一样的。实际上,您可能只想使用
\pretocmd\@startsection{\def\currentsection{#2}}{}{}
之后你可以做类似的事情
\ifcase\currentsection% ignore 0, which should only happen with no sections
\or % stuff for sections
\or % stuff for subsections
....
\fi
编辑
如前所述,这可能需要使用不同的文档类进行调整。例如,KOMA 脚本scrartcl.cls
重新定义了大多数 LaTeX 内部结构,因此不足为奇,并且如注释中所述,上面的代码不起作用。KOMA 脚本确实提供了一个\At@startsection
钩子,但我不知道如何使用它,因为据我所知,它无法知道它位于哪个“部分”。话虽如此,事实证明,用替换scrartcl.cls
,就像上面一样,可以使用:@\startsection
\scr@startsection
\pretocmd\scr@startsection{\def\currentsection{Current section index: #2}}{}{}
但请注意,KOMA 文档明确不鼓励更改宏,\scr@startsection
因为它们不能保证将来不会更改它们。这是完整的代码 - 模块 KOMA 样式更改,输出类似。
\documentclass{scrartcl}
\usepackage{etoolbox}
\makeatletter
\def\currentsection{0}% initialise
\pretocmd\scr@startsection{\def\currentsection{Current section index: #2}}{}{}
\makeatother
\begin{document}
\section{A section}
\currentsection
\subsection{A subsection}
\currentsection
\subsubsection{A subsubsection}
\currentsection
\section*{A starred section}
\currentsection
\subsection*{A starred subsection}
\currentsection
\subsubsection*{A starred subsubsection}
\currentsection
\end{document}