2003-11-05 12:06:20 +00:00
|
|
|
|
/**
|
|
|
|
|
* \file output_docbook.C
|
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
|
*
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author Jos<EFBFBD> Matos
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include "output_docbook.h"
|
|
|
|
|
|
|
|
|
|
#include "buffer.h"
|
|
|
|
|
#include "bufferparams.h"
|
2003-11-25 17:23:36 +00:00
|
|
|
|
#include "counters.h"
|
2003-12-31 08:44:42 +00:00
|
|
|
|
#include "debug.h"
|
2003-11-25 17:23:36 +00:00
|
|
|
|
#include "lyxtext.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
#include "paragraph.h"
|
|
|
|
|
#include "paragraph_funcs.h"
|
|
|
|
|
#include "ParagraphParameters.h"
|
|
|
|
|
#include "sgml.h"
|
|
|
|
|
|
|
|
|
|
#include "insets/insetcommand.h"
|
|
|
|
|
|
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
|
#include "support/lyxlib.h"
|
2003-11-25 17:23:36 +00:00
|
|
|
|
#include "support/tostr.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
#include <stack>
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_LOCALE
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
using lyx::support::atoi;
|
|
|
|
|
using lyx::support::split;
|
2003-11-25 17:23:36 +00:00
|
|
|
|
using lyx::support::subst;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
using std::endl;
|
|
|
|
|
using std::ostream;
|
|
|
|
|
using std::stack;
|
|
|
|
|
using std::vector;
|
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void docbookParagraphs(Buffer const & buf,
|
|
|
|
|
ParagraphList const & paragraphs,
|
|
|
|
|
ostream & os,
|
|
|
|
|
OutputParams const & runparams)
|
|
|
|
|
{
|
|
|
|
|
vector<string> environment_stack(10);
|
|
|
|
|
vector<string> environment_inner(10);
|
|
|
|
|
vector<string> command_stack(10);
|
|
|
|
|
|
|
|
|
|
bool command_flag = false;
|
|
|
|
|
Paragraph::depth_type command_depth = 0;
|
|
|
|
|
Paragraph::depth_type command_base = 0;
|
|
|
|
|
Paragraph::depth_type cmd_depth = 0;
|
|
|
|
|
Paragraph::depth_type depth = 0; // paragraph depth
|
|
|
|
|
|
|
|
|
|
string command_name;
|
|
|
|
|
|
2003-11-25 17:23:36 +00:00
|
|
|
|
string item_tag;
|
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
ParagraphList::iterator par = const_cast<ParagraphList&>(paragraphs).begin();
|
|
|
|
|
ParagraphList::iterator pend = const_cast<ParagraphList&>(paragraphs).end();
|
|
|
|
|
|
2003-11-25 17:23:36 +00:00
|
|
|
|
Counters & counters = buf.params().getLyXTextClass().counters();
|
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
for (; par != pend; ++par) {
|
|
|
|
|
|
|
|
|
|
LyXLayout_ptr const & style = par->layout();
|
|
|
|
|
|
|
|
|
|
// environment tag closing
|
|
|
|
|
for (; depth > par->params().depth(); --depth) {
|
|
|
|
|
sgml::closeEnvTags(os, false, environment_inner[depth],
|
2003-11-25 17:23:36 +00:00
|
|
|
|
item_tag, command_depth + depth);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
sgml::closeTag(os, depth + command_depth, false, 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()) {
|
|
|
|
|
sgml::closeEnvTags(os, false, environment_inner[depth],
|
2003-11-25 17:23:36 +00:00
|
|
|
|
item_tag, command_depth + depth);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
|
|
|
|
|
|
|
|
|
|
environment_stack[depth].erase();
|
|
|
|
|
environment_inner[depth].erase();
|
|
|
|
|
}
|
2003-11-25 17:23:36 +00:00
|
|
|
|
|
|
|
|
|
string ls = "";
|
|
|
|
|
bool labelid = false;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// Write opening SGML tags.
|
|
|
|
|
switch (style->latextype) {
|
|
|
|
|
case LATEX_PARAGRAPH:
|
2003-11-25 17:23:36 +00:00
|
|
|
|
if (!style->latexparam().empty()) {
|
|
|
|
|
counters.step("para");
|
|
|
|
|
int i = counters.value("para");
|
2003-12-31 08:44:42 +00:00
|
|
|
|
ls = subst(style->latexparam(), "#", tostr(i));
|
2003-11-25 17:23:36 +00:00
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
sgml::openTag(os, depth + command_depth,
|
2003-11-25 17:23:36 +00:00
|
|
|
|
false, style->latexname(), ls);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case LATEX_COMMAND:
|
|
|
|
|
if (depth != 0)
|
|
|
|
|
//error(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
command_name = style->latexname();
|
|
|
|
|
|
2003-11-14 14:05:03 +00:00
|
|
|
|
cmd_depth = style->commanddepth;
|
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
if (command_flag) {
|
|
|
|
|
if (cmd_depth < command_base) {
|
|
|
|
|
for (Paragraph::depth_type j = command_depth;
|
|
|
|
|
j >= command_base; --j) {
|
|
|
|
|
sgml::closeTag(os, j, false, command_stack[j]);
|
|
|
|
|
os << endl;
|
|
|
|
|
}
|
|
|
|
|
command_depth = command_base = cmd_depth;
|
|
|
|
|
} else if (cmd_depth <= command_depth) {
|
|
|
|
|
for (int j = command_depth;
|
|
|
|
|
j >= int(cmd_depth); --j) {
|
|
|
|
|
sgml::closeTag(os, j, false, command_stack[j]);
|
|
|
|
|
os << endl;
|
|
|
|
|
}
|
|
|
|
|
command_depth = cmd_depth;
|
|
|
|
|
} else
|
|
|
|
|
command_depth = cmd_depth;
|
|
|
|
|
} else {
|
|
|
|
|
command_depth = command_base = cmd_depth;
|
|
|
|
|
command_flag = true;
|
|
|
|
|
}
|
|
|
|
|
if (command_stack.size() == command_depth + 1)
|
|
|
|
|
command_stack.push_back(string());
|
|
|
|
|
command_stack[command_depth] = command_name;
|
|
|
|
|
|
2003-12-31 08:44:42 +00:00
|
|
|
|
if (style->latexparam().find('#') != string::npos) {
|
2003-11-25 17:23:36 +00:00
|
|
|
|
counters.step(style->counter);
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// treat label as a special case for
|
|
|
|
|
// more WYSIWYM handling.
|
|
|
|
|
// This is a hack while paragraphs can't have
|
|
|
|
|
// attributes, like id in this case.
|
2003-12-18 12:42:02 +00:00
|
|
|
|
if (par->size() && par->isInset(0)) {
|
2004-01-26 10:13:15 +00:00
|
|
|
|
InsetBase * inset = par->getInset(0);
|
|
|
|
|
if (inset->lyxCode() == InsetOld::LABEL_CODE) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
command_name += " id=\"";
|
|
|
|
|
command_name += (static_cast<InsetCommand *>(inset))->getContents();
|
|
|
|
|
command_name += '"';
|
2003-11-25 17:23:36 +00:00
|
|
|
|
labelid = true;
|
|
|
|
|
}
|
2003-12-31 08:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
if (!labelid && !style->latexparam().empty()) {
|
|
|
|
|
ls = style->latexparam();
|
|
|
|
|
if (ls.find('#') != string::npos) {
|
|
|
|
|
string el = expandLabel(buf.params().getLyXTextClass(),
|
|
|
|
|
style, false);
|
|
|
|
|
ls = subst(ls, "#", el);
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
2003-11-25 17:23:36 +00:00
|
|
|
|
|
|
|
|
|
sgml::openTag(os, depth + command_depth, false, command_name, ls);
|
|
|
|
|
|
|
|
|
|
// Label around sectioning number:
|
|
|
|
|
if (!style->labeltag().empty()) {
|
|
|
|
|
sgml::openTag(os, depth + 1 + command_depth, false,
|
|
|
|
|
style->labeltag());
|
|
|
|
|
os << expandLabel(buf.params().getLyXTextClass(), style, false);
|
|
|
|
|
sgml::closeTag(os, depth + 1 + command_depth, false,
|
|
|
|
|
style->labeltag());
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2003-11-14 14:05:03 +00:00
|
|
|
|
// Inner tagged header text, e.g. <title> for sectioning:
|
2003-11-25 17:23:36 +00:00
|
|
|
|
sgml::openTag(os, depth + 1 + command_depth, false,
|
|
|
|
|
style->innertag());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
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()) {
|
|
|
|
|
if (environment_stack.size() == depth + 1) {
|
|
|
|
|
environment_stack.push_back("!-- --");
|
|
|
|
|
environment_inner.push_back("!-- --");
|
|
|
|
|
}
|
|
|
|
|
environment_stack[depth] = style->latexname();
|
|
|
|
|
environment_inner[depth] = "!-- --";
|
2003-11-25 17:23:36 +00:00
|
|
|
|
// outputs <environment_stack[depth] latexparam()>
|
|
|
|
|
sgml::openTag(os, depth + command_depth, false,
|
|
|
|
|
environment_stack[depth], style->latexparam());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
} else {
|
2003-11-25 17:23:36 +00:00
|
|
|
|
sgml::closeEnvTags(os, false, environment_inner[depth],
|
|
|
|
|
style->itemtag(), command_depth + depth);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (style->latextype == LATEX_ENVIRONMENT) {
|
2003-11-25 17:23:36 +00:00
|
|
|
|
if (!style->innertag().empty()) {
|
|
|
|
|
if (style->innertag() == "CDATA")
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os << "<![CDATA[";
|
|
|
|
|
else
|
2003-11-25 17:23:36 +00:00
|
|
|
|
sgml::openTag(os, depth + command_depth, false,
|
|
|
|
|
style->innertag());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2003-11-25 17:23:36 +00:00
|
|
|
|
environment_inner[depth] = style->innertag();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2003-11-25 17:23:36 +00:00
|
|
|
|
if (!environment_inner[depth].empty())
|
|
|
|
|
sgml::openTag(os, depth + 1 + command_depth,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
false, environment_inner[depth]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
sgml::openTag(os, depth + command_depth,
|
|
|
|
|
false, style->latexname());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2003-11-25 17:23:36 +00:00
|
|
|
|
par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs),
|
|
|
|
|
runparams, depth + 1 + command_depth, labelid);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
// write closing SGML tags
|
|
|
|
|
switch (style->latextype) {
|
|
|
|
|
case LATEX_COMMAND:
|
2003-11-25 17:23:36 +00:00
|
|
|
|
sgml::closeTag(os, depth + command_depth, false,
|
|
|
|
|
style->innertag());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case LATEX_ENVIRONMENT:
|
2003-11-25 17:23:36 +00:00
|
|
|
|
if (!style->innertag().empty()) {
|
|
|
|
|
if (style->innertag() == "CDATA")
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os << "]]>";
|
|
|
|
|
else
|
2003-11-25 17:23:36 +00:00
|
|
|
|
sgml::closeTag(os, depth + command_depth, false,
|
|
|
|
|
style->innertag());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LATEX_ITEM_ENVIRONMENT:
|
2003-11-25 17:23:36 +00:00
|
|
|
|
item_tag = style->itemtag();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case LATEX_PARAGRAPH:
|
|
|
|
|
sgml::closeTag(os, depth + command_depth, false, style->latexname());
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
sgml::closeTag(os, depth + command_depth, false, style->latexname());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close open tags
|
|
|
|
|
for (int d = depth; d >= 0; --d) {
|
|
|
|
|
if (!environment_stack[depth].empty()) {
|
|
|
|
|
sgml::closeEnvTags(os, false, environment_inner[depth],
|
2003-11-25 17:23:36 +00:00
|
|
|
|
item_tag, command_depth + depth);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int j = command_depth; j >= 0 ; --j)
|
|
|
|
|
if (!command_stack[j].empty()) {
|
|
|
|
|
sgml::closeTag(os, j, false, command_stack[j]);
|
|
|
|
|
os << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|