#include <fstream>
#include <iomanip>
#include <map>
+#include <stack>
+#include <list>
#include <cstdlib>
#include <cmath>
using std::map;
using std::max;
using std::set;
+using std::stack;
+using std::list;
// all these externs should eventually be removed.
extern BufferList bufferlist;
extern LyXAction lyxaction;
+namespace {
-static const int LYX_FORMAT = 218;
+const int LYX_FORMAT = 218;
+
+} // namespace anon
extern int tex_code_break_column;
// We'll remove this later. (Lgb)
-static string last_inset_read;
+namespace {
+
+string last_inset_read;
+
+} // anon
bool
#endif
)
{
+ bool the_end_read = false;
+#ifndef NO_PEXTRA_REALLY
#ifdef NEW_INSETS
// This is super temporary but is needed to get the compability
// mode for minipages work correctly together with new tabulars.
static int call_depth = 0;
++call_depth;
#endif
- bool the_end_read = false;
+ bool checkminipage = false;
+ static LyXParagraph * minipar = 0;
+ static LyXParagraph * parBeforeMinipage = 0;
+#endif
if (token[0] != '\\') {
for (string::const_iterator cit = token.begin();
- cit != token.end(); ++cit) {
+ cit != token.end(); ++cit)
+ {
par->InsertChar(pos, (*cit), font);
++pos;
}
+ checkminipage = true;
} else if (token == "\\i") {
Inset * inset = new InsetLatexAccent;
inset->Read(this, lex);
++pos;
} else {
#endif
- // BEGIN pextra_minipage compability
- // This should be removed in 1.3.x (Lgb)
-
- // This compability code is not perfect. In a couple
- // of rand cases it fails. When the minipage par is
- // the first par in the document, and when there are
- // none or only one regular paragraphs after the
- // minipage. Currently I am not investing any effort
- // in fixing those cases.
- static LyXParagraph * minipar = 0;
- //lyxerr << "Call depth: " << call_depth << endl;
- if (call_depth == 1) {
-
- if (minipar
- && par->params.pextraType() == LyXParagraph::PEXTRA_MINIPAGE) {
- lyxerr << "minipages in a row" << endl;
- if (par->params.pextraStartMinipage()) {
- lyxerr << "start new minipage" << endl;
- // minipages in a row
- par->previous()->next(0);
- par->previous(minipar->previous());
- minipar->previous()->next(par);
- minipar->previous(0);
-
- // Before we insert the list of
- // minipages into the inset we have
- // to clean up a bit.
- // This is not quite correct yet since
- // we do want to use some of these
- // parameters to set options in the
- // minipage inset.
- InsetMinipage::Position imp = static_cast<InsetMinipage::Position>(minipar->params.pextraAlignment());
- LyXParagraph * tmp = minipar;
- while (tmp) {
- tmp->params.pextraType(0);
- tmp->params.pextraWidth(string());
- tmp->params.pextraWidthp(string());
- tmp->params.pextraAlignment(0);
- tmp->params.pextraHfill(false);
- tmp->params.pextraStartMinipage(false);
- tmp = tmp->next();
- }
-
- InsetMinipage * mini = new InsetMinipage;
- mini->pos(imp);
- mini->inset->par = minipar;
- // Insert the minipage last in the
- // previous paragraph.
- par->previous()->InsertInset(par->previous()->size(), mini);
- minipar = par;
- } else {
- lyxerr << "new minipage par" << endl;
- //nothing to do just continue reading
- }
-
- } else if (minipar) {
- lyxerr << "last minipage par read" << endl;
- // The last paragraph read was not part of a
- // minipage but the par linked list is...
- // So we need to remove the last par from the
- // rest, insert the rest of the paragraphs into
- // a InsetMinipage, insert this minipage into
- // prevpar, append the current par to prevpar
- // and continue...
-
- LyXParagraph * lp = minipar;
- int pcount = 0;
- while (lp) {
- ++pcount;
- lp = lp->next();
- }
- lyxerr << "Minipar count: " << pcount << endl;
- lyxerr << "Par: " << (void*)par << endl;
- lyxerr << "Par->prev: " << (void*)par->previous() << endl;
-
- if (par->previous())
- par->previous()->next(0);
- par->previous(minipar->previous());
- minipar->previous()->next(par);
- minipar->previous(0);
-
- // Before we insert the list of
- // minipages into the inset we have
- // to clean up a bit.
- // This is not quite correct yet since we
- // do want to use some of these parameters
- // to set options in the minipage inset.
- InsetMinipage::Position imp = static_cast<InsetMinipage::Position>(minipar->params.pextraAlignment());
- LyXParagraph * tmp = minipar;
- while (tmp) {
- tmp->params.pextraType(0);
- tmp->params.pextraWidth(string());
- tmp->params.pextraWidthp(string());
- tmp->params.pextraAlignment(0);
- tmp->params.pextraHfill(false);
- tmp->params.pextraStartMinipage(false);
- tmp = tmp->next();
- }
-
- InsetMinipage * mini = new InsetMinipage;
- mini->pos(imp);
- mini->inset->par = minipar;
- par->previous()->InsertInset(par->previous()->size(), mini);
- minipar = 0;
- } else if (par->params.pextraType() == LyXParagraph::PEXTRA_MINIPAGE) {
-
- // par is the first paragraph in a minipage
- lyxerr << "begin minipage" << endl;
- minipar = par;
-
- }
- }
-
- // End of pextra_minipage compability
-
if (!return_par)
return_par = par;
else {
} else if (token == "\\added_space_bottom") {
lex.nextToken();
par->params.spaceBottom(VSpace(lex.GetString()));
+#ifndef NO_PEXTRA_REALLY
} else if (token == "\\pextra_type") {
lex.nextToken();
par->params.pextraType(lex.GetInteger());
} else if (token == "\\pextra_start_minipage") {
lex.nextToken();
par->params.pextraStartMinipage(lex.GetInteger());
+#endif
} else if (token == "\\labelwidthstring") {
lex.EatLine();
par->params.labelWidthString(lex.GetString());
inset->Read(this, lex);
par->InsertInset(pos, inset, font);
++pos;
+ // because of OLD_TABULAR_READ where tabulars have been
+ // one paragraph.
+ checkminipage = true;
} else if (token == "\\hfill") {
par->InsertChar(pos, LyXParagraph::META_HFILL, font);
++pos;
++pos;
} else if (token == "\\the_end") {
the_end_read = true;
+ minipar = parBeforeMinipage = 0;
} else {
// This should be insurance for the future: (Asger)
lex.printError("Unknown token `$$Token'. "
++pos;
}
}
+#ifndef NO_PEXTRA_REALLY
+ // now check if we have a minipage paragraph as at this
+ // point we already read all the necessary data!
+ // this cannot be done in layout because there we did
+ // not read yet the paragraph PEXTRA-params (Jug)
+ //
+ // BEGIN pextra_minipage compability
+ // This should be removed in 1.3.x (Lgb)
+
+ // This compability code is not perfect. In a couple
+ // of rand cases it fails. When the minipage par is
+ // the first par in the document, and when there are
+ // none or only one regular paragraphs after the
+ // minipage. Currently I am not investing any effort
+ // in fixing those cases.
+
+ //lyxerr << "Call depth: " << call_depth << endl;
+ if (checkminipage && (call_depth == 1)) {
+ checkminipage = false;
+ if (minipar && (minipar != par) &&
+ (par->params.pextraType()==LyXParagraph::PEXTRA_MINIPAGE))
+ {
+ lyxerr << "minipages in a row" << endl;
+ if (par->params.pextraStartMinipage()) {
+ lyxerr << "start new minipage" << endl;
+ // minipages in a row
+ par->previous()->next(0);
+ par->previous(0);
+
+ LyXParagraph * tmp = minipar;
+ while (tmp) {
+ tmp->params.pextraType(0);
+ tmp->params.pextraWidth(string());
+ tmp->params.pextraWidthp(string());
+ tmp->params.pextraAlignment(0);
+ tmp->params.pextraHfill(false);
+ tmp->params.pextraStartMinipage(false);
+ tmp = tmp->next();
+ }
+ // create a new paragraph to insert the
+ // minipages in the following case
+ if (par->params.pextraStartMinipage() &&
+ !par->params.pextraHfill())
+ {
+ LyXParagraph * p = new LyXParagraph;
+ p->layout = 0;
+ p->previous(parBeforeMinipage);
+ parBeforeMinipage->next(p);
+ p->next(0);
+ p->params.depth(parBeforeMinipage->params.depth());
+ parBeforeMinipage = p;
+ }
+ InsetMinipage * mini = new InsetMinipage;
+ mini->pos(static_cast<InsetMinipage::Position>(par->params.pextraAlignment()));
+ mini->width(par->params.pextraWidth());
+ mini->widthp(par->params.pextraWidthp());
+ mini->inset->par = par;
+ // Insert the minipage last in the
+ // previous paragraph.
+ if (par->params.pextraHfill()) {
+ parBeforeMinipage->InsertChar
+ (parBeforeMinipage->size(), LyXParagraph::META_HFILL);
+ }
+ parBeforeMinipage->InsertInset
+ (parBeforeMinipage->size(), mini);
+
+ minipar = par;
+ } else {
+ lyxerr << "new minipage par" << endl;
+ //nothing to do just continue reading
+ }
+
+ } else if (minipar && (minipar != par)) {
+ lyxerr << "last minipage par read" << endl;
+ // The last paragraph read was not part of a
+ // minipage but the par linked list is...
+ // So we need to remove the last par from the
+ // rest
+ if (par->previous())
+ par->previous()->next(0);
+ par->previous(parBeforeMinipage);
+ parBeforeMinipage->next(par);
+ LyXParagraph * tmp = minipar;
+ while (tmp) {
+ tmp->params.pextraType(0);
+ tmp->params.pextraWidth(string());
+ tmp->params.pextraWidthp(string());
+ tmp->params.pextraAlignment(0);
+ tmp->params.pextraHfill(false);
+ tmp->params.pextraStartMinipage(false);
+ tmp = tmp->next();
+ }
+ depth = parBeforeMinipage->params.depth();
+ minipar = parBeforeMinipage = 0;
+ } else if (!minipar &&
+ (par->params.pextraType() == LyXParagraph::PEXTRA_MINIPAGE))
+ {
+ // par is the first paragraph in a minipage
+ lyxerr << "begin minipage" << endl;
+ // To minimize problems for
+ // the users we will insert
+ // the first minipage in
+ // a sequence of minipages
+ // in its own paragraph.
+ LyXParagraph * p = new LyXParagraph;
+ p->layout = 0;
+ p->previous(par->previous());
+ p->next(0);
+ p->params.depth(depth);
+ par->params.depth(0);
+ depth = 0;
+ if (par->previous())
+ par->previous()->next(p);
+ par->previous(0);
+ parBeforeMinipage = p;
+ minipar = par;
+ if (!return_par || (return_par == par))
+ return_par = p;
+
+ InsetMinipage * mini = new InsetMinipage;
+ mini->pos(static_cast<InsetMinipage::Position>(minipar->params.pextraAlignment()));
+ mini->width(minipar->params.pextraWidth());
+ mini->widthp(minipar->params.pextraWidthp());
+ mini->inset->par = minipar;
+
+ // Insert the minipage last in the
+ // previous paragraph.
+ if (minipar->params.pextraHfill()) {
+ parBeforeMinipage->InsertChar
+ (parBeforeMinipage->size(),LyXParagraph::META_HFILL);
+ }
+ parBeforeMinipage->InsertInset
+ (parBeforeMinipage->size(), mini);
+ }
+ }
+ // End of pextra_minipage compability
+#endif
--call_depth;
return the_end_read;
}
void Buffer::sgmlOpenTag(ostream & os, int depth,
string const & latexname) const
{
- if (latexname != "!-- --")
+ if (!latexname.empty() && latexname != "!-- --")
os << string(depth, ' ') << "<" << latexname << ">\n";
}
void Buffer::sgmlCloseTag(ostream & os, int depth,
string const & latexname) const
{
- if (latexname != "!-- --")
+ if (!latexname.empty() && latexname != "!-- --")
os << string(depth, ' ') << "</" << latexname << ">\n";
}
void Buffer::makeLinuxDocFile(string const & fname, bool nice, bool body_only)
{
- LyXParagraph * par = paragraph;
-
- niceFile = nice; // this will be used by Insetincludes.
-
- string top_element = textclasslist.LatexnameOfClass(params.textclass);
- string environment_stack[10];
- string item_name;
-
- int depth = 0; // paragraph depth
-
ofstream ofs(fname.c_str());
if (!ofs) {
return;
}
+ niceFile = nice; // this will be used by included files.
+
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;
-
texrow.reset();
+ string top_element = textclasslist.LatexnameOfClass(params.textclass);
+
if (!body_only) {
string sgml_includedfiles=features.getIncludedFiles(fname);
<< " created this file. For more info see http://www.lyx.org/"
<< " -->\n";
+ int depth = 0; // paragraph depth
+ LyXParagraph * par = paragraph;
+ string item_name;
+ vector<string> environment_stack(5);
+
while (par) {
- int desc_on = 0; // description mode
LyXLayout const & style =
textclasslist.Style(params.textclass,
par->layout);
case LATEX_ENVIRONMENT:
case LATEX_ITEM_ENVIRONMENT:
if (depth == par->params.depth()
- && environment_stack[depth] != style.latexname()
- && !environment_stack[depth].empty()) {
-
+ && environment_stack[depth] != style.latexname()) {
sgmlCloseTag(ofs, depth,
environment_stack[depth]);
environment_stack[depth].erase();
}
if (environment_stack[depth] != style.latexname()) {
if (depth == 0) {
- string const temp = "p";
- sgmlOpenTag(ofs, depth, temp);
+ sgmlOpenTag(ofs, depth, "p");
}
+ sgmlOpenTag(ofs, depth, style.latexname());
+
+ if (environment_stack.size() == depth+1)
+ environment_stack.push_back("!-- --");
environment_stack[depth] = style.latexname();
- sgmlOpenTag(ofs, depth,
- environment_stack[depth]);
}
- if (style.latextype == LATEX_ENVIRONMENT) break;
- desc_on = (style.labeltype == LABEL_MANUAL);
+ if (style.latexparam() == "CDATA")
+ ofs << "<![CDATA[";
- if (desc_on)
+ if (style.latextype == LATEX_ENVIRONMENT) break;
+
+ if (style.labeltype == LABEL_MANUAL)
item_name = "tag";
else
item_name = "item";
#ifndef NEW_INSETS
do {
- SimpleLinuxDocOnePar(ofs, par, desc_on, depth);
+ SimpleLinuxDocOnePar(ofs, par, depth);
par = par->next_;
linuxDocHandleFootnote(ofs, par, depth);
}
while(par && par->IsDummy());
#else
- SimpleLinuxDocOnePar(ofs, par, desc_on, depth);
+ SimpleLinuxDocOnePar(ofs, par, depth);
- par = par->next();
+ par = par->next();
#endif
ofs << "\n";
// write closing SGML tags
switch (style.latextype) {
case LATEX_COMMAND:
+ break;
case LATEX_ENVIRONMENT:
case LATEX_ITEM_ENVIRONMENT:
+ if (style.latexparam() == "CDATA")
+ ofs << "]]>";
break;
default:
sgmlCloseTag(ofs, depth, style.latexname());
}
// Close open tags
- for (; depth > 0; --depth)
- sgmlCloseTag(ofs, depth, environment_stack[depth]);
-
- if (!environment_stack[depth].empty())
- sgmlCloseTag(ofs, depth, environment_stack[depth]);
+ for (int i=depth; i >= 0; --i)
+ sgmlCloseTag(ofs, depth, environment_stack[i]);
if (!body_only) {
ofs << "\n\n";
#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] << ">";
+// checks, if newcol chars should be put into this line
+// writes newline, if necessary.
+namespace {
- // add new tag
- sprintf(stack[++pos], "%s", tag.c_str());
+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
+ }
+}
- // push all tags
- for (int i = 0; i <= pos; ++i)
- os << "<" << stack[i] << ">";
+enum PAR_TAG {
+ NONE=0,
+ TT = 1,
+ SF = 2,
+ BF = 4,
+ IT = 8,
+ SL = 16,
+ EM = 32
+};
+
+
+string tag_name(PAR_TAG const & pt) {
+ switch (pt) {
+ case NONE: return "!-- --";
+ case TT: return "tt";
+ case SF: return "sf";
+ case BF: return "bf";
+ case IT: return "it";
+ case SL: return "sl";
+ case EM: return "em";
+ }
+ return "";
}
-void Buffer::pop_tag(ostream & os, string const & tag,
- int & pos, char stack[5][3])
+inline
+void operator|=(PAR_TAG & p1, PAR_TAG const & p2)
{
-#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] << ">";
+ p1 = static_cast<PAR_TAG>(p1 | p2);
+}
- // 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
+inline
+void reset(PAR_TAG & p1, PAR_TAG const & p2)
+{
+ p1 = static_cast<PAR_TAG>( p1 & ~p2);
}
+} // namespace anon
-// 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*/)
+// Handle internal paragraph parsing -- layout already processed.
+void Buffer::SimpleLinuxDocOnePar(ostream & os,
+ LyXParagraph * par, 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;
+ LyXFont font_old;
+ bool desc_on;
+ if (style.labeltype == LABEL_MANUAL) {
+ font_old = style.labelfont;
+ desc_on = true;
+ } else {
+ font_old = style.font;
+ desc_on = false;
+ }
+
+ LyXFont::FONT_FAMILY family_type = LyXFont::ROMAN_FAMILY;
+ LyXFont::FONT_SERIES series_type = LyXFont::MEDIUM_SERIES;
+ LyXFont::FONT_SHAPE shape_type = LyXFont::UP_SHAPE;
+ bool is_em = false;
-
+ stack < PAR_TAG > tag_state;
// parsing main loop
- for (LyXParagraph::size_type i = 0;
- i < par->size(); ++i) {
+ 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;
- }
+ PAR_TAG tag_close = NONE;
+ list < PAR_TAG > tag_open;
- LyXFont const font2 = par->getFont(params, i);
+ LyXFont const font = par->getFont(params, i);
- if (font1.family() != font2.family()) {
+ if (font_old.family() != font.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;
- }
+ case LyXFont::SANS_FAMILY:
+ tag_close |= SF;
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;
- }
+ case LyXFont::TYPEWRITER_FAMILY:
+ tag_close |= TT;
+ break;
+ default:
+ break;
+ }
+
+ family_type = font.family();
+
+ switch (family_type) {
+ case LyXFont::SANS_FAMILY:
+ tag_open.push_back(SF);
+ break;
+ case LyXFont::TYPEWRITER_FAMILY:
+ tag_open.push_back(TT);
+ break;
+ default:
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;
+ if (font_old.series() != font.series()) {
+ switch (series_type) {
+ case LyXFont::BOLD_SERIES:
+ tag_close |= BF;
+ break;
+ default:
+ break;
}
+
+ series_type = font.series();
+
+ switch (series_type) {
+ case LyXFont::BOLD_SERIES:
+ tag_open.push_back(BF);
+ break;
+ default:
+ break;
+ }
+
}
- // handle italic and slanted fonts
- if (font1.shape() != font2.shape()) {
+ if (font_old.shape() != font.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;
- }
+ case LyXFont::ITALIC_SHAPE:
+ tag_close |= IT;
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;
- }
+ case LyXFont::SLANTED_SHAPE:
+ tag_close |= SL;
+ break;
+ default:
+ break;
+ }
+
+ shape_type = font.shape();
+
+ switch (shape_type) {
+ case LyXFont::ITALIC_SHAPE:
+ tag_open.push_back(IT);
+ break;
+ case LyXFont::SLANTED_SHAPE:
+ tag_open.push_back(SL);
+ break;
+ default:
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 <em> tag
- if (font1.emph() != font2.emph()) {
- if (font2.emph() == LyXFont::ON) {
- push_tag(os, "em", stack_num, stack);
+ if (font_old.emph() != font.emph()) {
+ if (font.emph() == LyXFont::ON) {
+ tag_open.push_back(EM);
is_em = true;
- } else if (is_em) {
- pop_tag(os, "em", stack_num, stack);
+ }
+ else if (is_em) {
+ tag_close |= EM;
is_em = false;
}
}
- c = par->GetChar(i);
+ list < PAR_TAG > temp;
+ while(!tag_state.empty() && tag_close ) {
+ PAR_TAG k = tag_state.top();
+ tag_state.pop();
+ os << "</" << tag_name(k) << ">";
+ if (tag_close & k)
+ reset(tag_close,k);
+ else
+ temp.push_back(k);
+ }
+
+ for(list< PAR_TAG >::const_iterator j = temp.begin();
+ j != temp.end(); ++j) {
+ tag_state.push(*j);
+ os << "<" << tag_name(*j) << ">";
+ }
+
+ for(list< PAR_TAG >::const_iterator j = tag_open.begin();
+ j != tag_open.end(); ++j) {
+ tag_state.push(*j);
+ os << "<" << tag_name(*j) << ">";
+ }
+
+ char c = par->GetChar(i);
if (c == LyXParagraph::META_INSET) {
- inset = par->GetInset(i);
+ Inset * inset = par->GetInset(i);
inset->Linuxdoc(this, os);
+ font_old = font;
+ continue;
}
- if (font2.latex() == LyXFont::ON) {
+ if (font.latex() == LyXFont::ON || style.latexparam() == "CDATA") {
// "TeX"-Mode on == > SGML-Mode on.
if (c != '\0')
- os << c; // see LaTeX-Generation...
+ 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) {
+ && !style.free_spacing) {
+ // in freespacing mode, spaces are
+ // non-breaking characters
+ if (desc_on) {// if char is ' ' then...
+
++char_line_count;
linux_doc_line_break(os, char_line_count, 6);
os << "</tag>";
- desc_on = 2;
+ desc_on = false;
} else {
linux_doc_line_break(os, char_line_count, 1);
os << c;
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;
+ font_old = 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] << ">";
+ while (!tag_state.empty()) {
+ os << "</" << tag_name(tag_state.top()) << ">";
+ tag_state.pop();
}
// resets description flag correctly
- switch (desc_on){
- case 1:
+ if (desc_on) {
// <tag> not closed...
linux_doc_line_break(os, char_line_count, 6);
os << "</tag>";
- break;
- case 2:
- // fprintf(file, "</p>");
- break;
}
}
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)
{
+ ofstream ofs(fname.c_str());
+ if (!ofs) {
+ WriteAlert(_("LYX_ERROR:"), _("Cannot write file"), fname);
+ return;
+ }
+
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();
+ string top_element= textclasslist.LatexnameOfClass(params.textclass);
+
if (!only_body) {
string sgml_includedfiles=features.getIncludedFiles(fname);
ofs << "<!-- DocBook file was created by " << LYX_DOCVERSION
<< "\n See http://www.lyx.org/ for more information -->\n";
+ vector <string> environment_stack(10);
+ vector <string> environment_inner(10);
+ vector <string> command_stack(10);
+
+ bool command_flag= false;
+ int command_depth= 0, command_base= 0, cmd_depth= 0;
+ int depth = 0; // paragraph depth
+
+ string item_name, command_name;
+
while (par) {
+ string sgmlparam, c_depth, c_params;
int desc_on = 0; // description mode
+
LyXLayout const & style =
textclasslist.Style(params.textclass,
par->layout);
command_name = style.latexname();
- tmps = style.latexparam();
- c_params = split(tmps, c_depth,'|');
+ sgmlparam = style.latexparam();
+ c_params = split(sgmlparam, c_depth,'|');
cmd_depth= lyx::atoi(c_depth);
if (command_flag) {
if (cmd_depth<command_base) {
- for (int j = command_depth;
- j >= command_base; --j)
- if (!command_stack[j].empty())
- sgmlCloseTag(ofs, j, command_stack[j]);
+ for (int j = command_depth; j >= command_base; --j)
+ 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]);
+ for (int j = command_depth; j >= cmd_depth; --j)
+ sgmlCloseTag(ofs, j, command_stack[j]);
command_depth= cmd_depth;
} else
command_depth= cmd_depth;
command_depth = command_base = cmd_depth;
command_flag = true;
}
+ if (command_stack.size() == command_depth +1)
+ command_stack.push_back("");
command_stack[command_depth]= command_name;
// treat label as a special case for
}
if (environment_stack[depth] != style.latexname()) {
+ if(environment_stack.size() == depth+1) {
+ environment_stack.push_back("!-- --");
+ environment_inner.push_back("!-- --");
+ }
environment_stack[depth] = style.latexname();
environment_inner[depth] = "!-- --";
sgmlOpenTag(ofs, depth + command_depth,
if (style.latextype == LATEX_ENVIRONMENT) {
if (!style.latexparam().empty()) {
if(style.latexparam() == "CDATA")
- ofs << "<![ CDATA [";
+ ofs << "<![CDATA[";
else
sgmlOpenTag(ofs, depth + command_depth,
style.latexparam());
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();
+ LyXFont font_old = style.labeltype == LABEL_MANUAL ? style.labelfont : style.font;
- // 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 << ' ';
+ os << string(depth,' ');
// parsing main loop
for (LyXParagraph::size_type i = 0;
i < par->size(); ++i) {
- LyXFont font2 = par->getFont(params, i);
+ LyXFont font = par->getFont(params, i);
// handle <emphasis> tag
- if (font1.emph() != font2.emph() && i) {
- if (font2.emph() == LyXFont::ON) {
+ if (font_old.emph() != font.emph()) {
+ if (font.emph() == LyXFont::ON) {
os << "<emphasis>";
emph_flag = true;
- }else {
+ }else if(i) {
os << "</emphasis>";
emph_flag = false;
}
else
os << tmp_out;
}
- } else if (font2.latex() == LyXFont::ON) {
+ } else if (font.latex() == LyXFont::ON) {
// "TeX"-Mode on ==> SGML-Mode on.
if (c != '\0')
os << c;
os << sgml_string;
}
}
- font1 = font2;
+ font_old = font;
}
- // 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 << "</emphasis>";
}
// resets description flag correctly
- switch (desc_on){
- case 1:
+ if (desc_on == 1) {
// <term> not closed...
os << "</term>";
- break;
}
os << '\n';
}