]> git.lyx.org Git - lyx.git/blob - src/output_docbook.C
AGU header stuff
[lyx.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 "counters.h"
19 #include "lyxtext.h"
20 #include "paragraph.h"
21 #include "paragraph_funcs.h"
22 #include "ParagraphParameters.h"
23 #include "sgml.h"
24
25 #include "insets/insetcommand.h"
26
27 #include "support/lstrings.h"
28 #include "support/lyxlib.h"
29 #include "support/tostr.h"
30
31 #include <stack>
32
33 #ifdef HAVE_LOCALE
34 #endif
35
36 using lyx::support::atoi;
37 using lyx::support::split;
38 using lyx::support::subst;
39
40 using std::endl;
41 using std::ostream;
42 using std::stack;
43 using std::vector;
44 using std::string;
45
46
47 void docbookParagraphs(Buffer const & buf,
48                        ParagraphList const & paragraphs,
49                        ostream & os,
50                        OutputParams const & runparams)
51 {
52         vector<string> environment_stack(10);
53         vector<string> environment_inner(10);
54         vector<string> command_stack(10);
55
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
61
62         string command_name;
63
64         string item_tag;
65
66         ParagraphList::iterator par = const_cast<ParagraphList&>(paragraphs).begin();
67         ParagraphList::iterator pend = const_cast<ParagraphList&>(paragraphs).end();
68
69     Counters & counters = buf.params().getLyXTextClass().counters();
70         
71         for (; par != pend; ++par) {
72
73                 LyXLayout_ptr const & style = par->layout();
74
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();
82                 }
83
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]);
90
91                         environment_stack[depth].erase();
92                         environment_inner[depth].erase();
93                 }
94                 
95                 string ls = "";
96                 bool labelid = false;
97                 // Write opening SGML tags.
98                 switch (style->latextype) {
99                 case LATEX_PARAGRAPH:
100                         if (!style->latexparam().empty()) {
101                                 counters.step("para");
102                                 int i = counters.value("para");
103                                 ls = "id=\"" + subst(style->latexparam(), "#", tostr(i)) + '"';
104                         }
105                         sgml::openTag(os, depth + command_depth,
106                                     false, style->latexname(), ls);
107                         break;
108
109                 case LATEX_COMMAND:
110                         if (depth != 0)
111                                 //error(ErrorItem(_("Error"), _("Wrong depth for LatexType Command."), par->id(), 0, par->size()));
112                                 ;
113                         
114                         command_name = style->latexname();
115
116                         cmd_depth = style->commanddepth;
117                         
118                         if (command_flag) {
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]);
123                                                 os << endl;
124                                         }
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]);
130                                                 os << endl;
131                                         }
132                                         command_depth = cmd_depth;
133                                 } else
134                                         command_depth = cmd_depth;
135                         } else {
136                                 command_depth = command_base = cmd_depth;
137                                 command_flag = true;
138                         }
139                         if (command_stack.size() == command_depth + 1)
140                                 command_stack.push_back(string());
141                         command_stack[command_depth] = command_name;
142
143                         if (!style->latexparam().empty()) {
144                                 counters.step(style->counter);
145                         }
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->size() && 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();
156                                         command_name += '"';
157                                         labelid = true;
158                                 }
159                         } else {
160                                 if (!style->latexparam().empty()) {
161                                         ls = expandLabel(buf.params().getLyXTextClass(), style, false);
162                                         ls = "id=\"" + subst(style->latexparam(), "#", ls) + '"';
163                                 }
164                         }
165                         
166                         sgml::openTag(os, depth + command_depth, false, command_name, ls);
167
168                         // Label around sectioning number:
169                         if (!style->labeltag().empty()) {
170                                 sgml::openTag(os, depth + 1 + command_depth, false, 
171                                         style->labeltag());
172                                 os << expandLabel(buf.params().getLyXTextClass(), style, false);
173                                 sgml::closeTag(os, depth + 1 + command_depth, false, 
174                                         style->labeltag());
175                         }
176
177                         // Inner tagged header text, e.g. <title> for sectioning:
178                         sgml::openTag(os, depth + 1 + command_depth, false, 
179                                 style->innertag());
180                         break;
181
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();
187                         }
188
189                         if (environment_stack[depth] != style->latexname()) {
190                                 if (environment_stack.size() == depth + 1) {
191                                         environment_stack.push_back("!-- --");
192                                         environment_inner.push_back("!-- --");
193                                 }
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());
199                         } else {
200                                 sgml::closeEnvTags(os, false, environment_inner[depth], 
201                                         style->itemtag(), command_depth + depth);
202                         }
203
204                         if (style->latextype == LATEX_ENVIRONMENT) {
205                                 if (!style->innertag().empty()) {
206                                         if (style->innertag() == "CDATA")
207                                                 os << "<![CDATA[";
208                                         else
209                                                 sgml::openTag(os, depth + command_depth, false, 
210                                                         style->innertag());
211                                 }
212                                 break;
213                         }
214
215                         environment_inner[depth] = style->innertag();
216
217                         if (!environment_inner[depth].empty())
218                                 sgml::openTag(os, depth + 1 + command_depth,
219                                     false, environment_inner[depth]);
220                         break;
221                 default:
222                         sgml::openTag(os, depth + command_depth,
223                                     false, style->latexname());
224                         break;
225                 }
226
227                 par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs),
228                                          runparams, depth + 1 + command_depth, labelid);
229
230                 // write closing SGML tags
231                 switch (style->latextype) {
232                 case LATEX_COMMAND:
233                         sgml::closeTag(os, depth + command_depth, false, 
234                                 style->innertag());
235                         break;
236                 case LATEX_ENVIRONMENT:
237                         if (!style->innertag().empty()) {
238                                 if (style->innertag() == "CDATA")
239                                         os << "]]>";
240                                 else
241                                         sgml::closeTag(os, depth + command_depth, false, 
242                                                 style->innertag());
243                         }
244                         break;
245                 case LATEX_ITEM_ENVIRONMENT:
246                         item_tag = style->itemtag();
247                         break;
248                 case LATEX_PARAGRAPH:
249                         sgml::closeTag(os, depth + command_depth, false, style->latexname());
250                         break;
251                 default:
252                         sgml::closeTag(os, depth + command_depth, false, style->latexname());
253                         break;
254                 }
255         }
256
257         // Close open tags
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);
262                 }
263         }
264
265         for (int j = command_depth; j >= 0 ; --j)
266                 if (!command_stack[j].empty()) {
267                         sgml::closeTag(os, j, false, command_stack[j]);
268                         os << endl;
269                 }
270 }
271