Am Freitag, 3. März 2006 00:46 schrieb João Luis Meloni Assirati:

> Sorry, guys. I hadn't reallized that Lars post  was about the .h file. I 
> understand now, it was a stupid error. Attached is the updated patch.

João,

I think that DVI search is a very useful feature and that it should go in 
as soon as possible. It is great that you implemented it, and I am going 
to use it in my tree from now on, but there is one thing in your patch 
that I did not like so much: You added a lot of special code to handle 
the commandline flags for latex, xdvi and kdvi. Almost all of this 
special code can be avoided if we use the existing converter mechanism: 
Insetad of carrying flags around that specify whether a to-be-generated 
DVI file is for preview or not, we simply define a format dvi2. The latex 
-> dvi2 converter is defined with the -src-specials commandline switch, 
and the dvi2 viewer is defined with the appropriate arguments for xdvi or 
kdvi, respectively. Another advantage is that no new keywords are needed 
in the preferences file, so it can be incorporated into a 1.4.x release 
without problems.
I created the attached patch, based on your last one (dvi-search-3.diff). 
It works for me (did only test xdvi).
In order to give the DVI file with source specials a different name I 
defined the suffix of the new dvi2 format as dvix. This triggered a bug 
in the current converter mechanism: It is always assumed that the output 
file name of a converter can be set by a command line argument, but this 
is not the case for e.g. latex.
I extended the converter mechanims to use the resultfile flag as output 
file name for these converters, and rename the created file as needed. 
This could also be useful for other converters.
One drawback of this solution compared to the original one is that an 
existing dvi file in the temp dir will be overwritten (and then renamed) 
if a dvi2 file is created. This could be easily solved by defining a 
latex2 format and using that as source for dvi2 creation.
A final remark about the new placeholders: $$s is already used for the 
script directory, so it is possibly a good idea to rename it to something 
else.


Georg
Index: src/exporter.C
===================================================================
--- src/exporter.C	(Revision 13290)
+++ src/exporter.C	(Arbeitskopie)
@@ -19,6 +19,7 @@
 #include "exporter.h"
 
 #include "buffer.h"
+#include "BufferView.h"
 #include "buffer_funcs.h"
 #include "bufferparams.h"
 #include "converter.h"
@@ -259,12 +260,12 @@ bool Exporter::Export(Buffer * buffer, s
 }
 
 
-bool Exporter::Preview(Buffer * buffer, string const & format)
+bool Exporter::Preview(BufferView * bv, string const & format)
 {
 	string result_file;
-	if (!Export(buffer, format, true, result_file))
+	if (!Export(bv->buffer(), format, true, result_file))
 		return false;
-	return formats.view(*buffer, result_file, format);
+	return formats.view(*bv, result_file, format);
 }
 
 
Index: src/converter.C
===================================================================
--- src/converter.C	(Revision 13290)
+++ src/converter.C	(Arbeitskopie)
@@ -353,6 +353,22 @@ bool Converters::convert(Buffer const * 
 			real_outfile = infile;
 			outfile = AddName(buffer->temppath(), "tmpfile.out");
 		}
+		if (conv.result_dir.empty() && !conv.result_file.empty()) {
+			// This is a converter with a fixed output name.
+			// We need to rename the generated file.
+			if (real_outfile.empty())
+				real_outfile = outfile;
+			else {
+				// A converter with a fixed output name that
+				// is equal to the input name needs even more
+				// tricks.
+				string const real_infile = infile;
+				infile = lyx::support::tempName(buffer->temppath());
+				if (!move(conv.from, real_infile, infile, true))
+					return false;
+			}
+			outfile = subst(conv.result_file, token_base, from_base);
+		}
 
 		if (conv.latex) {
 			run_latex = true;
@@ -405,20 +421,6 @@ bool Converters::convert(Buffer const * 
 			} else
 				res = one.startscript(type, command);
 
-			if (!real_outfile.empty()) {
-				Mover const & mover = movers(conv.to);
-				if (!mover.rename(outfile, real_outfile))
-					res = -1;
-				else
-					lyxerr[Debug::FILES]
-						<< "renaming file " << outfile
-						<< " to " << real_outfile
-						<< endl;
-				// Finally, don't forget to tell any future
-				// converters to use the renamed file...
-				outfile = real_outfile;
-			}
-
 			if (!conv.parselog.empty()) {
 				string const logfile =  infile2 + ".log";
 				string const script = LibScriptSearch(conv.parselog);
@@ -444,6 +446,20 @@ bool Converters::convert(Buffer const * 
 				return false;
 			}
 		}
+
+		if (!real_outfile.empty()) {
+			Mover const & mover = movers(conv.to);
+			if (!mover.rename(outfile, real_outfile))
+				return false;
+			else
+				lyxerr[Debug::FILES]
+					<< "renaming file " << outfile
+					<< " to " << real_outfile
+					<< endl;
+			// Finally, don't forget to tell any future
+			// converters to use the renamed file...
+			outfile = real_outfile;
+		}
 	}
 
 	Converter const & conv = converterlist_[edgepath.back()];
