Sortieren neuer Befehle nach einer Variablen

Sortieren neuer Befehle nach einer Variablen

Zwei Gutachter haben mehrere Kommentare zu meinem Artikel abgegeben, und ich schreibe einen Antwortbrief. Ich habe einen neuen Befehl wie folgt definiert:

\newcommand{\response}[3]{Comment by Reviewer #1 \\ Comment: #2 \\ Response: #3}

Ich habe vor, die Antworten in der Reihenfolge zu schreiben, in der sie in meinem Aufsatz erschienen sind. Ich möchte jedoch auch ein weiteres Dokument wie dieses:

KOMMENTARE VON BEWERTER 1

Kommentar: Dies ist ein Kommentar.

Antwort: Dies ist die Antwort.

...

KOMMENTARE VON BEWERTER 2

Kommentar: Dies ist ein Kommentar.

Antwort: Dies ist die Antwort.

...

Wie kann ich die Befehle nach der ersten Variable des Befehls sortieren?

Da ich noch nicht mit dem Schreiben meines Dokuments begonnen habe, sind auch alternative Lösungen willkommen.

Antwort1

Hier ist ein Ansatz, bei dem

  • Mögliche Namen der Prüfer sind „John Doe“ und „John Smith“
    und Antwort- und Antworteinträge gehen an externe Dateien \jobname.rvallund \jobname.rvdoe/ \jobname.rvsmith.
  • das zweite und dritte Argument von \response(Kommentar und Antwort) werden unter dem wörtlichen Kategorie-Code-Regime gelesen.
    Anstatt diese Argumente in Klammern zu verschachteln, können Sie wörtliche Trennzeichen wie beim \verb-Befehl verwenden, wenn Sie dies möchten oder müssen.

    Innerhalb des Haupttextes werden diese Argumente an eTeX weitergegeben \scantokens.

    Diese Argumente werden auch wortwörtlich in .auxdie -Datei und in die Dateien \jobname.rvallund \jobname.rvdoedie jeweiligen kopiert/geschrieben \jobname.rvsmith.

\jobname.rvallSie können die Dateien und \jobname.rvdoe/ \jobname.rvsmithüber in andere TeX-Dokumente importieren \input.
Sie müssen lediglich sicherstellen, dass in diesen anderen TeX-Dokumenten die Makros \responselinewithreviewer/ \responselinewithoutreviewerdefiniert sind, um die drei Argumente zu verarbeiten.
Wenn Sie \UDcollectverbargvon unten verwenden, um sie so zu definieren, dass sie das zweite und das dritte Argument unter verbatim-category-code-régime mit \verb-Syntax lesen, können Sie sie auch Dinge wie \verbund ungleichmäßige Klammern enthalten lassen.

Der Kerngedanke ist:

Dies ist eine Art Neuimplementierung des / -Mechanismus des LaTeX 2e-Kernels. (Dieser Mechanismus liegt auch / , , , usw. zugrunde.)@starttoc{⟨tocfile⟩}\addtocontents{⟨tocfile⟩}{...}\tableofcontents\addcontentsline\listoffigures\listoftables

Die Neuimplementierung liest und verarbeitet Argumente unter dem Verbatim-Category-Code-Regime.

\listofallresponsesliefert alle Kommentare und Antworten.

\dummylistofallresponsesbewirkt, dass die .rvall-Datei geschrieben wird, ohne Dinge in das Dokument zu liefern.

\listofreviewersresponses{⟨reviewer⟩}liefert alle Kommentare und Antworten, die zu⟨Rezensent⟩.

\dummylistofreviewersresponses{⟨reviewer⟩}verursacht die.rv⟨reviewer⟩-Datei geschrieben werden, ohne ihren Inhalt in das Dokument zu liefern.

Datei test.tex:

% Due to usage of \detokenize and \scantokens compiling this file
% requires LaTeX with eTeX-extensions.
\makeatletter
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%=============================================================================
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstofone{\expandafter} %
  \@secondoftwo}{\@firstofone{\expandafter} \@firstoftwo}%
}%
%%=============================================================================
%% Extract K-th inner undelimited argument:
%%
%% \UD@ExtractKthArg{<integer K>}{<list of undelimited args>} 
%% 
%% In case there is no K-th argument in <list of indelimited args> : 
%%   Does not deliver any token.
%% In case there is a K-th argument in <list of indelimited args> : 
%%   Does deliver that K-th argument with one level of braces removed.
%%
%% Examples:
%%
%%   \UD@ExtractKthArg{0}{ABCDE} yields: <nothing>
%%
%%   \UD@ExtractKthArg{3}{ABCDE} yields:  C
%%
%%   \UD@ExtractKthArg{3}{AB{CD}E} yields:  CD
%%
%%   \UD@ExtractKthArg{4}{{001}{002}{003}{004}{005}} yields: 004
%%
%%   \UD@ExtractKthArg{6}{{001}{002}{003}} yields: <nothing> 
%% 
%%=============================================================================
\newcommand\UD@ExtractKthArg[1]{%
  \romannumeral0%
  % #1: <integer number K>
  \expandafter\UD@ExtractKthArgCheck
  \expandafter{\romannumeral\number\number#1 000}%
}%
\newcommand\UD@ExtractKthArgCheck[2]{%
  \UD@CheckWhetherNull{#1}{ }{%
    \expandafter\UD@ExtractKthArgLoop\expandafter{\@firstoftwo{}#1}{#2}%
  }%
}%
\newcommand\UD@ExtractKthArgLoop[2]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#2{}.}{ }{%
    \UD@CheckWhetherNull{#1}{%
      \UD@ExtractFirstArgLoop{#2\UD@SelDOm}%
    }{%
      \expandafter\UD@PassFirstToSecond\expandafter{\@firstoftwo{}#2}%
      {\expandafter\UD@ExtractKthArgLoop\expandafter{\@firstoftwo{}#1}}%
    }%
  }%
}%
\@ifdefinable\UD@RemoveTillUD@SelDOm{%
  \long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\@firstoftwo\expandafter{} \@secondoftwo{}#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% Check whether argument contains no exclamation mark which is not nested in 
%% braces:
%%.............................................................................
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%=============================================================================
\newcommand\UD@GobbleToExclam{}\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%=============================================================================
%% Act depending on whether argument is "John Doe" or "John Smith":
%% \reviewerfork{<Argument>}{%
%%   {<tokens in case <Argument> is John Doe>}%
%%   {<tokens in case <Argument> is John Smith>}%
%%   {<tokens in case <Argument> is something else>}%
%% }
%%=============================================================================
\newcommand\reviewerfork[1]{%
  \romannumeral0%
  \UD@CheckWhetherNoExclam{#1}{%
    \@reviewerfork
    !#1!John Smith!{\@firstoftwo{\expandafter\expandafter\expandafter}{} \UD@ExtractKthArg{1}}%
    !John Doe!#1!{\@firstoftwo{\expandafter\expandafter\expandafter}{} \UD@ExtractKthArg{2}}%
    !John Doe!John Smith!{\@firstoftwo{\expandafter\expandafter\expandafter}{} \UD@ExtractKthArg{3}}%
    !!!!%
  }{%
   \@firstoftwo{\expandafter\expandafter\expandafter}{} \UD@ExtractKthArg{3}%
  }%
}%
\newcommand\@reviewerfork{}%
\long\def\@reviewerfork#1!John Doe!John Smith!#2#3!!!!{#2}%
%%=============================================================================
%% Act depending on whether is known/unknown:
%% \CheckWhetherReviewerknown{<Argument>}
%%                           {<tokens in case <Argument> is a known reviewer>}%
%%                           {<tokens in case <Argument> is not a known reviewer>}%
%%=============================================================================
\newcommand\CheckWhetherReviewerknown[1]{%
  \romannumeral0%
  \reviewerfork{#1}{%
     {\@firstofone{\expandafter} \@firstoftwo}%
     {\@firstofone{\expandafter} \@firstoftwo}%
     {\@firstofone{\expandafter} \@secondoftwo}%
  }%
}%
%%=============================================================================
%% Error-message in case the reviewer is unknown:
%% \unknownreviewererror{<reviewer>}%
%%                      {<name of macro that called \unknownreviewererror>}
%%=============================================================================
\newcommand\unknownreviewererror[2]{%
  \GenericError{%
    \space\space\space\@spaces\@spaces\@spaces
  }{%
   \@backslashchar#2-error\on@line: Reviewer `\detokenize{#1}' unknown%
  }{%
    See the comments of this file for explanation.%
  }{%
    Known reviewers in this demo are `John Doe' and `John Smith'.%
    \MessageBreak(The reviewer-argument is case sensitive.)%
  }%
}%
%%======================Code for \UDcollectverbarg=============================
%% \UDcollectverbarg{^^M-replacement}{<mandatory 1>}{<mandatory 2>}|<verbatim arg>|
%% 
%% reads <verbatim arg> under verbatim-catcode-regime and delivers:
%%
%%    <mandatory 1>{<mandatory 2>{<verbatim arg>}{|<verbatim arg>|}}
%%
%% Instead of verbatim-delimiter | the <verbatim arg> can be nested in braces.
%% You cannot use percent or spaces or horizontal tab as verbatim-delimiter.
%%
%% You can use <mandatory 1> for nesting calls to \UDcollectverbarg.
%% <mandatory 2> gets the <verbatim arg> twice: Once without verbatim-delimiters/braces,
%% once surrounded by verbatim-delimiters/braces.
%% Reason: When you feed it to \scantokens you don't need the verbatim-delimiters.
%%         When you use it for writing to temporary files and reading back,
%%         you need them.
%%=============================================================================
\begingroup
\catcode`\^^M=12 %
\@firstofone{%
  \endgroup%
  \newcommand\UDEndlreplace[2]{\romannumeral0\@UDEndlreplace{#2}#1^^M\relax{}}%
  \@ifdefinable\@UDEndlreplace{%
    \long\def\@UDEndlreplace#1#2^^M#3\relax#4#5{%
      \UD@CheckWhetherNull{#3}%
      { #5{#4#2}}{\@UDEndlreplace{#1}#3\relax{#4#2#1}{#5}}%
    }%
  }%
}%
\newcommand\UDcollectverbarg[3]{%
  \begingroup
  \let\do\@makeother % <- this and the next line switch to
  \dospecials        %    verbatim-category-code-régime.
  \catcode`\{=1      % <- give opening curly brace the usual catcode so a 
                     %    curly-brace-balanced argument can be gathered in
                     %    case of the first thing of the verbatimized-argument 
                     %    being a curly opening brace.
  \catcode`\ =10     % <- give space and horizontal tab the usual catcode so \UD@collectverbarg
  \catcode`\^^I=10   %    cannot catch a space or a horizontal tab as its 4th undelimited argument.
                     %    (Its 4th undelimited argument denotes the verbatim-
                     %     syntax-delimiter in case of not gathering a
                     %     curly-brace-nested argument.)
  \catcode`\%=14     % <- make percent comment.
  \kernel@ifnextchar\bgroup
  {% seems a curly-brace-nested argument is to be caught:
    \catcode`\}=2    % <- give closing curly brace the usual catcode also.
    \UD@collectverbarg{#1}{#2}{#3}{}%
  }{% seems an argument with verbatim-syntax-delimiter is to be caught:
    \do\{% <- give opening curly brace the verbatim-catcode again.
    \UD@collectverbarg{#1}{#2}{#3}%
  }%
}%
\newcommand\UD@collectverbarg[4]{%
  \do\ %   <- Now that \UD@collectverbarg has the delimiter or
  \do\^^I%    emptiness in its 4th arg, give space and horizontal tab
         %    the verbatim-catcode again.
  \do\^^M% <- Give the carriage-return-character the verbatim-catcode.
  \do\%%   <- Give the percent-character the verbatim-catcode.
  \long\def\@tempb##1#4{%
    \def\@tempb{##1}%
    \UD@CheckWhetherNull{#4}{%
      \def\@tempc{{##1}}%
    }{%
      \def\@tempc{#4##1#4}%
    }%
    \@onelevel@sanitize\@tempb % <- Turn characters into their "12/other"-pendants.
                               %    This may be important with things like the 
                               %    inputenc-package which may make characters 
                               %    active/which give them catcode 13(active).
    \expandafter\UDEndlreplace\expandafter{\@tempb}{#1}{\def\@tempb}% <- this starts 
                               %    the loop for replacing endline-characters.
    \@onelevel@sanitize\@tempc
    \expandafter\UDEndlreplace\expandafter{\@tempc}{#1}{\def\@tempc}%
    \expandafter\expandafter\expandafter\UD@@collectverbarg% <- this "spits out the result.
    \expandafter\expandafter\expandafter{%
    \expandafter\@tempb\expandafter}%
    \expandafter{\@tempc}{#2}{#3}%
  }%
  \@tempb
}%
\newcommand\UD@@collectverbarg[4]{%
  \endgroup
  #3{#4{#1}{#2}}%
}%
%%================= End of code for \UDcollectverbarg =========================
%%=============================================================================
%% \response{<reviewer>}{<comment>}{<response>}
%%    adds entries to toc-like-files \jobname.rvdoe or \jobname.rvsmith
%%    and \jobname.rvall
%%=============================================================================
\@ifdefinable\response{%
  \outer\long\def\response#1{%
    \UDcollectverbarg{^^J}{%
      \UDcollectverbarg{^^J}{\@firstofone}%
    }{\innerresponse{#1}}%
  }%
}%
\begingroup
% Now ^^A is used instead of %:
\catcode`\^^A=\the\catcode`\%\relax
\catcode`\%=12\relax
\@firstofone{^^A
  \endgroup
  \newcommand\innerresponse[5]{^^A
    ^^A #1 = <reviewer>
    ^^A #2 = <verbatimized comment without surrounding verbatim-delimiters>
    ^^A #3 = <verbatimized comment with surrounding verbatim-delimiters>
    ^^A #4 = <verbatimized response without surrounding verbatim-delimiters>
    ^^A #5 = <verbatimized response with surrounding verbatim-delimiters>
    \CheckWhetherReviewerknown{#1}{^^A
      \par\bigskip\noindent Comment by reviewer #1\\Comment: \scantokens{#2%}\\Response: \scantokens{#4%}^^A
      \responseentries{#1}{#3}{#5}^^A
    }{^^A
      \unknownreviewererror{#1}{response}^^A
    }^^A
  }^^A
  \newcommand\@innerresponsewritefile[1]{^^A
    \renewcommand\@innerresponsewritefile[6]{^^A
      ^^A #1 = space token
      ^^A ##1 = rv<reviewer>  (filename-extension)
      ^^A ##2 = <reviewer>
      ^^A ##3 = <verbatimized comment without surrounding verbatim-delimiters>
      ^^A ##4 = <verbatimized comment with surrounding verbatim-delimiters>
      ^^A ##5 = <verbatimized response without surrounding verbatim-delimiters>
      ^^A ##6 = <verbatimized response with surrounding verbatim-delimiters>
      \expandafter\UD@PassFirstToSecond\expandafter{^^A
                             \string\responselinewithreviewer^^J#1#1{##2}%^^J#1#1##4%^^J#1#1##6%^^A
                           }^^A
                           {\@writefile{rvall}}^^A
      \expandafter\UD@PassFirstToSecond\expandafter{^^A
                             \string\responselinewithoutreviewer^^J#1#1{##2}%^^J#1#1##4%^^J#1#1##6%^^A
                           }^^A
                           {\@writefile{##1}}^^A
    }^^A
  }^^A
  \@innerresponsewritefile{ }^^A
  \newcommand\innerresponselinewithreviewer[5]{^^A
    ^^A #1 = <reviewer>
    ^^A #2 = <verbatimized comment without surrounding verbatim-delimiters>
    ^^A #3 = <verbatimized comment with surrounding verbatim-delimiters>
    ^^A #4 = <verbatimized response without surrounding verbatim-delimiters>
    ^^A #5 = <verbatimized response with surrounding verbatim-delimiters>
    \par\bigskip\noindent Comment by reviewer #1\\Comment: \scantokens{#2%}\\Response: \scantokens{#4%}^^A
  }^^A
  \newcommand\innerresponselinewithoutreviewer[5]{^^A
    ^^A #1 = <reviewer>
    ^^A #2 = <verbatimized comment without surrounding verbatim-delimiters>
    ^^A #3 = <verbatimized comment with surrounding verbatim-delimiters>
    ^^A #4 = <verbatimized response without surrounding verbatim-delimiters>
    ^^A #5 = <verbatimized response with surrounding verbatim-delimiters>
    \par\bigskip\noindent Comment: \scantokens{#2%}\\Response: \scantokens{#4%}^^A
  }^^A
}% <- \@firstofone with changed catcodes done.
\newcommand\responseentries[3]{%
  % #1 = <reviewer>
  % #2 = <verbatimized comment with surrounding verbatim-delimiters>
  % #3 = <verbatimized response with surrounding verbatim-delimiters>
  \protected@write\@mainaux{}{%
     \string\@responsewritefile{\reviewerfork{#1}{{rvdoe}{rvsmith}{}}}\@percentchar^^J\space\space
     {#1}\@percentchar^^J\space\space
     #2\@percentchar^^J\space\space
     #3\@percentchar
  }%
}%
\newcommand\@responsewritefile[2]{%
  % #1 = rv<reviewer>  (filename-extension)
  % #2 = <reviewer>
  \UDcollectverbarg{^^J}{%
    \UDcollectverbarg{^^J}{\@firstofone}%
  }{\@innerresponsewritefile{#1}{#2}}%
}%
\newcommand\responselinewithreviewer[1]{%
  % #1 = <reviewer>
  \UDcollectverbarg{^^J}{%
    \UDcollectverbarg{^^J}{\@firstofone}%
  }{\innerresponselinewithreviewer{#1}}%
}%
\newcommand\responselinewithoutreviewer[1]{%
  % #1 = <reviewer>
  \UDcollectverbarg{^^J}{%
    \UDcollectverbarg{^^J}{\@firstofone}%
  }{\innerresponselinewithoutreviewer{#1}}%
}%
%%=============================================================================
%% \listofallresponses
%%   delivers all comments and responses.
%%
%% \dummylistofallresponses
%%   causes the .rvall-file to be written without delivering things into
%%   the document.
%%=============================================================================
\newcommand\listofallresponses{%
  \par\noindent ALL COMMENTS\par
  \@starttoc{rvall}%
}%
\newcommand\dummylistofallresponses{%
  \@dummystarttoc{rvall}%
}%
%%=============================================================================
%% \listofreviewersresponses{<reviewer>}%
%%   delivers all comments and responses that belong tp <reviewer>.
%%
%% \dummylistofreviewersresponses{<reviewer>}%
%%   causes the .rv<reviewer>-file to be written without delivering its 
%%   content into the document.
%%=============================================================================
\newcommand\listofreviewersresponses[1]{%
   \reviewerfork{#1}{%
     {\par\noindent COMMENTS BY REVIEWER JOHN DOE\par\@starttoc{rvdoe}}%
     {\par\noindent COMMENTS BY REVIEWER JOHN SMITH\par\@starttoc{rvsmith}}%
     {\unknownreviewererror{#1}{listofreviewersresponses}}%
   }%
}%
\newcommand\dummylistofreviewersresponses[1]{%
   \reviewerfork{#1}{%
     {\@dummystarttoc{rvdoe}}%
     {\@dummystarttoc{rvsmith}}%
     {\unknownreviewererror{#1}{dummylistofreviewersresponses}}%
   }%
}%
\newcommand\@dummystarttoc[1]{%
  \begingroup
  \makeatletter
  \if@filesw
    \expandafter\newwrite\csname tf@#1\endcsname
    \immediate\openout\csname tf@#1\endcsname\jobname.#1\relax
  \fi
  \@nobreakfalse
  \endgroup 
}%
\makeatother

\documentclass{article}
\usepackage{verbatim}% <- used only for \verbatiminput

\begin{document}
\enlargethispage{3cm}%
\vspace*{-3cm}%
\par\bigskip\noindent\textbf{\jobname.rvall looks like this:}

\verbatiminput{\jobname.rvall}%

\par\bigskip\noindent\textbf{\jobname.rvdoe looks like this:}

\verbatiminput{\jobname.rvdoe}%

\par\bigskip\noindent\textbf{\jobname.rvsmith looks like this:}

\verbatiminput{\jobname.rvsmith}%

\newpage

\InputIfFileExists{\jobname.rvall}{\par\bigskip\noindent\textbf{Inputting \jobname.rvall yields:}}{}

\InputIfFileExists{\jobname.rvdoe}{\par\bigskip\noindent\textbf{Inputting \jobname.rvdoe yields:}}{}%

\InputIfFileExists{\jobname.rvsmith}{\par\bigskip\noindent\textbf{Inputting \jobname.rvsmith yields:}}{}%

\newpage

% now let's cause the .rvall-file and the .rvdoe-file and the .rvsmith-file
% to be created_
%
% This will also import the files:
%
%\listofreviewersresponses{John Smith}%
%\bigskip
%\listofallresponses
%\bigskip
%\listofreviewersresponses{John Doe}%
%
% This will cause creation of these files only.
%
\dummylistofallresponses
\dummylistofreviewersresponses{John Smith}%
\dummylistofreviewersresponses{John Doe}%

\par\bigskip\noindent\textbf{The text of the main document is:}

\bigskip\noindent Some text.

\response{John Doe}{John Doe's first comment.}{Response to John Doe's first comment.}
\response{John Smith}%
         {John Smith's first comment.}%
         {Response to John Smith's first comment.}
\response{John Doe}{John Doe's second comment. It has verbatim
material: \verb|\TeX is funny|.
}{Response to John Doe's second comment.}
\response{John Smith}%
         {John Smith's second comment.}%
         |Response to John Smith's second comment. 
It has verbatim material 
with unbalanced braces:
\verb+\TeX}}} is funny!+|

\end{document}

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

verwandte Informationen