summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/repltext/repltext.dtx
blob: 9a116df516a72226f69f63cc4ace1279ab62c4e5 (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
% \iffalse meta-comment
%
% Copyright (C) 2014-2020 Scott Pakin <scott+repl@pakin.org>
% ----------------------------------------------------------
%
% This file 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
% 2006/05/20 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{repltext.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{repltext}
%<*package>
    [2020/09/25 v1.1 PDF replacement text]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{repltext}
\usepackage{graphicx}
\usepackage{color}
\usepackage{hypdoc}
\usepackage{hyperref}
\usepackage{hyperxmp}
\EnableCrossrefs
\CodelineIndex
\RecordChanges

% Specify this document's metadata.
\title{The \textsf{repltext} package\thanks{This document
  corresponds to \textsf{repltext}~\fileversion, dated \filedate.}}
\author{Scott Pakin \\ \texttt{scott+repl@pakin.org}}
\hypersetup{%
  pdftitle={The repltext package},
  pdfauthor={Scott Pakin},
  pdfsubject={LaTeX package for PDF replacement text},
  pdfkeywords={LaTeX, PDF, replacement text, ActualText, copy and paste},
  pdfcopyright={Copyright (C) 2014-2020 Scott Pakin},
  pdflicenseurl={http://www.latex-project.org/lppl/},
  pdfcaptionwriter={Scott Pakin},
  pdfcontactemail={scott+repl@pakin.org},
  pdfcontacturl={http://www.pakin.org/\xmptilde scott/},
  pdflang={en-US},
  baseurl={http://mirror.ctan.org/macros/latex/contrib/repltext/repltext.pdf},
%
  colorlinks=false,
  pdfstartview=Fit
}

\begin{document}
  \DocInput{repltext.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{59}
%
% \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         \~}
%
%
% \changes{v1.0}{2014/04/11}{Initial version}
% \changes{v1.1}{2020/09/25}{Support modern Lua\protect\LaTeX\ versions}
%
% \GetFileInfo{repltext.dtx}
%
% \DoNotIndex{\{,\},\bgroup,\catcode,\def,\egroup,\expandafter,\global,\let}
% \DoNotIndex{\newcommand,\newenvironment,\protected,\providecommand,\the}
%
% ^^A  Define some logical styles.
% \newcommand{\pkgname}[1]{^^A
%   \textsf{#1}\SortIndex{#1}{\string\textsf{#1} (package)\encapchar usage}}
% \newcommand{\pdfname}[1]{^^A
%   \textsf{#1}\SortIndex{#1}{\string\textsf{#1}\encapchar usage}}
% \newcommand{\acronym}[1]{^^A
%   \textsc{\MakeLowercase{#1}}^^A
%   \SortIndex{#1}{\string\textsc{\string\MakeLowercase{#1}}\encapchar usage}^^A
% }
% \DeclareRobustCommand{\cs}[1]{^^A
%   \texttt{\char`\\#1}^^A
%   \SpecialUsageIndex{#1}^^A
% }
%
% ^^A  The following was derived from
% ^^A  http://upload.wikimedia.org/wikipedia/en/a/af/Prince_logo.svg
% \newcommand{\Prince}{^^A
%   \pdfliteral{
%     q
%     0 0 1 rg
%     3.625 5.456 m 3.625 5.933 3.18 6.214 2.82 6.214 c 2.359 6.214 2.047 5.823
%      2.047 5.398 c 2.047 5.003 2.395 4.632 2.828 4.632 c 3.25 4.632 3.625 4.984
%      3.625 5.456 c h
%     1.457 5.452 m 1.457 6.394 2.23 6.8 2.828 6.8 c 3.582 6.8 4.199 6.198 4.199
%      5.456 c 4.199 4.905 4 4.515 3.637 4.304 c 4.004 4.331 4.383 4.378 4.719
%      4.515 c 5.07 4.652 5.375 4.882 5.633 5.112 c 5.574 4.816 5.445 4.437 5.441
%      4.069 c 5.434 3.694 5.516 3.39 5.695 3.109 c 5.742 3.027 5.66 3.034 5.633
%      3.081 c 4.957 3.948 4.023 3.882 3.117 3.882 c 3.117 2.835 l 3.383 2.835
%      l 3.582 3.038 l 3.582 2.136 l 3.348 2.343 l 3.117 2.343 l 3.117 1.085 l
%      3.516 1.359 l 2.855 -0.001 l 2.164 1.37 l 2.57 1.085 l 2.57 2.343 l 2.301
%      2.343 l 2.078 2.136 l 2.078 3.038 l 2.277 2.835 l 2.57 2.835 l 2.57 3.882
%      l 1.945 3.874 1.344 3.777 0.902 3.577 c 0.547 3.417 0.262 3.194 0.258 2.89
%      c 0.254 2.624 0.324 2.398 0.633 2.398 c 0.934 2.398 1.008 2.542 1.008 2.648
%      c 1.008 2.753 0.934 2.851 0.848 2.874 c 1.113 2.487 0.438 2.327 0.406 2.726
%      c 0.387 3.003 0.641 3.069 0.836 3.069 c 1.035 3.069 1.211 2.855 1.234 2.632
%      c 1.254 2.444 1.07 2.183 0.645 2.183 c 0.121 2.187 0 2.534 0 2.886 c 0
%     3.343 0.395 3.698 0.852 3.937 c 1.277 4.155 1.746 4.273 2.098 4.292 c 1.723
%      4.499 1.457 4.886 1.457 5.452 c h
%     f
%     Q
%   }^^A
%   \hspace*{5.7bp}^^A
% }
%
% ^^A  A handy use of repltext is to make \LaTeX copy as "LaTeX", not "LATEX".
% \DeclareRobustCommand{\latex}[1][]{^^A
%   \repltext{#1LaTeX}{#1\LaTeX}^^A
%   \SortIndex{#1LaTeX}{#1\string\LaTeX\encapchar usage}^^A
% }
%
% ^^A  Ditto for e-TeX...
% \DeclareRobustCommand{\etex}{^^A
%   \repltext{e-TeX}{$\varepsilon$-\TeX}^^A
%   \SortIndex{e-TeX}{$\string\varepsilon$-\string\TeX\encapchar usage}^^A
% }
%
% ^^A  ...and plain, old TeX.
% \DeclareRobustCommand{\tex}{^^A
%   \repltext{TeX}{\TeX}^^A
%   \SortIndex{TeX}{\string\TeX\encapchar usage}^^A
% }
%
% ^^A  The following environment was copied verbatim from ltxguide.tex.
% \makeatletter
% \DeleteShortVerb{\|}
% \newenvironment{decl}[1][]%
%     {\par\small\addvspace{4.5ex plus 1ex}%
%      \vskip -\parskip
%      \ifx\relax#1\relax
%         \def\@decl@date{}%
%      \else
%         \def\@decl@date{\NEWfeature{#1}}%
%      \fi
%      \noindent\hspace{-\leftmargini}%
%      \begin{tabular}{|l|}\hline\ignorespaces}%
%     {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak
%      \vspace{2.3ex}\vskip -\parskip}
% \MakeShortVerb{\|}
% \makeatother
%
% ^^A  The following definitions were adapted from ltxguide.tex.
% \renewcommand{\arg}[1]{\texttt{\char`\{}\meta{#1}\texttt{\char`\}}}
% \renewcommand{\oarg}[1]{\texttt{[}\meta{#1}\texttt{]}}
%
%
% \maketitle
%
% \section{Introduction}
%
% The \pkgname{repltext} packages exposes to \latex\ a relatively obscure
% \acronym{PDF} feature: replacement text.  When replacement text is
% specified for a piece of text, it is the replacement text, not the
% typeset text that is copied and pasted.  Try selecting and copying the
% following sentence and pasting it into some other document:
%
% \begin{center}
%   \color{blue}
%   I love to eat \repltext{ice cream}{celery}.
% \end{center}
%
% If your \acronym{PDF} reader supports replacement text---Adobe Acrobat
% and Acrobat Reader currently appear to be the only ones---the pasted
% text will say ``ice cream'' instead of ``celery''.  Why is this
% useful?  The \acronym{PDF} specification presents the following usage
% model~\cite{Adobe2008:PDF}:
%
% \begin{quote}
%    Just as alternate descriptions can be provided for images and other
%    items that do not translate naturally into text~\dots\ replacement
%    text can be specified for content that does translate into text but
%    that is represented in a nonstandard way.  These nonstandard
%    representations might include, for example, glyphs for ligatures or
%    custom characters, or inline graphics corresponding to letters in
%    an illuminated manuscript or to dropped capitals.
% \end{quote}
%
% Hence, one might imagine using replacement text in a sentence such as,
%
% \begin{center}
%   \color{blue}
%   Have you ever seen
%   \repltext{The Artist Formerly Known as Prince}{\Prince}
%   perform live in concert?
% \end{center}
%
% \noindent
% although in the context of \latex, mathematical typesetting
% may present a more practical use for replacement text:
% ^^A
% \[
%   \color{blue}
%   \repltext{sum as n goes from 1 to infinty of 1/n^2}{\sum_{n=1}^{\infty}\frac{1}{n^2}}
% \]
%
%
% \section{Usage}
% \label{sec:usage}
%
% The \pkgname{repltext} package works only with \latex[pdf] or
% \latex[Lua] as it requires certain primitives that only those
% \repltext{TeX}{\TeX} engines provide.
% To use \pkgname{repltext}, simply include |\usepackage{repltext}| in
% your document's prologue.  There are currently no package options.
%
% \begin{decl}
%   |\repltext|\SpecialUsageIndex{\repltext} \arg{replacement text} \arg{general text}
% \end{decl}
%
% This is the main command defined by \pkgname{repltext}.  It takes two
% arguments: the replacement text that goes into the copy buffer and
% some arbitrary \latex\ code to which the replacement text corresponds.
% That \latex\ code is typeset as normal; only its behavior when copied
% and pasted is different.
%
% The replacement text is included verbatim; no characters have any
% special meaning to \latex\ with the exception that curly braces must
% appear as properly nested, open and close pairs.
% For example, \cs{repltext}|{$7| |or| |50%}{|\texttt{seven bucks or half
% the total}|}|, produces
%
% \bigskip
% \hfill
% {\color{blue}\repltext{$7 or 50%}{seven bucks or half the total}}
% \hfill
% \makebox[0pt][r]{$\Rightarrow$ \texttt{\$7 or 50\%}}
% \bigskip
%
% \noindent
% Because of \meta{replacement text}'s verbatim-like nature, if the
% ``|$|'' or ``|%|'' in the preceding \cs{repltext} command were
% backslashed, the replacement text would also include a literal
% backslash.
%
% \section{Limitations}
%
% \pkgname{repltext}'s most severe limitation is the dearth of
% \acronym{PDF} readers that support replacement text: as far as I know,
% only Adobe Acrobat and Acrobat Reader.  A secondary limitation is
% that, in the Adobe programs, a selection backed by replacement text
% extends only to the first space or kern.  This can be somewhat
% disconcerting to a person trying to select a piece of text.  A
% workaround is to try to use only word-for-word substitutions and to
% prevent kerning by inserting ``|{}|'' at kerning points (which, alas,
% results in inferior typesetting).  Contrast selecting ``\texttt{Zippy
%   drinks \cs{repltext}}|{fine wines}{Valvoline}.|''
%
% \begin{center}
%   \color{blue}Zippy drinks \repltext{fine wines}{Valvoline}.
% \end{center}
%
% \noindent
% with ``\texttt{Zippy drinks \cs{repltext}}|{fine wines}{V{}alv{}oline}.|''
%
% \begin{center}
%   \color{blue}Zippy drinks \repltext{fine wines}{V{}alv{}oline}.
% \end{center}
%
% Yet another limitation, again in the Adobe programs, is that spurious
% spaces are sometimes, but not always, introduced into the copy
% buffer following a \cs{repltext}.  I have yet to determine the source
% of those spaces and whether a workaround exists.
%
% Finally, like |\||verb|, \cs{repltext} does not behave as expected
% within an argument to another macro.  \cs{repltext} does not currently
% detect and warn if it is being used as an argument, but the
% replacement text may be altered in surprising and undesirable ways.
% Consider, for example, |\fbox{\repltext{###| |BAD_BAD_BAD|
%     |###}{terrible}}|:
%
% \bigskip
% \hfill
% {\color{blue}\fbox{\repltext{### BAD_BAD_BAD ###}{terrible}}}
% \hfill
% \makebox[0pt][r]{$\Rightarrow$ \texttt{\#\#\#\#\#\# BADBADBAD \#\#\#\#\#\#}}
% \bigskip
%
%
% \StopEventually{^^A
% \begin{thebibliography}{1}
% \bibitem{Adobe2008:PDF}
% Adobe Systems, Inc., San Jose, California.
% \newblock \emph{Document Management---Portable Document Format---Part 1:
%   PDF~1.7}, July 2008.
% \newblock ISO \mbox{32000-1} standard document. Available from
%   \url{http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf}.
% \end{thebibliography}
% }
%
% \section{Implementation}
%
% This section presents the documented source code for
% \pkgname{repltext}.  Most users can ignore this section.
%
% \begin{macro}{\@ifdefined}
% I find \cs{@ifdefined} a more natural construct than \cs{@ifundefined}.
%    \begin{macrocode}
\providecommand{\@ifdefined}[3]{\@ifundefined{#1}{#3}{#2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\repl@literal}
% \pkgname{repltext} needs a mechanism to insert literal PDF code.  This
% varies by \TeX\ engine so we have to define \cs{repl@literal} on an
% engine-by-engine basis.
% \changes{v1.1}{2020/09/25}{Add this macro}
%    \begin{macrocode}
\@ifdefined{pdfliteral}{%
%    \end{macrocode}
% \latex[pdf]
%    \begin{macrocode}
  \let\repl@literal=\pdfliteral
}{%
  \@ifdefined{pdfextension}{%
%    \end{macrocode}
% \latex[Lua]
%    \begin{macrocode}
    \protected\def\repl@literal{\pdfextension literal}%
  }{%
%    \end{macrocode}
% Other
%    \begin{macrocode}
    \PackageError{repltext}{Unrecognized TeX engine}{%
      The repltext package currently works only with pdfLaTeX and\MessageBreak
      LuaLaTeX.\space\space Please use of those engines to build your document.%
    }%
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \pkgname{repltext} additionally needs a mechanism to escape
% backslashes and parentheses in a string to make it usable as a PDF
% string.  This is easy in pdf\LaTeX, which provides
% \cs{pdfescapestring}.  Unfortunately, to my knowledge, no other
% \TeX\ engine provides equivalent functionality.  Rather than write our
% own function, we leverage \pkgname{hyperref}'s \cs{Hy@pstringdef},
% which provides similar functionality.
%    \begin{macrocode}
\RequirePackage{etoolbox}
\AtEndPreamble{%
  \@ifpackageloaded{hyperref}{}{\RequirePackage{hyperref}}%
}
%    \end{macrocode}
%
% The \cs{repl@text@ii} macro invokes \cs{scalebox}, which is defined by
% the \pkgname{graphicx} package.
%    \begin{macrocode}
\RequirePackage{graphicx}
%    \end{macrocode}
%
% Replacement text is stored temporarily in \cs{repl@text@toks}.
%    \begin{macrocode}
\newtoks\repl@text@toks
%    \end{macrocode}
%
% \begin{macro}{\repltext}
% \begin{macro}{\do}
% The \cs{repltext} user macro nominally takes as arguments the
% replacement text and its visual representation.  However, we want the
% first argument to be interpreted as text, not as \LaTeX\ code.  For
% this to work, \cs{repltext} must in fact take no arguments.  Instead,
% it marks all characters with category code~12 (``other'') except for
% curly braces, which retain their original roles.  It ends by storing
% all characters from ``|{|'' to ``|}|'' (i.e.,~what appears to the
% document author to be the first argument to \cs{repltext}) in
% \cs{repl@text@toks} and transferring control to the \cs{repl@text@i}
% macro.
%    \begin{macrocode}
\newcommand{\repltext}{%
  \bgroup
  \let\do=\@makeother
  \dospecials
  \catcode`\{=1
  \catcode`\}=2
  \afterassignment\repl@text@i
  \global\repl@text@toks=%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\repl@text@i}
% The \cs{repl@text@i} macro ends the group begun by \cs{repltext}.
% Doing so restores all characters to their previous category code.  It
% then transfers control to the \cs{repl@text@ii} macro.
%    \begin{macrocode}
\newcommand{\repl@text@i}{%
  \egroup
  \repl@text@ii
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\repl@text@ii}
% \begin{macro}{\repl@escaped}
% \cs{repl@text@ii} is the macro that finally outputs something.  It
% takes ordinary \LaTeX\ code as its argument and writes a PDF
% marked-content sequence that uses an \pdfname{ActualText} entry to
% indicate that \cs{repltext}'s first argument (currently stored in
% \cs{repl@text@toks}) is the replacement text for \cs{repltext}'s
% second argument (\cs{repl@text@ii}'s |#1|~argument).
%    \begin{macrocode}
\newcommand{\repl@text@ii}[1]{%
  \Hy@pstringdef\repl@escaped{\the\repl@text@toks}%
  \repl@literal{
    /Span << /ActualText (\repl@escaped) >>
    BDC
  }%
  #1%
%    \end{macrocode}
% It seems that either Adobe Acrobat (or perhaps the \acronym{PDF}
% specification itself; I'm not sure) requires the spanned item to
% include true \acronym{PDF} text, not just graphics.  We therefore
% include a microscopic piece of text to satisfy that requirement
% without being noticeable.
%    \begin{macrocode}
  \scalebox{0.000001}{-}%
  \repl@literal{EMC}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prevrepl}
% For the author's convenience we define \cs{prevrepl} to refer to the
% previous first argument of \cs{repltext}, interpreted as ordinary
% \LaTeX\ code.  It is intended to be used in the second argument of
% \cs{repltext} to present typeset text that can be copied and pasted like
% \LaTeX\ source, as in \cs{repltext}|{$\sum_{i=1}^n|
% |\frac{1}{n^2}$}{|\cs{prevrepl}|}| (result:
% {\color{blue}\repltext{$\sum_{i=1}^n \frac{1}{n^2}$}{\prevrepl}}).
%
% Because \cs{prevrepl} requires \cs{scantokens}, this macro requires
% \etex\@.  Fortunately, all modern \latex[pdf] and \latex[Lua] engines
% include \etex\ support.
%
% \cs{prevrepl} is not currently documented in the author documentation
% because I'm not sure it's a sufficiently useful macro to retain in
% \pkgname{repltext}.  For the time being, I'm leaving it in on the off
% chance that someone requests a feature like what \cs{prevrepl} provides.
%    \begin{macrocode}
\newcommand{\prevrepl}{%
  \expandafter\scantokens\expandafter{\the\repl@text@toks}%
}
%    \end{macrocode}
% \end{macro}
%
% \Finale
\endinput