2000-08-30 03:40:51 +00:00
|
|
|
/* This file is part of
|
|
|
|
* ======================================================
|
|
|
|
*
|
|
|
|
* LyX, The Document Processor
|
|
|
|
*
|
|
|
|
* Copyright 1995 Matthias Ettrich
|
|
|
|
* Copyright 1995-2000 The LyX Team.
|
|
|
|
*
|
|
|
|
* ====================================================== */
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
#include "converter.h"
|
|
|
|
#include "lyxrc.h"
|
|
|
|
#include "support/syscall.h"
|
|
|
|
#include "support/path.h"
|
2000-11-08 09:39:46 +00:00
|
|
|
#include "support/filetools.h"
|
2000-08-30 03:40:51 +00:00
|
|
|
#include "buffer.h"
|
|
|
|
#include "bufferview_funcs.h"
|
|
|
|
#include "LaTeX.h"
|
|
|
|
#include "LyXView.h"
|
|
|
|
#include "minibuffer.h"
|
|
|
|
#include "lyx_gui_misc.h"
|
2000-09-05 13:16:19 +00:00
|
|
|
#include "lyx_cb.h" // ShowMessage()
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
using std::map;
|
|
|
|
using std::vector;
|
|
|
|
using std::queue;
|
2000-08-31 11:51:59 +00:00
|
|
|
using std::pair;
|
|
|
|
using std::endl;
|
2000-10-23 12:16:05 +00:00
|
|
|
using std::find;
|
|
|
|
using std::find_if;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
vector<Command> Converter::commands;
|
2000-09-11 15:42:17 +00:00
|
|
|
string Converter::latex_command;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
static inline
|
2000-09-14 17:53:12 +00:00
|
|
|
string const add_options(string const & command, string const & options)
|
2000-09-05 13:16:19 +00:00
|
|
|
{
|
|
|
|
string head;
|
2000-11-08 09:39:46 +00:00
|
|
|
string const tail = split(command, head, ' ');
|
2000-09-05 13:16:19 +00:00
|
|
|
return head + ' ' + options + ' ' + tail;
|
|
|
|
}
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
|
|
|
|
bool Format::dummy() const
|
|
|
|
{
|
|
|
|
return extension.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
void Formats::Add(string const & name)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
if (formats.find(name) == formats.end())
|
2000-11-06 11:20:22 +00:00
|
|
|
formats[name] = Format(name, name, name, "", "");
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
void Formats::Add(string const & name, string const & extension,
|
|
|
|
string const & prettyname, string const & shortcut)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-11-06 11:20:22 +00:00
|
|
|
|
|
|
|
if (prettyname.empty()) {
|
|
|
|
FormatList::iterator it = formats.find(name);
|
|
|
|
if (it != formats.end())
|
|
|
|
formats.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
string const old_viewer = formats[name].viewer;
|
2000-11-06 11:20:22 +00:00
|
|
|
formats[name] = Format(name, extension, prettyname, shortcut,
|
|
|
|
old_viewer);
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
void Formats::SetViewer(string const & name, string const & command)
|
|
|
|
{
|
2000-10-02 16:44:47 +00:00
|
|
|
string command2 = command;
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!command2.empty() && !contains(command2,"$$FName"))
|
2000-10-02 16:44:47 +00:00
|
|
|
command2 += " $$FName";
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
Add(name);
|
2000-09-05 13:16:19 +00:00
|
|
|
GetFormat(name)->viewer = command2;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
bool Formats::View(Buffer const * buffer, string const & filename,
|
|
|
|
string const & format_name)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-09-11 15:42:17 +00:00
|
|
|
if (filename.empty())
|
|
|
|
return false;
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
Format const * format = GetFormat(format_name);
|
2000-08-30 03:40:51 +00:00
|
|
|
if (!format || format->viewer.empty()) {
|
|
|
|
WriteAlert(_("Can not view file"),
|
|
|
|
_("No information for viewing ")
|
2000-11-06 11:20:22 +00:00
|
|
|
+ PrettyName(format_name));
|
2000-08-30 03:40:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
string command = format->viewer;
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
if (format_name == "dvi" &&
|
2000-09-05 13:16:19 +00:00
|
|
|
!lyxrc.view_dvi_paper_option.empty()) {
|
|
|
|
string options = lyxrc.view_dvi_paper_option;
|
|
|
|
options += " " + Converter::dvi_papersize(buffer);
|
|
|
|
if (buffer->params.orientation
|
|
|
|
== BufferParams::ORIENTATION_LANDSCAPE)
|
|
|
|
options += 'r';
|
|
|
|
command = add_options(command, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
string command2 = subst(command, "$$FName", OnlyFilename(filename));
|
|
|
|
lyxerr << "Executing command: " << command2 << endl;
|
|
|
|
ShowMessage(buffer, _("Executing command:"), command2);
|
|
|
|
|
2000-10-02 16:44:47 +00:00
|
|
|
command = subst(command, "$$FName", QuoteName(filename));
|
2000-08-30 03:40:51 +00:00
|
|
|
Systemcalls one;
|
2000-09-05 13:16:19 +00:00
|
|
|
int res = one.startscript(Systemcalls::SystemDontWait, command);
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
if (res) {
|
|
|
|
WriteAlert(_("Can not view file"),
|
|
|
|
_("Error while executing"),
|
|
|
|
command.substr(0, 50));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
// This method should return a reference, and throw an exception
|
|
|
|
// if the format named name cannot be found (Lgb)
|
2000-08-30 03:40:51 +00:00
|
|
|
Format * Formats::GetFormat(string const & name)
|
|
|
|
{
|
2000-11-06 11:20:22 +00:00
|
|
|
FormatList::iterator it = formats.find(name);
|
2000-08-30 03:40:51 +00:00
|
|
|
if (it != formats.end())
|
2000-11-06 11:20:22 +00:00
|
|
|
return &it->second;
|
2000-08-30 03:40:51 +00:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
string const Formats::PrettyName(string const & name)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
Format const * format = GetFormat(name);
|
|
|
|
if (format)
|
|
|
|
return format->prettyname;
|
2000-08-30 03:40:51 +00:00
|
|
|
else
|
2000-10-23 12:16:05 +00:00
|
|
|
return name;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
string const Formats::Extension(string const & name)
|
|
|
|
{
|
|
|
|
Format const * format = GetFormat(name);
|
|
|
|
if (format)
|
|
|
|
return format->extension;
|
|
|
|
else
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
|
|
|
|
vector<Format>
|
2000-11-08 09:39:46 +00:00
|
|
|
const Formats::GetAllFormats() const
|
2000-11-06 11:20:22 +00:00
|
|
|
{
|
|
|
|
vector<Format> result;
|
2000-11-08 09:39:46 +00:00
|
|
|
for (FormatList::const_iterator cit = formats.begin();
|
|
|
|
cit != formats.end(); ++cit)
|
|
|
|
result.push_back(cit->second);
|
2000-11-06 11:20:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
// Instead of storing an object we could just store an const reference.
|
|
|
|
// _but_ that is not guaranteed to work in all cases. (Lgb)
|
2000-10-23 12:16:05 +00:00
|
|
|
class compare_Command {
|
|
|
|
public:
|
|
|
|
compare_Command(Command const & c) : com(c) {}
|
|
|
|
bool operator()(Command const & c) {
|
|
|
|
return c.from == com.from && c.to == com.to;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
Command com;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
void Converter::Add(string const & from, string const & to,
|
|
|
|
string const & command, string const & flags)
|
|
|
|
{
|
2000-11-06 11:20:22 +00:00
|
|
|
formats.Add(from);
|
|
|
|
formats.Add(to);
|
|
|
|
Command Com(formats.GetFormat(from), formats.GetFormat(to), command);
|
2000-10-23 12:16:05 +00:00
|
|
|
vector<Command>::iterator it = find_if(commands.begin(),
|
|
|
|
commands.end(),
|
|
|
|
compare_Command(Com));
|
|
|
|
|
|
|
|
if (command.empty() || command == "none") {
|
|
|
|
if (it != commands.end())
|
|
|
|
commands.erase(it);
|
2000-09-05 13:16:19 +00:00
|
|
|
return;
|
2000-10-23 12:16:05 +00:00
|
|
|
}
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-09-11 15:42:17 +00:00
|
|
|
|
|
|
|
// Read the flags
|
|
|
|
string flag_list(flags);
|
|
|
|
while (!flag_list.empty()) {
|
2000-10-23 12:16:05 +00:00
|
|
|
string flag_name, flag_value;
|
|
|
|
flag_list = split(flag_list, flag_value, ',');
|
2000-09-11 15:42:17 +00:00
|
|
|
flag_value = split(flag_value, flag_name, '=');
|
2000-10-23 12:16:05 +00:00
|
|
|
if (flag_name == "*") {
|
|
|
|
if (it != commands.end()) {
|
|
|
|
Com = *it;
|
|
|
|
Com.command = command;
|
|
|
|
}
|
|
|
|
}
|
2000-11-06 11:20:22 +00:00
|
|
|
else if (flag_name == "importer")
|
|
|
|
Com.importer = true;
|
2000-10-23 12:16:05 +00:00
|
|
|
else if (flag_name == "latex")
|
|
|
|
Com.latex = true;
|
|
|
|
else if (flag_name == "originaldir")
|
2000-09-11 15:42:17 +00:00
|
|
|
Com.original_dir = true;
|
|
|
|
else if (flag_name == "needaux")
|
|
|
|
Com.need_aux = true;
|
|
|
|
else if (flag_name == "resultdir")
|
|
|
|
Com.result_dir = (flag_value.empty())
|
|
|
|
? "$$BaseName" : flag_value;
|
|
|
|
else if (flag_name == "resultfile")
|
|
|
|
Com.result_file = flag_value;
|
2000-10-02 16:44:47 +00:00
|
|
|
else if (flag_name == "parselog")
|
|
|
|
Com.parselog = flag_value;
|
2000-10-23 12:16:05 +00:00
|
|
|
else if (flag_name == "disable") {
|
|
|
|
while (!flag_value.empty()) {
|
|
|
|
string tmp;
|
|
|
|
flag_value = split(flag_value, tmp, '&');
|
|
|
|
Com.disable.push_back(tmp);
|
|
|
|
}
|
|
|
|
}
|
2000-09-11 15:42:17 +00:00
|
|
|
}
|
|
|
|
if (!Com.result_dir.empty() && Com.result_file.empty())
|
|
|
|
Com.result_file = "index." + to;
|
2000-10-23 12:16:05 +00:00
|
|
|
//if (!contains(command, "$$FName"))
|
|
|
|
// Com.latex = true;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
if (Com.latex && (latex_command.empty() || to == "dvi"))
|
|
|
|
latex_command = command;
|
|
|
|
// If we have both latex & pdflatex, we set latex_command to latex.
|
|
|
|
// The latex_command is used to update the .aux file when running
|
|
|
|
// a converter that uses it.
|
|
|
|
|
|
|
|
if (it != commands.end()) {
|
|
|
|
*it = Com;
|
|
|
|
return;
|
|
|
|
}
|
2000-09-11 15:42:17 +00:00
|
|
|
commands.push_back(Com);
|
2000-10-23 12:16:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
static inline
|
2000-10-23 12:16:05 +00:00
|
|
|
bool enable(vector<Command>::iterator it, string const & from)
|
|
|
|
{
|
2000-11-06 11:20:22 +00:00
|
|
|
return find(it->disable.begin(), it->disable.end(), from)
|
|
|
|
== it->disable.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<FormatPair> const
|
|
|
|
Converter::GetReachableTo(string const & target)
|
|
|
|
{
|
|
|
|
vector<FormatPair> result;
|
|
|
|
|
|
|
|
queue< vector<Command>::iterator > Q;
|
|
|
|
for (vector<Command>::iterator it = commands.begin();
|
|
|
|
it != commands.end(); ++it)
|
|
|
|
if (it->to->name == target && it->importer) {
|
|
|
|
Q.push(it);
|
|
|
|
it->visited = true;
|
|
|
|
} else
|
|
|
|
it->visited = false;
|
|
|
|
|
|
|
|
while (!Q.empty()) {
|
|
|
|
vector<Command>::iterator it = Q.front();
|
|
|
|
Q.pop();
|
|
|
|
result.push_back(FormatPair(it->from, 0, ""));
|
|
|
|
for (vector<Command>::iterator it2 = commands.begin();
|
|
|
|
it2 != commands.end(); ++it2)
|
|
|
|
if (!it2->visited && it->from == it2->to &&
|
|
|
|
it2->importer) {
|
|
|
|
Q.push(it2);
|
|
|
|
it2->visited = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
|
2000-10-16 13:27:56 +00:00
|
|
|
vector<FormatPair> const
|
2000-11-06 11:20:22 +00:00
|
|
|
Converter::GetReachable(string const & from, bool only_viewable)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-10-16 13:27:56 +00:00
|
|
|
vector<FormatPair> result;
|
2000-11-06 11:20:22 +00:00
|
|
|
Format const * format = formats.GetFormat(from);
|
2000-08-30 03:40:51 +00:00
|
|
|
if (!format)
|
|
|
|
return result;
|
|
|
|
|
2000-10-16 13:27:56 +00:00
|
|
|
if (!only_viewable || !format->viewer.empty())
|
|
|
|
result.push_back(FormatPair(format, 0, ""));
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
queue< vector<Command>::iterator > Q;
|
|
|
|
for (vector<Command>::iterator it = commands.begin();
|
|
|
|
it != commands.end(); ++it)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->from->name == from && enable(it, from)
|
|
|
|
&& !it->importer) {
|
2000-08-30 03:40:51 +00:00
|
|
|
Q.push(it);
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = true;
|
2000-08-30 03:40:51 +00:00
|
|
|
} else
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = false;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
while (!Q.empty()) {
|
|
|
|
vector<Command>::iterator it = Q.front();
|
2000-10-16 13:27:56 +00:00
|
|
|
Q.pop();
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!only_viewable || !it->to->viewer.empty())
|
|
|
|
result.push_back(FormatPair(it->to, it->from,
|
|
|
|
it->command));
|
2000-08-30 03:40:51 +00:00
|
|
|
for (vector<Command>::iterator it2 = commands.begin();
|
|
|
|
it2 != commands.end(); ++it2)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!it2->visited && it->to == it2->from &&
|
|
|
|
enable(it2, from) && !it2->importer) {
|
2000-08-30 03:40:51 +00:00
|
|
|
Q.push(it2);
|
2000-11-06 11:20:22 +00:00
|
|
|
it2->visited = true;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
|
|
|
|
bool Converter::IsReachable(string const & from, string const & to)
|
2000-10-16 13:27:56 +00:00
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
if (from == to)
|
2000-10-16 13:27:56 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
queue< vector<Command>::iterator > Q;
|
|
|
|
for (vector<Command>::iterator it = commands.begin();
|
|
|
|
it != commands.end(); ++it)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->from->name == from && enable(it, from)) {
|
2000-10-16 13:27:56 +00:00
|
|
|
Q.push(it);
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = true;
|
2000-10-16 13:27:56 +00:00
|
|
|
} else
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = false;
|
2000-10-16 13:27:56 +00:00
|
|
|
|
|
|
|
while (!Q.empty()) {
|
|
|
|
vector<Command>::iterator it = Q.front();
|
|
|
|
Q.pop();
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->to->name == to)
|
2000-10-16 13:27:56 +00:00
|
|
|
return true;
|
|
|
|
for (vector<Command>::iterator it2 = commands.begin();
|
|
|
|
it2 != commands.end(); ++it2)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!it2->visited && it->to == it2->from &&
|
2000-10-23 12:16:05 +00:00
|
|
|
enable(it2, from)) {
|
2000-10-16 13:27:56 +00:00
|
|
|
Q.push(it2);
|
2000-11-06 11:20:22 +00:00
|
|
|
it2->visited = true;
|
2000-10-16 13:27:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
bool Converter::Convert(Buffer const * buffer,
|
|
|
|
string const & from_file, string const & to_file_base,
|
|
|
|
string const & from_format, string const & to_format,
|
|
|
|
string const & using_format, string & to_file)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
to_file = ChangeExtension(to_file_base,
|
2000-11-06 11:20:22 +00:00
|
|
|
formats.Extension(to_format));
|
2000-09-11 15:42:17 +00:00
|
|
|
|
2000-09-05 13:16:19 +00:00
|
|
|
if (from_format == to_format)
|
|
|
|
if (from_file != to_file)
|
2000-09-26 13:54:57 +00:00
|
|
|
return lyx::rename(from_file, to_file);
|
2000-09-05 13:16:19 +00:00
|
|
|
else
|
|
|
|
return true;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
queue< vector<Command>::iterator > Q;
|
|
|
|
for (vector<Command>::iterator it = commands.begin();
|
|
|
|
it != commands.end(); ++it)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->from->name == from_format && enable(it, from_format)) {
|
2000-08-30 03:40:51 +00:00
|
|
|
Q.push(it);
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = true;
|
|
|
|
it->previous = commands.end();
|
2000-08-30 03:40:51 +00:00
|
|
|
} else
|
2000-11-06 11:20:22 +00:00
|
|
|
it->visited = false;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
if (Q.empty()) {
|
|
|
|
WriteAlert(_("Can not convert file"),
|
|
|
|
("Unknown format ") + from_format);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool found = false;
|
|
|
|
vector<Command>::iterator it;
|
|
|
|
while (!Q.empty()) {
|
|
|
|
it = Q.front();
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->to->name == to_format &&
|
|
|
|
(using_format.empty() || using_format == it->from->name)) {
|
2000-08-30 03:40:51 +00:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Q.pop();
|
|
|
|
for (vector<Command>::iterator it2 = commands.begin();
|
|
|
|
it2 != commands.end(); ++it2)
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!it2->visited && it->to == it2->from &&
|
2000-10-23 12:16:05 +00:00
|
|
|
enable(it2, from_format)) {
|
2000-08-30 03:40:51 +00:00
|
|
|
Q.push(it2);
|
2000-11-06 11:20:22 +00:00
|
|
|
it2->visited = true;
|
|
|
|
it2->previous = it;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
WriteAlert(_("Can not convert file"),
|
|
|
|
_("No information for converting from ")
|
2000-11-06 11:20:22 +00:00
|
|
|
+ formats.PrettyName(from_format) + _(" to ")
|
|
|
|
+ formats.PrettyName(to_format));
|
2000-08-30 03:40:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2000-09-05 13:16:19 +00:00
|
|
|
vector< vector<Command>::iterator > S;
|
2000-08-30 03:40:51 +00:00
|
|
|
while (it != commands.end()) {
|
2000-09-05 13:16:19 +00:00
|
|
|
S.push_back(it);
|
2000-11-06 11:20:22 +00:00
|
|
|
it = it->previous;
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
|
|
|
|
2000-09-11 15:42:17 +00:00
|
|
|
string path = OnlyPath(from_file);
|
|
|
|
Path p(path);
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-09-11 15:42:17 +00:00
|
|
|
bool run_latex = false;
|
|
|
|
string from_base = ChangeExtension(from_file, "");
|
|
|
|
string to_base = ChangeExtension(to_file, "");
|
|
|
|
string infile;
|
|
|
|
string outfile = from_file;
|
2000-09-05 13:16:19 +00:00
|
|
|
for (vector< vector<Command>::iterator >::reverse_iterator rit =
|
|
|
|
S.rbegin(); rit != S.rend(); ++rit) {
|
|
|
|
it = *rit;
|
2000-11-06 11:20:22 +00:00
|
|
|
bool dummy = it->to->dummy() && it->to->name != "program";
|
|
|
|
if (!dummy)
|
|
|
|
lyxerr << "Converting from "
|
|
|
|
<< it->from->name << " to " << it->to->name << endl;
|
2000-09-11 15:42:17 +00:00
|
|
|
infile = outfile;
|
2000-11-06 11:20:22 +00:00
|
|
|
outfile = it->result_dir.empty()
|
|
|
|
? ChangeExtension(from_file, it->to->extension)
|
|
|
|
: AddName(subst(it->result_dir,
|
2000-09-11 15:42:17 +00:00
|
|
|
"$$BaseName", from_base),
|
2000-11-06 11:20:22 +00:00
|
|
|
subst(it->result_file,
|
2000-09-11 15:42:17 +00:00
|
|
|
"$$BaseName", OnlyFilename(from_base)));
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->latex) {
|
|
|
|
lyxrc.pdf_mode = it->to->name == "pdf";
|
|
|
|
lyxerr << "Running " << it->command << endl;
|
2000-09-11 15:42:17 +00:00
|
|
|
run_latex = true;
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!runLaTeX(buffer, it->command))
|
2000-08-30 03:40:51 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->need_aux && !run_latex
|
2000-09-11 15:42:17 +00:00
|
|
|
&& !latex_command.empty()) {
|
|
|
|
lyxerr << "Running " << latex_command
|
|
|
|
<< " to update aux file"<< endl;
|
|
|
|
runLaTeX(buffer, latex_command);
|
|
|
|
}
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
string infile2 = (it->original_dir)
|
2000-09-11 15:42:17 +00:00
|
|
|
? infile : MakeRelPath(infile, path);
|
2000-11-06 11:20:22 +00:00
|
|
|
string outfile2 = (it->original_dir)
|
2000-09-11 15:42:17 +00:00
|
|
|
? outfile : MakeRelPath(outfile, path);
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
string command = it->command;
|
2000-10-02 16:44:47 +00:00
|
|
|
command = subst(command, "$$FName", QuoteName(infile2));
|
|
|
|
command = subst(command, "$$BaseName", QuoteName(from_base));
|
|
|
|
command = subst(command, "$$OutName", QuoteName(outfile2));
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!it->parselog.empty())
|
2000-10-02 16:44:47 +00:00
|
|
|
command += " 2> " + QuoteName(infile2 + ".out");
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->from->name == "dvi" && it->to->name == "ps")
|
2000-09-05 13:16:19 +00:00
|
|
|
command = add_options(command,
|
|
|
|
dvips_options(buffer));
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
lyxerr << "Calling " << command << endl;
|
2000-10-23 12:16:05 +00:00
|
|
|
if (buffer)
|
|
|
|
ShowMessage(buffer, _("Executing command:"), command);
|
2000-11-06 11:20:22 +00:00
|
|
|
|
|
|
|
Systemcalls::Starttype type = (dummy)
|
|
|
|
? Systemcalls::SystemDontWait : Systemcalls::System;
|
2000-08-30 03:40:51 +00:00
|
|
|
Systemcalls one;
|
|
|
|
int res;
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->original_dir && buffer) {
|
2000-08-30 03:40:51 +00:00
|
|
|
Path p(buffer->filepath);
|
2000-11-06 11:20:22 +00:00
|
|
|
res = one.startscript(type, command);
|
2000-08-30 03:40:51 +00:00
|
|
|
} else
|
2000-11-06 11:20:22 +00:00
|
|
|
res = one.startscript(type, command);
|
2000-10-02 16:44:47 +00:00
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!it->parselog.empty()) {
|
2000-10-02 16:44:47 +00:00
|
|
|
string const logfile = infile2 + ".log";
|
2000-11-06 11:20:22 +00:00
|
|
|
string const command2 = it->parselog +
|
2000-10-02 16:44:47 +00:00
|
|
|
" < " + QuoteName(infile2 + ".out") +
|
|
|
|
" > " + QuoteName(logfile);
|
|
|
|
one.startscript(Systemcalls::System, command2);
|
|
|
|
if (!scanLog(buffer, command, logfile))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
if (res) {
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->to->name == "program")
|
2000-10-02 16:44:47 +00:00
|
|
|
WriteAlert(_("There were errors during the Build process."),
|
|
|
|
_("You should try to fix them."));
|
|
|
|
else
|
|
|
|
WriteAlert(_("Can not convert file"),
|
|
|
|
"Error while executing",
|
|
|
|
command.substr(0, 50));
|
2000-08-30 03:40:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
if (it->to->dummy())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
if (!it->result_dir.empty()) {
|
|
|
|
to_file = AddName(subst(it->result_dir,
|
2000-10-23 12:16:05 +00:00
|
|
|
"$$BaseName", to_base),
|
2000-11-06 11:20:22 +00:00
|
|
|
subst(it->result_file,
|
2000-10-23 12:16:05 +00:00
|
|
|
"$$BaseName", OnlyFilename(to_base)));
|
2000-09-11 15:42:17 +00:00
|
|
|
if (from_base != to_base) {
|
2000-11-06 11:20:22 +00:00
|
|
|
string from = subst(it->result_dir,
|
2000-09-11 15:42:17 +00:00
|
|
|
"$$BaseName", from_base);
|
2000-11-06 11:20:22 +00:00
|
|
|
string to = subst(it->result_dir,
|
2000-09-11 15:42:17 +00:00
|
|
|
"$$BaseName", to_base);
|
2000-11-06 11:20:22 +00:00
|
|
|
if (!lyx::rename(from, to)) {
|
|
|
|
WriteAlert(_("Error while trying to move directory:"),
|
|
|
|
from, ("to ") + to);
|
|
|
|
return false;
|
|
|
|
}
|
2000-09-11 15:42:17 +00:00
|
|
|
}
|
2000-11-06 11:20:22 +00:00
|
|
|
} else if (outfile != to_file) {
|
|
|
|
bool moved = (it->latex)
|
|
|
|
? lyx::copy(outfile, to_file)
|
|
|
|
: lyx::rename(outfile, to_file);
|
|
|
|
if (!moved) {
|
|
|
|
WriteAlert(_("Error while trying to move file:"),
|
|
|
|
outfile, _("to ") + to_file);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
bool Converter::Convert(Buffer const * buffer,
|
|
|
|
string const & from_file, string const & to_file_base,
|
|
|
|
string const & from_format, string const & to_format,
|
|
|
|
string const & using_format)
|
|
|
|
{
|
|
|
|
string to_file;
|
|
|
|
return Convert(buffer, from_file, to_file_base, from_format, to_format,
|
|
|
|
using_format, to_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-30 04:38:32 +00:00
|
|
|
string const Converter::SplitFormat(string const & str, string & format)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-11-08 09:39:46 +00:00
|
|
|
string const using_format = split(str, format, ':');
|
2000-08-30 03:40:51 +00:00
|
|
|
if (format.empty())
|
|
|
|
format = "dvi";
|
|
|
|
return using_format;
|
|
|
|
}
|
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
|
2000-10-12 15:17:42 +00:00
|
|
|
bool Converter::scanLog(Buffer const * buffer, string const & command,
|
2000-10-02 16:44:47 +00:00
|
|
|
string const & filename)
|
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
if (!buffer)
|
|
|
|
return false;
|
|
|
|
|
2000-10-02 16:44:47 +00:00
|
|
|
BufferView * bv = buffer->getUser();
|
|
|
|
bool need_redraw = false;
|
|
|
|
if (bv) {
|
|
|
|
ProhibitInput(bv);
|
|
|
|
// Remove all error insets
|
|
|
|
need_redraw = bv->removeAutoInsets();
|
|
|
|
}
|
|
|
|
|
|
|
|
LaTeX latex("", filename, "");
|
|
|
|
TeXErrors terr;
|
|
|
|
int result = latex.scanLogFile(terr);
|
|
|
|
if (bv) {
|
|
|
|
if ((result & LaTeX::ERRORS)) {
|
|
|
|
// Insert all errors as errors boxes
|
|
|
|
bv->insertErrors(terr);
|
|
|
|
need_redraw = true;
|
|
|
|
}
|
|
|
|
if (need_redraw) {
|
|
|
|
bv->redraw();
|
|
|
|
bv->fitCursor(bv->text);
|
|
|
|
}
|
|
|
|
AllowInput(bv);
|
|
|
|
}
|
2000-10-23 12:16:05 +00:00
|
|
|
|
2000-10-02 16:44:47 +00:00
|
|
|
if ((result & LaTeX::ERRORS)) {
|
|
|
|
int num_errors = latex.getNumErrors();
|
|
|
|
string s;
|
|
|
|
string t;
|
|
|
|
if (num_errors == 1) {
|
|
|
|
s = _("One error detected");
|
|
|
|
t = _("You should try to fix it.");
|
|
|
|
} else {
|
|
|
|
s = tostr(num_errors);
|
|
|
|
s += _(" errors detected.");
|
|
|
|
t = _("You should try to fix them.");
|
|
|
|
}
|
|
|
|
string head;
|
|
|
|
split(command, head, ' ');
|
|
|
|
WriteAlert(_("There were errors during running of ") + head,
|
|
|
|
s, t);
|
|
|
|
return false;
|
2000-10-23 12:16:05 +00:00
|
|
|
} else if (result & LaTeX::NO_OUTPUT) {
|
|
|
|
string const s = _("The operation resulted in");
|
|
|
|
string const t = _("an empty file.");
|
|
|
|
WriteAlert(_("Resulting file is empty"), s, t);
|
|
|
|
return false;
|
2000-10-02 16:44:47 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2000-08-30 04:38:32 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
|
2000-10-12 15:17:42 +00:00
|
|
|
bool Converter::runLaTeX(Buffer const * buffer, string const & command)
|
2000-08-30 03:40:51 +00:00
|
|
|
{
|
2000-10-23 12:16:05 +00:00
|
|
|
if (!buffer)
|
|
|
|
return false;
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
BufferView * bv = buffer->getUser();
|
|
|
|
string name = buffer->getLatexName();
|
2000-10-02 04:21:44 +00:00
|
|
|
bool need_redraw = false;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-02 04:21:44 +00:00
|
|
|
if (bv) {
|
|
|
|
ProhibitInput(bv);
|
|
|
|
bv->owner()->getMiniBuffer()->Set(_("Running LaTeX..."));
|
|
|
|
// Remove all error insets
|
|
|
|
need_redraw = bv->removeAutoInsets();
|
|
|
|
}
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
// do the LaTex run(s)
|
|
|
|
TeXErrors terr;
|
|
|
|
LaTeX latex(command, name, buffer->filepath);
|
|
|
|
int result = latex.run(terr,
|
2000-10-02 04:21:44 +00:00
|
|
|
bv ? bv->owner()->getMiniBuffer() : 0);
|
|
|
|
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-02 04:21:44 +00:00
|
|
|
if (bv) {
|
|
|
|
if ((result & LaTeX::ERRORS)) {
|
|
|
|
// Insert all errors as errors boxes
|
|
|
|
bv->insertErrors(terr);
|
|
|
|
need_redraw = true;
|
|
|
|
}
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-02 04:21:44 +00:00
|
|
|
// if we removed error insets before we ran LaTeX or if we inserted
|
|
|
|
// error insets after we ran LaTeX this must be run:
|
|
|
|
if (need_redraw) {
|
|
|
|
bv->redraw();
|
|
|
|
bv->fitCursor(bv->text);
|
|
|
|
}
|
|
|
|
}
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
// check return value from latex.run().
|
|
|
|
if ((result & LaTeX::NO_LOGFILE)) {
|
|
|
|
WriteAlert(_("LaTeX did not work!"),
|
|
|
|
_("Missing log file:"), name);
|
|
|
|
} else if ((result & LaTeX::ERRORS)) {
|
|
|
|
int num_errors = latex.getNumErrors();
|
|
|
|
string s;
|
|
|
|
string t;
|
|
|
|
if (num_errors == 1) {
|
|
|
|
s = _("One error detected");
|
|
|
|
t = _("You should try to fix it.");
|
|
|
|
} else {
|
|
|
|
s = tostr(num_errors);
|
|
|
|
s += _(" errors detected.");
|
|
|
|
t = _("You should try to fix them.");
|
|
|
|
}
|
|
|
|
WriteAlert(_("There were errors during the LaTeX run."),
|
|
|
|
s, t);
|
2000-10-23 12:16:05 +00:00
|
|
|
} else if (result & LaTeX::NO_OUTPUT) {
|
|
|
|
string const s = _("The operation resulted in");
|
|
|
|
string const t = _("an empty file.");
|
|
|
|
WriteAlert(_("Resulting file is empty"), s, t);
|
2000-08-30 03:40:51 +00:00
|
|
|
}
|
2000-10-02 04:21:44 +00:00
|
|
|
|
|
|
|
if (bv)
|
|
|
|
AllowInput(bv);
|
2000-08-30 03:40:51 +00:00
|
|
|
|
2000-10-16 13:27:56 +00:00
|
|
|
int const ERROR_MASK =
|
|
|
|
LaTeX::NO_LOGFILE |
|
|
|
|
LaTeX::ERRORS |
|
|
|
|
LaTeX::NO_OUTPUT;
|
|
|
|
|
|
|
|
return (result & ERROR_MASK) == 0;
|
2000-08-30 03:40:51 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2000-09-05 13:16:19 +00:00
|
|
|
|
2000-09-14 17:53:12 +00:00
|
|
|
string const Converter::dvi_papersize(Buffer const * buffer)
|
2000-09-05 13:16:19 +00:00
|
|
|
{
|
|
|
|
char real_papersize = buffer->params.papersize;
|
|
|
|
if (real_papersize == BufferParams::PAPER_DEFAULT)
|
|
|
|
real_papersize = lyxrc.default_papersize;
|
|
|
|
|
|
|
|
switch (real_papersize) {
|
|
|
|
case BufferParams::PAPER_A3PAPER:
|
|
|
|
return "a3";
|
|
|
|
case BufferParams::PAPER_A4PAPER:
|
|
|
|
return "a4";
|
|
|
|
case BufferParams::PAPER_A5PAPER:
|
|
|
|
return "a5";
|
|
|
|
case BufferParams::PAPER_B5PAPER:
|
|
|
|
return "b5";
|
|
|
|
case BufferParams::PAPER_EXECUTIVEPAPER:
|
|
|
|
return "foolscap";
|
|
|
|
case BufferParams::PAPER_LEGALPAPER:
|
|
|
|
return "legal";
|
|
|
|
case BufferParams::PAPER_USLETTER:
|
|
|
|
default:
|
|
|
|
return "us";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-14 17:53:12 +00:00
|
|
|
string const Converter::dvips_options(Buffer const * buffer)
|
2000-09-05 13:16:19 +00:00
|
|
|
{
|
|
|
|
string result;
|
2000-10-23 12:16:05 +00:00
|
|
|
if (!buffer)
|
|
|
|
return result;
|
|
|
|
|
2000-09-05 13:16:19 +00:00
|
|
|
if (buffer->params.use_geometry
|
|
|
|
&& buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
|
|
|
|
&& !lyxrc.print_paper_dimension_flag.empty()
|
|
|
|
&& !buffer->params.paperwidth.empty()
|
|
|
|
&& !buffer->params.paperheight.empty()) {
|
|
|
|
// using a custom papersize
|
|
|
|
result = lyxrc.print_paper_dimension_flag;
|
|
|
|
result += ' ' + buffer->params.paperwidth;
|
|
|
|
result += ',' + buffer->params.paperheight;
|
|
|
|
} else {
|
|
|
|
string paper_option = dvi_papersize(buffer);
|
2000-09-11 15:42:17 +00:00
|
|
|
if (paper_option == "us")
|
|
|
|
paper_option = "letter";
|
2000-09-05 13:16:19 +00:00
|
|
|
if (paper_option != "letter" ||
|
|
|
|
buffer->params.orientation != BufferParams::ORIENTATION_LANDSCAPE) {
|
|
|
|
// dvips won't accept -t letter -t landscape. In all other
|
|
|
|
// cases, include the paper size explicitly.
|
|
|
|
result = lyxrc.print_paper_flag;
|
|
|
|
result += ' ' + paper_option;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
|
|
|
|
result += ' ' + lyxrc.print_landscape_flag;
|
|
|
|
return result;
|
|
|
|
}
|
2000-10-16 13:27:56 +00:00
|
|
|
|
2000-10-23 12:16:05 +00:00
|
|
|
|
2000-10-16 13:27:56 +00:00
|
|
|
void Converter::init()
|
|
|
|
{
|
|
|
|
}
|
2000-11-06 11:20:22 +00:00
|
|
|
|
2000-11-08 09:39:46 +00:00
|
|
|
vector<Command> const Converter::GetAllCommands()
|
|
|
|
{
|
|
|
|
vector<Command> result;
|
|
|
|
for (vector<Command>::iterator it = commands.begin();
|
|
|
|
it != commands.end(); ++it)
|
|
|
|
result.push_back(*it);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-11-06 11:20:22 +00:00
|
|
|
/// The global instance
|
|
|
|
Formats formats;
|
|
|
|
|
|
|
|
// The global copy of the system lyxrc entries (everything except preferences)
|
|
|
|
Formats system_formats;
|