Ich habe ein Makro \printauthors, das eine Liste von Autoren enthält, zum Beispiel
John Doe, Barack Obama,...
Wie kann ich diesen Inhalt beispielsweise in eine Datei schreiben authors.txt
? Der Befehl
\immediate\write\myfile{\printauthors}
funktioniert nicht. Mache ich etwas falsch oder sollte ich einen anderen Weg verwenden?
Antwort1
Wenn \printauthors
es sich um das von mir vorgeschlagene Makro handelt,Zum Sortieren einer Zeichenfolge mit mehreren Einträgen, dann ist es einfach, die Funktionalität hinzuzufügen. Mit dieser Version
\printauthors
druckt nur die Namen aus, während
\printauthors[filename.ext]
gibt die gleichen Daten für die angegebene Datei aus:
\documentclass{article}
\usepackage{xparse,l3sort,pdftexcmds}
\ExplSyntaxOn
% a macro from pdftexcmds that works with all engines
\cs_set_eq:Nc \konewka_strcmp:nn { pdf@strcmp }
\NewDocumentCommand{\addauthor}{ o m m }
{
\IfNoValueTF{#1}
{
\konewka_add_author:nnn { #3 } { #2 } { #3 }
}
{
\konewka_add_author:nnn { #1 } { #2 } { #3 }
}
}
\NewDocumentCommand{\printauthors}{ o }
{
\IfNoValueTF { #1 }
{
\konewka_print_authors:
}
{
\konewka_print_authors_to_file:n { #1 }
}
}
\seq_new:N \g_konewka_authors_id_seq
\seq_new:N \l__konewka_authors_full_seq
\iow_new:N \g_konewka_write_authors_stream
\msg_new:nnn { konewka/authors } { author~exists }
{
The ~ author ~ #1 ~ already ~ exists; ~ it ~ won't ~ be ~ added ~ again
}
\cs_new_protected:Npn \konewka_add_author:nnn #1 #2 #3
{
\prop_if_exist:cTF { g_konewka_author_#1_prop }
{
\msg_warning:nnn { konewka/authors } { author~exists } { #1 }
}
{
\seq_gput_right:Nn \g_konewka_authors_id_seq { #1 }
\prop_new:c { g_konewka_author_#1_prop }
\prop_gput:cnn { g_konewka_author_#1_prop } { fname } { #2 }
\prop_gput:cnn { g_konewka_author_#1_prop } { lname } { #3 }
}
}
\cs_new_protected:Npn \konewka_print_authors:
{
\__konewka_sort_authors:
\seq_use:Nn \l__konewka_authors_full_seq { ,~ }
}
\cs_new_protected:Npn \konewka_print_authors_to_file:n #1
{
\iow_open:Nn \g_konewka_write_authors_stream { #1 }
\__konewka_sort_authors:
\iow_now:Nx \g_konewka_write_authors_stream
{
\seq_use:Nn \l__konewka_authors_full_seq { ,~ }
}
\iow_close:N \g_konewka_write_authors_stream
}
\cs_new_protected:Npn \__konewka_sort_authors:
{
\seq_gsort:Nn \g_konewka_authors_id_seq
{
\string_compare:nnnTF {##1} {>} {##2} {\sort_reversed:} {\sort_ordered:}
}
\seq_clear:N \l__konewka_authors_full_seq
\seq_map_inline:Nn \g_konewka_authors_id_seq
{
\seq_put_right:Nx \l__konewka_authors_full_seq
{
\prop_item:cn { g_konewka_author_##1_prop } { fname }
\c_space_tl
\prop_item:cn { g_konewka_author_##1_prop } { lname }
}
}
}
\prg_new_conditional:Npnn \string_compare:nnn #1 #2 #3 {TF}
{
\if_int_compare:w \konewka_strcmp:nn {#1}{#3} #2 \c_zero
\prg_return_true:
\else:
\prg_return_false:
\fi
}
\ExplSyntaxOff
\begin{document}
\addauthor{John}{Doe}
\addauthor{Harry}{Potter}
\addauthor[Uthor]{Archibald}{\"Uthor}
\addauthor{John}{Doe}
\addauthor{Bill}{Clinton}
\addauthor{Barack}{Obama}
\printauthors
\printauthors[\jobname.txt]
\end{document}
Der Inhalt \jobname.txt
ist
Bill Clinton, John Doe, Barack Obama, Harry Potter, Archibald \"Uthor
Beachten Sie, dass ich \jobname
früher keine meiner Dateien überschrieben habe.
Antwort2
\printauthors
Wenn Sie Folgendes verwenden :Zum Sortieren einer Zeichenfolge mit mehreren Einträgendann ist dieses Makro nicht erweiterbar und kann daher nicht in verwendet werden \immediate\write
. Sie müssen die Verarbeitung in die beiden Schritte „Vorbereiten“ und „Verwenden“ aufteilen. Der Schritt „Vorbereiten“ sortiert und dieses Makro ist nicht erweiterbar. Der Schritt „Verwenden“ erweitert nur das Ergebnis des Vorbereitungsschritts.
Ich kann dieses Konzept anhand meines Beispiels zeigen, aber Sie können diesen Code nicht direkt verwenden, da Sie nicht einfaches TeX verwenden.
\input opmac
\def\sort{\begingroup\setprimarysorting\def\iilist{}\sortA}
\def\sortA#1#2{\ifx\relax#1\sortB\else
\expandafter\addto\expandafter\iilist\csname,#1\endcsname
\expandafter\preparesorting\csname,#1\endcsname
\expandafter\edef\csname,#1\endcsname{{\tmpb}{#2}}%
\expandafter\sortA\fi
}
\def\sortB{\def\message##1{}\dosorting
\def\act##1{\ifx##1\relax\else \seconddata##1\sortC \expandafter\act\fi}%
\gdef\tmpb{}\expandafter\act\iilist\relax
\endgroup
}
\def\sortC#1&{\global\addto\tmpb{{#1}}}
\def\sortauthors{\def\tmp{}\expandafter\sortauthorsA\authors [] {} {}; }
\def\sortauthorsA [#1] #2 #3; {%
\ifx^#1^\expandafter\sort\tmp\relax\relax \let\sortedauthors=\tmpb
\else\addto\tmp{{#1}{#2 #3}}\expandafter\sortauthorsA\fi
}
\def\printauthors{\expandafter\printauthorsB\sortedauthors\relax}
\def\printauthorsB#1{\ifx\relax#1\else #1, \expandafter\printauthorsB\fi}
\newwrite
\def\authors{[Doe] John Doe; [Potter] Harry Potter; [Clinton] Bill Clinton;
[Uthor] Archibald \"Uthor; [Obama] Barack Obama; }
\sortauthors
\immediate\write\myfile{\printauthors}
\bye
Antwort3
Wenn \printauthors
es sich wirklich nur um ein einfaches Makro handelt, das zu einem String erweitert wird, dann genügt dies:
\documentclass{article}
\newwrite\myfile
\newcommand{\printauthors}{John Doe, Barack Obama}
\begin{document}
\immediate\openout\myfile=authors.txt
\immediate\write\myfile{\printauthors}
\end{document}