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;
1690 tmp->text.reserve(pos_end - pos);
1692 for (i = pos; i <= pos_end; i++) {
1693 par->CutIntoMinibuffer(i - pos_first);
1694 tmp->InsertFromMinibuffer(i - pos);
1697 for (i = pos_end; i >= pos; i--)
1698 par->Erase(i - pos_first);
1700 par->text.resize(par->text.size());
1703 // just an idea of me
1705 tmp->line_top = firstpar->line_top;
1706 tmp->pagebreak_top = firstpar->pagebreak_top;
1707 tmp->added_space_top = firstpar->added_space_top;
1708 tmp->bibkey = firstpar->bibkey;
1710 // layout stays the same with latex-environments
1712 firstpar->SetOnlyLayout(tmp->layout);
1713 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1714 firstpar->depth = tmp->depth;
1720 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1722 par = par->FirstPhysicalPar();
1723 footnoteflag = par->footnoteflag;
1724 footnotekind = par->footnotekind;
1726 layout = par->layout;
1727 align = par-> align;
1728 SetLabelWidthString(par->labelwidthstring);
1730 line_bottom = par->line_bottom;
1731 pagebreak_bottom = par->pagebreak_bottom;
1732 added_space_bottom = par->added_space_bottom;
1734 line_top = par->line_top;
1735 pagebreak_top = par->pagebreak_top;
1736 added_space_top = par->added_space_top;
1738 pextra_type = par->pextra_type;
1739 pextra_width = par->pextra_width;
1740 pextra_widthp = par->pextra_widthp;
1741 pextra_alignment = par->pextra_alignment;
1742 pextra_hfill = par->pextra_hfill;
1743 pextra_start_minipage = par->pextra_start_minipage;
1745 noindent = par->noindent;
1750 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1752 LyXParagraph * tmppar = this;
1755 && tmppar->previous->footnoteflag ==
1756 LyXParagraph::CLOSED_FOOTNOTE)
1757 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1758 tmppar = tmppar->previous;
1761 return this; // This should never happen!
1767 LyXParagraph * LyXParagraph::Clone() const
1769 // create a new paragraph
1770 LyXParagraph * result = new LyXParagraph;
1772 result->MakeSameLayout(this);
1774 // this is because of the dummy layout of the paragraphs that
1776 result->layout = layout;
1778 /* table stuff -- begin*/
1780 result->table = table->Clone();
1783 /* table stuff -- end*/
1786 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1789 // copy everything behind the break-position to the new paragraph
1791 for (size_type i = 0; i < size(); i++) {
1792 CopyIntoMinibuffer(i);
1793 result->InsertFromMinibuffer(i);
1795 result->text.resize(result->text.size());
1800 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1802 par = par->FirstPhysicalPar();
1805 par->footnoteflag == footnoteflag &&
1806 par->footnotekind == footnotekind &&
1808 par->layout == layout &&
1810 par->align == align &&
1812 par->line_bottom == line_bottom &&
1813 par->pagebreak_bottom == pagebreak_bottom &&
1814 par->added_space_bottom == added_space_bottom &&
1816 par->line_top == line_top &&
1817 par->pagebreak_top == pagebreak_top &&
1818 par->added_space_top == added_space_top &&
1820 par->pextra_type == pextra_type &&
1821 par->pextra_width == pextra_width &&
1822 par->pextra_widthp == pextra_widthp &&
1823 par->pextra_alignment == pextra_alignment &&
1824 par->pextra_hfill == pextra_hfill &&
1825 par->pextra_start_minipage == pextra_start_minipage &&
1827 par->table == table && // what means: NO TABLE AT ALL
1829 par->noindent == noindent &&
1830 par->depth == depth);
1834 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1836 size_type i, pos_end, pos_first;
1838 // create a new paragraph
1839 LyXParagraph * par = ParFromPos(pos);
1841 LyXParagraph * tmp = new LyXParagraph(par);
1843 tmp->MakeSameLayout(par);
1846 // copy everything behind the break-position to the new
1849 while (ParFromPos(pos_first) != par)
1851 pos_end = pos_first + par->text.size() - 1;
1852 // make shure there is enough memory for the now larger
1853 // paragraph. This is not neccessary, because
1854 // InsertFromMinibuffer will enlarge the memory (it uses
1855 // InsertChar of course). But doing it by hand
1856 // is MUCH faster! (only one time, not thousend times!!)
1858 tmp->text.reserve(pos_end - pos);
1860 for (i = pos; i <= pos_end; i++) {
1862 par->CutIntoMinibuffer(i - pos_first);
1863 tmp->InsertFromMinibuffer(i - pos);
1865 for (i = pos_end; i >= pos; i--)
1866 par->Erase(i - pos_first);
1868 par->text.resize(par->text.size());
1873 // Be carefull, this does not make any check at all.
1874 void LyXParagraph::PasteParagraph()
1876 // copy the next paragraph to this one
1877 LyXParagraph * the_next = Next();
1879 LyXParagraph * firstpar = FirstPhysicalPar();
1881 // first the DTP-stuff
1882 firstpar->line_bottom = the_next->line_bottom;
1883 firstpar->added_space_bottom = the_next->added_space_bottom;
1884 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1886 size_type pos_end = the_next->text.size() - 1;
1887 size_type pos_insert = Last();
1890 // ok, now copy the paragraph
1891 for (i = 0; i <= pos_end; i++) {
1892 the_next->CutIntoMinibuffer(i);
1893 InsertFromMinibuffer(pos_insert + i);
1896 // delete the next paragraph
1901 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1903 LyXParagraph * par = ParFromPos(pos);
1905 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1906 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1912 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1914 LyXParagraph * par = ParFromPos(pos);
1916 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1917 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1923 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1925 return FirstPhysicalPar()->layout;
1929 char LyXParagraph::GetDepth() const
1931 return FirstPhysicalPar()->depth;
1935 char LyXParagraph::GetAlign() const
1937 return FirstPhysicalPar()->align;
1941 string LyXParagraph::GetLabestring() const
1943 return FirstPhysicalPar()->labelstring;
1947 int LyXParagraph::GetFirstCounter(int i) const
1949 return FirstPhysicalPar()->counter_[i];
1953 // the next two functions are for the manual labels
1954 string LyXParagraph::GetLabelWidthString() const
1956 if (!FirstPhysicalPar()->labelwidthstring.empty())
1957 return FirstPhysicalPar()->labelwidthstring;
1959 return _("Senseless with this layout!");
1963 void LyXParagraph::SetLabelWidthString(string const & s)
1965 LyXParagraph * par = FirstPhysicalPar();
1967 par->labelwidthstring = s;
1971 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1973 LyXParagraph * par = FirstPhysicalPar();
1974 LyXParagraph * ppar = 0;
1975 LyXParagraph * npar = 0;
1977 par->layout = new_layout;
1978 /* table stuff -- begin*/
1981 /* table stuff -- end*/
1982 if (par->pextra_type == PEXTRA_NONE) {
1983 if (par->Previous()) {
1984 ppar = par->Previous()->FirstPhysicalPar();
1987 && (ppar->depth > par->depth))
1988 ppar = ppar->Previous()->FirstPhysicalPar();
1991 npar = par->Next()->NextAfterFootnote();
1994 && (npar->depth > par->depth))
1995 npar = npar->Next()->NextAfterFootnote();
1997 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1999 p1 = ppar->pextra_width,
2000 p2 = ppar->pextra_widthp;
2001 ppar->SetPExtraType(ppar->pextra_type,
2002 p1.c_str(), p2.c_str());
2004 if ((par->pextra_type == PEXTRA_NONE) &&
2005 npar && (npar->pextra_type != PEXTRA_NONE)) {
2007 p1 = npar->pextra_width,
2008 p2 = npar->pextra_widthp;
2009 npar->SetPExtraType(npar->pextra_type,
2010 p1.c_str(), p2.c_str());
2016 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
2019 * par = FirstPhysicalPar(),
2023 par->layout = new_layout;
2024 par->labelwidthstring.clear();
2025 par->align = LYX_ALIGN_LAYOUT;
2026 par->added_space_top = VSpace(VSpace::NONE);
2027 par->added_space_bottom = VSpace(VSpace::NONE);
2028 /* table stuff -- begin*/
2031 /* table stuff -- end*/
2032 if (par->pextra_type == PEXTRA_NONE) {
2033 if (par->Previous()) {
2034 ppar = par->Previous()->FirstPhysicalPar();
2037 && (ppar->depth > par->depth))
2038 ppar = ppar->Previous()->FirstPhysicalPar();
2041 npar = par->Next()->NextAfterFootnote();
2044 && (npar->depth > par->depth))
2045 npar = npar->Next()->NextAfterFootnote();
2047 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2049 p1 = ppar->pextra_width,
2050 p2 = ppar->pextra_widthp;
2051 ppar->SetPExtraType(ppar->pextra_type,
2052 p1.c_str(), p2.c_str());
2054 if ((par->pextra_type == PEXTRA_NONE) &&
2055 npar && (npar->pextra_type != PEXTRA_NONE)) {
2057 p1 = npar->pextra_width,
2058 p2 = npar->pextra_widthp;
2059 npar->SetPExtraType(npar->pextra_type,
2060 p1.c_str(), p2.c_str());
2066 // if the layout of a paragraph contains a manual label, the beginning of the
2067 // main body is the beginning of the second word. This is what the par-
2068 // function returns. If the layout does not contain a label, the main
2069 // body always starts with position 0. This differentiation is necessary,
2070 // because there cannot be a newline or a blank <= the beginning of the
2071 // main body in TeX.
2073 int LyXParagraph::BeginningOfMainBody() const
2075 if (FirstPhysicalPar() != this)
2078 // Unroll the first two cycles of the loop
2079 // and remember the previous character to
2080 // remove unnecessary GetChar() calls
2083 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2085 char previous_char, temp;
2087 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2088 // Yes, this ^ is supposed to be "= " not "=="
2091 && previous_char != ' '
2092 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2094 previous_char = temp;
2099 if (i == 0 && i == size() &&
2100 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2101 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2102 i++; /* the cursor should not jump
2103 * to the main body if there
2109 LyXParagraph * LyXParagraph::DepthHook(int deth)
2111 LyXParagraph * newpar = this;
2116 newpar = newpar->FirstPhysicalPar()->Previous();
2117 } while (newpar && newpar->GetDepth() > deth
2118 && newpar->footnoteflag == footnoteflag);
2121 if (Previous() || GetDepth())
2122 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2126 return newpar->FirstPhysicalPar();
2130 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2132 LyXParagraph const * newpar = this;
2137 newpar = newpar->FirstPhysicalPar()->Previous();
2138 } while (newpar && newpar->GetDepth() > deth
2139 && newpar->footnoteflag == footnoteflag);
2142 if (Previous() || GetDepth())
2143 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2147 return newpar->FirstPhysicalPar();
2151 int LyXParagraph::AutoDeleteInsets()
2153 #ifdef NEW_INSETTABLE
2154 vector<size_type> tmpvec;
2156 for (InsetList::iterator it = insetlist.begin();
2157 it != insetlist.end(); ++it) {
2158 if ((*it).inset && (*it).inset->AutoDelete()) {
2159 tmpvec.push_back((*it).pos);
2163 for (vector<size_type>::const_iterator cit = tmpvec.begin();
2164 cit != tmpvec.end(); ++cit) {
2169 InsetTable * tmpi = insettable;
2170 InsetTable * tmpi2 = tmpi;
2176 if (tmpi2->inset->AutoDelete()) {
2181 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2182 "cannot auto-delete insets" << endl;
2190 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2192 #ifdef NEW_INSETTABLE
2193 InsetList::iterator it2 = insetlist.end();
2194 for (InsetList::iterator it = insetlist.begin();
2195 it != insetlist.end(); ++it) {
2196 if ((*it).pos >= pos) {
2197 if (it2 != insetlist.end() || (*it).pos < (*it2).pos)
2201 if (it2 != insetlist.end()) {
2203 return (*it2).inset;
2207 InsetTable * tmpi = insettable;
2208 InsetTable * tmpi2 = 0;
2210 if (tmpi->pos >= pos) {
2211 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2218 return tmpi2->inset;
2226 // returns -1 if inset not found
2227 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2230 #ifdef NEW_INSETTABLE
2231 for (InsetList::const_iterator cit = insetlist.begin();
2232 cit != insetlist.end(); ++cit) {
2233 if ((*cit).inset == inset) {
2238 InsetTable * tmpi = insettable;
2239 while (tmpi && tmpi->inset != inset) {
2242 if (tmpi && tmpi->inset)
2245 // Think about footnotes.
2246 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2247 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2249 NextAfterFootnote()->GetPositionOfInset(inset);
2251 return text.size() + 1 + further;
2257 void LyXParagraph::readSimpleWholeFile(istream & is)
2263 InsertChar(text.size(), c);
2268 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2269 string & foot, TexRow & foot_texrow,
2272 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2273 LyXParagraph * par = next;
2274 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2277 bool further_blank_line = false;
2279 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2281 if (start_of_appendix) {
2282 file += "\\appendix\n";
2286 if (tex_code_break_column && style.isCommand()){
2291 if (pagebreak_top) {
2292 file += "\\newpage";
2293 further_blank_line = true;
2295 if (added_space_top.kind() != VSpace::NONE) {
2296 file += added_space_top.asLatexCommand();
2297 further_blank_line = true;
2301 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2302 file += "\\vspace{-1\\parskip}";
2303 further_blank_line = true;
2306 if (further_blank_line){
2311 switch (style.latextype) {
2314 file += style.latexname();
2315 file += style.latexparam();
2317 case LATEX_ITEM_ENVIRONMENT:
2319 bibkey->Latex(file, false);
2323 case LATEX_LIST_ENVIRONMENT:
2330 bool need_par = SimpleTeXOnePar(file, texrow);
2332 // Spit out footnotes
2333 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2334 && par->footnoteflag != footnoteflag) {
2335 par = par->TeXFootnote(file, texrow,
2336 foot, foot_texrow, foot_count);
2337 par->SimpleTeXOnePar(file, texrow);
2341 // Make sure that \\par is done with the font of the last
2342 // character if this has another size as the default.
2343 // This is necessary because LaTeX (and LyX on the screen)
2344 // calculates the space between the baselines according
2345 // to this font. (Matthias)
2346 LyXFont font = getFont(Last()-1);
2348 if (style.resfont.size() != font.size()) {
2350 file += font.latexSize();
2354 } else if (textclasslist.Style(current_view->buffer()->params.textclass,
2355 GetLayout()).isCommand()){
2356 if (style.resfont.size() != font.size()) {
2358 file += font.latexSize();
2362 } else if (style.resfont.size() != font.size()){
2363 file += "{\\" + font.latexSize() + " \\par}";
2366 switch (style.latextype) {
2367 case LATEX_ITEM_ENVIRONMENT:
2368 case LATEX_LIST_ENVIRONMENT:
2369 if (par && (depth < par->depth)) {
2374 case LATEX_ENVIRONMENT:
2375 // if its the last paragraph of the current environment
2376 // skip it otherwise fall through
2378 && (par->layout != layout
2379 || par->depth != depth
2380 || par->pextra_type != pextra_type))
2383 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2384 && footnotekind != LyXParagraph::FOOTNOTE
2385 && footnotekind != LyXParagraph::MARGIN
2389 // don't insert this if we would be adding it
2390 // before or after a table in a float. This
2391 // little trick is needed in order to allow
2392 // use of tables in \subfigures or \subtables.
2398 further_blank_line = false;
2400 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2401 further_blank_line = true;
2404 if (added_space_bottom.kind() != VSpace::NONE) {
2405 file += added_space_bottom.asLatexCommand();
2406 further_blank_line = true;
2409 if (pagebreak_bottom) {
2410 file += "\\newpage";
2411 further_blank_line = true;
2414 if (further_blank_line){
2419 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2420 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2425 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2430 // This one spits out the text of the paragraph
2431 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2433 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2436 return SimpleTeXOneTablePar(file, texrow);
2439 size_type main_body;
2441 bool return_value = false;
2443 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2446 // Maybe we have to create a optional argument.
2447 if (style.labeltype != LABEL_MANUAL)
2450 main_body = BeginningOfMainBody();
2452 if (main_body > 0) {
2454 basefont = getFont(-2); // Get label font
2456 basefont = getFont(-1); // Get layout font
2464 if (style.isCommand()) {
2467 } else if (align != LYX_ALIGN_LAYOUT) {
2470 return_value = true;
2474 // Which font is currently active?
2475 LyXFont running_font = basefont;
2476 // Do we have an open font change?
2477 bool open_font = false;
2479 texrow.start(this, 0);
2481 for (size_type i = 0; i < size(); ++i) {
2483 // First char in paragraph or after label?
2484 if (i == main_body && !IsDummy()) {
2485 if (main_body > 0) {
2487 column += running_font.latexWriteEndChanges(file, basefont);
2490 basefont = getFont(-1); // Now use the layout font
2491 running_font = basefont;
2495 if (style.isCommand()) {
2498 } else if (align != LYX_ALIGN_LAYOUT) {
2501 return_value = true;
2505 file += "\\noindent ";
2509 case LYX_ALIGN_NONE:
2510 case LYX_ALIGN_BLOCK:
2511 case LYX_ALIGN_LAYOUT:
2512 case LYX_ALIGN_SPECIAL: break;
2513 case LYX_ALIGN_LEFT:
2514 file += "\\raggedright ";
2517 case LYX_ALIGN_RIGHT:
2518 file += "\\raggedleft ";
2521 case LYX_ALIGN_CENTER:
2522 file += "\\centering ";
2530 // Fully instantiated font
2531 LyXFont font = getFont(i);
2533 // Spaces at end of font change are simulated to be
2534 // outside font change, i.e. we write "\textXX{text} "
2535 // rather than "\textXX{text }". (Asger)
2536 if (open_font && c == ' ' && i <= size() - 2
2537 && !getFont(i+1).equalExceptLatex(running_font)
2538 && !getFont(i+1).equalExceptLatex(font)) {
2539 font = getFont(i+1);
2541 // We end font definition before blanks
2542 if (!font.equalExceptLatex(running_font) && open_font) {
2543 column += running_font.latexWriteEndChanges(file,
2545 running_font = basefont;
2549 // Blanks are printed before start of fontswitch
2551 // Do not print the separation of the optional argument
2552 if (i != main_body - 1) {
2553 SimpleTeXBlanks(file, texrow, i,
2554 column, font, style);
2558 // Do we need to change font?
2559 if (!font.equalExceptLatex(running_font)
2560 && i != main_body-1) {
2561 column += font.latexWriteStartChanges(file, basefont);
2562 running_font = font;
2566 if (c == LyXParagraph::META_NEWLINE) {
2567 // newlines are handled differently here than
2568 // the default in SimpleTeXSpecialChars().
2569 if (!style.newline_allowed
2570 || font.latex() == LyXFont::ON) {
2574 column += running_font.latexWriteEndChanges(file, basefont);
2577 basefont = getFont(-1);
2578 running_font = basefont;
2579 if (font.family() ==
2580 LyXFont::TYPEWRITER_FAMILY) {
2586 texrow.start(this, i+1);
2589 SimpleTeXSpecialChars(file, texrow,
2590 font, running_font, basefont,
2591 open_font, style, i, column, c);
2595 // If we have an open font definition, we have to close it
2597 running_font.latexWriteEndChanges(file, basefont);
2600 // Needed if there is an optional argument but no contents.
2601 if (main_body > 0 && main_body == size()) {
2603 return_value = false;
2606 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2607 return return_value;
2611 // This one spits out the text of a table paragraph
2612 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2614 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2618 bool return_value = false;
2619 int current_cell_number = -1;
2621 LyXLayout const & style =
2622 textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2623 LyXFont basefont = getFont(-1); // Get layout font
2624 // Which font is currently active?
2625 LyXFont running_font = basefont;
2626 // Do we have an open font change?
2627 bool open_font = false;
2630 if (!IsDummy()) { // it is dummy if it is in a float!!!
2631 if (style.isCommand()) {
2634 } else if (align != LYX_ALIGN_LAYOUT) {
2637 return_value = true;
2640 file += "\\noindent ";
2644 case LYX_ALIGN_NONE:
2645 case LYX_ALIGN_BLOCK:
2646 case LYX_ALIGN_LAYOUT:
2647 case LYX_ALIGN_SPECIAL: break;
2648 case LYX_ALIGN_LEFT:
2649 file += "\\raggedright ";
2652 case LYX_ALIGN_RIGHT:
2653 file += "\\raggedleft ";
2656 case LYX_ALIGN_CENTER:
2657 file += "\\centering ";
2662 current_cell_number = -1;
2663 tmp = table->TexEndOfCell(file, current_cell_number);
2664 for (; tmp > 0 ; --tmp)
2667 texrow.start(this, 0);
2669 for (size_type i = 0; i < size(); ++i) {
2671 if (table->IsContRow(current_cell_number+1)) {
2672 if (c == LyXParagraph::META_NEWLINE)
2673 current_cell_number++;
2678 // Fully instantiated font
2679 LyXFont font = getFont(i);
2681 // Spaces at end of font change are simulated to be
2682 // outside font change.
2683 // i.e. we write "\textXX{text} " rather than
2684 // "\textXX{text }". (Asger)
2685 if (open_font && c == ' ' && i <= size() - 2
2686 && getFont(i+1) != running_font && getFont(i+1) != font) {
2687 font = getFont(i+1);
2690 // We end font definition before blanks
2691 if (font != running_font && open_font) {
2692 column += running_font.latexWriteEndChanges(file,
2694 running_font = basefont;
2697 // Blanks are printed before start of fontswitch
2699 SimpleTeXBlanks(file, texrow, i, column, font, style);
2701 // Do we need to change font?
2702 if (font != running_font) {
2703 column += font.latexWriteStartChanges(file, basefont);
2704 running_font = font;
2707 // Do we need to turn on LaTeX mode?
2708 if (font.latex() != running_font.latex()) {
2709 if (font.latex() == LyXFont::ON
2710 && style.needprotect) {
2711 file += "\\protect ";
2715 if (c == LyXParagraph::META_NEWLINE) {
2716 // special case for inside a table
2717 // different from default case in
2718 // SimpleTeXSpecialChars()
2720 column += running_font
2721 .latexWriteEndChanges(file, basefont);
2724 basefont = getFont(-1);
2725 running_font = basefont;
2726 current_cell_number++;
2727 if (table->CellHasContRow(current_cell_number) >= 0) {
2728 TeXContTableRows(file, i+1,
2729 current_cell_number,
2732 // if this cell follow only ContRows till end don't
2733 // put the EndOfCell because it is put after the
2735 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2736 current_cell_number--;
2739 int tmp = table->TexEndOfCell(file,
2740 current_cell_number);
2743 } else if (tmp < 0) {
2749 texrow.start(this, i+1);
2751 SimpleTeXSpecialChars(file, texrow,
2752 font, running_font, basefont,
2753 open_font, style, i, column, c);
2757 // If we have an open font definition, we have to close it
2759 running_font.latexWriteEndChanges(file, basefont);
2761 current_cell_number++;
2762 tmp = table->TexEndOfCell(file, current_cell_number);
2763 for (; tmp > 0; --tmp)
2765 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2766 return return_value;
2770 // This one spits out the text off ContRows in tables
2771 bool LyXParagraph::TeXContTableRows(string & file,
2772 LyXParagraph::size_type i,
2773 int current_cell_number,
2774 int & column, TexRow & texrow)
2776 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2782 bool return_value = false;
2783 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2787 basefont = getFont(-1); // Get layout font
2788 // Which font is currently active?
2789 LyXFont running_font = basefont;
2790 // Do we have an open font change?
2791 bool open_font = false;
2793 size_type lastpos = i;
2794 int cell = table->CellHasContRow(current_cell_number);
2795 ++current_cell_number;
2797 // first find the right position
2799 for (; (i < size()) && (current_cell_number<cell); ++i) {
2801 if (c == LyXParagraph::META_NEWLINE)
2802 current_cell_number++;
2806 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2810 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2815 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2819 // Fully instantiated font
2820 LyXFont font = getFont(i);
2822 // Spaces at end of font change are simulated to
2823 // be outside font change. i.e. we write
2824 // "\textXX{text} " rather than "\textXX{text }".
2826 if (open_font && c == ' ' && i <= size() - 2
2827 && getFont(i + 1) != running_font
2828 && getFont(i + 1) != font) {
2829 font = getFont(i + 1);
2832 // We end font definition before blanks
2833 if (font != running_font && open_font) {
2834 column += running_font.latexWriteEndChanges(file, basefont);
2835 running_font = basefont;
2838 // Blanks are printed before start of fontswitch
2840 SimpleTeXBlanks(file, texrow, i,
2841 column, font, style);
2843 // Do we need to change font?
2844 if (font != running_font) {
2846 font.latexWriteStartChanges(file,
2848 running_font = font;
2851 // Do we need to turn on LaTeX mode?
2852 if (font.latex() != running_font.latex()) {
2853 if (font.latex() == LyXFont::ON
2854 && style.needprotect)
2856 file += "\\protect ";
2860 SimpleTeXSpecialChars(file, texrow, font,
2861 running_font, basefont,
2862 open_font, style, i, column, c);
2864 // If we have an open font definition, we have to close it
2866 running_font.latexWriteEndChanges(file, basefont);
2869 basefont = getFont(-1);
2870 running_font = basefont;
2871 cell = table->CellHasContRow(current_cell_number);
2873 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2874 return return_value;
2878 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2880 bool retval = false;
2882 case LyXParagraph::META_HFILL:
2883 sgml_string.clear();
2885 case LyXParagraph::META_PROTECTED_SEPARATOR:
2888 case LyXParagraph::META_NEWLINE:
2892 sgml_string = "&";
2895 sgml_string = "<";
2898 sgml_string = ">";
2901 sgml_string = "$";
2904 sgml_string = "#";
2907 sgml_string = "%";
2910 sgml_string = "[";
2913 sgml_string = "]";
2916 sgml_string = "{";
2919 sgml_string = "}";
2922 sgml_string = "˜";
2925 sgml_string = """;
2928 sgml_string = "\";
2934 case '\0': // Ignore :-)
2935 sgml_string.clear();
2945 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2946 int & desc_on, int depth)
2949 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2951 LyXFont font1, font2;
2954 size_type main_body;
2955 string emph = "emphasis";
2956 bool emph_flag = false;
2958 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2961 if (style.labeltype != LABEL_MANUAL)
2964 main_body = BeginningOfMainBody();
2966 // Gets paragraph main font.
2968 font1 = style.labelfont;
2972 int char_line_count = depth;
2973 addNewlineAndDepth(file, depth);
2974 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2975 file += "<INFORMALTABLE>";
2976 addNewlineAndDepth(file, ++depth);
2978 int current_cell_number = -1;
2979 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2981 // Parsing main loop.
2982 for (size_type i = 0; i < size(); ++i) {
2984 if (table->IsContRow(current_cell_number+1)) {
2985 if (c == LyXParagraph::META_NEWLINE)
2986 ++current_cell_number;
2991 // Fully instantiated font
2994 // Handle <emphasis> tag.
2995 if (font1.emph() != font2.emph() && i) {
2996 if (font2.emph() == LyXFont::ON) {
2997 file += "<emphasis>";
2999 } else if (emph_flag) {
3000 file += "</emphasis>";
3004 if (c == LyXParagraph::META_NEWLINE) {
3005 // We have only to control for emphasis open here!
3007 file += "</emphasis>";
3010 font1 = font2 = getFont(-1);
3011 current_cell_number++;
3012 if (table->CellHasContRow(current_cell_number) >= 0) {
3013 DocBookContTableRows(file, extra, desc_on, i+1,
3014 current_cell_number,
3017 // if this cell follow only ContRows till end don't
3018 // put the EndOfCell because it is put after the
3020 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3021 current_cell_number--;
3024 tmp= table->DocBookEndOfCell(file, current_cell_number,
3029 } else if (c == LyXParagraph::META_INSET) {
3030 inset = GetInset(i);
3032 inset->DocBook(tmp_out);
3034 // This code needs some explanation:
3035 // Two insets are treated specially
3036 // label if it is the first element in a
3037 // command paragraph
3039 // graphics inside tables or figure floats
3041 // title (the equivalente in latex for this
3043 // and title should come first
3046 if(desc_on != 3 || i != 0) {
3047 if(tmp_out[0] == '@') {
3049 extra += frontStrip(tmp_out,
3052 file += frontStrip(tmp_out,
3057 } else if (font2.latex() == LyXFont::ON) {
3058 // "TeX"-Mode on == > SGML-Mode on.
3064 if (linuxDocConvertChar(c, sgml_string)
3065 && !style.free_spacing) {
3066 // in freespacing mode, spaces are
3067 // non-breaking characters
3072 file += "</term><listitem><para>";
3078 file += sgml_string;
3084 // Needed if there is an optional argument but no contents.
3085 if (main_body > 0 && main_body == size()) {
3090 file += "</emphasis>";
3093 current_cell_number++;
3094 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3095 // Resets description flag correctly.
3098 // <term> not closed...
3102 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3103 file += "</INFORMALTABLE>";
3105 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3110 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3112 LyXParagraph::size_type i,
3113 int current_cell_number, int &column)
3118 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3121 LyXFont font1, font2;
3124 size_type main_body;
3126 string emph= "emphasis";
3127 bool emph_flag= false;
3128 int char_line_count= 0;
3130 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3133 if (style.labeltype != LABEL_MANUAL)
3136 main_body = BeginningOfMainBody();
3138 // Gets paragraph main font.
3140 font1 = style.labelfont;
3145 cell = table->CellHasContRow(current_cell_number);
3146 ++current_cell_number;
3148 // first find the right position
3150 for (; i < size() && current_cell_number < cell; ++i) {
3152 if (c == LyXParagraph::META_NEWLINE)
3153 current_cell_number++;
3157 // I don't know how to handle this so I comment it
3158 // for the moment (Jug)
3159 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3160 // file += " \\\\\n";
3163 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3168 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3172 // Fully instantiated font
3175 // Handle <emphasis> tag.
3176 if (font1.emph() != font2.emph() && i) {
3177 if (font2.emph() == LyXFont::ON) {
3178 file += "<emphasis>";
3180 } else if (emph_flag) {
3181 file += "</emphasis>";
3185 if (c == LyXParagraph::META_INSET) {
3186 inset = GetInset(i);
3188 inset->DocBook(tmp_out);
3190 // This code needs some explanation:
3191 // Two insets are treated specially
3192 // label if it is the first element in a command paragraph
3194 // graphics inside tables or figure floats can't go on
3195 // title (the equivalente in latex for this case is caption
3196 // and title should come first
3199 if(desc_on != 3 || i != 0) {
3200 if(tmp_out[0] == '@') {
3202 extra += frontStrip(tmp_out, '@');
3204 file += frontStrip(tmp_out, '@');
3208 } else if (font2.latex() == LyXFont::ON) {
3209 // "TeX"-Mode on == > SGML-Mode on.
3215 if (linuxDocConvertChar(c, sgml_string)
3216 && !style.free_spacing) {
3217 // in freespacing mode, spaces are
3218 // non-breaking characters
3223 file += "</term><listitem><para>";
3229 file += sgml_string;
3233 // we have only to control for emphasis open here!
3235 file += "</emphasis>";
3238 font1 = font2 = getFont(-1);
3239 cell = table->CellHasContRow(current_cell_number);
3241 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3245 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3246 LyXParagraph::size_type const i,
3247 int & column, LyXFont const & font,
3248 LyXLayout const & style)
3250 if (column > tex_code_break_column
3252 && GetChar(i - 1) != ' '
3254 // In LaTeX mode, we don't want to
3255 // break lines since some commands
3257 && ! (font.latex() == LyXFont::ON)
3258 // same in FreeSpacing mode
3259 && !style.free_spacing
3260 // In typewriter mode, we want to avoid
3261 // ! . ? : at the end of a line
3262 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3263 && (GetChar(i-1) == '.'
3264 || GetChar(i-1) == '?'
3265 || GetChar(i-1) == ':'
3266 || GetChar(i-1) == '!'))) {
3267 if (tex_code_break_column == 0) {
3268 // in batchmode we need LaTeX to still
3269 // see it as a space not as an extra '\n'
3275 texrow.start(this, i+1);
3277 } else if (font.latex() == LyXFont::OFF) {
3278 if (style.free_spacing) {
3287 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3289 LyXFont & running_font,
3292 LyXLayout const & style,
3293 LyXParagraph::size_type & i,
3294 int & column, char const c)
3296 // Two major modes: LaTeX or plain
3297 // Handle here those cases common to both modes
3298 // and then split to handle the two modes separately.
3300 case LyXParagraph::META_INSET: {
3301 Inset * inset = GetInset(i);
3303 int len = file.length();
3304 int tmp = inset->Latex(file, style.isCommand());
3309 column += file.length() - len;
3318 case LyXParagraph::META_NEWLINE:
3320 column += running_font.latexWriteEndChanges(file,
3324 basefont = getFont(-1);
3325 running_font = basefont;
3328 case LyXParagraph::META_HFILL:
3329 file += "\\hfill{}";
3334 // And now for the special cases within each mode
3335 // Are we in LaTeX mode?
3336 if (font.latex() == LyXFont::ON) {
3337 // at present we only have one option
3338 // but I'll leave it as a switch statement
3339 // so its simpler to extend. (ARRae)
3341 case LyXParagraph::META_PROTECTED_SEPARATOR:
3346 // make sure that we will not print
3347 // error generating chars to the tex
3348 // file. This test would not be needed
3349 // if it were done in the buffer
3357 // Plain mode (i.e. not LaTeX)
3359 case LyXParagraph::META_PROTECTED_SEPARATOR:
3364 file += "\\textbackslash{}";
3368 case '°': case '±': case '²': case '³':
3369 case '×': case '÷': case '¹': case 'ª':
3370 case 'º': case '¬': case 'µ':
3371 if (current_view->buffer()->params.inputenc == "latin1") {
3372 file += "\\ensuremath{";
3381 case '|': case '<': case '>':
3382 // In T1 encoding, these characters exist
3383 if (lyxrc->fontenc == "T1") {
3385 //... but we should avoid ligatures
3386 if ((c == '>' || c == '<')
3388 && GetChar(i+1) == c){
3389 file += "\\textcompwordmark{}";
3394 // Typewriter font also has them
3395 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3399 // Otherwise, we use what LaTeX
3403 file += "\\textless{}";
3407 file += "\\textgreater{}";
3411 file += "\\textbar{}";
3417 case '-': // "--" in Typewriter mode -> "-{}-"
3419 && GetChar(i + 1) == '-'
3420 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3429 file += "\\char`\\\"{}";
3434 if (current_view->buffer()->params.inputenc == "default") {
3435 file += "\\pounds{}";
3443 case '%': case '#': case '{':
3451 file += "\\textasciitilde{}";
3456 file += "\\textasciicircum{}";
3460 case '*': case '[': case ']':
3461 // avoid being mistaken for optional arguments
3469 // Blanks are printed before font switching.
3470 // Sure? I am not! (try nice-latex)
3471 // I am sure it's correct. LyX might be smarter
3472 // in the future, but for now, nothing wrong is
3477 /* idea for labels --- begin*/
3481 && font.family() != LyXFont::TYPEWRITER_FAMILY
3482 && GetChar(i + 1) == 'y'
3483 && GetChar(i + 2) == 'X') {
3491 && font.family() != LyXFont::TYPEWRITER_FAMILY
3492 && GetChar(i + 1) == 'e'
3493 && GetChar(i + 2) == 'X') {
3498 // Check for "LaTeX2e"
3501 && font.family() != LyXFont::TYPEWRITER_FAMILY
3502 && GetChar(i + 1) == 'a'
3503 && GetChar(i + 2) == 'T'
3504 && GetChar(i + 3) == 'e'
3505 && GetChar(i + 4) == 'X'
3506 && GetChar(i + 5) == '2'
3507 && GetChar(i + 6) == 'e') {
3508 file += "\\LaTeXe{}";
3512 // Check for "LaTeX"
3515 && font.family() != LyXFont::TYPEWRITER_FAMILY
3516 && GetChar(i + 1) == 'a'
3517 && GetChar(i + 2) == 'T'
3518 && GetChar(i + 3) == 'e'
3519 && GetChar(i + 4) == 'X') {
3520 file += "\\LaTeX{}";
3523 /* idea for labels --- end*/
3524 } else if (c != '\0') {
3534 bool LyXParagraph::RoffContTableRows(ostream & os,
3535 LyXParagraph::size_type i,
3541 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3546 string fname2 = TmpFileName(string(), "RAT2");
3548 int cell = table->CellHasContRow(actcell);
3551 // first find the right position
3553 for (; i < size() && actcell < cell; ++i) {
3555 if (c == LyXParagraph::META_NEWLINE)
3560 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3563 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3565 font2 = GetFontSettings(i);
3566 if (font1.latex() != font2.latex()) {
3567 if (font2.latex() != LyXFont::OFF)
3572 case LyXParagraph::META_INSET:
3573 if ((inset = GetInset(i))) {
3574 fstream fs(fname2.c_str(),
3577 WriteAlert(_("LYX_ERROR:"),
3578 _("Cannot open temporary file:"),
3582 inset->Latex(fs, -1);
3595 case LyXParagraph::META_NEWLINE:
3597 case LyXParagraph::META_HFILL:
3599 case LyXParagraph::META_PROTECTED_SEPARATOR:
3608 lyxerr.debug() << "RoffAsciiTable: "
3609 "NULL char in structure."
3614 cell = table->CellHasContRow(actcell);
3620 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3621 string & foot, TexRow & foot_texrow,
3624 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3625 LyXParagraph * par = this;
3627 while (par && par->depth == depth) {
3629 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3630 if (textclasslist.Style(current_view->buffer()->params.textclass,
3631 par->layout).isEnvironment()
3632 || par->pextra_type != PEXTRA_NONE)
3634 par = par->TeXEnvironment(file, texrow,
3638 par = par->TeXOnePar(file, texrow,
3643 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3649 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3650 string & foot, TexRow & foot_texrow,
3653 bool eindent_open = false;
3654 bool foot_this_level = false;
3655 // flags when footnotetext should be appended to file.
3656 static bool minipage_open = false;
3657 static int minipage_open_depth = 0;
3658 char par_sep = current_view->buffer()->params.paragraph_separation;
3660 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3662 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3664 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3667 if (pextra_type == PEXTRA_INDENT) {
3668 if (!pextra_width.empty()) {
3669 file += "\\begin{LyXParagraphIndent}{"
3670 + pextra_width + "}\n";
3672 //float ib = atof(pextra_widthp.c_str())/100;
3673 // string can't handle floats at present (971109)
3674 // so I'll do a conversion by hand knowing that
3675 // the limits are 0.0 to 1.0. ARRae.
3676 file += "\\begin{LyXParagraphIndent}{";
3677 switch (pextra_widthp.length()) {
3683 file += pextra_widthp;
3687 file += pextra_widthp;
3689 file += "\\columnwidth}\n";
3692 eindent_open = true;
3694 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3695 if (pextra_hfill && Previous() &&
3696 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3697 file += "\\hfill{}\n";
3700 if (par_sep == BufferParams::PARSEP_INDENT) {
3701 file += "{\\setlength\\parindent{0pt}\n";
3704 file += "\\begin{minipage}";
3705 switch(pextra_alignment) {
3706 case MINIPAGE_ALIGN_TOP:
3709 case MINIPAGE_ALIGN_MIDDLE:
3712 case MINIPAGE_ALIGN_BOTTOM:
3716 if (!pextra_width.empty()) {
3718 file += pextra_width + "}\n";
3720 //float ib = atof(par->pextra_width.c_str())/100;
3721 // string can't handle floats at present
3722 // so I'll do a conversion by hand knowing that
3723 // the limits are 0.0 to 1.0. ARRae.
3725 switch (pextra_widthp.length()) {
3731 file += pextra_widthp;
3735 file += pextra_widthp;
3737 file += "\\columnwidth}\n";
3740 if (par_sep == BufferParams::PARSEP_INDENT) {
3741 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3744 minipage_open = true;
3745 minipage_open_depth = depth;
3748 #ifdef WITH_WARNINGS
3749 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3750 //I disabled it because it breaks when lists span on several
3753 if (style.isEnvironment()){
3754 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3755 #ifdef FANCY_FOOTNOTE_CODE
3756 if (foot_count < 0) {
3757 // flag that footnote[mark][text] should be
3758 // used for any footnotes from now on
3760 foot_this_level = true;
3763 file += "\\begin{" + style.latexname() + "}{"
3764 + labelwidthstring + "}\n";
3765 } else if (style.labeltype == LABEL_BIBLIO) {
3767 file += "\\begin{" + style.latexname() + "}{"
3768 + bibitemWidthest() + "}\n";
3769 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3770 #ifdef FANCY_FOOTNOTE_CODE
3771 if (foot_count < 0) {
3772 // flag that footnote[mark][text] should be
3773 // used for any footnotes from now on
3775 foot_this_level = true;
3778 file += "\\begin{" + style.latexname() + '}'
3779 + style.latexparam() + '\n';
3781 file += "\\begin{" + style.latexname() + '}'
3782 + style.latexparam() + '\n';
3785 LyXParagraph * par = this;
3787 par = par->TeXOnePar(file, texrow,
3788 foot, foot_texrow, foot_count);
3790 if (minipage_open && par && !style.isEnvironment() &&
3791 (par->pextra_type == PEXTRA_MINIPAGE) &&
3792 par->pextra_start_minipage) {
3793 file += "\\end{minipage}\n";
3795 if (par_sep == BufferParams::PARSEP_INDENT) {
3799 minipage_open = false;
3801 if (par && par->depth > depth) {
3802 if (textclasslist.Style(current_view->buffer()->params.textclass,
3803 par->layout).isParagraph()
3805 && !suffixIs(file, "\n\n")) {
3806 // There should be at least one '\n' already
3807 // but we need there to be two for Standard
3808 // paragraphs that are depth-increment'ed to be
3809 // output correctly. However, tables can
3810 // also be paragraphs so don't adjust them.
3815 par = par->TeXDeeper(file, texrow,
3816 foot, foot_texrow, foot_count);
3818 if (par && par->layout == layout && par->depth == depth &&
3819 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3820 if (par->pextra_hfill && par->Previous() &&
3821 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3822 file += "\\hfill{}\n";
3825 if (par_sep == BufferParams::PARSEP_INDENT) {
3826 file += "{\\setlength\\parindent{0pt}\n";
3829 file += "\\begin{minipage}";
3830 switch(par->pextra_alignment) {
3831 case MINIPAGE_ALIGN_TOP:
3834 case MINIPAGE_ALIGN_MIDDLE:
3837 case MINIPAGE_ALIGN_BOTTOM:
3841 if (!par->pextra_width.empty()) {
3843 file += par->pextra_width;
3846 //float ib = atof(par->pextra_widthp.c_str())/100;
3847 // string can't handle floats at present
3848 // so I'll do a conversion by hand knowing that
3849 // the limits are 0.0 to 1.0. ARRae.
3851 switch (par->pextra_widthp.length()) {
3857 file += par->pextra_widthp;
3861 file += par->pextra_widthp;
3863 file += "\\columnwidth}\n";
3866 if (par_sep == BufferParams::PARSEP_INDENT) {
3867 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3870 minipage_open = true;
3871 minipage_open_depth = par->depth;
3874 && par->layout == layout
3875 && par->depth == depth
3876 && par->pextra_type == pextra_type);
3878 if (style.isEnvironment()) {
3879 file += "\\end{" + style.latexname() + '}';
3880 // maybe this should go after the minipage closes?
3881 if (foot_this_level) {
3882 if (foot_count >= 1) {
3883 if (foot_count > 1) {
3884 file += "\\addtocounter{footnote}{-";
3885 file += tostr(foot_count - 1);
3889 texrow += foot_texrow;
3891 foot_texrow.reset();
3896 if (minipage_open && (minipage_open_depth == depth) &&
3897 (!par || par->pextra_start_minipage ||
3898 par->pextra_type != PEXTRA_MINIPAGE)) {
3899 file += "\\end{minipage}\n";
3901 if (par_sep == BufferParams::PARSEP_INDENT) {
3905 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3906 file += "\\medskip\n\n";
3910 minipage_open = false;
3913 file += "\\end{LyXParagraphIndent}\n";
3916 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3917 && par->pextra_hfill)) {
3921 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3922 return par; // ale970302
3926 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3927 string & foot, TexRow & foot_texrow,
3930 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3931 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3932 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3933 "No footnote!" << endl;
3935 LyXParagraph * par = this;
3936 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3937 previous->GetLayout());
3939 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3940 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3941 "Float other than footnote in command"
3942 " with moving argument is illegal" << endl;
3945 if (footnotekind != LyXParagraph::FOOTNOTE
3946 && footnotekind != LyXParagraph::MARGIN
3948 && !suffixIs(file, '\n')) {
3949 // we need to ensure that real floats like tables and figures
3950 // have their \begin{} on a new line otherwise we can get
3951 // incorrect results when using the endfloat.sty package
3952 // especially if two floats follow one another. ARRae 981022
3953 // NOTE: if the file is length 0 it must have just been
3954 // written out so we assume it ended with a '\n'
3959 BufferParams * params = ¤t_view->buffer()->params;
3960 bool footer_in_body = true;
3961 switch (footnotekind) {
3962 case LyXParagraph::FOOTNOTE:
3963 if (style.intitle) {
3964 file += "\\thanks{\n";
3965 footer_in_body = false;
3967 if (foot_count == -1) {
3968 // we're at depth 0 so we can use:
3969 file += "\\footnote{%\n";
3970 footer_in_body = false;
3972 file += "\\footnotemark{}%\n";
3974 // we only need this when there are
3975 // multiple footnotes
3976 foot += "\\stepcounter{footnote}";
3978 foot += "\\footnotetext{%\n";
3979 foot_texrow.start(this, 0);
3980 foot_texrow.newline();
3985 case LyXParagraph::MARGIN:
3986 file += "\\marginpar{\n";
3988 case LyXParagraph::FIG:
3989 if (pextra_type == PEXTRA_FLOATFLT
3990 && (!pextra_width.empty()
3991 || !pextra_widthp.empty())) {
3993 if (!pextra_width.empty())
3994 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3995 pextra_width.c_str());
3998 "\\begin{floatingfigure}{%f\\textwidth}\n",
3999 atoi(pextra_widthp.c_str())/100.0);
4002 file += "\\begin{figure}";
4003 if (!params->float_placement.empty()) {
4005 file += params->float_placement;
4012 case LyXParagraph::TAB:
4013 file += "\\begin{table}";
4014 if (!params->float_placement.empty()) {
4016 file += params->float_placement;
4022 case LyXParagraph::WIDE_FIG:
4023 file += "\\begin{figure*}";
4024 if (!params->float_placement.empty()) {
4026 file += params->float_placement;
4032 case LyXParagraph::WIDE_TAB:
4033 file += "\\begin{table*}";
4034 if (!params->float_placement.empty()) {
4036 file += params->float_placement;
4042 case LyXParagraph::ALGORITHM:
4043 file += "\\begin{algorithm}\n";
4048 if (footnotekind != LyXParagraph::FOOTNOTE
4049 || !footer_in_body) {
4050 // Process text for all floats except footnotes in body
4052 LyXLayout const & style =
4053 textclasslist.Style(current_view->buffer()->params.textclass,
4056 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4058 if (style.isEnvironment()
4059 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4060 // Allows the use of minipages within float
4061 // environments. Shouldn't be circular because
4062 // we don't support footnotes inside
4063 // floats (yet). ARRae
4064 par = par->TeXEnvironment(file, texrow,
4068 par = par->TeXOnePar(file, texrow,
4073 if (par && !par->IsDummy() && par->depth > depth) {
4074 par = par->TeXDeeper(file, texrow,
4078 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4080 // process footnotes > depth 0 or in environments separately
4081 // NOTE: Currently don't support footnotes within footnotes
4082 // even though that is possible using the \footnotemark
4084 TexRow dummy_texrow;
4085 int dummy_count = 0;
4087 LyXLayout const & style =
4088 textclasslist.Style(current_view->buffer()->params.textclass,
4091 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4093 if (style.isEnvironment()
4094 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4095 // Allows the use of minipages within float
4096 // environments. Shouldn't be circular because
4097 // we don't support footnotes inside
4098 // floats (yet). ARRae
4099 par = par->TeXEnvironment(foot, foot_texrow,
4100 dummy, dummy_texrow,
4103 par = par->TeXOnePar(foot, foot_texrow,
4104 dummy, dummy_texrow,
4108 if (par && !par->IsDummy() && par->depth > depth) {
4109 par = par->TeXDeeper(foot, foot_texrow,
4110 dummy, dummy_texrow,
4114 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4116 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4117 "Footnote in a Footnote -- not supported"
4122 switch (footnotekind) {
4123 case LyXParagraph::FOOTNOTE:
4124 if (footer_in_body) {
4125 // This helps tell which of the multiple
4126 // footnotetexts an error was in.
4128 foot_texrow.newline();
4133 case LyXParagraph::MARGIN:
4136 case LyXParagraph::FIG:
4137 if (pextra_type == PEXTRA_FLOATFLT
4138 && (!pextra_width.empty()
4139 || !pextra_widthp.empty()))
4140 file += "\\end{floatingfigure}";
4142 file += "\\end{figure}";
4144 case LyXParagraph::TAB:
4145 file += "\\end{table}";
4147 case LyXParagraph::WIDE_FIG:
4148 file += "\\end{figure*}";
4150 case LyXParagraph::WIDE_TAB:
4151 file += "\\end{table*}";
4153 case LyXParagraph::ALGORITHM:
4154 file += "\\end{algorithm}";
4158 if (footnotekind != LyXParagraph::FOOTNOTE
4159 && footnotekind != LyXParagraph::MARGIN) {
4160 // we need to ensure that real floats like tables and figures
4161 // have their \end{} on a line of their own otherwise we can
4162 // get incorrect results when using the endfloat.sty package.
4167 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4172 void LyXParagraph::SetPExtraType(int type, char const * width,
4173 char const * widthp)
4176 pextra_width = width;
4177 pextra_widthp = widthp;
4179 if (textclasslist.Style(current_view->buffer()->params.textclass,
4180 layout).isEnvironment()) {
4185 while (par && (par->layout == layout)
4186 && (par->depth == depth)) {
4188 par = par->Previous();
4190 par = par->FirstPhysicalPar();
4191 while (par && par->depth > depth) {
4192 par = par->Previous();
4194 par = par->FirstPhysicalPar();
4198 while (par && (par->layout == layout)
4199 && (par->depth == depth)) {
4200 par->pextra_type = type;
4201 par->pextra_width = width;
4202 par->pextra_widthp = widthp;
4203 par = par->NextAfterFootnote();
4204 if (par && (par->depth > depth))
4205 par->SetPExtraType(type, width, widthp);
4206 while (par && ((par->depth > depth) || par->IsDummy()))
4207 par = par->NextAfterFootnote();
4213 void LyXParagraph::UnsetPExtraType()
4215 if (pextra_type == PEXTRA_NONE)
4218 pextra_type = PEXTRA_NONE;
4219 pextra_width.clear();
4220 pextra_widthp.clear();
4222 if (textclasslist.Style(current_view->buffer()->params.textclass,
4223 layout).isEnvironment()) {
4228 while (par && (par->layout == layout)
4229 && (par->depth == depth)) {
4231 par = par->Previous();
4233 par = par->FirstPhysicalPar();
4234 while (par && par->depth > depth) {
4235 par = par->Previous();
4237 par = par->FirstPhysicalPar();
4241 while (par && (par->layout == layout)
4242 && (par->depth == depth)) {
4243 par->pextra_type = PEXTRA_NONE;
4244 par->pextra_width.clear();
4245 par->pextra_widthp.clear();
4246 par = par->NextAfterFootnote();
4247 if (par && (par->depth > depth))
4248 par->UnsetPExtraType();
4249 while (par && ((par->depth > depth) || par->IsDummy()))
4250 par = par->NextAfterFootnote();
4256 bool LyXParagraph::IsHfill(size_type pos) const
4258 return IsHfillChar(GetChar(pos));
4262 bool LyXParagraph::IsInset(size_type pos) const
4264 return IsInsetChar(GetChar(pos));
4268 bool LyXParagraph::IsFloat(size_type pos) const
4270 return IsFloatChar(GetChar(pos));
4274 bool LyXParagraph::IsNewline(size_type pos) const
4278 tmp = IsNewlineChar(GetChar(pos));
4283 bool LyXParagraph::IsSeparator(size_type pos) const
4285 return IsSeparatorChar(GetChar(pos));
4289 bool LyXParagraph::IsLineSeparator(size_type pos) const
4291 return IsLineSeparatorChar(GetChar(pos));
4295 bool LyXParagraph::IsKomma(size_type pos) const
4297 return IsKommaChar(GetChar(pos));
4301 /// Used by the spellchecker
4302 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4304 unsigned char c = GetChar(pos);
4305 if (IsLetterChar(c))
4307 // '\0' is not a letter, allthough every string contains "" (below)
4310 // We want to pass the ' and escape chars to ispell
4311 string extra = lyxrc->isp_esc_chars + '\'';
4315 return contains(extra, ch);
4319 bool LyXParagraph::IsWord(size_type pos ) const
4321 return IsWordChar(GetChar(pos)) ;