有条件导入

有条件导入

我正在制作测试表。
我有很多 .tex 文件。
每个 .tex 文件都包含问题、分数、日期。

例如,
file1.tex -> 问题,1 分,2020-1-01
file2.tex -> 问题,1 分,2020-1-12
file3.tex -> 问题,2 分,2021-2-12
file4.tex -> 问题,2 分,2021-3-3

我想要的是轻松制作不同版本的试卷。
版本 1:仅包含问题
版本 2:仅包含 2 分的问题。

文件列表
文件1
文件2

答案1

下面定义了一个question环境,它将使用键检查其 key=value 输入datepoints并将它们与您可以定义的一些过滤器列表进行比较。

过滤器列表接受键includeexclude。如果您使用include不带值的,则初始行为是包含所有问题,如果您使用exclude不带值的,则所有问题都将被排除。

include和都exclude接受一个值,该值可以包含pointsdate。您可以经常任意使用这些键,这将向筛选器列表添加规则。并且两者可以与=(仅匹配的)、>=(分数相等或更高/该日期或更晚的)和<=(分数相等或更低/该日期或更早的)一起使用。作为特殊键,两者includeexclude都接受all,这将清除筛选器列表并包含/排除所有问题。

如果你使用include一个值您使用的include不带值或(带或不带)表示排除所有问题(除匹配给定值中的规则的问题外)。 (除匹配规则的问题外全部包括)exclude也一样。exclude

例如

\questionFilter{exclude={points<=2, date<=2019-12-31}}

表示除给出 2 分或更少分数的问题,或早于 2020-01-01 的问题外,所有问题均包括在内。

如果您愿意,您还可以在文档中间更改过滤规则。

如果环境question本身不符合过滤规则points,则它会吞噬其内容date。吞噬是通过将其内容排版到不输出的框中来完成的。

\question@start您很可能希望根据您的需要定制代码\question@end以获得所需的输出。

对于新问题,points默认为 0,对于新问题,date默认为 0000-00-00。

question所有这些的结果是,无论是在文件中还是在主文档中都并不重要,因为排除是基于环境完成的。

\documentclass[]{article}

\usepackage{expkv-def}

\makeatletter
% initial values of internals
\let\question@\relax
\newcommand*\question@check@{}