Index: src/exporter.h
===================================================================
--- src/exporter.h	(Revision 13290)
+++ src/exporter.h	(Arbeitskopie)
@@ -19,6 +19,7 @@
 
 
 class Buffer;
+class BufferView;
 class Format;
 
 class Exporter {
@@ -33,7 +34,7 @@ public:
 		    bool put_in_tempdir);
 	///
 	static
-	bool Preview(Buffer * buffer, std::string const & format);
+	bool Preview(BufferView * bv, std::string const & format);
 	///
 	static
 	bool IsExportable(Buffer const & buffer, std::string const & format);
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C	(Revision 13290)
+++ src/lyxfunc.C	(Arbeitskopie)
@@ -829,7 +829,7 @@ void LyXFunc::dispatch(FuncRequest const
 			break;
 
 		case LFUN_PREVIEW:
-			Exporter::Preview(owner->buffer(), argument);
+			Exporter::Preview(view(), argument);
 			view()->showErrorList(BufferFormat(*owner->buffer()));
 			break;
 
@@ -1131,10 +1131,8 @@ void LyXFunc::dispatch(FuncRequest const
 			}
 
 			view()->setCursorFromRow(row);
-
 			view()->center();
-			// see BufferView_pimpl::center()
-			view()->updateScrollbar();
+			view()->update();
 			break;
 		}
 
Index: src/format.C
===================================================================
--- src/format.C	(Revision 13290)
+++ src/format.C	(Arbeitskopie)
@@ -12,6 +12,7 @@
 
 #include "format.h"
 #include "buffer.h"
+#include "BufferView.h"
 #include "bufferparams.h"
 #include "lyxrc.h"
 #include "debug.h"
@@ -23,6 +24,8 @@
 #include "support/filetools.h"
 #include "support/path.h"
 #include "support/systemcall.h"
+#include "support/convert.h"
+#include "support/filetools.h"
 
 using lyx::support::bformat;
 using lyx::support::compare_ascii_no_case;
@@ -35,6 +38,7 @@ using lyx::support::Path;
 using lyx::support::QuoteName;
 using lyx::support::subst;
 using lyx::support::Systemcall;
+using lyx::support::ChangeExtension;
 
 using std::string;
 using std::distance;
