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"
18 #include "paragraph.h"
19 #include "paragraph_funcs.h"
20 #include "ParagraphParameters.h"
23 #include "insets/insetcommand.h"
25 #include "support/lstrings.h"
26 #include "support/lyxlib.h"
33 using lyx::support::atoi;
34 using lyx::support::split;
43 void docbookParagraphs(Buffer const & buf,
44 ParagraphList const & paragraphs,
46 OutputParams const & runparams)
48 vector<string> environment_stack(10);
49 vector<string> environment_inner(10);
50 vector<string> command_stack(10);
52 bool command_flag = false;
53 Paragraph::depth_type command_depth = 0;
54 Paragraph::depth_type command_base = 0;
55 Paragraph::depth_type cmd_depth = 0;
56 Paragraph::depth_type depth = 0; // paragraph depth
61 ParagraphList::iterator par = const_cast<ParagraphList&>(paragraphs).begin();
62 ParagraphList::iterator pend = const_cast<ParagraphList&>(paragraphs).end();
64 for (; par != pend; ++par) {
68 int desc_on = 0; // description mode
70 LyXLayout_ptr const & style = par->layout();
72 // environment tag closing
73 for (; depth > par->params().depth(); --depth) {
74 if (!environment_inner[depth].empty())
75 sgml::closeEnvTags(os, false, environment_inner[depth],
76 command_depth + depth);
77 sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
78 environment_stack[depth].erase();
79 environment_inner[depth].erase();
82 if (depth == par->params().depth()
83 && environment_stack[depth] != style->latexname()
84 && !environment_stack[depth].empty()) {
85 sgml::closeEnvTags(os, false, environment_inner[depth],
86 command_depth + depth);
87 sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
89 environment_stack[depth].erase();
90 environment_inner[depth].erase();
93 // Write opening SGML tags.
94 switch (style->latextype) {
96 sgml::openTag(os, depth + command_depth,
97 false, style->latexname());
102 //error(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
105 command_name = style->latexname();
107 sgmlparam = style->latexparam();
108 c_params = split(sgmlparam, c_depth,'|');
110 cmd_depth = atoi(c_depth);
113 if (cmd_depth < command_base) {
114 for (Paragraph::depth_type j = command_depth;
115 j >= command_base; --j) {
116 sgml::closeTag(os, j, false, command_stack[j]);
119 command_depth = command_base = cmd_depth;
120 } else if (cmd_depth <= command_depth) {
121 for (int j = command_depth;
122 j >= int(cmd_depth); --j) {
123 sgml::closeTag(os, j, false, command_stack[j]);
126 command_depth = cmd_depth;
128 command_depth = cmd_depth;
130 command_depth = command_base = cmd_depth;
133 if (command_stack.size() == command_depth + 1)
134 command_stack.push_back(string());
135 command_stack[command_depth] = command_name;
137 // treat label as a special case for
138 // more WYSIWYM handling.
139 // This is a hack while paragraphs can't have
140 // attributes, like id in this case.
141 if (par->isInset(0)) {
142 InsetOld * inset = par->getInset(0);
143 InsetOld::Code lyx_code = inset->lyxCode();
144 if (lyx_code == InsetOld::LABEL_CODE) {
145 command_name += " id=\"";
146 command_name += (static_cast<InsetCommand *>(inset))->getContents();
152 sgml::openTag(os, depth + command_depth, false, command_name);
154 item_name = c_params.empty() ? "title" : c_params;
155 sgml::openTag(os, depth + 1 + command_depth, false, item_name);
158 case LATEX_ENVIRONMENT:
159 case LATEX_ITEM_ENVIRONMENT:
160 if (depth < par->params().depth()) {
161 depth = par->params().depth();
162 environment_stack[depth].erase();
165 if (environment_stack[depth] != style->latexname()) {
166 if (environment_stack.size() == depth + 1) {
167 environment_stack.push_back("!-- --");
168 environment_inner.push_back("!-- --");
170 environment_stack[depth] = style->latexname();
171 environment_inner[depth] = "!-- --";
172 sgml::openTag(os, depth + command_depth, false, environment_stack[depth]);
174 sgml::closeEnvTags(os, false, environment_inner[depth],
175 command_depth + depth);
178 if (style->latextype == LATEX_ENVIRONMENT) {
179 if (!style->latexparam().empty()) {
180 if (style->latexparam() == "CDATA")
183 sgml::openTag(os, depth + command_depth, false, style->latexparam());
188 desc_on = (style->labeltype == LABEL_MANUAL);
190 environment_inner[depth] = desc_on ? "varlistentry" : "listitem";
191 sgml::openTag(os, depth + 1 + command_depth,
192 false, environment_inner[depth]);
194 item_name = desc_on ? "term" : "para";
195 sgml::openTag(os, depth + 1 + command_depth,
199 sgml::openTag(os, depth + command_depth,
200 false, style->latexname());
204 par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs), desc_on,
205 runparams, depth + 1 + command_depth);
208 // write closing SGML tags
209 switch (style->latextype) {
211 end_tag = c_params.empty() ? "title" : c_params;
212 sgml::closeTag(os, depth + command_depth,
215 case LATEX_ENVIRONMENT:
216 if (!style->latexparam().empty()) {
217 if (style->latexparam() == "CDATA")
220 sgml::closeTag(os, depth + command_depth, false, style->latexparam());
223 case LATEX_ITEM_ENVIRONMENT:
224 if (desc_on == 1) break;
226 sgml::closeTag(os, depth + 1 + command_depth, false, end_tag);
228 case LATEX_PARAGRAPH:
229 sgml::closeTag(os, depth + command_depth, false, style->latexname());
232 sgml::closeTag(os, depth + command_depth, false, style->latexname());
238 for (int d = depth; d >= 0; --d) {
239 if (!environment_stack[depth].empty()) {
240 sgml::closeEnvTags(os, false, environment_inner[depth],
241 command_depth + depth);
245 for (int j = command_depth; j >= 0 ; --j)
246 if (!command_stack[j].empty()) {
247 sgml::closeTag(os, j, false, command_stack[j]);