Linux下看英文PDF的“神器”
看原版英文书的时候,经常因为词汇量不够,或对句法不熟悉,搞得磕磕绊绊的,严重影响思路的连续性。
在机器学习的加持下,现在的机翻越来越进步,Google translate,百度翻译,有道翻译都很不错。但是在将整段文字复制到页面的输入框之后,断行出了问题。PDF并没有段落的概念,肉眼可见的一行,即物理上的一行,每一行的末尾都有一个换行符,等于常规意义上的一个段落。
错误的断句除了不便于阅读,还会误导翻译程序,使得翻译的准确率严重降低。解决的办法很简单直接,每次复制文字的时候复制一个段落,然后将剪切板文字中的所有的换行符全部替换成空格就解决了。
在 Linux 系统下,剪贴板是由 X 窗口系统提供的,而且不止一个,除了与 Windows 系统兼容的 Ctrl + C, Ctrl + V 剪贴板,还有另外一个层面的剪贴板。使用过 Linux 的人应该都很熟悉,就是鼠标选择文本后会自动复制,点击鼠标中键粘贴。本文所涉及的脚本和程序针对的是后者。
xclip
是一个命令行程序,可以访问和操作 X 剪贴板。
通常可以从软件仓库直接安装:
apt install xclip
直接运行命令不太方便,随便写个脚本包裹一下就好用了,随便什么语言都可以。下面的脚本是用 Lisp 写的。
(require "asdf")
(defun string-join (string-list sep)
"join sep between each element of the string-list to build a new string"
(cond ((null string-list) "")
((null (cdr string-list)) (car string-list))
(T (concatenate 'string (car string-list) sep
(string-join (cdr string-list) sep)))))
(defun enabled? ()
(with-open-file (in "~/.rmln")
(let ((switch (read-line in)))
(string= switch "ON"))))
(defun read-clip ()
(with-input-from-string (stream (uiop:run-program '("xclip" "-o")
:ignore-error-status t
:output :string))
(loop :for line = (read-line stream nil nil)
:while line
:collect line)))
(defun write-clip (string)
(uiop:run-program '("xclip")
:input (list string)))
(defun update-clip ()
(when (enabled?)
(let ((string-list (read-clip)))
(when (> (length string-list) 1)
(let ((new-string (string-join string-list " ")))
(write-clip new-string))))))
(defun main ()
(format t "running...~%")
(handler-case
(loop
(update-clip)
(sleep 0.5))
(#+sbcl sb-sys:interactive-interrupt
#+clisp system::simple-interrupt-condition
()
(progn
(format t "~&User quit...~%")
(uiop:quit)))))
(main)
此脚本有一个切换开关,程序在运行时会检查 $HOME 目录下的隐藏文件.rmln
,文件内容是“ON”就启用,不是“ON”就禁用。这是为了在某些情况下避免干扰到其它程序的正常使用。
可以保持此脚本在后台持续运行,由另外一个 shell 脚本来快速地切换开关状态:
#!/bin/sh
cfg="$HOME/.rmln"
if [ ! -f $cfg ]
then
touch $cfg
fi
switch=`cat $cfg`
# echo $switch
if [ $switch = ON ]
then
echo 'OFF' > $cfg
else
echo 'ON' > $cfg
fi
将这个 shell 脚本绑定到某个全局快捷键上(我绑定到 F9 上),现在看外文 PDF 的姿势是:
1.鼠标选中一个段落的文字;
2.切换到翻译页面,点鼠标中键。