2 * \file output_docbook.C
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS.
14 #include "output_docbook.h"
17 #include "bufferparams.h"
20 #include "paragraph.h"
21 #include "paragraph_funcs.h"
22 #include "ParagraphParameters.h"
25 #include "insets/insetcommand.h"
27 #include "support/lstrings.h"
28 #include "support/lyxlib.h"
29 #include "support/tostr.h"
36 using lyx::support::atoi;
37 using lyx::support::split;
38 using lyx::support::subst;
47 void docbookParagraphs(Buffer const & buf,
48 ParagraphList const & paragraphs,
50 OutputParams const & runparams)
52 vector<string> environment_stack(10);
53 vector<string> environment_inner(10);
54 vector<string> command_stack(10);
56 bool command_flag = false;
57 Paragraph::depth_type command_depth = 0;
58 Paragraph::depth_type command_base = 0;
59 Paragraph::depth_type cmd_depth = 0;
60 Paragraph::depth_type depth = 0; // paragraph depth
66 ParagraphList::iterator par = const_cast<ParagraphList&>(paragraphs).begin();
67 ParagraphList::iterator pend = const_cast<ParagraphList&>(paragraphs).end();
69 Counters & counters = buf.params().getLyXTextClass().counters();
71 for (; par != pend; ++par) {
73 LyXLayout_ptr const & style = par->layout();
75 // environment tag closing
76 for (; depth > par->params().depth(); --depth) {
77 sgml::closeEnvTags(os, false, environment_inner[depth],
78 item_tag, command_depth + depth);
79 sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
80 environment_stack[depth].erase();
81 environment_inner[depth].erase();
84 if (depth == par->params().depth()
85 && environment_stack[depth] != style->latexname()
86 && !environment_stack[depth].empty()) {
87 sgml::closeEnvTags(os, false, environment_inner[depth],
88 item_tag, command_depth + depth);
89 sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
91 environment_stack[depth].erase();
92 environment_inner[depth].erase();
97 // Write opening SGML tags.
98 switch (style->latextype) {
100 if (!style->latexparam().empty()) {
101 counters.step("para");
102 int i = counters.value("para");
103 ls = "id=\"" + subst(style->latexparam(), "#", tostr(i)) + '"';
105 sgml::openTag(os, depth + command_depth,
106 false, style->latexname(), ls);
111 //error(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
114 command_name = style->latexname();
116 cmd_depth = style->commanddepth;
119 if (cmd_depth < command_base) {
120 for (Paragraph::depth_type j = command_depth;
121 j >= command_base; --j) {
122 sgml::closeTag(os, j, false, command_stack[j]);
125 command_depth = command_base = cmd_depth;
126 } else if (cmd_depth <= command_depth) {
127 for (int j = command_depth;
128 j >= int(cmd_depth); --j) {
129 sgml::closeTag(os, j, false, command_stack[j]);
132 command_depth = cmd_depth;
134 command_depth = cmd_depth;
136 command_depth = command_base = cmd_depth;
139 if (command_stack.size() == command_depth + 1)
140 command_stack.push_back(string());
141 command_stack[command_depth] = command_name;
143 if (!style->latexparam().empty()) {
144 counters.step(style->counter);
146 // treat label as a special case for
147 // more WYSIWYM handling.
148 // This is a hack while paragraphs can't have
149 // attributes, like id in this case.
150 if (par->isInset(0)) {
151 InsetOld * inset = par->getInset(0);
152 InsetOld::Code lyx_code = inset->lyxCode();
153 if (lyx_code == InsetOld::LABEL_CODE) {
154 command_name += " id=\"";
155 command_name += (static_cast<InsetCommand *>(inset))->getContents();
160 if (!style->latexparam().empty()) {
161 ls = expandLabel(buf.params().getLyXTextClass(), style, false);
162 ls = "id=\"" + subst(style->latexparam(), "#", ls) + '"';
166 sgml::openTag(os, depth + command_depth, false, command_name, ls);
168 // Label around sectioning number:
169 if (!style->labeltag().empty()) {
170 sgml::openTag(os, depth + 1 + command_depth, false,
172 os << expandLabel(buf.params().getLyXTextClass(), style, false);
173 sgml::closeTag(os, depth + 1 + command_depth, false,
177 // Inner tagged header text, e.g. <title> for sectioning:
178 sgml::openTag(os, depth + 1 + command_depth, false,
182 case LATEX_ENVIRONMENT:
183 case LATEX_ITEM_ENVIRONMENT:
184 if (depth < par->params().depth()) {
185 depth = par->params().depth();
186 environment_stack[depth].erase();
189 if (environment_stack[depth] != style->latexname()) {
190 if (environment_stack.size() == depth + 1) {
191 environment_stack.push_back("!-- --");
192 environment_inner.push_back("!-- --");
194 environment_stack[depth] = style->latexname();
195 environment_inner[depth] = "!-- --";
196 // outputs <environment_stack[depth] latexparam()>
197 sgml::openTag(os, depth + command_depth, false,
198 environment_stack[depth], style->latexparam());
200 sgml::closeEnvTags(os, false, environment_inner[depth],
201 style->itemtag(), command_depth + depth);
204 if (style->latextype == LATEX_ENVIRONMENT) {
205 if (!style->innertag().empty()) {
206 if (style->innertag() == "CDATA")
209 sgml::openTag(os, depth + command_depth, false,
215 environment_inner[depth] = style->innertag();
217 if (!environment_inner[depth].empty())
218 sgml::openTag(os, depth + 1 + command_depth,
219 false, environment_inner[depth]);
222 sgml::openTag(os, depth + command_depth,
223 false, style->latexname());
227 par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs),
228 runparams, depth + 1 + command_depth, labelid);
230 // write closing SGML tags
231 switch (style->latextype) {
233 sgml::closeTag(os, depth + command_depth, false,
236 case LATEX_ENVIRONMENT:
237 if (!style->innertag().empty()) {
238 if (style->innertag() == "CDATA")
241 sgml::closeTag(os, depth + command_depth, false,
245 case LATEX_ITEM_ENVIRONMENT:
246 item_tag = style->itemtag();
248 case LATEX_PARAGRAPH:
249 sgml::closeTag(os, depth + command_depth, false, style->latexname());
252 sgml::closeTag(os, depth + command_depth, false, style->latexname());
258 for (int d = depth; d >= 0; --d) {
259 if (!environment_stack[depth].empty()) {
260 sgml::closeEnvTags(os, false, environment_inner[depth],
261 item_tag, command_depth + depth);
265 for (int j = command_depth; j >= 0 ; --j)
266 if (!command_stack[j].empty()) {
267 sgml::closeTag(os, j, false, command_stack[j]);