1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation "lyxparagraph.h"
21 #include "lyxparagraph.h"
22 #include "support/textutils.h"
25 #include "tex-strings.h"
26 #include "bufferparams.h"
27 #include "support/FileInfo.h"
28 #include "support/LAssert.h"
30 #include "LaTeXFeatures.h"
31 #include "insets/insetinclude.h"
32 #include "support/filetools.h"
33 #include "lyx_gui_misc.h"
37 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
38 int tex_code_break_column = 72; // needs non-zero initialization. set later.
39 // this is a bad idea, but how can LyXParagraph find its buffer to get
40 // parameters? (JMarc)
41 extern BufferView * current_view;
46 extern string bibitemWidthest();
48 // this is a minibuffer
49 static char minibuffer_char;
50 static LyXFont minibuffer_font;
51 static Inset * minibuffer_inset;
54 // Initialization of the counter for the paragraph id's,
55 // declared in lyxparagraph.h
56 unsigned int LyXParagraph::paragraph_id = 0;
59 LyXParagraph::LyXParagraph()
61 text.reserve(500); // is this number too big?
63 for (int i = 0; i < 10; ++i) setCounter(i , 0);
69 #ifndef NEW_FONTTABLE // OK
72 #ifndef NEW_INSETTABLE
75 footnoteflag = LyXParagraph::NO_FOOTNOTE;
77 align = LYX_ALIGN_BLOCK;
79 /* table stuff -- begin*/
81 /* table stuff -- end*/
83 bibkey = 0; // ale970302
88 // This konstruktor inserts the new paragraph in a list.
89 LyXParagraph::LyXParagraph(LyXParagraph * par)
92 par->text.resize(par->text.size());
94 for (int i = 0; i < 10; ++i) setCounter(i, 0);
100 next->previous = this;
102 previous->next = this;
103 #ifndef NEW_FONTTABLE // OK
106 #ifndef NEW_INSETTABLE
109 footnoteflag = LyXParagraph::NO_FOOTNOTE;
110 footnotekind = LyXParagraph::FOOTNOTE;
112 /* table stuff -- begin*/
114 /* table stuff -- end*/
115 id_ = paragraph_id++;
117 bibkey = 0; // ale970302
123 void LyXParagraph::writeFile(ostream & os, BufferParams & params,
124 char footflag, char dth)
126 LyXFont font1, font2;
132 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
134 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
136 // The beginning or the end of a footnote environment?
137 if (footflag != footnoteflag) {
138 footflag = footnoteflag;
140 os << "\n\\begin_float "
141 << string_footnotekinds[footnotekind]
145 os << "\n\\end_float ";
149 // The beginning or end of a deeper (i.e. nested) area?
152 while (depth > dth) {
153 os << "\n\\begin_deeper ";
158 while (depth < dth) {
159 os << "\n\\end_deeper ";
165 // First write the layout
167 << textclasslist.NameOfLayout(params.textclass, layout)
170 // Maybe some vertical spaces.
171 if (added_space_top.kind() != VSpace::NONE)
172 os << "\\added_space_top "
173 << added_space_top.asLyXCommand() << " ";
174 if (added_space_bottom.kind() != VSpace::NONE)
175 os << "\\added_space_bottom "
176 << added_space_bottom.asLyXCommand() << " ";
178 // The labelwidth string used in lists.
179 if (!labelwidthstring.empty())
180 os << "\\labelwidthstring "
181 << labelwidthstring << '\n';
183 // Lines above or below?
187 os << "\\line_bottom ";
189 // Pagebreaks above or below?
191 os << "\\pagebreak_top ";
192 if (pagebreak_bottom)
193 os << "\\pagebreak_bottom ";
195 // Start of appendix?
196 if (start_of_appendix)
197 os << "\\start_of_appendix ";
204 if (align != LYX_ALIGN_LAYOUT) {
206 case LYX_ALIGN_LEFT: h = 1; break;
207 case LYX_ALIGN_RIGHT: h = 2; break;
208 case LYX_ALIGN_CENTER: h = 3; break;
209 default: h = 0; break;
211 os << "\\align " << string_align[h] << " ";
213 if (pextra_type != PEXTRA_NONE) {
214 os << "\\pextra_type " << pextra_type;
215 if (pextra_type == PEXTRA_MINIPAGE) {
216 os << " \\pextra_alignment "
219 os << " \\pextra_hfill "
221 if (pextra_start_minipage)
222 os << " \\pextra_start_minipage "
223 << pextra_start_minipage;
225 if (!pextra_width.empty()) {
226 os << " \\pextra_width "
227 << VSpace(pextra_width).asLyXCommand();
228 } else if (!pextra_widthp.empty()) {
229 os << " \\pextra_widthp "
236 // Dummy layout. This means that a footnote ended.
237 os << "\n\\end_float ";
238 footflag = LyXParagraph::NO_FOOTNOTE;
241 // It might be a table.
243 os << "\\LyXTable\n";
251 font1 = LyXFont(LyXFont::ALL_INHERIT);
254 for (size_type i = 0; i < size(); i++) {
260 // Write font changes
261 font2 = GetFontSettings(i);
262 if (font2 != font1) {
263 font2.lyxWriteChanges(font1, os);
273 if (inset->DirectWrite()) {
274 // international char, let it write
275 // code directly so it's shorter in
279 os << "\n\\begin_inset ";
281 os << "\n\\end_inset \n\n";
286 os << "\n\\newline \n";
290 os << "\n\\hfill \n";
293 case META_PROTECTED_SEPARATOR:
294 os << "\n\\protected_separator \n";
298 os << "\n\\backslash \n";
302 if (i + 1 < size() && GetChar(i + 1) == ' ') {
309 if ((column > 70 && c == ' ')
314 // this check is to amend a bug. LyX sometimes
315 // inserts '\0' this could cause problems.
319 lyxerr << "ERROR (LyXParagraph::writeFile):"
320 " NULL char in structure." << endl;
326 // now write the next paragraph
328 next->writeFile(os, params, footflag, dth);
332 void LyXParagraph::validate(LaTeXFeatures & features)
334 // this will be useful later
335 LyXLayout const & layout = textclasslist.Style(current_view->buffer()->params.textclass,
339 if (line_top || line_bottom)
340 features.lyxline = true;
343 features.layout[GetLayout()] = true;
346 #ifdef NEW_FONTTABLE // OK, but does not affect structure anyway
347 for (FontList::const_iterator cit = fontlist.begin();
348 cit != fontlist.end(); ++cit) {
349 if ((*cit).font.noun() == LyXFont::ON) {
350 lyxerr[Debug::LATEX] << "font.noun: "
351 << (*cit).font.noun()
353 features.noun = true;
354 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
355 << (*cit).font.stateText()
358 switch ((*cit).font.color()) {
360 case LyXFont::INHERIT_COLOR:
361 case LyXFont::IGNORE_COLOR:
364 features.color = true;
365 lyxerr[Debug::LATEX] << "Color enabled. Font: "
366 << (*cit).font.stateText()
371 FontTable * tmpfonttable = fonttable;
372 while (tmpfonttable) {
373 if (tmpfonttable->font.noun() == LyXFont::ON) {
374 lyxerr[Debug::LATEX] << "font.noun: "
375 << tmpfonttable->font.noun()
377 features.noun = true;
378 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
379 << tmpfonttable->font.stateText()
382 switch (tmpfonttable->font.color()) {
384 case LyXFont::INHERIT_COLOR:
385 case LyXFont::IGNORE_COLOR:
388 features.color = true;
389 lyxerr[Debug::LATEX] << "Color enabled. Font: "
390 << tmpfonttable->font.stateText()
393 tmpfonttable = tmpfonttable->next;
397 #ifdef NEW_INSETTABLE
398 for (InsetList::const_iterator cit = insetlist.begin();
399 cit != insetlist.end(); ++cit) {
401 (*cit).inset->Validate(features);
404 InsetTable * tmpinsettable = insettable;
405 while (tmpinsettable) {
406 if (tmpinsettable->inset) {
407 tmpinsettable->inset->Validate(features);
409 tmpinsettable = tmpinsettable->next;
413 if (table && table->IsLongTable())
414 features.longtable = true;
415 if (pextra_type == PEXTRA_INDENT)
416 features.LyXParagraphIndent = true;
417 if (pextra_type == PEXTRA_FLOATFLT)
418 features.floatflt = true;
419 if (layout.needprotect
420 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
421 features.NeedLyXFootnoteCode = true;
422 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
423 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
424 features.NeedLyXMinipageIndent = true;
425 if (table && table->NeedRotating())
426 features.rotating = true;
427 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
428 features.algorithm = true;
432 // First few functions needed for cut and paste and paragraph breaking.
433 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
435 minibuffer_char = GetChar(pos);
436 minibuffer_font = GetFontSettings(pos);
437 minibuffer_inset = 0;
438 if (minibuffer_char == LyXParagraph::META_INSET) {
440 minibuffer_inset = GetInset(pos)->Clone();
442 minibuffer_inset = 0;
443 minibuffer_char = ' ';
444 // This reflects what GetInset() does (ARRae)
449 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
451 minibuffer_char = GetChar(pos);
452 minibuffer_font = GetFontSettings(pos);
453 minibuffer_inset = 0;
454 if (minibuffer_char == LyXParagraph::META_INSET) {
456 minibuffer_inset = GetInset(pos);
457 // This is a little hack since I want exactly
458 // the inset, not just a clone. Otherwise
459 // the inset would be deleted when calling Erase(pos)
461 #ifdef NEW_INSETTABLE
462 for (InsetList::iterator it = insetlist.begin();
463 it != insetlist.end(); ++it) {
464 if ((*it).pos == pos) {
471 InsetTable * tmpi = insettable;
472 while (tmpi && tmpi->pos != pos) {
475 if (tmpi) { // This should always be true.
480 minibuffer_inset = 0;
481 minibuffer_char = ' ';
482 // This reflects what GetInset() does (ARRae)
487 // Erase(pos); now the caller is responsible for that.
491 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
493 InsertChar(pos, minibuffer_char);
494 SetFont(pos, minibuffer_font);
495 if (minibuffer_char == LyXParagraph::META_INSET)
496 InsertInset(pos, minibuffer_inset);
503 void LyXParagraph::Clear()
508 pagebreak_top = false;
509 pagebreak_bottom = false;
511 added_space_top = VSpace(VSpace::NONE);
512 added_space_bottom = VSpace(VSpace::NONE);
514 align = LYX_ALIGN_LAYOUT;
518 pextra_type = PEXTRA_NONE;
519 pextra_width.clear();
520 pextra_widthp.clear();
521 pextra_alignment = MINIPAGE_ALIGN_TOP;
522 pextra_hfill = false;
523 pextra_start_minipage = false;
526 labelwidthstring.clear();
530 start_of_appendix = false;
534 // the destructor removes the new paragraph from the list
535 LyXParagraph::~LyXParagraph()
538 previous->next = next;
540 next->previous = previous;
542 #ifdef NEW_INSETTABLE
543 for (InsetList::iterator it = insetlist.begin();
544 it != insetlist.end(); ++it) {
548 InsetTable * tmpinset;
550 tmpinset = insettable;
551 insettable = insettable->next;
553 delete tmpinset->inset;
555 if (insettable && insettable->next == insettable) {
556 // somehow this recursion appears occasionally
557 // but I can't find where. This bandaid
558 // helps but isn't the best fix. (ARRae)
559 if (insettable->inset) {
560 delete insettable->inset;
567 #ifndef NEW_FONTTABLE // OK
571 fonttable = fonttable->next;
576 /* table stuff -- begin*/
579 /* table stuff -- end*/
587 void LyXParagraph::Erase(LyXParagraph::size_type pos)
589 // > because last is the next unused position, and you can
590 // use it if you want
592 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
593 NextAfterFootnote()->Erase(pos - text.size() - 1);
595 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
596 "position does not exist." << endl;
599 if (pos < size()) { // last is free for insertation, but should be empty
600 // if it is an inset, delete the inset entry
601 if (text[pos] == LyXParagraph::META_INSET) {
603 #ifdef NEW_INSETTABLE
604 for (InsetList::iterator it = insetlist.begin();
605 it != insetlist.end(); ++it) {
606 if ((*it).pos == pos) {
613 InsetTable *tmpi = insettable;
614 InsetTable *tmpi2 = tmpi;
615 while (tmpi && tmpi->pos != pos) {
619 if (tmpi) { // this should always be true
620 if (tmpi->inset) // delete the inset if it exists
622 if (tmpi == insettable)
623 insettable = tmpi->next;
625 tmpi2->next = tmpi->next;
630 text.erase(text.begin() + pos);
631 // Erase entries in the tables.
632 #ifdef NEW_FONTTABLE // Seems OK
633 for (FontList::iterator it = fontlist.begin();
634 it != fontlist.end(); ++it) {
635 if (pos >= (*it).pos && pos <= (*it).pos_end) {
636 if ((*it).pos == (*it).pos_end) {
637 // If it is a multi-character font
638 // entry, we just make it smaller
639 // (see update below), otherwise we
646 // Update all other entries.
647 for (FontList::iterator it = fontlist.begin();
648 it != fontlist.end(); ++it) {
651 if ((*it).pos_end >= pos)
656 FontTable * tmp = fonttable;
657 FontTable * prev = 0;
658 while (tmp && !found) {
659 if (pos >= tmp->pos && pos <= tmp->pos_end)
667 if (found && tmp->pos == tmp->pos_end) {
668 // if it is a multi-character font entry, we just make
669 // it smaller (see update below), otherwise we should
672 prev->next = tmp->next;
674 fonttable = tmp->next;
679 // Update all other entries.
685 if (tmp->pos_end >= pos)
690 // Update the inset table.
691 #ifdef NEW_INSETTABLE
692 for (InsetList::iterator it = insetlist.begin();
693 it != insetlist.end(); ++it) {
698 InsetTable * tmpi = insettable;
706 lyxerr << "ERROR (LyXParagraph::Erase): "
707 "can't erase non-existant char." << endl;
712 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
714 // > because last is the next unused position, and you can
715 // use it if you want
718 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
719 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
722 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
723 "position does not exist." << endl;
726 text.insert(text.begin() + pos, c);
727 // Update the font table.
728 #ifdef NEW_FONTTABLE // Seems OK
729 for (FontList::iterator it = fontlist.begin();
730 it != fontlist.end(); ++it) {
731 if ((*it).pos >= pos)
733 if ((*it).pos_end >= pos)
737 FontTable * tmp = fonttable;
741 if (tmp->pos_end >= pos)
747 // Update the inset table.
748 #ifdef NEW_INSETTABLE
749 for (InsetList::iterator it = insetlist.begin();
750 it != insetlist.end(); ++it) {
751 if ((*it).pos >= pos)
755 InsetTable * tmpi = insettable;
757 if (tmpi->pos >= pos)
765 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
768 // > because last is the next unused position, and you can
769 // use it if you want
772 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
774 ->InsertInset(pos - text.size() - 1, inset);
776 lyxerr << "ERROR (LyXParagraph::InsertInset): "
777 "position does not exist: " << pos << endl;
780 if (text[pos] != LyXParagraph::META_INSET) {
781 lyxerr << "ERROR (LyXParagraph::InsertInset): "
782 "there is no LyXParagraph::META_INSET" << endl;
787 // Add a new entry in the inset table.
788 #ifdef NEW_INSETTABLE
790 InsetList::iterator it =
791 insetlist.insert(insetlist.begin(), tmpi);
795 InsetTable * tmpi = new InsetTable;
798 tmpi->next = insettable;
805 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
809 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
810 return NextAfterFootnote()
811 ->GetInset(pos - text.size() - 1);
813 lyxerr << "ERROR (LyXParagraph::GetInset): "
814 "position does not exist: "
820 #ifdef NEW_INSETTABLE
821 for (InsetList::iterator it = insetlist.begin();
822 it != insetlist.end(); ++it) {
823 if ((*it).pos == pos) {
827 lyxerr << "ERROR (LyXParagraph::GetInset): "
828 "Inset does not exist: " << pos << endl;
829 text[pos] = ' '; // WHY!!! does this set the pos to ' '????
830 // Did this commenting out introduce a bug? So far I have not
831 // see any, please enlighten me. (Lgb)
832 // My guess is that since the inset does not exist, we might
833 // as well replace it with a space to prevent craches. (Asger)
836 InsetTable * tmpi = insettable;
838 while (tmpi && tmpi->pos != pos)
844 lyxerr << "ERROR (LyXParagraph::GetInset): "
845 "Inset does not exist: " << pos << endl;
846 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
847 // Did this commenting out introduce a bug? So far I have not
848 // seen any, please enlighten me. (Lgb)
849 // My guess is that since the inset does not exist, we might
850 // as well replace it with a space to prevent crashes. (Asger)
857 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
861 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
862 return NextAfterFootnote()
863 ->GetInset(pos - text.size() - 1);
865 lyxerr << "ERROR (LyXParagraph::GetInset): "
866 "position does not exist: "
872 #ifdef NEW_INSETTABLE
873 for (InsetList::const_iterator cit = insetlist.begin();
874 cit != insetlist.end(); ++cit) {
875 if ((*cit).pos == pos) {
879 lyxerr << "ERROR (LyXParagraph::GetInset): "
880 "Inset does not exist: " << pos << endl;
881 //text[pos] = ' '; // WHY!!! does this set the pos to ' '????
882 // Did this commenting out introduce a bug? So far I have not
883 // see any, please enlighten me. (Lgb)
884 // My guess is that since the inset does not exist, we might
885 // as well replace it with a space to prevent craches. (Asger)
888 InsetTable * tmpi = insettable;
890 while (tmpi && tmpi->pos != pos)
896 lyxerr << "ERROR (LyXParagraph::GetInset): "
897 "Inset does not exist: " << pos << endl;
898 // in the const version we need to comment it out anyway...
899 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
900 // Did this commenting out introduce a bug? So far I have not
901 // seen any, please enlighten me. (Lgb)
902 // My guess is that since the inset does not exist, we might
903 // as well replace it with a space to prevent crashes. (Asger)
910 // Gets uninstantiated font setting at position.
911 // Optimized after profiling. (Asger)
912 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
915 #ifdef NEW_FONTTABLE // Seems OK
916 for (FontList::const_iterator cit = fontlist.begin();
917 cit != fontlist.end(); ++cit) {
918 if (pos >= (*cit).pos && pos <= (*cit).pos_end)
922 FontTable * tmp = fonttable;
924 if (pos >= tmp->pos && pos <= tmp->pos_end)
930 // > because last is the next unused position, and you can
931 // use it if you want
932 else if (pos > size()) {
934 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
935 return NextAfterFootnote()
936 ->GetFontSettings(pos - text.size() - 1);
938 // Why is it an error to ask for the font of a
939 // position that does not exist? Would it be
940 // enough for this to be anable on debug?
941 // We want strict error checking, but it's ok to only
942 // have it when debugging. (Asger)
943 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
944 "position does not exist. "
945 << pos << " (" << static_cast<int>(pos)
949 return GetFontSettings(pos - 1);
951 return LyXFont(LyXFont::ALL_INHERIT);
955 // Gets the fully instantiated font at a given position in a paragraph
956 // This is basically the same function as LyXText::GetFont() in text2.C.
957 // The difference is that this one is used for generating the LaTeX file,
958 // and thus cosmetic "improvements" are disallowed: This has to deliver
959 // the true picture of the buffer. (Asger)
960 // If position is -1, we get the layout font of the paragraph.
961 // If position is -2, we get the font of the manual label of the paragraph.
962 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
965 LyXLayout const & layout = textclasslist.Style(current_view->buffer()->params.textclass,
967 LyXParagraph::size_type main_body = 0;
968 if (layout.labeltype == LABEL_MANUAL)
969 main_body = BeginningOfMainBody();
974 layoutfont = layout.labelfont;
976 layoutfont = layout.font;
977 tmpfont = GetFontSettings(pos);
978 tmpfont.realize(layoutfont);
980 // process layoutfont for pos == -1 and labelfont for pos < -1
982 tmpfont = layout.font;
984 tmpfont = layout.labelfont;
987 // check for environment font information
988 char par_depth = GetDepth();
989 LyXParagraph const * par = this;
990 while (par && par_depth && !tmpfont.resolved()) {
991 par = par->DepthHook(par_depth - 1);
993 tmpfont.realize(textclasslist.
994 Style(current_view->buffer()->params.textclass,
995 par->GetLayout()).font);
996 par_depth = par->GetDepth();
1000 tmpfont.realize(textclasslist.TextClass(current_view->buffer()->params.textclass).defaultfont());
1005 /// Returns the height of the highest font in range
1007 LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos,
1008 LyXParagraph::size_type endpos) const
1010 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
1011 #ifdef NEW_FONTTABLE // Seems OK
1012 for (FontList::const_iterator cit = fontlist.begin();
1013 cit != fontlist.end(); ++cit) {
1014 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1015 LyXFont::FONT_SIZE size = (*cit).font.size();
1016 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1021 FontTable * tmp = fonttable;
1023 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1024 LyXFont::FONT_SIZE size = tmp->font.size();
1025 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1035 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1042 // > because last is the next unused position, and you can
1043 // use it if you want
1044 else if (pos > size()) {
1045 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1046 return NextAfterFootnote()
1047 ->GetChar(pos - text.size() - 1);
1049 lyxerr << "ERROR (LyXParagraph::GetChar): "
1050 "position does not exist."
1051 << pos << " (" << static_cast<int>(pos)
1056 // We should have a footnote environment.
1057 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1058 // Notice that LyX does request the
1059 // last char from time to time. (Asger)
1060 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1061 // "expected footnote." << endl;
1064 switch (next->footnotekind) {
1065 case LyXParagraph::FOOTNOTE:
1066 return LyXParagraph::META_FOOTNOTE;
1067 case LyXParagraph::MARGIN:
1068 return LyXParagraph::META_MARGIN;
1069 case LyXParagraph::FIG:
1070 case LyXParagraph::WIDE_FIG:
1071 return LyXParagraph::META_FIG;
1072 case LyXParagraph::TAB:
1073 case LyXParagraph::WIDE_TAB:
1074 return LyXParagraph::META_TAB;
1075 case LyXParagraph::ALGORITHM:
1076 return LyXParagraph::META_ALGORITHM;
1078 return '\0'; // to shut up gcc
1083 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1090 // > because last is the next unused position, and you can
1091 // use it if you want
1092 else if (pos > size()) {
1093 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1094 return NextAfterFootnote()
1095 ->GetChar(pos - text.size() - 1);
1097 lyxerr << "ERROR (LyXParagraph::GetChar): "
1098 "position does not exist."
1099 << pos << " (" << static_cast<int>(pos)
1104 // We should have a footnote environment.
1105 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1106 // Notice that LyX does request the
1107 // last char from time to time. (Asger)
1108 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1109 // "expected footnote." << endl;
1112 switch (next->footnotekind) {
1113 case LyXParagraph::FOOTNOTE:
1114 return LyXParagraph::META_FOOTNOTE;
1115 case LyXParagraph::MARGIN:
1116 return LyXParagraph::META_MARGIN;
1117 case LyXParagraph::FIG:
1118 case LyXParagraph::WIDE_FIG:
1119 return LyXParagraph::META_FIG;
1120 case LyXParagraph::TAB:
1121 case LyXParagraph::WIDE_TAB:
1122 return LyXParagraph::META_TAB;
1123 case LyXParagraph::ALGORITHM:
1124 return LyXParagraph::META_ALGORITHM;
1126 return '\0'; // to shut up gcc
1131 // return an string of the current word, and the end of the word in lastpos.
1132 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1136 // the current word is defined as starting at the first character from
1137 // the immediate left of lastpospos which meets the definition of IsLetter(),
1138 // continuing to the last character to the right of this meeting
1145 // move back until we have a letter
1147 //there's no real reason to have firstpos & lastpos as
1148 //separate variables as this is written, but maybe someon
1149 // will want to return firstpos in the future.
1151 //since someone might have typed a punctuation first
1152 int firstpos = lastpos;
1154 while ((firstpos >= 0) && !IsLetter(firstpos))
1157 // now find the beginning by looking for a nonletter
1159 while ((firstpos>= 0) && IsLetter(firstpos))
1162 // the above is now pointing to the preceeding non-letter
1166 // so copy characters into theword until we get a nonletter
1167 // note that this can easily exceed lastpos, wich means
1168 // that if used in the middle of a word, the whole word
1171 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1178 LyXParagraph::size_type LyXParagraph::Last() const
1180 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1181 return text.size() + NextAfterFootnote()->Last() + 1;
1182 // the 1 is the symbol
1189 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1191 // > because last is the next unused position, and you can
1192 // use it if you want
1195 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1196 return NextAfterFootnote()
1197 ->ParFromPos(pos - text.size() - 1);
1199 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1200 "position does not exist." << endl;
1208 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1210 // > because last is the next unused position, and you can
1211 // use it if you want
1214 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1215 return NextAfterFootnote()
1216 ->PositionInParFromPos(pos - text.size() - 1);
1219 "ERROR (LyXParagraph::PositionInParFromPos): "
1220 "position does not exist." << endl;
1228 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1229 LyXFont const & font)
1231 // > because last is the next unused position, and you can
1232 // use it if you want
1234 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1235 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1238 lyxerr << "ERROR (LyXParagraph::SetFont): "
1239 "position does not exist." << endl;
1243 LyXFont patternfont(LyXFont::ALL_INHERIT);
1245 // First, reduce font against layout/label font
1246 // Update: The SetCharFont() routine in text2.C already
1247 // reduces font, so we don't need to do that here. (Asger)
1248 // No need to simplify this because it will disappear
1249 // in a new kernel. (Asger)
1250 // Next search font table
1251 #ifdef NEW_FONTTABLE
1252 FontList::iterator tmp = fontlist.begin();
1253 for (; tmp != fontlist.end(); ++tmp) {
1254 if (pos >= (*tmp).pos && pos <= (*tmp).pos_end) {
1258 if (tmp == fontlist.end()) { // !found
1259 // if we did not find a font entry, but if the font at hand
1260 // is the same as default, we just forget it
1261 if (font == patternfont) return;
1263 // ok, we did not find a font entry. But maybe there is exactly
1264 // the needed font ientry one position left
1265 FontList::iterator tmp2 = fontlist.begin();
1266 for (; tmp2 != fontlist.end(); ++tmp2) {
1267 if (pos - 1 >= (*tmp2).pos
1268 && pos - 1 <= (*tmp2).pos_end)
1271 if (tmp2 != fontlist.end()) {
1272 // ok there is one, maybe it is exactly
1274 if ((*tmp2).font == font) {
1275 // put the position under the font
1280 // Add a new entry in the
1281 // fontlist for the position
1285 ft.font = font; // or patternfont
1286 // It seems that using font instead of patternfont here
1287 // fixes all the problems. This also surfaces a "bug" in
1289 fontlist.insert(fontlist.begin(), ft);
1290 } else if ((*tmp).pos != (*tmp).pos_end) { // we found a font entry. maybe we have to split it and create a new one.
1292 // more than one character
1293 if (pos == (*tmp).pos) {
1294 // maybe we should enlarge the left fonttable
1295 FontList::iterator tmp2 = fontlist.begin();
1296 for (; tmp2 != fontlist.end(); ++tmp2) {
1297 if (pos - 1 >= (*tmp2).pos
1298 && pos - 1 <= (*tmp2).pos_end)
1301 // Is there is one, and is it exactly
1303 if (tmp2 != fontlist.end() &&
1304 (*tmp2).font == font) {
1305 // Put the position under the font
1311 // Add a new entry in the
1312 // fontlist for the position
1315 ft.pos_end = (*tmp).pos_end;
1316 ft.font = (*tmp).font;
1317 (*tmp).pos_end = pos;
1319 fontlist.insert(fontlist.begin(), ft);
1320 } else if (pos == (*tmp).pos_end) {
1321 // Add a new entry in the
1322 // fontlist for the position
1324 ft.pos = (*tmp).pos;
1325 ft.pos_end = (*tmp).pos_end - 1;
1326 ft.font = (*tmp).font;
1327 (*tmp).pos = (*tmp).pos_end;
1329 fontlist.insert(fontlist.begin(), ft);
1331 // Add a new entry in the
1332 // fontlist for the position
1334 ft.pos = (*tmp).pos;
1335 ft.pos_end = pos - 1;
1336 ft.font = (*tmp).font;
1340 ft2.pos_end = (*tmp).pos_end;
1341 ft2.font = (*tmp).font;
1344 (*tmp).pos_end = pos;
1347 fontlist.insert(fontlist.begin(), ft);
1348 fontlist.insert(fontlist.begin(), ft2);
1358 FontTable * tmp = fonttable;
1359 while (tmp && !found) {
1360 if (pos >= tmp->pos && pos <= tmp->pos_end)
1367 // if we did not find a font entry, but if the font at hand
1368 // is the same as default, we just forget it
1369 if (font == patternfont)
1372 // ok, we did not find a font entry. But maybe there is exactly
1373 // the needed font entry one position left
1376 while (tmp2 && !found) {
1377 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1383 // ok there is one. maybe it is exactly
1385 if (tmp2->font == font) {
1386 // put the position under the font
1391 // Add a new entry in the
1392 // fonttable for the position
1393 tmp = new FontTable;
1396 tmp->font = patternfont; // It seems that is actually totally
1397 // wrong to use patternfont here, the correct should be font
1398 // lockily at the end of this function we have
1399 // tmp->font = font, so this one setting it to patternfont
1401 tmp->next = fonttable;
1404 // we found a font entry. maybe we have
1405 // to split it and create a new one
1407 if (tmp->pos != tmp->pos_end) { // more than one character
1408 if (pos == tmp->pos) {
1409 // maybe we could enlarge the left fonttable
1412 while (tmp2 && !found) {
1413 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1419 // Is there is one, and is it exactly
1421 if (found && tmp2->font == font) {
1422 // Put the position under the font
1428 // Add a new entry in the
1429 // fonttable for the position
1430 tmp2 = new FontTable;
1431 tmp2->pos = pos + 1;
1432 tmp2->pos_end = tmp->pos_end;
1433 tmp2->font = tmp->font;
1435 tmp2->next = fonttable;
1438 else if (pos == tmp->pos_end) {
1439 // Add a new entry in the
1440 // fonttable for the position
1441 tmp2 = new FontTable;
1442 tmp2->pos = tmp->pos;
1443 tmp2->pos_end = tmp->pos_end - 1;
1444 tmp2->font = tmp->font;
1445 tmp->pos = tmp->pos_end;
1446 tmp2->next = fonttable;
1450 // Add a new entry in the
1451 // fonttable for the position
1452 tmp2 = new FontTable;
1453 tmp2->pos = tmp->pos;
1454 tmp2->pos_end = pos - 1;
1455 tmp2->font = tmp->font;
1456 tmp2->next = fonttable;
1459 tmp2 = new FontTable;
1460 tmp2->pos = pos + 1;
1461 tmp2->pos_end = tmp->pos_end;
1462 tmp2->font = tmp->font;
1463 tmp2->next = fonttable;
1476 // This function is able to hide closed footnotes.
1477 LyXParagraph * LyXParagraph::Next()
1479 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1480 LyXParagraph * tmp = next;
1482 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1484 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1485 return tmp->Next(); /* there can be more than one
1486 footnote in a logical
1489 return next; // This should never happen!
1496 LyXParagraph * LyXParagraph::NextAfterFootnote()
1498 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1499 LyXParagraph * tmp = next;
1500 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1502 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1503 return tmp; /* there can be more than one footnote
1504 in a logical paragraph */
1506 return next; // This should never happen!
1513 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1515 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1516 LyXParagraph * tmp = next;
1517 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1519 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1520 return tmp; /* there can be more than one footnote
1521 in a logical paragraph */
1523 return next; // This should never happen!
1530 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1533 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1535 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1536 tmp = tmp->previous;
1537 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1538 return tmp; /* there can be more than one footnote
1539 in a logical paragraph */
1541 return previous; // This should never happen!
1548 LyXParagraph * LyXParagraph::LastPhysicalPar()
1550 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1553 LyXParagraph * tmp = this;
1555 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1556 tmp = tmp->NextAfterFootnote();
1563 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1567 LyXParagraph * tmppar = this;
1569 while (tmppar && (tmppar->IsDummy()
1570 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1571 tmppar = tmppar->previous;
1574 return this; // This should never happen!
1580 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1584 LyXParagraph const * tmppar = this;
1586 while (tmppar && (tmppar->IsDummy()
1587 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1588 tmppar = tmppar->previous;
1591 return this; // This should never happen!
1597 // This function is able to hide closed footnotes.
1598 LyXParagraph * LyXParagraph::Previous()
1600 LyXParagraph * tmp = previous;
1605 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1606 tmp = tmp->previous;
1608 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1609 tmp = tmp->previous;
1610 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1611 return tmp->next->Previous();
1621 // This function is able to hide closed footnotes.
1622 LyXParagraph const * LyXParagraph::Previous() const
1624 LyXParagraph * tmp = previous;
1629 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1630 tmp = tmp->previous;
1632 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1633 tmp = tmp->previous;
1634 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1635 return tmp->next->Previous();
1645 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1648 size_type i, pos_end, pos_first;
1649 // create a new paragraph
1650 LyXParagraph * par = ParFromPos(pos);
1651 LyXParagraph * firstpar = FirstPhysicalPar();
1653 LyXParagraph * tmp = new LyXParagraph(par);
1655 tmp->footnoteflag = footnoteflag;
1656 tmp->footnotekind = footnotekind;
1658 // this is an idea for a more userfriendly layout handling, I will
1659 // see what the users say */
1661 // layout stays the same with latex-environments
1663 tmp->SetOnlyLayout(firstpar->layout);
1664 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1667 if (Last() > pos || !Last() || flag == 2) {
1668 tmp->SetOnlyLayout(firstpar->layout);
1669 tmp->align = firstpar->align;
1670 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1672 tmp->line_bottom = firstpar->line_bottom;
1673 firstpar->line_bottom = false;
1674 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1675 firstpar->pagebreak_bottom = false;
1676 tmp->added_space_bottom = firstpar->added_space_bottom;
1677 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1679 tmp->depth = firstpar->depth;
1680 tmp->noindent = firstpar->noindent;
1682 // copy everything behind the break-position
1683 // to the new paragraph
1685 while (ParFromPos(pos_first) != par)
1688 pos_end = pos_first + par->text.size() - 1;
1689 tmp->text.reserve(pos_end - pos);
1691 for (i = pos; i <= pos_end; i++) {
1692 par->CutIntoMinibuffer(i - pos_first);
1693 tmp->InsertFromMinibuffer(i - pos);
1696 for (i = pos_end; i >= pos; i--)
1697 par->Erase(i - pos_first);
1699 par->text.resize(par->text.size());
1702 // just an idea of me
1704 tmp->line_top = firstpar->line_top;
1705 tmp->pagebreak_top = firstpar->pagebreak_top;
1706 tmp->added_space_top = firstpar->added_space_top;
1707 tmp->bibkey = firstpar->bibkey;
1709 // layout stays the same with latex-environments
1711 firstpar->SetOnlyLayout(tmp->layout);
1712 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1713 firstpar->depth = tmp->depth;
1719 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1721 par = par->FirstPhysicalPar();
1722 footnoteflag = par->footnoteflag;
1723 footnotekind = par->footnotekind;
1725 layout = par->layout;
1726 align = par-> align;
1727 SetLabelWidthString(par->labelwidthstring);
1729 line_bottom = par->line_bottom;
1730 pagebreak_bottom = par->pagebreak_bottom;
1731 added_space_bottom = par->added_space_bottom;
1733 line_top = par->line_top;
1734 pagebreak_top = par->pagebreak_top;
1735 added_space_top = par->added_space_top;
1737 pextra_type = par->pextra_type;
1738 pextra_width = par->pextra_width;
1739 pextra_widthp = par->pextra_widthp;
1740 pextra_alignment = par->pextra_alignment;
1741 pextra_hfill = par->pextra_hfill;
1742 pextra_start_minipage = par->pextra_start_minipage;
1744 noindent = par->noindent;
1749 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1751 LyXParagraph * tmppar = this;
1754 && tmppar->previous->footnoteflag ==
1755 LyXParagraph::CLOSED_FOOTNOTE)
1756 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1757 tmppar = tmppar->previous;
1760 return this; // This should never happen!
1766 LyXParagraph * LyXParagraph::Clone() const
1768 // create a new paragraph
1769 LyXParagraph * result = new LyXParagraph;
1771 result->MakeSameLayout(this);
1773 // this is because of the dummy layout of the paragraphs that
1775 result->layout = layout;
1777 /* table stuff -- begin*/
1779 result->table = table->Clone();
1782 /* table stuff -- end*/
1785 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1788 // copy everything behind the break-position to the new paragraph
1790 for (size_type i = 0; i < size(); i++) {
1791 CopyIntoMinibuffer(i);
1792 result->InsertFromMinibuffer(i);
1794 result->text.resize(result->text.size());
1799 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1801 par = par->FirstPhysicalPar();
1804 par->footnoteflag == footnoteflag &&
1805 par->footnotekind == footnotekind &&
1807 par->layout == layout &&
1809 par->align == align &&
1811 par->line_bottom == line_bottom &&
1812 par->pagebreak_bottom == pagebreak_bottom &&
1813 par->added_space_bottom == added_space_bottom &&
1815 par->line_top == line_top &&
1816 par->pagebreak_top == pagebreak_top &&
1817 par->added_space_top == added_space_top &&
1819 par->pextra_type == pextra_type &&
1820 par->pextra_width == pextra_width &&
1821 par->pextra_widthp == pextra_widthp &&
1822 par->pextra_alignment == pextra_alignment &&
1823 par->pextra_hfill == pextra_hfill &&
1824 par->pextra_start_minipage == pextra_start_minipage &&
1826 par->table == table && // what means: NO TABLE AT ALL
1828 par->noindent == noindent &&
1829 par->depth == depth);
1833 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1835 size_type i, pos_end, pos_first;
1837 // create a new paragraph
1838 LyXParagraph * par = ParFromPos(pos);
1840 LyXParagraph * tmp = new LyXParagraph(par);
1842 tmp->MakeSameLayout(par);
1845 // copy everything behind the break-position to the new
1848 while (ParFromPos(pos_first) != par)
1850 pos_end = pos_first + par->text.size() - 1;
1851 // make shure there is enough memory for the now larger
1852 // paragraph. This is not neccessary, because
1853 // InsertFromMinibuffer will enlarge the memory (it uses
1854 // InsertChar of course). But doing it by hand
1855 // is MUCH faster! (only one time, not thousend times!!)
1856 tmp->text.reserve(pos_end - pos);
1858 for (i = pos; i <= pos_end; i++) {
1860 par->CutIntoMinibuffer(i - pos_first);
1861 tmp->InsertFromMinibuffer(i - pos);
1863 for (i = pos_end; i >= pos; i--)
1864 par->Erase(i - pos_first);
1866 par->text.resize(par->text.size());
1871 // Be carefull, this does not make any check at all.
1872 void LyXParagraph::PasteParagraph()
1874 // copy the next paragraph to this one
1875 LyXParagraph * the_next = Next();
1877 LyXParagraph * firstpar = FirstPhysicalPar();
1879 // first the DTP-stuff
1880 firstpar->line_bottom = the_next->line_bottom;
1881 firstpar->added_space_bottom = the_next->added_space_bottom;
1882 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1884 size_type pos_end = the_next->text.size() - 1;
1885 size_type pos_insert = Last();
1888 // ok, now copy the paragraph
1889 for (i = 0; i <= pos_end; i++) {
1890 the_next->CutIntoMinibuffer(i);
1891 InsertFromMinibuffer(pos_insert + i);
1894 // delete the next paragraph
1899 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1901 LyXParagraph * par = ParFromPos(pos);
1903 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1904 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1910 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1912 LyXParagraph * par = ParFromPos(pos);
1914 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1915 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1921 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1923 return FirstPhysicalPar()->layout;
1927 char LyXParagraph::GetDepth() const
1929 return FirstPhysicalPar()->depth;
1933 char LyXParagraph::GetAlign() const
1935 return FirstPhysicalPar()->align;
1939 string LyXParagraph::GetLabestring() const
1941 return FirstPhysicalPar()->labelstring;
1945 int LyXParagraph::GetFirstCounter(int i) const
1947 return FirstPhysicalPar()->counter_[i];
1951 // the next two functions are for the manual labels
1952 string LyXParagraph::GetLabelWidthString() const
1954 if (!FirstPhysicalPar()->labelwidthstring.empty())
1955 return FirstPhysicalPar()->labelwidthstring;
1957 return _("Senseless with this layout!");
1961 void LyXParagraph::SetLabelWidthString(string const & s)
1963 LyXParagraph * par = FirstPhysicalPar();
1965 par->labelwidthstring = s;
1969 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1971 LyXParagraph * par = FirstPhysicalPar();
1972 LyXParagraph * ppar = 0;
1973 LyXParagraph * npar = 0;
1975 par->layout = new_layout;
1976 /* table stuff -- begin*/
1979 /* table stuff -- end*/
1980 if (par->pextra_type == PEXTRA_NONE) {
1981 if (par->Previous()) {
1982 ppar = par->Previous()->FirstPhysicalPar();
1985 && (ppar->depth > par->depth))
1986 ppar = ppar->Previous()->FirstPhysicalPar();
1989 npar = par->Next()->NextAfterFootnote();
1992 && (npar->depth > par->depth))
1993 npar = npar->Next()->NextAfterFootnote();
1995 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1997 p1 = ppar->pextra_width,
1998 p2 = ppar->pextra_widthp;
1999 ppar->SetPExtraType(ppar->pextra_type,
2000 p1.c_str(), p2.c_str());
2002 if ((par->pextra_type == PEXTRA_NONE) &&
2003 npar && (npar->pextra_type != PEXTRA_NONE)) {
2005 p1 = npar->pextra_width,
2006 p2 = npar->pextra_widthp;
2007 npar->SetPExtraType(npar->pextra_type,
2008 p1.c_str(), p2.c_str());
2014 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
2017 * par = FirstPhysicalPar(),
2021 par->layout = new_layout;
2022 par->labelwidthstring.clear();
2023 par->align = LYX_ALIGN_LAYOUT;
2024 par->added_space_top = VSpace(VSpace::NONE);
2025 par->added_space_bottom = VSpace(VSpace::NONE);
2026 /* table stuff -- begin*/
2029 /* table stuff -- end*/
2030 if (par->pextra_type == PEXTRA_NONE) {
2031 if (par->Previous()) {
2032 ppar = par->Previous()->FirstPhysicalPar();
2035 && (ppar->depth > par->depth))
2036 ppar = ppar->Previous()->FirstPhysicalPar();
2039 npar = par->Next()->NextAfterFootnote();
2042 && (npar->depth > par->depth))
2043 npar = npar->Next()->NextAfterFootnote();
2045 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2047 p1 = ppar->pextra_width,
2048 p2 = ppar->pextra_widthp;
2049 ppar->SetPExtraType(ppar->pextra_type,
2050 p1.c_str(), p2.c_str());
2052 if ((par->pextra_type == PEXTRA_NONE) &&
2053 npar && (npar->pextra_type != PEXTRA_NONE)) {
2055 p1 = npar->pextra_width,
2056 p2 = npar->pextra_widthp;
2057 npar->SetPExtraType(npar->pextra_type,
2058 p1.c_str(), p2.c_str());
2064 // if the layout of a paragraph contains a manual label, the beginning of the
2065 // main body is the beginning of the second word. This is what the par-
2066 // function returns. If the layout does not contain a label, the main
2067 // body always starts with position 0. This differentiation is necessary,
2068 // because there cannot be a newline or a blank <= the beginning of the
2069 // main body in TeX.
2071 int LyXParagraph::BeginningOfMainBody() const
2073 if (FirstPhysicalPar() != this)
2076 // Unroll the first two cycles of the loop
2077 // and remember the previous character to
2078 // remove unnecessary GetChar() calls
2081 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2083 char previous_char, temp;
2085 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2086 // Yes, this ^ is supposed to be "= " not "=="
2089 && previous_char != ' '
2090 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2092 previous_char = temp;
2097 if (i == 0 && i == size() &&
2098 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2099 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2100 i++; /* the cursor should not jump
2101 * to the main body if there
2107 LyXParagraph * LyXParagraph::DepthHook(int deth)
2109 LyXParagraph * newpar = this;
2114 newpar = newpar->FirstPhysicalPar()->Previous();
2115 } while (newpar && newpar->GetDepth() > deth
2116 && newpar->footnoteflag == footnoteflag);
2119 if (Previous() || GetDepth())
2120 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2124 return newpar->FirstPhysicalPar();
2128 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2130 LyXParagraph const * newpar = this;
2135 newpar = newpar->FirstPhysicalPar()->Previous();
2136 } while (newpar && newpar->GetDepth() > deth
2137 && newpar->footnoteflag == footnoteflag);
2140 if (Previous() || GetDepth())
2141 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2145 return newpar->FirstPhysicalPar();
2149 int LyXParagraph::AutoDeleteInsets()
2151 #ifdef NEW_INSETTABLE
2152 vector<size_type> tmpvec;
2154 for (InsetList::iterator it = insetlist.begin();
2155 it != insetlist.end(); ++it) {
2156 if ((*it).inset && (*it).inset->AutoDelete()) {
2157 tmpvec.push_back((*it).pos);
2161 for (vector<size_type>::const_iterator cit = tmpvec.begin();
2162 cit != tmpvec.end(); ++cit) {
2167 InsetTable * tmpi = insettable;
2168 InsetTable * tmpi2 = tmpi;
2174 if (tmpi2->inset->AutoDelete()) {
2179 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2180 "cannot auto-delete insets" << endl;
2188 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2190 #ifdef NEW_INSETTABLE
2191 InsetList::iterator it2 = insetlist.end();
2192 for (InsetList::iterator it = insetlist.begin();
2193 it != insetlist.end(); ++it) {
2194 if ((*it).pos >= pos) {
2195 if (it2 != insetlist.end() || (*it).pos < (*it2).pos)
2199 if (it2 != insetlist.end()) {
2201 return (*it2).inset;
2205 InsetTable * tmpi = insettable;
2206 InsetTable * tmpi2 = 0;
2208 if (tmpi->pos >= pos) {
2209 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2216 return tmpi2->inset;
2224 // returns -1 if inset not found
2225 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2228 #ifdef NEW_INSETTABLE
2229 for (InsetList::const_iterator cit = insetlist.begin();
2230 cit != insetlist.end(); ++cit) {
2231 if ((*cit).inset == inset) {
2236 InsetTable * tmpi = insettable;
2237 while (tmpi && tmpi->inset != inset) {
2240 if (tmpi && tmpi->inset)
2243 // Think about footnotes.
2244 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2245 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2247 NextAfterFootnote()->GetPositionOfInset(inset);
2249 return text.size() + 1 + further;
2255 void LyXParagraph::readSimpleWholeFile(istream & is)
2261 InsertChar(text.size(), c);
2266 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2267 string & foot, TexRow & foot_texrow,
2270 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2271 LyXParagraph * par = next;
2272 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2275 bool further_blank_line = false;
2277 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2279 if (start_of_appendix) {
2280 file += "\\appendix\n";
2284 if (tex_code_break_column && style.isCommand()){
2289 if (pagebreak_top) {
2290 file += "\\newpage";
2291 further_blank_line = true;
2293 if (added_space_top.kind() != VSpace::NONE) {
2294 file += added_space_top.asLatexCommand();
2295 further_blank_line = true;
2299 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2300 file += "\\vspace{-1\\parskip}";
2301 further_blank_line = true;
2304 if (further_blank_line){
2309 switch (style.latextype) {
2312 file += style.latexname();
2313 file += style.latexparam();
2315 case LATEX_ITEM_ENVIRONMENT:
2317 bibkey->Latex(file, false);
2321 case LATEX_LIST_ENVIRONMENT:
2328 bool need_par = SimpleTeXOnePar(file, texrow);
2330 // Spit out footnotes
2331 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2332 && par->footnoteflag != footnoteflag) {
2333 par = par->TeXFootnote(file, texrow,
2334 foot, foot_texrow, foot_count);
2335 par->SimpleTeXOnePar(file, texrow);
2339 // Make sure that \\par is done with the font of the last
2340 // character if this has another size as the default.
2341 // This is necessary because LaTeX (and LyX on the screen)
2342 // calculates the space between the baselines according
2343 // to this font. (Matthias)
2344 LyXFont font = getFont(Last()-1);
2346 if (style.resfont.size() != font.size()) {
2348 file += font.latexSize();
2352 } else if (textclasslist.Style(current_view->buffer()->params.textclass,
2353 GetLayout()).isCommand()){
2354 if (style.resfont.size() != font.size()) {
2356 file += font.latexSize();
2360 } else if (style.resfont.size() != font.size()){
2361 file += "{\\" + font.latexSize() + " \\par}";
2364 switch (style.latextype) {
2365 case LATEX_ITEM_ENVIRONMENT:
2366 case LATEX_LIST_ENVIRONMENT:
2367 if (par && (depth < par->depth)) {
2372 case LATEX_ENVIRONMENT:
2373 // if its the last paragraph of the current environment
2374 // skip it otherwise fall through
2376 && (par->layout != layout
2377 || par->depth != depth
2378 || par->pextra_type != pextra_type))
2381 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2382 && footnotekind != LyXParagraph::FOOTNOTE
2383 && footnotekind != LyXParagraph::MARGIN
2387 // don't insert this if we would be adding it
2388 // before or after a table in a float. This
2389 // little trick is needed in order to allow
2390 // use of tables in \subfigures or \subtables.
2396 further_blank_line = false;
2398 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2399 further_blank_line = true;
2402 if (added_space_bottom.kind() != VSpace::NONE) {
2403 file += added_space_bottom.asLatexCommand();
2404 further_blank_line = true;
2407 if (pagebreak_bottom) {
2408 file += "\\newpage";
2409 further_blank_line = true;
2412 if (further_blank_line){
2417 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2418 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2423 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2428 // This one spits out the text of the paragraph
2429 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2431 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2434 return SimpleTeXOneTablePar(file, texrow);
2437 size_type main_body;
2439 bool return_value = false;
2441 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2444 // Maybe we have to create a optional argument.
2445 if (style.labeltype != LABEL_MANUAL)
2448 main_body = BeginningOfMainBody();
2450 if (main_body > 0) {
2452 basefont = getFont(-2); // Get label font
2454 basefont = getFont(-1); // Get layout font
2462 if (style.isCommand()) {
2465 } else if (align != LYX_ALIGN_LAYOUT) {
2468 return_value = true;
2472 // Which font is currently active?
2473 LyXFont running_font = basefont;
2474 // Do we have an open font change?
2475 bool open_font = false;
2477 texrow.start(this, 0);
2479 for (size_type i = 0; i < size(); ++i) {
2481 // First char in paragraph or after label?
2482 if (i == main_body && !IsDummy()) {
2483 if (main_body > 0) {
2485 column += running_font.latexWriteEndChanges(file, basefont);
2488 basefont = getFont(-1); // Now use the layout font
2489 running_font = basefont;
2493 if (style.isCommand()) {
2496 } else if (align != LYX_ALIGN_LAYOUT) {
2499 return_value = true;
2503 file += "\\noindent ";
2507 case LYX_ALIGN_NONE:
2508 case LYX_ALIGN_BLOCK:
2509 case LYX_ALIGN_LAYOUT:
2510 case LYX_ALIGN_SPECIAL: break;
2511 case LYX_ALIGN_LEFT:
2512 file += "\\raggedright ";
2515 case LYX_ALIGN_RIGHT:
2516 file += "\\raggedleft ";
2519 case LYX_ALIGN_CENTER:
2520 file += "\\centering ";
2528 // Fully instantiated font
2529 LyXFont font = getFont(i);
2531 // Spaces at end of font change are simulated to be
2532 // outside font change, i.e. we write "\textXX{text} "
2533 // rather than "\textXX{text }". (Asger)
2534 if (open_font && c == ' ' && i <= size() - 2
2535 && !getFont(i+1).equalExceptLatex(running_font)
2536 && !getFont(i+1).equalExceptLatex(font)) {
2537 font = getFont(i+1);
2539 // We end font definition before blanks
2540 if (!font.equalExceptLatex(running_font) && open_font) {
2541 column += running_font.latexWriteEndChanges(file,
2543 running_font = basefont;
2547 // Blanks are printed before start of fontswitch
2549 // Do not print the separation of the optional argument
2550 if (i != main_body - 1) {
2551 SimpleTeXBlanks(file, texrow, i,
2552 column, font, style);
2556 // Do we need to change font?
2557 if (!font.equalExceptLatex(running_font)
2558 && i != main_body-1) {
2559 column += font.latexWriteStartChanges(file, basefont);
2560 running_font = font;
2564 if (c == LyXParagraph::META_NEWLINE) {
2565 // newlines are handled differently here than
2566 // the default in SimpleTeXSpecialChars().
2567 if (!style.newline_allowed
2568 || font.latex() == LyXFont::ON) {
2572 column += running_font.latexWriteEndChanges(file, basefont);
2575 basefont = getFont(-1);
2576 running_font = basefont;
2577 if (font.family() ==
2578 LyXFont::TYPEWRITER_FAMILY) {
2584 texrow.start(this, i+1);
2587 SimpleTeXSpecialChars(file, texrow,
2588 font, running_font, basefont,
2589 open_font, style, i, column, c);
2593 // If we have an open font definition, we have to close it
2595 running_font.latexWriteEndChanges(file, basefont);
2598 // Needed if there is an optional argument but no contents.
2599 if (main_body > 0 && main_body == size()) {
2601 return_value = false;
2604 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2605 return return_value;
2609 // This one spits out the text of a table paragraph
2610 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2612 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2616 bool return_value = false;
2617 int current_cell_number = -1;
2619 LyXLayout const & style =
2620 textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2621 LyXFont basefont = getFont(-1); // Get layout font
2622 // Which font is currently active?
2623 LyXFont running_font = basefont;
2624 // Do we have an open font change?
2625 bool open_font = false;
2628 if (!IsDummy()) { // it is dummy if it is in a float!!!
2629 if (style.isCommand()) {
2632 } else if (align != LYX_ALIGN_LAYOUT) {
2635 return_value = true;
2638 file += "\\noindent ";
2642 case LYX_ALIGN_NONE:
2643 case LYX_ALIGN_BLOCK:
2644 case LYX_ALIGN_LAYOUT:
2645 case LYX_ALIGN_SPECIAL: break;
2646 case LYX_ALIGN_LEFT:
2647 file += "\\raggedright ";
2650 case LYX_ALIGN_RIGHT:
2651 file += "\\raggedleft ";
2654 case LYX_ALIGN_CENTER:
2655 file += "\\centering ";
2660 current_cell_number = -1;
2661 tmp = table->TexEndOfCell(file, current_cell_number);
2662 for (; tmp > 0 ; --tmp)
2665 texrow.start(this, 0);
2667 for (size_type i = 0; i < size(); ++i) {
2669 if (table->IsContRow(current_cell_number+1)) {
2670 if (c == LyXParagraph::META_NEWLINE)
2671 current_cell_number++;
2676 // Fully instantiated font
2677 LyXFont font = getFont(i);
2679 // Spaces at end of font change are simulated to be
2680 // outside font change.
2681 // i.e. we write "\textXX{text} " rather than
2682 // "\textXX{text }". (Asger)
2683 if (open_font && c == ' ' && i <= size() - 2
2684 && getFont(i+1) != running_font && getFont(i+1) != font) {
2685 font = getFont(i+1);
2688 // We end font definition before blanks
2689 if (font != running_font && open_font) {
2690 column += running_font.latexWriteEndChanges(file,
2692 running_font = basefont;
2695 // Blanks are printed before start of fontswitch
2697 SimpleTeXBlanks(file, texrow, i, column, font, style);
2699 // Do we need to change font?
2700 if (font != running_font) {
2701 column += font.latexWriteStartChanges(file, basefont);
2702 running_font = font;
2705 // Do we need to turn on LaTeX mode?
2706 if (font.latex() != running_font.latex()) {
2707 if (font.latex() == LyXFont::ON
2708 && style.needprotect) {
2709 file += "\\protect ";
2713 if (c == LyXParagraph::META_NEWLINE) {
2714 // special case for inside a table
2715 // different from default case in
2716 // SimpleTeXSpecialChars()
2718 column += running_font
2719 .latexWriteEndChanges(file, basefont);
2722 basefont = getFont(-1);
2723 running_font = basefont;
2724 current_cell_number++;
2725 if (table->CellHasContRow(current_cell_number) >= 0) {
2726 TeXContTableRows(file, i+1,
2727 current_cell_number,
2730 // if this cell follow only ContRows till end don't
2731 // put the EndOfCell because it is put after the
2733 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2734 current_cell_number--;
2737 int tmp = table->TexEndOfCell(file,
2738 current_cell_number);
2741 } else if (tmp < 0) {
2747 texrow.start(this, i+1);
2749 SimpleTeXSpecialChars(file, texrow,
2750 font, running_font, basefont,
2751 open_font, style, i, column, c);
2755 // If we have an open font definition, we have to close it
2757 running_font.latexWriteEndChanges(file, basefont);
2759 current_cell_number++;
2760 tmp = table->TexEndOfCell(file, current_cell_number);
2761 for (; tmp > 0; --tmp)
2763 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2764 return return_value;
2768 // This one spits out the text off ContRows in tables
2769 bool LyXParagraph::TeXContTableRows(string & file,
2770 LyXParagraph::size_type i,
2771 int current_cell_number,
2772 int & column, TexRow & texrow)
2774 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2780 bool return_value = false;
2781 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2785 basefont = getFont(-1); // Get layout font
2786 // Which font is currently active?
2787 LyXFont running_font = basefont;
2788 // Do we have an open font change?
2789 bool open_font = false;
2791 size_type lastpos = i;
2792 int cell = table->CellHasContRow(current_cell_number);
2793 ++current_cell_number;
2795 // first find the right position
2797 for (; (i < size()) && (current_cell_number<cell); ++i) {
2799 if (c == LyXParagraph::META_NEWLINE)
2800 current_cell_number++;
2804 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2808 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2813 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2817 // Fully instantiated font
2818 LyXFont font = getFont(i);
2820 // Spaces at end of font change are simulated to
2821 // be outside font change. i.e. we write
2822 // "\textXX{text} " rather than "\textXX{text }".
2824 if (open_font && c == ' ' && i <= size() - 2
2825 && getFont(i + 1) != running_font
2826 && getFont(i + 1) != font) {
2827 font = getFont(i + 1);
2830 // We end font definition before blanks
2831 if (font != running_font && open_font) {
2832 column += running_font.latexWriteEndChanges(file, basefont);
2833 running_font = basefont;
2836 // Blanks are printed before start of fontswitch
2838 SimpleTeXBlanks(file, texrow, i,
2839 column, font, style);
2841 // Do we need to change font?
2842 if (font != running_font) {
2844 font.latexWriteStartChanges(file,
2846 running_font = font;
2849 // Do we need to turn on LaTeX mode?
2850 if (font.latex() != running_font.latex()) {
2851 if (font.latex() == LyXFont::ON
2852 && style.needprotect)
2854 file += "\\protect ";
2858 SimpleTeXSpecialChars(file, texrow, font,
2859 running_font, basefont,
2860 open_font, style, i, column, c);
2862 // If we have an open font definition, we have to close it
2864 running_font.latexWriteEndChanges(file, basefont);
2867 basefont = getFont(-1);
2868 running_font = basefont;
2869 cell = table->CellHasContRow(current_cell_number);
2871 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2872 return return_value;
2876 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2878 bool retval = false;
2880 case LyXParagraph::META_HFILL:
2881 sgml_string.clear();
2883 case LyXParagraph::META_PROTECTED_SEPARATOR:
2886 case LyXParagraph::META_NEWLINE:
2890 sgml_string = "&";
2893 sgml_string = "<";
2896 sgml_string = ">";
2899 sgml_string = "$";
2902 sgml_string = "#";
2905 sgml_string = "%";
2908 sgml_string = "[";
2911 sgml_string = "]";
2914 sgml_string = "{";
2917 sgml_string = "}";
2920 sgml_string = "˜";
2923 sgml_string = """;
2926 sgml_string = "\";
2932 case '\0': // Ignore :-)
2933 sgml_string.clear();
2943 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2944 int & desc_on, int depth)
2947 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2949 LyXFont font1, font2;
2952 size_type main_body;
2953 string emph = "emphasis";
2954 bool emph_flag = false;
2956 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2959 if (style.labeltype != LABEL_MANUAL)
2962 main_body = BeginningOfMainBody();
2964 // Gets paragraph main font.
2966 font1 = style.labelfont;
2970 int char_line_count = depth;
2971 addNewlineAndDepth(file, depth);
2972 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2973 file += "<INFORMALTABLE>";
2974 addNewlineAndDepth(file, ++depth);
2976 int current_cell_number = -1;
2977 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2979 // Parsing main loop.
2980 for (size_type i = 0; i < size(); ++i) {
2982 if (table->IsContRow(current_cell_number+1)) {
2983 if (c == LyXParagraph::META_NEWLINE)
2984 ++current_cell_number;
2989 // Fully instantiated font
2992 // Handle <emphasis> tag.
2993 if (font1.emph() != font2.emph() && i) {
2994 if (font2.emph() == LyXFont::ON) {
2995 file += "<emphasis>";
2997 } else if (emph_flag) {
2998 file += "</emphasis>";
3002 if (c == LyXParagraph::META_NEWLINE) {
3003 // We have only to control for emphasis open here!
3005 file += "</emphasis>";
3008 font1 = font2 = getFont(-1);
3009 current_cell_number++;
3010 if (table->CellHasContRow(current_cell_number) >= 0) {
3011 DocBookContTableRows(file, extra, desc_on, i+1,
3012 current_cell_number,
3015 // if this cell follow only ContRows till end don't
3016 // put the EndOfCell because it is put after the
3018 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3019 current_cell_number--;
3022 tmp= table->DocBookEndOfCell(file, current_cell_number,
3027 } else if (c == LyXParagraph::META_INSET) {
3028 inset = GetInset(i);
3030 inset->DocBook(tmp_out);
3032 // This code needs some explanation:
3033 // Two insets are treated specially
3034 // label if it is the first element in a
3035 // command paragraph
3037 // graphics inside tables or figure floats
3039 // title (the equivalente in latex for this
3041 // and title should come first
3044 if(desc_on != 3 || i != 0) {
3045 if(tmp_out[0] == '@') {
3047 extra += frontStrip(tmp_out,
3050 file += frontStrip(tmp_out,
3055 } else if (font2.latex() == LyXFont::ON) {
3056 // "TeX"-Mode on == > SGML-Mode on.
3062 if (linuxDocConvertChar(c, sgml_string)
3063 && !style.free_spacing) {
3064 // in freespacing mode, spaces are
3065 // non-breaking characters
3070 file += "</term><listitem><para>";
3076 file += sgml_string;
3082 // Needed if there is an optional argument but no contents.
3083 if (main_body > 0 && main_body == size()) {
3088 file += "</emphasis>";
3091 current_cell_number++;
3092 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3093 // Resets description flag correctly.
3096 // <term> not closed...
3100 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3101 file += "</INFORMALTABLE>";
3103 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3108 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3110 LyXParagraph::size_type i,
3111 int current_cell_number, int &column)
3116 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3119 LyXFont font1, font2;
3122 size_type main_body;
3124 string emph= "emphasis";
3125 bool emph_flag= false;
3126 int char_line_count= 0;
3128 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3131 if (style.labeltype != LABEL_MANUAL)
3134 main_body = BeginningOfMainBody();
3136 // Gets paragraph main font.
3138 font1 = style.labelfont;
3143 cell = table->CellHasContRow(current_cell_number);
3144 ++current_cell_number;
3146 // first find the right position
3148 for (; i < size() && current_cell_number < cell; ++i) {
3150 if (c == LyXParagraph::META_NEWLINE)
3151 current_cell_number++;
3155 // I don't know how to handle this so I comment it
3156 // for the moment (Jug)
3157 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3158 // file += " \\\\\n";
3161 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3166 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3170 // Fully instantiated font
3173 // Handle <emphasis> tag.
3174 if (font1.emph() != font2.emph() && i) {
3175 if (font2.emph() == LyXFont::ON) {
3176 file += "<emphasis>";
3178 } else if (emph_flag) {
3179 file += "</emphasis>";
3183 if (c == LyXParagraph::META_INSET) {
3184 inset = GetInset(i);
3186 inset->DocBook(tmp_out);
3188 // This code needs some explanation:
3189 // Two insets are treated specially
3190 // label if it is the first element in a command paragraph
3192 // graphics inside tables or figure floats can't go on
3193 // title (the equivalente in latex for this case is caption
3194 // and title should come first
3197 if(desc_on != 3 || i != 0) {
3198 if(tmp_out[0] == '@') {
3200 extra += frontStrip(tmp_out, '@');
3202 file += frontStrip(tmp_out, '@');
3206 } else if (font2.latex() == LyXFont::ON) {
3207 // "TeX"-Mode on == > SGML-Mode on.
3213 if (linuxDocConvertChar(c, sgml_string)
3214 && !style.free_spacing) {
3215 // in freespacing mode, spaces are
3216 // non-breaking characters
3221 file += "</term><listitem><para>";
3227 file += sgml_string;
3231 // we have only to control for emphasis open here!
3233 file += "</emphasis>";
3236 font1 = font2 = getFont(-1);
3237 cell = table->CellHasContRow(current_cell_number);
3239 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3243 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3244 LyXParagraph::size_type const i,
3245 int & column, LyXFont const & font,
3246 LyXLayout const & style)
3248 if (column > tex_code_break_column
3250 && GetChar(i - 1) != ' '
3252 // In LaTeX mode, we don't want to
3253 // break lines since some commands
3255 && ! (font.latex() == LyXFont::ON)
3256 // same in FreeSpacing mode
3257 && !style.free_spacing
3258 // In typewriter mode, we want to avoid
3259 // ! . ? : at the end of a line
3260 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3261 && (GetChar(i-1) == '.'
3262 || GetChar(i-1) == '?'
3263 || GetChar(i-1) == ':'
3264 || GetChar(i-1) == '!'))) {
3265 if (tex_code_break_column == 0) {
3266 // in batchmode we need LaTeX to still
3267 // see it as a space not as an extra '\n'
3273 texrow.start(this, i+1);
3275 } else if (font.latex() == LyXFont::OFF) {
3276 if (style.free_spacing) {
3285 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3287 LyXFont & running_font,
3290 LyXLayout const & style,
3291 LyXParagraph::size_type & i,
3292 int & column, char const c)
3294 // Two major modes: LaTeX or plain
3295 // Handle here those cases common to both modes
3296 // and then split to handle the two modes separately.
3298 case LyXParagraph::META_INSET: {
3299 Inset * inset = GetInset(i);
3301 int len = file.length();
3302 int tmp = inset->Latex(file, style.isCommand());
3307 column += file.length() - len;
3316 case LyXParagraph::META_NEWLINE:
3318 column += running_font.latexWriteEndChanges(file,
3322 basefont = getFont(-1);
3323 running_font = basefont;
3326 case LyXParagraph::META_HFILL:
3327 file += "\\hfill{}";
3332 // And now for the special cases within each mode
3333 // Are we in LaTeX mode?
3334 if (font.latex() == LyXFont::ON) {
3335 // at present we only have one option
3336 // but I'll leave it as a switch statement
3337 // so its simpler to extend. (ARRae)
3339 case LyXParagraph::META_PROTECTED_SEPARATOR:
3344 // make sure that we will not print
3345 // error generating chars to the tex
3346 // file. This test would not be needed
3347 // if it were done in the buffer
3355 // Plain mode (i.e. not LaTeX)
3357 case LyXParagraph::META_PROTECTED_SEPARATOR:
3362 file += "\\textbackslash{}";
3366 case '°': case '±': case '²': case '³':
3367 case '×': case '÷': case '¹': case 'ª':
3368 case 'º': case '¬': case 'µ':
3369 if (current_view->buffer()->params.inputenc == "latin1") {
3370 file += "\\ensuremath{";
3379 case '|': case '<': case '>':
3380 // In T1 encoding, these characters exist
3381 if (lyxrc->fontenc == "T1") {
3383 //... but we should avoid ligatures
3384 if ((c == '>' || c == '<')
3386 && GetChar(i+1) == c){
3387 file += "\\textcompwordmark{}";
3392 // Typewriter font also has them
3393 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3397 // Otherwise, we use what LaTeX
3401 file += "\\textless{}";
3405 file += "\\textgreater{}";
3409 file += "\\textbar{}";
3415 case '-': // "--" in Typewriter mode -> "-{}-"
3417 && GetChar(i + 1) == '-'
3418 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3427 file += "\\char`\\\"{}";
3432 if (current_view->buffer()->params.inputenc == "default") {
3433 file += "\\pounds{}";
3441 case '%': case '#': case '{':
3449 file += "\\textasciitilde{}";
3454 file += "\\textasciicircum{}";
3458 case '*': case '[': case ']':
3459 // avoid being mistaken for optional arguments
3467 // Blanks are printed before font switching.
3468 // Sure? I am not! (try nice-latex)
3469 // I am sure it's correct. LyX might be smarter
3470 // in the future, but for now, nothing wrong is
3475 /* idea for labels --- begin*/
3479 && font.family() != LyXFont::TYPEWRITER_FAMILY
3480 && GetChar(i + 1) == 'y'
3481 && GetChar(i + 2) == 'X') {
3489 && font.family() != LyXFont::TYPEWRITER_FAMILY
3490 && GetChar(i + 1) == 'e'
3491 && GetChar(i + 2) == 'X') {
3496 // Check for "LaTeX2e"
3499 && font.family() != LyXFont::TYPEWRITER_FAMILY
3500 && GetChar(i + 1) == 'a'
3501 && GetChar(i + 2) == 'T'
3502 && GetChar(i + 3) == 'e'
3503 && GetChar(i + 4) == 'X'
3504 && GetChar(i + 5) == '2'
3505 && GetChar(i + 6) == 'e') {
3506 file += "\\LaTeXe{}";
3510 // Check for "LaTeX"
3513 && font.family() != LyXFont::TYPEWRITER_FAMILY
3514 && GetChar(i + 1) == 'a'
3515 && GetChar(i + 2) == 'T'
3516 && GetChar(i + 3) == 'e'
3517 && GetChar(i + 4) == 'X') {
3518 file += "\\LaTeX{}";
3521 /* idea for labels --- end*/
3522 } else if (c != '\0') {
3532 bool LyXParagraph::RoffContTableRows(ostream & os,
3533 LyXParagraph::size_type i,
3539 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3544 string fname2 = TmpFileName(string(), "RAT2");
3546 int cell = table->CellHasContRow(actcell);
3549 // first find the right position
3551 for (; i < size() && actcell < cell; ++i) {
3553 if (c == LyXParagraph::META_NEWLINE)
3558 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3561 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3563 font2 = GetFontSettings(i);
3564 if (font1.latex() != font2.latex()) {
3565 if (font2.latex() != LyXFont::OFF)
3570 case LyXParagraph::META_INSET:
3571 if ((inset = GetInset(i))) {
3572 fstream fs(fname2.c_str(),
3575 WriteAlert(_("LYX_ERROR:"),
3576 _("Cannot open temporary file:"),
3580 inset->Latex(fs, -1);
3593 case LyXParagraph::META_NEWLINE:
3595 case LyXParagraph::META_HFILL:
3597 case LyXParagraph::META_PROTECTED_SEPARATOR:
3606 lyxerr.debug() << "RoffAsciiTable: "
3607 "NULL char in structure."
3612 cell = table->CellHasContRow(actcell);
3618 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3619 string & foot, TexRow & foot_texrow,
3622 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3623 LyXParagraph * par = this;
3625 while (par && par->depth == depth) {
3627 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3628 if (textclasslist.Style(current_view->buffer()->params.textclass,
3629 par->layout).isEnvironment()
3630 || par->pextra_type != PEXTRA_NONE)
3632 par = par->TeXEnvironment(file, texrow,
3636 par = par->TeXOnePar(file, texrow,
3641 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3647 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3648 string & foot, TexRow & foot_texrow,
3651 bool eindent_open = false;
3652 bool foot_this_level = false;
3653 // flags when footnotetext should be appended to file.
3654 static bool minipage_open = false;
3655 static int minipage_open_depth = 0;
3656 char par_sep = current_view->buffer()->params.paragraph_separation;
3658 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3660 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3662 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3665 if (pextra_type == PEXTRA_INDENT) {
3666 if (!pextra_width.empty()) {
3667 file += "\\begin{LyXParagraphIndent}{"
3668 + pextra_width + "}\n";
3670 //float ib = atof(pextra_widthp.c_str())/100;
3671 // string can't handle floats at present (971109)
3672 // so I'll do a conversion by hand knowing that
3673 // the limits are 0.0 to 1.0. ARRae.
3674 file += "\\begin{LyXParagraphIndent}{";
3675 switch (pextra_widthp.length()) {
3681 file += pextra_widthp;
3685 file += pextra_widthp;
3687 file += "\\columnwidth}\n";
3690 eindent_open = true;
3692 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3693 if (pextra_hfill && Previous() &&
3694 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3695 file += "\\hfill{}\n";
3698 if (par_sep == BufferParams::PARSEP_INDENT) {
3699 file += "{\\setlength\\parindent{0pt}\n";
3702 file += "\\begin{minipage}";
3703 switch(pextra_alignment) {
3704 case MINIPAGE_ALIGN_TOP:
3707 case MINIPAGE_ALIGN_MIDDLE:
3710 case MINIPAGE_ALIGN_BOTTOM:
3714 if (!pextra_width.empty()) {
3716 file += pextra_width + "}\n";
3718 //float ib = atof(par->pextra_width.c_str())/100;
3719 // string can't handle floats at present
3720 // so I'll do a conversion by hand knowing that
3721 // the limits are 0.0 to 1.0. ARRae.
3723 switch (pextra_widthp.length()) {
3729 file += pextra_widthp;
3733 file += pextra_widthp;
3735 file += "\\columnwidth}\n";
3738 if (par_sep == BufferParams::PARSEP_INDENT) {
3739 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3742 minipage_open = true;
3743 minipage_open_depth = depth;
3746 #ifdef WITH_WARNINGS
3747 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3748 //I disabled it because it breaks when lists span on several
3751 if (style.isEnvironment()){
3752 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3753 #ifdef FANCY_FOOTNOTE_CODE
3754 if (foot_count < 0) {
3755 // flag that footnote[mark][text] should be
3756 // used for any footnotes from now on
3758 foot_this_level = true;
3761 file += "\\begin{" + style.latexname() + "}{"
3762 + labelwidthstring + "}\n";
3763 } else if (style.labeltype == LABEL_BIBLIO) {
3765 file += "\\begin{" + style.latexname() + "}{"
3766 + bibitemWidthest() + "}\n";
3767 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3768 #ifdef FANCY_FOOTNOTE_CODE
3769 if (foot_count < 0) {
3770 // flag that footnote[mark][text] should be
3771 // used for any footnotes from now on
3773 foot_this_level = true;
3776 file += "\\begin{" + style.latexname() + '}'
3777 + style.latexparam() + '\n';
3779 file += "\\begin{" + style.latexname() + '}'
3780 + style.latexparam() + '\n';
3783 LyXParagraph * par = this;
3785 par = par->TeXOnePar(file, texrow,
3786 foot, foot_texrow, foot_count);
3788 if (minipage_open && par && !style.isEnvironment() &&
3789 (par->pextra_type == PEXTRA_MINIPAGE) &&
3790 par->pextra_start_minipage) {
3791 file += "\\end{minipage}\n";
3793 if (par_sep == BufferParams::PARSEP_INDENT) {
3797 minipage_open = false;
3799 if (par && par->depth > depth) {
3800 if (textclasslist.Style(current_view->buffer()->params.textclass,
3801 par->layout).isParagraph()
3803 && !suffixIs(file, "\n\n")) {
3804 // There should be at least one '\n' already
3805 // but we need there to be two for Standard
3806 // paragraphs that are depth-increment'ed to be
3807 // output correctly. However, tables can
3808 // also be paragraphs so don't adjust them.
3813 par = par->TeXDeeper(file, texrow,
3814 foot, foot_texrow, foot_count);
3816 if (par && par->layout == layout && par->depth == depth &&
3817 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3818 if (par->pextra_hfill && par->Previous() &&
3819 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3820 file += "\\hfill{}\n";
3823 if (par_sep == BufferParams::PARSEP_INDENT) {
3824 file += "{\\setlength\\parindent{0pt}\n";
3827 file += "\\begin{minipage}";
3828 switch(par->pextra_alignment) {
3829 case MINIPAGE_ALIGN_TOP:
3832 case MINIPAGE_ALIGN_MIDDLE:
3835 case MINIPAGE_ALIGN_BOTTOM:
3839 if (!par->pextra_width.empty()) {
3841 file += par->pextra_width;
3844 //float ib = atof(par->pextra_widthp.c_str())/100;
3845 // string can't handle floats at present
3846 // so I'll do a conversion by hand knowing that
3847 // the limits are 0.0 to 1.0. ARRae.
3849 switch (par->pextra_widthp.length()) {
3855 file += par->pextra_widthp;
3859 file += par->pextra_widthp;
3861 file += "\\columnwidth}\n";
3864 if (par_sep == BufferParams::PARSEP_INDENT) {
3865 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3868 minipage_open = true;
3869 minipage_open_depth = par->depth;
3872 && par->layout == layout
3873 && par->depth == depth
3874 && par->pextra_type == pextra_type);
3876 if (style.isEnvironment()) {
3877 file += "\\end{" + style.latexname() + '}';
3878 // maybe this should go after the minipage closes?
3879 if (foot_this_level) {
3880 if (foot_count >= 1) {
3881 if (foot_count > 1) {
3882 file += "\\addtocounter{footnote}{-";
3883 file += tostr(foot_count - 1);
3887 texrow += foot_texrow;
3889 foot_texrow.reset();
3894 if (minipage_open && (minipage_open_depth == depth) &&
3895 (!par || par->pextra_start_minipage ||
3896 par->pextra_type != PEXTRA_MINIPAGE)) {
3897 file += "\\end{minipage}\n";
3899 if (par_sep == BufferParams::PARSEP_INDENT) {
3903 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3904 file += "\\medskip\n\n";
3908 minipage_open = false;
3911 file += "\\end{LyXParagraphIndent}\n";
3914 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3915 && par->pextra_hfill)) {
3919 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3920 return par; // ale970302
3924 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3925 string & foot, TexRow & foot_texrow,
3928 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3929 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3930 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3931 "No footnote!" << endl;
3933 LyXParagraph * par = this;
3934 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3935 previous->GetLayout());
3937 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3938 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3939 "Float other than footnote in command"
3940 " with moving argument is illegal" << endl;
3943 if (footnotekind != LyXParagraph::FOOTNOTE
3944 && footnotekind != LyXParagraph::MARGIN
3946 && !suffixIs(file, '\n')) {
3947 // we need to ensure that real floats like tables and figures
3948 // have their \begin{} on a new line otherwise we can get
3949 // incorrect results when using the endfloat.sty package
3950 // especially if two floats follow one another. ARRae 981022
3951 // NOTE: if the file is length 0 it must have just been
3952 // written out so we assume it ended with a '\n'
3957 BufferParams * params = ¤t_view->buffer()->params;
3958 bool footer_in_body = true;
3959 switch (footnotekind) {
3960 case LyXParagraph::FOOTNOTE:
3961 if (style.intitle) {
3962 file += "\\thanks{\n";
3963 footer_in_body = false;
3965 if (foot_count == -1) {
3966 // we're at depth 0 so we can use:
3967 file += "\\footnote{%\n";
3968 footer_in_body = false;
3970 file += "\\footnotemark{}%\n";
3972 // we only need this when there are
3973 // multiple footnotes
3974 foot += "\\stepcounter{footnote}";
3976 foot += "\\footnotetext{%\n";
3977 foot_texrow.start(this, 0);
3978 foot_texrow.newline();
3983 case LyXParagraph::MARGIN:
3984 file += "\\marginpar{\n";
3986 case LyXParagraph::FIG:
3987 if (pextra_type == PEXTRA_FLOATFLT
3988 && (!pextra_width.empty()
3989 || !pextra_widthp.empty())) {
3991 if (!pextra_width.empty())
3992 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3993 pextra_width.c_str());
3996 "\\begin{floatingfigure}{%f\\textwidth}\n",
3997 atoi(pextra_widthp.c_str())/100.0);
4000 file += "\\begin{figure}";
4001 if (!params->float_placement.empty()) {
4003 file += params->float_placement;
4010 case LyXParagraph::TAB:
4011 file += "\\begin{table}";
4012 if (!params->float_placement.empty()) {
4014 file += params->float_placement;
4020 case LyXParagraph::WIDE_FIG:
4021 file += "\\begin{figure*}";
4022 if (!params->float_placement.empty()) {
4024 file += params->float_placement;
4030 case LyXParagraph::WIDE_TAB:
4031 file += "\\begin{table*}";
4032 if (!params->float_placement.empty()) {
4034 file += params->float_placement;
4040 case LyXParagraph::ALGORITHM:
4041 file += "\\begin{algorithm}\n";
4046 if (footnotekind != LyXParagraph::FOOTNOTE
4047 || !footer_in_body) {
4048 // Process text for all floats except footnotes in body
4050 LyXLayout const & style =
4051 textclasslist.Style(current_view->buffer()->params.textclass,
4054 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4056 if (style.isEnvironment()
4057 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4058 // Allows the use of minipages within float
4059 // environments. Shouldn't be circular because
4060 // we don't support footnotes inside
4061 // floats (yet). ARRae
4062 par = par->TeXEnvironment(file, texrow,
4066 par = par->TeXOnePar(file, texrow,
4071 if (par && !par->IsDummy() && par->depth > depth) {
4072 par = par->TeXDeeper(file, texrow,
4076 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4078 // process footnotes > depth 0 or in environments separately
4079 // NOTE: Currently don't support footnotes within footnotes
4080 // even though that is possible using the \footnotemark
4082 TexRow dummy_texrow;
4083 int dummy_count = 0;
4085 LyXLayout const & style =
4086 textclasslist.Style(current_view->buffer()->params.textclass,
4089 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4091 if (style.isEnvironment()
4092 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4093 // Allows the use of minipages within float
4094 // environments. Shouldn't be circular because
4095 // we don't support footnotes inside
4096 // floats (yet). ARRae
4097 par = par->TeXEnvironment(foot, foot_texrow,
4098 dummy, dummy_texrow,
4101 par = par->TeXOnePar(foot, foot_texrow,
4102 dummy, dummy_texrow,
4106 if (par && !par->IsDummy() && par->depth > depth) {
4107 par = par->TeXDeeper(foot, foot_texrow,
4108 dummy, dummy_texrow,
4112 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4114 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4115 "Footnote in a Footnote -- not supported"
4120 switch (footnotekind) {
4121 case LyXParagraph::FOOTNOTE:
4122 if (footer_in_body) {
4123 // This helps tell which of the multiple
4124 // footnotetexts an error was in.
4126 foot_texrow.newline();
4131 case LyXParagraph::MARGIN:
4134 case LyXParagraph::FIG:
4135 if (pextra_type == PEXTRA_FLOATFLT
4136 && (!pextra_width.empty()
4137 || !pextra_widthp.empty()))
4138 file += "\\end{floatingfigure}";
4140 file += "\\end{figure}";
4142 case LyXParagraph::TAB:
4143 file += "\\end{table}";
4145 case LyXParagraph::WIDE_FIG:
4146 file += "\\end{figure*}";
4148 case LyXParagraph::WIDE_TAB:
4149 file += "\\end{table*}";
4151 case LyXParagraph::ALGORITHM:
4152 file += "\\end{algorithm}";
4156 if (footnotekind != LyXParagraph::FOOTNOTE
4157 && footnotekind != LyXParagraph::MARGIN) {
4158 // we need to ensure that real floats like tables and figures
4159 // have their \end{} on a line of their own otherwise we can
4160 // get incorrect results when using the endfloat.sty package.
4165 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4170 void LyXParagraph::SetPExtraType(int type, char const * width,
4171 char const * widthp)
4174 pextra_width = width;
4175 pextra_widthp = widthp;
4177 if (textclasslist.Style(current_view->buffer()->params.textclass,
4178 layout).isEnvironment()) {
4183 while (par && (par->layout == layout)
4184 && (par->depth == depth)) {
4186 par = par->Previous();
4188 par = par->FirstPhysicalPar();
4189 while (par && par->depth > depth) {
4190 par = par->Previous();
4192 par = par->FirstPhysicalPar();
4196 while (par && (par->layout == layout)
4197 && (par->depth == depth)) {
4198 par->pextra_type = type;
4199 par->pextra_width = width;
4200 par->pextra_widthp = widthp;
4201 par = par->NextAfterFootnote();
4202 if (par && (par->depth > depth))
4203 par->SetPExtraType(type, width, widthp);
4204 while (par && ((par->depth > depth) || par->IsDummy()))
4205 par = par->NextAfterFootnote();
4211 void LyXParagraph::UnsetPExtraType()
4213 if (pextra_type == PEXTRA_NONE)
4216 pextra_type = PEXTRA_NONE;
4217 pextra_width.clear();
4218 pextra_widthp.clear();
4220 if (textclasslist.Style(current_view->buffer()->params.textclass,
4221 layout).isEnvironment()) {
4226 while (par && (par->layout == layout)
4227 && (par->depth == depth)) {
4229 par = par->Previous();
4231 par = par->FirstPhysicalPar();
4232 while (par && par->depth > depth) {
4233 par = par->Previous();
4235 par = par->FirstPhysicalPar();
4239 while (par && (par->layout == layout)
4240 && (par->depth == depth)) {
4241 par->pextra_type = PEXTRA_NONE;
4242 par->pextra_width.clear();
4243 par->pextra_widthp.clear();
4244 par = par->NextAfterFootnote();
4245 if (par && (par->depth > depth))
4246 par->UnsetPExtraType();
4247 while (par && ((par->depth > depth) || par->IsDummy()))
4248 par = par->NextAfterFootnote();
4254 bool LyXParagraph::IsHfill(size_type pos) const
4256 return IsHfillChar(GetChar(pos));
4260 bool LyXParagraph::IsInset(size_type pos) const
4262 return IsInsetChar(GetChar(pos));
4266 bool LyXParagraph::IsFloat(size_type pos) const
4268 return IsFloatChar(GetChar(pos));
4272 bool LyXParagraph::IsNewline(size_type pos) const
4276 tmp = IsNewlineChar(GetChar(pos));
4281 bool LyXParagraph::IsSeparator(size_type pos) const
4283 return IsSeparatorChar(GetChar(pos));
4287 bool LyXParagraph::IsLineSeparator(size_type pos) const
4289 return IsLineSeparatorChar(GetChar(pos));
4293 bool LyXParagraph::IsKomma(size_type pos) const
4295 return IsKommaChar(GetChar(pos));
4299 /// Used by the spellchecker
4300 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4302 unsigned char c = GetChar(pos);
4303 if (IsLetterChar(c))
4305 // '\0' is not a letter, allthough every string contains "" (below)
4308 // We want to pass the ' and escape chars to ispell
4309 string extra = lyxrc->isp_esc_chars + '\'';
4313 return contains(extra, ch);
4317 bool LyXParagraph::IsWord(size_type pos ) const
4319 return IsWordChar(GetChar(pos)) ;