2 * \file output_plaintext.cpp
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
8 * Full author contact details are available in file CREDITS.
13 #include "output_plaintext.h"
16 #include "BufferParams.h"
19 #include "OutputParams.h"
20 #include "Paragraph.h"
21 #include "ParagraphList.h"
22 #include "ParagraphParameters.h"
24 #include "support/debug.h"
25 #include "support/gettext.h"
26 #include "support/lstrings.h"
29 using namespace lyx::support;
34 void writePlaintextFile(Buffer const & buf, FileName const & fname,
35 OutputParams const & runparams)
38 if (!openFileWrite(ofs, fname))
41 // make sure we are ready to export
43 buf.updateMacroInstances(OutputUpdate);
44 buf.makeCitationLabels();
46 writePlaintextFile(buf, ofs, runparams);
50 void writePlaintextFile(Buffer const & buf, odocstream & os,
51 OutputParams const & runparams)
53 bool ref_printed = false;
54 ParagraphList const & par = buf.paragraphs();
55 ParagraphList::const_iterator beg = par.begin();
56 ParagraphList::const_iterator end = par.end();
57 ParagraphList::const_iterator it = beg;
58 for (; it != end; ++it) {
59 writePlaintextParagraph(buf, *it, os, runparams, ref_printed);
61 if (runparams.linelen > 0)
67 static pair<int, docstring> addDepth(int depth, int ldepth)
71 d += (ldepth - depth) * 2;
72 return make_pair(d, docstring(d, ' '));
76 void writePlaintextParagraph(Buffer const & buf,
77 Paragraph const & par,
79 OutputParams const & runparams,
80 bool & ref_printed, size_t max_length)
83 depth_type ltype_depth = 0;
84 depth_type depth = par.params().depth();
86 // First write the layout
87 string const tmp = to_utf8(par.layout().name());
88 if (compare_ascii_no_case(tmp, "itemize") == 0) {
90 ltype_depth = depth + 1;
91 } else if (compare_ascii_no_case(tmp, "enumerate") == 0) {
93 ltype_depth = depth + 1;
94 } else if (contains(ascii_lowercase(tmp), "ection")) {
96 ltype_depth = depth + 1;
97 } else if (contains(ascii_lowercase(tmp), "aragraph")) {
99 ltype_depth = depth + 1;
100 } else if (compare_ascii_no_case(tmp, "description") == 0) {
102 ltype_depth = depth + 1;
103 } else if (compare_ascii_no_case(tmp, "abstract") == 0) {
106 } else if (compare_ascii_no_case(tmp, "bibliography") == 0) {
114 /* the labelwidthstring used in lists */
118 /* what about the alignment */
120 // runparams.linelen == 0 is special and means we don't have paragraph breaks
122 string::size_type currlinelen = 0;
125 os << docstring(depth * 2, ' ');
126 currlinelen += depth * 2;
129 // we should probably change to the paragraph language in the
130 // support/gettext.here (if possible) so that strings are output in
131 // the correct language! (20012712 Jug)
135 case 4: // (Sub)Paragraph
136 case 5: // Description
140 if (runparams.linelen > 0) {
141 os << buf.B_("Abstract") << "\n\n";
144 docstring const abst = buf.B_("Abstract: ");
146 currlinelen += abst.length();
150 case 7: // Bibliography
152 if (runparams.linelen > 0) {
153 os << buf.B_("References") << "\n\n";
156 docstring const refs = buf.B_("References: ");
158 currlinelen += refs.length();
165 docstring const label = par.params().labelString();
166 if (!label.empty()) {
168 currlinelen += label.length() + 1;
175 if (currlinelen == 0) {
176 pair<int, docstring> p = addDepth(depth, ltype_depth);
178 currlinelen += p.first;
183 for (pos_type i = 0; i < par.size(); ++i) {
184 // deleted characters don't make much sense in plain text output
185 if (par.isDeleted(i))
188 if (os.str().size() > max_length)
191 char_type c = par.getUChar(buf.params(), runparams, i);
193 if (par.isInset(i) || c == ' ') {
194 if (runparams.linelen > 0 &&
195 currlinelen + word.length() > runparams.linelen) {
197 pair<int, docstring> p = addDepth(depth, ltype_depth);
199 currlinelen = p.first;
202 currlinelen += word.length();
206 if (par.isInset(i)) {
207 OutputParams rp = runparams;
208 rp.depth = par.params().depth();
209 int len = par.getInset(i)->plaintext(os, rp, max_length);
210 if (len >= Inset::PLAINTEXT_NEWLINE)
211 currlinelen = len - Inset::PLAINTEXT_NEWLINE;
224 LYXERR(Debug::INFO, "writePlaintextFile: NUL char in structure.");
233 // currlinelen may be greater than runparams.linelen!
234 // => check whether word is empty and do nothing in this case
236 if (runparams.linelen > 0 &&
237 currlinelen + word.length() > runparams.linelen) {
239 pair<int, docstring> p = addDepth(depth, ltype_depth);
241 currlinelen = p.first;