루프 기반 Tabularray 콘텐츠로 확장 문제를 단순화하는 Expl3

루프 기반 Tabularray 콘텐츠로 확장 문제를 단순화하는 Expl3

후속작내 이전 질문@egreg 덕분에 대답했습니다. (아마도 Gregorio 교수가 여기서도 나를 도와줄 수 있을 것입니다.)

상황

시험이나 과제 표지에 표시 표를 만들기 위한 ToQ(질문표) 매크로를 만들고 있습니다. 잘 작동했지만 사랑에 빠진 tabularTabularray로 전환했습니다 . tblr불행하게도 저는 totcount새로운 질문이 나올 때마다 성적에 대한 카운터를 생성하곤 했기 때문에 오늘날 저를 당황하게 만드는 확장 문제에 직면하게 되었습니다.

문제

루프는 환경 내부에 배치될 수 없습니다 tblr(참조:§3.2.3매뉴얼의) 일반 표의 경우와 같습니다. 그러나 일반 표 형식에서는 작동하는 것으로 보이는 솔루션은 다음과 같습니다.

  • LaTeX 기본 루프를 사용하여,
  • \edefs로 만든 \gdef로 테이블 외부에 몸체를 만들고,
  • 토큰 레지스터로 본문을 구축하고,

에서 일하지 않았습니다 tblr. 또한 본문을 처리하기 전에 확장을 위한 토큰을 지정하는 옵션을 tblr지정할 수 있습니다 . expand(이 내용은 나중에 MWE에서 보여드리겠습니다.)

내가 원하는 것

@frougon의 답변에서 영감을 얻었습니다.여기, 어쨌든 expl3을 배우려고 하기 때문에 완전히 expl3 접근 방식을 취하고 싶습니다. 하지만 너무 힘들어서 도움을 주시면 감사하겠습니다. 단순한 해결책이 아니라, 너무 친절하시다면 문서를 크롤링하여 해결책을 연구할 수 있도록 간략한 개요를 부탁드리겠습니다.

MWE

\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.

초기값이 이미 0이므로 \setcounter{questioncount}{0}뒤에 붙일 필요는 없습니다 .\newcounter{questioncount}

\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}

관련 정보