Evince:如何从终端进行前向搜索?

Evince:如何从终端进行前向搜索?

假设我已经pdf从带有或tex选项的文档生成了一个文件。\synctex=1pdflatexxelatex

各种前向搜索方法告诉我们如何从文本编辑器跳转到 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 &

qpdfview 用于前向搜索的命令行参数

答案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标志不能用于此。

相关内容