Uma vez que encontrei na Internet este trecho de código que notei recentemente me ajudaria totalmente com um problema que tenho. Aqui está o código:
\documentclass{article}
\usepackage{catoptions}
\makeatletter
\robust@def*\inputcommandnames{\cpt@testopt\@inputcommandnames{general}}
\newletcs\inputcommandname\inputcommandnames
% #1=stack name, #2=input name(s)
\robust@def*\@inputcommandnames[#1]#2{%
\ifblankFT{#1}{%
\@latex@info{No stack name given: using 'general' instead}%
}{%
% It is possible to iterate over stack names, but leave this for now:
% the use case isn't yet apparent.
\ifinsetTF,{#1}{%
\@latexerr{List '#1' not allowed}\@ehd
}{}%
}%
\ifcsndefTF{name@stack@#1}{}{\csn@def{name@stack@#1}{}}%
\ifcsndefTF{name@stackcount@#1}{}{\csn@def{name@stackcount@#1}{0}}%
\cptdocommalist{#2}{%
\csn@edef{name@stackcount@#1}%
{\the\numexpr\usename{name@stackcount@#1}+1}%
\csn@edef{name@stack@#1}{%
\expandcsnonce{name@stack@#1}\noexpand
\do{\usename{name@stackcount@#1}}{\unexpanded{##1}}%
}%
}%
}
\robust@def*\outputinnormalorder{\@outputcommandnames{normal}}
\newletcs\outputcommandnames\outputinnormalorder
\robust@def*\outputinreverseorder{\@outputcommandnames{reverse}}
% #1=listing/printing order, #2=stack name(s)
\robust@def*\@outputcommandnames#1#2{%
\cptdocommalist{#2}{%
\begingroup
\let\reserved@a\relax
\ifcsndefTF{name@stack@##1}{%
% If the stack is defined but it is currently empty, ignore it
% (but issue a warning). A 'verbose' option for triggering the
% warning will be useful here, but it hasn't been provided:
\ifcsnnullFT{name@stack@##1}{}{%
\@latex@info{Stack '##1' is empty}%
\def\reserved@a####1\endgroup{\endgroup}%
}%
}{%
\@latexerr{Stack '##1' is not defined}\@ehd
}%
\reserved@a
\xifstrcmpTF{#1}{normal}{%
\let\do\curroutputformat
\csname name@stack@##1\endcsname
}{%
\def\name@sentinel####1\name@stop{%
\let\do\curroutputformat####1%
}%
\def\do####1####2####3\name@sentinel####4\name@stop{%
####3\name@sentinel\do{####1}{####2}####4\name@stop
}%
\usename{name@stack@##1}\name@sentinel\name@stop
}%
\endgroup
}%
}
% \commandnameoutputformat<input no.><input item>
\robust@def*\commandnameoutputformat{%
% Skip any spurious spaces before opening brace:
\begingroup
\toks0{##1##2}%
\def\reserved@a{%
\expandafter\endgroup\expandafter\def\expandafter
\curroutputformat\the\toks\expandafter0\expandafter{\the\toks1}%
}%
\afterassignment\reserved@a\toks1=%
}
% If the stack isn't initialized after use, it will start building
% from the last count whenever it is called:
\robust@def*\initializecommandstacks#1{%
\cptdocommalist{#1}{%
\csn@def{name@stackcount@##1}{0}%
\csn@def{name@stack@##1}{}%
}%
}
\newletcs\initializecommandstack\initializecommandstacks
% Set empty stack 'xx' for warning later:
\csn@def{name@stack@xx}{}
\makeatother
% Examples:
\begin{document}
\inputcommandname{I wanted this whole sentence on this input, but when I use a comma it breaks the input and starts a new one}
\inputcommandname{If I don't use commas then it's ok}
\commandnameoutputformat{Input number #1 is: #2.\par}
Output:\par
\outputinnormalorder{general}
\end{document}
Então, aqui está o problema: quero que o código faça exatamente o que faz (armazenar variáveis que iteram sobre um comando), mas sem criar automaticamente novas entradas toda vez que digito vírgulas. Tenho tentado mudar isso, mas falhei todas as vezes. Vocês poderiam modificá-lo para que funcionasse dessa maneira (sem "quebra de vírgula")? Grata pela atenção.
Responder1
Você pode obter um código flexível usando expl3
:
\documentclass{article}
\usepackage{xparse}
\usepackage{booktabs} % for the last example
\ExplSyntaxOn
% first define the user interface
\NewDocumentCommand{\addtolist}{O{general}m}
{
\marinho_lists_add:nn { #1 } { #2 }
}
\NewDocumentCommand{\listoutputformat}{+m}
{
\marinho_lists_output_format:n { #1 }
}
\NewDocumentCommand{\outputlist}{m}
{
\marinho_lists_output:n { #1 }
}
% define the internal functions
\cs_new_protected:Nn \marinho_lists_add:nn
{
% create the sequence if it doesn't exist
\seq_if_exist:cF { l_marinho_lists_#1_seq }
{
\seq_new:c { l_marinho_lists_#1_seq }
}
% add the item in the form {<number>}{<text>}
\seq_put_right:cx { l_marinho_lists_#1_seq }
{% compute the number based on the sequence length
{ \int_to_arabic:n { \seq_count:c { l_marinho_lists_#1_seq } + 1 } }
{ \exp_not:n { #2 } }
}
}
\cs_new_protected:Nn \marinho_lists_output_format:n
{% the private function holds the format
\cs_set:Nn \__marinho_lists_output_current:nn { #1 }
}
\marinho_lists_output_format:n { #1~--~#2 \par } % a default
\cs_new_protected:Nn \marinho_lists_output:n
{% map the sequence using the current format
\seq_map_function:cN { l_marinho_lists_#1_seq } \__marinho_lists_item:n
}
\cs_new:Nn \__marinho_lists_item:n
{% \__marinho_lists_item:n receives an argument in the form {<number>}{<text>}
% which we pass to \__marinho_lists_output_current:nn as two arguments
\__marinho_lists_output_current:nn #1
}
\ExplSyntaxOff
\setlength{\parindent}{0pt} % just for this example
\begin{document}
\section{Fill in the lists}
This section will have no other output.
\addtolist{%
I wanted this whole sentence on this input, even with commas,
without breaking the sentence
}
\addtolist{If I don't use commas then it's ok}
\addtolist[another]{Some text to go first}
\addtolist[another]{Some text to go second}
\addtolist[another]{Some text to go third}
\addtolist{This is in the general list}
\section{Output the \texttt{general} list}
\listoutputformat{Input number #1 is: #2\par}
\outputlist{general}
\section{Output the list named \texttt{another}}
{%
\listoutputformat{(#1) #2\par}
\outputlist{another}
}
\bigskip
Since the code above was in a group, the \texttt{general}
list will now be output identically as before.
\bigskip
\outputlist{general}
\section{We can do in a \texttt{tabular}}
\listoutputformat{#1 & #2 \\}% for a table
\begin{tabular}{ll}
\toprule
N & \multicolumn{1}{c}{Text} \\
\midrule
\outputlist{another}
\bottomrule
\end{tabular}
\end{document}
Sem um argumento opcional, \addtolist
adiciona à lista “geral”. Você pode definir quantas listas desejar. Ao gerar uma lista, use um \listoutputformat
comando se o formato padrão não for adequado. Isso respeita o agrupamento, conforme mostrado no exemplo.
O exemplo final mostra que você pode usar a \outputlist
macro para construir uma tabela, desde que cada item da lista forme uma linha da tabela.
Uma versão diferente que permite reiniciar a contagem, com \addtolist*
(várias listas ainda são permitidas).
\documentclass{article}
\usepackage{xparse}
\usepackage{booktabs} % for the last example
\ExplSyntaxOn
% first define the user interface
\NewDocumentCommand{\addtolist}{sO{general}m}
{
\IfBooleanTF{#1}
{ \marinho_lists_add_restart:nn { #2 } { #3 } }
{ \marinho_lists_add_continue:nn { #2 } { #3 } }
}
\NewDocumentCommand{\listoutputformat}{+m}
{
\marinho_lists_output_format:n { #1 }
}
\NewDocumentCommand{\outputlist}{m}
{
\marinho_lists_output:n { #1 }
}
% define the internal functions
\cs_new_protected:Nn \__marinho_lists_check:n
{
% create the sequence if it doesn't exist
\seq_if_exist:cF { l_marinho_lists_#1_seq }
{
\seq_new:c { l_marinho_lists_#1_seq }
\int_new:c { l_marinho_lists_#1_int }
\int_incr:c { l_marinho_lists_#1_int }
}
}
\cs_new_protected:Nn \marinho_lists_add_restart:nn
{
\__marinho_lists_check:n { #1 }
% add the item in the form {<number>}{<text>}
\int_set:cn { l_marinho_lists_#1_int } { 1 }
\seq_put_right:cx { l_marinho_lists_#1_seq }
{
{ \int_eval:n { \int_use:c { l_marinho_lists_#1_int } } }
{ \exp_not:n { #2 } }
}
\int_incr:c { l_marinho_lists_#1_int }
}
\cs_new_protected:Nn \marinho_lists_add_continue:nn
{
\__marinho_lists_check:n { #1 }
% add the item in the form {<number>}{<text>}
\seq_put_right:cx { l_marinho_lists_#1_seq }
{% compute the number based on the sequence length
{ \int_eval:n { \int_use:c { l_marinho_lists_#1_int } } }
{ \exp_not:n { #2 } }
}
\int_incr:c { l_marinho_lists_#1_int }
}
\cs_new_protected:Nn \marinho_lists_output_format:n
{% the private function holds the format
\cs_set:Nn \__marinho_lists_output_current:nn { #1 }
}
\marinho_lists_output_format:n { #1~--~#2 \par } % a default
\cs_new_protected:Nn \marinho_lists_output:n
{% map the sequence using the current format
\seq_map_function:cN { l_marinho_lists_#1_seq } \__marinho_lists_item:n
}
\cs_new:Nn \__marinho_lists_item:n
{% \__marinho_lists_item:n receives an argument in the form {<number>}{<text>}
% which we pass to \__marinho_lists_output_current:nn as two arguments
\__marinho_lists_output_current:nn #1
}
\ExplSyntaxOff
\setlength{\parindent}{0pt} % just for this example
\begin{document}
\section{Fill in the lists}
This section will have no other output.
\addtolist{%
I wanted this whole sentence on this input, even with commas,
without breaking the sentence
}
\addtolist{If I don't use commas then it's ok}
\addtolist{This is in the general list}
\addtolist*{This will have number 1}
\addtolist{This will have number 2}
\section{Output the \texttt{general} list}
\listoutputformat{Input number #1 is: #2\par}
\outputlist{general}
\section{We can do in a \texttt{tabular}}
\listoutputformat{#1 & #2 \\}% for a table
\begin{tabular}{lp{6cm}}
\toprule
N & \multicolumn{1}{c}{Text} \\
\midrule
\outputlist{general}
\bottomrule
\end{tabular}
\end{document}
Responder2
quase todo o código que você publica é implementado em uma lista separada por vírgulas, \cptdocommalist
mas acho que sua pergunta implica que você não deseja isso, mas talvez
\documentclass{article}
\newcount\mycount
\newtoks\mylist
%odd name for this command? what is the "name" here?
\def\inputcommandname#1{%
\advance\mycount1
\mylist\expandafter{\the\expandafter\mylist
\expandafter\mydo\expandafter
{\the\mycount}{#1}}}
\def\commandnameoutputformat{\def\mydo##1##2}
\def\outputinnormalorder{\the\mylist}
\begin{document}
\inputcommandname{I wanted this whole sentence on this input, but when I use a comma it breaks the input and starts a new one}
\inputcommandname{If I don't use commas then it's ok}
\commandnameoutputformat{\par Input number #1 is: #2.\par}
Output:\par
\outputinnormalorder
\end{document}