diff options
-rw-r--r-- | Master/texmf-dist/doc/latex/morewrites/README | 28 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/morewrites/morewrites.pdf | bin | 0 -> 489717 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/morewrites/morewrites.dtx | 838 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/morewrites/morewrites.ins | 19 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/morewrites/morewrites.sty | 428 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 2 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/morewrites.tlpsrc | 0 |
8 files changed, 1315 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/morewrites/README b/Master/texmf-dist/doc/latex/morewrites/README new file mode 100644 index 00000000000..98889b012f5 --- /dev/null +++ b/Master/texmf-dist/doc/latex/morewrites/README @@ -0,0 +1,28 @@ +---------------------------------------------------------------- +morewrites --- Always room for a new write +E-mail: blflatex@gmail.com +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +The morewrites package silently hooks into the TeX primitives +responsible for writing to files to lift the restriction on +the number of files open at the same time (16). Load the package +with "\usepackage{morewrites}" as early as possible. + +This package uses the l3kernel bundle. + +This is work in progress, all suggestions/comments/bug reports are welcome! + +The package is extracted by running + pdflatex morewrites.ins + +The documentation is produced by running + pdflatex morewrites.dtx + makeindex -s gglo.ist -o morewrites.gls morewrites.glo + makeindex -s gind.ist -o morewrites.ind morewrites.idx + pdflatex morewrites.dtx + pdflatex morewrites.dtx + + + diff --git a/Master/texmf-dist/doc/latex/morewrites/morewrites.pdf b/Master/texmf-dist/doc/latex/morewrites/morewrites.pdf Binary files differnew file mode 100644 index 00000000000..3bea8a5edd4 --- /dev/null +++ b/Master/texmf-dist/doc/latex/morewrites/morewrites.pdf diff --git a/Master/texmf-dist/source/latex/morewrites/morewrites.dtx b/Master/texmf-dist/source/latex/morewrites/morewrites.dtx new file mode 100644 index 00000000000..846186617df --- /dev/null +++ b/Master/texmf-dist/source/latex/morewrites/morewrites.dtx @@ -0,0 +1,838 @@ +% \iffalse meta-comment +% +%% File: morewrites.dtx Copyright (C) 2011 Bruno Le Floch +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% ----------------------------------------------------------------------- +% +%<*driver|package> +\RequirePackage{l3names} +\GetIdInfo$Id: morewrites.dtx 0.0 2011-07-09 00:00:00Z bruno $ + {Always room for a new write}% +%</driver|package> +%<*driver> +\RequirePackage{morewrites} +\documentclass[full]{l3doc} +\newwrite\foo \newwrite\foo \newwrite\foo \newwrite\foo +\newwrite\foo \newwrite\foo \newwrite\foo \newwrite\foo +\newwrite\foo \newwrite\foo \newwrite\foo \newwrite\foo +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{morewrites} package: \\ +% Always room for a new \cs{write}\thanks{This +% file has version number \ExplFileVersion, last revised \ExplFileDate.}} +% \author{Bruno Le Floch} +% \date{\ExplFileDate} +% +% \maketitle +% \tableofcontents +% +% \begin{documentation} +% +% \section{\pkg{morewrites} documentation} +% +% This \LaTeX{} package is meant to be a solution for the error +% \enquote{no room for a new \cs{write}}, which occurs when too +% many macro packages reserve streams to write data to various +% auxiliary files. It is in principle possible to rewrite packages +% so that they are less greedy on resources, but that is often +% unpractical for the end-user. Instead, \pkg{morewrites} hooks +% at the lowest level (\TeX{} primitives). If I did my job +% correctly, users simply need to add the line +% |\usepackage{morewrites}| somewhere near the beginning of the +% \LaTeX{} file, and the \enquote{no room for a new \cs{write}} +% error should be gone. +% +% As this is a rather new package, it has not been tested very +% thoroughly yet. I thus encourage you to check that references +% are correct after loading that package: if they are correct +% without \pkg{morewrites}, but wrong with, please send me a +% minimal file showing the problem, or post a question on the +% \url{tex.stackexchange.com} question and answers website, +% or the \url{comp.text.tex} newsgroup. +% +% \section{Known deficiencies} +% +% Some distributions of \TeX{} allow a quoted syntax for file +% names with spaces. I haven't yet coded that. A temporary fix +% is to avoid file names with spaces. +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{morewrites} implementation} +% +%<*package> +% \begin{macrocode} +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\RequirePackage{expl3} +% \end{macrocode} +% +% Let us recall the syntax of the commands that we need to modify +% (from Chapter 24 of the \TeX{}book): each of those can be preceeded +% by \cs{immediate}, which we will thus also have to modify. +% \begin{itemize} +% \item \cs{openout} \meta{4-bit number} \meta{equals} \meta{filename} +% \item \cs{write} \meta{number} \meta{general text} +% with a special case when \meta{number} is $18$. +% \item \cs{closeout} \meta{4-bit number} +% \end{itemize} +% Finally, we also need to modify \cs{newwrite} to let it allocate +% more than $16$ streams. +% +% \begin{macro}[aux]{\mw_tex_openin:w,\mw_tex_read:w, +% \mw_etex_readline:w,\mw_tex_closein:w} +% \begin{macro}[aux]{\mw_tex_immediate:w,\mw_tex_openout:w, +% \mw_tex_write:w,\mw_tex_closeout:w} +% First save the primitives (including those for input, +% because this package might be extended to cover that +% as well). +% \begin{macrocode} +\cs_new_eq:NN \mw_tex_openin:w \tex_openin:D +\cs_new_eq:NN \mw_tex_read:w \tex_read:D +\cs_new_eq:NN \mw_etex_readline:w \etex_readline:D +\cs_new_eq:NN \mw_tex_closein:w \tex_closein:D +\cs_new_eq:NN \mw_tex_immediate:w \tex_immediate:D +\cs_new_eq:NN \mw_tex_openout:w \tex_openout:D +\cs_new_eq:NN \mw_tex_write:w \tex_write:D +\cs_new_eq:NN \mw_tex_closeout:w \tex_closeout:D +\cs_new_eq:NN \mw_tex_shipout:w \tex_shipout:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Variables} +% +% \begin{variable}{\g_mw_late_write_int} +% The integer \cs{g_mw_late_write_int} labels the various +% non-immediate operations in the order in which they appear +% in the source. +% \begin{macrocode} +\int_new:N \g_mw_late_write_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_mw_writes_prop} +% The property list \cs{g_mw_writes_prop} +% associates a file name to each open stream. +% \begin{macrocode} +\prop_new:N \g_mw_writes_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_mw_read,\c_mw_tmp_file_tl} +% The expansion that \cs{write} performs is impossible +% to emulate with anything else than \cs{write}. We will +% need to write to a file and read back from it for things +% to work properly. +% \begin{macrocode} +\newread \g_mw_read +\tl_const:Nn \c_mw_tmp_file_tl { \jobname.mw } +\newwrite \g_mw_write +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_mw_reserved_writes_seq} +% Some of the writing streams are already allocated when loading +% this package, and we let \LaTeX{} manage them. +% \begin{macrocode} +\seq_new:N \g_mw_reserved_writes_seq +\prg_stepwise_inline:nnnn {0} {1} { \g_mw_write - 1 } + { \seq_gput_right:Nn \g_mw_reserved_writes_seq {#1} } +\seq_gput_right:Nn \g_mw_reserved_writes_seq {18} +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_mw_tmpa_tl,\g_mw_step_int,\g_mw_tmpa_int,\g_mw_box} +% \begin{macrocode} +\tl_new:N \l_mw_tmpa_tl +\int_new:N \g_mw_step_int +\int_new:N \g_mw_tmpa_int +\newbox \g_mw_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_mw_stream_int,\g_mw_filename_tl,\g_mw_text_tl} +% What parsing finds is stored in those three variables. +% \begin{macrocode} +\int_new:N \g_mw_stream_int +\tl_new:N \g_mw_filename_tl +\tl_new:N \g_mw_text_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[aux]{\mw_scan_stop:} +% A recognizable version of \cs{scan_stop:}. +% \begin{macrocode} +\cs_new_eq:NN \mw_scan_stop: \scan_stop: +% \end{macrocode} +% \end{macro} +% +% \subsection{Parsing} +% +% \begin{macro}[aux]{\mw_parse_number:Nw} +% Stores a number in \cs{g_mw_stream_int} before performing |#1|. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_number:Nw #1 + { + \tex_afterassignment:D #1 + \tex_global:D \g_mw_stream_int + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_parse_text:Nw} +% This is used for the \cs{write} command: to grab +% a \meta{general text} we assign a \cs{toks}, within +% a group to avoid clobbering \cs{toks}\texttt{0}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_text:Nw #1 + { + \group_begin: + \tex_aftergroup:D #1 + \tex_afterassignment:D \mw_parse_text_aux: + \tex_toks:D \c_zero = + } +\cs_new_protected_nopar:Npn \mw_parse_text_aux: + { + \tl_gset:Nx \g_mw_text_tl { \tex_the:D \tex_toks:D \c_zero } + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_parse_equals_filename:Nw} +% Remove a potential \texttt{=} sign. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_equals_filename:Nw #1 + { + \peek_meaning_remove:NTF = + { \mw_parse_filename:Nw #1 } { \mw_parse_filename:Nw #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_parse_filename:Nw} +% Empty the filename, and build it one character at a time. +% We need to expand tokens as in an f-type expansion, but +% without losing spaces. For that, we use \cs{peek_gafter:Nw} +% to find out whether the coming token is expandable or not, +% and distinguish further depending on what kind of +% non-expandable token it is. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_filename:Nw #1 + { + \group_begin: + \group_align_safe_begin: + \tex_aftergroup:D #1 + \tl_gclear:N \g_mw_filename_tl + \mw_parse_filename_loop:w + } +\cs_new_protected_nopar:Npn \mw_parse_filename_loop:w + { \peek_gafter:Nw \mw_parse_filename_loop_test: } +% \end{macrocode} +% The test \cs{token_if_expandable:NTF} should not be used here, +% since it returns false for undefined control sequences (by design). +% But when parsing a file name, undefined control sequences would +% be expanded, and cause errors. In order to keep this behaviour, +% we do the test ourselves. +% +% A non-expandable token is either a non-space character, a space +% character, or a control sequence (either a primitive or a register). +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_filename_loop_test: + { + \exp_after:wN \if_meaning:w \exp_not:N \g_peek_token \g_peek_token + \exp_after:wN \use_ii:nn + \else: + \exp_after:wN \use_i:nn + \fi: + { \exp_after:wN \mw_parse_filename_loop:w } + { + \token_if_cs:NTF \g_peek_token + { \mw_parse_filename_end: } + { + \mw_parse_filename_space_test:NTF \g_peek_token + { \mw_parse_filename_space_do:w } + { + \exp_after:wN \mw_parse_filename_push:w + \token_to_meaning:N + } + } + } + } +% \end{macrocode} +% We stop at the first non-expandable non-character token. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_filename_end: + { + \group_align_safe_end: + \group_end: + } +% \end{macrocode} +% We also stop when seeing a space, after removing it. +% \begin{macrocode} + %^^A TeXlive's behaviour (?): space with any catcode +\cs_new_protected_nopar:Npn \mw_parse_filename_space_test:NTF + { \token_if_eq_charcode:NNTF \c_space_token } +\cs_new_protected_nopar:Npn \mw_parse_filename_space_do:w + { + \tex_afterassignment:D \mw_parse_filename_end: + \cs_set_eq:NN \g_peek_token + } +% \end{macrocode} +% Finally, the case of normal characters. It seems +% that e.g., \cs{bgroup} is seen in the same way as an +% explicit left-brace character. Hence, we work with +% the \cs{meaning} of the character we are looking at. +% Most meanings of characters are two words, followed +% by the character. Three exceptions: ``math shift character'', +% ``alignment tab character'', and ``macro parameter character'', +% which have three words. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_parse_filename_push:w #1 ~ % + { + \tl_if_in:nnTF { math ~ alignment ~ macro } { #1 } + { \mw_parse_filename_push_three:w } + { \mw_parse_filename_push_two:w } + } +\cs_new_protected_nopar:Npn \mw_parse_filename_push_two:w #1 ~ #2 + { + \tl_gput_right:Nn \g_mw_filename_tl {#2} + \mw_parse_filename_loop:w + } +\cs_new_protected_nopar:Npn \mw_parse_filename_push_three:w #1 ~ #2 ~ #3 + { + \tl_gput_right:Nn \g_mw_filename_tl {#3} + \mw_parse_filename_loop:w + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Immediate (writing)} +% +% In the context of immediate writing, we can store the text +% in a token list, and only write it at the corresponding +% \cs{closeout} command. We keep track of a property list, +% \cs{g_mw_writes_prop}, of the writes which are +% open (from the point of view of the user), with the +% corresponding file name. +% +% \subsubsection{What follows \cs{immediate}} +% +% \begin{macro}[aux]{\mw_prg_case_meaning:Nnn} +% \begin{macro}[aux]{\mw_prg_case_meaning_aux:Nw} +% See \cs{prg_case_tl:Nnn}. Here, it is used by \cs{mw_immediate:w} +% to decide whether the following token is a writing command. +% \begin{macrocode} +\cs_new:Npn \mw_prg_case_meaning:Nnn #1#2#3 + { \mw_prg_case_meaning_aux:Nw #1 #2 #1 {#3} \q_recursion_stop } +\cs_new:Npn \mw_prg_case_meaning_aux:Nw #1#2#3 + { + \token_if_eq_meaning:NNTF #1 #2 + { \prg_case_end:nw {#3} } + { \mw_prg_case_meaning_aux:Nw #1 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\mw_exp_after:Nf} +% Eventually, this should be replaced by a slow \cs{futurelet}-based +% expansion which does not lose a space. +% \begin{macrocode} +\cs_new:Npn \mw_exp_after:Nf #1 + { \exp_after:wN #1 \tex_romannumeral:D -`0 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_immediate:w} +% This is a little bit subtle: \TeX{}'s \cs{immediate} primitive +% raises a flag which is cancelled once \TeX{} sees a non-expandable +% token. This can be emulated by expanding tokens in front of it until +% the first non-expandable token, and checking if it is either +% \cs{openout}, \cs{write}, or \cs{closeout}. We will use f-type +% expansion.\footnote{Unfortunately, this is not quite correct, since it +% loses a space if someone puts \cs{immediate} at places where it +% does not belong, such as \cs{immediate} \cs{c_space_tl}.} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate:w + { + \scan_stop: %^^A? + \mw_exp_after:Nf \mw_immediate_aux:w + } +\cs_new_protected_nopar:Npn \mw_immediate_aux:w + { + \peek_meaning:NT \mw_scan_stop: + { \mw_immediate_mw_scan_stop:N } + } +\cs_new_protected_nopar:Npn \mw_immediate_mw_scan_stop:N #1 + { + \str_if_eq:nnTF { #1 } { \mw_scan_stop: } + { \mw_immediate_do:NN } + { #1 } + } +\cs_new_protected_nopar:Npn \mw_immediate_do:NN #1 #2 + { + \exp_args:Nc \mw_parse_number:Nw + { + \exp_after:wN \mw_immediate_do_aux:w + \token_to_str:N #2 + } + } +\use:x + { + \cs_new_protected_nopar:Npn \exp_not:N \mw_immediate_do_aux:w + ##1 \tl_to_str:n {mw_} { mw_immediate_ } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Immediate closeout} +% +% \begin{macro}[aux]{\mw_immediate_closeout_test:} +% When the user requests to close a stream, we look in +% \cs{g_mw_reserved_writes_seq} to see if it is a reserved +% stream: in this case, we simply use the primitive. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_closeout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_stream_int } + { \mw_immediate_closeout_aux: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_immediate_closeout_aux:} +% We then look in \cs{g_mw_writes_prop} to find +% the file name corresponding to that stream number. If the +% stream does not appear as a key in the property list, +% then it was not open yet, and we do nothing. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_closeout_aux: + { + \exp_args:NNV \prop_pop:NnNT + \g_mw_writes_prop \g_mw_stream_int \l_mw_tmpa_tl + { + \mw_tex_immediate:w \mw_tex_openout:w + \g_mw_write \l_mw_tmpa_tl \scan_stop: + \group_begin: + \int_set_eq:NN \tex_newlinechar:D \c_minus_one + \tl_use:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + \tl_gclear:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + \group_end: + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Immediate openout} +% +% \begin{macro}[aux]{\mw_immediate_openout_test:} +% Read the stream number. If it is one of the reserved streams, +% we use the primitive. Otherwise, parse an optional equal sign, +% followed by the file name. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_openout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_openout:w \g_mw_stream_int } + { \mw_parse_equals_filename:Nw \mw_immediate_openout_aux: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_immediate_openout_aux:} +% When the user requests to open a stream, it might already be +% open, with another file as its destination. We thus need to +% first close the stream, writing all that we collected so far +% to that other file. This has no effect if the stream was not +% open yet. +% +% We then put the stream and its associated filename in the +% property list, and empty the corresponding token list. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_openout_aux: + { + \mw_immediate_closeout_aux: + \prop_gput:NVV \g_mw_writes_prop \g_mw_stream_int \g_mw_filename_tl + \tl_gclear_new:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Immediate write} +% +% \begin{macro}[aux]{\mw_immediate_write_test:} +% Read the stream number. If it is one of the reserved streams, +% we use the primitive. Otherwise, parse the text. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_write_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_write:w \g_mw_stream_int } + { \mw_parse_text:Nw \mw_immediate_write_aux: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_immediate_write_aux:} +% Only \cs{write} itself can emulate how \cs{write} expands tokens, +% because |#| don't have to be doubled. Hence, we write to a file, +% and re-read from it, setting \cs{endlinechar} to $-1$ to avoid +% spurious characters. Lines will be written one at a time: this +% allows us to set \cs{newlinechar} to $-1$ when writing, so that +% no extra line will be created. +% +% If the stream \cs{g_mw_stream_int} is not allocated, +% then write either to the terminal or only to the log file. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_immediate_write_aux: + { + \prop_if_in:NVTF \g_mw_writes_prop \g_mw_stream_int + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write + \c_mw_tmp_file_tl \scan_stop: + \mw_tex_immediate:w \mw_tex_write:w \g_mw_write { \g_mw_text_tl } + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + \group_begin: + \int_set_eq:NN \tex_endlinechar:D \c_minus_one + \mw_tex_openin:w \g_mw_read \c_mw_tmp_file_tl \scan_stop: + \mw_immediate_write_aux_readlines: + \mw_tex_closein:w \g_mw_read + \group_end: + } + { + \mw_tex_immediate:w \mw_tex_write:w + \if_num:w \g_mw_stream_int < \c_zero + -1 + \else: + 16 + \fi: + { \g_mw_text_tl } + } + } +\cs_new_protected_nopar:Npn \mw_immediate_write_aux_readlines: + { + \mw_etex_readline:w \g_mw_read to \l_tmpa_tl + \ior_if_eof:NF \g_mw_read + { + \tl_gput_right:cx + { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + { \mw_tex_immediate:w \mw_tex_write:w \g_mw_write { \l_tmpa_tl } } + \mw_immediate_write_aux_readlines: + } + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Non-immediate writing} +% +% This is trickier, because the expansion of the text for +% a non-immediate \cs{write} takes place immediately after +% the page containing it is shipped out. We store each +% non-immediate \cs{openout}, \cs{write}, or \cs{closeout} +% without expansion in separate token lists +% \cs{g_mw_late_write_}\meta{N}\texttt{_tl} to be used later, +% and instead write |`(|\meta{N}|)| to a file (including the +% strange delimiters). After each shipout, we can read the +% file to see which output operations we need to perform, +% and in what order. +% +% \begin{macro}[aux]{\mw_late_aux:nN} +% Store the action to be done at shipout in a token list, +% and non-immediately write the label \cs{g_mw_late_write_int} +% of the output operation to the temporary file. +% Here, |#1| holds an assignment similar to the lines above it, +% and |#2| holds the relevant immediate action to be performed +% after shipout. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_late_aux:nN #1 #2 + { + \int_gincr:N \g_mw_late_write_int + \tl_const:cx { c_mw_late_write_ \int_use:N \g_mw_late_write_int _tl } + { + \int_gset:Nn \exp_not:N \g_mw_stream_int + { \exp_not:V \g_mw_stream_int } + #1 + \exp_not:N #2 + } + \exp_args:NNx \mw_tex_write:w \g_mw_write + { `( \int_use:N \g_mw_late_write_int ) } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_openout:w} +% \begin{macro}[aux]{\mw_openout_test:,\mw_openout_aux:} +% \cs{openout} tests if the number to come is among reserved streams. +% If it is, use the primitive, otherwise, parse a filename. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_openout:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_openout_test: } +\cs_new_protected_nopar:Npn \mw_openout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_openout:w \g_mw_stream_int } + { \mw_parse_equals_filename:Nw \mw_openout_aux: } + } +\cs_new_protected_nopar:Npn \mw_openout_aux: + { + \mw_late_aux:nN + { + \tl_gset:Nn \exp_not:N \g_mw_filename_tl + { \exp_not:V \g_mw_filename_tl } + } + \mw_immediate_openout_aux: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\mw_write:w} +% \begin{macro}[aux]{\mw_write_test:,\mw_write_aux:} +% Same idea for \cs{write}, except that we parse a text. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_write:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_write_test: } +\cs_new_protected_nopar:Npn \mw_write_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_write:w \g_mw_stream_int } + { \mw_parse_text:Nw \mw_write_aux: } + } +\cs_new_protected_nopar:Npn \mw_write_aux: + { + \mw_late_aux:nN + { + \tl_gset:Nn \exp_not:N \g_mw_text_tl + { \exp_not:V \g_mw_text_tl } + } + \mw_immediate_write_aux: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\mw_closeout:w} +% \begin{macro}[aux]{\mw_closeout_test:,\mw_closeout_aux:} +% Same idea for \cs{closeout}, and we don't need to parse +% anything else than the number. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_closeout:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_closeout_test: } +\cs_new_protected_nopar:Npn \mw_closeout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_closeout:w \g_mw_stream_int } + { \mw_closeout_aux: } + } +\cs_new_protected_nopar:Npn \mw_closeout_aux: + { \mw_late_aux:nN { } \mw_immediate_closeout_aux: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\mw_before_shipout:} +% Immediately before the shipout, we must open the writing stream +% \cs{g_mw_write}. Each delayed output operation has been replaced +% by \cs{write} \cs{g_mw_write} |{`(|\meta{operation number}|}|. +% The delimiters we chose to put around numbers must be at least +% two distinct characters on the left (then \cs{tex_newlinechar:D} +% cannot be equal to the delimiter), and at least one non-digit +% character on the right. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_before_shipout: + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write + \c_mw_tmp_file_tl \scan_stop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_after_shipout:} +% After all the \cs{write}s are performed, we read the file, +% and grab the relevant pieces in a seq. +% \begin{macrocode} +\seq_new:N \g_mw_operations_seq +\cs_new_protected_nopar:Npn \mw_after_shipout: + { + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + \group_begin: + \int_set_eq:NN \tex_endlinechar:D \tex_newlinechar:D + \tl_map_inline:nn { `(0123456789) } + { \char_set_catcode_other:n {`##1} } + \etex_everyeof:D { `() \exp_not:N } + \tl_gset:Nx \g_mw_operations_seq + { \if_false: } \fi: + \exp_after:wN \mw_after_shipout_loop:ww + \tex_input:D \c_mw_tmp_file_tl \scan_stop: + \group_end: + \seq_map_inline:Nn \g_mw_operations_seq + { + \tl_use:c + { c_mw_late_write_ ##1 _tl } + } + } +\cs_new:Npn \mw_after_shipout_loop:ww #1 `( #2 ) + { + \tl_if_empty:nTF {#2} + { \if_false: { \fi: } } + { + \exp_not:N \seq_item:n {#2} + \mw_after_shipout_loop:ww + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\shipout} +% \begin{macro}[aux]{\mw_shipout:w} +% If \pkg{atbegshi} is available, patch it by adding +% \cs{mw_after_shipout:} at the right place. Otherwise, +% redefine \cs{shipout} to add a hook. +% \begin{macrocode} +\IfFileExists{atbegshi.sty} + { + \RequirePackage{atbegshi} + \tl_replace_in:Nnn \AtBegShi@Output + { \AtBegShi@OrgShipout \box \AtBeginShipoutBox } + { + \mw_before_shipout: + \AtBegShi@OrgShipout \box \AtBeginShipoutBox + \mw_after_shipout: + } + \tl_replace_in:Nnn \AtBegShi@Output + { \AtBeginShipoutOriginalShipout \box \AtBeginShipoutBox } + { + \mw_before_shipout: + \AtBeginShipoutOriginalShipout \box \AtBeginShipoutBox + \mw_after_shipout: + } + } + { + \cs_new_protected_nopar:Npn \mw_shipout:w + { + \int_gset_eq:NN \g_mw_tmpa_int \etex_currentgrouplevel:D + \tex_afterassignment:D \mw_shipout_aux: + \tex_global:D \tex_setbox:D \g_mw_box + } + \cs_new_protected_nopar:Npn \mw_shipout_aux: + { + \int_compare:nNnTF { \g_mw_tmpa_int } + = { \etex_currentgrouplevel:D } + { \mw_shipout_aux_ii: } + { \tex_aftergroup:D \mw_shipout_aux_ii: } + } + \cs_new_protected_nopar:Npn \mw_shipout_aux_ii: + { + \mw_before_shipout: + \mw_tex_shipout:w \tex_box:D \g_mw_box + \mw_after_shipout: + } + \cs_gset_eq:NN \shipout \mw_shipout:w + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Hook at the very end} +% +% \begin{macro}[aux]{\mw_close_all:} +% At the end of the document, close all the files. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \mw_close_all: + { + \prop_map_inline:Nn \g_mw_writes_prop + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write ##2 \scan_stop: + \group_begin: + \int_set_eq:NN \tex_newlinechar:D \c_minus_one + \tl_use:c { g_mw_write_ ##1 _tl } + \tl_gclear:c { g_mw_write_ ##1 _tl } + \group_end: + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + } + \prop_gclear:N \g_mw_writes_prop + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\mw_put_at_end:Nw} +% This pushes its first argument to the very end of the \LaTeX{} run, +% recursively, just in case some other code adds things there. +% If \pkg{atveryend} is available, we use it instead. +% \begin{macrocode} +\IfFileExists{atveryend.sty} { \use_i:nn } { \use_ii:nn } + { + \RequirePackage {atveryend} + \AtVeryVeryEnd { \mw_close_all: } + } + { + \cs_new_protected:Npn \mw_put_at_end:Nw #1 #2 \@@end + { + \tl_if_empty:nTF {#2} + { #1 \@@end } + { #2 \mw_put_at_end:Nw #1 \@@end } + } + \AtEndDocument { \mw_put_at_end:Nw \mw_close_all: } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Modified \cs{newwrite}} +% +% \begin{macro}[aux]{\newwrite} +% We need to allow \cs{newwrite} to allocate more than $16$ writes, +% but beware that $18$ is reserved, and that packages might expect +% $16$ or $17$ to write to the terminal. So instead skip until $20$. +% \begin{macrocode} +\countdef \mw_write_int 17 \scan_stop: +\cs_new:Npn \mw_newwrite:N #1 + { + \if_num:w \mw_write_int = \c_sixteen + \int_gset:Nn \mw_write_int { 20 } + \fi: + \int_set_eq:NN \allocationnumber \mw_write_int + \int_gincr:N \mw_write_int + \cs_undefine:N #1 + \int_const:Nn #1 { \allocationnumber } + \wlog {\string #1=\string \write \the \allocationnumber } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Redefining the ``normal'' control sequences} +% +% \begin{macro}[aux]{\immediate,\openout,\write,\closeout,\newwrite} +% \cs{shipout} has been redefined earlier. +% \begin{macrocode} +\cs_gset_eq:NN \immediate \mw_immediate:w +\cs_gset_eq:NN \openout \mw_openout:w +\cs_gset_eq:NN \write \mw_write:w +\cs_gset_eq:NN \closeout \mw_closeout:w +\cs_gset_eq:NN \newwrite \mw_newwrite:N +% \end{macrocode} +% \end{macro} +% +%</package> +% +% \end{implementation} +% +% \endinput diff --git a/Master/texmf-dist/source/latex/morewrites/morewrites.ins b/Master/texmf-dist/source/latex/morewrites/morewrites.ins new file mode 100644 index 00000000000..814fd46a489 --- /dev/null +++ b/Master/texmf-dist/source/latex/morewrites/morewrites.ins @@ -0,0 +1,19 @@ +\input docstrip.tex +\askforoverwritefalse + +\preamble + +Communicate any suggestions for changing this package +to Bruno Le Floch (blflatex@gmail.com). + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble + +\keepsilent + +% the package +\generate{\file{morewrites.sty}{\from{morewrites.dtx}{package}}} + +\endbatchfile diff --git a/Master/texmf-dist/tex/latex/morewrites/morewrites.sty b/Master/texmf-dist/tex/latex/morewrites/morewrites.sty new file mode 100644 index 00000000000..eaf2c1b4bcb --- /dev/null +++ b/Master/texmf-dist/tex/latex/morewrites/morewrites.sty @@ -0,0 +1,428 @@ +%% +%% This is file `morewrites.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% morewrites.dtx (with options: `package') +%% +%% Communicate any suggestions for changing this package +%% to Bruno Le Floch (blflatex@gmail.com). +%% +%% File: morewrites.dtx Copyright (C) 2011 Bruno Le Floch +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% ----------------------------------------------------------------------- +\RequirePackage{l3names} +\GetIdInfo$Id: morewrites.dtx 0.0 2011-07-09 00:00:00Z bruno $ + {Always room for a new write}% +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\RequirePackage{expl3} +\cs_new_eq:NN \mw_tex_openin:w \tex_openin:D +\cs_new_eq:NN \mw_tex_read:w \tex_read:D +\cs_new_eq:NN \mw_etex_readline:w \etex_readline:D +\cs_new_eq:NN \mw_tex_closein:w \tex_closein:D +\cs_new_eq:NN \mw_tex_immediate:w \tex_immediate:D +\cs_new_eq:NN \mw_tex_openout:w \tex_openout:D +\cs_new_eq:NN \mw_tex_write:w \tex_write:D +\cs_new_eq:NN \mw_tex_closeout:w \tex_closeout:D +\cs_new_eq:NN \mw_tex_shipout:w \tex_shipout:D +\int_new:N \g_mw_late_write_int +\prop_new:N \g_mw_writes_prop +\newread \g_mw_read +\tl_const:Nn \c_mw_tmp_file_tl { \jobname.mw } +\newwrite \g_mw_write +\seq_new:N \g_mw_reserved_writes_seq +\prg_stepwise_inline:nnnn {0} {1} { \g_mw_write - 1 } + { \seq_gput_right:Nn \g_mw_reserved_writes_seq {#1} } +\seq_gput_right:Nn \g_mw_reserved_writes_seq {18} +\tl_new:N \l_mw_tmpa_tl +\int_new:N \g_mw_step_int +\int_new:N \g_mw_tmpa_int +\newbox \g_mw_box +\int_new:N \g_mw_stream_int +\tl_new:N \g_mw_filename_tl +\tl_new:N \g_mw_text_tl +\cs_new_eq:NN \mw_scan_stop: \scan_stop: +\cs_new_protected_nopar:Npn \mw_parse_number:Nw #1 + { + \tex_afterassignment:D #1 + \tex_global:D \g_mw_stream_int + } +\cs_new_protected_nopar:Npn \mw_parse_text:Nw #1 + { + \group_begin: + \tex_aftergroup:D #1 + \tex_afterassignment:D \mw_parse_text_aux: + \tex_toks:D \c_zero = + } +\cs_new_protected_nopar:Npn \mw_parse_text_aux: + { + \tl_gset:Nx \g_mw_text_tl { \tex_the:D \tex_toks:D \c_zero } + \group_end: + } +\cs_new_protected_nopar:Npn \mw_parse_equals_filename:Nw #1 + { + \peek_meaning_remove:NTF = + { \mw_parse_filename:Nw #1 } { \mw_parse_filename:Nw #1 } + } +\cs_new_protected_nopar:Npn \mw_parse_filename:Nw #1 + { + \group_begin: + \group_align_safe_begin: + \tex_aftergroup:D #1 + \tl_gclear:N \g_mw_filename_tl + \mw_parse_filename_loop:w + } +\cs_new_protected_nopar:Npn \mw_parse_filename_loop:w + { \peek_gafter:Nw \mw_parse_filename_loop_test: } +\cs_new_protected_nopar:Npn \mw_parse_filename_loop_test: + { + \exp_after:wN \if_meaning:w \exp_not:N \g_peek_token \g_peek_token + \exp_after:wN \use_ii:nn + \else: + \exp_after:wN \use_i:nn + \fi: + { \exp_after:wN \mw_parse_filename_loop:w } + { + \token_if_cs:NTF \g_peek_token + { \mw_parse_filename_end: } + { + \mw_parse_filename_space_test:NTF \g_peek_token + { \mw_parse_filename_space_do:w } + { + \exp_after:wN \mw_parse_filename_push:w + \token_to_meaning:N + } + } + } + } +\cs_new_protected_nopar:Npn \mw_parse_filename_end: + { + \group_align_safe_end: + \group_end: + } + %^^A TeXlive's behaviour (?): space with any catcode +\cs_new_protected_nopar:Npn \mw_parse_filename_space_test:NTF + { \token_if_eq_charcode:NNTF \c_space_token } +\cs_new_protected_nopar:Npn \mw_parse_filename_space_do:w + { + \tex_afterassignment:D \mw_parse_filename_end: + \cs_set_eq:NN \g_peek_token + } +\cs_new_protected_nopar:Npn \mw_parse_filename_push:w #1 ~ % + { + \tl_if_in:nnTF { math ~ alignment ~ macro } { #1 } + { \mw_parse_filename_push_three:w } + { \mw_parse_filename_push_two:w } + } +\cs_new_protected_nopar:Npn \mw_parse_filename_push_two:w #1 ~ #2 + { + \tl_gput_right:Nn \g_mw_filename_tl {#2} + \mw_parse_filename_loop:w + } +\cs_new_protected_nopar:Npn \mw_parse_filename_push_three:w #1 ~ #2 ~ #3 + { + \tl_gput_right:Nn \g_mw_filename_tl {#3} + \mw_parse_filename_loop:w + } +\cs_new:Npn \mw_prg_case_meaning:Nnn #1#2#3 + { \mw_prg_case_meaning_aux:Nw #1 #2 #1 {#3} \q_recursion_stop } +\cs_new:Npn \mw_prg_case_meaning_aux:Nw #1#2#3 + { + \token_if_eq_meaning:NNTF #1 #2 + { \prg_case_end:nw {#3} } + { \mw_prg_case_meaning_aux:Nw #1 } + } +\cs_new:Npn \mw_exp_after:Nf #1 + { \exp_after:wN #1 \tex_romannumeral:D -`0 } +\cs_new_protected_nopar:Npn \mw_immediate:w + { + \scan_stop: %^^A? + \mw_exp_after:Nf \mw_immediate_aux:w + } +\cs_new_protected_nopar:Npn \mw_immediate_aux:w + { + \peek_meaning:NT \mw_scan_stop: + { \mw_immediate_mw_scan_stop:N } + } +\cs_new_protected_nopar:Npn \mw_immediate_mw_scan_stop:N #1 + { + \str_if_eq:nnTF { #1 } { \mw_scan_stop: } + { \mw_immediate_do:NN } + { #1 } + } +\cs_new_protected_nopar:Npn \mw_immediate_do:NN #1 #2 + { + \exp_args:Nc \mw_parse_number:Nw + { + \exp_after:wN \mw_immediate_do_aux:w + \token_to_str:N #2 + } + } +\use:x + { + \cs_new_protected_nopar:Npn \exp_not:N \mw_immediate_do_aux:w + ##1 \tl_to_str:n {mw_} { mw_immediate_ } + } +\cs_new_protected_nopar:Npn \mw_immediate_closeout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_stream_int } + { \mw_immediate_closeout_aux: } + } +\cs_new_protected_nopar:Npn \mw_immediate_closeout_aux: + { + \exp_args:NNV \prop_pop:NnNT + \g_mw_writes_prop \g_mw_stream_int \l_mw_tmpa_tl + { + \mw_tex_immediate:w \mw_tex_openout:w + \g_mw_write \l_mw_tmpa_tl \scan_stop: + \group_begin: + \int_set_eq:NN \tex_newlinechar:D \c_minus_one + \tl_use:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + \tl_gclear:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + \group_end: + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + } + } +\cs_new_protected_nopar:Npn \mw_immediate_openout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_openout:w \g_mw_stream_int } + { \mw_parse_equals_filename:Nw \mw_immediate_openout_aux: } + } +\cs_new_protected_nopar:Npn \mw_immediate_openout_aux: + { + \mw_immediate_closeout_aux: + \prop_gput:NVV \g_mw_writes_prop \g_mw_stream_int \g_mw_filename_tl + \tl_gclear_new:c { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + } +\cs_new_protected_nopar:Npn \mw_immediate_write_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_immediate:w \mw_tex_write:w \g_mw_stream_int } + { \mw_parse_text:Nw \mw_immediate_write_aux: } + } +\cs_new_protected_nopar:Npn \mw_immediate_write_aux: + { + \prop_if_in:NVTF \g_mw_writes_prop \g_mw_stream_int + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write + \c_mw_tmp_file_tl \scan_stop: + \mw_tex_immediate:w \mw_tex_write:w \g_mw_write { \g_mw_text_tl } + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + \group_begin: + \int_set_eq:NN \tex_endlinechar:D \c_minus_one + \mw_tex_openin:w \g_mw_read \c_mw_tmp_file_tl \scan_stop: + \mw_immediate_write_aux_readlines: + \mw_tex_closein:w \g_mw_read + \group_end: + } + { + \mw_tex_immediate:w \mw_tex_write:w + \if_num:w \g_mw_stream_int < \c_zero + -1 + \else: + 16 + \fi: + { \g_mw_text_tl } + } + } +\cs_new_protected_nopar:Npn \mw_immediate_write_aux_readlines: + { + \mw_etex_readline:w \g_mw_read to \l_tmpa_tl + \ior_if_eof:NF \g_mw_read + { + \tl_gput_right:cx + { g_mw_write_ \int_use:N \g_mw_stream_int _tl } + { \mw_tex_immediate:w \mw_tex_write:w \g_mw_write { \l_tmpa_tl } } + \mw_immediate_write_aux_readlines: + } + } +\cs_new_protected_nopar:Npn \mw_late_aux:nN #1 #2 + { + \int_gincr:N \g_mw_late_write_int + \tl_const:cx { c_mw_late_write_ \int_use:N \g_mw_late_write_int _tl } + { + \int_gset:Nn \exp_not:N \g_mw_stream_int + { \exp_not:V \g_mw_stream_int } + #1 + \exp_not:N #2 + } + \exp_args:NNx \mw_tex_write:w \g_mw_write + { `( \int_use:N \g_mw_late_write_int ) } + } +\cs_new_protected_nopar:Npn \mw_openout:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_openout_test: } +\cs_new_protected_nopar:Npn \mw_openout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_openout:w \g_mw_stream_int } + { \mw_parse_equals_filename:Nw \mw_openout_aux: } + } +\cs_new_protected_nopar:Npn \mw_openout_aux: + { + \mw_late_aux:nN + { + \tl_gset:Nn \exp_not:N \g_mw_filename_tl + { \exp_not:V \g_mw_filename_tl } + } + \mw_immediate_openout_aux: + } +\cs_new_protected_nopar:Npn \mw_write:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_write_test: } +\cs_new_protected_nopar:Npn \mw_write_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_write:w \g_mw_stream_int } + { \mw_parse_text:Nw \mw_write_aux: } + } +\cs_new_protected_nopar:Npn \mw_write_aux: + { + \mw_late_aux:nN + { + \tl_gset:Nn \exp_not:N \g_mw_text_tl + { \exp_not:V \g_mw_text_tl } + } + \mw_immediate_write_aux: + } +\cs_new_protected_nopar:Npn \mw_closeout:w + { \mw_scan_stop: \mw_parse_number:Nw \mw_closeout_test: } +\cs_new_protected_nopar:Npn \mw_closeout_test: + { + \seq_if_in:NVTF \g_mw_reserved_writes_seq \g_mw_stream_int + { \mw_tex_closeout:w \g_mw_stream_int } + { \mw_closeout_aux: } + } +\cs_new_protected_nopar:Npn \mw_closeout_aux: + { \mw_late_aux:nN { } \mw_immediate_closeout_aux: } +\cs_new_protected_nopar:Npn \mw_before_shipout: + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write + \c_mw_tmp_file_tl \scan_stop: + } +\seq_new:N \g_mw_operations_seq +\cs_new_protected_nopar:Npn \mw_after_shipout: + { + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + \group_begin: + \int_set_eq:NN \tex_endlinechar:D \tex_newlinechar:D + \tl_map_inline:nn { `(0123456789) } + { \char_set_catcode_other:n {`##1} } + \etex_everyeof:D { `() \exp_not:N } + \tl_gset:Nx \g_mw_operations_seq + { \if_false: } \fi: + \exp_after:wN \mw_after_shipout_loop:ww + \tex_input:D \c_mw_tmp_file_tl \scan_stop: + \group_end: + \seq_map_inline:Nn \g_mw_operations_seq + { + \tl_use:c + { c_mw_late_write_ ##1 _tl } + } + } +\cs_new:Npn \mw_after_shipout_loop:ww #1 `( #2 ) + { + \tl_if_empty:nTF {#2} + { \if_false: { \fi: } } + { + \exp_not:N \seq_item:n {#2} + \mw_after_shipout_loop:ww + } + } +\IfFileExists{atbegshi.sty} + { + \RequirePackage{atbegshi} + \tl_replace_in:Nnn \AtBegShi@Output + { \AtBegShi@OrgShipout \box \AtBeginShipoutBox } + { + \mw_before_shipout: + \AtBegShi@OrgShipout \box \AtBeginShipoutBox + \mw_after_shipout: + } + \tl_replace_in:Nnn \AtBegShi@Output + { \AtBeginShipoutOriginalShipout \box \AtBeginShipoutBox } + { + \mw_before_shipout: + \AtBeginShipoutOriginalShipout \box \AtBeginShipoutBox + \mw_after_shipout: + } + } + { + \cs_new_protected_nopar:Npn \mw_shipout:w + { + \int_gset_eq:NN \g_mw_tmpa_int \etex_currentgrouplevel:D + \tex_afterassignment:D \mw_shipout_aux: + \tex_global:D \tex_setbox:D \g_mw_box + } + \cs_new_protected_nopar:Npn \mw_shipout_aux: + { + \int_compare:nNnTF { \g_mw_tmpa_int } + = { \etex_currentgrouplevel:D } + { \mw_shipout_aux_ii: } + { \tex_aftergroup:D \mw_shipout_aux_ii: } + } + \cs_new_protected_nopar:Npn \mw_shipout_aux_ii: + { + \mw_before_shipout: + \mw_tex_shipout:w \tex_box:D \g_mw_box + \mw_after_shipout: + } + \cs_gset_eq:NN \shipout \mw_shipout:w + } +\cs_new_protected_nopar:Npn \mw_close_all: + { + \prop_map_inline:Nn \g_mw_writes_prop + { + \mw_tex_immediate:w \mw_tex_openout:w \g_mw_write ##2 \scan_stop: + \group_begin: + \int_set_eq:NN \tex_newlinechar:D \c_minus_one + \tl_use:c { g_mw_write_ ##1 _tl } + \tl_gclear:c { g_mw_write_ ##1 _tl } + \group_end: + \mw_tex_immediate:w \mw_tex_closeout:w \g_mw_write + } + \prop_gclear:N \g_mw_writes_prop + } +\IfFileExists{atveryend.sty} { \use_i:nn } { \use_ii:nn } + { + \RequirePackage {atveryend} + \AtVeryVeryEnd { \mw_close_all: } + } + { + \cs_new_protected:Npn \mw_put_at_end:Nw #1 #2 \@@end + { + \tl_if_empty:nTF {#2} + { #1 \@@end } + { #2 \mw_put_at_end:Nw #1 \@@end } + } + \AtEndDocument { \mw_put_at_end:Nw \mw_close_all: } + } +\countdef \mw_write_int 17 \scan_stop: +\cs_new:Npn \mw_newwrite:N #1 + { + \if_num:w \mw_write_int = \c_sixteen + \int_gset:Nn \mw_write_int { 20 } + \fi: + \int_set_eq:NN \allocationnumber \mw_write_int + \int_gincr:N \mw_write_int + \cs_undefine:N #1 + \int_const:Nn #1 { \allocationnumber } + \wlog {\string #1=\string \write \the \allocationnumber } + } +\cs_gset_eq:NN \immediate \mw_immediate:w +\cs_gset_eq:NN \openout \mw_openout:w +\cs_gset_eq:NN \write \mw_write:w +\cs_gset_eq:NN \closeout \mw_closeout:w +\cs_gset_eq:NN \newwrite \mw_newwrite:N +%% +%% +%% End of file `morewrites.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 44a50507592..611d3230f91 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -244,7 +244,7 @@ my @TLP_working = qw( mla-paper mlist mmap mnsymbol moderncv modref modroman mongolian-babel montex moreenum morefloats morehype moresize - moreverb movie15 mp3d mparhack mpgraphics + moreverb morewrites movie15 mp3d mparhack mpgraphics mpman-ru ms msc msg mslapa msuthesis mtgreek multenum multibbl multibib multicap multirow multido multiobjective munich musixguit musixtex muthesis diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index 74c831db41a..e6378de1da5 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -418,6 +418,7 @@ depend morefloats depend morehype depend moresize depend moreverb +depend morewrites depend movie15 depend mparhack depend msc diff --git a/Master/tlpkg/tlpsrc/morewrites.tlpsrc b/Master/tlpkg/tlpsrc/morewrites.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/morewrites.tlpsrc |