【问题标题】:From .ps/.dvi/.pdf, go to the corresponding location of .tex in Emacs从.ps/.dvi/.pdf,到Emacs中.tex对应的位置
【发布时间】:2014-10-25 00:17:06
【问题描述】:

我正在使用 Emacs 编辑 .tex 文件。似乎有一种方法可以查看文档(.dvi 或 .ps),然后如果我们点击文档,我们可以转到 Emacs 中 .tex 文件的相应位置,谁能告诉我如何配置 Emacs实现这个功能?

谢谢。

【问题讨论】:

  • 我终于使用了来自here的类似解决方案。最后,我现在使用 Okular 而不是 Evince,Shift+左键单击 .pdf 文档以转到 Emacs 中 .tex 文件的位置。但我还没有弄清楚如何精确地进行前向搜索:从 .tex 快速定位到 .pdf。

标签: emacs latex


【解决方案1】:

您想要SyncTeX,还应该查看tex.stackexchange.com

【讨论】:

    【解决方案2】:

    如果你有一个表现良好的 dbus 系统,它应该在 cvs 版本中开箱即用。

    如果您不(像我一样),或者您现在更愿意使用 11.86 版,您可以使用以下脚本。它们是其他人努力的修改版本(参见 (c) 和 http://ubuntuforums.org/showthread.php?t=1716268)。

    您只需 ctrl + 左键单击您的 pdf 文件(该文件当然必须有 synctex 信息)。

    Evince-backward-search(注意 shebang):

    #!/usr/bin/python2
    # -*- coding: utf-8 -*-
    
    # Copyright (C) 2010 Jose Aliste <jose.aliste@gmail.com>
    #               2011 Benjamin Kellermann <Benjamin.Kellermann@tu-dresden.de>
    #
    # 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
    
    import dbus, subprocess, time, re
    
    RUNNING, CLOSED = range(2)
    
    EV_DAEMON_PATH = "/org/gnome/evince/Daemon"
    EV_DAEMON_NAME = "org.gnome.evince.Daemon"
    EV_DAEMON_IFACE = "org.gnome.evince.Daemon"
    
    EVINCE_PATH = "/org/gnome/evince/Evince"
    EVINCE_IFACE = "org.gnome.evince.Application"
    
    EV_WINDOW_IFACE = "org.gnome.evince.Window"
    
    
    
    class EvinceWindowProxy:
        """A DBUS proxy for an Evince Window."""
        daemon = None
        bus = None
    
        def __init__(self, uri, editor, spawn = False, logger = None):
            self._log = logger
            self.uri = uri
            self.editor = editor
            self.status = CLOSED
            self.source_handler = None
            self.dbus_name = ''
            self._handler = None
            try:
                if EvinceWindowProxy.bus is None:
                    EvinceWindowProxy.bus = dbus.SessionBus()
    
                if EvinceWindowProxy.daemon is None:
                    EvinceWindowProxy.daemon = EvinceWindowProxy.bus.get_object(EV_DAEMON_NAME,
                                                    EV_DAEMON_PATH,
                                                    follow_name_owner_changes=True)
                EvinceWindowProxy.bus.add_signal_receiver(self._on_doc_loaded, signal_name="DocumentLoaded", 
                                                          dbus_interface = EV_WINDOW_IFACE, 
                                                          sender_keyword='sender')
                self._get_dbus_name(False)
    
            except dbus.DBusException:
                if self._log:
                    self._log.debug("Could not connect to the Evince Daemon")
    
        def _on_doc_loaded(self, uri, **keyargs):
            if uri == self.uri and self._handler is None:
                self.handle_find_document_reply(keyargs['sender'])
    
        def _get_dbus_name(self, spawn):
            EvinceWindowProxy.daemon.FindDocument(self.uri,spawn,
                         reply_handler=self.handle_find_document_reply,
                         error_handler=self.handle_find_document_error,
                         dbus_interface = EV_DAEMON_IFACE)
    
        def handle_find_document_error(self, error):
            if self._log:
                self._log.debug("FindDocument DBus call has failed")
    
        def handle_find_document_reply(self, evince_name):
            if self._handler is not None:
                handler = self._handler
            else:
                handler = self.handle_get_window_list_reply
            if evince_name != '':
                self.dbus_name = evince_name
                self.status = RUNNING
                self.evince = EvinceWindowProxy.bus.get_object(self.dbus_name, EVINCE_PATH)
                self.evince.GetWindowList(dbus_interface = EVINCE_IFACE,
                              reply_handler = handler,
                              error_handler = self.handle_get_window_list_error)
    
        def handle_get_window_list_error (self, e):
            if self._log:
                self._log.debug("GetWindowList DBus call has failed")
    
        def handle_get_window_list_reply (self, window_list):
            if len(window_list) > 0:
                window_obj = EvinceWindowProxy.bus.get_object(self.dbus_name, window_list[0])
                self.window = dbus.Interface(window_obj,EV_WINDOW_IFACE)
                self.window.connect_to_signal("SyncSource", self.on_sync_source)
            else:
                #That should never happen. 
                if self._log:
                    self._log.debug("GetWindowList returned empty list")
    
        def on_sync_source(self, input_file, source_link):
            print input_file + ":" + str(source_link[0])
            cmd = re.sub("%f",input_file,self.editor)
            cmd = re.sub("%l",str(source_link[0]), cmd)
            print cmd
            subprocess.call(cmd, shell=True)
            if self.source_handler is not None:
                self.source_handler(input_file, source_link)
    
    
    ## This file offers backward search in any editor.
    ##  evince_dbus  pdf_file  line_source input_file
    if __name__ == '__main__':
        import dbus.mainloop.glib, gobject, glib, sys, os
    
        def print_usage():
            print """Usage: 
      evince_backward_search pdf_file "editorcmd %f %l"'
        %f ... TeX-file to load
        %l ... line to jump to
    E.g.:
      evince_backward_search somepdf.pdf "gvim --servername somepdf --remote '+%l<Enter>' %f"
      evince_backward_search somepdf.pdf "emacsclient -a emacs --no-wait +%l %f"
      evince_backward_search somepdf.pdf "scite %f '-goto:%l'"
      evince_backward_search somepdf.pdf "lyxclient -g %f %l"
      evince_backward_search somepdf.pdf "kate --use --line %l"
      evince_backward_search somepdf.pdf "kile --line %l" """
            sys.exit(1)
    
        if len(sys.argv)!=3:
            print_usage()
    
        pdf_file = os.path.abspath(sys.argv[1])
    
        if not os.path.isfile(pdf_file):
            print_usage()
    
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        a = EvinceWindowProxy('file://' + pdf_file, sys.argv[2] ,True)
    
    
        loop = gobject.MainLoop()
        loop.run() 
    # ex:ts=4:et:
    

    Evince 前向搜索:

    #!/usr/bin/python2
    # -*- coding: utf-8 -*-
    
    # Copyright (C) 2010 Jose Aliste <jose.aliste@gmail.com>
    #               2011 Benjamin Kellermann <Benjamin.Kellermann@tu-dresden.de>
    #
    # 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 dbus, subprocess, time, sys, os
    
    def print_usage():
        print 'Usage: evince_forward_search pdf_file line_number tex_file\n   or: evince_forward_search pdf_file tex_file' 
        sys.exit(1)
    
    if len(sys.argv)< 3 or len(sys.argv)>4: 
        print_usage()
    
    if len(sys.argv)==4 :
        try:
            line_number = int(sys.argv[2])
        except ValueError:
            print_usage()
    
        pdf_file = os.path.abspath(sys.argv[1])
        tex_file = os.path.abspath(sys.argv[3])
    if len(sys.argv)==3 :
        line_number  = 0
        pdf_file = os.path.abspath(sys.argv[1])
        tex_file = os.path.abspath(sys.argv[2])
    try:
        bus = dbus.SessionBus()
        daemon = bus.get_object('org.gnome.evince.Daemon', '/org/gnome/evince/Daemon')
        dbus_name = daemon.FindDocument('file://' + pdf_file, True, dbus_interface = "org.gnome.evince.Daemon")
        window = bus.get_object(dbus_name, '/org/gnome/evince/Window/0')
    except dbus.DBusException:
        print_exc()     
    
    if len(sys.argv)==4 :
        window.SyncView(tex_file, (line_number,1), dbus_interface="org.gnome.evince.Window")
    
    if len(sys.argv)==3 :
        subprocess.Popen(["evince",pdf_file])
    

    Evince(我将它存储在我的 ~/bin 中,但更合适的名称可能会更好):

    #!/bin/sh
    EDITORCMD="emacsclient -a '' --no-wait +%l %f"
    PDFFILE="$1"
    
    ~/bin/evince_forward_search "$@"
    
    if [ -f "$PDFFILE" ];then
        if [ -f `basename "$PDFFILE" .pdf`.synctex.gz ];then
            ~/build/evince_backward_search "$PDFFILE" "$EDITORCMD"&
            BACKWARD_SEARCH_PID=$!
            echo $BACKWARD_SEARCH_PID
        fi
    fi
    
    if [ "$BACKWARD_SEARCH_PID" ];then
        echo "Killing $BACKWARD_SEARCH_PID"
        kill $BACKWARD_SEARCH_PID
    fi
    

    这是我的 Emacs-config 中的相关片段(Org 格式):

    *** Make Evince synctex friendly 
    I want to use [[http://ubuntuforums.org/showthread.php?t%3D1716268][these scripts]] to make AUCTeX more synctex friendly.
    The evince sh script is found [[file:~/bin/evince][here]].
    
    The process is as follows:
     1. AUCTeX should call the ~/bin/evince rather than /usr/bin/evince
     2. local evince in turn call [[~/bin/evince_backward_search][evince_backward_search]] (with two
        arguments, pdf and editor) and  [[file:~/bin/evince_forward%20script][evince_forward script]] with two to
        three arguments
    #+begin_src emacs-lisp
    ;;      ("Evince" ("evince" (mode-io-correlate " -p %(outpage)") " %o"))
    (add-to-list 'TeX-view-program-list
    (quote ("Evince2" ("~/bin/evince %o " (mode-io-correlate "%n ") "%t"))))
    ;;(setq TeX-view-program-selection (quote (((output-dvi style-pstricks) "dvips and gv") (output-dvi "xdvi") (output-pdf "Evince2") (output-html "xdg-open"))))
    (add-to-list 'TeX-view-program-selection
             (quote (output-pdf "Evince2")))
    #+end_src
    

    这整件事可能很糟糕——我不是程序员!我刚刚将上述内容放在一起以获得可行的解决方案。

    注意:你不会得到红色框,在 AUCTeX 的 cvs 版本中突出显示当前 tex-file 行。

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 1970-01-01
      • 2010-12-09
      • 2011-01-15
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多