Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Note: The original phrasing of my question was this: How to use accsupp to produce all-upercase in the visual output from input that should paste in its original, ordinary-case form? However I think a more general phrasing of this question will be of greater use.

How can I produce character-by-character-pastable output that has a functional relation to the source code input?


One example would be the following problem I bumped into:

I desire output in all-caps but which should paste in an alternate form given in the source code. (Here the abstract function mapping the pasting input to the visual output would be the uppercasing function.)

Specifically, I am required to produce all-caps text in the (visual) output but would like the pasting behavior of that text to be that ordinary-case text is being handled. That is, I would like something like "THIS IS A TECHNICAL REPORT" to paste as "This is a Technical Report". Now starting with This is a Technical Report in the source file and producing all-uppercase text from that seems easier than writing a macro that undoes uppercasing in the source (because I would need to selectively apply it to the words-minus-any-intended-initial-capitals).

I assume a correct answer will use the accsupp package. However it will also make it possible to paste parts of words; the obvious solution to enclose the entire textchunk in \BeginAccSupp{...}...\EndAccSupp{...} wouldn't make that possible.

I think that the right answer is a derivative of the answer thread to Ulrike Fischer's answer to this question about alternative text with accsupp using the \textsc macro.


Other examples:

  • Writing a custom function that both "capitalizes" (converts to all-caps) French letters and selectively strips them of their accent marks for display but not for pasting. (I can't find a reference right now (here is a good place to start, though), but due to technical limitations and simplicity, there used to be a tradition of omitting accent marks on capital letters for certain combinations, on posters and other all-caps contexts. Not in dictionaries, though.)
  • Writing a custom function converting Arabic text to its rasm-representation for display but not for pasting.
share|improve this question

2 Answers 2

up vote 14 down vote accepted

Solution via packages accsupp/soul

The following method uses package soul to split the text into tokens. Then the tokens are examined and if a lowercase letter is found, it is set using package accsupp. If the PDF viewer supports the ActualText feature, then you can copy and paste parts of the words.

See documentation of package soul for its limitations. Also the file size is blown up proportional to the length of the lowercase letters.

The example file:

\documentclass{article}
\usepackage{soul}
\usepackage{accsupp}
\usepackage{kvsetkeys}

\makeatletter
\DeclareRobustCommand*{\toup}{%
  \SOUL@setup
  \def\SOUL@everyspace##1{##1\space}%
  \let\SOUL@everyhyphen\SOUL@soeveryhyphen
  \let\SOUL@everyexhyphen\@firstofone
  \let\SOUL@everytoken\toup@everytoken
  \SOUL@
}
\newcommand*{\toup@everytoken}{%
  \edef\toup@temp{%
    \detokenize\expandafter{\the\SOUL@token}%
  }%
  \@ifundefined{toup@@\toup@temp}{%
    \the\SOUL@token
  }{%
    \@nameuse{toup@@\toup@temp}%
  }%
}
\newcommand*{\toup@map}[2]{%
  \BeginAccSupp{method=plain,ActualText={#1}}%
    #2%
  \EndAccSupp{}%
}
\newcommand*{\toupdef}[2]{%
  \@namedef{toup@@#1}{\toup@map{#1}{#2}}%
}
\newcommand*{\toup@temp}[1]{%
  \lowercase{\toupdef{#1}}{#1}%
}
\comma@parse{%
  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%
}\toup@temp
\makeatother

\begin{document}
\toup{This is a Technical Report}
\end{document}

Extended version via accsupp/soul with some kerning support

The inserted specials (\special or \pdfliteral) of \BeginAccSupp and \EndAccSupp destroys the kerning. And souls kerning functions do not see the right characters. The following file hacks into \SOUL@getkern to fix the characters and disable accsupp to get the right kerning value and extends the soul driver to add the kerning.

\documentclass{article}
\usepackage{soul}
\usepackage{accsupp}
\usepackage{kvsetkeys}

\makeatletter
\DeclareRobustCommand*{\toup}{%
  \SOUL@setup
  \def\SOUL@everyspace##1{##1\space}%
  \let\SOUL@everyhyphen\SOUL@soeveryhyphen
  \let\SOUL@everyexhyphen\@firstofone
  \let\SOUL@everytoken\toup@everytoken
  \let\SOUL@getkern\toup@getkern
  \SOUL@
}
\let\toup@org@getkern\SOUL@getkern
\def\toup@thesoultoken{\the\SOUL@token}%
\def\toup@thelasttoken{\the\SOUL@lasttoken}%
\newtoks\toup@toks
\def\toup@getkern#1#2#3{%
  \toup@toks{\toup@org@getkern}%
  \def\toup@temp{#1}%
  \ifx\toup@temp\toup@thelasttoken
    \edef\toup@temp{%
      \detokenize\expandafter{\the\SOUL@lasttoken}%
    }%
    \@ifundefined{toup@@\toup@temp}{%
      \toup@toks\expandafter{\the\toup@toks{#1}{#2}}%
    }{%
      \toup@toks\expandafter{%
        \the\expandafter\toup@toks\expandafter
        {\csname toup@@\toup@temp\endcsname}{#2}%
      }%
    }%
  \else
    \toup@toks\expandafter{\the\toup@toks{#1}{#2}}%
  \fi
  \def\toup@temp{#3}%
  \ifx\toup@temp\toup@thesoultoken
    \edef\toup@temp{%
      \detokenize\expandafter{\the\SOUL@token}%
    }%
    \@ifundefined{toup@@\toup@temp}{%
      \toup@toks\expandafter{\the\toup@toks{#3}}%
    }{%
      \toup@toks\expandafter{%
        \the\expandafter\toup@toks\expandafter
        {\csname toup@@\toup@temp\endcsname}%
      }%
    }%
  \else
    \toup@toks\expandafter{\the\toup@toks{#3}}%
  \fi
  \let\BeginAccSupp\@gobble
  \let\EndAccSupp\@gobble  
  \the\toup@toks
  \let\BeginAccSupp\toup@org@BeginAccSupp
  \let\EndAccSupp\toup@org@EndAccSupp
}
\let\toup@org@BeginAccSupp\BeginAccSupp
\let\toup@org@EndAccSupp\EndAccSupp
\newcommand*{\toup@everytoken}{%   
  \edef\toup@temp{%
    \detokenize\expandafter{\the\SOUL@token}%
  }%
  \@ifundefined{toup@@\toup@temp}{%
    \the\SOUL@token
  }{%
    \@nameuse{toup@@\toup@temp}%
  }%
  \SOUL@setkern\SOUL@charkern
}
\newcommand*{\toup@map}[2]{%
  \BeginAccSupp{method=plain,ActualText={#1}}%
    #2%
  \EndAccSupp{}%
}
\newcommand*{\toupdef}[2]{%
  \@namedef{toup@@#1}{\toup@map{#1}{#2}}%
}
\newcommand*{\toup@temp}[1]{%
  \lowercase{\toupdef{#1}}{#1}%
}
\comma@parse{%
  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%
}\toup@temp
\makeatother

\begin{document}
\toup{This is a Technical Report PA TAT pa tat Pa TaT pA tAt}
\end{document}

Uppercase fonts

Your problem could be solved without any limitations, if a special font is used. The font says that it have upper and lowercase letters, but instead of drawing lowercase letters, it draws the uppercase ones. Then copy & pasting will work with any PDF viewer, because they see lowercase glyphs in the PDF file.

However, creating such fonts is the hard part (fontforge, …). The virtual font feature of TeX cannot be used here to map lowercase to uppercase letters. The driver part would resolve the mapping and the PDF file would contain uppercase letters with uppercase glyph names.

share|improve this answer
    
Impressive! I am inclined to accept your answer now already, but I'm undecided whether to branch off my generalized question (see question statement) into a separate question. I have feeling that if users supplied something like a function \modifytext transforming plaintext letter-by-letter that could be useful. Anyone feel free to give opinions. –  Lover of Structure Oct 3 '12 at 5:29
    
PS: I added other use cases in the question description, for people's reference. –  Lover of Structure Oct 4 '12 at 1:00
2  
This seems to be a classic application for a callback and some Lua code in LuaTeX... :-). –  Martin Schröder Oct 9 '12 at 14:31
    
Would it be possible to extend this to microtypes letterspace feature? I.e. character-by-character pastable text that would return Hello World from \textls{\textsc{HELLO WORLD}}. –  Jörg May 2 at 12:46
    
@Jörg: AFAIK no. –  Heiko Oberdiek May 2 at 13:14

If all you want is case-folding (as opposed to arbitrarily pairing displayed and selected strings), why not build on \textsc? The following is a proof-of-concept (based on this question): it scales up the smaller font that \textsc is configured to use, so that all letters have identical height (but the scalled small caps are slightly heavier); a real solution would use capital letters from the regular size, instead of the smaller font that \textsc uses.

\documentclass{article}
\usepackage{fontspec}
\usepackage{scalefnt}
\newcommand{\textfolded}[1]{\textsc{\scalefont{1.32}#1}}

\begin{document}
T\textfolded{his is a} T\textfolded{echnical} R\textfolded{eport}
\end{document}

The output looks like this (but actually contains mixed case, as intended):

THIS IS A TECHNICAL REPORT

Because of the non-standard scaling factor required (for Computer Modern-- YMMV), the above requires XeLaTeX and fontspec. Using the right font size from the start would eliminate the need for scaling, and for using XeLaTeX.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.