如何生成可逐个字符粘贴的视觉输出,该输出是(旨在粘贴的)源代码输入的函数?

如何生成可逐个字符粘贴的视觉输出,该输出是(旨在粘贴的)源代码输入的函数?

笔记:我的问题的原始表述是这样的:如何使用 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),上述操作需要XeLaTeXfontspec。从一开始就使用正确的字体大小将消除缩放和使用的需求XeLaTeX

相关内容