@@ -46,6 +50,8 @@ namespace {
 string const token_from("$$i");
 string const token_path("$$p");
 string const token_socket("$$a");
+string const token_srcfile("$$s");
+string const token_srcline("$$l");
 
 
 class FormatNamesEqual : public std::unary_function<Format, bool> {
@@ -213,7 +219,7 @@ void Formats::setViewer(string const & n
 }
 
 
-bool Formats::view(Buffer const & buffer, string const & filename,
+bool Formats::view(BufferView const & bv, string const & filename,
 		   string const & format_name) const
 {
 	if (filename.empty())
@@ -237,11 +243,11 @@ bool Formats::view(Buffer const & buffer
 	if (format_name == "dvi" &&
 	    !lyxrc.view_dvi_paper_option.empty()) {
 		command += ' ' + lyxrc.view_dvi_paper_option;
-		string paper_size = buffer.params().paperSizeName();
+		string paper_size = bv.buffer()->params().paperSizeName();
 		if (paper_size == "letter")
 			paper_size = "us";
 		command += ' ' + paper_size;
-		if (buffer.params().orientation == ORIENTATION_LANDSCAPE)
+		if (bv.buffer()->params().orientation == ORIENTATION_LANDSCAPE)
 			command += 'r';
 	}
 
@@ -252,8 +258,11 @@ bool Formats::view(Buffer const & buffer
 			QuoteName(OnlyFilename(filename)));
 	command = subst(command, token_path, QuoteName(OnlyPath(filename)));
 	command = subst(command, token_socket, QuoteName(lyxsocket->address()));
+	command = subst(command, token_srcfile,
+			QuoteName(ChangeExtension(filename, "tex")));
+	command = subst(command, token_srcline, convert<string>(bv.texrow_ref()));
 	lyxerr[Debug::FILES] << "Executing command: " << command << std::endl;
-	buffer.message(_("Executing command: ") + command);
+	bv.buffer()->message(_("Executing command: ") + command);
 
 	Path p(OnlyPath(filename));
 	Systemcall one;
Index: src/converter.h
===================================================================
--- src/converter.h	(Revision 13290)
+++ src/converter.h	(Arbeitskopie)
@@ -59,6 +59,9 @@ public:
 	std::string result_dir;
 	/// If the converter put the result in a directory, then result_file
 	/// is the name of the main file in that directory
+	/// Otherwise, and if the converter does not accept a command line
+	/// option to set the output file name, it is the fixed name of the
+	/// output file.
 	std::string result_file;
 	/// Command to convert the program output to a LaTeX log file format
 	std::string parselog;
Index: src/texrow.C
===================================================================
--- src/texrow.C	(Revision 13290)
+++ src/texrow.C	(Arbeitskopie)
@@ -78,6 +78,39 @@ bool TexRow::getIdFromRow(int row, int &
 }
 
 
+int TexRow::getRowFromId(int id, int pos) const
+{
+	RowList::const_iterator cit = rowlist.begin();
+	RowList::const_iterator rowlist_end = rowlist.end();
+	int diff_id = abs(cit->id() - id);
+	int best_id = cit->id();
+	int diff_pos = abs(cit->pos() - pos);
+	int best_row = cit->rownumber();
+	for (++cit; cit != rowlist_end; ++cit) {
+		int new_diff_id = abs(cit->id() - id);
+		int new_best_id = cit->id();
+		int new_diff_pos = abs(cit->pos() - pos);
+		if (new_diff_id < diff_id) {
+			diff_id = new_diff_id;
+			best_id = new_best_id;
+			diff_pos = new_diff_pos;
+			best_row = cit->rownumber();
+		} else if (new_diff_id == diff_id) {
+			if (new_best_id > best_id) {
+				best_id = new_best_id;
+				diff_pos = new_diff_pos;
+				best_row = cit->rownumber();
+			} else if ((new_best_id == best_id)
+				   && (new_diff_pos < diff_pos)) {
+				diff_pos = new_diff_pos;
+				best_row = cit->rownumber();
+			}
+		}
+	}
+	return best_row;
+}
+
+
 TexRow & TexRow::operator+=(TexRow const & tr)
 {
 	rowlist.insert(rowlist.end(), tr.rowlist.begin(), tr.rowlist.end());
Index: src/format.h
===================================================================
--- src/format.h	(Revision 13290)
+++ src/format.h	(Arbeitskopie)
@@ -16,6 +16,7 @@
 #include <string>
 
 class Buffer;
+class BufferView;
 
 class Format {
 public:
@@ -108,7 +109,7 @@ public:
 	///
 	void setViewer(std::string const & name, std::string const & command);
 	///
-	bool view(Buffer const & buffer, std::string const & filename,
+	bool view(BufferView const & bv, std::string const & filename,
 		  std::string const & format_name) const;
 	///
 	bool edit(Buffer const & buffer, std::string const & filename,
Index: src/texrow.h
===================================================================
--- src/texrow.h	(Revision 13290)
+++ src/texrow.h	(Arbeitskopie)
@@ -46,6 +46,9 @@ public:
 	 */
 	bool getIdFromRow(int row, int & id, int & pos) const;
 
+	/// getRowFromId - find the closest row for a given (id, pos) pair
+	int getRowFromId(int id, int pos) const;
+
 	/// Returns the number of rows contained
 	int rows() const { return count; }
 
Index: src/BufferView.C
===================================================================
--- src/BufferView.C	(Revision 13290)
+++ src/BufferView.C	(Arbeitskopie)
@@ -387,6 +387,13 @@ lyx::pit_type BufferView::anchor_ref() c
 }
 
 
+int BufferView::texrow_ref() const 
+{
+	return buffer()->texrow().getRowFromId(
+		buffer()->paragraphs()[anchor_ref()].id(), offset_ref());
+}
+
+
 int BufferView::offset_ref() const
 {
 	return pimpl_->offset_ref_;
Index: src/MenuBackend.C
===================================================================
--- src/MenuBackend.C	(Revision 13290)
+++ src/MenuBackend.C	(Arbeitskopie)
@@ -511,17 +511,31 @@ void expandFormats(MenuItem::Kind kind, 
 		if (label == "EPS" || label == "XPM" || label == "PNG")
 			continue;
 
-		if (kind == MenuItem::ImportFormats) {
+		switch (kind) {
+		case MenuItem::ImportFormats:
 			if ((*fit)->name() == "text")
 				label = _("Plain Text as Lines");
 			else if ((*fit)->name() == "textparagraph")
 				label = _("Plain Text as Paragraphs");
 			label += "...";
-		} else if (kind == MenuItem::ExportFormats) {
+			break;
+		case MenuItem::ExportFormats:
 			// exporting to LyX does not make sense
 			// FIXME: Introduce noexport flag
 			if ((*fit)->name() == "lyx")
 				continue;
+			// only export to dvi (without source specials)
+			// FIXME: Introduce noexport flag
+			if ((*fit)->name() == "dvi2")
+				continue;
+			break;
+		case MenuItem::ViewFormats:
+		case MenuItem::UpdateFormats:
+			// only show dvi2 (with source specials)
+			// FIXME: Introduce noview flag
+			if ((*fit)->name() == "dvi")
+				continue;
+			break;
 		}
 		if (!(*fit)->shortcut().empty())
 			label += '|' + (*fit)->shortcut();
Index: src/BufferView.h
===================================================================
--- src/BufferView.h	(Revision 13290)
+++ src/BufferView.h	(Arbeitskopie)
@@ -179,6 +179,8 @@ public:
 	int offset_ref() const;
 	/// access to anchor
 	lyx::pit_type anchor_ref() const;
+	/// access to the texrow corresponding to the beginning of the view
+	int texrow_ref() const;
 
 	/// access to full cursor
 	LCursor & cursor();
Index: lib/configure.m4
===================================================================
--- lib/configure.m4	(Revision 13290)
+++ lib/configure.m4	(Arbeitskopie)
@@ -294,6 +294,13 @@ SEARCH_PROG([for a PDF previewer],PDF_VI
 
 # Search something to preview dvi
 SEARCH_PROG([for a DVI previewer],DVI_VIEWER, xdvi windvi yap kdvi)
+if test "$DVI_VIEWER" = "xdvi"; then
+	DVI_VIEWER_SPECIAL=" -sourceposition '\$\$l \$\$s'"
+elif test "$DVI_VIEWER" = "kdvi"; then
+	DVI_VIEWER_SPECIAL=" --unique 'file:\$\$i#src:\$\$l\$\$s'"
+else
+	DVI_VIEWER_SPECIAL=""
+fi
 
 # Search something to preview html
 SEARCH_PROG([for a HTML previewer],HTML_VIEWER, "mozilla file://\$\$p\$\$i" netscape)
@@ -581,6 +588,7 @@ cat >$outfile <<EOF
 \\Format docbook    sgml    DocBook                B  ""	"$TEXT_EDITOR"
 \\Format docbook-xml xml   "Docbook (XML)"         "" ""	"$TEXT_EDITOR"
 \\Format dvi        dvi     DVI                    D  "$DVI_VIEWER"	""
+\\Format dvi2       dvix    DVI                    D  "$DVI_VIEWER$DVI_VIEWER_SPECIAL"	""
 \\Format eps        eps     EPS                    "" "$EPS_VIEWER"	""
 \\Format fax        ""      Fax                    "" ""	""
 \\Format fen        fen     FEN                    "" "$FEN_VIEWER"	"$FEN_EDITOR"
@@ -627,6 +635,7 @@ cat >$outfile <<EOF
 \\converter html       latex      "$html_to_latex_command"	""
 \\converter latex      html       "$latex_to_html_command"	"originaldir,needaux"
 \\converter latex      dvi        "$latex_to_dvi"	"latex"
+\\converter latex      dvi2       "$latex_to_dvi -src-specials"	"latex,resultfile=\$\$b.dvi"
 \\converter latex      lyx        "$tex_to_lyx_command"	""
 \\converter latex      pdf2       "$latex_to_pdf"	"latex"
 \\converter latex      sxw        "$latex_to_sxw_command"	"latex"

Reply via email to