[Okular-devel] [PATCH] Re: how to invoke okular with inverse search with pdf?
Jochen Trumpf
Jochen.Trumpf at anu.edu.au
Wed Aug 26 05:49:41 CEST 2009
Hi,
I believe that this hasn't been implemented for pdf files, yet, but the following patch enables the functionality for me. I also copy an excerpt from my .emacs.d/init.el
that configures the command. Note however the current limitations due to KDE bug #205076 and bug #205084. Despite its title the latter bug also affects pdf files.
I have no idea if the okular developers approve of the approach I have taken with this, but we will see, I guess.
--- generators/poppler/generator_pdf.h.old 2009-08-24 11:05:46.000000000 +1000
+++ generators/poppler/generator_pdf.h 2009-08-24 12:14:23.000000000 +1000
@@ -129,6 +129,8 @@
void loadPdfSync( const QString & fileName, QVector<Okular::Page*> & pagesVector );
// init the synctex parser if a synctex file exists
void initSynctexParser( const QString& filePath );
+ // search document for source reference
+ void fillViewportFromSourceReference( Okular::DocumentViewport &viewport, const QString &reference ) const;
Okular::TextPage * abstractTextPage(const QList<Poppler::TextBox*> &text, double height, double width, int rot);
--- generators/poppler/generator_pdf.cpp.old 2009-08-24 10:12:49.000000000 +1000
+++ generators/poppler/generator_pdf.cpp 2009-08-24 17:19:37.000000000 +1000
@@ -958,17 +958,27 @@
}
else if ( key == "NamedViewport" && !option.toString().isEmpty() )
{
- // asking for the page related to a 'named link destination'. the
- // option is the link name. @see addSynopsisChildren.
Okular::DocumentViewport viewport;
- userMutex()->lock();
- Poppler::LinkDestination *ld = pdfdoc->linkDestination( option.toString() );
- userMutex()->unlock();
- if ( ld )
- {
- fillViewportFromLinkDestination( viewport, *ld );
- }
- delete ld;
+
+ // if option starts with "src:" assume that we are handling a
+ // source reference
+ if (option.toString().indexOf("src:", 0, Qt::CaseInsensitive) == 0)
+ {
+ fillViewportFromSourceReference( viewport, option.toString() );
+ }
+ else
+ {
+ // asking for the page related to a 'named link destination'. the
+ // option is the link name. @see addSynopsisChildren.
+ userMutex()->lock();
+ Poppler::LinkDestination *ld = pdfdoc->linkDestination( option.toString() );
+ userMutex()->unlock();
+ if ( ld )
+ {
+ fillViewportFromLinkDestination( viewport, *ld );
+ }
+ delete ld;
+ }
if ( viewport.pageNumber >= 0 )
return viewport.toString();
}
@@ -1484,6 +1494,57 @@
return 0;
}
+void PDFGenerator::fillViewportFromSourceReference( Okular::DocumentViewport &viewport, const QString &reference ) const
+{
+ if ( !synctex_scanner )
+ return;
+
+ // The reference is of form "src:1111Filename", where "1111"
+ // points to line number 1111 in the file "Filename".
+ // Extract the file name and the numeral part from the reference string.
+ // This will fail if Filename starts with a digit.
+ QString name, line;
+ // Remove "src:". Presence of substring has been checked before this
+ // function is called.
+ name = reference.mid(4);
+ // split
+ quint32 max = name.length();
+ quint32 i = 0;
+ for(i=0; i<max; ++i) if ( !name[i].isDigit()) break;
+ line = name.left(i);
+ name = name.mid(i);
+ // Remove spaces.
+ name = name.trimmed();
+ line = line.trimmed();
+ // Convert line to integer.
+ bool ok;
+ int m_line = line.toInt(&ok);
+ if (!ok) m_line = -1;
+
+ // Use column == -1 for now.
+ if( synctex_display_query( synctex_scanner, name.toLatin1(), m_line, -1 ) > 0 )
+ {
+ synctex_node_t node;
+ // For now use the first hit. Could possibly be made smarter
+ // in case there are multiple hits.
+ while( (node = synctex_next_result(synctex_scanner)) )
+ {
+ // TeX pages start at 1.
+ viewport.pageNumber = synctex_node_page( node ) - 1;
+
+ if (!viewport.isValid()) return;
+
+ // TeX small points ...
+ viewport.rePos.normalizedX = (synctex_node_h( node ) * dpiX) / (72.27 * 65536.0 * document()->page(viewport.pageNumber)->width());
+ viewport.rePos.normalizedY = (synctex_node_v( node ) * dpiY) / (72.27 * 65536.0 * document()->page(viewport.pageNumber)->height());
+ viewport.rePos.enabled = true;
+ viewport.rePos.pos = Okular::DocumentViewport::TopLeft;
+
+ return;
+ }
+ }
+}
+
QWidget* PDFGenerator::printConfigurationWidget() const
{
if ( !pdfOptionsPage )
And here the init.el excerpt. Note that my solution completely overwrites the view commands, so you probably want to modify this.
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-to-list 'TeX-expand-list
'("%u" Okular-make-url))))
(setq TeX-output-view-style
'(("^dvi$" "." "okular --unique %u")
("^pdf$" "." "okular --unique %u")
("^html?$" "." "firefox %o")))
(defun Okular-make-url () (concat
"file://"
(expand-file-name (funcall file (TeX-output-extension) t))
"#src:"
(TeX-current-line)
(TeX-current-file-name-master-relative)))
Cheers,
Jochen
On Wed, 26 Aug 2009 07:31:59 Oliver Heins wrote:
> Hello,
>
> I compiled the latest okular from svn for being able to do inverse
> search with synctex/pdf. It works great for okular->emacs. Sadly, i
> have no idea of how i should invoke okular from within emacs to be put
> to right place in the pdf. I tried things like
>
> okular --unique 'diss.pdf#src:40 ./Chapters/Chapter12.tex'
>
> but that did not work.
>
> How do i have to invoke okular?
>
> TIA,
> olli
More information about the Okular-devel
mailing list