summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/filecontents/filecontents.dtx
blob: 40ad96f26dc781888409d385f80c0fa5ceb65bc8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
% \iffalse meta-comment
%
% Copyright (C) 2001-2019 Scott Pakin <scott+fc@pakin.org>
% --------------------------------------------------------
%
% This package may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%
%    http://www.latex-project.org/lppl.txt
%
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008/05/04 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{filecontents.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{filecontents}
%<*package>
    [2019/09/20 v1.5 Create an external file from within a LaTeX document]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{color}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{filecontents.dtx}
\end{document}
%</driver>
% \fi
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \CheckSum{191}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \GetFileInfo{filecontents.dtx}
%
% \title{The \textsf{filecontents} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}}
% \author{Scott Pakin \\ \textit{scott+fc@pakin.org}}
% \maketitle
%
% \changes{v1.0}{2001/07/31}{Initial version}
% \changes{v1.1a}{2006/03/11}{%
%   Clarified/corrected the \texttt{\string\string\string\documentclass}
%   restriction as per Robin Fairbairns's suggestion}
%
% ^^A  The following were copied verbatim from source2e.tex.
% \DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global}
% \DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,%
%             \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi}
% \DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,%
%             \vbox,\vtop,\vcenter}
% \DoNotIndex{\@empty,\immediate,\write}
% \DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup}
% \DoNotIndex{\divide,\advance,\multiply,\count,\dimen}
% \DoNotIndex{\relax,\space,\string}
% \DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,%
%             \closein,\closeout}
% \DoNotIndex{\catcode,\endinput}
% \DoNotIndex{\jobname,\message,\read,\the,\m@ne,\noexpand}
% \DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss}
% \DoNotIndex{\m@ne,\z@,\z@skip,\@ne,\tw@,\p@}
% \DoNotIndex{\dp,\wd,\ht,\vss,\unskip}
%
% ^^A  The following are specific to filecontents.dtx.
% \DoNotIndex{\@currenvir,\@gobble,\@gobblefour,\@ifundefined,\@makeother}
% \DoNotIndex{\@undefined,\active,\chardef,\day,\do,\dospecials,\E,\end,\I}
% \DoNotIndex{\if@tempswa,\L,\LaTeX,\loop,\MessageBreak,\month}
% \DoNotIndex{\newenvironment,\number,\repeat,\reserved@b,\reserved@c}
% \DoNotIndex{\two@digits,\year,\*,\^}
%
% ^^A  Define some commands to help delineate my changes.
% \newcommand{\startfcchanges}{^^A
%   \centerline{^^A
%     \makebox[0pt]{^^A
%       \raisebox{-2\baselineskip}[0pt][0pt]{^^A
%       \makebox[0pt][l]{\rule{1pt}{2\baselineskip}}}^^A
%       \rule{1em}{1pt}^^A
%       \rule{\linewidth}{1pt}^^A
%       \rule{1em}{1pt}^^A
%       \raisebox{-2\baselineskip}[0pt][0pt]{^^A
%       \makebox[0pt][r]{\rule{1pt}{2\baselineskip}}}^^A
%     }^^A
%   }^^A
%  \noindent
% }
% \newcommand{\stopfcchanges}{^^A
%   \centerline{^^A
%     \makebox[0pt]{^^A
%       \raisebox{0pt}[0pt][0pt]{^^A
%       \makebox[0pt][l]{\rule{1pt}{2\baselineskip}}}^^A
%       \rule{1em}{1pt}^^A
%       \rule{\linewidth}{1pt}^^A
%       \rule{1em}{1pt}^^A
%       \raisebox{0pt}[0pt][0pt]{^^A
%       \makebox[0pt][r]{\rule{1pt}{2\baselineskip}}}^^A
%     }^^A
%   }^^A
% }
%
% \begin{center}
%   \color{red}
%   \fbox{^^A
%     \begin{minipage}{0.75\linewidth}
%       \centerline{\textsc{Notice}}
%       \smallskip
%       The version of \LaTeX\ released in Fall 2019 incorporates all of
%       this package's functionality (and more) into the \LaTeX\ kernel
%       itself.  As a result, there is no longer a need for the
%       |filecontents| package.  Please use the new, built-in
%       |filecontents| environment instead.
%     \end{minipage}^^A
%   }
% \end{center}
%
%
% \section{Introduction}
%
% \DescribeEnv{filecontents}
% There is a little-known environment called |filecontents| that is
% built into \LaTeXe.  Here is |filecontents|' description, which was
% taken from |ltclass.dtx|:
%
% \begin{quotation}
%   The environment |filecontents| is intended for passing the contents of
%   packages, options, or other files along with a document in a single
%   file.  It has one argument, which is the name of the file to
%   create.  If that file already exists (maybe only in the current
%   directory if the OS supports a notion of a `current directory' or
%   `default directory') then nothing happens (except for an information
%   message) and the body of the environment is bypassed.  Otherwise, the
%   body of the environment is written verbatim to the file name given as
%   the first argument, together with some comments about how it was
%   produced.
%
%   The environment is allowed only before |\documentclass| to ensure that
%   all packages or options necessary for this particular run are present
%   when needed.  The begin and end tags should each be on a line by
%   itself.  There is also a star-form; this does not write extra comments
%   into the file.
% \end{quotation}
%
% \noindent
% (The comment about |filecontents| being valid only before
% |\documentclass| is, in fact, untrue.  |filecontents| is allowed
% anywhere in the document's preamble.)
%
% \bigskip
%
% The \textsf{filecontents} package provides a hacked-up version of the
% |filecontents| and |filecontents*| environments that lifts the two
% restrictions stated above, namely that existing files are never
% overwritten and that |filecontents| must be used before the
% |\documentclass| declaration (really, the |\begin{document}|).
% \textsf{filecontents} is therefore a more convenient way to write
% external files from within a \LaTeX\ document than is provided by
% default by the \LaTeXe\ kernel.
%
%
% \paragraph{Sample usage}
% |filecontents| works much like |verbatim|, except that it takes
% a mandatory filename argument:
%
% \begin{verbatim}
%     \begin{filecontents}{myfile.tex}
%     This text gets written to \texttt{myfile.tex}.
%     \end{filecontents}
% \end{verbatim}
%
% \noindent
% The preceding code will write a |myfile.tex| file with contents resembling
% the following:
%
% \begin{verbatim}
%     %% LaTeX2e file `myfile.tex'
%     %% generated by the `filecontents' environment
%     %% from source `mydocument' on 2001/07/31.
%     %%
%     This text gets written to \texttt{myfile.tex}.
% \end{verbatim}
%
% \noindent
% |myfile.tex| can then be incorporated back into the document with
% |\include| or |\input|.  Had |filecontents*| been used instead of
% |filecontents|, the file would have contained only the
% ``\texttt{This text gets written to} \verb"\texttt{myfile.tex}."'' line.
% |filecontents*| is therefore useful for writing non-\LaTeX\ files such as
% Encapsulated PostScript files.
%
% If you use the \textsf{ltxtable} package you may find
% \textsf{filecontents} particularly useful.  \textsf{ltxtable} is a
% crude conglomeration of \textsf{longtable}, which allows tables to
% cross page boundaries, and \textsf{tabularx}, which enables tables to
% stretch to a specified width.  \textsf{ltxtable}'s interface is a bit
% cumbersome, however; it requires that the |longtable| environment be
% contained in a separate file.  With the \textsf{filecontents} package
% you can create this file right before the |\LTXtable| invocation---a
% far more convenient alternative than having to manually place the
% table within a separate file.
%
%
% \StopEventually{^^A
%   \PrintChanges
%   \PrintIndex
% }
%
% \section{Implementation}
%
% Most users can stop reading at this point.  The Implementation section
% contains the annotated source code for the \textsf{filecontents}
% package itself, which is useful only to people who want a detailed and
% precise explanation of how \textsf{filecontents} works.
%
% To give credit where credit is due, I wrote virtually none of the
% \textsf{filecontents} code myself.  It comes almost exclusively from
% the \LaTeXe\ source code, specifically from the file |ltclass.dtx|,
% which is attributed to Frank Mittelbach, Chris Rowley, Alan Jeffrey,
% and David Carlisle.  I merely made a few small changes (indicated below
% by bracketed blocks of code and comments) to make the |filecontents|
% environment more convenient to use.
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \begin{macro}{\filec@ntents@old@kernel}
% Except where indicated, the source---including comments---to the
% |\filec@ntents| macro---was taken verbatim from |ltclass.dtx|.
%    \begin{macrocode}
\begingroup%
\catcode`\*=11 %
\catcode`\^^M\active%
\catcode`\^^L\active\let^^L\relax%
\catcode`\^^I\active%
%    \end{macrocode}
%
%    \begin{macrocode}
\gdef\filec@ntents@old@kernel#1{%
  \openin\@inputcheck#1 %
%    \end{macrocode}
%
% \startfcchanges
% In the original code a pre-existing file would not be overwritten.
% In the new version the file existence check is used solely to decide
% whether to output ``\texttt{Writing file `\textrm{\meta{filename}}'}''
% or ``\texttt{Overwriting file `\textrm{\meta{filename}}'}''.  Control
% flow then always falls through to what used to be the |\ifeof| case
% (file does not exist; open it), never the |\else| case (file already
% exists; do nothing).
% \changes{v1.2}{2009/03/17}{Added percent signs after the
%   \texttt{\char`\\else} and \texttt{\char`\\fi}
%   lines as per Heiko Oberdiek's suggestion for getting \textsf{filecontents}
%   to work with the \textsf{guitar} package}
% \changes{v1.3}{2011/10/08}{Added a \texttt{\char`\\closein} to fix bug
%   \textsf{latex/1487} (reported by Ulrike Fischer and Heiko Oberdiek)}
%    \begin{macrocode}
  \ifeof\@inputcheck%
    \@latex@warning@no@line%
        {Writing file `\@currdir#1'}%
  \else %
    \@latex@warning@no@line%
        {Overwriting file `\@currdir#1'}%
  \fi %
  \closein\@inputcheck %
%    \end{macrocode}
%    \begin{macrocode}
  \chardef\reserved@c15 %
  \ch@ck7\reserved@c\write%
  \immediate\openout\reserved@c#1\relax%
%    \end{macrocode}
% \stopfcchanges
%
%    \begin{macrocode}
  \if@tempswa%
    \immediate\write\reserved@c{%
      \@percentchar\@percentchar\space%
          \expandafter\@gobble\string\LaTeX2e file `#1'^^J%
      \@percentchar\@percentchar\space  generated by the %
        `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J%
      \@percentchar\@percentchar\space from source `\jobname' on %
         \number\year/\two@digits\month/\two@digits\day.^^J%
      \@percentchar\@percentchar}%
  \fi%
  \let\do\@makeother\dospecials%
%    \end{macrocode}
% \startfcchanges
% The \textsf{inputenc} packages might have marked some of the upper~128
% character codes ``active'' (category code~13).  That confuses
% \textsf{filecontents}.  Hence, we locally mark each of the upper~128
% character codes as ``letter'' (category code~11) so that they can be
% written correctly to a file.
% \changes{v1.1}{2004/08/16}{Made it possible for \textsf{filecontents}
%   to write \mbox{Latin-1} characters as per Harry Schmidt's feature
%   request and Frank Mittelbach's suggestion of how to implement it.}
% \changes{v1.2}{2009/03/17}{Added percent signs after each line in
%   the loop as per Heiko Oberdiek's suggestion for getting
%   \textsf{filecontents} to work with the \textsf{guitar} package}
%    \begin{macrocode}
  \count0=128\relax %
  \loop %
    \catcode\count0=11\relax %
    \advance\count0 by 1\relax %
    \ifnum\count0<256 %
  \repeat %
%    \end{macrocode}
% \stopfcchanges
%
%    \begin{macrocode}
  \edef\E{\@backslashchar end\string{\@currenvir\string}}%
  \edef\reserved@b{%
    \def\noexpand\reserved@b%
         ####1\E####2\E####3\relax}%
  \reserved@b{%
    \ifx\relax##3\relax%
%    \end{macrocode}
% There was no |\end{filecontents}|
%    \begin{macrocode}
      \immediate\write\reserved@c{##1}%
    \else%
%    \end{macrocode}
% There was a |\end{filecontents}|, so stop this time.
%    \begin{macrocode}
      \edef^^M{\noexpand\end{\@currenvir}}%
      \ifx\relax##1\relax%
      \else%
%    \end{macrocode}
% Text before the |\end|, write it with a warning.
%    \begin{macrocode}
          \@latex@warning{Writing text `##1' before %
             \string\end{\@currenvir}\MessageBreak as last line of #1}%
        \immediate\write\reserved@c{##1}%
      \fi%
      \ifx\relax##2\relax%
      \else%
%    \end{macrocode}
% Text after the |\end|, ignore it with a warning.
%    \begin{macrocode}
         \@latex@warning{%
           Ignoring text `##2' after \string\end{\@currenvir}}%
      \fi%
    \fi%
    ^^M}%
%    \end{macrocode}
%
% \changes{v1.4}{2018/05/30}{Update definitions of
%   \string\texttt{\string\^{}\string\^{}L} and
%   \string\texttt{\string\^{}\string\^{}I} for compatibility with the
%   2018-04-01 \string\LaTeX\ release}
%    \begin{macrocode}
  \catcode`\^^L\active%
  \let\L\@undefined%
  \def^^L{\expandafter\ifx\csname L\endcsname\relax\fi ^^J^^J}%
  \catcode`\^^I\active%
  \let\I\@undefined%
  \def^^I{\expandafter\ifx\csname I\endcsname\relax\fi\space}%
  \catcode`\^^M\active%
  \edef^^M##1^^M{%
    \noexpand\reserved@b##1\E\E\relax}}%
\endgroup
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fc@no@preamblecmds}
% \LaTeXe\ declares |\filecontents|, |\filecontents*|, and all of the
% related helper macros as |\@onlypreamble|, meaning they become invalid
% after the |\begin{document}|.  The following code re-enables their
% usage anywhere in the document.  It was taken from the
% \textsf{pkgindoc} package (which is generated from |ltclass.dtx|), but
% modified to re-enable only the commands needed by
% \textsf{filecontents}, not all of the class and package
% option-processing commands, as well.
%    \begin{macrocode}
\def\fc@no@preamblecmds#1\do\filecontents#2\do\filec@ntents#3\relax{%
  \gdef\@preamblecmds{#1#3}}
%    \end{macrocode}
% \end{macro}
%
% Newer \LaTeX\ kernels define a most sophisticated |filecontents|
% environment than what this package provides.  We currently use the
% existence of |\filec@ntents@opt| as indication that the new
% |filecontents| environment is available.
% \changes{v1.5}{2019/09/20}{Declare the package obsolete when running
% under newer \LaTeX\ kernels}
%    \begin{macrocode}
\@ifundefined{filec@ntents@opt}{%
%    \end{macrocode}
% Older kernel: Install this package's version of the |filecontents|
% environment.
%    \begin{macrocode}
  \let\filec@ntents=\filec@ntents@old@kernel
  \expandafter\fc@no@preamblecmds\@preamblecmds\relax
}{%
%    \end{macrocode}
% Newer kernel: Issue a warning and do not install this package's
% version of |filecontents|.
%    \begin{macrocode}
  \PackageWarningNoLine{filecontents}{%
    This package is obsolete.  Disabling it and\MessageBreak
    passing control to the filecontents environment\MessageBreak
    defined by the LaTeX kernel%
  }%
}
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
%