Vorhandenen iterativen Code ändern

Vorhandenen iterativen Code ändern

Ich habe im Internet diesen Code gefunden, der mir bei einem Problem, das ich habe, wirklich helfen würde. Hier ist der Code:

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

Es produziert: Bildbeschreibung hier eingeben

Also, hier ist das Problem: Ich möchte, dass der Code genau das tut, was er tut (Variablen speichern, die über einen Befehl iterieren), aber ohne automatisch neue Eingaben zu erstellen, wenn ich Kommas eingebe. Ich habe versucht, es zu ändern, aber es ist jedes Mal fehlgeschlagen. Könntet ihr es so ändern, dass es so funktioniert (kein „Komma-Umbruch“)? Danke für eure Aufmerksamkeit.

Antwort1

Sie können einen flexiblen Code erhalten, indem Sie Folgendes verwenden 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}

Ohne optionales Argument \addtolistwird zur „allgemeinen“ Liste hinzugefügt. Sie können so viele Listen definieren, wie Sie möchten. Verwenden Sie bei der Ausgabe einer Liste einen \listoutputformatBefehl, wenn das Standardformat nicht geeignet ist. Dabei wird die Gruppierung berücksichtigt, wie im Beispiel gezeigt.

Das letzte Beispiel zeigt, dass Sie das Makro zum Erstellen einer Tabelle verwenden können \outputlist, solange jedes Element in der Liste eine Tabellenzeile bildet.

Bildbeschreibung hier eingeben

Eine andere Version, die es Ihnen ermöglicht, die Zählung neu zu starten, mit \addtolist*(mehrere Listen sind weiterhin zulässig).

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

Bildbeschreibung hier eingeben

Antwort2

fast der gesamte Code, den Sie veröffentlichen, wird über eine durch Kommas getrennte Liste implementiert \cptdocommalist, aber ich denke, Ihre Frage impliziert, dass Sie das überhaupt nicht wollen, aber vielleicht

Bildbeschreibung hier eingeben

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

verwandte Informationen