请教,有没有宏包可以实现给题库中的题目动态打标签的功能?
我有一些题目,每道题目需要打上1-4个不等的知识点标签,比如:
\begin{problem}
题目1
\tagit{标签1}{标签2}
\end{problem}
\begin{problem}
题目2
\tagit{标签1}{标签3}
\end{problem}
\begin{problem}
题目3
\tagit{标签1}{标签4}
\end{problem}
\begin{problem}
题目4
\tagit{标签2}{标签3}{标签4}
\end{problem}
然后希望能按照标签打印该标签下的所有题目到一个单独的tex文件中,
比如 \print_by_tag{标签1}
会打印出一个.tex
文件包含
\begin{problem}
题目1
\tagit{标签1}{标签2}
\end{problem}
\begin{problem}
题目2
\tagit{标签1}{标签3}
\end{problem}
\begin{problem}
题目3
\tagit{标签1}{标签4}
\end{problem}
又比如 \print_by_tag{标签4}
会打印出一个.tex
文件包含
\begin{problem}
题目3
\tagit{标签1}{标签4}
\end{problem}
\begin{problem}
题目4
\tagit{标签2}{标签3}{标签4}
\end{problem}
刚造完一个,,,还是用楼上的吧
\documentclass{article}
\ExplSyntaxOn
\clist_new:N \g_tags_clist
\clist_new:N \g_contents_clist
\cs_new:Npn \__tagit:n #1 {
\clist_gput_right:Nn \g_tags_clist { { #1 } }
}
\NewDocumentCommand{\tagit}{}{\__tagit:n}
\newcounter{problem}
\NewDocumentEnvironment{problem}{+b}{
\stepcounter{problem}
\clist_gput_right:Nn \g_contents_clist {\exp_not:N\begin{problem} #1 \exp_not:N\end{problem} }
#1
}{}
\iow_new:N \g_tags_file
\cs_new:Npn \__print_by_tag:n #1 {
\tl_clear:N \l_tmpa_tl
\int_step_inline:nn { \the\value{problem} } {
\exp_args:Ne \clist_if_in:nnT
{ \clist_item:Nn \g_tags_clist { ##1 } }
{ #1 }
{
\tl_put_right:Ne \l_tmpa_tl { \clist_item:Nn \g_contents_clist { ##1 } }
}
}
\iow_open:Nn \g_tags_file { \jobname-#1.tex }
\iow_now:Ne \g_tags_file { \l_tmpa_tl }
\iow_close:N \g_tags_file
}
\NewDocumentCommand{\printByTag}{}{\__print_by_tag:n}
\ExplSyntaxOff
\begin{document}
\begin{problem}
aa
\tagit{tag1, tag2, tag3}
\end{problem}
\begin{problem}
aa
\tagit{tag2, tag3}
\end{problem}
\begin{problem}
aa
\tagit{tag1, tag2, tag3}
\end{problem}
\printByTag{tag1}
\end{document}
本着「不要重复造轮子」的原则,一个比较适合的包是texdox xsim
一个简单的用例在这里
给一个更完整点的例子(注意可能要手动删除.xsim
文件以防止错误的结果):
\documentclass{article}
\usepackage{xsim}
\usepackage{lipsum}
\DeclareExerciseCollection[label=A]{A}
\DeclareExerciseCollection[label=B]{B}
\DeclareExerciseCollection[label=C]{C}
\DeclareExerciseCollection[label=D]{D}
\DeclareExerciseTagging{label}
\xsimsetup{collect}
\begin{document}
\begin{exercise}[label=C]
\textbf{C} \lipsum[2]
\end{exercise}
\begin{exercise}[label={A,B}]
\textbf{A and B} \lipsum[2]
\end{exercise}
\begin{exercise}[label={B,C,D}]
\textbf{B and C and D} \lipsum[2]
\end{exercise}
\begin{exercise}[label={D,A}]
\textbf{D and A} \lipsum[2]
\end{exercise}
\section{AAA}
\printcollection{A}
\section{CCC}
\printcollection{C}
\section{DDD}
\printcollection{D}
\end{document}