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.

I'm fairly new to TeX and learning as I go. I am trying to keep a journal in LaTeX. I'm using the solution provided at Using LaTeX to keep a diary . It's essentially a setup where each day's entry is stored in a new file.

I hit the No room for a new \read error at entry 14. It seems like there are only so many files that I can include like this. Even then 14 sounds like a very small number. Is there a solution to this? A solution which will let me go on for years, adding thousands of entries. I have looked at No room for a new \read/\write which seems to discuss this or similar issue. But I'm not sure how to fix this code.

I have put the code in journal.tex file. In the same directory there is a folder called 2013, which contains a folder called Jan, which contains 14 .tex files 1.tex - 14.tex. All of them are completely empty.

journal.tex follows.

%This file layout courtesy of the following online recipe
%http://tex.stackexchange.com/questions/68525/using-latex-to-keep-a-diary

\documentclass{tufte-book}
%\usepackage{lipsum}
\usepackage{tikz}
\usepackage{xifthen}
\usepackage{soul}
\usepackage{minted}


\newenvironment{loggentry}[2]% date, heading
{\noindent\textbf{#2}\marginnote{#1}\par}{\vspace{0.5cm}}

\def\?#1{}

\pgfmathtruncatemacro{\StartYear}{2012}
\pgfmathtruncatemacro{\EndYear}{2013}

\newcommand{\writetitle}{0}
\newcommand{\mytitle}[1]
{   \ifthenelse{\writetitle=1}{#1}{}
}

\begin{document}

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
    {   \foreach \Day in {1,...,31}
        {   \IfFileExists{\Year/\Month/\Day}
                {   \newread\mysource
                    \openin\mysource=\Year/\Month/\Day.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{\Year/\Month/\Day}
                    \end{loggentry} 
                }
                {   % files does not exist, so nothing to do
                }
        }  
    }
}

\end{document}
share|improve this question
    
tex.stackexchange.com/questions/64372/… covers this to some extent, but perhaps without enough detail for the non-expert! –  Joseph Wright Jan 19 '13 at 20:19
    
yeah I had looked at that question but couldn't understand if any of that info, applied, and how. –  Spundun Jan 19 '13 at 20:21
    
OK, I suspected as much. Answer coming up if no-one beats me :-) –  Joseph Wright Jan 19 '13 at 20:21
add comment

1 Answer

up vote 8 down vote accepted

TeX allows only 16 file streams for reading. These are the 'lowest level' structures, and limit how many files can be read from at one go. However, this does not mean that you can only use 16 files! Assuming you need to read one line at a time (i.e. that you can' just \input the entire subfile), what you want is a single stream for reading, as you don't need to read from more than one file at a time. Thus instead of

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
    {   \foreach \Day in {1,...,31}
        {   \IfFileExists{\Year/\Month/\Day}
                {   \newread\mysource
                    \openin\mysource=\Year/\Month/\Day.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{\Year/\Month/\Day}
                    \end{loggentry} 
                }
                {   % files does not exist, so nothing to do
                }
        }  
    }
}

you want

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
    {   \foreach \Day in {1,...,31}
        {   \IfFileExists{\Year/\Month/\Day}
                {  % Line removed here
                    \openin\mysource=\Year/\Month/\Day.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{\Year/\Month/\Day}
                    \end{loggentry} 
                }
                {   % files does not exist, so nothing to do
                }
        }  
    }
}

with the line

\newread\mysource

moved outside of the loop: I'd put it in the preamble.

share|improve this answer
    
The same applies to \write streams: there are a maximum of 16. It's possible to use a 'pool' of streams so that user code is very unlikely to run out, but this is not set up by the LaTeX2e kernel. –  Joseph Wright Jan 19 '13 at 20:26
    
you mean \newread\mysource followed by \foreach \Year in...? –  Spundun Jan 19 '13 at 20:28
    
OK THAT worked perfectly for 14 files! Hopefully it'll work for 1014 files also... Thanks for a quick and accurate response. –  Spundun Jan 19 '13 at 20:30
    
@Spundun Well possibly yes, but as creating a read is a global thing (for the entire document), 'good style' would be to put that line in the preamble. –  Joseph Wright Jan 19 '13 at 20:30
    
ummm, what's a preamble, the part before \begin{document} ? (I feel highly silly asking this question :) ) –  Spundun Jan 19 '13 at 20:32
show 3 more comments

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.