% internals for the filter definition 
\newcommand\question@check[1]
  {%
    \edef\question@check@
      {%
        \unexpanded\expandafter{\question@check@#1}%
        {\unexpanded\expandafter{\question@action}}%
      }%
  }
\newcommand*\question@datetonum[1]
  {\numexpr\expandafter\question@datetonum@#1\relax}
\def\question@datetonum@#1-#2-{31*(12*#1+#2)+}
\newcommand*\question@check@points[4]
  {\ifnum\question@points#1#2 #3#4\fi}
\newcommand*\question@check@date[4]
  {\ifnum\question@datetonum\question@date#1\question@datetonum{#2} #3#4\fi}

% key=value setup for the filter
\ekvdefinekeys{qh23570filter-internal}
  {
     code  date    = \question@check{\question@check@date={#1}{}}
    ,code  date   >= \question@check{\question@check@date<{#1}\else}
    ,code  date   <= \question@check{\question@check@date>{#1}\else}
    ,code  points  = \question@check{\question@check@points={#1}{}}
    ,code  points >= \question@check{\question@check@points<{#1}\else}
    ,code  points <= \question@check{\question@check@points>{#1}\else}
    ,noval all     = \let\question@check@\@empty\question@action
  }
\ekvdefinekeys{qh23570filter}
  {
     noval include = \let\question@check@\@empty\let\question@\question@start
    ,code  include =
      \ifx\question@\relax\let\question@\question@remove\fi
      \def\question@action{\let\question@\question@start}%
      \questionFilter@{#1}%
    ,noval exclude = \let\question@check@\@empty\let\question@\question@remove
    ,code  exclude =
      \ifx\question@\relax\let\question@\question@start\fi
      \def\question@action{\let\question@\question@remove}
      \questionFilter@{#1}%
  }
\ekvletkv{qh23570filter-internal}{date>}  {qh23570filter-internal}{date >}
\ekvletkv{qh23570filter-internal}{date<}  {qh23570filter-internal}{date <}
\ekvletkv{qh23570filter-internal}{points>}{qh23570filter-internal}{points >}
\ekvletkv{qh23570filter-internal}{points<}{qh23570filter-internal}{points <}
\ekvsetdef\questionFilter{qh23570filter}
\ekvsetdef\questionFilter@{qh23570filter-internal}

% key=value setup for the environment
\ekvdefinekeys{qh23570question}
  {
     store   points = \question@points
    ,initial points = 0
    ,store   date   = \question@date
    ,initial date   = 0000-00-00
  }
\ekvsetdef\question@kv{qh23570question}
\newenvironment{question}[1][]
  {%
    \ifx\question@\relax
      \PackageError{question}{Initial behaviour unset. Defaulting to include}{}%
      \global\let\question@\question@start
    \fi
    \question@kv{#1}%
    \question@check@
    \question@
  }
  {\question@end}
\newcommand*\question@remove
  {%
    \setbox0\vbox\bgroup
    \edef\question@end{\unexpanded\expandafter{\question@end\egroup}}%
    \question@start
  }

% TODO: Add the start and end code you need for questions that are included here
\newcommand*\question@start{\par\bigskip\section{Question}}
\newcommand*\question@end{}
\makeatother

% just to create many questions with less effort
\newcommand\testquestion[2]
  {%
    \begin{question}[points=#1, date=#2]
      This is a question giving #1 points and created on #2.
    \end{question}
  }

% set the rules which questions are used
\questionFilter
  {
     include={points >= 2, points <= 0}
    ,exclude={points = 3, date <= 2020-10-09}
  }

\begin{document}
\begin{question}[points=15, date=2021-12-04]
  Does this answer your question?
\end{question}

% just to create many questions with less effort
\testquestion{0}{2020-10-08}
\testquestion{1}{2020-10-08}
\testquestion{2}{2020-10-08}
\testquestion{3}{2020-10-08}
\testquestion{4}{2020-10-08}
\testquestion{0}{2020-10-09}
\testquestion{1}{2020-10-09}
\testquestion{2}{2020-10-09}
\testquestion{3}{2020-10-09}
\testquestion{4}{2020-10-09}
\testquestion{0}{2020-10-10}
\testquestion{1}{2020-10-10}
\testquestion{2}{2020-10-10}
\testquestion{3}{2020-10-10}
\testquestion{4}{2020-10-10}
\end{document}

在此处输入图片描述

答案2

使用包可以很容易地过滤问题dbshow。带有日期和分数的问题将保存到名为的数据库中ques-db。然后您可以使用自定义过滤器和样式显示它们。

在此处输入图片描述

\documentclass{article}
\usepackage{dbshow}

\dbNewDatabase{ques-db}{
  ques  = tl,
  date  = date,
  point = int,
}
\begin{dbFilters}{ques-db}
  \dbNewConditional{point-cond}{point}{\dbval > 2}
  \dbNewConditional {date-cond}{date} {\dbval > 2022/01/01}
\end{dbFilters}
\dbNewStyle{base-style}{ques-db}{
  before-code     = \section{All Questions},
  item-code       = {%
    \par\noindent\dbuse{date}~(\dbuse{point} points)
    \par\noindent\dbarabic.~\dbuse{ques},
  },
  item-after-code = \medskip,
}
\dbNewStyle[base-style]{point-style}{ques-db}{
  before-code = \section{Questions with Points Greater than 2},
  raw-filter  = point-cond,
}
\dbNewStyle[base-style] {date-style}{ques-db}{
  before-code = \section{Questions after 2022/01/01},
  raw-filter  = date-cond,
}
\dbNewStyle[base-style]  {mix-style}{ques-db}{
  before-code = \section{Questions with Mix Conditionals},
  raw-filter  = {point-cond && date-cond},
}

\begin{document}

\begin{dbitem}{ques-db}[date=2022/01/01, point=2]
  \dbsave{ques}{$x + y =$}
\end{dbitem}

\begin{dbitem}{ques-db}[date=2022/01/02, point=1]
  \dbsave{ques}{$z^2 =$}
\end{dbitem}

\begin{dbitem}{ques-db}[date=2022/01/03, point=3]
  \dbsave{ques}{$x / \alpha =$}
\end{dbitem}

\dbshow {base-style}{ques-db}
\dbshow{point-style}{ques-db}
\dbshow {date-style}{ques-db}
\dbshow  {mix-style}{ques-db}

\end{document}

相关内容