笔记:我的问题的原始表述是这样的:如何使用 accsupp 从应以原始普通形式粘贴的输入中生成可视输出中的全大写字母?然而,我认为对这个问题进行更一般性的表述将会更有用。
如何生成与源代码输入具有功能关系的逐个字符可粘贴的输出?
一个例子我遇到的问题如下:
我希望输出全部大写,但应以源代码中给出的替代形式粘贴。(此处将粘贴输入映射到视觉输出的抽象函数将是大写函数。)
具体来说,我需要在(可视)输出中生成全大写文本,但希望该文本的粘贴行为是处理普通大小写文本。也就是说,我希望将“这是一份技术报告”之类的内容粘贴为“这是一份技术报告”。现在从This is a Technical Report
源文件中开始并从中生成全大写文本似乎比编写一个在源文件中撤消大写字母的宏更容易(因为我需要有选择地将其应用于减去任何预期首字母大写的单词)。
我假设正确答案将使用该accsupp
包。然而,它也可以粘贴部分单词;将整个文本块括起来的明显解决方案\BeginAccSupp{...}...\EndAccSupp{...}
无法实现这一点。
我认为正确答案是 Ulrike Fischer 回答的答案线索的衍生accsupp
关于使用\textsc
宏替代文本的问题。
其他示例:
答案1
通过包解决accsupp
/soul
以下方法使用 packagesoul
将文本拆分为标记。然后检查标记,如果发现小写字母,则使用 package 设置它accsupp
。如果 PDF 查看器支持该ActualText
功能,那么您可以复制和粘贴部分单词。
看包装文件soul
因为它的局限性。而且文件大小会随着小写字母的长度而增大。
示例文件:
\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}
accsupp
通过/扩展版本,soul
并支持一些字距调整
插入的和的特殊字符(\special
或\pdfliteral
)\BeginAccSupp
破坏\EndAccSupp
了字距调整。和soul
的字距调整函数看不到正确的字符。以下文件侵入\SOUL@getkern
以修复字符并禁用accsupp
以获取正确的字距调整值,并扩展soul
驱动程序以添加字距调整。
\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}
大写字体
如果使用特殊字体,您的问题可以不受任何限制地得到解决。字体显示有大写和小写字母,但它绘制的是大写字母,而不是小写字母。然后复制和粘贴将适用于任何 PDF 查看器,因为它们会在 PDF 文件中看到小写字形。
然而,创建这样的字体是最困难的部分(fontforge
,...)。TeX 的虚拟字体功能不能在这里用于将小写字母映射到大写字母。驱动程序部分将解析映射,PDF 文件将包含大写字母和大写字形名称。
答案2
如果你想要的只是大小写折叠(而不是任意配对显示和选择的字符串),为什么不基于\textsc
?以下是概念验证(基于这个问题):它会放大\textsc
配置使用的较小字体,以便所有字母具有相同的高度(但所谓的小型大写字母会稍微重一些);真正的解决方案是使用常规尺寸的大写字母,而不是较小的字体\textsc
。
\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}
输出如下所示(但实际上包含混合大小写,正如预期的那样):
THIS IS A TECHNICAL REPORT
由于需要非标准缩放因子(对于 Computer Modern-- YMMV),上述操作需要XeLaTeX
和fontspec
。从一开始就使用正确的字体大小将消除缩放和使用的需求XeLaTeX
。