]> git.lyx.org Git - features.git/blob - src/output_docbook.C
047b6a0300497bc7bcb37931a4ac344c42bf5d3a
[features.git] / src / output_docbook.C
1 /**
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.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author José Matos
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "output_docbook.h"
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "paragraph.h"
19 #include "paragraph_funcs.h"
20 #include "ParagraphParameters.h"
21 #include "sgml.h"
22
23 #include "insets/insetcommand.h"
24
25 #include "support/lstrings.h"
26 #include "support/lyxlib.h"
27
28 #include <stack>
29
30 #ifdef HAVE_LOCALE
31 #endif
32
33 using lyx::support::atoi;
34 using lyx::support::split;
35
36 using std::endl;
37 using std::ostream;
38 using std::stack;
39 using std::vector;
40 using std::string;
41
42
43 void docbookParagraphs(Buffer const & buf,
44                        ParagraphList const & paragraphs,
45                        ostream & os,
46                        OutputParams const & runparams)
47 {
48         vector<string> environment_stack(10);
49         vector<string> environment_inner(10);
50         vector<string> command_stack(10);
51
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
57
58         string command_name;
59
60         ParagraphList::iterator par = const_cast<ParagraphList&>(paragraphs).begin();
61         ParagraphList::iterator pend = const_cast<ParagraphList&>(paragraphs).end();
62
63         for (; par != pend; ++par) {
64                 string inner_tag;
65                 int desc_on = 0; // description mode
66
67                 LyXLayout_ptr const & style = par->layout();
68
69                 // environment tag closing
70                 for (; depth > par->params().depth(); --depth) {
71                         if (!environment_inner[depth].empty()) 
72                         sgml::closeEnvTags(os, false, environment_inner[depth], 
73                                         command_depth + depth);
74                         sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
75                         environment_stack[depth].erase();
76                         environment_inner[depth].erase();
77                 }
78
79                 if (depth == par->params().depth()
80                    && environment_stack[depth] != style->latexname()
81                    && !environment_stack[depth].empty()) {
82                                 sgml::closeEnvTags(os, false, environment_inner[depth], 
83                                         command_depth + depth);
84                         sgml::closeTag(os, depth + command_depth, false, environment_stack[depth]);
85
86                         environment_stack[depth].erase();
87                         environment_inner[depth].erase();
88                 }
89
90                 // Write opening SGML tags.
91                 string item_name;
92                 switch (style->latextype) {
93                 case LATEX_PARAGRAPH:
94                         sgml::openTag(os, depth + command_depth,
95                                     false, style->latexname());
96                         break;
97
98                 case LATEX_COMMAND:
99                         if (depth != 0)
100                                 //error(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
101                                 ;
102                         
103                         command_name = style->latexname();
104
105                         cmd_depth = style->commanddepth;
106                         inner_tag = style->innertag();
107                         
108                         if (command_flag) {
109                                 if (cmd_depth < command_base) {
110                                         for (Paragraph::depth_type j = command_depth;
111                                              j >= command_base; --j) {
112                                                 sgml::closeTag(os, j, false, command_stack[j]);
113                                                 os << endl;
114                                         }
115                                         command_depth = command_base = cmd_depth;
116                                 } else if (cmd_depth <= command_depth) {
117                                         for (int j = command_depth;
118                                              j >= int(cmd_depth); --j) {
119                                                 sgml::closeTag(os, j, false, command_stack[j]);
120                                                 os << endl;
121                                         }
122                                         command_depth = cmd_depth;
123                                 } else
124                                         command_depth = cmd_depth;
125                         } else {
126                                 command_depth = command_base = cmd_depth;
127                                 command_flag = true;
128                         }
129                         if (command_stack.size() == command_depth + 1)
130                                 command_stack.push_back(string());
131                         command_stack[command_depth] = command_name;
132
133                         // treat label as a special case for
134                         // more WYSIWYM handling.
135                         // This is a hack while paragraphs can't have
136                         // attributes, like id in this case.
137                         if (par->isInset(0)) {
138                                 InsetOld * inset = par->getInset(0);
139                                 InsetOld::Code lyx_code = inset->lyxCode();
140                                 if (lyx_code == InsetOld::LABEL_CODE) {
141                                         command_name += " id=\"";
142                                         command_name += (static_cast<InsetCommand *>(inset))->getContents();
143                                         command_name += '"';
144                                         desc_on = 3;
145                                 }
146                         }
147
148                         sgml::openTag(os, depth + command_depth, false, command_name);
149                         // Inner tagged header text, e.g. <title> for sectioning:
150                         sgml::openTag(os, depth + 1 + command_depth, false, inner_tag);
151                         break;
152
153                 case LATEX_ENVIRONMENT:
154                 case LATEX_ITEM_ENVIRONMENT:
155                         if (depth < par->params().depth()) {
156                                 depth = par->params().depth();
157                                 environment_stack[depth].erase();
158                         }
159
160                         if (environment_stack[depth] != style->latexname()) {
161                                 if (environment_stack.size() == depth + 1) {
162                                         environment_stack.push_back("!-- --");
163                                         environment_inner.push_back("!-- --");
164                                 }
165                                 environment_stack[depth] = style->latexname();
166                                 environment_inner[depth] = "!-- --";
167                                 sgml::openTag(os, depth + command_depth, false, environment_stack[depth]);
168                         } else {
169                                         sgml::closeEnvTags(os, false, environment_inner[depth], 
170                                                 command_depth + depth);
171                         }
172
173                         if (style->latextype == LATEX_ENVIRONMENT) {
174                                 if (!style->latexparam().empty()) {
175                                         if (style->latexparam() == "CDATA")
176                                                 os << "<![CDATA[";
177                                         else
178                                                 sgml::openTag(os, depth + command_depth, false, style->latexparam());
179                                 }
180                                 break;
181                         }
182
183                         desc_on = (style->labeltype == LABEL_MANUAL);
184
185                         environment_inner[depth] = desc_on ? "varlistentry" : "listitem";
186                         sgml::openTag(os, depth + 1 + command_depth,
187                                     false, environment_inner[depth]);
188
189                         item_name = desc_on ? "term" : "para";
190                         sgml::openTag(os, depth + 1 + command_depth,
191                                     false, item_name);
192                         break;
193                 default:
194                         sgml::openTag(os, depth + command_depth,
195                                     false, style->latexname());
196                         break;
197                 }
198
199                 par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs), desc_on,
200                                          runparams, depth + 1 + command_depth);
201
202                 string end_tag;
203                 // write closing SGML tags
204                 switch (style->latextype) {
205                 case LATEX_COMMAND:
206                         sgml::closeTag(os, depth + command_depth, false, inner_tag);
207                         break;
208                 case LATEX_ENVIRONMENT:
209                         if (!style->latexparam().empty()) {
210                                 if (style->latexparam() == "CDATA")
211                                         os << "]]>";
212                                 else
213                                         sgml::closeTag(os, depth + command_depth, false, style->latexparam());
214                         }
215                         break;
216                 case LATEX_ITEM_ENVIRONMENT:
217                         if (desc_on == 1) break;
218                         end_tag = "para";
219                         sgml::closeTag(os, depth + 1 + command_depth, false, end_tag);
220                         break;
221                 case LATEX_PARAGRAPH:
222                         sgml::closeTag(os, depth + command_depth, false, style->latexname());
223                         break;
224                 default:
225                         sgml::closeTag(os, depth + command_depth, false, style->latexname());
226                         break;
227                 }
228         }
229
230         // Close open tags
231         for (int d = depth; d >= 0; --d) {
232                 if (!environment_stack[depth].empty()) {
233                                 sgml::closeEnvTags(os, false, environment_inner[depth], 
234                                         command_depth + depth);
235                 }
236         }
237
238         for (int j = command_depth; j >= 0 ; --j)
239                 if (!command_stack[j].empty()) {
240                         sgml::closeTag(os, j, false, command_stack[j]);
241                         os << endl;
242                 }
243 }
244