我想编写一个 .pdf,以便我的读者可以复制呈现的公式并将其直接粘贴到他们的 TeX 文档中。
复制的文本将自动为:
\int x\sin ax\;\mathrm{d}x = \frac{\sin ax}{a^2}-\frac{x\cos ax}{a}+C
这可能吗?
答案1
PDF 格式支持“ActualText”功能,用于复制粘贴而不是实际排版文本。但是,并非所有 PDF 查看器都支持此功能,但 Acrobat Reader 支持此功能。
\documentclass{article}
\usepackage{accsupp}
\newcommand*{\copyable}[1]{%
\BeginAccSupp{%
ActualText=\detokenize{#1},%
method=escape,
}%
#1%
\EndAccSupp{}%
}
\begin{document}
\[
\copyable{\int x\sin ax\;\mathrm{d}x = \frac{\sin ax}{a^2}-\frac{x\cos ax}{a}+C}
\]
\end{document}
复制粘贴结果(\detokenize
在命令名称后添加空格):
\int x\sin ax\;\mathrm {d}x = \frac {\sin ax}{a^2}-\frac {x\cos ax}{a}+C
更逐字逐句的复制要复杂得多:
\documentclass{article}
\usepackage{accsupp}
\makeatletter
\newcommand*{\copyable}{%
\begingroup
\@sanitize
\catcode`\%=14 % allow % as comment char, also needed for \%
\@copyable
}
\newcommand*{\@copyable}[1]{%
\endgroup
\BeginAccSupp{%
ActualText=\detokenize{#1},%
method=escape,
}%
\scantokens{#1}%
\EndAccSupp{}%
}
\makeatother
\begin{document}
\[
\copyable{\int x\sin ax\;\mathrm{d}x = \frac{\sin ax}{a^2}-\frac{x\cos ax}{a}+C}
\]
\end{document}
复制粘贴结果:
\int x\sin ax\;\mathrm{d}x = \frac{\sin ax}{a^2}-\frac{x\cos ax}{a}+C
但是,的参数是用逐字 catcode 读取的。因此,如果位于另一个宏的参数内(或在包的环境中) \copyable
,此技巧将不起作用。在这种情况下,至少有一个函数可以在命令名称后带有空格的情况下获取先前的版本。\copyable
amsmath
\detokenize
区域讨论
\copyable
插入不影响数学间距的元素。因此整个方程可以拆分:
\[
\copyable{\int x\sin ax\;\mathrm{d}x}
\copyable{=}
\copyable{\frac{\sin ax}{a^2}}
\copyable{-}
\copyable{\frac{x\cos ax}{a}}
\copyable{+}
\copyable{C}
\]
并且从公式到复制粘贴文本的映射是正确的,\copyable
可以省略:
\[
\copyable{\int x\sin ax\;\mathrm{d}x}
=
\copyable{\frac{\sin ax}{a^2}}
-
\copyable{\frac{x\cos ax}{a}}
+ C
\]
PDF 查看器中显示的供选择的区域取决于公式,尤其是 PDF 查看器。
爱看阅读器通常只显示公式第一个符号上方的区域。如果是积分符号,则在其上方显示一个小矩形。AR9/Linux 的最新示例:
表明3.4.0 在矩形的覆盖方面稍好一些。第一个方程,其中整个方程为\copyable
:
但是 Evince 在方程分离方面存在问题。这里我只想选择第二个方程,但它与第三个方程混淆了:
奥克拉尔0.14.3 有一个更好的选择工具,但如果将其\copyable
分成项(最新示例的第二个和第三个方程),那么这些项就会混淆。 - 对数学家来说是致命的。
答案2
也可以使用数学家桌面应用程序(适用于 Mac 和 PC(测试版))截取 PDF 的屏幕截图,它将立即呈现 LaTeX(并且已将其复制到剪贴板,您所要做的就是粘贴到您选择的编辑器中)。
以下是使用 Mathpix 从 PDF 中提取 LaTeX 并粘贴到 Overleaf 的简短演示:
答案3
使用https://tex.stackexchange.com/a/621117/250119,可以重新定义各种命令以使复制粘贴功能正常工作自动地。
改编自https://tex.stackexchange.com/a/233397/250119最佳答案https://tex.stackexchange.com/a/119718/250119。
很遗憾,该解决方案重新定义了各种标准 LaTeX 数学环境,因此它可能很脆弱并破坏其他意想不到的解决方案。如果出现问题,调试的第一步就是注释掉这部分。
仅处理\(...\)
、\[...\]
、\begin{align*}
。\begin{gather*}
\documentclass{article}
\usepackage{amsmath}
\usepackage{accsupp}
\newcommand\copypaste[2]{%
\BeginAccSupp{method=escape,ActualText={\detokenize{#2}}}%
#1%
\EndAccSupp{}%
}
\ExplSyntaxOn
% ======== redefine $...$
\char_set_catcode_active:N $
\cs_new:Npn $ #1 $ { \c_math_toggle_token \copypaste{#1}{$#1$} \c_math_toggle_token }
\char_set_catcode_other:N $
\AtBeginDocument{ \char_set_catcode_active:N \$ }
% ======== redefine \(...\)
\cs_new_eq:NN \jonas__old_open_parenthesis: \(
\cs_gset:Npn \( #1 \) {
\jonas__old_open_parenthesis: \copypaste{#1}{\( #1 \)} \)
}
% ======== redefine \[...\]
\cs_new_eq:NN \jonas__old_open_square_bracket: \[
\cs_gset:Npn \[ #1 \] {
\jonas__old_open_square_bracket: \copypaste{#1}{\[ #1 \]} \]
}
% ======== redefine align*
\ProvideDocumentCommand \NewEnvironmentCopy {mm} { % lines taken from https://tex.stackexchange.com/a/680717/250119, can be deleted if LaTeX version is new enough
\expandafter \NewCommandCopy \csname#1\expandafter\endcsname \csname#2\endcsname
\expandafter \NewCommandCopy \csname end#1\expandafter\endcsname \csname end#2\endcsname }
\ProvideDocumentCommand \RenewEnvironmentCopy {mm} {
\expandafter \RenewCommandCopy \csname#1\expandafter\endcsname \csname#2\endcsname
\expandafter \RenewCommandCopy \csname end#1\expandafter\endcsname \csname end#2\endcsname }
\clist_map_inline:nn {
align*,gather*
} {
\message{======== #1}
\NewEnvironmentCopy{old-#1}{#1} % backup the old definition
\RenewDocumentEnvironment{#1}{b}{
\copypaste{
\begin{old-#1}
##1
\end{old-#1}
}{
\begin{#1} ^^J
##1 ^^J
\end{#1}
}
}{}
}
% ======== done
\ExplSyntaxOff
\begin{document}
What I have is $x^2 + y^2 = z^2$ and \(\frac{1}{2}\).
Try to copy/paste me.
\[
y = \frac{\cos{x}}{1+\cos{x}}
\]
Some aligned equations:
\begin{align*}
1+2 &= 3 \\
4+5 &= 9
\end{align*}
Gather environment:
\begin{gather*}
1+2 = 3 \\
4+5 = 8+1
\end{gather*}
Other environments (not handled):
\begin{align}
1+2 &= 3
\end{align}
\begin{equation}
1+2=3
\end{equation}
\begin{equation*}
1+2=3
\end{equation*}
\end{document}