Un seguimiento demi pregunta anteriorRespondido gracias a @egreg. (Quizás el Prof. Gregorio también pueda ayudarme en esto).
Situación
Estoy creando una macro de tabla de preguntas (ToQ) para crear una tabla de calificaciones en la portada de un examen o tarea. Estaba funcionando bien, tabular
pero cambié a Tabularray tblr
, del cual me estoy enamorando. Desafortunadamente, debido a que suelo totcount
crear contadores para las calificaciones en cada nueva pregunta a medida que se van encontrando, me encuentro con problemas de expansión que me han dejado perplejo hoy.
Problema
Los bucles no se pueden poner dentro de un tblr
entorno (ver§3.2.3del manual), como es el caso de los tabulares ordinarios. Pero las soluciones que parecen funcionar para tablas ordinarias:
- usando bucles primitivos de LaTeX,
- construir el cuerpo fuera de la mesa como un \gdef hecho de \edefs, y
- construir el cuerpo como un registro simbólico,
no he trabajado para tblr
. Además, tblr
permite especificar una expand
opción para especificar tokens para la expansión antes de procesar el cuerpo. (Mostraré esto en el MWE posterior).
lo que me gustaria
Inspirado por la respuesta de @frougonaquí, Me gustaría adoptar un enfoque completamente expl3, ya que de todos modos estoy tratando de aprender expl3. Pero estoy perdido y agradecería un poco de ayuda. No es simplemente una solución, si pudiera ser tan amable, me gustaría un breve resumen para poder estudiar la solución rastreando los documentos.
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}
Produce:
Respuesta1
El último \\
después \nquestion{15}
provocó un Badbox por lo que se eliminó.
El tblr
entorno se puede poner fuera del código expl3. Se utiliza la opción expand
en el entorno. tblr
Entonces \my_typeset_table_generic:nn
ya no es necesario.
En el tblr
entorno, la opción rowsep=1ex
se coloca en la lista de opciones, la configuración para la primera fila se determina con la tecla row{1}
. Entonces no es necesario escribir \color{white}
tres veces.
\null
Se elimina la macro .
\TOTAL{scoretotal}
Se eliminan los tirantes alrededor .
En el comando \nquestion
, {}
se agrega después \thequestioncount
para que los paréntesis no sigan inmediatamente después del número.
La macro \l_my_tabular_tl
no se inicializó con \tl_new:N
. Esto ya está hecho con \tl_new:N \tblrbody
.
El contenido se recopila con \tl_build_put_right:Nn
. Este proceso se inicia \tl_build_begin:N
y finaliza con \tl_build_end:N
.
No es necesario ponerlo \setcounter{questioncount}{0}
después \newcounter{questioncount}
porque el valor inicial ya es 0.
En lugar de utilizar \newcounter
y , se puede utilizar \regtotcounter
la taquigrafía .\newtotcounter
No es necesario definir el comando \TOTAL
. Esto se reemplaza por \total
.
El mando \setquestionpoints
está integrado en el mando \nquestion
. Aquí, \arabic{questioncount}
se reemplaza por \thequestioncount
. Para \setcounter
y \expanded
son \noexpand
innecesarios.
Después \SetCell
, &
se agrega an porque al usar \SetCell
, las celdas omitidas no deben eliminarse.
\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}
Respuesta2
Encontré una solución en la que construyo las líneas de una macro en expl3. No creo que sea el más elegante, pero funciona. Estoy interesado en consejos/comentarios para mejorarlo, así que dejo esta respuesta como no aceptada para ver si alguien aporta algo hermoso.
\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
produce
Respuesta3
La vida no tiene por qué ser tan complicada. Comience siempre especificando cómo desea que sea la entrada y cómo la salida. Eso es proporcionar una API.
- No necesitas los contadores LaTeX2e, usa el
int
módulo. - Cuando quieras almacenar valores, piensa en
csname
. - Cree una serie de comandos
\Q1
...\Qn
almacenando el valor como\Q1-marks
si lo desea,\Q1-question
también podría tener un archivo para almacenar la pregunta real.
Aquí tienes una solución rápida. He usado tabular, solo para demostrar los conceptos. Como regla general trato de minimizar los paquetes que uso. Modifique para agregar prefijos a los comandos l3, como es una buena práctica.
\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}