ループ構築された Tabularray コンテンツの拡張問題を簡素化する Expl3

ループ構築された Tabularray コンテンツの拡張問題を簡素化する Expl3

続き前回の質問@egreg のおかげで回答できました。(おそらく、Gregorio 教授もここで私を助けてくれるでしょう。)

状況

私は、試験や課題の表紙に採点表を作成するための質問表 (ToQ) マクロを作成しています。 では問題なく動作していましたtabularが、Tabularray の に切り替えてtblr、すっかり気に入ってしまいました。残念ながら、totcount新しい質問が発生するたびに成績のカウンターを作成するため、拡張の問題に遭遇し、今日困惑しています。

問題

ループは環境内に置くことはできませんtblr§3.2.3通常の表形式の場合と同様に、マニュアルの()でも同様です。しかし、通常の表形式に機能すると思われる解決策は次のとおりです。

  • LaTeXのプリミティブループを使用して、
  • テーブルの外側に\edefでできた\gdefとして本体を構築し、
  • 身体をトークンレジスターとして構築し、

は機能していませんtblr。さらに、本文を処理する前に拡張するトークンを指定するオプションをtblr指定できます。(これについては、後の MWE で説明します。)expand

私が望むこと

@frougon の回答に触発されてここいずれにせよ、私は expl3 を学ぼうとしているので、完全に expl3 のアプローチを取りたいと思っています。しかし、私は手に負えない状況にあり、助けていただければ幸いです。解決策だけではなく、もし親切にしていただければ、ドキュメントをクロールして解決策を研究できるように、簡単な概要を教えていただきたいです。

ムウェ

\documentclass{article}
\usepackage{tabularray}
\usepackage{xcolor}

\usepackage{totcount}

% Stuff for keeping account of questions and their scores
% ........................................................<<<
\newcounter{questioncount}
\setcounter{questioncount}{0}
\regtotcounter{questioncount}%
\newcounter{scoretotal}
\setcounter{scoretotal}{0}
\regtotcounter{scoretotal}%

