1

I have a macro \printauthors that contains a list of authors, for example

John Doe, Barack Obama,...

How can I write this content to a file, for example authors.txt. The command

\immediate\write\myfile{\printauthors}

doesn't work. Am I doing something wrong or should I use another way?

  • Is \printauthors the macro I suggested? – egreg Dec 12 '14 at 13:21
2

If \printauthors is the macro I suggested in On sorting a string with multiple entries, then it's easy to add the functionality. With this version,

\printauthors

will just print the names while

\printauthors[filename.ext]

will output the same data on the specified file:

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

The contents of \jobname.txt is

Bill Clinton, John Doe, Barack Obama, Harry Potter, Archibald \"Uthor

Note that I used \jobname just not to clobber any of my files.

1

If you are using \printauthors from this: On sorting a string with multiple entries then this macro isn't expandable, thus it cannot be used in \immediate\write. You have to split the processing to the two steps: preparing and using. The "preparing" step does sorting and this macro is not expandable. The "using" step only expands the result of preparing step.

I can show this concept on my example, but you cannot use this code directly because you are not using plain TeX.

\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
  • On the other hand, my macros work (with minor modifications just because xparse isn't available) both with Plain e-TeX and LaTeX. Only the user level macros need to be redefined with \cs_new.... – egreg Dec 12 '14 at 15:38
  • @egreg On the other hand, my macros work (with minor modifications) in LaTeX too. But it is somewhat absurd to do \input opmac in LaTeX, bacause most functionalities (font selection, colors, hyperlinks, bibliography, indexes, references, multilingual support, ...) are iplemented twice in such case. Of course, better in opmac. This is comparable, why I am not doing somethig like \input latex.ltx in plain TeX, but TeX by its principle allows this (with minor modifictions). – wipet Dec 13 '14 at 5:02
0

If \printauthors really is just a simple macro that expands to a string, then this suffices:

\documentclass{article}
\newwrite\myfile
\newcommand{\printauthors}{John Doe, Barack Obama}
\begin{document}
\immediate\openout\myfile=authors.txt
\immediate\write\myfile{\printauthors}
\end{document}

See How to write a command to file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.