假设我已经pdf
从带有或tex
选项的文档生成了一个文件。\synctex=1
pdflatex
xelatex
各种前向搜索方法告诉我们如何从文本编辑器跳转到 evince pdf viewer 中的相应位置。
假设给出了源 TeX 文件的特定行号,是否有方法从 Linux 中的终端转到 evince 中 pdf 文件的相应位置?
更明确地,如何从终端跳转到 evince 到与 TeX 源文件的特定行(比如第 304 行)相对应的位置?
就像是:
evince --some-args myfile.pdf --some-args myfile.tex -line 304
对于 qpdfview,可以执行以下操作:
qpdfview --unique myfile.pdf#src:myfile.tex:304:0 &
答案1
Evince 没有提供 synctex 行号的命令行选项。但是,如果 pdf 文件已在 Evince 中打开,则可以通过 dbus 直接调用 Evince 守护程序来执行SyncView
库命令。从终端:
gdbus call --session --dest :[id] --object-path /org/gnome/evince/Window/0 --method org.gnome.evince.Window.SyncView "[file.tex]" "([line], 1)" "0"
其中,[id]
是 pdf 文件的当前 Evince 实例的标识符,[file.tex]
是源文件,[line]
是行号。请注意, 表示[]
占位符,它们不是实际命令的一部分。
当然,这个终端命令非常不实用,因为 Evince 已经需要打开,而且您需要知道 ID,这需要其他dbus
调用。因此,编写一些包装器代码会更容易。dbus
例如,Python 库以更用户友好的方式公开了用于查找 ID 和执行同步的 dbus 方法。
下面的代码稍微改编自(接受命令行参数)https://github.com/PHPirates/evince_dbus。这也是上面讨论的终端命令的来源,并且存储库dbus
还包含其他编程语言的示例代码。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Source: https://github.com/PHPirates/evince_dbus/blob/master/python/evince_forward_search_minimal.py
# Copyright (C) 2010 Jose Aliste <[email protected]>
# 2011 Benjamin Kellermann <[email protected]>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public Licence as published by the Free Software
# Foundation; either version 2 of the Licence, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more
# details.
#
# You should have received a copy of the GNU General Public Licence along with
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
# Street, Fifth Floor, Boston, MA 02110-1301, USA
# This file offers forward search for evince.
import os
from traceback import print_exc
import dbus
import sys
import time
line_number = int(sys.argv[1])
pdf_file = os.getcwd() + '/' + sys.argv[2] + ".pdf"
tex_file = os.getcwd() + '/' + sys.argv[2] + ".tex"
try:
# Initialize a session bus
bus = dbus.SessionBus()
# Get a reference to the evince daemon object
daemon = bus.get_object('org.gnome.evince.Daemon', '/org/gnome/evince/Daemon')
# findDocument is a method provided by Evince on the dbus, see
# https://mail.gnome.org/archives/commits-list/2010-July/msg02054.html
# "It returns the name owner of the evince process for the given document
# URI."
dbus_name: str = daemon.FindDocument('file://' + pdf_file, True, dbus_interface="org.gnome.evince.Daemon")
print("evince process owner: " + dbus_name) # Something like :1.149
time.sleep(0.5) # small delay to allow Evince to start up before syncing. Could probably be set even smaller.
# Get the window remote object
window = bus.get_object(dbus_name, '/org/gnome/evince/Window/0')
# Call a method on the object: highlight a line in the pdf
window.SyncView(tex_file, (line_number, 1), 0, dbus_interface="org.gnome.evince.Window")
except dbus.DBusException:
print_exc()
myfile.tex
现在,给出使用以下方式编译的LaTeX 文件synctex
:
\documentclass{article}
\begin{document}
\section{Example section}
regular contents
\newpage
\section{New page}
with some contents
\end{document}
和以下命令(参数:行号、文件的基本名称):
python3 evince_forward_search.py 6 myfile
Evince 打开文件并跳转到第二页并显示 Synctex 边框:
.py
当然,您可以通过使文件可执行并将其放在路径中,使其更加用户友好。
请注意,当我尝试代码时,如果在关闭 Evince 的情况下启动,它并不能 100% 正常工作。查看器始终会启动并显示 pdf 文件,但在某些情况下没有同步。但是,在这些情况下,在 Evince 仍然打开的情况下再次运行该命令将可靠地显示同步。因此,我怀疑在打开 pdf 时存在时间问题,其中 id 已经返回,但该过程尚未接受交互。我在执行同步之前添加了 0.5 秒的延迟。这有点分散注意力,因为 Evince 明显跳转到正确的位置,并且当 Evince 已经打开时这也是不必要的,因此您可能需要删除它或缩短延迟 - 但它似乎解决了偶尔出现的不执行同步的问题。
备注:Evince 本身有一个--named-dest
命令行标志,请参阅man evince
(或在线手册页)。此标志可用于跳转到文档中具有命名锚点的部分,例如由包生成的部分hyperref
。例如:
evince --named-dest=section.2.1 myfile.pdf &
但是,Synctex 不会生成这种类型的锚点,而是将源线的原始网格位置存储在文件中synctex.gz
- 因此该--named-dest
标志不能用于此。