/* This file is part of
* ======================================================
*
* LyX, The Document Processor
*
* Copyright 1995 Matthias Ettrich
* Copyright 1995-2000 The LyX Team.
*
* This file is Copyright 1996-1999
* Lars Gullik Bjønnes
*
* ======================================================
*/
#include
#include
#include
#include
";
}
sgmlOpenTag(ofs, depth, style.latexname());
break;
case LATEX_COMMAND:
if (depth!= 0)
LinuxDocError(par, 0,
_("Error : Wrong depth for"
" LatexType Command.\n"));
if (!environment_stack[depth].empty()){
sgmlCloseTag(ofs, depth,
environment_stack[depth]);
ofs << "";
}
environment_stack[depth].erase();
sgmlOpenTag(ofs, depth, style.latexname());
break;
case LATEX_ENVIRONMENT:
case LATEX_ITEM_ENVIRONMENT:
if (depth == par->params.depth()
&& environment_stack[depth] != style.latexname()
&& !environment_stack[depth].empty()) {
sgmlCloseTag(ofs, depth,
environment_stack[depth]);
environment_stack[depth].erase();
}
if (depth < par->params.depth()) {
depth = par->params.depth();
environment_stack[depth].erase();
}
if (environment_stack[depth] != style.latexname()) {
if (depth == 0) {
string const temp = "p";
sgmlOpenTag(ofs, depth, temp);
}
environment_stack[depth] = style.latexname();
sgmlOpenTag(ofs, depth,
environment_stack[depth]);
}
if (style.latextype == LATEX_ENVIRONMENT) break;
desc_on = (style.labeltype == LABEL_MANUAL);
if (desc_on)
item_name = "tag";
else
item_name = "item";
sgmlOpenTag(ofs, depth + 1, item_name);
break;
default:
sgmlOpenTag(ofs, depth, style.latexname());
break;
}
#ifndef NEW_INSETS
do {
SimpleLinuxDocOnePar(ofs, par, desc_on, depth);
par = par->next_;
linuxDocHandleFootnote(ofs, par, depth);
}
while(par && par->IsDummy());
#else
SimpleLinuxDocOnePar(ofs, par, desc_on, depth);
par = par->next();
#endif
ofs << "\n";
// write closing SGML tags
switch (style.latextype) {
case LATEX_COMMAND:
case LATEX_ENVIRONMENT:
case LATEX_ITEM_ENVIRONMENT:
break;
default:
sgmlCloseTag(ofs, depth, style.latexname());
break;
}
}
// Close open tags
for (; depth > 0; --depth)
sgmlCloseTag(ofs, depth, environment_stack[depth]);
if (!environment_stack[depth].empty())
sgmlCloseTag(ofs, depth, environment_stack[depth]);
if (!body_only) {
ofs << "\n\n";
sgmlCloseTag(ofs, 0, top_element);
}
ofs.close();
// How to check for successful close
}
#ifndef NEW_INSETS
void Buffer::linuxDocHandleFootnote(ostream & os, LyXParagraph * & par,
int depth)
{
string const tag = "footnote";
while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
sgmlOpenTag(os, depth + 1, tag);
SimpleLinuxDocOnePar(os, par, 0, depth + 1);
sgmlCloseTag(os, depth + 1, tag);
par = par->next_;
}
}
#endif
void Buffer::DocBookHandleCaption(ostream & os, string & inner_tag,
int depth, int desc_on,
LyXParagraph * & par)
{
LyXParagraph * tpar = par;
#ifndef NEW_INSETS
while (tpar
&& (tpar->footnoteflag != LyXParagraph::NO_FOOTNOTE)
&& (tpar->layout != textclasslist.NumberOfLayout(params.textclass,
"Caption").second))
tpar = tpar->next_;
#else
while (tpar
&& (tpar->layout != textclasslist.NumberOfLayout(params.textclass,
"Caption").second))
tpar = tpar->next();
#endif
if (tpar &&
tpar->layout == textclasslist.NumberOfLayout(params.textclass,
"Caption").second) {
sgmlOpenTag(os, depth + 1, inner_tag);
string extra_par;
SimpleDocBookOnePar(os, extra_par, tpar,
desc_on, depth + 2);
sgmlCloseTag(os, depth+1, inner_tag);
if (!extra_par.empty())
os << extra_par;
}
}
#ifndef NEW_INSETS
void Buffer::DocBookHandleFootnote(ostream & os, LyXParagraph * & par,
int depth)
{
string tag, inner_tag;
string tmp_par, extra_par;
bool inner_span = false;
int desc_on = 4;
// Someone should give this enum a proper name (Lgb)
enum SOME_ENUM {
NO_ONE,
FOOTNOTE_LIKE,
MARGIN_LIKE,
FIG_LIKE,
TAB_LIKE
};
SOME_ENUM last = NO_ONE;
SOME_ENUM present = FOOTNOTE_LIKE;
while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
if (last == present) {
if (inner_span) {
if (!tmp_par.empty()) {
os << tmp_par;
tmp_par.erase();
sgmlCloseTag(os, depth + 1, inner_tag);
sgmlOpenTag(os, depth + 1, inner_tag);
}
} else {
os << "\n";
}
} else {
os << tmp_par;
if (!inner_tag.empty()) sgmlCloseTag(os, depth + 1,
inner_tag);
if (!extra_par.empty()) os << extra_par;
if (!tag.empty()) sgmlCloseTag(os, depth, tag);
extra_par.erase();
switch (par->footnotekind) {
case LyXParagraph::FOOTNOTE:
case LyXParagraph::ALGORITHM:
tag = "footnote";
inner_tag = "para";
present = FOOTNOTE_LIKE;
inner_span = true;
break;
case LyXParagraph::MARGIN:
tag = "sidebar";
inner_tag = "para";
present = MARGIN_LIKE;
inner_span = true;
break;
case LyXParagraph::FIG:
case LyXParagraph::WIDE_FIG:
tag = "figure";
inner_tag = "title";
present = FIG_LIKE;
inner_span = false;
break;
case LyXParagraph::TAB:
case LyXParagraph::WIDE_TAB:
tag = "table";
inner_tag = "title";
present = TAB_LIKE;
inner_span = false;
break;
}
sgmlOpenTag(os, depth, tag);
if ((present == TAB_LIKE) || (present == FIG_LIKE)) {
DocBookHandleCaption(os, inner_tag, depth,
desc_on, par);
inner_tag.erase();
} else {
sgmlOpenTag(os, depth + 1, inner_tag);
}
}
// ignore all caption here, we processed them above!!!
if (par->layout != textclasslist
.NumberOfLayout(params.textclass,
"Caption").second) {
std::ostringstream ost;
SimpleDocBookOnePar(ost, extra_par, par,
desc_on, depth + 2);
tmp_par += ost.str().c_str();
}
tmp_par = frontStrip(strip(tmp_par));
last = present;
par = par->next_;
}
os << tmp_par;
if (!inner_tag.empty()) sgmlCloseTag(os, depth + 1, inner_tag);
if (!extra_par.empty()) os << extra_par;
if (!tag.empty()) sgmlCloseTag(os, depth, tag);
}
#endif
// push a tag in a style stack
void Buffer::push_tag(ostream & os, string const & tag,
int & pos, char stack[5][3])
{
#ifdef WITH_WARNINGS
#warning Use a real stack! (Lgb)
#endif
// pop all previous tags
for (int j = pos; j >= 0; --j)
os << "" << stack[j] << ">";
// add new tag
sprintf(stack[++pos], "%s", tag.c_str());
// push all tags
for (int i = 0; i <= pos; ++i)
os << "<" << stack[i] << ">";
}
void Buffer::pop_tag(ostream & os, string const & tag,
int & pos, char stack[5][3])
{
#ifdef WITH_WARNINGS
#warning Use a real stack! (Lgb)
#endif
// Please, Lars, do not remove the global variable. I already
// had to reintroduce it twice! (JMarc)
// but...but... I'll remove it anyway. (well not quite) (Lgb)
#if 0
int j;
// pop all tags till specified one
for (j = pos; (j >= 0) && tag != stack[j]; --j)
os << "" << stack[j] << ">";
// closes the tag
os << "" << tag << ">";
// push all tags, but the specified one
for (j = j + 1; j <= pos; ++j) {
os << "<" << stack[j] << ">";
strcpy(stack[j - 1], stack[j]);
}
--pos;
#else
// pop all tags till specified one
int j = pos;
for (int j = pos; (j >= 0) && tag != stack[j]; --j)
os << "" << stack[j] << ">";
// closes the tag
os << "" << tag << ">";
// push all tags, but the specified one
for (int i = j + 1; i <= pos; ++i) {
os << "<" << stack[i] << ">";
strcpy(stack[i - 1], stack[i]);
}
--pos;
#endif
}
// Handle internal paragraph parsing -- layout already processed.
// checks, if newcol chars should be put into this line
// writes newline, if necessary.
static
void linux_doc_line_break(ostream & os, string::size_type & colcount,
string::size_type newcol)
{
colcount += newcol;
if (colcount > lyxrc.ascii_linelen) {
os << "\n";
colcount = newcol; // assume write after this call
}
}
void Buffer::SimpleLinuxDocOnePar(ostream & os, LyXParagraph * par,
int desc_on, int /*depth*/)
{
LyXFont font1;
char c;
Inset * inset;
LyXParagraph::size_type main_body;
int j;
LyXLayout const & style = textclasslist.Style(params.textclass,
par->GetLayout());
char family_type = 0; // family font flag
bool is_bold = false; // series font flag
char shape_type = 0; // shape font flag
bool is_em = false; // emphasis (italic) font flag
int stack_num = -1; // style stack position
// Can this be rewritten to use a std::stack, please. (Lgb)
char stack[5][3]; // style stack
string::size_type char_line_count = 5; // Heuristic choice ;-)
if (style.labeltype != LABEL_MANUAL)
main_body = 0;
else
main_body = par->BeginningOfMainBody();
// gets paragraph main font
if (main_body > 0)
font1 = style.labelfont;
else
font1 = style.font;
// parsing main loop
for (LyXParagraph::size_type i = 0;
i < par->size(); ++i) {
// handle quote tag
if (i == main_body
#ifndef NEW_INSETS
&& !par->IsDummy()
#endif
) {
if (main_body > 0)
font1 = style.font;
}
LyXFont const font2 = par->getFont(params, i);
if (font1.family() != font2.family()) {
switch (family_type) {
case 0:
if (font2.family() == LyXFont::TYPEWRITER_FAMILY) {
push_tag(os, "tt", stack_num, stack);
family_type = 1;
}
else if (font2.family() == LyXFont::SANS_FAMILY) {
push_tag(os, "sf", stack_num, stack);
family_type = 2;
}
break;
case 1:
pop_tag(os, "tt", stack_num, stack);
if (font2.family() == LyXFont::SANS_FAMILY) {
push_tag(os, "sf", stack_num, stack);
family_type = 2;
} else {
family_type = 0;
}
break;
case 2:
pop_tag(os, "sf", stack_num, stack);
if (font2.family() == LyXFont::TYPEWRITER_FAMILY) {
push_tag(os, "tt", stack_num, stack);
family_type = 1;
} else {
family_type = 0;
}
}
}
// handle bold face
if (font1.series() != font2.series()) {
if (font2.series() == LyXFont::BOLD_SERIES) {
push_tag(os, "bf", stack_num, stack);
is_bold = true;
} else if (is_bold) {
pop_tag(os, "bf", stack_num, stack);
is_bold = false;
}
}
// handle italic and slanted fonts
if (font1.shape() != font2.shape()) {
switch (shape_type) {
case 0:
if (font2.shape() == LyXFont::ITALIC_SHAPE) {
push_tag(os, "it", stack_num, stack);
shape_type = 1;
} else if (font2.shape() == LyXFont::SLANTED_SHAPE) {
push_tag(os, "sl", stack_num, stack);
shape_type = 2;
}
break;
case 1:
pop_tag(os, "it", stack_num, stack);
if (font2.shape() == LyXFont::SLANTED_SHAPE) {
push_tag(os, "sl", stack_num, stack);
shape_type = 2;
} else {
shape_type = 0;
}
break;
case 2:
pop_tag(os, "sl", stack_num, stack);
if (font2.shape() == LyXFont::ITALIC_SHAPE) {
push_tag(os, "it", stack_num, stack);
shape_type = 1;
} else {
shape_type = 0;
}
}
}
// handle tag
if (font1.emph() != font2.emph()) {
if (font2.emph() == LyXFont::ON) {
push_tag(os, "em", stack_num, stack);
is_em = true;
} else if (is_em) {
pop_tag(os, "em", stack_num, stack);
is_em = false;
}
}
c = par->GetChar(i);
if (c == LyXParagraph::META_INSET) {
inset = par->GetInset(i);
inset->Linuxdoc(this, os);
}
if (font2.latex() == LyXFont::ON) {
// "TeX"-Mode on == > SGML-Mode on.
if (c != '\0')
os << c; // see LaTeX-Generation...
++char_line_count;
} else {
string sgml_string;
if (par->linuxDocConvertChar(c, sgml_string)
&& !style.free_spacing) { // in freespacing
// mode, spaces are
// non-breaking characters
// char is ' '
if (desc_on == 1) {
++char_line_count;
linux_doc_line_break(os, char_line_count, 6);
os << "";
desc_on = 2;
} else {
linux_doc_line_break(os, char_line_count, 1);
os << c;
}
} else {
os << sgml_string;
char_line_count += sgml_string.length();
}
}
font1 = font2;
}
// needed if there is an optional argument but no contents
if (main_body > 0 && main_body == par->size()) {
font1 = style.font;
}
// pop all defined Styles
for (j = stack_num; j >= 0; --j) {
linux_doc_line_break(os,
char_line_count,
3 + strlen(stack[j]));
os << "" << stack[j] << ">";
}
// resets description flag correctly
switch (desc_on){
case 1:
// not closed...
linux_doc_line_break(os, char_line_count, 6);
os << "";
break;
case 2:
// fprintf(file, "");
break;
}
}
// Print an error message.
void Buffer::LinuxDocError(LyXParagraph * par, int pos,
string const & message)
{
// insert an error marker in text
InsetError * new_inset = new InsetError(message);
par->InsertInset(pos, new_inset);
}
// This constant defines the maximum number of
// environment layouts that can be nesteded.
// The same applies for command layouts.
// These values should be more than enough.
// José Matos (1999/07/22)
enum { MAX_NEST_LEVEL = 25};
void Buffer::makeDocBookFile(string const & fname, bool nice, bool only_body)
{
LyXParagraph * par = paragraph;
niceFile = nice; // this will be used by Insetincludes.
string top_element= textclasslist.LatexnameOfClass(params.textclass);
// Please use a real stack.
string environment_stack[MAX_NEST_LEVEL];
string environment_inner[MAX_NEST_LEVEL];
// Please use a real stack.
string command_stack[MAX_NEST_LEVEL];
bool command_flag= false;
int command_depth= 0, command_base= 0, cmd_depth= 0;
string item_name, command_name;
string c_depth, c_params, tmps;
int depth = 0; // paragraph depth
LyXTextClass const & tclass =
textclasslist.TextClass(params.textclass);
LaTeXFeatures features(params, tclass.numLayouts());
validate(features);
//if (nice)
tex_code_break_column = lyxrc.ascii_linelen;
//else
//tex_code_break_column = 0;
ofstream ofs(fname.c_str());
if (!ofs) {
WriteAlert(_("LYX_ERROR:"), _("Cannot write file"), fname);
return;
}
texrow.reset();
if (!only_body) {
string sgml_includedfiles=features.getIncludedFiles(fname);
ofs << "\n\n";
else
ofs << "\n [ " << params.preamble
<< sgml_includedfiles << " \n]>\n\n";
}
string top = top_element;
top += " lang=\"";
top += params.language->code();
top += "\"";
if (!params.options.empty()) {
top += " ";
top += params.options;
}
sgmlOpenTag(ofs, 0, top);
ofs << "\n";
while (par) {
int desc_on = 0; // description mode
LyXLayout const & style =
textclasslist.Style(params.textclass,
par->layout);
// environment tag closing
for (; depth > par->params.depth(); --depth) {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
sgmlCloseTag(ofs, command_depth + depth,
item_name);
if (environment_inner[depth] == "varlistentry")
sgmlCloseTag(ofs, depth+command_depth,
environment_inner[depth]);
}
sgmlCloseTag(ofs, depth + command_depth,
environment_stack[depth]);
environment_stack[depth].erase();
environment_inner[depth].erase();
}
if (depth == par->params.depth()
&& environment_stack[depth] != style.latexname()
&& !environment_stack[depth].empty()) {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
sgmlCloseTag(ofs, command_depth+depth,
item_name);
if (environment_inner[depth] == "varlistentry")
sgmlCloseTag(ofs,
depth + command_depth,
environment_inner[depth]);
}
sgmlCloseTag(ofs, depth + command_depth,
environment_stack[depth]);
environment_stack[depth].erase();
environment_inner[depth].erase();
}
// Write opening SGML tags.
switch (style.latextype) {
case LATEX_PARAGRAPH:
sgmlOpenTag(ofs, depth+command_depth, style.latexname());
break;
case LATEX_COMMAND:
if (depth!= 0)
LinuxDocError(par, 0,
_("Error : Wrong depth for "
"LatexType Command.\n"));
command_name = style.latexname();
tmps = style.latexparam();
c_params = split(tmps, c_depth,'|');
cmd_depth= lyx::atoi(c_depth);
if (command_flag) {
if (cmd_depth= command_base; --j)
if (!command_stack[j].empty())
sgmlCloseTag(ofs, j, command_stack[j]);
command_depth= command_base= cmd_depth;
} else if (cmd_depth <= command_depth) {
for (int j = command_depth;
j >= cmd_depth; --j)
if (!command_stack[j].empty())
sgmlCloseTag(ofs, j, command_stack[j]);
command_depth= cmd_depth;
} else
command_depth= cmd_depth;
} else {
command_depth = command_base = cmd_depth;
command_flag = true;
}
command_stack[command_depth]= command_name;
// treat label as a special case for
// more WYSIWYM handling.
if (par->GetChar(0) == LyXParagraph::META_INSET) {
Inset * inset = par->GetInset(0);
Inset::Code lyx_code = inset->LyxCode();
if (lyx_code == Inset::LABEL_CODE){
command_name += " id=\"";
command_name += (static_cast(inset))->getContents();
command_name += "\"";
desc_on = 3;
}
}
sgmlOpenTag(ofs, depth + command_depth, command_name);
if (c_params.empty())
item_name = "title";
else
item_name = c_params;
sgmlOpenTag(ofs, depth + 1 + command_depth, item_name);
break;
case LATEX_ENVIRONMENT:
case LATEX_ITEM_ENVIRONMENT:
if (depth < par->params.depth()) {
depth = par->params.depth();
environment_stack[depth].erase();
}
if (environment_stack[depth] != style.latexname()) {
environment_stack[depth] = style.latexname();
environment_inner[depth] = "!-- --";
sgmlOpenTag(ofs, depth + command_depth,
environment_stack[depth]);
} else {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
sgmlCloseTag(ofs,
command_depth + depth,
item_name);
if (environment_inner[depth] == "varlistentry")
sgmlCloseTag(ofs,
depth + command_depth,
environment_inner[depth]);
}
}
if (style.latextype == LATEX_ENVIRONMENT) {
if (!style.latexparam().empty()) {
if(style.latexparam() == "CDATA")
ofs << "next_;
DocBookHandleFootnote(ofs, par,
depth + 1 + command_depth);
} while(par && par->IsDummy());
#else
string extra_par;
SimpleDocBookOnePar(ofs, extra_par, par, desc_on,
depth + 1 + command_depth);
par = par->next();
#endif
string end_tag;
// write closing SGML tags
switch (style.latextype) {
case LATEX_COMMAND:
if (c_params.empty())
end_tag = "title";
else
end_tag = c_params;
sgmlCloseTag(ofs, depth + command_depth, end_tag);
break;
case LATEX_ENVIRONMENT:
if (!style.latexparam().empty()) {
if(style.latexparam() == "CDATA")
ofs << "]]>";
else
sgmlCloseTag(ofs, depth + command_depth,
style.latexparam());
}
break;
case LATEX_ITEM_ENVIRONMENT:
if (desc_on == 1) break;
end_tag= "para";
sgmlCloseTag(ofs, depth + 1 + command_depth, end_tag);
break;
case LATEX_PARAGRAPH:
sgmlCloseTag(ofs, depth + command_depth, style.latexname());
break;
default:
sgmlCloseTag(ofs, depth + command_depth, style.latexname());
break;
}
}
// Close open tags
for (; depth >= 0; --depth) {
if (!environment_stack[depth].empty()) {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
sgmlCloseTag(ofs, command_depth + depth,
item_name);
if (environment_inner[depth] == "varlistentry")
sgmlCloseTag(ofs, depth + command_depth,
environment_inner[depth]);
}
sgmlCloseTag(ofs, depth + command_depth,
environment_stack[depth]);
}
}
for (int j = command_depth; j >= command_base; --j)
if (!command_stack[j].empty())
sgmlCloseTag(ofs, j, command_stack[j]);
ofs << "\n\n";
sgmlCloseTag(ofs, 0, top_element);
ofs.close();
// How to check for successful close
}
void Buffer::SimpleDocBookOnePar(ostream & os, string & extra,
LyXParagraph * par, int & desc_on,
int depth) const
{
bool emph_flag = false;
LyXLayout const & style = textclasslist.Style(params.textclass,
par->GetLayout());
LyXParagraph::size_type main_body;
if (style.labeltype != LABEL_MANUAL)
main_body = 0;
else
main_body = par->BeginningOfMainBody();
// gets paragraph main font
LyXFont font1 = main_body > 0 ? style.labelfont : style.font;
int char_line_count = depth;
if (!style.free_spacing)
for (int j = 0; j < depth; ++j)
os << ' ';
// parsing main loop
for (LyXParagraph::size_type i = 0;
i < par->size(); ++i) {
LyXFont font2 = par->getFont(params, i);
// handle tag
if (font1.emph() != font2.emph() && i) {
if (font2.emph() == LyXFont::ON) {
os << "";
emph_flag = true;
}else {
os << "";
emph_flag = false;
}
}
char c = par->GetChar(i);
if (c == LyXParagraph::META_INSET) {
Inset * inset = par->GetInset(i);
std::ostringstream ost;
inset->DocBook(this, ost);
string tmp_out = ost.str().c_str();
//
// This code needs some explanation:
// Two insets are treated specially
// label if it is the first element in a command paragraph
// desc_on == 3
// graphics inside tables or figure floats can't go on
// title (the equivalente in latex for this case is caption
// and title should come first
// desc_on == 4
//
if (desc_on!= 3 || i!= 0) {
if (!tmp_out.empty() && tmp_out[0] == '@') {
if (desc_on == 4)
extra += frontStrip(tmp_out, '@');
else
os << frontStrip(tmp_out, '@');
}
else
os << tmp_out;
}
} else if (font2.latex() == LyXFont::ON) {
// "TeX"-Mode on ==> SGML-Mode on.
if (c != '\0')
os << c;
++char_line_count;
} else {
string sgml_string;
if (par->linuxDocConvertChar(c, sgml_string)
&& !style.free_spacing) { // in freespacing
// mode, spaces are
// non-breaking characters
// char is ' '
if (desc_on == 1) {
++char_line_count;
os << "\n";
desc_on = 2;
} else {
os << c;
}
} else {
os << sgml_string;
}
}
font1 = font2;
}
// needed if there is an optional argument but no contents
if (main_body > 0 && main_body == par->size()) {
font1 = style.font;
}
if (emph_flag) {
os << "";
}
// resets description flag correctly
switch (desc_on){
case 1:
// not closed...
os << "";
break;
}
os << '\n';
}
// This should be enabled when the Chktex class is implemented. (Asger)
// chktex should be run with these flags disabled: 3, 22, 25, 30, 38(?)
// Other flags: -wall -v0 -x
int Buffer::runChktex()
{
if (!users->text) return 0;
ProhibitInput(users);
// get LaTeX-Filename
string const name = getLatexName();
string path = OnlyPath(filename);
string const org_path = path;
if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
path = tmppath;
}
Path p(path); // path to LaTeX file
users->owner()->getMiniBuffer()->Set(_("Running chktex..."));
// Remove all error insets
bool const removedErrorInsets = users->removeAutoInsets();
// Generate the LaTeX file if neccessary
makeLaTeXFile(name, org_path, false);
TeXErrors terr;
Chktex chktex(lyxrc.chktex_command, name, filepath);
int res = chktex.run(terr); // run chktex
if (res == -1) {
WriteAlert(_("chktex did not work!"),
_("Could not run with file:"), name);
} else if (res > 0) {
// Insert all errors as errors boxes
users->insertErrors(terr);
}
// if we removed error insets before we ran chktex or if we inserted
// error insets after we ran chktex, this must be run:
if (removedErrorInsets || res){
users->redraw();
users->fitCursor(users->text);
}
AllowInput(users);
return res;
}
void Buffer::validate(LaTeXFeatures & features) const
{
LyXParagraph * par = paragraph;
LyXTextClass const & tclass =
textclasslist.TextClass(params.textclass);
// AMS Style is at document level
features.amsstyle = (params.use_amsmath ||
tclass.provides(LyXTextClass::amsmath));
while (par) {
// We don't use "lyxerr.debug" because of speed. (Asger)
if (lyxerr.debugging(Debug::LATEX))
lyxerr << "Paragraph: " << par << endl;
// Now just follow the list of paragraphs and run
// validate on each of them.
par->validate(features);
// and then the next paragraph
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
}
// the bullet shapes are buffer level not paragraph level
// so they are tested here
for (int i = 0; i < 4; ++i) {
if (params.user_defined_bullets[i] != ITEMIZE_DEFAULTS[i]) {
int const font = params.user_defined_bullets[i].getFont();
if (font == 0) {
int const c = params
.user_defined_bullets[i]
.getCharacter();
if (c == 16
|| c == 17
|| c == 25
|| c == 26
|| c == 31) {
features.latexsym = true;
}
} else if (font == 1) {
features.amssymb = true;
} else if ((font >= 2 && font <= 5)) {
features.pifont = true;
}
}
}
if (lyxerr.debugging(Debug::LATEX)) {
features.showStruct();
}
}
void Buffer::setPaperStuff()
{
params.papersize = BufferParams::PAPER_DEFAULT;
char const c1 = params.paperpackage;
if (c1 == BufferParams::PACKAGE_NONE) {
char const c2 = params.papersize2;
if (c2 == BufferParams::VM_PAPER_USLETTER)
params.papersize = BufferParams::PAPER_USLETTER;
else if (c2 == BufferParams::VM_PAPER_USLEGAL)
params.papersize = BufferParams::PAPER_LEGALPAPER;
else if (c2 == BufferParams::VM_PAPER_USEXECUTIVE)
params.papersize = BufferParams::PAPER_EXECUTIVEPAPER;
else if (c2 == BufferParams::VM_PAPER_A3)
params.papersize = BufferParams::PAPER_A3PAPER;
else if (c2 == BufferParams::VM_PAPER_A4)
params.papersize = BufferParams::PAPER_A4PAPER;
else if (c2 == BufferParams::VM_PAPER_A5)
params.papersize = BufferParams::PAPER_A5PAPER;
else if ((c2 == BufferParams::VM_PAPER_B3) || (c2 == BufferParams::VM_PAPER_B4) ||
(c2 == BufferParams::VM_PAPER_B5))
params.papersize = BufferParams::PAPER_B5PAPER;
} else if ((c1 == BufferParams::PACKAGE_A4) || (c1 == BufferParams::PACKAGE_A4WIDE) ||
(c1 == BufferParams::PACKAGE_WIDEMARGINSA4))
params.papersize = BufferParams::PAPER_A4PAPER;
}
// This function should be in Buffer because it's a buffer's property (ale)
string const Buffer::getIncludeonlyList(char delim)
{
string lst;
for (inset_iterator it = inset_iterator_begin();
it != inset_iterator_end(); ++it) {
if ((*it)->LyxCode() == Inset::INCLUDE_CODE) {
InsetInclude * insetinc =
static_cast(*it);
if (insetinc->isInclude()
&& insetinc->isNoLoad()) {
if (!lst.empty())
lst += delim;
lst += OnlyFilename(ChangeExtension(insetinc->getContents(), string()));
}
}
}
lyxerr.debug() << "Includeonly(" << lst << ')' << endl;
return lst;
}
vector const Buffer::getLabelList()
{
/// if this is a child document and the parent is already loaded
/// Use the parent's list instead [ale990407]
if (!params.parentname.empty()
&& bufferlist.exists(params.parentname)) {
Buffer * tmp = bufferlist.getBuffer(params.parentname);
if (tmp)
return tmp->getLabelList();
}
vector label_list;
for (inset_iterator it = inset_iterator_begin();
it != inset_iterator_end(); ++it) {
vector const l = (*it)->getLabelList();
label_list.insert(label_list.end(), l.begin(), l.end());
}
return label_list;
}
map > const Buffer::getTocList() const
{
#ifndef NEW_INSETS
int figs = 0;
int tables = 0;
int algs = 0;
#endif
map > l;
LyXParagraph * par = paragraph;
while (par) {
#ifndef NEW_INSETS
if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
if (textclasslist.Style(params.textclass,
par->GetLayout()).labeltype
== LABEL_SENSITIVE) {
TocItem tmp;
tmp.par = par;
tmp.depth = 0;
tmp.str = par->String(this, false);
switch (par->footnotekind) {
case LyXParagraph::FIG:
case LyXParagraph::WIDE_FIG:
{
tmp.str = tostr(++figs) + ". "
+ tmp.str;
map >::iterator it = l.find("LOF");
if (it == l.end()) {
vector vti;
vti.push_back(tmp);
l["LOF"] = vti;
} else {
it->second.push_back(tmp);
}
break;
}
case LyXParagraph::TAB:
case LyXParagraph::WIDE_TAB:
{
tmp.str = tostr(++tables) + ". "
+ tmp.str;
map >::iterator it = l.find("LOT");
if (it == l.end()) {
vector vti;
vti.push_back(tmp);
l["LOT"] = vti;
} else {
it->second.push_back(tmp);
}
break;
}
case LyXParagraph::ALGORITHM:
{
tmp.str = tostr(++algs) + ". "
+ tmp.str;
map >::iterator it = l.find("LOA");
if (it == l.end()) {
vector vti;
vti.push_back(tmp);
l["LOA"] = vti;
} else {
it->second.push_back(tmp);
}
break;
}
case LyXParagraph::FOOTNOTE:
case LyXParagraph::MARGIN:
break;
}
}
} else if (!par->IsDummy()) {
#endif
char const labeltype =
textclasslist.Style(params.textclass,
par->GetLayout()).labeltype;
if (labeltype >= LABEL_COUNTER_CHAPTER
&& labeltype <= LABEL_COUNTER_CHAPTER + params.tocdepth) {
// insert this into the table of contents
TocItem tmp;
tmp.par = par;
tmp.depth = max(0,
labeltype -
textclasslist.TextClass(params.textclass).maxcounter());
tmp.str = par->String(this, true);
map >::iterator it = l.find("TOC");
if (it == l.end()) {
vector vti;
vti.push_back(tmp);
l["TOC"] = vti;
} else {
it->second.push_back(tmp);
}
}
#ifdef NEW_INSETS
// For each paragrph, traverse its insets and look for
// FLOAT_CODE
LyXParagraph::inset_iterator it =
par->inset_iterator_begin();
LyXParagraph::inset_iterator end =
par->inset_iterator_end();
bool found;
LyXTextClassList::size_type cap;
tie(found, cap) = textclasslist
.NumberOfLayout(params.textclass, "Caption");
if (found) {
for (; it != end; ++it) {
if ((*it)->LyxCode() == Inset::FLOAT_CODE) {
InsetFloat * il =
static_cast(*it);
//lyxerr << "Found a float!" << endl;
string const type = il->type();
// Now find the caption in the float...
// We now tranverse the paragraphs of
// the inset...
LyXParagraph * tmp = il->inset->par;
while (tmp) {
if (tmp->layout == cap) {
TocItem ti;
ti.par = tmp;
ti.depth = 0;
ti.str = tmp->String(this, false);
map >::iterator it = l.find(type);
if (it == l.end()) {
vector vti;
vti.push_back(ti);
l[type] = vti;
} else {
it->second.push_back(ti);
}
}
tmp = tmp->next();
}
}
}
} else {
lyxerr << "caption not found" << endl;
}
#endif
#ifndef NEW_INSETS
}
par = par->next_;
#else
par = par->next();
#endif
}
return l;
}
// This is also a buffer property (ale)
vector > const Buffer::getBibkeyList()
{
/// if this is a child document and the parent is already loaded
/// Use the parent's list instead [ale990412]
if (!params.parentname.empty() && bufferlist.exists(params.parentname)) {
Buffer * tmp = bufferlist.getBuffer(params.parentname);
if (tmp)
return tmp->getBibkeyList();
}
vector > keys;
LyXParagraph * par = paragraph;
while (par) {
if (par->bibkey)
keys.push_back(pair(par->bibkey->getContents(),
par->String(this, false)));
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
}
// Might be either using bibtex or a child has bibliography
if (keys.empty()) {
for (inset_iterator it = inset_iterator_begin();
it != inset_iterator_end(); ++it) {
// Search for Bibtex or Include inset
if ((*it)->LyxCode() == Inset::BIBTEX_CODE) {
vector > tmp =
static_cast(*it)->getKeys(this);
keys.insert(keys.end(), tmp.begin(), tmp.end());
} else if ((*it)->LyxCode() == Inset::INCLUDE_CODE) {
vector > const tmp =
static_cast(*it)->getKeys();
keys.insert(keys.end(), tmp.begin(), tmp.end());
}
}
}
return keys;
}
bool Buffer::isDepClean(string const & name) const
{
DEPCLEAN * item = dep_clean;
while (item && item->master != name)
item = item->next;
if (!item) return true;
return item->clean;
}
void Buffer::markDepClean(string const & name)
{
if (!dep_clean) {
dep_clean = new DEPCLEAN;
dep_clean->clean = true;
dep_clean->master = name;
dep_clean->next = 0;
} else {
DEPCLEAN * item = dep_clean;
while (item && item->master != name)
item = item->next;
if (item) {
item->clean = true;
} else {
item = new DEPCLEAN;
item->clean = true;
item->master = name;
item->next = 0;
}
}
}
bool Buffer::Dispatch(string const & command)
{
// Split command string into command and argument
string cmd;
string line = frontStrip(command);
string const arg = strip(frontStrip(split(line, cmd, ' ')));
return Dispatch(lyxaction.LookupFunc(cmd), arg);
}
bool Buffer::Dispatch(int action, string const & argument)
{
bool dispatched = true;
switch (action) {
case LFUN_EXPORT:
Exporter::Export(this, argument, false);
break;
default:
dispatched = false;
}
return dispatched;
}
void Buffer::resize()
{
/// resize the BufferViews!
if (users)
users->resize();
}
void Buffer::resizeInsets(BufferView * bv)
{
/// then remove all LyXText in text-insets
LyXParagraph * par = paragraph;
#ifndef NEW_INSETS
for (; par; par = par->next_) {
par->resizeInsetsLyXText(bv);
}
#else
for (; par; par = par->next()) {
par->resizeInsetsLyXText(bv);
}
#endif
}
void Buffer::ChangeLanguage(Language const * from, Language const * to)
{
LyXParagraph * par = paragraph;
while (par) {
par->ChangeLanguage(params, from, to);
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
}
}
bool Buffer::isMultiLingual()
{
LyXParagraph * par = paragraph;
while (par) {
if (par->isMultiLingual(params))
return true;
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
}
return false;
}
Buffer::inset_iterator::inset_iterator(LyXParagraph * paragraph,
LyXParagraph::size_type pos)
: par(paragraph)
{
it = par->InsetIterator(pos);
if (it == par->inset_iterator_end()) {
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
SetParagraph();
}
}
void Buffer::inset_iterator::SetParagraph()
{
while (par) {
it = par->inset_iterator_begin();
if (it != par->inset_iterator_end())
return;
#ifndef NEW_INSETS
par = par->next_;
#else
par = par->next();
#endif
}
//it = 0;
// We maintain an invariant that whenever par = 0 then it = 0
}