Expl3 透過循環建構的 Tabularray 內容簡化擴充問題

Expl3 透過循環建構的 Tabularray 內容簡化擴充問題

後續來自我之前的問題感謝@egreg 的回答。 (也許格雷戈里奧教授也能在這方面幫助我。)

情況

我正在建立一個問題表 (ToQ) 宏,用於在考試或作業的封面上建立評分錶。它工作得很好,tabular但我改用了 Tabularray tblr,我愛上了它。不幸的是,因為我過去常常totcount為遇到的每個新問題的成績創建計數器,所以我遇到了今天困擾我的擴展問題。

問題

循環不能放入環境中tblr(請參閱§3.2.3手冊的內容),與普通表格的情況一樣。但似乎適用於普通表格的解決方案:

  • 使用 LaTeX 原始循環,
  • 將表體建構成由 \edefs 組成的 \gdef,以及
  • 將主體建構成令牌暫存器,

沒有工作過tblr。此外,tblr允許expand在處理主體之前指定一個選項來指定用於擴展的標記。 (我會在後面的MWE中展示這一點。)

我想要什麼

受到@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,因此將其刪除。

環境tblr可以放在 expl3 程式碼之外。使用環境expand中的選項。tblr那就\my_typeset_table_generic:nn不再需要了。

tblr環境中,選項rowsep=1ex被放置在選項清單中,第一行的設定由鍵決定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

不需要加在\setcounter{questioncount}{0}後面,\newcounter{questioncount}因為初始值已經是0了。

可以使用簡寫來代替\newcounterand 。\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}

相關內容