summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/cprotect/cprotect.dtx
blob: d8bc5495d28ef484fd0292c93090dbebdd73526d (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
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*readme>
----------------------------------------------------------------
cprotect --- verbatim in macro arguments
E-mail: bruno@le-floch.fr
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

A user of the cprotect.sty package can include verbatim text (\verb,
verbatim environment, ...) in the argument of any command, 
including moving arguments. Including verbatim text in footnotes, 
section titles (and other titles), etc. is as simple as typing 
`\cprotect\footnote` instead of `\footnote`, etc. 

A similar approach is taken for environments. Nesting of the 
various environments is taken into account.

This is work in progress, all comments/bug reports are welcome!


The whole package can be built from the file `cprotect.dtx' by running

pdflatex cprotect.dtx
makeindex -s gglo.ist -o cprotect.gls cprotect.glo
makeindex -s gind.ist -o cprotect.ind cprotect.idx
pdflatex cprotect.dtx
pdflatex cprotect.dtx
mv README.txt README

The first run of pdflatex produces `cprotect.ins', `cprotect.sty',
`cprotect.pdf', and this file. The other commands are necessary for
the pdf to contain its index and glossary.


%</readme>
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
  \expandafter\begingroup
\fi
%</internal>
%<*install>
\input docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble
----------------------------------------------------------------
cprotect --- verbatim in macro arguments
E-mail: bruno@le-floch.fr
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

\endpreamble
\postamble

Copyright (C) 2010 by Bruno Le Floch <bruno@le-floch.fr>

This work 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

This work is "maintained" (as per LPPL maintenance status) by
Bruno Le Floch.

This work consists of the file  cprotect.dtx
and the derived files           cprotect.ins,
                                cprotect.pdf and
                                cprotect.sty.

\endpostamble
\usedir{tex/latex/cprotect}
\generate{
  \file{\jobname.sty}{\from{\jobname.dtx}{package}}
}
%</install>
%<install>\endbatchfile
%<*internal>
\usedir{source/latex/cprotect}
\generate{
  \file{\jobname.ins}{\from{\jobname.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/latex/cprotect}
\generate{
  \file{README.txt}{\from{\jobname.dtx}{readme}}
}
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile
\else
  \expandafter\endgroup
\fi
%</internal>
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{cprotect}[2010/12/30 v1.0 (Bruno Le Floch)]
%</package>
%<*driver>
\documentclass[12pt]{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{cprotect}
\usepackage{amsmath}
\usepackage[margin=4cm]{geometry}
\usepackage{hyperref}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{cprotect.dtx}
\end{document}
%</driver>
% \fi
% 
% \CheckSum{244}
%
%
%\GetFileInfo{cprotect.sty}
%
%\DoNotIndex{\addtocounter,\advance,\afterassignment,\aftergroup,\arabic}
%\DoNotIndex{\begingroup,\closeout,\count,\csname,\def,\edef,\gdef,\else}
%\DoNotIndex{\endcsname,\endgroup,\expandafter,\fi,\ifnum,\ifthenelse,\ifx}
%\DoNotIndex{\immediate,\indexspace,\let,\newcommand,\newcounter,\newwrite}
%\DoNotIndex{\openout,\relax,\repeat,\RequirePackage,\setcounter,\string}
%\DoNotIndex{\stepcounter,\value,\WithSuffix,\(,\),\+,\/,\=,\@gobble}
%\DoNotIndex{\{}
%\DoNotIndex{\}}
%\DoNotIndex{\^}
%
%\cprotect\title{|{cprotect.sty}|\\
%  |\verb|atim in |\macro| arguments\thanks{This file
%    describes version \fileversion, last revised \filedate.}}
%\author{Bruno Le Floch\thanks{E-mail: bruno@le-floch.fr}}
%\date{Released \filedate}
%
%\maketitle
%
% \tableofcontents
% \changes{v1.0}{2010/12/30}{First version with documentation}
%
% 
% 
% \cprotect\section{Include \verb-\verb- anywhere!}
% \label{sec:intro}
% 
% The |cprotect| package will allow you to put verbatim in 
% footnotes\cprotect\footnote{Like this: \verb-!@#$%^&*()_+-.} 
% in a straightforward way. The section above was typeset using
% \begin{verbatim}
% \cprotect\section{Include\verb-\verb- anywhere!}\end{verbatim}
% and the footnote was
% \begin{verbatim}
% ...tes\cprotect\footnote{Like this: \verb-!@#$%^&*()_+-.}\end{verbatim}
%
% More generally, let us assume that you want to use verbatim text in
% the argument of some macro |\cs| \marg{arg1}, and that this 
% macro is normally allergic to verbatim. It probably has a good reason
% to be allergic, but using an auxiliary file, we can solve the problem
% entirely: if you want \marg{arg1} to contain verbatim, just write
% |\cprotect\cs| or |\cprotect{\cs}| instead of |\cs|.\cprotect\footnote{This 
% solves most problems, for instance, verbatim text in section titles
% written as |\cprotect\section|\marg{title} appears correctly in the table
% of contents. However, there are still bugs in capitalized headers.}
% All the examples I give use very standard macros, but it should work
% with any macro.\cprotect\footnote{If you have a macro that works when it is not
% preceeded by |\cprotect|, but breaks down if you put |\cprotect| in front of
% it, I will be interested to know why.}
%
% Braces are useful if a macro has \emph{several} arguments, and you want
% to put verbatim in the second one: then type 
% |\cprotect{\cs|\marg{arg1}|}|\marg{arg2}. If you want to put verbatim in
% both arguments, well \ldots\ it is not implemented yet, but if you send
% me an email saying why you need it, I will look into it (suggestions
% are, as always, welcome).
%
% 
% \section{List of user commands}
% \label{sec:commandlist}
% 
% \DescribeMacro{\cprotect}
% Possibly the single most useful command is |\cprotect|, used as
% |\cprotect| |\foo| \marg{arg1} or |\cprotect| \marg{cslist} \marg{arg1}.
% As described in the previous section, the first form behaves as
% |\foo| \marg{arg1}, and the second as \meta{cslist} \marg{arg1}. 
% The difference is that the argument \marg{arg1} can now contain 
% |\catcode| changes (e.g., induced by the |\verb| command and the
% |verbatim| environment). In fact, \marg{arg1} is written to a file, and 
% then read again as the argument of |\foo|. So using |\cprotect|, one could
% in principle build weird macros that read their arguments several times, 
% with different |\catcodes| in effect each time. The macro
% |\ReadVerbatimUntil| below gives a better way of doing that.
%
% \DescribeMacro{\cMakeRobust}
% If you find yourself using a |\cprotect\foo| combination frequently, you
% can simply define |\bar| to mean |\cprotect\foo|. It should work at least 
% most of the time. You can also use the typical 
% \begin{verbatim}
% \let\oldfoo\foo
% \def\foo{\cprotect\oldfoo}\end{verbatim}
% to redefine |\foo| itself instead of a new command |\bar|. The package
% provides a wrapper for this construction: |\cMakeRobust\foo| replaces |\foo|
% by a version which accepts verbatim. As a stupid example,
% \begin{verbatim}
% \newcommand{\expon}[1]{\mathrm{#1}^{#1}}
% \cMakeRobust{\expon}
% \(\expon{Hel\verb+|+o}\)\end{verbatim}
% produces
% \newcommand{\expon}[1]{\mathrm{#1}^{#1}}
% \cMakeRobust{\expon}
% \(\expon{Hel\verb+|+o}\), and the verbatim is treated correctly.
%
% \DescribeMacro{\cprotEnv}
% Something similar to |\cprotect| exists for environments: |\cprotEnv|. Simply
% put |\cprotEnv| |\body| \marg{name} instead of |\body| \marg{name}. For
% example, 
% \begin{verbatim}
% \cprotEnv\begin{align}
% x&=\begin{cases}
%   1 &\text{if }\verb"@#%^&*"\\
%   2 &\text{otherwise}
% \end{cases}
% \end{align}\end{verbatim}
% gives
% \cprotEnv\begin{align}
% x&=\begin{cases}
%   1 &\text{if }\verb"@#%^&*"\\
%   2 &\text{otherwise}
% \end{cases}
% \end{align}
% Note that unfortunately we need to put the |\verb| outside |\text|. 
% This is because currently, nesting of |\cprotect| and friends is not supported.
%
% You can use |\CPTbegin| as a short-hand for |\cprotEnv\begin|, but this will 
% fail when nesting the same environment twice: the inner nesting is
% distinguished by \emph{precisely} the characters 
% \texttt{\textbackslash\ b e g i n \{ \emph{n a m e} \}}.
% 
%
% \DescribeMacro{\ReadVerbatimUntil}
% Finally, the most powerful and the root of all these macros, from which
% the package currently derives its name, is |\ReadVerbatimUntil|. The aim
% of this command is to read a piece of text verbatim, until it reaches an
% end-marker. It then writes all that it has read to an auxiliary file for
% future use. The most naive approach has a major flaw when nesting is
% involved: when parsing |{}}| for instance, with an end-marker of |}|, we
% often wish to stop at the \emph{second} closing bracket, not the first one.
% Thus, |\ReadVerbatimUntil| needs to be aware of a begin-marker. Also, for
% some applications we need to write things before and after the content 
% read by |\ReadVerbatimUntil|. Finally, we want to do something once the 
% file has been written, and possibly something before. 
%
% The syntax is thus |\ReadVerbatimUntil| \oarg{arg1} \marg{arg2}
% |^begin|\-|text^end|\-|text^begin|\-|tag^end|\-|tag^|, followed by the text
% in which we look for |endtag|. The caret (|^|) can be any character.
% It delimits the four verbatim-like arguments of 
% |\ReadVerbatimUntil|. The strings of letters |begintext| 
% and |endtext| are pre- and ap-pended to the file. As mentionned before, 
% |begintag| and |endtag| are used when reading the content, to determine
% how far |\ReadVerbatimUntil| should go. The mandatory argument 
% \marg{arg2} is executed once the whole text has been stored to a file.
% Typically, \marg{arg2} involves reading the file one or more times,
% and acting on it in any way we like. The optional argument is used for 
% hacks such as changing where |cprotect| writes his files.
%
% 
% 
% \section{Known bugs/limitations}
% \label{sec:bugs}
%
% Incompatibility with |\pagestyle{headings}|: when a chapter title is put
% as a header, it gets upper-cased. If you did |\cprotect\chapter{...}| as
% usual, the title has been stored to a file, but now, the name of the file
% is capitalized, and \TeX\ cannot find it.
% 
% Issues with nesting of |\cprotect| in |align| environments: the issue seems 
% to arise because the |align| environment wants to fully expand it argument
% once before typesetting it.
%
% For commands with two or more arguments, it is only possible to put verbatim
% in one of the arguments (and the syntax is not great).
%
% The argument of any command that is prefixed with |\cprotect| has to have balanced
% braces, \emph{even when hidden inside verbatim environments, or even comments}. For
% instance, 
% \begin{verbatim}
% \cprotect\footnote{On the \verb:{: character} \end{verbatim}
% would fail: |\cprotect| would see the brace in |\verb:{:|, and count it 
% as an opening tag, which then has to be closed. This is most likely 
% to lead |\cprotect| to gobble the whole file before complaining. Similarly,
% \begin{verbatim}
% \cprotect\footnote{On the \verb:!: %should it be }?
% character}\end{verbatim}
% would only gobble until the closing brace in |%should it be }?|, and 
% I am not sure what error would be produced.
%
% But we can use one ailment to cure the other! A correct way to typeset 
% the first example is
% \begin{verbatim}
% \cprotect\footnote{On the \verb:{: character%}
% } \end{verbatim}
% if |%| is a comment character at the time it is read. A safer solution 
% would be to use |\iffalse}\fi| instead of |%}|. It still requires to
% be sure that |\| is an escape character when this piece of code is read,
% and can lead to problems if the previous token is |\let| for instance.
%
%
% 
% \section{The code}
% \label{sec:code}
% 
%\StopEventually{\clearpage\PrintChanges\PrintIndex}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%    
% \subsection{Setting up}
%
% We first load a few packages
%    \begin{macrocode}
\RequirePackage{ifthen}
\RequirePackage{suffix}
%    \end{macrocode}
%
% Then we introduce the commands pertaining to writing 
% files.\footnote{To be rewritten. For the moment, we use a new file
%   each time cprotect is used. Thus, many files. But this is needed if
%   people want to nest cprotect's.}
%
% We write files |\jobname-1.cpt|, |\jobname-2.cpt|, etc. in order.
%    \begin{macrocode}
\newwrite\CPT@WriteOut
\newcounter{CPT@WriteCount}
\newcommand{\CPT@Write}[1]{%
  \stepcounter{CPT@WriteCount}%
  \immediate\openout\CPT@WriteOut=\jobname-%
                              \arabic{CPT@WriteCount}.cpt%
  \newlinechar`\^^M%
  \immediate\write\CPT@WriteOut{#1}%
  \immediate\closeout\CPT@WriteOut%
  \aftergroup\CPT@setLastFileName%
}
\newcommand{\CPT@setLastFileName}{%
  \def\CPT@lastFileName{\jobname-\arabic{CPT@WriteCount}.cpt}}
\newcommand{\CPT@input@last}{%
  \expandafter\protect\expandafter\input
                              \expandafter{\CPT@lastFileName}}
%    \end{macrocode}
% 
%
% The next command changes all catcodes to letters. It was adapted from
% |filecontents.sty|.
%    \begin{macrocode}
\newcommand{\makeallletters}{%
  \count0=0\relax %
  \loop %
  \catcode\count0=11\relax %
  \advance\count0 by 1\relax %
  \ifnum\count0<256 %
  \repeat %
}
%    \end{macrocode}
% 
%
% \cprotect\subsection{|\ReadVerbatimUntil|}
% Both |\ReadVerbatimUntil| and its starred version (which we define using 
% the |suffix.sty| package) take one optional argument \oarg{first-cs} and
% a mandatory argument \marg{final-cs}. The \meta{final-cs} is saved as
% |\CPT@commandatend| to be executed when we close the file (and the 
% group).\cprotect\footnote{It is not a straightforward |\aftergroup|, 
% because I want this to be executed after another |\aftergroup| that 
% comes later.}
%    \begin{macrocode}
\newcommand\ReadVerbatimUntil[2][]{%
  \def\CPT@commandatend{#2}%
  \begingroup #1%
  \makeallletters%
  \CPT@setup}
\WithSuffix\newcommand\ReadVerbatimUntil*[2][]{%
  \def\CPT@commandatend{#2}%
  \begingroup #1%
  \makeallletters%
  \CPT@starsetup}
%    \end{macrocode}
% 
% |\CPT@setup| reads the four ``verbatim'' arguments following 
% \marg{final-cs}, and stores them in this order as macros |\CPT@preText|,
% |\CPT@postText|, |\CPT@begin|, and |\CPT@end|. The macros which read each 
% of these arguments need to be defined inside |\CPT@setup|, because
% I don't want any constraint on the delimiter. I could write a single
% macro that gobbles all four arguments at once, but this would require
% a crazy number of |\expandafter|s, so instead I do it one by one.
%
% If the delimiter was given, say |^|, then we would define |\CPT@readBegin|
% as |\def \CPT@readBegin#1^{\def \CPT@begin{#1}\CPT@readEnd}|.
% But since |^| is not given explicitly, we need |\expandafter|s to 
% expand it before the definition takes place. To avoid code repetition,
% I did it once and for all in the auxiliary macro |\CPT@def|. Note that
% a parameter of |##1| is somehow hidden inside |\CPT@def|, and that the
% |##1| inside the replacement text refer to the arguments of the 
% |\CPT@read...| macros.
%    \begin{macrocode}
\newcommand{\CPT@def}[2]{\expandafter\def\expandafter#1%
  \expandafter##\expandafter1#2}
\newcommand{\CPT@setup}[1]{%
  \def\CPT@delimiter{#1}%
  \CPT@def\CPT@readPreText\CPT@delimiter{%
       \def\CPT@preText{##1}\CPT@readPostText}%
  \CPT@def\CPT@readPostText\CPT@delimiter{%
       \def\CPT@postText{##1}\CPT@readBegin}%
  \CPT@def\CPT@readBegin\CPT@delimiter{%
       \def\CPT@begin{##1}\CPT@readEnd}%
  \CPT@def\CPT@readEnd\CPT@delimiter{%
       \def\CPT@end{##1}\CPT@readContent}%
  \CPT@readPreText%
}
\newcommand{\CPT@starsetup}[1]{\CPT@setup#1#1#1}
%    \end{macrocode}
% We also give the variant |\CPT@starsetup|, which has empty
% |\CPT@preText| and |\CPT@postText|.
% 
% When |\CPT@setup| is expanded, it will call |\CPT@|\-|readPreText|, 
% |\CPT@|\-|readPostText|, |\CPT@|\-|readBegin|, and |\CPT@|\-|readEnd|,
% and finish with |\CPT@|\-|readContent|, which we describe now.
% 
%
% We borrow the idea of quark from |expl3|: |\CPT@qend| expands to
% itself, useful for |\ifx| comparisons. The counter |CPT@numB| will count
% the surplus of |begin-tag|s compared to |end-tag|s when we parse the text 
% following |\CPT@readContent|. And |\CPT@store| is a macro that adds its
% argument to an other macro (I was too lazy to learn about token lists).
% The storage itself will be initialized later.
%    \begin{macrocode}
\def\CPT@qend{\CPT@qend}
\newcounter{CPT@numB}
\newcommand{\CPT@store}[1]{\edef\CPT@storage{\CPT@storage#1}}
%    \end{macrocode}
% 
% The macro |\CPT@readContent| is quite tricky: if the |begin-tag| and 
% |end-tag| were one character, things would be easy: I would read one
% character at a time, and compare it to both |begin-tag| and |end-tag|,
% then either store it, and possibly increase or decrease |CPT@numB|, or
% decide that I am done if |CPT@numB| becomes negative.
%
% Unfortunately, I want to use |\ReadVerbatimUntil| for environments, in
% which case the |begin-tag| is |\begin{myenv}| and the |end-tag| is
% |\end{myenv}|. So two options: 
% \begin{itemize}
% \item code a standard string searching algorithm... I did not feel 
%   like it, but it might lead to a regexp package later on;
% \item use \TeX's delimited parameters.
% \end{itemize}
% I did the latter, using |\CPT@def| again (we want to expand the string
% which delimits the parameter before doing the definition).
%
% The details are ugly: 
% \begin{itemize}
% \item gobble until the first |end-tag|,\cprotect\footnote{This will fail for 
%     devious cases: if |begin-tag| is |abc| and |end-tag| is |bcd|, and 
%     |\CPT@readContent| is followed by |abcd...|: we will wrongly see
%     |bcd| as an |end-tag|.} and insert a fake |begin-tag|, as well as the
%   quark guard |\CPT@qend|,
% \item inside what we gobbled, gobble |begin-tag|s until reaching the fake
%   one (marked by the quark guard).
% \item continue until we have one more |end-tag| than |begin-tag|.
% \end{itemize}
%    \begin{macrocode}
\newcommand{\CPT@readContent}{%
  \CPT@def\CPT@gobbleOneB\CPT@begin##2{%
    \ifx\CPT@qend##2\CPT@store{##1}\addtocounter{CPT@numB}{-1}%
    \else\CPT@store{##1\CPT@begin}\stepcounter{CPT@numB}%
    \expandafter\CPT@gobbleOneB\expandafter##2\fi}%
  % 
  \CPT@def\CPT@gobbleUntilE\CPT@end{%
    \edef\CPT@tempi{##1\CPT@begin}%
    \expandafter\CPT@gobbleOneB\CPT@tempi\CPT@qend%
    \ifthenelse{\value{CPT@numB}<0}{%
      \CPT@store{\CPT@postText}%
      \CPT@Write{\CPT@storage}\endgroup%
      \CPT@commandatend%
    }{%
      \CPT@store{\CPT@end}\CPT@gobbleUntilE%
    }%
  }%
  \setcounter{CPT@numB}{0}%
  \def\CPT@storage{\CPT@preText}%
  \CPT@gobbleUntilE%
}
%    \end{macrocode}
%
% 
% \cprotect\subsection{For macros: |\cprotect| and friends}
%
% Equipped with |\ReadVerbatimUntil|, we are ready for the more practical 
% macros. |\cprotect| cheats: it uses |{| and |}| as a |begin-tag| and |end-tag|.
% This works most of the time, but fails in cases such as those presented in
% Section~\ref{sec:bugs} (in usual cases there are 
% workarounds\cprotect\footnote{But I could definitely not have the contents of
% this |.dtx| file as a (huge) footnote in some document: since |{| and |}|
% change |\catcode|s, it is unlikely that the numbers balance correctly.}).
% 
% The first argument of |\cprotect| is the control sequence |\cs| that we are
% patching. 
%    \begin{macrocode}
\newcommand{\cprotect}[1]{\def\CPT@cs{#1}%
  \afterassignment\CPT@A\let\CPT@next}
%    \end{macrocode}
% Then, we check whether the next token is a brace or not: 
% \begin{itemize}
% \item If it is, we discard the |{|, and the argument of |\cs| stops
%     at the matching explicit closing brace |}|. (See |\CPT@n{| below...
%     yes, the name of the control sequence does contain the brace, 
%     which is simply a letter, after all.)
% \item If it is not, the argument of |\cs| is this token only: we insert 
%   a brace after the token, and launch |\ReadVerbatimUntil|. Think of this
%   as inserting braces around the argument, and doing what we did in the 
%   former case: discarding the opening brace. (See |\CPT@N| below.)
% \end{itemize}
%
% Since |\ReadVerbatimUntil| makes everything into letters, we need braces
% to be letters when we define most macros in this Section. We thus need
% a few |\catcode| changes. Think of \(|{|\to|(|\) and \(|}|\to|)|\).
%    \begin{macrocode}
\begingroup
  \catcode`\{=11 \catcode`\}=11 \catcode`\+=11
  \catcode`\(=1 \catcode`\)=2
  \gdef\CPT@A(%
    \ifx\CPT@next\bgroup%
    \expandafter\CPT@n{%
    \else%
    \expandafter\CPT@N%
    \fi)
  \gdef\CPT@n{(\ReadVerbatimUntil*(%
         \CPT@cs(\CPT@input@last))+{+}+)%
  \gdef\CPT@N(\expandafter\CPT@n{\CPT@next })%
\endgroup
%    \end{macrocode}
% Note the use of |\bgroup| in |\CPT@A|: if the argument of |\cs| starts 
% with an opening brace, it has been read early, and its |\catcode| will 
% still be |1|.\cprotect\footnote{I am not sure whether catcodes really matter
% in such an |\ifx|.}
%
% We use |+| as a delimiter for |\ReadVerbatimUntil|. No |begin-text|
% nor |end-text|. |begin-tag| and |end-tag| are |{| and |}| as mentionned 
% before.
% 
% Once the matching |}| is found, we apply |\CPT@cs| (|\cs| stored) to
% |\CPT@input@last|, aka the file where we saved the argument
% (we add some protection so that things work well in |\section| and
% similar situations).
%
% Finally, the |\cMakeRobust| command is a mess, and could probably be improved,
% although... it works |:)|.
%    \begin{macrocode}
\newcommand{\cMakeRobust}[1]{%
  \def\CPT@cs@name{\expandafter\@gobble\string#1}%
  \expandafter\let\csname CPT@old@\CPT@cs@name\endcsname #1%
  \expandafter\def\csname\CPT@cs@name\endcsname{%
    \expandafter\cprotect\csname CPT@old@\CPT@cs@name\endcsname}%
}
%    \end{macrocode}
%
%
% \cprotect\subsection{For Environments: |\cprotEnv\begin| and |\CPTbegin|}
%   
%   \DescribeMacro{\CPTbegin}
%   We introduce the command |\CPTbegin|, which has a behaviour close to
%   the behaviour of |\begin|. Namely, |\CPTbegin{env}| gobbles its argument
%     until it sees the matching |\end|, and it writes what it gobbled to
%   a file. It then inputs the file between |\begin{...}| and |\end{...}|,
%   as we can see from the definition of |\CPT@commandatend|.
%   
%   As for the case of |\cprotect|, we need to setup the values of the four
%   arguments of |\ReadVerbatimUntil| before reading the content. Since 
%   the |begin-tag| and |end-tag| depend on a parameter, it would be 
%   incredibly messy to try to expandafter the right things, so we 
%   define |\CPT@env@setup| to, well, setup the values of the four 
%   arguments of |\ReadVerbatimUntil|, and then skip directly to 
%   |\CPT@readContent|.
%
%    \begin{macrocode}
\newcommand{\CPTbegin}[1]{%
  \def\CPT@commandatend{\begin{#1}\CPT@input@last\end{#1}}%
  \begingroup%
  \CPT@env@setup{#1}%
  \makeallletters%
  \CPT@readContent%
}
%    \end{macrocode}
%
% As announced, |\CPT@env@setup|, defined with lots of catcode changes. 
% Since the catcode of |\| changes, I need an extra escape character,
% which I take to be |/|. I use two groups so each group is opened and
% closed using the same escape character (this is technically irrelevant,
% but seems less messy).
%    \begin{macrocode}
\begingroup\catcode`\/=0
/begingroup/catcode`/\=11
  /catcode`/{=11 /catcode`/}=11 /catcode`/-=11
  /catcode`/(=1 /catcode`/)=2
  /gdef/CPT@env@setup#1(%
    /def/CPT@preText(\relax )%
    /def/CPT@postText(\relax )%
    /def/CPT@begin(\begin{#1})%
    /def/CPT@end(\end{#1})%
    )
/endgroup
\endgroup
%    \end{macrocode}
%
% A final piece of code is needed so that |\CPT|-environments can be
% nested: in order to be able to nest, we need |\ReadVerbatimUntil| 
% to be aware that our environment has been opened when |\CPTbegin{foo}|
% or |\begin{foo}| appear in the text. Given the rules for delimited
% parameters in TeX, this is quite difficult. A workaround is to replace
% |\CPTbegin| by something that ends in |\begin| shuch as |\cprotEnv\begin|
% as defined below. Thus, for nesting to work, you need to prepend every
% one of your |env| environments with |\cprotEnv|.
%    \begin{macrocode}
\def\cprotEnv\begin{\CPTbegin}
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%\Finale
\endinput