\newcommand{\setquestionpoints}[2]{%
  \expanded{\noexpand\newtotcounter{qpoints#1}}%
  \expanded{\noexpand\setcounter{qpoints#1}}{#2}%
}
\newcommand{\getquestionpoints}[1]{%
  \ifnum\value{qpoints#1}>0
    \arabic{qpoints#1}%
  \else
    0%
  \fi
}

\newcommand{\TOTAL}[1]{%
  \ifcsname c@#1@totc\endcsname
    \total{#1}%
  \else
    ??%
  \fi
}
% ........................................................>>>

% Typesetting questions
% ........................................................<<<
\newcommand{\nquestion}[1]{%
  \stepcounter{questioncount}%
  \setquestionpoints{\arabic{questioncount}}{#1}%
  \addtocounter{scoretotal}{#1}%
  Question~\thequestioncount (#1 marks.)%
}
% ........................................................>>>

\ExplSyntaxOn

\cs_new_protected:Npn \my_typeset_table_generic:nn #1#2
  {
    \group_begin:
      \cs_set_protected:Npn \__my_typeset_table_generic_tmp_func:n ##1 {#1}
      \__my_typeset_table_generic_tmp_func:n {#2}
    \group_end:
  }

\cs_generate_variant:Nn \my_typeset_table_generic:nn { nV }

\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn

% This works, but I would like to know how expl3 can help me build this
%  list automatically, looping for
%      q ∈ [1, \totvalue{questioncount}]
%  to obtain \TOTAL{qpoints\theq} in each cell of the middle column.
\tl_set:Nn \l_my_tabular_tl {%
    1 & \TOTAL{qpoints1} & \null \\ \hline
    2 & \TOTAL{qpoints2} & \null \\ \hline
    3 & \TOTAL{qpoints3} & \null \\ \hline
}
\my_typeset_table_generic:nV
  {
    \SetTblrInner{rowsep=1ex}%
    \begin{tblr}{colspec={|ccX[c]|}, width=0.35\linewidth}
      \SetRow{black, rowsep=0.25ex}
      \color{white}\textit{Q}\textnumero & \color{white}Marks & \color{white}Grade \\ \hline
      #1
    \SetCell[c=2]{c}~TOTAL:~&~\null\\\cline[r]{3-3}
           && {\TOTAL{scoretotal}}\\\hline
    \end{tblr}
  }
  \l_my_tabular_tl
\ExplSyntaxOff

%%% Make some questions:
\vspace{2cm}
\noindent
\nquestion{10}\\
\nquestion{12}\\
\nquestion{15}\\


\end{document}

生産:

答え1

最後\\に、\nquestion{15}Badbox が発生したため、削除されました。

環境は expl3 コードの外側に置くことができます。環境内のtblrオプションが使用されます。その後は不要になります。expandtblr\my_typeset_table_generic:nn

環境ではtblr、オプションはrowsep=1exオプションリストに配置され、最初の行の設定はキーで決定されます。そうすれば、 3回row{1}記述する必要はありません。\color{white}

マクロは\null削除されます。

周りの括弧\TOTAL{scoretotal}は削除されます。

コマンドでは\nquestion、括弧が数字の直後に続かないように、 の{}後に が追加されます。\thequestioncount

マクロは\l_my_tabular_tlで初期化されませんでした\tl_new:N。 で初期化されるようになりました\tl_new:N \tblrbody

コンテンツは で収集されます\tl_build_put_right:Nn。このプロセスは で開始され\tl_build_begin:N、 で終了します\tl_build_end:N

初期値がすでに 0 なので、\setcounter{questioncount}{0}後に置く必要はありません。\newcounter{questioncount}

\newcounterおよびを使用する代わりに\regtotcounter、省略形\newtotcounterを使用できます。

コマンドを定義する必要はありません\TOTAL。これは に置き換えられます\total

コマンドは\setquestionpoints、コマンド に統合されます\nquestion。ここで、\arabic{questioncount}は に置き換えられます\thequestioncount。 の場合\setcounter、、、\expanded\noexpand不要です。

の後に\SetCell&追加されます。 を使用すると\SetCell、省略されたセルは削除されてはならないためです。

ここに画像の説明を入力してください

\documentclass{article}
\usepackage{xcolor}
\usepackage{tabularray}

\usepackage{totcount}

% Stuff for keeping account of questions and their scores
% ........................................................<<<
\newtotcounter{questioncount}
\newtotcounter{scoretotal}

\newcommand{\getquestionpoints}[1]{%
  \ifnum\value{qpoints#1}>0
    \arabic{qpoints#1}%
  \else
    0%
  \fi
}

% ........................................................>>>

% Typesetting questions
% ........................................................<<<
\newcommand{\nquestion}[1]{%
  \stepcounter{questioncount}%
  \expanded{\noexpand\newtotcounter{qpoints\thequestioncount}}%
  \setcounter{qpoints\thequestioncount}{#1}%
  \addtocounter{scoretotal}{#1}%
  Question~\thequestioncount{} (#1 marks.)%
}
% ........................................................>>>


\begin{document}
\ExplSyntaxOn
\tl_new:N \tblrbody
\tl_build_begin:N \tblrbody
\int_step_inline:nn { \totvalue { questioncount } }
  {
    \tl_build_put_right:Nn \tblrbody { #1 & \total { qpoints#1 } & \\ \hline }
  }
\tl_build_end:N \tblrbody
\ExplSyntaxOff
\begin{tblr}[expand=\tblrbody]{
  colspec={|ccX[c]|},
  width=0.35\linewidth,
  rowsep=1ex,
  row{1}={bg=black,fg=white,rowsep=0.25ex}
}
\emph{Q}\textnumero & Marks & Grade\\\hline
\tblrbody
\SetCell[c=2]{c} ~TOTAL:~ & & \\\cline[r]{3-3}
 & & \total{scoretotal}\\\hline
\end{tblr}


%%% Make some questions:
\vspace{2cm}
\noindent
\nquestion{10}\\
\nquestion{12}\\
\nquestion{15}


\end{document}

答え2

expl3 でマクロの行を作成するという解決策を見つけました。最もエレガントだとは思いませんが、機能します。改善するためのヒントやコメントに興味があるので、誰かが何か美しいものを提案してくれるかどうかを見るために、この回答は未承認のままにしておきます。

\ExplSyntaxOn
\NewDocumentCommand{\ToQ}{}{
  \tl_set:Nn \l_tmpa_tl {
    \SetTblrInner{rowsep=1ex}%
    \begin{tblr}[b]{colspec={|ccX[c]|}, width=0.35\linewidth}
      \SetRow{black, rowsep=0.25ex}
      \color{white}\textit{Q}\textnumero
        & \color{white}Marks
          & \color{white}Grade \\ \hline
  }
  \int_step_inline:nn {\totvalue{questioncount}} {
      \tl_put_right:Nn \l_tmpa_tl { ##1 & \fromaux{qpoints##1} & \null \\ \hline }
  }
  \tl_put_right:Nn \l_tmpa_tl {
      \SetCell[c=2]{c}~TOTAL:~&~\null\\\cline[r]{3-3}
      && {\fromaux{scoretotal}}\\\hline
    \end{tblr}
  }
  \l_tmpa_tl
}
\ExplSyntaxOff

生産する

ここに画像の説明を入力してください

答え3

人生はそれほど複雑である必要はありません。常に、入力と出力をどのようにしたいかを指定することから始めてください。つまり、API を提供するのです。

  1. LaTeX2e カウンターは必要ありません。intモジュールを使用してください。
  2. 値を保存したい場合は、 を考えますcsname
  3. 一連のコマンドを作成し\Q1、必要に応じて\Qn値を保存します。実際の質問を保存することもできます。\Q1-marks\Q1-question

簡単な解決策は次のとおりです。概念を説明するために、表形式を使用しました。原則として、使用するパッケージを最小限に抑えるようにしています。良い習慣として、l3 コマンドにプレフィックスを追加するように変更してください。

出力

\documentclass{article}
%------------------------------------------------------------
% INPUT : \AddQuestion{name}{marks}
% OUTPUT: PrintScoreSheet  
%------------------------------------------------------------
\ExplSyntaxOn
\int_new:N \g_questions_total_int
\clist_new:N \g_questions_clist
\prop_new:N \g_questions_marks_prop
\cs_new_protected:Npn \questions_add:nn  #1 #2
  {
    \clist_gput_right:Nn \g_questions_clist {#1}
    \prop_gput:Nnn \g_questions_marks_prop {#1} {#2}
  }

\cs_new_protected:Npn \questions_printlist:
  {
    \begin{tabular}{lrr}
      \hline
      \clist_map_inline:Nn \g_questions_clist
        {
          \prop_get:NnN \g_questions_marks_prop {##1} \l_tmpa_tl
          \int_gadd:Nn \g_questions_total_int { \l_tmpa_tl } 
           ##1  &  \use:c{##1-marks} &\\  %Row
        }
      \\\noalign{\vskip-10pt}
      \cline{2-3} 
      Total & \int_use:N\g_questions_total_int &\\ 
      \hline
    \end{tabular}
  }
\let\AddQuestion\questions_add:nn
\let\PrintScoreSheet\questions_printlist:

\ExplSyntaxOff
\begin{document}
\AddQuestion {Q1}{10}
\AddQuestion {Q2}{20}
\AddQuestion {Q3}{5}
\AddQuestion{Q4}{5}
\PrintScoreSheet
\end{document}

関連情報