样式sebmcq.sty文件

样式sebmcq.sty文件

考虑我之前的两个问题:

方格用于选择答案,与数学答案完美对齐

首先@egreg 的代码

\documentclass{article}

\newcommand{\squarecap}[1]{\fbox{\makebox[\height]{#1}}}

\begin{document}

\squarecap{A}\par
\squarecap{B}\par
\squarecap{C}\par
\squarecap{D}\par
\squarecap{E}\par
\squarecap{M}\par

\end{document}

第二个@egreg的代码

编译后自动摇动使用 LaTeX 创建的测试的问题和答案

\documentclass{article}
\usepackage[a5paper,margin=1cm]{geometry} % just to make smaller images
\usepackage{multicol,mathtools}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}
\usepackage{siunitx}

\pagestyle{empty}

\sisetup{output-decimal-marker={,}}

\ExplSyntaxOn
\NewDocumentCommand{\question}{mm}
 {
  \seq_clear:N \l__sebastiano_question_body_seq
  \tl_map_inline:nn { #2 } { \seq_put_right:Nn \l__sebastiano_question_body_seq { ##1 } }
  \seq_shuffle:N \l__sebastiano_question_body_seq

  \item #1 \\[2ex]

  \seq_indexed_map_inline:Nn \l__sebastiano_question_body_seq
   {
    \fbox { \int_to_Alph:n { ##1 } } ~ ##2 \\[0.5ex]
   }

  \fbox { \int_to_Alph:n { \seq_count:N \l__sebastiano_question_body_seq + 1 } } ~
  \makebox[9em]{\hrulefill}
 }

\NewDocumentEnvironment{test}{m+b}
 {
  \prg_replicate:nn { #1 } { #2 \clearpage }
 }
 {}
\ExplSyntaxOff

\begin{document}

\begin{test}{4}

\begin{enumerate}
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
  {\SI{36}{km/h}.}
  {\SI{360}{km/h}.}
  {\SI{27,8}{km/h}.}
  {\SI{3,60e8}{km/h}.}
}

\question{In fisica nucleare si usa l'angstrom (simbolo: $\SI{1}{\angstrom}=\SI{1e-10}{m}$) 
e il fermi o femtometro ($\SI{1}{fm}=\SI{1e-15}{m}$). Qual è la relazione tra queste due 
unità di misura?}{
  {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
  {$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
  {$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
  {$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}

\end{enumerate}

\end{test}

\end{document}

我怎样才能将代码组合起来以获得完全平方数(不使用siunitx包)并得到我需要的标记十字作为校正器,我可以在我给学生的测试打印件中将其消除?

答案1

我相信下面的代码应该或多或少能满足您的要求。我假设每个问题始终只有一个正确答案(否则,我们可能不得不更改输入语法,因为自由格式的答案目前不是输入的一部分)。正确答案必须用前面的[x]或表示,[X]如下所示:

\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
     {\SI{36}{km/h}.}
  [X]{\SI{360}{km/h}.}
     {\SI{27,8}{km/h}.}
     {\SI{3,60e8}{km/h}.}
}

[x]或之前和之后的空格会被忽略[X],因此这种输入也是合法的:

\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
      {\SI{36}{km/h}.}
  [X] {\SI{360}{km/h}.}
      {\SI{27,8}{km/h}.}
      {\SI{3,60e8}{km/h}.}
}

如果对于给定的问题,所有建议的答案都没有这样的标记,则自由形式的答案(在上面的输入中没有相应的行)被认为是正确的。

\ShowCorrectAnswers是否打印每个问题的正确答案旁边的复选标记取决于和的使用\HideCorrectAnswers(见下面的屏幕截图)。这些命令遵守 TeX 分组规则(即它们在本地起作用)。或者,您可以:

  • sebmcq使用show-correct-answers=trueshow-correct-answers=false或加载包

  • 使用\sebmcqSetup{show-correct-answers=true}\sebmcqSetup{show-correct-answers=false}

\sebmcqSetup命令尊重分组并接受以下选项。它们也可以在调用中\usepackage{sebmcq}以及在环境的可选参数中传递questionnaire

  • questionnaire-env(最初:)enumerate。这是 用来打印所有问题的环境questionnaire。它必须接受\item与 中工作方式相同的命令enumerate

  • shuffle-questions(初始值为false);值可以是truefalse。如果使用不带值的选项,则表示true

  • shuffle-answers(最初:false)。该值的解释方式与 相同shuffle-questions

  • show-correct-answers(最初:)false。价值也是如此。

  • after-answer-num-skip=〈skip〉确定每个答案数字/字母与相应答案之间的水平间距。

  • answer-number-format=〈code〉允许完全改变答案数字的格式(字母、Alph、罗马、罗马、阿拉伯;自定义 TiZ 代码在其周围绘制一个圆形或矩形等)。#1〈code〉 参数中出现的任何 都将被建议的答案数字(一个整数)替换。

下面的示例展示了如何使用这些选项。

样式sebmcq.sty文件

% sebmcq.sty --- Multiple choice questions. Can print questions and proposed
%                answers in a random order. Optionally show the correct
%                answers.
%
% See <https://tex.stackexchange.com/a/529060/73317> for more information.
%
% Copyright (C) 2020  Florent Rougon, Enrico Gregorio
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 can be found in the LICENSE file present in this
% distribution.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Florent Rougon.
%
% This work consists of only one file: sebmcq.sty.
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\RequirePackage{expl3}
\RequirePackage{xparse}
\RequirePackage{l3keys2e}
\RequirePackage{amssymb}        % for the \checkmark
\ProvidesExplPackage{sebmcq}{2020-03-14}{0.6}
  {Multiple choice questions}

\str_new:N \l_questionnaire_env_str
\seq_new:N \l__sebmcq_questions_seq
\tl_new:N \l__sebmcq_answers_tl
\tl_new:N \l__sebmcq_correctness_code_tl
\tl_new:N \l__sebmcq_answer_tl
\bool_new:N \l_sebmcq_shuffle_questions_bool
\bool_new:N \l_sebmcq_shuffle_answers_bool
\bool_new:N \l_sebmcq_show_correct_answers_bool
\bool_new:N \l__sebmcq_has_correct_answer_bool    % parsing stage
\bool_new:N \l__sebmcq_correct_answer_marked_bool % rendering stage
\skip_new:N \l_sebmcq_after_answer_num_skip        % horizontal skip

\msg_new:nnn { sebmcq } { invalid-answer-opt-arg }
  { Invalid~input~inside~brackets~before~answer:~'#1'. }

\msg_new:nnn { sebmcq } { empty-answer-opt-arg }
  { Empty~input~inside~brackets~before~answer. }

\msg_new:nnn { sebmcq } { question-cmd-used-outside-of-questionnaire-env }
  { \question command~used~outside~of~questionnaire~environment. }

% This is assumed to be illegal
\msg_new:nnn { sebmcq } { several-correct-answers }
  { Several~answers~have~been~marked~as~correct~for~a~question. }

\cs_new_protected:Npn \__sebmcq_read_answer_with_optarg:wn [#1]#2
  {
    \tl_if_empty:nTF {#1}
      { \msg_error:nn { sebmcq } { empty-answer-opt-arg } }
      {
        \str_if_in:nnTF { xX } {#1}
          {
            \bool_if:NTF \l__sebmcq_has_correct_answer_bool
              { \msg_error:nn { sebmcq } { several-correct-answers } }
              {
                \bool_set_true:N \l__sebmcq_has_correct_answer_bool
                \tl_put_right:Nn \l__sebmcq_answers_tl
                  { { { \correct } {#2} } }
              }
          }
          { \msg_error:nnn { sebmcq } { invalid-answer-opt-arg } {#1} }
      }
    \__sebmcq_read_answers:w % recurse
  }

\cs_new_protected:Npn \__sebmcq_read_answer_without_optarg:n #1
  {
    % Incorrect answer
    \tl_put_right:Nn \l__sebmcq_answers_tl { { { } {#1} } }
    \__sebmcq_read_answers:w % recurse
  }

\cs_new_protected:Npn \__sebmcq_read_answers:w
  {
    \peek_meaning_ignore_spaces:NTF \q_stop
      { \use_none:n }
      {
        \peek_meaning_ignore_spaces:NTF [
          { \__sebmcq_read_answer_with_optarg:wn }
          { \__sebmcq_read_answer_without_optarg:n }
      }
  }

\cs_new_protected:Npn \__sebmcq_maybe_mark_correct_answer:
  {
    % Little trick in the boolean expression: this allows us to automatically
    % mark the freeform answer as correct if none of the explicitly given
    % answers was declared as correct.
    \bool_if:nT
      {
          \bool_if_p:N \l_sebmcq_show_correct_answers_bool &&
        ! \bool_if_p:N \l__sebmcq_correct_answer_marked_bool
      }
      {
        \makebox[0pt][r] { \checkmark \skip_horizontal:n { 0.7em } }
        % No other answer will be marked as correct for this question.
        \bool_set_true:N \l__sebmcq_correct_answer_marked_bool
      }
  }

% Default function for formatting the question number
\cs_new_protected:Npn \sebmcq_format_question_number_default:n #1
  {
    \fbox { \makebox[\height]{ \int_to_Alph:n {#1} } }
  }

% #1: empty means the answer is incorrect
% #2: answer number
% #3: answer text
\cs_new_protected:Npn \__sebmcq_print_proposed_answer:nnn #1#2#3
  {
    \tl_if_empty:nF {#1} { \__sebmcq_maybe_mark_correct_answer: }
    \__sebmcq_format_question_number:n {#2}
    \skip_horizontal:n { \l_sebmcq_after_answer_num_skip } {#3} \\[0.5ex]
  }

\cs_generate_variant:Nn \__sebmcq_print_proposed_answer:nnn { VnV }
\cs_generate_variant:Nn \__sebmcq_format_question_number:n { x }

% Based on egreg's code: <https://tex.stackexchange.com/a/519972/73317>
% #1: question text; #2: proposed answers
\cs_new_protected:Npn \__sebmcq_read_question:nn #1#2
  {
    \tl_clear:N \l__sebmcq_answers_tl
    \bool_set_false:N \l__sebmcq_has_correct_answer_bool
    \__sebmcq_read_answers:w #2 \q_stop
    \seq_put_right:Nx \l__sebmcq_questions_seq
      {
        { \exp_not:n {#1} }                                    % { question }
        { \exp_not:n \exp_after:wN { \l__sebmcq_answers_tl } } % { answers }
      }
  }

\seq_new:N \l__sebmcq_oq_answers_seq

% #1: question
% #2: answers, each of which being of the form
% { { \correct or empty } { answer text } }
\cs_new_protected:Npn \__sebmcq_output_question:nn #1#2
  {
    \seq_set_split:Nnn \l__sebmcq_oq_answers_seq { } {#2}
    \bool_if:NT \l_sebmcq_shuffle_answers_bool
      { \seq_shuffle:N \l__sebmcq_oq_answers_seq }

    \item {#1} \\[2ex]          % question text

    \bool_set_false:N \l__sebmcq_correct_answer_marked_bool
    \seq_indexed_map_inline:Nn \l__sebmcq_oq_answers_seq
      {
        \seq_set_split:Nnn \l_tmpa_seq { } {##2}
        \seq_pop_left:NN \l_tmpa_seq \l__sebmcq_correctness_code_tl
        \seq_pop_left:NN \l_tmpa_seq \l__sebmcq_answer_tl
        \__sebmcq_print_proposed_answer:VnV
          \l__sebmcq_correctness_code_tl {##1}
          \l__sebmcq_answer_tl
      }

    \__sebmcq_maybe_mark_correct_answer:
    \__sebmcq_format_question_number:x
      { \int_eval:n { \seq_count:N \l__sebmcq_oq_answers_seq + 1 } }
    \skip_horizontal:n { \l_sebmcq_after_answer_num_skip }
    \hbox_to_wd:nn { 9em } { \hrulefill }
  }

\cs_new_protected:Npn \__sebmcq_output_question:n #1
  { \__sebmcq_output_question:nn #1 }

\cs_new_protected:Npn \__sebmcq_output_questionnaire:
  {
    \bool_if:NT \l_sebmcq_shuffle_questions_bool
      { \seq_shuffle:N \l__sebmcq_questions_seq }
    % I didn't use \seq_map_inline:Nn here because it would fail with l3kernel
    % older than 2020-03-14 (this is due to a bug in \seq_shuffle:N
    % <https://github.com/latex3/latex3/issues/687>, fixed in this commit:
    % <https://github.com/latex3/latex3/commit/42c70c63fd83324c5792dd14538a39dd7e388a55>).
    \seq_map_function:NN \l__sebmcq_questions_seq \__sebmcq_output_question:n
  }

\NewDocumentCommand \question { }
  {
    \msg_error:nn { sebmcq } { question-cmd-used-outside-of-questionnaire-env }
  }

\NewDocumentEnvironment { questionnaire } { O{} }
  {
    \keys_set:nn { sebmcq } {#1}
    \cs_set_eq:NN \question \__sebmcq_read_question:nn
    \tl_clear:N \l__sebmcq_questions_seq
    \use:c { \str_use:N \l_questionnaire_env_str }
  }
  {
    \__sebmcq_output_questionnaire:
    \use:c { end \str_use:N \l_questionnaire_env_str }
  }

\NewDocumentCommand \ShowCorrectAnswers { }
 {
   \bool_set_true:N \l_sebmcq_show_correct_answers_bool
 }

\NewDocumentCommand \HideCorrectAnswers { }
 {
   \bool_set_false:N \l_sebmcq_show_correct_answers_bool
 }

% Set the default question number formatter
\cs_new_eq:NN \__sebmcq_format_question_number:n
              \sebmcq_format_question_number_default:n

\keys_define:nn { sebmcq }
  {
    after-answer-num-skip .skip_set:N = \l_sebmcq_after_answer_num_skip ,
    after-answer-num-skip .value_required:n = true,
    after-answer-num-skip .initial:n = { 0.9em },
    %
    answer-number-format  .code:n = {
      \cs_set_protected:Npn \__sebmcq_format_question_number:n ##1 {#1} },
    answer-number-format  .value_required:n = true,
    %
    questionnaire-env     .code:n = {
      \str_set:Nn \l_questionnaire_env_str {#1} },
    questionnaire-env     .value_required:n = true,
    questionnaire-env     .initial:n = { enumerate },
    %
    show-correct-answers  .bool_set:N = \l_sebmcq_show_correct_answers_bool,
    show-correct-answers  .initial:n = { false },
    show-correct-answers  .default:n = { true },
    %
    shuffle-questions     .bool_set:N = \l_sebmcq_shuffle_questions_bool,
    shuffle-questions     .initial:n = { false },
    shuffle-questions     .default:n = { true },
    %
    shuffle-answers       .bool_set:N = \l_sebmcq_shuffle_answers_bool,
    shuffle-answers       .initial:n = { false },
    shuffle-answers       .default:n = { true },
  }

\NewDocumentCommand \sebmcqSetup { m }
  {
    \keys_set:nn { sebmcq } {#1}
  }

% Process LaTeX2e-style package options. This uses l3keys2e, see
% <https://tex.stackexchange.com/a/371754/73317> for explanations.
\ProcessKeysPackageOptions { sebmcq }

\endinput

第一个例子

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}                      % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
            hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx}                      % only for the examples
\usepackage{xparse}                       % only for the 'test' environment
\usepackage[shuffle-questions, shuffle-answers]{sebmcq} % your new package :-)

\pagestyle{empty}

\sisetup{output-decimal-marker={,}}

\ExplSyntaxOn
\NewDocumentEnvironment { test } { m +b }
  { \prg_replicate:nn { #1 } { #2 \clearpage } }
  { }
\ExplSyntaxOff

\ShowCorrectAnswers

\begin{document}

\begin{test}{4}
\begin{questionnaire}
% Mark the correct answer with either [x] or [X]. If no mark is present, the
% correct answer is assumed to be the freeform one.
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
     {\SI{36}{km/h}.}
  [X]{\SI{360}{km/h}.}
     {\SI{27,8}{km/h}.}
     {\SI{3,60e8}{km/h}.}
}

\question{In fisica nucleare si usa l'angstrom
  (simbolo: $\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
  ($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due
  unità di misura?}{
  [x]{$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
     {$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
     {$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
     {$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}
\end{test}

\end{document}

示例输出:

显示正确答案

\ShowCorrectAnswers带有注释的样例输出,或者带有\HideCorrectAnswers

未显示正确答案

第二个例子

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}                      % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=12cm,
            hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx}                      % for the examples
\usepackage{tikz}                         % for \myCircled
\usepackage{sebmcq}
\sebmcqSetup{
  shuffle-questions, shuffle-answers, show-correct-answers=true,
  answer-number-format={\myCircled{#1}}, after-answer-num-skip=1.5em,
}

\pagestyle{empty}
\sisetup{output-decimal-marker={,}}

\newcommand*{\myCircled}[1]{%
  \begin{tikzpicture}[baseline=(number.base)]
    \node[circle, draw=green!10!gray, fill=blue!30!green!10] (number) {#1};
  \end{tikzpicture}%
}

\begin{document}

\begin{questionnaire}
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
      {\SI{36}{km/h}.}
  [X] {\SI{360}{km/h}.}
      {\SI{27,8}{km/h}.}
      {\SI{3,60e8}{km/h}.}
}

\question{In fisica nucleare si usa l'angstrom (simbolo:
   $\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
   ($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
   misura?}{
  [X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}

\end{document}

1.5em示例输出(传递给选项的值after-answer-num-skip可能太大;这只是为了展示其效果):

第二个例子

第三个例子

这是上一个示例的一个小变体。这一次,键answer-number-format不是用 设置的\sebmcqSetup,而是在环境的可选参数中设置的questionnaire

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}                      % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
            hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx}                      % for the examples
\usepackage{tikz}                         % for \myCircled
\usepackage{sebmcq}
\sebmcqSetup{shuffle-questions, shuffle-answers, show-correct-answers}

\pagestyle{empty}
\sisetup{output-decimal-marker={,}}

\begin{document}

% Use a specific answer number format for this questionnaire
\begin{questionnaire}[answer-number-format={%
  \tikz[baseline=(number.base)]
    \node[rectangle, rounded corners=1pt, draw=none, fill=gray!40] (number)
      {#1};%
  }]

\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
      {\SI{36}{km/h}.}
  [X] {\SI{360}{km/h}.}
      {\SI{27,8}{km/h}.}
      {\SI{3,60e8}{km/h}.}
}

\question{In fisica nucleare si usa l'angstrom (simbolo:
   $\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
   ($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
   misura?}{
  [X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}

\end{document}

第三个例子

第四个例子

这是前面例子的一个小变体,\alph对建议的答案使用了 -style 编号(\alph这里不能使用 LaTeX2e 的命令,因为当#1在 的参数中表示时,建议的答案编号不是一个计数器answer-number-format)。

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}                      % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
            hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx}                      % for the examples
\usepackage{tikz}                         % for \mySquared
\usepackage{expl3}                        % for \int_to_alph:n
\usepackage{sebmcq}
\sebmcqSetup{
  shuffle-questions, shuffle-answers, show-correct-answers,
  answer-number-format={\mySquared{#1}},
}

\pagestyle{empty}
\sisetup{output-decimal-marker={,}}

\ExplSyntaxOn
% Borrow \int_to_alph:n from expl3
\cs_new_eq:NN \inttoalph \int_to_alph:n
\ExplSyntaxOff

\newcommand*{\mySquared}[1]{%
  \begin{tikzpicture}[baseline=(number.base)]
    \node[rectangle, rounded corners=1pt, draw=none, fill=gray!40] (number)
      {\inttoalph{#1}};
  \end{tikzpicture}%
}

\begin{document}

\begin{questionnaire}
\question{In fisica nucleare si usa l'angstrom (simbolo:
   $\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
   ($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
   misura?}{
  [X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
      {$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}

\end{document}

第四个例子

相关内容