Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

My script needs to read a command from one aux file (testFileWriteReadExecute.yposIN.txt), then execute that same command which is a actually a call to a write macro which writes another command to a second file (testFileWriteReadExecute.yposOUT.txt).

Currently it produces the command in the PDF output instead of executing it. At some stage I had something similar working halfway, but have messed it up since, unfortunately.

testFileWriteReadExecute.yposin.txt looks like this:

\writeVerse{A}{1}{F}\comment{30580738}\endcomment
\writeVerse{A}{1}{L}\comment{29138946}\endcomment
\writeVerse{A}{2}{F}\comment{29138946}\endcomment
\writeVerse{A}{2}{L}\comment{27566082}\endcomment
\writeVerse{A}{3}{F}\comment{27566082}\endcomment
\writeVerse{A}{3}{L}\comment{25993218}\endcomment

MWE:

\documentclass[pagesize=pdftex, fontsize=10]{scrbook}
\usepackage[paperwidth=11.2cm, paperheight=17.4cm, top=1cm,bottom=1cm, left=1cm, right=1cm]{geometry}
\usepackage{fontspec}

\AtBeginDocument{%
    \newwrite\yposoutputfile%
    \openout\yposoutputfile=\jobname.yposout.txt%
}
\AtEndDocument{%
    \closeout\yposoutputfile%
}

