% \iffalse meta-comment % % Copyright (C) 2014-2020 Scott Pakin % ---------------------------------------------------------- % % 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} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{repltext} %<*package> [2020/09/25 v1.1 PDF replacement text] % % %<*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} % % \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