Продолжение отмой предыдущий вопросответил спасибо @egreg. (Возможно, профессор Грегорио тоже сможет мне помочь.)
Ситуация
Я создаю макрос Table of Questions (ToQ) для создания таблицы оценок на обложке экзамена или задания. Он работал нормально, tabular
но я переключился на Tabularray tblr
, в который я влюбился. К сожалению, поскольку я использую totcount
для создания счетчиков оценок в каждом новом вопросе по мере их появления, я сталкиваюсь с проблемами расширения, которые поставили меня сегодня в тупик.
Проблема
Циклы не могут быть помещены внутрь tblr
среды (см.§3.2.3руководства), как и в случае с обычными табличными. Но решения, которые, похоже, работают для обычных табличных:
- с использованием примитивных циклов LaTeX,
- построение тела вне таблицы как \gdef, сделанного из \edefs, и
- создание тела как регистра токенов,
не работали для 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, поэтому оно удалено.
Окружение можно вынести за пределы кода expl3. Используется tblr
опция 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.
Вместо использования \newcounter
and можно использовать \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.
- Вам не нужны счетчики LaTeX2e, используйте модуль
int
. - Если вы хотите сохранить значения, подумайте о
csname
. - Создайте ряд команд
\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}