\newcommand\writeVerse[3][]{%
  \writelines{#1}{#2}{#3}%
}

% Write the position to file.
\def\writelines#1#2#3{%
  \pdfsavepos%
    \write\yposoutputfile{%
    \string\writeVerse%
    \string{#1\string}%
    \string{#2\string}%
        \string{#3\string}%
        \string\comment\string{\the\pdflastypos\string}\string\endcomment%
    }%
}

% Open the file to read the commands.
\def\fromFile{
  \newread\yposinputfile%
  \openin\yposinputfile=\jobname.yposin.txt%
    \readline\yposinputfile to \fromFileLine%
  \closein\yposinputfile%
  \fromFileLine
}

\begin{document}
\fromFile %\writeVerse{A}{1}{F}
 LIBRO de la generación de Jesucristo, hijo de David, hijo de Abraham. \fromFile %\writeVerse{A}{1}{L}
\writeVerse{A}{2}{F} \textbf{2}~Abraham engendró á Isaac: é Isaac engendró á Jacob: y Jacob engendró á Judas y á sus hermanos:\writeVerse{A}{2}{L}
\writeVerse{A}{3}{F} \textbf{3}~Y Judas engendró de Thamar á Phares y á Zara: y Phares engendró á Esrom: y Esrom engendró á Aram:\writeVerse{A}{3}{L}
\end{document}

EDIT

The basic concept of what I want is simple.

  1. The XeLaTeX script grabs a line from the one text file which happens to be a TeX command, i.e. \writeVerse{A}{1}{F}
  2. It places in a particular place of the document this command, where this command gets executed/expanded instead of printed.
  3. The command is a call to a macro which in turn writes to another file.

EDIT 2:

Since the closest answer is this one by egreg I'll accept it, although it does not answer the fundamentals of my question. It does seem that this is a limitation in TeX.

share|improve this question
    
Your \fromFile command always reads the first line, because it opens and closes the file each time. But the main problem is that it can't be read, because it has been also opened for writing in it, so it's empty when \fromFile is found. –  egreg Mar 4 '13 at 10:47
    
@egreg Thanks, but I thought I circumvented that issue by using two files. A \jobname.yposIN.txt and a \jobname.yposOUT.txt. Did I miss something there? –  McGafter Mar 4 '13 at 10:54
    
You want to read an inexistent file. –  egreg Mar 4 '13 at 11:06
    
@egreg Did you mean the input file? I've created the input file by some other means (manually in this case), that's why I've given the contents thereof separately. The output file gets created by the tex script. Both exists with contents after the xelatex run, although the output is shorting the first two lines, due to the write command not executing. –  McGafter Mar 4 '13 at 11:13

1 Answer 1

up vote 3 down vote accepted

I don't really understand what \fromFile should do. However, you can avoid juggling the files by doing the write in the standard .aux file, and then overwriting the old "ypos" file at begin document.

\documentclass[pagesize=pdftex, fontsize=10]{scrbook}
\usepackage[
  paperwidth=11.2cm,
  paperheight=17.4cm,
  top=1cm,bottom=1cm,
  left=1cm,
  right=1cm]{geometry}
%\usepackage{fontspec}

% Allocate an output and an input stream
\newwrite\yposfileout
\newread\yposfilein

% If the file has been written, open it for reading
\AtBeginDocument{%
  \immediate\closeout\yposfileout
  \IfFileExists{\jobname.ypos.txt}
    {\openin\yposfilein=\jobname.ypos.txt}
    {\let\fromFile\relax}
}

% Write the position to file.
\makeatletter
\def\writelines#1#2#3{%
  \pdfsavepos%
  \write\@auxout{%
    \string\rewriteVerse{%
      \string\writeVerse{#1}{#2}{#3}%
      \string\comment\string{\the\pdflastypos\string}\string\endcomment
    }}%
}
\newif\if@writeverseopened
% when the `.aux` file is being read in at begin document, write out a new ypos file
\def\rewriteVerse#1{%
  \if@writeverseopened\else
    \immediate\openout\yposfileout=\jobname.ypos.txt
    \@writeverseopenedtrue
  \fi
  \immediate\write\yposfileout{\unexpanded{#1}}%
}
% Do nothing when the aux file is read in at end document
\AtEndDocument{\let\rewriteVerse\@gobble}

% Read the commands from the ypos file
\def\fromFile{%
  \readline\yposfilein to \fromFileLine
  \texttt{\fromFileLine}
}
\makeatother

% \writeVerse has an optional argument and two mandatory ones
\newcommand\writeVerse[3][]{%
  \writelines{#1}{#2}{#3}%
}


\begin{document}
\fromFile \writeVerse[A]{1}{F} LIBRO de la generación de Jesucristo,
hijo de David, hijo de Abraham. \fromFile \writeVerse[A]{1}{L}
\writeVerse[A]{2}{F} \textbf{2}~Abraham engendró á Isaac: é Isaac
engendró á Jacob: y Jacob engendró á Judas y á sus
hermanos:\writeVerse[A]{2}{L} \writeVerse[A]{3}{F} \textbf{3}~Y Judas
engendró de Thamar á Phares y á Zara: y Phares engendró á Esrom: y
Esrom engendró á Aram:\writeVerse[A]{3}{L}
\end{document}

You can use two files, provided your script changes the name of the former output file to the input file.

\documentclass[pagesize=pdftex, fontsize=10]{scrbook}
\usepackage[
  paperwidth=11.2cm,
  paperheight=17.4cm,
  top=1cm,bottom=1cm,
  left=1cm,
  right=1cm]{geometry}
\usepackage{atveryend,pdftexcmds}

\newwrite\yposfileout
\newread\yposfilein
\AtBeginDocument{%
  \IfFileExists{\jobname.yposin.txt}
    {\openin\yposfilein=\jobname.yposin.txt}
    {\let\fromFile\relax}
  \immediate\openout\yposfileout=\jobname.yposout.txt
}

% Write the position to file.
\def\writelines#1#2#3{%
  \pdfsavepos%
  \write\yposfileout{%
    \string\writeVerse{#1}{#2}{#3}%
    \string\comment\string{\the\pdflastypos\string}\string\endcomment
    }%
}
% Open the file to read the commands.
\def\fromFile{%
  \readline\yposfilein to \fromFileLine
  \texttt{\fromFileLine}
}

\makeatletter
\AtVeryEndDocument{%
  \closein\yposfilein
  \immediate\closeout\yposfileout
  \ifnum\pdf@shellescape>\z@
    \immediate\write18{mv \jobname.yposout.txt \jobname.yposin.txt}
  \fi
}
\makeatother

\newcommand\writeVerse[3][]{%
  \writelines{#1}{#2}{#3}%
}


\begin{document}
\fromFile \writeVerse[A]{1}{F} LIBRO de la generación de Jesucristo,
hijo de David, hijo de Abraham. \fromFile \writeVerse[A]{1}{L}
\writeVerse[A]{2}{F} \textbf{2}~Abraham engendró á Isaac: é Isaac
engendró á Jacob: y Jacob engendró á Judas y á sus
hermanos:\writeVerse[A]{2}{L} \writeVerse[A]{3}{F} \textbf{3}~Y Judas
engendró de Thamar á Phares y á Zara: y Phares engendró á Esrom: y
Esrom engendró á Aram:\writeVerse[A]{3}{L}
\end{document}

The \fromFile macro reads one line of the input file at each call.

If I run the file with -shell-escape, the \write18 istruction takes care of the name switching for the next run. You can do it with your script, of course.

share|improve this answer
    
Thanks but the \fromFile is really a replacement for writing out \writeVerse{A}{1}{F} etc. each time since due to other factors beyond the scope of the MWE the parameters will change for \writeVerse. So in reality you would not see \writeVerse{A}{1}{F} in there at all except in the aux files. This script gets called by an external OS script and might have to be run even up to a 1000 times before the layout would be satisfactory. But that's handled by the external script. This TeX file just need to be able to read an executable command from the first aux file and write to the second. –  McGafter Mar 4 '13 at 13:38
    
@McGafter Sorry, but I don't get it. –  egreg Mar 4 '13 at 13:39
    
Ok, Thanks. I've given a small clarification in the OP for what it's worth. The main issue at present is reading a command from an aux file and executing it on the same run. –  McGafter Mar 4 '13 at 14:07
    
@McGafter You can't do that: if the file is open for writing, you can't (reliably) read from it. –  egreg Mar 4 '13 at 14:10
    
I understand, but I want to read from the first file then write to a second file on the same run. –  McGafter Mar 4 '13 at 14:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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