home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / paragraph.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  96KB  |  3,752 lines

  1. /* This file is part of
  2. * ======================================================
  3. *           LyX, The Document Processor
  4. *      
  5. *        Copyright (C) 1995 Matthias Ettrich
  6. *           Copyright (C) 1995-1998 The LyX Team. 
  7. *
  8. *======================================================*/
  9.  
  10. #include <config.h>
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "lyxparagraph.h"
  14. #endif
  15.  
  16. #include "lyxparagraph.h"
  17. #include "lyxrc.h"
  18. #include "layout.h"
  19. #include "tex-strings.h"
  20. #include "bufferparams.h"
  21. #include "FileInfo.h"
  22. #include "error.h"
  23. #include "LaTeXFeatures.h"
  24. #include "insetinclude.h"
  25. #include "filetools.h"
  26. #include "lyx_gui_misc.h"
  27. #include "texrow.h"
  28.  
  29. //     $Id: paragraph.C,v 1.1.1.1 1998/04/23 16:02:56 larsbj Exp $    
  30.  
  31. #if !defined(lint) && !defined(WITH_WARNINGS)
  32. static char vcid[] = "$Id: paragraph.C,v 1.1.1.1 1998/04/23 16:02:56 larsbj Exp $";
  33. #endif /* lint */
  34.  
  35. #define INITIAL_SIZE_PAR 10 /*Number of bytes in one paragraph*/
  36. #define STEP_SIZE_PAR 10 /*Number of bytes added when reallocated*/
  37.  
  38. extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
  39. int tex_code_break_column;
  40. // this is a bad idea, but how can LyXParagraph find its buffer to get
  41. // parameters? (JMarc)
  42. extern BufferView *current_view;
  43. extern LyXRC *lyxrc;
  44.  
  45.  
  46. // ale970405
  47. extern LString bibitemWidthest();
  48.  
  49. /* this is a minibuffer */
  50. static char minibuffer_char;
  51. static LyXFont minibuffer_font;
  52. static Inset *minibuffer_inset;
  53.  
  54.  
  55. /* the counter for the paragraph id's */ 
  56. static paragraph_id = 0;
  57.  
  58.  
  59. LyXParagraph::LyXParagraph()
  60. {
  61.     size = INITIAL_SIZE_PAR;
  62.     last = 0;
  63.     text = new char[size];
  64.     for (int i=0; i<10; i++) counter[i] = 0;
  65.     enumdepth = 0;
  66.     itemdepth = 0;
  67.     next = NULL;
  68.     previous = NULL;
  69.     fonttable = NULL;
  70.     insettable = NULL;
  71.     footnoteflag = LyXParagraph::NO_FOOTNOTE;
  72.  
  73.     align = LYX_ALIGN_BLOCK;
  74.  
  75.     /* table stuff -- begin*/ 
  76.     table = NULL;
  77.     /* table stuff -- end*/ 
  78.     id = paragraph_id++;
  79.         bibkey = NULL; // ale970302
  80.     Clear();
  81. }
  82.  
  83.  
  84. /* this konstruktor inserts the new paragraph in a list */ 
  85. LyXParagraph::LyXParagraph(LyXParagraph *par)
  86. {
  87.     size = INITIAL_SIZE_PAR;
  88.     last = 0;
  89.     text = new char[size];
  90.     for (int i=0; i<10; i++) counter[i] = 0;
  91.     enumdepth = 0;
  92.     itemdepth = 0;
  93.     next = par->next;
  94.     if (next)
  95.         next->previous = this;
  96.     previous = par;
  97.     previous->next = this;
  98.     fonttable = NULL;
  99.     insettable = NULL;
  100.     footnoteflag = LyXParagraph::NO_FOOTNOTE;
  101.     footnotekind = LyXParagraph::FOOTNOTE;
  102.     
  103.     /* table stuff -- begin*/ 
  104.     table = NULL;
  105.     /* table stuff -- end*/ 
  106.     id = paragraph_id++;
  107.  
  108.         bibkey = NULL; // ale970302        
  109.         // ale970302
  110. //        fprintf(stderr, "new bib "); fflush(stderr);    
  111. //        if (par->bibkey) {
  112. //        bibkey = new InsetBibKey(par->bibkey);
  113. //        }
  114.     
  115.     Clear();
  116. }
  117.  
  118. /// Used by the spellchecker
  119. bool LyXParagraph::IsLetter(int pos){
  120.     unsigned char c = GetChar(pos);
  121.     if (IsLetterChar(c))
  122.         return true;
  123.     // We want to pass the ' and escape chars to ispell
  124.     LString extra = lyxrc->isp_esc_chars + '\'';
  125.     char ch[2];
  126.     ch[0] = c;
  127.     ch[1] = 0;
  128.     return extra.contains(ch);
  129. }
  130.  
  131.  
  132. void LyXParagraph::writeFile(FILE *file, BufferParams ¶ms,
  133.                  char footflag, char dth)
  134. {
  135.     LyXFont font1, font2;
  136.     Inset *inset;
  137.     int column = 0;
  138.     int h = 0;
  139.     char c = 0;
  140.  
  141.     if (footnoteflag != LyXParagraph::NO_FOOTNOTE
  142.         || !previous
  143.         || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
  144.         
  145.         /* The beginning or the end of a footnote environment? */ 
  146.         if (footflag != footnoteflag) {
  147.             footflag = footnoteflag;
  148.             if (footflag) {
  149.                 fprintf(file, "\n\\begin_float %s ", 
  150.                     string_footnotekinds[footnotekind]);
  151.             }
  152.             else {
  153.                 fprintf(file, "\n\\end_float ");
  154.             }
  155.         }
  156.  
  157.         /* The beginning or end of a deeper (i.e. nested) area? */
  158.         if (dth != depth) {
  159.             if (depth > dth) {
  160.                 while (depth > dth) {
  161.                     fprintf(file, "\n\\begin_deeper ");
  162.                     dth++;
  163.                 }
  164.             }
  165.             else {
  166.                 while (depth < dth) {
  167.                     fprintf(file, "\n\\end_deeper ");
  168.                     dth--;
  169.                 }
  170.             }
  171.         }
  172.  
  173.         /* First write the layout */ 
  174.         fprintf(file, "\n\\layout %s\n",
  175.             lyxstyle.NameOfLayout(params.textclass,layout).c_str());
  176.  
  177.         /* maybe some vertical spaces */ 
  178.         if (added_space_top.kind() != VSpace::NONE)
  179.             fprintf(file, "\\added_space_top %s ", 
  180.                 added_space_top.asLyXCommand().c_str());
  181.         if (added_space_bottom.kind() != VSpace::NONE)
  182.             fprintf(file, "\\added_space_bottom %s ",
  183.                 added_space_bottom.asLyXCommand().c_str());
  184.             
  185.         /* The labelwidth string used in lists */
  186.         if (!labelwidthstring.empty())
  187.             fprintf(file, "\\labelwidthstring %s\n",
  188.                 labelwidthstring.c_str());
  189.  
  190.         /* Lines above or below? */
  191.         if (line_top)
  192.             fprintf(file, "\\line_top ");
  193.         if (line_bottom)
  194.             fprintf(file, "\\line_bottom ");
  195.  
  196.         /* Pagebreaks above or below? */
  197.         if (pagebreak_top)
  198.             fprintf(file, "\\pagebreak_top ");
  199.         if (pagebreak_bottom)
  200.             fprintf(file, "\\pagebreak_bottom ");
  201.             
  202.         /* Noindent? */
  203.         if (noindent)
  204.             fprintf(file, "\\noindent ");
  205.             
  206.         /* Alignment? */
  207.         if (align != LYX_ALIGN_LAYOUT) {
  208.             switch (align) {
  209.             case LYX_ALIGN_LEFT: h = 1; break;
  210.             case LYX_ALIGN_RIGHT: h = 2; break;
  211.             case LYX_ALIGN_CENTER: h = 3; break;
  212.             default: h = 0; break;
  213.             }
  214.             fprintf(file, "\\align %s ", string_align[h]);
  215.         }
  216.                 if (pextra_type != PEXTRA_NONE) {
  217.                         fprintf(file, "\\pextra_type %d", pextra_type);
  218.                         if (pextra_type == PEXTRA_MINIPAGE) {
  219.                 fprintf(file, " \\pextra_alignment %d",
  220.                     pextra_alignment);
  221.                 if (pextra_hfill)
  222.                     fprintf(file, " \\pextra_hfill %d",
  223.                         pextra_hfill);
  224.                 if (pextra_start_minipage)
  225.                     fprintf(file, " \\pextra_start_minipage %d",
  226.                         pextra_start_minipage);
  227.                         }
  228.                         if (!pextra_width.empty()) {
  229.                 fprintf(file, " \\pextra_width %s",
  230.                                         VSpace(pextra_width).asLyXCommand().c_str());
  231.                         } else if (!pextra_widthp.empty()) {
  232.                 fprintf(file, " \\pextra_widthp %s",pextra_widthp.c_str());
  233.                         }
  234.                         fprintf(file,"\n");
  235.                 }
  236.     }
  237.     else {
  238.            /* Dummy layout. This means that a footnote ended */
  239.         fprintf(file, "\n\\end_float ");
  240.         footflag = LyXParagraph::NO_FOOTNOTE;
  241.     }
  242.         
  243.     /* It might be a table */ 
  244.     if (table){
  245.         fprintf(file, "\\LyXTable\n");
  246.         table->Write(file);
  247.     }
  248.  
  249.     // bibitem  ale970302
  250.     if (bibkey)
  251.         bibkey->Write(file);
  252.  
  253.     font1 = LyXFont(LyXFont::ALL_INHERIT);
  254.  
  255.     column = 0;
  256.     for (int i = 0; i < last; i++) {
  257.         if (!i){
  258.             fprintf(file, "\n");
  259.             column = 0;
  260.         }
  261.  
  262.         // Write font changes
  263.         font2 = GetFontSettings(i);
  264.         if (font2 != font1) {
  265.             font2.lyxWriteChanges(font1, file);
  266.             column = 0;
  267.             font1 = font2;
  268.         }
  269.  
  270.         c = GetChar(i);
  271.         switch (c) {
  272.         case LYX_META_INSET:
  273.             inset = GetInset(i);
  274.             if (inset)
  275.                 if (inset->DirectWrite()) {
  276.                     // international char, let it write
  277.                     // code directly so it's shorter in
  278.                     // the file
  279.                     inset->Write(file);
  280.                 } else {
  281.                     fprintf(file, "\n\\begin_inset ");
  282.                     inset->Write(file);
  283.                     fprintf(file, "\n\\end_inset \n");
  284.                     fprintf(file, "\n");
  285.                     column = 0;
  286.                 }
  287.             break;
  288.         case LYX_META_NEWLINE: 
  289.             fprintf(file, "\n\\newline \n");
  290.             column = 0;
  291.             break;
  292.         case LYX_META_HFILL: 
  293.             fprintf(file, "\n\\hfill \n");
  294.             column = 0;
  295.             break;
  296.         case LYX_META_PROTECTED_SEPARATOR: 
  297.             fprintf(file, "\n\\protected_separator \n");
  298.             column = 0;
  299.             break;
  300.         case '\\': 
  301.             fprintf(file, "\n\\backslash \n");
  302.             column = 0;
  303.             break;
  304.         case '.':
  305.             if (i + 1 < last && GetChar(i + 1) == ' ') {
  306.                 fprintf(file, ".\n");
  307.                 column = 0;
  308.             } else
  309.                 fprintf(file, ".");
  310.             break;
  311.         default:
  312.             if ((column > 70 && c==' ')
  313.                 || column > 79){
  314.                 fprintf(file, "\n");
  315.                 column = 0;
  316.             }
  317.             // this check is to amend a bug. LyX sometimes
  318.             // inserts '\0' this could cause problems.
  319.             if (c != '\0')
  320.                 fprintf(file, "%c", c);
  321.             else
  322.                 lyxerr.print("ERROR (LyXParagraph::writeFile):"
  323.                          " NULL char in structure.");
  324.             column++;
  325.             break;
  326.         }
  327.     }
  328.  
  329.     // now write the next paragraph
  330.     if (next)
  331.         next->writeFile(file, params, footflag, dth);
  332. }
  333.  
  334.  
  335. void LyXParagraph::validate(LaTeXFeatures &features)
  336. {
  337.     // this will be useful later
  338.     LyXLayout *layout = lyxstyle.Style(GetCurrentTextClass(), 
  339.                        GetLayout());
  340.     
  341.     // check the params.
  342.     if (line_top || line_bottom)
  343.         features.lyxline = true;
  344.     
  345.     // then the layouts
  346.     features.layout[GetLayout()] = true;
  347.  
  348.     // then the fonts
  349.     FontTable *tmpfonttable = fonttable;
  350.     while (tmpfonttable) {
  351.         if (tmpfonttable->font.noun() == LyXFont::ON) {
  352.             lyxerr.debug(LString("font.noun: ") 
  353.                      + int(tmpfonttable->font.noun()),
  354.                      Error::LATEX);
  355.             features.noun = true;
  356.             lyxerr.debug("Noun enabled. Font: "
  357.                      +tmpfonttable->font.stateText(),
  358.                      Error::LATEX);
  359.         }
  360.         switch (tmpfonttable->font.color()) {
  361.         case LyXFont::NONE: 
  362.         case LyXFont::INHERIT_COLOR:
  363.         case LyXFont::IGNORE_COLOR:
  364.             break;
  365.         default:
  366.             features.color = true;
  367.             lyxerr.debug("Color enabled. Font: "
  368.                      +tmpfonttable->font.stateText(),
  369.                      Error::LATEX);
  370.         }
  371.         tmpfonttable = tmpfonttable->next;
  372.     }
  373.     
  374.     // then the insets
  375.     InsetTable *tmpinsettable = insettable;
  376.     while (tmpinsettable) {
  377.         if (tmpinsettable->inset) {
  378.             tmpinsettable->inset->Validate(features);
  379.         }
  380.         tmpinsettable = tmpinsettable->next;
  381.     }
  382.         if (table && table->IsLongTable())
  383.         features.longtable = true;
  384.         if (pextra_type == PEXTRA_INDENT)
  385.                 features.LyXParagraphIndent = true;
  386.         if (pextra_type == PEXTRA_FLOATFLT)
  387.                 features.floatflt = true;
  388.         if (layout->needprotect 
  389.         && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
  390.         features.NeedLyXFootnoteCode = true;
  391.         if ((current_view->currentBuffer()->params.paragraph_separation == LYX_PARSEP_INDENT) &&
  392.             (pextra_type == PEXTRA_MINIPAGE))
  393.         features.NeedLyXMinipageIndent = true;
  394.         if (table && table->NeedRotating())
  395.         features.rotating = true;
  396. }
  397.  
  398.  
  399. /* first few functions needed for cut and paste and paragraph breaking */
  400. void LyXParagraph::CopyIntoMinibuffer(int pos)
  401. {
  402.     minibuffer_char = GetChar(pos);
  403.     minibuffer_font = GetFontSettings(pos);
  404.     if (minibuffer_char == LYX_META_INSET) {
  405.         if (GetInset(pos)) {
  406.             minibuffer_inset = GetInset(pos)->Clone();
  407.         } else {
  408.             minibuffer_inset = NULL;
  409.             minibuffer_char = ' ';
  410.             // This reflects what GetInset() does (ARRae)
  411.         }
  412.     }
  413. }
  414.  
  415.  
  416. void LyXParagraph::CutIntoMinibuffer(int pos)
  417. {
  418.     minibuffer_char = GetChar(pos);
  419.     minibuffer_font = GetFontSettings(pos);
  420.     if (minibuffer_char == LYX_META_INSET) {
  421.         if (GetInset(pos)) {
  422.             minibuffer_inset = GetInset(pos);
  423.         } else {
  424.             minibuffer_inset = NULL;
  425.             minibuffer_char = ' ';
  426.             // This reflects what GetInset() does (ARRae)
  427.         }
  428.  
  429.         /* this is a little hack since I want exactly the inset,
  430.            not just a clone. Otherwise the inset would be deleted
  431.            when calling Erase(pos) */
  432.         /* and it's only useful inside the if{} above 
  433.            since the else{} means its not there (ARRae) */
  434.  
  435.         /* find the entry */ 
  436.         InsetTable *tmpi = insettable;
  437.         while (tmpi && tmpi->pos != pos) {
  438.             tmpi=tmpi->next;
  439.         }
  440.         if (tmpi) {               /* this should always be true */
  441.             tmpi->inset = NULL;
  442.         }
  443.     }
  444.  
  445.     /* Erase(pos); now the caller is responsible for that*/
  446. }
  447.  
  448.  
  449. void LyXParagraph::InsertFromMinibuffer(int pos)
  450. {
  451.     InsertChar(pos, minibuffer_char);
  452.     SetFont(pos, minibuffer_font);
  453.     if (minibuffer_char == LYX_META_INSET)
  454.         InsertInset(pos, minibuffer_inset);
  455. }
  456.  
  457. /* end of minibuffer */ 
  458.  
  459.  
  460.  
  461. void LyXParagraph::Clear()
  462. {
  463.     line_top = false;
  464.     line_bottom = false;
  465.    
  466.     pagebreak_top = false;
  467.     pagebreak_bottom = false;
  468.  
  469.     added_space_top = VSpace::NONE;
  470.     added_space_bottom = VSpace::NONE;
  471.  
  472.     align = LYX_ALIGN_LAYOUT;
  473.     depth = 0;
  474.     noindent = false;
  475.  
  476.         pextra_type = PEXTRA_NONE;
  477.         pextra_width.erase();
  478.         pextra_widthp.erase();
  479.         pextra_alignment = MINIPAGE_ALIGN_TOP;
  480.         pextra_hfill = false;
  481.         pextra_start_minipage = false;
  482.  
  483.         labelstring.erase();
  484.     labelwidthstring.erase();
  485.     layout = 0;
  486. }
  487.  
  488.  
  489. /* the destructor removes the new paragraph from the list */ 
  490. LyXParagraph::~LyXParagraph()
  491. {
  492.     if (previous)
  493.         previous->next = next;
  494.     if (next)
  495.         next->previous = previous;
  496.  
  497.     if (text)
  498.         delete[] text;
  499.    
  500.     InsetTable *tmpinset;
  501.     while (insettable) {
  502.         tmpinset = insettable;
  503.         insettable = insettable->next;
  504.         if (tmpinset->inset)
  505.             delete tmpinset->inset;
  506.         delete tmpinset;
  507.         if (insettable && insettable->next == insettable) {
  508.             // somehow this recursion appears occasionally
  509.             // but I can't find where.  This bandaid
  510.             // helps but isn't the best fix. (ARRae)
  511.             if (insettable->inset) {
  512.                 delete insettable->inset;
  513.             }
  514.             delete insettable;
  515.             break;
  516.         }
  517.     }
  518.  
  519.     FontTable *tmpfont;
  520.     while (fonttable) {
  521.         tmpfont = fonttable;
  522.         fonttable = fonttable->next;
  523.         delete tmpfont;
  524.     }
  525.  
  526.     /* table stuff -- begin*/ 
  527.     if (table)
  528.         delete table;
  529.     /* table stuff -- end*/ 
  530.  
  531.         // ale970302
  532.     if (bibkey)
  533.             delete bibkey;
  534. }
  535.  
  536.  
  537. void LyXParagraph::Erase(int pos)
  538. {
  539.     int i;
  540.  
  541.     /* > because last is the next unused position, and you can 
  542.      * use it if you want  */
  543.     if (pos > last) {
  544.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  545.             NextAfterFootnote()->Erase(pos - last - 1);
  546.         else 
  547.             lyxerr.print("ERROR (LyXParagraph::Erase): position does not exist.");
  548.         return;
  549.     }
  550.     if (pos < last) { // last is free for insertation, but should be empty
  551.       
  552.         /* if it is an inset, delete the inset entry */ 
  553.         if (text[pos] == LYX_META_INSET) {
  554.             /* find the entry */ 
  555.             InsetTable *tmpi = insettable;
  556.             InsetTable *tmpi2 = tmpi;
  557.             while (tmpi && tmpi->pos != pos) {
  558.                 tmpi2=tmpi;
  559.                 tmpi=tmpi->next;
  560.             }
  561.             if (tmpi) {    // this should always be true
  562.                 if (tmpi->inset) // delete the inset if it exists
  563.                     delete tmpi->inset;
  564.                 if (tmpi == insettable)
  565.                     insettable = tmpi->next;
  566.                 else 
  567.                     tmpi2->next = tmpi->next;
  568.                 delete tmpi;
  569.             }
  570.         }
  571.  
  572.         // Shift rest of text      
  573.         for (i = pos; i < last - 1; i++) {
  574.             text[i]=text[i+1];
  575.         }
  576.         last--;
  577.  
  578.         /* erase entries in the tables */ 
  579.         int found = 0;
  580.         FontTable *tmp = fonttable;
  581.         FontTable *prev = NULL;
  582.         while (tmp && !found) {
  583.             if (pos >= tmp->pos && pos <= tmp->pos_end)
  584.                 found = 1;
  585.             else {
  586.                 prev = tmp;
  587.                 tmp = tmp->next;
  588.             }
  589.         }
  590.       
  591.         if (found && tmp->pos == tmp->pos_end) {  
  592.             /* if it is a multi-character font entry, we just make 
  593.              * it smaller (see update below), otherwise we should 
  594.              * delete it */
  595.             if (prev)
  596.                 prev->next = tmp->next;
  597.             else
  598.                 fonttable = tmp->next;
  599.      
  600.             delete tmp;
  601.         }
  602.  
  603.         /* update all other entries */
  604.  
  605.         tmp = fonttable;
  606.         while (tmp) {
  607.             if (tmp->pos > pos)
  608.                 tmp->pos--;
  609.             if (tmp->pos_end >= pos)
  610.                 tmp->pos_end--;
  611.             tmp = tmp->next;
  612.         }
  613.       
  614.         /* update the inset table */ 
  615.         InsetTable *tmpi = insettable;
  616.         while (tmpi) {
  617.             if (tmpi->pos > pos)
  618.                 tmpi->pos--;
  619.             tmpi=tmpi->next;
  620.         }
  621.       
  622.     } else {
  623.         lyxerr.print("ERROR (LyXParagraph::Erase): can't erase non-existant char.");
  624.     }
  625. }
  626.  
  627.  
  628. /* pos is needed to specify the paragraph correctly. Remember the
  629. * closed footnotes */ 
  630. void LyXParagraph::Enlarge(int pos, int number)
  631. {
  632.     int i;
  633.  
  634.     /* > because last is the next unused position, and you can 
  635.      * use it if you want  */
  636.     if (pos > last) {
  637.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  638.             NextAfterFootnote()->Enlarge(pos - last - 1, number);
  639.         else 
  640.             lyxerr.print("ERROR (LyXParagraph::Enlarge): position does not exist.");
  641.         return;
  642.     }
  643.  
  644.     if (size - last < number) {
  645.         size += number - size + last + STEP_SIZE_PAR;
  646.         char *tmp = new char[size];
  647.         for (i = 0; i < last; i++)
  648.             tmp[i] = text[i];
  649.         delete[] text;
  650.         text = tmp;
  651.     }
  652. }
  653.  
  654.  
  655. /* make the allocated memory fit to the needed size */
  656. /* used to make a paragraph smaller */
  657. void LyXParagraph::FitSize()
  658. {
  659.     int i;
  660.   
  661.     if (size - last > STEP_SIZE_PAR) {
  662.         size = last + STEP_SIZE_PAR;
  663.         char *tmp = new char[size];
  664.         for (i = 0; i < last; i++)
  665.             tmp[i] = text[i];
  666.         delete[] text;
  667.         text = tmp;
  668.     }
  669. }
  670.  
  671.  
  672. void LyXParagraph::InsertChar(int pos, char c)
  673. {
  674.     register int i;
  675.    
  676.     /* > because last is the next unused position, and you can 
  677.      * use it if you want  */
  678.     if (pos > last) {
  679.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  680.             NextAfterFootnote()->InsertChar(pos - last - 1, c);
  681.         else 
  682.             lyxerr.debug("ERROR (LyXParagraph::InsertChar): "
  683.                      "position does not exist.");
  684.         return;
  685.     }
  686.  
  687.     // Are we full? If so, enlarge.
  688.     if (last == size) {
  689.         size += STEP_SIZE_PAR;
  690.         char *tmp = new char[size];
  691.         for (i = 0; i < last; i++)
  692.             tmp[i] = text[i];
  693.         delete[] text;
  694.         text = tmp;
  695.     }
  696.  
  697.     // Shift rest of character
  698.     for (i = last; i>pos; i--) {
  699.         text[i]=text[i-1];
  700.     }
  701.  
  702.     text[pos]=c;
  703.     last++;
  704.    
  705.     /* update the font table */ 
  706.     FontTable *tmp = fonttable;
  707.     while (tmp) {
  708.         if (tmp->pos >= pos)
  709.             tmp->pos++;
  710.         if (tmp->pos_end >= pos)
  711.             tmp->pos_end++;
  712.         tmp = tmp->next;
  713.     }
  714.    
  715.     /* update the inset table */ 
  716.     InsetTable *tmpi = insettable;
  717.     while (tmpi) {
  718.         if (tmpi->pos >= pos)
  719.             tmpi->pos++;
  720.         tmpi=tmpi->next;
  721.     }
  722. }
  723.  
  724.  
  725. void LyXParagraph::InsertInset(int pos, Inset *inset)
  726. {
  727.     /* > because last is the next unused position, and you can 
  728.      * use it if you want  */
  729.     if (pos > last) {
  730.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  731.             NextAfterFootnote()->InsertInset(pos - last - 1, inset);
  732.         else 
  733.             lyxerr.print("ERROR (LyXParagraph::InsertInset): " 
  734.                      "position does not exist: " + pos);
  735.         return;
  736.     }
  737.  
  738.     if (text[pos]!=LYX_META_INSET) {
  739.         lyxerr.print("ERROR (LyXParagraph::InsertInset): "
  740.                  "there is no LYX_META_INSET");
  741.         return;
  742.     }
  743.  
  744.     if (inset) {
  745.         /* add a new entry in the inset table */ 
  746.         InsetTable *tmpi = new InsetTable;
  747.         tmpi->pos = pos;
  748.         tmpi->inset = inset;
  749.         tmpi->next = insettable;
  750.         insettable = tmpi;
  751.     }
  752. }
  753.  
  754.  
  755. Inset* LyXParagraph::GetInset(int pos)
  756. {
  757.     if (pos >= last) {
  758.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  759.             return NextAfterFootnote()->GetInset(pos - last - 1);
  760.         else { 
  761.                 lyxerr.print(LString("ERROR (LyXParagraph::GetInset): position does not exist: ") + pos);
  762.         }
  763.         return NULL;
  764.     }
  765.  
  766.     /* find the inset */ 
  767.     InsetTable *tmpi = insettable;
  768.  
  769.     while (tmpi && tmpi->pos != pos)
  770.         tmpi = tmpi->next;
  771.  
  772.     if (tmpi)
  773.         return tmpi->inset;
  774.     else {
  775.         lyxerr.print(LString("ERROR (LyXParagraph::GetInset): "
  776.                      "Inset does not exist: ") + pos);
  777.         text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
  778.         // Did this commenting out introduce a bug? So far I have not
  779.         // seen any, please enlighten me. (Lgb)
  780.         // My guess is that since the inset does not exist, we might
  781.         // as well replace it with a space to prevent crashes. (Asger)
  782.         return NULL;
  783.     }
  784. }
  785.  
  786.  
  787. // Gets uninstantiated font setting at position.
  788. // Optimized after profiling. (Asger)
  789. LyXFont LyXParagraph::GetFontSettings(int pos)
  790. {
  791.     if (pos < last) {
  792.         FontTable *tmp = fonttable;
  793.         while (tmp) {
  794.             if (pos >= tmp->pos && pos <= tmp->pos_end) 
  795.                 return tmp->font;
  796.             tmp = tmp->next;
  797.         }
  798.     }
  799.  
  800.     /* > because last is the next unused position, and you can 
  801.      * use it if you want  */
  802.     else if (pos > last) {
  803.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  804.             return NextAfterFootnote()->GetFontSettings(pos - last - 1);
  805.         else {
  806.             // Why is it an error to ask for the font of a
  807.             // position that does not exist? Would it be
  808.             // enough for this to be anable on debug?
  809.             // We want strict error checking, but it's ok to only
  810.             // have it when debugging. (Asger)
  811.             lyxerr.print(
  812.                 LString("ERROR (LyXParagraph::GetFontSettings): "
  813.                     "position does not exist. ") + pos);
  814.         }
  815.     } else if (pos) {
  816.         return GetFontSettings(pos - 1);
  817.     }
  818.     return LyXFont(LyXFont::ALL_INHERIT);
  819. }
  820.  
  821.  
  822. // Gets the fully instantiated font at a given position in a paragraph
  823. // This is basically the same function as LyXText::GetFont() in text2.C.
  824. // The difference is that this one is used for generating the LaTeX file,
  825. // and thus cosmetic "improvements" are disallowed: This has to deliver
  826. // the true picture of the buffer. (Asger)
  827. // If position is -1, we get the layout font of the paragraph.
  828. // If position is -2, we get the font of the manual label of the paragraph.
  829. LyXFont LyXParagraph::getFont(int pos)
  830. {
  831.     LyXFont tmpfont;
  832.     LyXLayout *layout = lyxstyle.Style(GetCurrentTextClass(), 
  833.                        GetLayout());
  834.    
  835.     int main_body=0;
  836.     if (layout->labeltype == LABEL_MANUAL)
  837.         main_body = BeginningOfMainBody();
  838.  
  839.     if (pos >= 0){
  840.         LyXFont layoutfont;
  841.         if (pos < main_body)
  842.             layoutfont = layout->labelfont;
  843.         else
  844.             layoutfont = layout->font;
  845.         tmpfont = GetFontSettings(pos);
  846.         tmpfont.realize(layoutfont);
  847.     } else {
  848.         // process layoutfont for pos == -1 and labelfont for pos < -1
  849.         if (pos == -1)
  850.             tmpfont = layout->font;
  851.         else
  852.             tmpfont = layout->labelfont;
  853.     }
  854.  
  855.     // check for environment font information
  856.     char par_depth = GetDepth();
  857.     LyXParagraph * par = this;
  858.     while (par && par_depth && !tmpfont.resolved()) {
  859.         par = par->DepthHook(par_depth - 1);
  860.         if (par) {
  861.             tmpfont.realize(lyxstyle.
  862.                     Style(GetCurrentTextClass(),
  863.                           par->GetLayout())->font);
  864.             par_depth = par->GetDepth();
  865.         }
  866.     }
  867.  
  868.     tmpfont.realize(lyxstyle.TextClass(GetCurrentTextClass())->defaultfont);
  869.     return tmpfont;
  870. }
  871.  
  872.  
  873. /// Returns the height of the highest font in range
  874. LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(int startpos, int endpos) const
  875. {
  876.     LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
  877.  
  878.     FontTable *tmp = fonttable;
  879.     while (tmp) {
  880.         if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
  881.             LyXFont::FONT_SIZE size = tmp->font.size();
  882.             if (size > maxsize && size<=LyXFont::SIZE_HUGER)
  883.                 maxsize = size;
  884.         }
  885.         tmp = tmp->next;
  886.     }
  887.     return maxsize;
  888. }
  889.  
  890.  
  891. char LyXParagraph::GetChar(int pos)
  892. {
  893. #ifdef DEVEL_VERSION
  894.     /* a workaround to 'fix' some bugs in text-class */
  895.     if (pos < 0) {
  896.         // This function is important. It should not work around bugs.
  897.         // Let's find the bugs instead and fix them. (Asger)
  898.         lyxerr.print(LString("FATAL ERROR (LyXParagraph::GetChar):"
  899.                      " bad position ") + pos);
  900.         abort();
  901.     }
  902. #endif
  903.  
  904.     if (pos < last) {
  905.         return text[pos];
  906.     }
  907.  
  908.     /* > because last is the next unused position, and you can 
  909.      * use it if you want  */
  910.     else if (pos > last) {
  911.         if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) 
  912.             return NextAfterFootnote()->GetChar(pos - last - 1);
  913.         else 
  914.             lyxerr.print("ERROR (LyXParagraph::GetChar): "
  915.                      "position does not exist.");
  916.         return 'F';
  917.     } else { // pos==last
  918.         /* we should have a footnote environment */ 
  919.         if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
  920. // Notice that LyX does request the last char from time to time. (Asger)
  921. //            lyxerr.print("ERROR (LyXParagraph::GetChar): "
  922. //                      "expected footnote.");
  923.             return 'F';
  924.         }
  925.         switch (next->footnotekind) {
  926.         case LyXParagraph::FOOTNOTE:
  927.             return LYX_META_FOOTNOTE;
  928.         case LyXParagraph::MARGIN:
  929.             return LYX_META_MARGIN;
  930.         case LyXParagraph::FIG:
  931.         case LyXParagraph::WIDE_FIG:
  932.             return LYX_META_FIG;
  933.         case LyXParagraph::TAB:
  934.         case LyXParagraph::WIDE_TAB:
  935.             return LYX_META_TAB;
  936.         case LyXParagraph::ALGORITHM:
  937.             return LYX_META_ALGORITHM;
  938.         }
  939. //         if (next->footnotekind == LyXParagraph::FOOTNOTE)
  940. //             return LYX_META_FOOTNOTE;
  941. //         if (next->footnotekind == LyXParagraph::MARGIN)
  942. //             return LYX_META_MARGIN;
  943. //         if (next->footnotekind == LyXParagraph::FIG)
  944. //             return LYX_META_FIG;
  945. //         if (next->footnotekind == LyXParagraph::TAB)
  946. //             return LYX_META_TAB;
  947. //         if (next->footnotekind == LyXParagraph::ALGORITHM)
  948. //             return LYX_META_ALGORITHM;
  949. //         lyxerr.print("ERROR (LyXParagraph::GetChar): "
  950. //                   "unknown footnote kind.");
  951. //         return 'F';        /* this should not happen!  */
  952.         // This _can_ not happen, due to the type of next->footnotekind
  953.         // being LyXParagraph::footnot_kind
  954.         return 'F'; // to shut up gcc
  955.     }
  956. }
  957.  
  958.  
  959. int LyXParagraph::Last()
  960. {
  961.     if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
  962.         return last + NextAfterFootnote()->Last() + 1;   /* the 1 is the symbol
  963.                                   * for the footnote */
  964.     else
  965.         return last;
  966. }
  967.  
  968.  
  969. LyXParagraph *LyXParagraph::ParFromPos(int pos)
  970. {
  971.     /* > because last is the next unused position, and you can 
  972.      * use it if you want  */
  973.     if (pos > last) {
  974.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  975.             return NextAfterFootnote()->ParFromPos(pos - last - 1);
  976.         else 
  977.             lyxerr.print("ERROR (LyXParagraph::ParFromPos): "
  978.                      "position does not exist.");
  979.         return this;
  980.     }
  981.     else
  982.         return this;
  983. }
  984.  
  985.  
  986. int LyXParagraph::PositionInParFromPos(int pos)
  987. {
  988.     /* > because last is the next unused position, and you can 
  989.      * use it if you want  */
  990.     if (pos > last) {
  991.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
  992.             return NextAfterFootnote()->PositionInParFromPos(pos - last - 1);
  993.         else 
  994.             lyxerr.print(
  995.                 "ERROR (LyXParagraph::PositionInParFromPos): "
  996.                 "position does not exist.");
  997.         return pos;
  998.     }
  999.     else
  1000.         return pos;
  1001. }
  1002.  
  1003.  
  1004. void LyXParagraph::SetFont(int pos, LyXFont const & font)
  1005. {
  1006.     /* > because last is the next unused position, and you can 
  1007.      * use it if you want  */
  1008.     if (pos > last) {
  1009.         if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
  1010.             NextAfterFootnote()->SetFont(pos - last - 1, font);
  1011.         } else {
  1012.             lyxerr.print("ERROR (LyXParagraph::SetFont): "
  1013.                      "position does not exist.");
  1014.         }
  1015.         return;
  1016.     }
  1017.  
  1018.     LyXFont patternfont(LyXFont::ALL_INHERIT);
  1019.  
  1020. // First, reduce font against layout/label font
  1021. // Update: The SetCharFont() routine in text2.C already reduces font, so
  1022. // we don't need to do that here. (Asger)
  1023. // No need to simplify this because it will disappear in a new kernel. (Asger)
  1024.  
  1025.     // Next search font table
  1026.     FontTable *tmp2;
  1027.  
  1028.     bool found = false;
  1029.     FontTable *tmp = fonttable;
  1030.     while (tmp && !found) {
  1031.         if (pos >= tmp->pos && pos <= tmp->pos_end)
  1032.             found = true;
  1033.         else
  1034.             tmp = tmp->next;
  1035.     }
  1036.  
  1037.     if (!found) {
  1038.         /* if we did not find a font entry, but if the font at hand
  1039.          * is the same as default, we just forget it */
  1040.         if (font == patternfont)
  1041.             return;
  1042.  
  1043.         /* ok, we did not find a font entry. But maybe there is exactly
  1044.          * the needed font entry one position left */ 
  1045.         found = false;
  1046.         tmp2 = fonttable;
  1047.         while (tmp2 && !found) {
  1048.             if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
  1049.                 found = true;
  1050.             else
  1051.                 tmp2 = tmp2->next;
  1052.         }
  1053.         if (found) {
  1054.             /* ok there is one. maybe it is exactly the needed font */
  1055.             if (tmp2->font == font) {
  1056.                 /* put the position under the font */ 
  1057.                 tmp2->pos_end++;
  1058.                 return;
  1059.             }
  1060.         }
  1061.         /* Add a new entry in the 
  1062.          * fonttable for the position */
  1063.         tmp = new FontTable;
  1064.         tmp->pos = pos;
  1065.         tmp->pos_end = pos;
  1066.         tmp->font = patternfont;
  1067.         tmp->next = fonttable;
  1068.         fonttable = tmp;
  1069.     }
  1070.     else {
  1071.         /* we found a font entry. maybe we have to split it and create
  1072.          * a new one */ 
  1073.  
  1074.         if (tmp->pos != tmp->pos_end) {  /* more than one character  */
  1075.  
  1076.             if (pos == tmp->pos) {
  1077.                 /* maybe we could enlarge the left fonttable */ 
  1078.  
  1079.                 found = false;
  1080.                 tmp2 = fonttable;
  1081.                 while (tmp2 && !found) {
  1082.                     if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
  1083.                         found = true;
  1084.                     else
  1085.                         tmp2 = tmp2->next;
  1086.                 }
  1087.  
  1088.                 /* Is there is one, and is it exactly the needed font? */
  1089.                 if (found && tmp2->font == font) {
  1090.                     /* put the position under the font */ 
  1091.                     tmp2->pos_end++;
  1092.                     tmp->pos++;
  1093.                     return;
  1094.                 }
  1095.  
  1096.                 /* Add a new entry in the 
  1097.                  * fonttable for the position */
  1098.                 tmp2 = new FontTable;
  1099.                 tmp2->pos = pos + 1;
  1100.                 tmp2->pos_end = tmp->pos_end;
  1101.                 tmp2->font = tmp->font;
  1102.                 tmp->pos_end = pos;
  1103.                 tmp2->next = fonttable;
  1104.                 fonttable = tmp2;
  1105.             }
  1106.             else if (pos == tmp->pos_end) {
  1107.                 /* Add a new entry in the 
  1108.                  * fonttable for the position */
  1109.                 tmp2 = new FontTable;
  1110.                 tmp2->pos = tmp->pos;
  1111.                 tmp2->pos_end = tmp->pos_end - 1;
  1112.                 tmp2->font = tmp->font;
  1113.                 tmp->pos = tmp->pos_end;
  1114.                 tmp2->next = fonttable;
  1115.                 fonttable = tmp2;
  1116.             }
  1117.             else {
  1118.                 /* Add a new entry in the 
  1119.                  * fonttable for the position */
  1120.                 tmp2 = new FontTable;
  1121.                 tmp2->pos = tmp->pos;
  1122.                 tmp2->pos_end = pos - 1;
  1123.                 tmp2->font = tmp->font;
  1124.                 tmp2->next = fonttable;
  1125.                 fonttable = tmp2;
  1126.         
  1127.                 tmp2 = new FontTable;
  1128.                 tmp2->pos = pos + 1;
  1129.                 tmp2->pos_end = tmp->pos_end;
  1130.                 tmp2->font = tmp->font;
  1131.                 tmp2->next = fonttable;
  1132.                 fonttable = tmp2;
  1133.         
  1134.                 tmp->pos = pos;
  1135.                 tmp->pos_end = pos;
  1136.             }
  1137.         }
  1138.     }
  1139.  
  1140.     tmp->font = font;
  1141. }
  1142.  
  1143.    
  1144. /* this function is able to hide closed footnotes */
  1145. LyXParagraph *LyXParagraph::Next()
  1146. {
  1147.     LyXParagraph *tmp;
  1148.     if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
  1149.         tmp = next;
  1150.         while (tmp && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
  1151.             tmp = tmp->next;
  1152.         if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
  1153.             return tmp->Next(); /* there can be more than one footnote
  1154.                          * in a logical paragraph */
  1155.         else
  1156.             return next;    /* this should never happen! */
  1157.     }
  1158.     else
  1159.         return next;
  1160. }
  1161.  
  1162.  
  1163. LyXParagraph *LyXParagraph::NextAfterFootnote()
  1164. {
  1165.     LyXParagraph *tmp;
  1166.     if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
  1167.         tmp = next;
  1168.         while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
  1169.             tmp = tmp->next;
  1170.         if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
  1171.             return tmp;           /* there can be more than one footnote
  1172.                         * in a logical paragraph */
  1173.         else
  1174.             return next;                /* this should never happen! */
  1175.     }
  1176.     else
  1177.         return next;
  1178. }
  1179.  
  1180.  
  1181. LyXParagraph *LyXParagraph::PreviousBeforeFootnote()
  1182. {
  1183.     LyXParagraph *tmp;
  1184.     if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
  1185.         tmp = next;
  1186.         while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
  1187.             tmp = tmp->previous;
  1188.         if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
  1189.             return tmp;           /* there can be more than one footnote
  1190.                         * in a logical paragraph */
  1191.         else
  1192.             return previous;                /* this should never happen! */
  1193.     }
  1194.     else
  1195.         return previous;
  1196. }
  1197.  
  1198.  
  1199. LyXParagraph *LyXParagraph::LastPhysicalPar()
  1200. {
  1201.     LyXParagraph *tmp;
  1202.     if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
  1203.         return this;
  1204.    
  1205.     tmp = this;
  1206.     while (tmp->next && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
  1207.         tmp = tmp->NextAfterFootnote();
  1208.    
  1209.     return tmp;
  1210.    
  1211. }
  1212.  
  1213.  
  1214. LyXParagraph *LyXParagraph::FirstPhysicalPar()
  1215. {
  1216.     if (!IsDummy())
  1217.         return this;
  1218.     LyXParagraph *tmppar = this;
  1219.  
  1220.     while (tmppar && (tmppar->IsDummy()
  1221.               || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
  1222.         tmppar = tmppar->previous;
  1223.    
  1224.     if (!tmppar)
  1225.         return this;           /* this should never happen!  */
  1226.     else
  1227.         return tmppar;
  1228. }
  1229.  
  1230.  
  1231. /* this function is able to hide closed footnotes */
  1232. LyXParagraph *LyXParagraph::Previous()
  1233. {
  1234.     LyXParagraph *tmp = previous;
  1235.     if (!tmp)
  1236.         return tmp;
  1237.    
  1238.     if (tmp->previous && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
  1239.         tmp = tmp->previous;
  1240.         while (tmp && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
  1241.             tmp = tmp->previous;
  1242.         if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
  1243.             return tmp->next->Previous();    
  1244.  
  1245.         else
  1246.             return previous; 
  1247.     }
  1248.     else
  1249.         return previous;
  1250. }
  1251.  
  1252.    
  1253. void LyXParagraph::BreakParagraph(int pos, int flag)
  1254. {
  1255.     int i, pos_end, pos_first;
  1256.  
  1257.     /* create a new paragraph */
  1258.     LyXParagraph *par = ParFromPos(pos);
  1259.     LyXParagraph *firstpar = FirstPhysicalPar();
  1260.    
  1261.     LyXParagraph *tmp = new LyXParagraph(par);
  1262.    
  1263.     tmp->footnoteflag = footnoteflag;
  1264.     tmp->footnotekind = footnotekind;
  1265.    
  1266.     /* this is an idea for a more userfriendly layout handling, I will
  1267.      * see what the users say */
  1268.    
  1269.     /* layout stays the same with latex-environments */ 
  1270.     if (flag) {
  1271.         tmp->SetOnlyLayout(firstpar->layout);
  1272.         tmp->SetLabelWidthString(firstpar->labelwidthstring);
  1273.     }
  1274.  
  1275.     if (Last() > pos || !Last() || flag == 2) {
  1276.         tmp->SetOnlyLayout(firstpar->layout);
  1277.         tmp->align = firstpar->align;
  1278.         tmp->SetLabelWidthString(firstpar->labelwidthstring);
  1279.       
  1280.         tmp->line_bottom = firstpar->line_bottom;
  1281.         firstpar->line_bottom = false;
  1282.         tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
  1283.         firstpar->pagebreak_bottom = false;
  1284.         tmp->added_space_bottom = firstpar->added_space_bottom;
  1285.         firstpar->added_space_bottom = VSpace::NONE;
  1286.       
  1287.         tmp->depth = firstpar->depth;
  1288.         tmp->noindent = firstpar->noindent;
  1289.    
  1290.         /* copy everything behind the break-position to the new paragraph */
  1291.         pos_first = 0;
  1292.         while (ParFromPos(pos_first) != par)
  1293.             pos_first++;
  1294.    
  1295.         pos_end = pos_first + par->last - 1;
  1296.    
  1297.         /* make sure there is enough memory for the now larger
  1298.            paragraph. This is not neccessary, because
  1299.            InsertFromMinibuffer will enlarge the memory (it uses
  1300.            InsertChar of course). But doing it by hand
  1301.            is MUCH faster! (only one time, not thousend times!!) */
  1302.  
  1303.         tmp->Enlarge(0, pos_end - pos);
  1304.  
  1305.         for (i = pos; i <= pos_end; i++) {
  1306.             par->CutIntoMinibuffer(i - pos_first);
  1307.             tmp->InsertFromMinibuffer(i - pos);
  1308.         }
  1309.  
  1310.         for (i = pos_end; i >= pos; i--)
  1311.             par->Erase(i - pos_first);
  1312.         /* free memory of the now shorter paragraph*/
  1313.         par->FitSize();
  1314.     }
  1315.  
  1316.     /* just an idea of me */ 
  1317.     if (!pos) {
  1318.         tmp->line_top = firstpar->line_top;
  1319.         tmp->pagebreak_top = firstpar->pagebreak_top;
  1320.         tmp->added_space_top = firstpar->added_space_top;
  1321.         firstpar->Clear();
  1322.         /* layout stays the same with latex-environments */ 
  1323.         if (flag) {
  1324.             firstpar->SetOnlyLayout(tmp->layout);
  1325.             firstpar->SetLabelWidthString(tmp->labelwidthstring);
  1326.             firstpar->depth = tmp->depth;
  1327.         }
  1328.     }
  1329. }
  1330.  
  1331.  
  1332. void LyXParagraph::MakeSameLayout(LyXParagraph *par)
  1333. {
  1334.     par = par->FirstPhysicalPar();
  1335.     footnoteflag = par->footnoteflag;
  1336.     footnotekind = par->footnotekind;
  1337.  
  1338.     layout = par->layout;
  1339.     align = par-> align;
  1340.     SetLabelWidthString(par->labelwidthstring);
  1341.  
  1342.     line_bottom = par->line_bottom;
  1343.     pagebreak_bottom = par->pagebreak_bottom;
  1344.     added_space_bottom = par->added_space_bottom;
  1345.  
  1346.     line_top = par->line_top;
  1347.     pagebreak_top = par->pagebreak_top;
  1348.     added_space_top = par->added_space_top;
  1349.  
  1350.         pextra_type = par->pextra_type;
  1351.         pextra_width = par->pextra_width;
  1352.         pextra_widthp = par->pextra_widthp;
  1353.         pextra_alignment = par->pextra_alignment;
  1354.         pextra_hfill = par->pextra_hfill;
  1355.         pextra_start_minipage = par->pextra_start_minipage;
  1356.  
  1357.     noindent = par->noindent;
  1358.     depth = par->depth;
  1359. }
  1360.  
  1361.  
  1362. LyXParagraph *LyXParagraph::FirstSelfrowPar()
  1363. {
  1364.     LyXParagraph *tmppar;
  1365.    
  1366.     tmppar = this;
  1367.     while (tmppar && (
  1368.         (tmppar->IsDummy() && tmppar->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
  1369.         || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
  1370.         tmppar = tmppar->previous;
  1371.    
  1372.     if (!tmppar)
  1373.         return this;           /* this should never happen!  */
  1374.     else
  1375.         return tmppar;
  1376. }
  1377.  
  1378.  
  1379. LyXParagraph *LyXParagraph::Clone()
  1380. {
  1381.     int i;
  1382.    
  1383.     /* create a new paragraph */
  1384.     LyXParagraph *result = new LyXParagraph();
  1385.    
  1386.     result->MakeSameLayout(this);
  1387.  
  1388.     /* this is because of the dummy layout of the paragraphs that
  1389.        follow footnotes */
  1390.     result->layout = layout;
  1391.    
  1392.     /* table stuff -- begin*/ 
  1393.     if (table)
  1394.         result->table = table->Clone();
  1395.     else
  1396.         result->table = NULL;
  1397.     /* table stuff -- end*/ 
  1398.    
  1399.         // ale970302
  1400.         result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
  1401.                
  1402.     
  1403.     /* copy everything behind the break-position to the new paragraph */
  1404.    
  1405.     /* make shure there is enough memory for the now larger paragraph.
  1406.      * This is not neccessary, because InsertFromMinibuffer will enlarge
  1407.      * the memory (it uses InsertChar of course). But doing it by hand
  1408.      * is MUCH faster! (only one time, not thousend times!!) */
  1409.    
  1410.     result->Enlarge(0, last+2);
  1411.    
  1412.     for (i = 0; i < last; i++) {
  1413.      
  1414.         CopyIntoMinibuffer(i);
  1415.         result->InsertFromMinibuffer(i);
  1416.     }
  1417.     return result;
  1418. }
  1419.  
  1420.  
  1421. bool LyXParagraph::HasSameLayout(LyXParagraph* par)
  1422. {
  1423.     par = par->FirstPhysicalPar();
  1424.  
  1425.     return (
  1426.         par->footnoteflag == footnoteflag &&
  1427.         par->footnotekind == footnotekind &&
  1428.  
  1429.         par->layout == layout &&
  1430.  
  1431.         par->align == align &&
  1432.  
  1433.         par->line_bottom == line_bottom &&
  1434.         par->pagebreak_bottom == pagebreak_bottom &&
  1435.         par->added_space_bottom == added_space_bottom &&
  1436.  
  1437.         par->line_top == line_top &&
  1438.         par->pagebreak_top == pagebreak_top &&
  1439.         par->added_space_top == added_space_top &&
  1440.  
  1441.                 par->pextra_type == pextra_type &&
  1442.                 par->pextra_width == pextra_width && 
  1443.                 par->pextra_widthp == pextra_widthp && 
  1444.                 par->pextra_alignment == pextra_alignment && 
  1445.                 par->pextra_hfill == pextra_hfill && 
  1446.                 par->pextra_start_minipage == pextra_start_minipage && 
  1447.  
  1448.         par->table == table && // what means: NO TABLE AT ALL 
  1449.  
  1450.         par->noindent == noindent &&
  1451.         par->depth == depth);
  1452. }
  1453.  
  1454.  
  1455. void LyXParagraph::BreakParagraphConservative(int pos)
  1456. {
  1457.     int i, pos_end, pos_first;
  1458.    
  1459.     /* create a new paragraph */
  1460.     LyXParagraph *par = ParFromPos(pos);
  1461.  
  1462.     LyXParagraph *tmp = new LyXParagraph(par);
  1463.    
  1464.     tmp->MakeSameLayout(par);
  1465.    
  1466.     if (Last() > pos) {   
  1467.         /* copy everything behind the break-position to the new
  1468.            paragraph */
  1469.         pos_first = 0;
  1470.         while (ParFromPos(pos_first) != par)
  1471.             pos_first++;
  1472.    
  1473.         pos_end = pos_first + par->last - 1;
  1474.    
  1475.         /* make shure there is enough memory for the now larger
  1476.            paragraph. This is not neccessary, because
  1477.            InsertFromMinibuffer will enlarge the memory (it uses
  1478.            InsertChar of course). But doing it by hand
  1479.            is MUCH faster! (only one time, not thousend times!!) */
  1480.    
  1481.         tmp->Enlarge(0, pos_end - pos);
  1482.    
  1483.         for (i = pos; i <= pos_end; i++) {
  1484.       
  1485.             par->CutIntoMinibuffer(i - pos_first);
  1486.             tmp->InsertFromMinibuffer(i - pos);
  1487.         }
  1488.         for (i = pos_end; i >= pos; i--)
  1489.             par->Erase(i - pos_first);
  1490.  
  1491.         /* free memory of the now shorter paragraph*/
  1492.         par->FitSize();
  1493.     }
  1494. }
  1495.    
  1496.  
  1497. /* be carefull, this does not make any check at all */ 
  1498. void LyXParagraph::PasteParagraph()
  1499. {
  1500.     int i, pos_end, pos_insert;
  1501.     LyXParagraph *the_next;
  1502.    
  1503.     /* copy the next paragraph to this one */
  1504.     the_next = Next();
  1505.    
  1506.     LyXParagraph *firstpar = FirstPhysicalPar();
  1507.    
  1508.     /* first the DTP-stuff */ 
  1509.     firstpar->line_bottom = the_next->line_bottom;
  1510.     firstpar->added_space_bottom = the_next->added_space_bottom;
  1511.     firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
  1512.    
  1513.     pos_end = the_next->last - 1;
  1514.     pos_insert = Last();
  1515.    
  1516.     /* enlarge the paragraph. This is faster than enlarge it
  1517.      * every 10th insertion. */ 
  1518.     if (pos_end >= 0)
  1519.         Enlarge(pos_insert, pos_end);
  1520.       
  1521.     /* ok, now copy the paragraph */ 
  1522.     for (i = 0; i <= pos_end; i++) {
  1523.         the_next->CutIntoMinibuffer(i);
  1524.         InsertFromMinibuffer(pos_insert + i);
  1525.     }
  1526.    
  1527.     /* delete the next paragraph */
  1528.     delete the_next;
  1529. }
  1530.  
  1531.  
  1532. void LyXParagraph::OpenFootnote(int pos)
  1533. {
  1534.     LyXParagraph *par = ParFromPos(pos);
  1535.     par = par->next;
  1536.     while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
  1537.         par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
  1538.         par = par->next;
  1539.     }
  1540. }
  1541.  
  1542.  
  1543. void LyXParagraph::CloseFootnote(int pos)
  1544. {
  1545.     LyXParagraph *par = ParFromPos(pos);
  1546.     par = par->next;
  1547.     while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
  1548.         par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
  1549.         par = par->next;
  1550.     }
  1551. }
  1552.  
  1553.  
  1554. int LyXParagraph::GetLayout()
  1555. {
  1556.     return FirstPhysicalPar()->layout;
  1557. }
  1558.  
  1559.  
  1560. char LyXParagraph::GetDepth()
  1561. {
  1562.     return FirstPhysicalPar()->depth;
  1563. }
  1564.  
  1565.  
  1566. char LyXParagraph::GetAlign()
  1567. {
  1568.     return FirstPhysicalPar()->align;
  1569. }
  1570.  
  1571.  
  1572. LString LyXParagraph::GetLabelString()
  1573. {
  1574.     return FirstPhysicalPar()->labelstring;
  1575. }
  1576.  
  1577.  
  1578. unsigned char LyXParagraph::GetCounter(int i)
  1579. {
  1580.     return FirstPhysicalPar()->counter[i];
  1581. }
  1582.  
  1583.  
  1584. /* the next two functions are for the manual labels */ 
  1585. LString LyXParagraph::GetLabelWidthString()
  1586. {
  1587.     if (!FirstPhysicalPar()->labelwidthstring.empty())
  1588.         return FirstPhysicalPar()->labelwidthstring;
  1589.     else
  1590.         return _("Senseless with this layout!");
  1591. }
  1592.  
  1593.  
  1594. void LyXParagraph::SetLabelWidthString(LString const & s)
  1595. {
  1596.     LyXParagraph *par = FirstPhysicalPar();
  1597.  
  1598.     par->labelwidthstring = s;
  1599. }
  1600.  
  1601.  
  1602. void LyXParagraph::SetOnlyLayout(char new_layout)
  1603. {
  1604.     LyXParagraph
  1605.         *par = FirstPhysicalPar(),
  1606.         *ppar = NULL,
  1607.                 *npar = NULL;
  1608.  
  1609.     par->layout = new_layout;
  1610.     /* table stuff -- begin*/ 
  1611.     if (table) 
  1612.         par->layout = 0;
  1613.     /* table stuff -- end*/ 
  1614.         if (par->pextra_type == PEXTRA_NONE) {
  1615.                 if (par->Previous()) {
  1616.                         ppar = par->Previous()->FirstPhysicalPar();
  1617.                         while(ppar
  1618.                   && ppar->Previous()
  1619.                   && (ppar->depth > par->depth))
  1620.                                 ppar = ppar->Previous()->FirstPhysicalPar();
  1621.                 }
  1622.                 if (par->Next()) {
  1623.                         npar = par->Next()->NextAfterFootnote();
  1624.                         while(npar
  1625.                   && npar->Next()
  1626.                   && (npar->depth > par->depth))
  1627.                                 npar = npar->Next()->NextAfterFootnote();
  1628.                 }
  1629.                 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
  1630.                         LString
  1631.                                 p1 = ppar->pextra_width,
  1632.                                 p2 = ppar->pextra_widthp;
  1633.                         ppar->SetPExtraType(ppar->pextra_type,
  1634.                                             p1.c_str(),p2.c_str());
  1635.                 }
  1636.                 if ((par->pextra_type == PEXTRA_NONE) &&
  1637.                     npar && (npar->pextra_type != PEXTRA_NONE)) {
  1638.                         LString
  1639.                                 p1 = npar->pextra_width,
  1640.                                 p2 = npar->pextra_widthp;
  1641.                         npar->SetPExtraType(npar->pextra_type,
  1642.                                             p1.c_str(),p2.c_str());
  1643.                 }
  1644.         }
  1645. }
  1646.  
  1647.  
  1648. void LyXParagraph::SetLayout(char new_layout)
  1649. {
  1650.     LyXParagraph
  1651.         *par = FirstPhysicalPar(),
  1652.         *ppar = NULL,
  1653.         *npar = NULL;
  1654.  
  1655.         par->layout = new_layout;
  1656.     par->labelwidthstring.erase();
  1657.     par->align = LYX_ALIGN_LAYOUT;
  1658.     //par->depth = 0;
  1659.     par->added_space_top = VSpace::NONE;
  1660.     par->added_space_bottom = VSpace::NONE;
  1661.     /* table stuff -- begin*/ 
  1662.     if (table) 
  1663.         par->layout = 0;
  1664.     /* table stuff -- end*/
  1665.         if (par->pextra_type == PEXTRA_NONE) {
  1666.                 if (par->Previous()) {
  1667.                         ppar = par->Previous()->FirstPhysicalPar();
  1668.                         while(ppar
  1669.                   && ppar->Previous()
  1670.                   && (ppar->depth > par->depth))
  1671.                                 ppar = ppar->Previous()->FirstPhysicalPar();
  1672.                 }
  1673.                 if (par->Next()) {
  1674.                         npar = par->Next()->NextAfterFootnote();
  1675.                         while(npar
  1676.                   && npar->Next()
  1677.                   && (npar->depth > par->depth))
  1678.                                 npar = npar->Next()->NextAfterFootnote();
  1679.                 }
  1680.                 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
  1681.                         LString
  1682.                                 p1 = ppar->pextra_width,
  1683.                                 p2 = ppar->pextra_widthp;
  1684.                         ppar->SetPExtraType(ppar->pextra_type,
  1685.                                             p1.c_str(),p2.c_str());
  1686.                 }
  1687.                 if ((par->pextra_type == PEXTRA_NONE) &&
  1688.                     npar && (npar->pextra_type != PEXTRA_NONE)) {
  1689.                         LString
  1690.                                 p1 = npar->pextra_width,
  1691.                                 p2 = npar->pextra_widthp;
  1692.                         npar->SetPExtraType(npar->pextra_type,
  1693.                                             p1.c_str(),p2.c_str());
  1694.                 }
  1695.         }
  1696. }
  1697.  
  1698.  
  1699. /* if the layout of a paragraph contains a manual label, the beginning of the 
  1700. * main body is the beginning of the second word. This is what the par-
  1701. * function returns. If the layout does not contain a label, the main
  1702. * body always starts with position 0. This differentiation is necessary,
  1703. * because there cannot be a newline or a blank <= the beginning of the 
  1704. * main body in TeX. */ 
  1705.  
  1706. int LyXParagraph::BeginningOfMainBody()
  1707. {
  1708.     if (FirstPhysicalPar() != this)
  1709.         return -1;
  1710.    
  1711.     int i = 0;
  1712.    
  1713. //    while (i < last   &&  !(i > 1 && GetChar(i-1)==' ')
  1714. //           && GetChar(i)!=LYX_META_NEWLINE)
  1715. //        i++;
  1716. // Unroll the first two cycles of this loop
  1717. // and remember the previous character to remove unnecessary GetChar() calls
  1718.  
  1719.     if (i < last
  1720.         && GetChar(i) != LYX_META_NEWLINE) {
  1721.         ++i;
  1722.         char previous_char, temp;
  1723.         if (i < last
  1724.             && (previous_char = GetChar(i)) != LYX_META_NEWLINE) {
  1725.             // Yes, this  ^ is supposed to be "=" not "=="
  1726.             ++i;
  1727.             while (i < last
  1728.                    && previous_char != ' '
  1729.                    && (temp = GetChar(i)) != LYX_META_NEWLINE) {
  1730.                 ++i;
  1731.                 previous_char = temp;
  1732.             }
  1733.         }
  1734.     }
  1735.  
  1736.     if (i==0 && i == last &&
  1737.         !(footnoteflag==LyXParagraph::NO_FOOTNOTE
  1738.           && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
  1739.         )
  1740.         i++;                   /* the cursor should not jump  
  1741.                         * to the main body if there
  1742.                         * is nothing in! */
  1743.     return i;
  1744. }
  1745.  
  1746.  
  1747. LyXParagraph* LyXParagraph::DepthHook(int deth)
  1748. {
  1749.     LyXParagraph *newpar = this;
  1750.     if (deth < 0)
  1751.         return NULL;
  1752.    
  1753.     do {
  1754.         newpar = newpar->FirstPhysicalPar()->Previous();
  1755.     } while (newpar && newpar->GetDepth() > deth
  1756.          && newpar->footnoteflag == footnoteflag);
  1757.    
  1758.     if (!newpar) {
  1759.         if (Previous() || GetDepth())
  1760.             lyxerr.print("ERROR (LyXParagraph::DepthHook): "
  1761.                      "no hook.");
  1762.         newpar = this;
  1763.     }
  1764.     return newpar->FirstPhysicalPar();
  1765. }
  1766.  
  1767.  
  1768. int LyXParagraph::AutoDeleteInsets()
  1769. {
  1770.     InsetTable *tmpi = insettable;
  1771.     InsetTable *tmpi2 = tmpi;
  1772.     int i=0;
  1773.     while (tmpi) {
  1774.         tmpi2 = tmpi;
  1775.         tmpi = tmpi->next;
  1776.         if (tmpi2->inset)
  1777.             if (tmpi2->inset->AutoDelete()) {
  1778.                 i++;
  1779.                 Erase(tmpi2->pos);
  1780.             } else {}
  1781.         else
  1782.             lyxerr.print(
  1783.                 "ERROR (LyXParagraph::AutoDeleteInsets): "
  1784.                 "cannot auto-delete insets");
  1785.     }
  1786.     return i;
  1787. }
  1788.  
  1789.  
  1790. Inset* LyXParagraph::ReturnNextInsetPointer(int &pos)
  1791. {
  1792.     InsetTable *tmpi = insettable;
  1793.     InsetTable *tmpi2 = NULL;
  1794.     while (tmpi){
  1795.         if (tmpi->pos >= pos) {
  1796.             if (!tmpi2 || tmpi->pos < tmpi2->pos)
  1797.                 tmpi2 = tmpi;
  1798.         }
  1799.         tmpi=tmpi->next;
  1800.     }
  1801.     if (tmpi2){
  1802.         pos = tmpi2->pos;
  1803.         return tmpi2->inset;
  1804.     }
  1805.     else
  1806.         return NULL;
  1807. }
  1808.  
  1809.  
  1810. /* returns -1 if inset not found */
  1811. int LyXParagraph::GetPositionOfInset(Inset* inset)
  1812. {
  1813.     /* find the entry */ 
  1814.     InsetTable *tmpi = insettable;
  1815.     while (tmpi && tmpi->inset != inset) {
  1816.         tmpi=tmpi->next;
  1817.     }
  1818.     if (tmpi && tmpi->inset)
  1819.         return tmpi->pos;
  1820.     else{
  1821.         /* think about footnotes */
  1822.         if (footnoteflag == LyXParagraph::NO_FOOTNOTE 
  1823.             && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
  1824.             int further =
  1825.                 NextAfterFootnote()->GetPositionOfInset(inset);
  1826.             if (further != -1)
  1827.                 return last + 1 + further;
  1828.         }
  1829.         return -1;
  1830.     }
  1831. }
  1832.  
  1833.  
  1834. void LyXParagraph::readSimpleWholeFile(FILE *myfile)
  1835. {
  1836.     char c;
  1837.  
  1838.     FileInfo fileInfo(fileno(myfile));
  1839.     long file_size = fileInfo.getSize();
  1840.     /* it is horrible, I know, but faster.
  1841.      * I should not use InsertString for that :-( */
  1842.    
  1843.     /* I will write a better insertion in the future */ 
  1844.     Enlarge(0, file_size + 10);
  1845.    
  1846.     rewind(myfile);
  1847.    
  1848.     if (!feof(myfile)) {
  1849.         do {
  1850.             c = fgetc(myfile);
  1851.             InsertChar(last,c);
  1852.         } while (!feof(myfile));
  1853.       
  1854.     }
  1855. }
  1856.  
  1857.  
  1858. LyXParagraph* LyXParagraph::TeXOnePar(LString &file, TexRow &texrow,
  1859.                       LString &foot, TexRow &foot_texrow,
  1860.                       int &foot_count)
  1861. {
  1862.     lyxerr.debug(LString("TeXOnePar...     ") + (long)this, Error::LATEX);
  1863.     LyXParagraph *par = next;
  1864.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), layout);
  1865.  
  1866.     bool further_blank_line = false;
  1867.     if (IsDummy())
  1868.         lyxerr.print("ERROR (LyXParagraph::TeXOnePar) is dummy.");
  1869.  
  1870.     if (tex_code_break_column && style->isCommand()){
  1871.         file += '\n';
  1872.         texrow.newline();
  1873.     }
  1874.  
  1875.     if (pagebreak_top) {
  1876.         file += "\\newpage";
  1877.         further_blank_line = true;
  1878.     }
  1879.     if (added_space_top.kind() != VSpace::NONE) {
  1880.         file += added_space_top.asLatexCommand();
  1881.         further_blank_line = true;
  1882.     }
  1883.       
  1884.     if (line_top) {
  1885.         file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
  1886.         file += "\\vspace{-1\\parskip}";
  1887.         further_blank_line = true;
  1888.     }
  1889.  
  1890.     if (further_blank_line){
  1891.         file += '\n';
  1892.         texrow.newline();
  1893.     }
  1894.  
  1895.     switch (style->latextype) {
  1896.     case LATEX_COMMAND:
  1897.                 //arrae970411
  1898.         if (style->latexparam.empty()) { 
  1899.             file += '\\';
  1900.             file += style->latexname;
  1901.         } else {
  1902.             file += '\\';
  1903.             file += style->latexname;
  1904.             file += '[';
  1905.             file += style->latexparam;
  1906.             file += ']';
  1907.         }
  1908.         break;
  1909.     case LATEX_ITEM_ENVIRONMENT:
  1910.             if (bibkey) 
  1911.             bibkey->Latex(file, false);
  1912.         else
  1913.             file += "\\item ";
  1914.         break;
  1915.     case LATEX_LIST_ENVIRONMENT:
  1916.         file += "\\item ";
  1917.         break;
  1918.     default:
  1919.         break;
  1920.     }
  1921.  
  1922.     bool need_par = SimpleTeXOnePar(file, texrow);
  1923.  
  1924.     // Spit out footnotes
  1925.     while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
  1926.            && par->footnoteflag != footnoteflag) {
  1927.         par = par->TeXFootnote(file, texrow,
  1928.                        foot, foot_texrow, foot_count);
  1929.             par->SimpleTeXOnePar(file, texrow);
  1930.             par = par->next;
  1931.     }
  1932.  
  1933.     // Make sure that \\par is done with the font of the last
  1934.     // character if this has another size as the default.
  1935.     // This is necessary because LaTeX (and LyX on the screen)
  1936.     // calculates the space between the baselines according
  1937.     // to this font. (Matthias)
  1938.     LyXFont font = getFont(Last()-1);
  1939.     if (need_par) {
  1940.         if (style->resfont.size() != font.size()) {
  1941.             file += '\\';
  1942.             file += font.latexSize();
  1943.             file += ' ';
  1944.         }
  1945.         file += "\\par}";
  1946.     } else if (lyxstyle.Style(GetCurrentTextClass(),
  1947.                   GetLayout())->isCommand()){
  1948.         if (style->resfont.size() != font.size()) {
  1949.             file += '\\';
  1950.             file += font.latexSize();
  1951.             file += ' ';
  1952.         }
  1953.         file += '}';
  1954.     } else if (style->resfont.size() != font.size()){
  1955.         file += "{\\" + font.latexSize() + " \\par}";
  1956.     }
  1957.     
  1958.     switch (style->latextype) {
  1959.     case LATEX_ITEM_ENVIRONMENT:
  1960.     case LATEX_LIST_ENVIRONMENT:
  1961.                 if (par && (depth < par->depth)) {
  1962.                         file += '\n';
  1963.                         texrow.newline();
  1964.                 }
  1965.         break;
  1966.     case LATEX_ENVIRONMENT:
  1967.         // if its the last paragraph of the current environment
  1968.         // skip it otherwise fall through
  1969.         if (par
  1970.             && !par->HasSameLayout(this)) {
  1971.             break;
  1972.         }
  1973.     default:
  1974.         file += '\n';
  1975.         texrow.newline();
  1976.     }
  1977.     
  1978.     further_blank_line = false;
  1979.     if (line_bottom) {
  1980.         file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
  1981.         further_blank_line = true;
  1982.     }
  1983.  
  1984.     if (added_space_bottom.kind() != VSpace::NONE) {
  1985.         file += added_space_bottom.asLatexCommand();
  1986.         further_blank_line = true;
  1987.     }
  1988.       
  1989.     if (pagebreak_bottom) {
  1990.         file += "\\newpage";
  1991.         further_blank_line = true;
  1992.     }
  1993.  
  1994.     if (further_blank_line){
  1995.         file += '\n';
  1996.         texrow.newline();
  1997.     }
  1998.  
  1999.     if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
  2000.               par->footnoteflag == LyXParagraph::NO_FOOTNOTE) // &&
  2001. //            (pextra_type != PEXTRA_MINIPAGE ||
  2002. /*             (par && !par->pextra_type == PEXTRA_MINIPAGE)) */ ) {
  2003.         file += '\n';
  2004.         texrow.newline();
  2005.     }
  2006.  
  2007.     lyxerr.debug(LString("TeXOnePar...done ") + (long)par, Error::LATEX);
  2008.     return par;
  2009. }
  2010.  
  2011.  
  2012. // This one spits out the text of the paragraph
  2013. bool LyXParagraph::SimpleTeXOnePar(LString &file, TexRow &texrow)
  2014. {
  2015.     lyxerr.debug(LString("SimpleTeXOnePar...     ")+(long)this, Error::LATEX);
  2016.     if (table)
  2017.         return SimpleTeXOneTablePar(file, texrow);
  2018.     char c;
  2019.     Inset *inset;
  2020.     int main_body;
  2021.     int column;
  2022.     
  2023.     bool return_value = false;
  2024.     //bool underbar = false;
  2025.  
  2026.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), GetLayout());
  2027.     LyXFont basefont;
  2028.  
  2029.     /* maybe we have to create a optional argument */ 
  2030.     if (style->labeltype != LABEL_MANUAL)
  2031.         main_body = 0;
  2032.     else
  2033.         main_body = BeginningOfMainBody();
  2034.  
  2035.     if (main_body > 0) {
  2036.         file += '[';
  2037.         basefont = getFont(-2); // Get label font
  2038.     } else
  2039.         basefont = getFont(-1); // Get layout font
  2040.  
  2041.     column = 0;
  2042.  
  2043.     if (main_body >= 0 && !last && !IsDummy()){
  2044.  
  2045.         if (style->isCommand()) {
  2046.             file += '{';
  2047.             column++;
  2048.         } else if (align != LYX_ALIGN_LAYOUT) {
  2049.             file += '{';
  2050.             column++;
  2051.             return_value = true;
  2052.         }
  2053.     }
  2054.  
  2055.     // Which font is currently active?
  2056.     LyXFont running_font = basefont;
  2057.     // Do we have an open font change?
  2058.     bool open_font = false;
  2059.  
  2060.     texrow.start(this, 0);
  2061.  
  2062.     for (int i = 0; i < last; i++) {
  2063.         column++;
  2064.         // First char in paragraph or after label?
  2065.         if (i == main_body && !IsDummy()) {
  2066.             if (main_body > 0) {
  2067.                 if (open_font) {
  2068.                     column += running_font.latexWriteEndChanges(file, basefont);
  2069.                     open_font = false;
  2070.                 }
  2071.                 basefont = getFont(-1); // Now use the layout font
  2072.                 running_font = basefont;
  2073.                 file += ']';
  2074.                 column++;
  2075.             }
  2076.             if (style->isCommand()) {
  2077.                 file += '{';
  2078.                 column++;
  2079.             } else if (align != LYX_ALIGN_LAYOUT) {
  2080.                 file += '{';
  2081.                 column++;
  2082.                 return_value = true;
  2083.             }
  2084.  
  2085.             if (noindent) {
  2086.                 file += "\\noindent ";
  2087.                 column += 10;
  2088.             }
  2089.             switch (align) {
  2090.             case LYX_ALIGN_LEFT:
  2091.                 file += "\\raggedright ";
  2092.                 column+=13;
  2093.                 break;
  2094.             case LYX_ALIGN_RIGHT:
  2095.                 file += "\\raggedleft ";
  2096.                 column+=12;
  2097.                 break;
  2098.             case LYX_ALIGN_CENTER:
  2099.                 file += "\\centering ";
  2100.                 column+=11;
  2101.                 break;
  2102.             }     
  2103.         }
  2104.  
  2105.         c = GetChar(i);
  2106.  
  2107.         // Fully instantiated font
  2108.         LyXFont font = getFont(i);
  2109.  
  2110.         // Spaces at end of font change are simulated to be outside font change.
  2111.         // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
  2112.         if (open_font && c == ' ' && i <= last-2 
  2113.             && getFont(i+1) != running_font && getFont(i+1) != font) {
  2114.             font = getFont(i+1);
  2115.         }
  2116.  
  2117.         // We end font definition before blanks
  2118.         if (font != running_font && open_font) {
  2119.             column += running_font.latexWriteEndChanges(file, basefont);
  2120.             running_font = basefont;
  2121.             open_font = false;
  2122.         }
  2123.  
  2124.         // Blanks are printed before start of fontswitch
  2125.         if (c==' '){
  2126.             // Do not print the separation of the optional argument
  2127.             if (i != main_body - 1) {
  2128.                 if (column > tex_code_break_column
  2129.                     && i && GetChar(i-1) != ' '
  2130.                     && (i < last-1) 
  2131.                     // In LaTeX mode, we don't want to
  2132.                     // break lines since some commands
  2133.                     // do not like this
  2134.                     && font.latex() != LyXFont::ON 
  2135.                     // same in FreeSpacing mode
  2136.                     && !style->free_spacing
  2137.                     // In typewriter mode, we want to avoid 
  2138.                     // ! . ? : at the end of a line
  2139.                     && !(font.family() == LyXFont::TYPEWRITER_FAMILY 
  2140.                      && (GetChar(i-1) == '.' 
  2141.                          || GetChar(i-1) == '?' 
  2142.                          || GetChar(i-1) == ':' 
  2143.                          || GetChar(i-1) == '!'))) {
  2144.                     file += '\n';
  2145.                     texrow.newline();
  2146.                     texrow.start(this, i+1);
  2147.                     column = 0;
  2148.                 } 
  2149.                 else if (font.latex() == LyXFont::OFF) {
  2150.                     if (font.family() == LyXFont::TYPEWRITER_FAMILY)
  2151.                         file += '~';
  2152.                     else
  2153.                         file += ' ';
  2154.                 }
  2155.             }
  2156.         }
  2157.  
  2158.         // Do we need to change font?
  2159.         if (font != running_font) {
  2160.             column += font.latexWriteStartChanges(file, basefont);
  2161.             running_font = font;
  2162.             open_font = true;
  2163.         }
  2164.  
  2165.         // Do we need to turn on LaTeX mode?
  2166.         if (font.latex() != running_font.latex()) {
  2167.             if (font.latex() == LyXFont::ON
  2168.                 && style->needprotect)
  2169.                 {
  2170.                     file += "\\protect ";
  2171.                     column += 9;
  2172.                 }
  2173.         }
  2174.  
  2175.         if (c == LYX_META_INSET) {
  2176.             inset = GetInset(i);
  2177.             if (inset) {
  2178.                 int len = file.length();
  2179.                 int tmp = inset->Latex(file, style->isCommand());
  2180.                 if (tmp)
  2181.                     column = 0;
  2182.                 else
  2183.                     column += file.length() - len;
  2184.                 //for (;tmp>0;tmp--)
  2185.                 for (;tmp--;)
  2186.                     texrow.newline();
  2187.             }
  2188.         } else {
  2189.             // Are we in LaTeX mode?
  2190.             if (font.latex() == LyXFont::ON) {
  2191.                 switch (c) {
  2192.                 case LYX_META_NEWLINE: 
  2193.                     if (!style->newline_allowed)
  2194.                         file += '\n';
  2195.                     else {
  2196.                         if (open_font) {
  2197.                             column += running_font.latexWriteEndChanges(file, basefont);
  2198.                             open_font = false;
  2199.                         }
  2200.                         basefont = getFont(-1);
  2201.                         running_font = basefont;
  2202.                         file += "\\\\\n";
  2203.                     }
  2204.                     texrow.newline();
  2205.                     texrow.start(this, i+1);
  2206.                     column = 0;
  2207.                     break;  
  2208.                 case LYX_META_HFILL: 
  2209.                     file += "\\hfill{}";
  2210.                     column+=7;
  2211.                     break;
  2212.                 case LYX_META_PROTECTED_SEPARATOR: 
  2213.                     file += '~';
  2214.                     break;
  2215.                 default:
  2216.                     // make sure that we will not print
  2217.                     // error generating chars to the tex
  2218.                     // file. This test would not be needed
  2219.                     // if it were done in the buffer
  2220.                     // itself.
  2221.                     if (c != '\0')
  2222.                         file += c;
  2223.                     break;
  2224.                 }
  2225.             } else {
  2226.                 // Plain mode (i.e. not LaTeX)
  2227.                 switch (c) {
  2228.                 case LYX_META_NEWLINE: 
  2229.                     if (!style->newline_allowed)
  2230.                         file += '\n';
  2231.                     else {
  2232.                         if (open_font) {
  2233.                             column += running_font.latexWriteEndChanges(file, basefont);
  2234.                             open_font = false;
  2235.                         }
  2236.                         basefont = getFont(-1);
  2237.                         running_font = basefont;
  2238.                         file += "\\\\\n";
  2239.                     }
  2240.                     texrow.newline();
  2241.                     texrow.start(this, i+1);
  2242.                     column = 0;
  2243.                     break;
  2244.                 case LYX_META_HFILL: 
  2245.                     file += "\\hfill{}";
  2246.                     column+=7;
  2247.                     break;
  2248.                 case LYX_META_PROTECTED_SEPARATOR: 
  2249.                     file += '~';
  2250.                     break;
  2251.                 case '\\': 
  2252.                     if (lyxrc->fontenc=="T1" 
  2253.                         || font.family() == LyXFont::TYPEWRITER_FAMILY){ 
  2254.                         file += "\\char`\\\\{}";
  2255.                         column+=9;
  2256.                     }
  2257.                     else {
  2258.                         file += "\\ensuremath{\\backslash}";
  2259.                         column+=22;
  2260.                     }
  2261.                     break;
  2262.                 case '░': case '▒': case '▓': case '│':  
  2263.                 case '╫': case '≈': case '╣': case '¬':
  2264.                 case '║': case '¼': case '╡':
  2265.                     if (current_view->currentBuffer()->params.inputenc == "latin1") {
  2266.                         file += "\\ensuremath{";
  2267.                         file += c;
  2268.                         file += '}';
  2269.                         column+=13;
  2270.                     } else
  2271.                         file += c;
  2272.                     break;
  2273.                 case '|': case '<': case '>':
  2274.                     if (lyxrc->fontenc=="T1") {
  2275.                         if ((c=='>' ||c=='<')
  2276.                             && i <= last-2 
  2277.                             && GetChar(i+1)==c){
  2278.                             file += c;
  2279.                             file += "\\textcompwordmark{}";
  2280.                             column+=19;
  2281.                         } else 
  2282.                             file += c;
  2283.                     } else if(font.family() == LyXFont::TYPEWRITER_FAMILY)
  2284.                         file += c;
  2285.                     else {
  2286.                         file +="\\ensuremath{";
  2287.                         file += c;
  2288.                         file += '}';
  2289.                         column+=13;
  2290.                     }
  2291.                     break;
  2292.                 case '-': // "--" in Typewriter mode -> "-{}-"
  2293.                     if (i <= last-2 
  2294.                         && GetChar(i+1) == '-'
  2295.                         && font.family() == LyXFont::TYPEWRITER_FAMILY) {
  2296.                         file += "-{}";
  2297.                         column += 2;
  2298.                     } else
  2299.                         file += '-';
  2300.                     break;
  2301.                 case '\"': 
  2302.                     file += "\\char`\\\"{}";
  2303.                     column+=9;
  2304.                     break;
  2305.                 case 'ú':
  2306.                     if (current_view->currentBuffer()->params.inputenc == "default") {
  2307.                         file += "\\pounds{}";
  2308.                         column+=8;
  2309.                     } else
  2310.                         file += c;
  2311.                     break;
  2312.                 case '$': case '&': 
  2313.                 case '%': case '#': case '{':   
  2314.                 case '}': case '_': 
  2315.                     file += '\\';
  2316.                     file += c;
  2317.                     column +=1;
  2318.                     break;
  2319.                 case '^': case '~':
  2320.                     file += '\\';
  2321.                     file += c;
  2322.                     file += "{}";
  2323.                     column +=3;
  2324.                     break;
  2325.                 case '*': case '[': case ']':
  2326.                     // avoid being mistaken for optional arguments
  2327.                     file += '{';
  2328.                     file += c;
  2329.                     file += '}';
  2330.                     column +=2;
  2331.                     break;
  2332.                 case ' ':
  2333.                     /* blanks are printed before font switching */
  2334.                     // Sure? I am not! (try nice-latex)
  2335.                     // I am sure it's correct. LyX might be smarter
  2336.                     // in the future, but for now, nothing wrong is
  2337.                     // written. (Asger)
  2338.                     break;
  2339.                 default:
  2340.                     /* idea for labels --- begin*/ 
  2341.  
  2342.                     /* check for LyX */ 
  2343.                     if (c ==  'L' && i <= last-3 
  2344.                         && font.family() 
  2345.                               != LyXFont::TYPEWRITER_FAMILY
  2346.                         && GetChar(i+1) == 'y'
  2347.                         && GetChar(i+2) == 'X'){
  2348.                         file += "\\LyX{}";
  2349.                         i+=2;
  2350.                         column += 5;
  2351.                     }
  2352.                     /* check for TeX */ 
  2353.                     else if (c ==  'T' && i <= last-3 
  2354.                          && font.family() 
  2355.                               != LyXFont::TYPEWRITER_FAMILY
  2356.                          && GetChar(i+1) == 'e'
  2357.                          && GetChar(i+2) == 'X'){
  2358.                         file += "\\TeX{}";
  2359.                         i+=2;
  2360.                         column += 5;
  2361.                     }
  2362.                     /* check for LaTeX2e */ 
  2363.                     else if (c ==  'L' && i <= last-7 
  2364.                          && font.family() 
  2365.                               != LyXFont::TYPEWRITER_FAMILY
  2366.                          && GetChar(i+1) == 'a'
  2367.                          && GetChar(i+2) == 'T'
  2368.                          && GetChar(i+3) == 'e'
  2369.                          && GetChar(i+4) == 'X'
  2370.                          && GetChar(i+5) == '2'
  2371.                          && GetChar(i+6) == 'e'){
  2372.                         file += "\\LaTeXe{}";
  2373.                         i+=6;
  2374.                         column += 8;
  2375.                     }
  2376.                     /* check for LaTeX */ 
  2377.                     else if (c ==  'L' && i <= last-5 
  2378.                          && font.family() 
  2379.                               != LyXFont::TYPEWRITER_FAMILY
  2380.                          && GetChar(i+1) == 'a'
  2381.                          && GetChar(i+2) == 'T'
  2382.                          && GetChar(i+3) == 'e'
  2383.                          && GetChar(i+4) == 'X'){
  2384.                         file += "\\LaTeX{}";
  2385.                         i+=4;
  2386.                         column += 7;
  2387.                     }
  2388.                     else
  2389.                         /* idea for labels --- end*/ 
  2390.                         // same test as above
  2391.                         if (c != '\0')
  2392.                             file += c;
  2393.                     break;
  2394.                 }
  2395.             }
  2396.         }
  2397.     }
  2398.  
  2399.     // If we have an open font definition, we have to close it
  2400.     if (open_font) {
  2401.         running_font.latexWriteEndChanges(file, basefont);
  2402.     }
  2403.  
  2404.     /* needed if there is an optional argument but no contents */ 
  2405.     if (main_body > 0 && main_body == last) {
  2406.         file += "]~";
  2407.         return_value = false;
  2408.     }
  2409.  
  2410.     lyxerr.debug(LString("SimpleTeXOnePar...done ") + (long)this, Error::LATEX);
  2411.     return return_value;
  2412. }
  2413.  
  2414.  
  2415. // This one spits out the text of a table paragraph
  2416. bool LyXParagraph::SimpleTeXOneTablePar(LString &file, TexRow &texrow)
  2417. {
  2418.     lyxerr.debug(LString("SimpleTeXOneTablePar...     ")+(long)this, Error::LATEX);
  2419.     char c;
  2420.     Inset *inset;
  2421.     int column, tmp;
  2422.    
  2423.     bool return_value = false;
  2424.     int current_cell_number = -1;
  2425.  
  2426.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), GetLayout());
  2427.     LyXFont basefont;
  2428.  
  2429.     basefont = getFont(-1); // Get layout font
  2430.     // Which font is currently active?
  2431.     LyXFont running_font = basefont;
  2432.     // Do we have an open font change?
  2433.     bool open_font = false;
  2434.  
  2435.     column = 0;
  2436. #ifdef THIS_IS_WRONG
  2437.     if (!last && !IsDummy()){
  2438.         if (style->isCommand()) {
  2439.             file += '{';
  2440.             column++;
  2441.         } else if (align != LYX_ALIGN_LAYOUT) {
  2442.             file += '{';
  2443.             column++;
  2444.             return_value = true;
  2445.         }
  2446.     } else if (last && !IsDummy())
  2447. #else
  2448.         if (!IsDummy())
  2449. #endif
  2450.             {
  2451.                 if (style->isCommand()) {
  2452.                     file += '{';
  2453.                     column++;
  2454.                 } else if (align != LYX_ALIGN_LAYOUT) {
  2455.                     file += '{';
  2456.                     column++;
  2457.                     return_value = true;
  2458.                 }
  2459.                 if (noindent) {
  2460.                     file += "\\noindent ";
  2461.                     column += 10;
  2462.                 }
  2463.                 switch (align) {
  2464.                 case LYX_ALIGN_LEFT:
  2465.                     file += "\\raggedright ";
  2466.                     column+=13;
  2467.                     break;
  2468.                 case LYX_ALIGN_RIGHT:
  2469.                     file += "\\raggedleft ";
  2470.                     column+=12;
  2471.                     break;
  2472.                 case LYX_ALIGN_CENTER:
  2473.                     file += "\\centering ";
  2474.                     column+=11;
  2475.                     break;
  2476.                 }     
  2477.                 current_cell_number = -1;
  2478.                 tmp = table->TexEndOfCell(file,current_cell_number);
  2479.                 for (;tmp>0;tmp--)
  2480.                     texrow.newline();
  2481.             }
  2482.  
  2483.     texrow.start(this, 0);
  2484.  
  2485.     for (int i = 0; i < last; i++) {
  2486.         c = GetChar(i);
  2487.         if (table->IsContRow(current_cell_number+1)) {
  2488.             if (c == LYX_META_NEWLINE)
  2489.                 current_cell_number++;
  2490.             continue;
  2491.         }
  2492.         column++;
  2493.         
  2494.         // Fully instantiated font
  2495.         LyXFont font = getFont(i);
  2496.         
  2497.         // We end font definition before blanks
  2498.         if (font != running_font && open_font) {
  2499.             column += running_font.latexWriteEndChanges(file, basefont);
  2500.             running_font = basefont;
  2501.             open_font = false;
  2502.         }
  2503.         // Blanks are printed before start of fontswitch
  2504.         if (c==' '){
  2505.             if (column > tex_code_break_column
  2506.                 && i && GetChar(i-1) != ' '
  2507.                 && (i < last-1) &&
  2508.                 // In LaTeX mode, we don't want to
  2509.                 // break lines since some commands
  2510.                 // do not like this
  2511.                 ! (font.latex() == LyXFont::ON) &&
  2512.                 // In typewriter mode, we want to avoid 
  2513.                 // ! . ? : at the end of a line
  2514.                 !(font.family() == LyXFont::TYPEWRITER_FAMILY &&
  2515.                   (GetChar(i-1) == '.' || GetChar(i-1) == '?' ||
  2516.                    GetChar(i-1) == ':' || GetChar(i-1) == '!')))
  2517.                 {
  2518.                     file += '\n';
  2519.                     texrow.newline();
  2520.                     texrow.start(this, i+1);
  2521.                     column = 0;
  2522.                 } else if (font.latex() == LyXFont::OFF) {
  2523.                     if (font.family() == LyXFont::TYPEWRITER_FAMILY)
  2524.                         file += '~';
  2525.                     else
  2526.                         file += ' ';
  2527.                 }
  2528.         }
  2529.         // Do we need to change font?
  2530.         if (font != running_font) {
  2531.             column += font.latexWriteStartChanges(file, basefont);
  2532.             running_font = font;
  2533.             open_font = true;
  2534.         }
  2535.         // Do we need to turn on LaTeX mode?
  2536.         if (font.latex() != running_font.latex()) {
  2537.             if (font.latex() == LyXFont::ON
  2538.                 && style->needprotect)
  2539.                 {
  2540.                     file += "\\protect ";
  2541.                     column += 9;
  2542.                 }
  2543.         }
  2544.         if (c == LYX_META_INSET) {
  2545.             inset = GetInset(i);
  2546.             if (inset) {
  2547.                 tmp = inset->Latex(file, style->isCommand());
  2548.                 if (tmp)
  2549.                     column = 0;
  2550.                 for (;tmp--;)
  2551.                     texrow.newline();
  2552.             }
  2553.         } else {
  2554.             // Are we in LaTeX mode?
  2555.             if (font.latex() == LyXFont::ON) {
  2556.                 switch (c) {
  2557.                 case LYX_META_NEWLINE: 
  2558.                     if (open_font) {
  2559.                         column += running_font.latexWriteEndChanges(file, basefont);
  2560.                         open_font = false;
  2561.                     }
  2562.                     basefont = getFont(-1);
  2563.                     running_font = basefont;
  2564.                     current_cell_number++;
  2565.                     if (table->CellHasContRow(current_cell_number)>=0)
  2566.                         TeXContTableRows(file, i+1,current_cell_number,column, texrow);
  2567.                     // if this cell follow only ContRows til end don't
  2568.                     // put the EndOfCell because it is put after the
  2569.                     // for(...)
  2570.                     if (table->ShouldBeVeryLastCell(current_cell_number))
  2571.                         break;
  2572.                     tmp = table->TexEndOfCell(file, current_cell_number);
  2573.                     if (tmp>0)
  2574.                         column = 0;
  2575.                     else if (tmp < 0)
  2576.                         tmp = -tmp;
  2577.                     for (;tmp--;)
  2578.                         texrow.newline();
  2579.                     texrow.start(this, i+1);
  2580.                     break;  
  2581.                 case LYX_META_HFILL: 
  2582.                     file += "\\hfill{}";
  2583.                     column+=7;
  2584.                     break;
  2585.                 case LYX_META_PROTECTED_SEPARATOR: 
  2586.                     file += '~';
  2587.                     break;
  2588.                 default:
  2589.                     // make sure that we will not print
  2590.                     // error generating chars to the tex
  2591.                     // file. This test would not be needed
  2592.                     // if it were done in the buffer
  2593.                     // itself.
  2594.                     if (c != '\0')
  2595.                         file += c;
  2596.                     break;
  2597.                 }
  2598.             } else {
  2599.                 // Plain mode (i.e. not LaTeX)
  2600.                 switch (c) {
  2601.                 case LYX_META_NEWLINE: 
  2602.                     if (open_font) {
  2603.                         column += running_font.latexWriteEndChanges(file, basefont);
  2604.                         open_font = false;
  2605.                     }
  2606.                     basefont = getFont(-1);
  2607.                     running_font = basefont;
  2608.  
  2609.                     current_cell_number++;
  2610.                     if (table->CellHasContRow(current_cell_number)>=0)
  2611.                         TeXContTableRows(file,i+1,current_cell_number,column, texrow);
  2612.                     // if this cell follow only ContRows til end don't
  2613.                     // put the EndOfCell because it is put after the
  2614.                     // for(...)
  2615.                     if (table->ShouldBeVeryLastCell(current_cell_number))
  2616.                         break;
  2617.                     tmp = table->TexEndOfCell(file, current_cell_number);
  2618.                     if (tmp>0)
  2619.                         column = 0;
  2620.                     else if (tmp < 0)
  2621.                         tmp = -tmp;
  2622.                     for (;tmp>0;tmp--)
  2623.                         texrow.newline();
  2624.                     texrow.start(this, i+1);
  2625.                     break;
  2626.                 case LYX_META_HFILL: 
  2627.                     file += "\\hfill{}";
  2628.                     column+=7;
  2629.                     break;
  2630.                 case LYX_META_PROTECTED_SEPARATOR: 
  2631.                     file += '~';
  2632.                     break;
  2633.                 case '\\': 
  2634.                     if (lyxrc->fontenc=="T1" 
  2635.                         || font.family() == LyXFont::TYPEWRITER_FAMILY){ 
  2636.                         file += "\\char`\\\\{}";
  2637.                         column+=9;
  2638.                     } else {
  2639.                         file += "\\ensuremath{\\backslash}";
  2640.                         column+=22;
  2641.                     }
  2642.                     break;
  2643.                 case '░': case '▒': case '▓': case '│':  
  2644.                 case '╫': case '≈': case '╣': case '¬':
  2645.                 case '║': case '¼': case '╡':
  2646.                     if (current_view->currentBuffer()->params.inputenc == "latin1") {
  2647.                         file += "\\ensuremath{";
  2648.                         file += c;
  2649.                         file += '}';
  2650.                         column+=13;
  2651.                     } else
  2652.                         file += c;
  2653.                     break;
  2654.                 case '|': case '<': case '>':
  2655.                     if (lyxrc->fontenc=="T1") {
  2656.                         if ((c=='>' ||c=='<')
  2657.                             && i <= last-2 
  2658.                             && GetChar(i+1)==c){
  2659.                             file += c;
  2660.                             file += "\\textcompwordmark{}";
  2661.                             column+=19;
  2662.                         } else 
  2663.                             file += c;
  2664.                     } else if(font.family() == LyXFont::TYPEWRITER_FAMILY)
  2665.                         file += c;
  2666.                     else {
  2667.                         file += "\\ensuremath{";
  2668.                         file += c;
  2669.                         file += '}';
  2670.                         column+=13;
  2671.                     }
  2672.                     break;
  2673.                 case '-': // "--" in Typewriter mode -> "-{}-"
  2674.                     if (i <= last-2 
  2675.                         && GetChar(i+1) == '-'
  2676.                         && font.family() == LyXFont::TYPEWRITER_FAMILY) {
  2677.                         file += "-{}";
  2678.                         column += 2;
  2679.                     } else
  2680.                         file += '-';
  2681.                     break;
  2682.                 case '\"': 
  2683.                     file += "\\char`\\\"{}";
  2684.                     column+=9;
  2685.                     break;
  2686.                 case 'ú':
  2687.                     if (current_view->currentBuffer()->params.inputenc == "default") {
  2688.                         file += "\\pounds{}";
  2689.                         column+=8;
  2690.                     } else
  2691.                         file += c;
  2692.                     break;
  2693.                 case '$': case '&': 
  2694.                 case '%': case '#': case '{':   
  2695.                 case '}': case '_': 
  2696.                     file += '\\';
  2697.                     file += c;
  2698.                     column +=1;
  2699.                     break;
  2700.                 case '^': case '~':
  2701.                     file += '\\';
  2702.                     file += c;
  2703.                     file += "{}";
  2704.                     column +=3;
  2705.                     break;
  2706.                 case '*': case '[': case ']':
  2707.                     // avoid being mistaken for optional arguments
  2708.                     file += '{';
  2709.                     file += c;
  2710.                     file += '}';
  2711.                     column +=2;
  2712.                     break;
  2713.                 case ' ':
  2714.                     /* blanks are printed before font switching */
  2715.                     // Sure? I am not! (try nice-latex)
  2716.                     // I am sure it's correct. LyX might be smarter
  2717.                     // in the future, but for now, nothing wrong is
  2718.                     // written. (Asger)
  2719.                     break;
  2720.                 default:
  2721.                     /* idea for labels --- begin*/ 
  2722.  
  2723.                     /* check for LyX */ 
  2724.                     if (c ==  'L' && i <= last-3
  2725.                         && font.family() 
  2726.                            != LyXFont::TYPEWRITER_FAMILY
  2727.                         && GetChar(i+1) == 'y'
  2728.                         && GetChar(i+2) == 'X'){
  2729.                         file += "\\LyX{}";
  2730.                         i+=2;
  2731.                         column += 5;
  2732.                     }
  2733.                     /* check for TeX */ 
  2734.                     else if (c ==  'T' && i <= last-3
  2735.                          && font.family() 
  2736.                           != LyXFont::TYPEWRITER_FAMILY
  2737.                          && GetChar(i+1) == 'e'
  2738.                          && GetChar(i+2) == 'X'){
  2739.                         file += "\\TeX{}";
  2740.                         i+=2;
  2741.                         column += 5;
  2742.                     }
  2743.                     /* check for LaTeX2e */ 
  2744.                     else if (c ==  'L' && i <= last-7 
  2745.                          && font.family() 
  2746.                           != LyXFont::TYPEWRITER_FAMILY
  2747.                          && GetChar(i+1) == 'a'
  2748.                          && GetChar(i+2) == 'T'
  2749.                          && GetChar(i+3) == 'e'
  2750.                          && GetChar(i+4) == 'X'
  2751.                          && GetChar(i+5) == '2'
  2752.                          && GetChar(i+6) == 'e'){
  2753.                         file += "\\LaTeXe{}";
  2754.                         i+=6;
  2755.                         column += 8;
  2756.                     }
  2757.                     /* check for LaTeX */ 
  2758.                     else if (c ==  'L' && i <= last-5 
  2759.                          && font.family() 
  2760.                           != LyXFont::TYPEWRITER_FAMILY
  2761.                          && GetChar(i+1) == 'a'
  2762.                          && GetChar(i+2) == 'T'
  2763.                          && GetChar(i+3) == 'e'
  2764.                          && GetChar(i+4) == 'X'){
  2765.                         file += "\\LaTeX{}";
  2766.                         i+=4;
  2767.                         column += 7;
  2768.                     } else
  2769.                         /* idea for labels --- end*/ 
  2770.                         // same test as above
  2771.                         if (c != '\0')
  2772.                             file += c;
  2773.                     break;
  2774.                 }
  2775.             }
  2776.         }
  2777.     }
  2778.  
  2779.     // If we have an open font definition, we have to close it
  2780.     if (open_font) {
  2781.         running_font.latexWriteEndChanges(file, basefont);
  2782.     }
  2783.     current_cell_number++;
  2784.     tmp = table->TexEndOfCell(file, current_cell_number);
  2785.     for (;tmp>0;tmp--)
  2786.         texrow.newline();
  2787.     lyxerr.debug(LString("SimpleTeXOneTablePar...done ")+(long)this, Error::LATEX);
  2788.     return return_value;
  2789. }
  2790.  
  2791.  
  2792. // This one spits out the text off ContRows in tables
  2793. bool LyXParagraph::TeXContTableRows(LString &file, int i,
  2794.                     int current_cell_number,
  2795.                     int &column, TexRow &texrow)
  2796. {
  2797.     lyxerr.debug(LString("TeXContTableRows...     ")+(long)this, Error::LATEX);
  2798.     if (!table)
  2799.         return false;
  2800.     
  2801.     char c;
  2802.     Inset *inset;
  2803.     int tmp, cell;
  2804.     int lastpos;
  2805.    
  2806.     bool return_value = false;
  2807.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), GetLayout());
  2808.     LyXFont basefont;
  2809.  
  2810.     basefont = getFont(-1); // Get layout font
  2811.     // Which font is currently active?
  2812.     LyXFont running_font = basefont;
  2813.     // Do we have an open font change?
  2814.     bool open_font = false;
  2815.  
  2816.     lastpos = i;
  2817.     cell = table->CellHasContRow(current_cell_number);
  2818.     current_cell_number++;
  2819.     while(cell >= 0) {
  2820.         // first find the right position
  2821.         i = lastpos;
  2822.         for (; (i<last) && (current_cell_number<cell); i++) {
  2823.             c = GetChar(i);
  2824.             if (c == LYX_META_NEWLINE)
  2825.                 current_cell_number++;
  2826.         }
  2827.         lastpos = i;
  2828.         c=GetChar(i);
  2829.         if (table->Linebreaks(table->FirstVirtualCell(cell))) {
  2830.             file += " \\\\\n";
  2831.             texrow.newline();
  2832.             column = 0;
  2833.         } else if ((c != ' ') && (c != LYX_META_NEWLINE))
  2834.             file += ' ';
  2835.         for (; (i < last) && ((c=GetChar(i)) != LYX_META_NEWLINE); i++) {
  2836.             column++;
  2837.  
  2838.             // Fully instantiated font
  2839.             LyXFont font = getFont(i);
  2840.             
  2841.             // We end font definition before blanks
  2842.             if (font != running_font && open_font) {
  2843.                 column += running_font.latexWriteEndChanges(file, basefont);
  2844.                 running_font = basefont;
  2845.                 open_font = false;
  2846.             }
  2847.             // Blanks are printed before start of fontswitch
  2848.             if (c==' '){
  2849.                 if (column > tex_code_break_column
  2850.                     && i && GetChar(i-1) != ' '
  2851.                     && (i < last-1) &&
  2852.                     // In LaTeX mode, we don't want to
  2853.                     // break lines since some commands
  2854.                     // do not like this
  2855.                     ! (font.latex() == LyXFont::ON) &&
  2856.                     // In typewriter mode, we want to avoid 
  2857.                     // ! . ? : at the end of a line
  2858.                     !(font.family() == LyXFont::TYPEWRITER_FAMILY &&
  2859.                       (GetChar(i-1) == '.' || GetChar(i-1) == '?' ||
  2860.                        GetChar(i-1) == ':' || GetChar(i-1) == '!')))
  2861.                     {
  2862.                         file += '\n';
  2863.                         texrow.newline();
  2864.                         texrow.start(this, i+1);
  2865.                         column = 0;
  2866.                     } else if (font.latex() == LyXFont::OFF) {
  2867.                         if (font.family() == LyXFont::TYPEWRITER_FAMILY)
  2868.                             file += '~';
  2869.                         else
  2870.                             file += ' ';
  2871.                     }
  2872.             }
  2873.             // Do we need to change font?
  2874.             if (font != running_font) {
  2875.                 column += font.latexWriteStartChanges(file, basefont);
  2876.                 running_font = font;
  2877.                 open_font = true;
  2878.             }
  2879.             // Do we need to turn on LaTeX mode?
  2880.             if (font.latex() != running_font.latex()) {
  2881.                 if (font.latex() == LyXFont::ON
  2882.                     && style->needprotect)
  2883.                     {
  2884.                         file += "\\protect ";
  2885.                         column += 9;
  2886.                     }
  2887.             }
  2888.             if (c == LYX_META_INSET) {
  2889.                 inset = GetInset(i);
  2890.                 if (inset) {
  2891.                     tmp = inset->Latex(file, style->isCommand());
  2892.                     if (tmp)
  2893.                         column = 0;
  2894.                     for (;tmp--;)
  2895.                         texrow.newline();
  2896.                 }
  2897.             } else {
  2898.                 // Are we in LaTeX mode?
  2899.                 if (font.latex() == LyXFont::ON) {
  2900.                     switch (c) {
  2901.                     case LYX_META_NEWLINE: 
  2902.                         if (open_font) {
  2903.                             column += running_font.latexWriteEndChanges(file, basefont);
  2904.                             open_font = false;
  2905.                         }
  2906.                         basefont = getFont(-1);
  2907.                         running_font = basefont;
  2908.                         break;  
  2909.                     case LYX_META_HFILL: 
  2910.                         file += "\\hfill{}";
  2911.                         column+=7;
  2912.                         break;
  2913.                     case LYX_META_PROTECTED_SEPARATOR: 
  2914.                         file += '~';
  2915.                         break;
  2916.                     default:
  2917.                         // make sure that we will not print
  2918.                         // error generating chars to the tex
  2919.                         // file. This test would not be needed
  2920.                         // if it were done in the buffer
  2921.                         // itself.
  2922.                         if (c != '\0')
  2923.                             file += (char)c;
  2924.                         break;
  2925.                     }
  2926.                 } else {
  2927.                     // Plain mode (i.e. not LaTeX)
  2928.                     switch (c) {
  2929.                     case LYX_META_NEWLINE: 
  2930.                         if (open_font) {
  2931.                             column += running_font.latexWriteEndChanges(file, basefont);
  2932.                             open_font = false;
  2933.                         }
  2934.                         basefont = getFont(-1);
  2935.                         running_font = basefont;
  2936.                         break;
  2937.                     case LYX_META_HFILL: 
  2938.                         file += "\\hfill{}";
  2939.                         column+=7;
  2940.                         break;
  2941.                     case LYX_META_PROTECTED_SEPARATOR: 
  2942.                         file += '~';
  2943.                         break;
  2944.                     case '\\': 
  2945.                         if (lyxrc->fontenc=="T1" 
  2946.                             || font.family() == LyXFont::TYPEWRITER_FAMILY){ 
  2947.                             file += "\\char`\\\\{}";
  2948.                             column+=9;
  2949.                         } else {
  2950.                             file += "\\ensuremath{\\backslash}";
  2951.                             column+=22;
  2952.                         }
  2953.                         break;
  2954.                     case '░': case '▒': case '▓': case '│':  
  2955.                     case '╫': case '≈': case '╣': case '¬':
  2956.                     case '║': case '¼': case '╡':
  2957.                         if (current_view->currentBuffer()->params.inputenc == "latin1") {
  2958.                             file += "\\ensuremath{";
  2959.                             file += c;
  2960.                             file += '}';
  2961.                             column+=13;
  2962.                         } else
  2963.                             file += c;
  2964.                         break;
  2965.                     case '|': case '<': case '>':
  2966.                         if (lyxrc->fontenc=="T1") {
  2967.                             if ((c=='>' ||c=='<')
  2968.                                 && i <= last-2 
  2969.                                 && GetChar(i+1)==c){
  2970.                                 file += c;
  2971.                                 file += "\\textcompwordmark{}";
  2972.                                 column+=19;
  2973.                             } else 
  2974.                                 file += c;
  2975.                         } else if(font.family() == LyXFont::TYPEWRITER_FAMILY)
  2976.                             file += c;
  2977.                         else {
  2978.                             file += "\\ensuremath{";
  2979.                             file += c;
  2980.                             file += '}';
  2981.                             column+=13;
  2982.                         }
  2983.                         break;
  2984.                     case '-': // "--" in Typewriter mode -> "-{}-"
  2985.                         if (i <= last-2 
  2986.                             && GetChar(i+1) == '-'
  2987.                             && font.family() == LyXFont::TYPEWRITER_FAMILY) {
  2988.                             file += "-{}";
  2989.                             column += 2;
  2990.                         } else
  2991.                             file += '-';
  2992.                         break;
  2993.                     case '\"': 
  2994.                         file += "\\char`\\\"{}";
  2995.                         column+=9;
  2996.                         break;
  2997.                     case 'ú':
  2998.                     if (current_view->currentBuffer()->params.inputenc == "default") {
  2999.                         file += "\\pounds{}";
  3000.                         column+=8;
  3001.                     } else
  3002.                         file += c;
  3003.                         break;
  3004.                     case '$': case '&': 
  3005.                     case '%': case '#': case '{':   
  3006.                     case '}': case '_': 
  3007.                         file += '\\';
  3008.                         file += c;
  3009.                         column +=1;
  3010.                         break;
  3011.                     case '^': case '~':
  3012.                         file += '\\';
  3013.                         file += c;
  3014.                         file += "{}";
  3015.                         column +=3;
  3016.                         break;
  3017.                     case '*': case '[': case ']':
  3018.                         // avoid being mistaken for optional arguments
  3019.                         file += '{';
  3020.                         file += c;
  3021.                         file += '}';
  3022.                         column +=2;
  3023.                         break;
  3024.                     case ' ':
  3025.                         /* blanks are printed before font switching */
  3026.                         // Sure? I am not! (try nice-latex)
  3027.                         // I am sure it's correct. LyX might be smarter
  3028.                         // in the future, but for now, nothing wrong is
  3029.                         // written. (Asger)
  3030.                         break;
  3031.                     default:
  3032.                         /* idea for labels --- begin*/ 
  3033.  
  3034.                         /* check for LyX */ 
  3035.                         if (c ==  'L' && i <= last-3
  3036.                                    && font.family() 
  3037.                              != LyXFont::TYPEWRITER_FAMILY
  3038.                             && GetChar(i+1) == 'y'
  3039.                             && GetChar(i+2) == 'X'){
  3040.                             file += "\\LyX{}";
  3041.                             i+=2;
  3042.                             column += 5;
  3043.                         }
  3044.                         /* check for TeX */ 
  3045.                         else if (c ==  'T' && i <= last-3 
  3046.                              && font.family() 
  3047.                               != LyXFont::TYPEWRITER_FAMILY
  3048.                              && GetChar(i+1) == 'e'
  3049.                              && GetChar(i+2) == 'X'){
  3050.                             file += "\\TeX{}";
  3051.                             i+=2;
  3052.                             column += 5;
  3053.                         }
  3054.                         /* check for LaTeX2e */ 
  3055.                         else if (c ==  'L' && i <= last-7 
  3056.                              && font.family() 
  3057.                               != LyXFont::TYPEWRITER_FAMILY
  3058.                              && GetChar(i+1) == 'a'
  3059.                              && GetChar(i+2) == 'T'
  3060.                              && GetChar(i+3) == 'e'
  3061.                              && GetChar(i+4) == 'X'
  3062.                              && GetChar(i+5) == '2'
  3063.                              && GetChar(i+6) == 'e'){
  3064.                             file += "\\LaTeXe{}";
  3065.                             i+=6;
  3066.                             column += 8;
  3067.                         }
  3068.                         /* check for LaTeX */ 
  3069.                         else if (c ==  'L' && i <= last-5 
  3070.                              && font.family() 
  3071.                                   != LyXFont::TYPEWRITER_FAMILY
  3072.                              && GetChar(i+1) == 'a'
  3073.                              && GetChar(i+2) == 'T'
  3074.                              && GetChar(i+3) == 'e'
  3075.                              && GetChar(i+4) == 'X'){
  3076.                             file += "\\LaTeX{}";
  3077.                             i+=4;
  3078.                             column += 7;
  3079.                         } else
  3080.                             /* idea for labels --- end*/ 
  3081.                             // same test as above
  3082.                             if (c != '\0')
  3083.                                 file += c;
  3084.                         break;
  3085.                     }
  3086.                 }
  3087.             }
  3088.         }
  3089.         // If we have an open font definition, we have to close it
  3090.         if (open_font) {
  3091.             running_font.latexWriteEndChanges(file, basefont);
  3092.             open_font=false;
  3093.         }
  3094.         basefont = getFont(-1);
  3095.         running_font = basefont;
  3096.         cell = table->CellHasContRow(current_cell_number);
  3097.     }
  3098.     lyxerr.debug(LString("TeXContTableRows...done ")+(long)this, Error::LATEX);
  3099.     return return_value;
  3100. }
  3101.  
  3102. bool LyXParagraph::RoffContTableRows(FILE *fp, int i, int actcell)
  3103. {
  3104.     if (!table)
  3105.         return false;
  3106.  
  3107.     LyXFont
  3108.         font1 = LyXFont(LyXFont::ALL_INHERIT),
  3109.         font2;
  3110.     Inset
  3111.         *inset;
  3112.     int
  3113.         lastpos, cell;
  3114.     char
  3115.         c;
  3116.     LString
  3117.         fname2;
  3118.     FILE
  3119.         *fp2;
  3120.  
  3121.     fname2 = TmpFileName(LString(),"RAT2");
  3122.     lastpos = i;
  3123.     cell = table->CellHasContRow(actcell);
  3124.     actcell++;
  3125.     while(cell >= 0) {
  3126.         // first find the right position
  3127.         i = lastpos;
  3128.         for (; (i<last) && (actcell<cell); i++) {
  3129.             c = GetChar(i);
  3130.             if (c == LYX_META_NEWLINE)
  3131.                 actcell++;
  3132.         }
  3133.         lastpos = i;
  3134.         c=GetChar(i);
  3135.         if ((c != ' ') && (c != LYX_META_NEWLINE))
  3136.             fprintf(fp," ");
  3137.         for (; (i < last) && ((c=GetChar(i)) != LYX_META_NEWLINE); i++) {
  3138.             font2 = GetFontSettings(i);
  3139.             if (font1.latex() != font2.latex()) {
  3140.                 if (font2.latex() != LyXFont::OFF)
  3141.                     continue;
  3142.             }
  3143.             c = GetChar(i);
  3144.             switch (c) {
  3145.             case LYX_META_INSET:
  3146.                 if ((inset = GetInset(i))) {
  3147.                     if (!(fp2=fopen(fname2.c_str(),"w+"))) {
  3148.                         WriteAlert(_("LYX_ERROR:"), _("Cannot open temporary file:"), fname2);
  3149.                         return false;
  3150.                     }
  3151.                     inset->Latex(fp2,-1);
  3152.                     rewind(fp2);
  3153.                     c = fgetc(fp2);
  3154.                     while(!feof(fp2)) {
  3155.                         if (c == '\\')
  3156.                             fprintf(fp,"\\\\");
  3157.                         else
  3158.                             fputc(c,fp);
  3159.                         c = fgetc(fp2);
  3160.                     }
  3161.                     fclose(fp2);
  3162.                 }
  3163.                 break;
  3164.             case LYX_META_NEWLINE:
  3165.                 break;
  3166.             case LYX_META_HFILL: 
  3167.                 break;
  3168.             case LYX_META_PROTECTED_SEPARATOR:
  3169.                 break;
  3170.             case '\\': 
  3171.                 fprintf(fp, "\\\\");
  3172.                 break;
  3173.             default:
  3174.                 if (c != '\0')
  3175.                     fprintf(fp, "%c", c);
  3176.                 else
  3177.                     lyxerr.debug("RoffAsciiTable: NULL char in structure.");
  3178.                 break;
  3179.             }
  3180.         }
  3181.         cell = table->CellHasContRow(actcell);
  3182.     }
  3183.     return true;
  3184. }
  3185.  
  3186. LyXParagraph * LyXParagraph::TeXDeeper(LString &file, TexRow &texrow,
  3187.                        LString &foot, TexRow &foot_texrow,
  3188.                        int &foot_count)
  3189. {
  3190.     lyxerr.debug(LString("TeXDeeper...     ") + (long)this, Error::LATEX);
  3191.     LyXParagraph *par = this;
  3192.  
  3193.     while (par && par->depth == depth) {
  3194.         if (par->IsDummy())
  3195.             lyxerr.print("ERROR (LyXParagraph::TeXDeeper)");
  3196.         if (lyxstyle.Style(GetCurrentTextClass(), 
  3197.                    par->layout)->isEnvironment()
  3198.             || par->pextra_type != PEXTRA_NONE) 
  3199.             {
  3200.                 par = par->TeXEnvironment(file, texrow,
  3201.                               foot, foot_texrow,
  3202.                               foot_count);
  3203.             } else {
  3204.                 par = par->TeXOnePar(file, texrow,
  3205.                              foot, foot_texrow,
  3206.                              foot_count);
  3207.             }
  3208.     }
  3209.     lyxerr.debug(LString("TeXDeeper...done ") + (long)par, Error::LATEX);
  3210.  
  3211.     return par;
  3212. }
  3213.  
  3214.  
  3215. LyXParagraph* LyXParagraph::TeXEnvironment(LString &file, TexRow &texrow,
  3216.                        LString &foot, TexRow &foot_texrow,
  3217.                        int &foot_count)
  3218. {
  3219.     bool
  3220.         eindent_open = false;
  3221.         static bool
  3222.         minipage_open = false;
  3223.         static int
  3224.                 minipage_open_depth = 0;
  3225.     char
  3226.         par_sep = current_view->currentBuffer()->params.paragraph_separation;
  3227.     
  3228.     lyxerr.debug(LString("TeXEnvironment...     ") + long(this), Error::LATEX);
  3229.     if (IsDummy())
  3230.         lyxerr.print("ERROR (LyXParagraph::TeXEnvironment)");
  3231.  
  3232.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), layout);
  3233.        
  3234.     if (pextra_type == PEXTRA_INDENT) {
  3235.         if (!pextra_width.empty()) {
  3236.             file += "\\begin{LyXParagraphIndent}{"
  3237.                 + pextra_width + "}\n";
  3238.         } else {
  3239.             //float ib = atof(pextra_widthp.c_str())/100;
  3240.             // LString can't handle floats at present (971109)
  3241.             // so I'll do a conversion by hand knowing that
  3242.             // the limits are 0.0 to 1.0. ARRae.
  3243.             file += "\\begin{LyXParagraphIndent}{";
  3244.             switch (pextra_widthp.length()) {
  3245.             case 3:
  3246.                 file += "1.00";
  3247.                 break;
  3248.             case 2:
  3249.                 file += "0.";
  3250.                 file += pextra_widthp;
  3251.                 break;
  3252.             case 1:
  3253.                 file += "0.0";
  3254.                 file += pextra_widthp;
  3255.             }
  3256.             file += "\\columnwidth}\n";
  3257.         }
  3258.         texrow.newline();
  3259.         eindent_open = true;
  3260.     }
  3261.     if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
  3262.         if (pextra_hfill && Previous() &&
  3263.             (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
  3264.             file += "\\hfill{}\n";
  3265.             texrow.newline();
  3266.         }
  3267.         if (par_sep == LYX_PARSEP_INDENT) {
  3268.             file += "{\\setlength\\parindent{0pt}\n";
  3269.             texrow.newline();
  3270.         }
  3271.         file += "\\begin{minipage}";
  3272.         switch(pextra_alignment) {
  3273.         case MINIPAGE_ALIGN_TOP:
  3274.             file += "[t]";
  3275.             break;
  3276.         case MINIPAGE_ALIGN_MIDDLE:
  3277.             file += "[m]";
  3278.             break;
  3279.         case MINIPAGE_ALIGN_BOTTOM:
  3280.             file += "[b]";
  3281.             break;
  3282.         }
  3283.         if (!pextra_width.empty()) {
  3284.             file += '{';
  3285.             file += pextra_width + "}\n";
  3286.         } else {
  3287.             //float ib = atof(par->pextra_width.c_str())/100;
  3288.             // LString can't handle floats at present
  3289.             // so I'll do a conversion by hand knowing that
  3290.             // the limits are 0.0 to 1.0. ARRae.
  3291.             file += '{';
  3292.             switch (pextra_widthp.length()) {
  3293.             case 3:
  3294.                 file += "1.00";
  3295.                 break;
  3296.             case 2:
  3297.                 file += "0.";
  3298.                 file += pextra_widthp;
  3299.                 break;
  3300.             case 1:
  3301.                 file += "0.0";
  3302.                 file += pextra_widthp;
  3303.             }
  3304.             file += "\\columnwidth}\n";
  3305.         }
  3306.         texrow.newline();
  3307.         if (par_sep == LYX_PARSEP_INDENT) {
  3308.             file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
  3309.             texrow.newline();
  3310.         }
  3311.         minipage_open = true;
  3312.                 minipage_open_depth = depth;
  3313.     }
  3314.     if (style->isEnvironment()){
  3315.         if (style->latextype == LATEX_LIST_ENVIRONMENT)
  3316.             file += "\\begin{" + style->latexname + "}{"
  3317.                 + labelwidthstring + "}\n";
  3318.         else if (style->labeltype == LABEL_BIBLIO) {
  3319.             // ale970405
  3320.             file += "\\begin{" + style->latexname + "}{"
  3321.                 + bibitemWidthest() + "}\n";
  3322.         }
  3323.         //arrae970411
  3324.         else if (style->latexparam.empty())
  3325.             file += "\\begin{" + style->latexname + "}\n";
  3326.         else
  3327.             file += "\\begin{" + style->latexname + "}{"
  3328.                 + style->latexparam + "}\n";
  3329.         texrow.newline();
  3330.     }
  3331.     LyXParagraph *par = this;
  3332.     do {
  3333.         par = par->TeXOnePar(file, texrow,
  3334.                      foot, foot_texrow, foot_count);
  3335. #if 0
  3336.         if (eindent_open && par && par->pextra_type != PEXTRA_INDENT) {
  3337.             file += "\\end{LyXParagraphIndent}\n";
  3338.             texrow.newline();
  3339.             eindent_open = false;
  3340.             if (!style->isEnvironment())
  3341.                 break;
  3342.         }
  3343. #endif
  3344.                 if (minipage_open && par && !style->isEnvironment() &&
  3345.                     (par->pextra_type == PEXTRA_MINIPAGE) &&
  3346.                     par->pextra_start_minipage) {
  3347.                     file += "\\end{minipage}\n";
  3348.                     texrow.newline();
  3349.                     if (par_sep == LYX_PARSEP_INDENT) {
  3350.                         file += "}\n";
  3351.             texrow.newline();
  3352.                     }
  3353.                     minipage_open = false;
  3354.                 }
  3355.         if (par && par->depth > depth) {
  3356.             if (lyxstyle.Style(GetCurrentTextClass(),
  3357.                        par->layout)->isParagraph()
  3358.                 && !par->table
  3359.                 && !file.suffixIs("\n\n")) {
  3360.                 // There should be at least one '\n' already
  3361.                 // but we need there to be two for Standard 
  3362.                 // paragraphs that are depth-increment'ed to be
  3363.                 // output correctly.  However, tables can also be
  3364.                 // paragraphs so don't adjust them.  ARRae
  3365.                 file += '\n';
  3366.                 texrow.newline();
  3367.             }
  3368.             par = par->TeXDeeper(file, texrow,
  3369.                          foot, foot_texrow, foot_count);
  3370.         }
  3371.         if (par && par->layout == layout && par->depth == depth &&
  3372.             (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
  3373.             if (par->pextra_hfill && par->Previous() &&
  3374.                 (par->Previous()->pextra_type == PEXTRA_MINIPAGE))
  3375.                 file += "\\hfill{}\n";
  3376.             else
  3377.                 file += '\n';
  3378.             texrow.newline();
  3379.             if (par_sep == LYX_PARSEP_INDENT) {
  3380.                 file += "{\\setlength\\parindent{0pt}\n";
  3381.                 texrow.newline();
  3382.             }
  3383.             file += "\\begin{minipage}";
  3384.             switch(par->pextra_alignment) {
  3385.             case MINIPAGE_ALIGN_TOP:
  3386.                 file += "[t]";
  3387.                 break;
  3388.             case MINIPAGE_ALIGN_MIDDLE:
  3389.                 file += "[m]";
  3390.                 break;
  3391.             case MINIPAGE_ALIGN_BOTTOM:
  3392.                 file += "[b]";
  3393.                 break;
  3394.             }
  3395.             if (!par->pextra_width.empty()) {
  3396.                 file += '{';
  3397.                 file += par->pextra_width;
  3398.                 file += "}\n";
  3399.             } else {
  3400.                 //float ib = atof(par->pextra_widthp.c_str())/100;
  3401.                 // LString can't handle floats at present
  3402.                 // so I'll do a conversion by hand knowing that
  3403.                 // the limits are 0.0 to 1.0. ARRae.
  3404.                 file += '{';
  3405.                 switch (par->pextra_widthp.length()) {
  3406.                 case 3:
  3407.                     file += "1.00";
  3408.                     break;
  3409.                 case 2:
  3410.                     file += "0.";
  3411.                     file += par->pextra_widthp;
  3412.                     break;
  3413.                 case 1:
  3414.                     file += "0.0";
  3415.                     file += par->pextra_widthp;
  3416.                 }
  3417.                 file += "\\columnwidth}\n";
  3418.             }
  3419.             texrow.newline();
  3420.             if (par_sep == LYX_PARSEP_INDENT) {
  3421.                 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
  3422.                 texrow.newline();
  3423.             }
  3424.             minipage_open = true;
  3425.                         minipage_open_depth = par->depth;
  3426.         }
  3427.     } while (par
  3428.          && par->layout == layout
  3429.          && par->depth == depth
  3430.          && par->pextra_type == pextra_type);
  3431.  
  3432.     if (style->isEnvironment()) {
  3433.         file += "\\end{" + style->latexname + '}';
  3434.         //texrow.newline();
  3435.     }
  3436.         if (minipage_open && (minipage_open_depth == depth) &&
  3437.             (!par || par->pextra_start_minipage ||
  3438.              par->pextra_type != PEXTRA_MINIPAGE)) {
  3439.                 file += "\\end{minipage}\n";
  3440.         texrow.newline();
  3441.                 if (par_sep == LYX_PARSEP_INDENT) {
  3442.                         file += "}\n";
  3443.             texrow.newline();
  3444.                 }
  3445.                 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
  3446.                         file += "\\medskip\n\n";
  3447.             texrow.newline();
  3448.             texrow.newline();
  3449.                 }
  3450.                 minipage_open = false;
  3451.         }
  3452.     if (eindent_open) {
  3453.         file += "\\end{LyXParagraphIndent}\n";
  3454.         texrow.newline();
  3455.     }
  3456. //    if (tex_code_break_column){
  3457.         if (!(par && (par->pextra_type==PEXTRA_MINIPAGE) 
  3458.           && par->pextra_hfill)) {
  3459.                 file += '\n';
  3460.         texrow.newline();
  3461.     }
  3462.     lyxerr.debug(LString("TeXEnvironment...done ") 
  3463.              + (long)par, Error::LATEX);
  3464.     return par;  // ale970302
  3465. }
  3466.  
  3467.  
  3468. LyXParagraph * LyXParagraph::TeXFootnote(LString &file, TexRow &texrow,
  3469.                      LString &foot, TexRow &foot_texrow,
  3470.                      int &foot_count)
  3471. {
  3472.     lyxerr.debug(LString("TeXFootnote...     ") 
  3473.              + (long)this, Error::LATEX);
  3474.     if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
  3475.         lyxerr.print("ERROR (LyXParagraph::TeXFootnote): "
  3476.                  "No footnote!");
  3477.  
  3478.     LyXParagraph *par = this;
  3479.     LyXLayout * style = lyxstyle.Style(GetCurrentTextClass(), 
  3480.                        previous->GetLayout());
  3481.     
  3482.     if (style->needprotect && footnotekind != LyXParagraph::FOOTNOTE){
  3483.         lyxerr.print("ERROR (LyXParagraph::TeXFootnote): "
  3484.                  "Float other than footnote in command"
  3485.                  " with moving argument is illegal");
  3486.     }
  3487.  
  3488.     BufferParams *params = ¤t_view->currentBuffer()->params;
  3489.     bool footer_in_body = true;
  3490.     switch (footnotekind) {
  3491.     case LyXParagraph::FOOTNOTE:
  3492.         if (style->intitle) {
  3493.             file += "\\thanks{\n";
  3494.             footer_in_body = false;
  3495.         } else {
  3496.             if (foot_count == -1) {
  3497.                 // we're at depth 0 so we can use:
  3498.                 file += "\\footnote{\n";
  3499.                 footer_in_body = false;
  3500.             } else {
  3501.                 file += "\\footnotemark{}\n";
  3502.                 if (foot_count) {
  3503.                     // we only need this when there are
  3504.                     // multiple footnotes
  3505.                     foot += "\\stepcounter{footnote}";
  3506.                 }
  3507.                 foot += "\\footnotetext{\n";
  3508.                 foot_texrow.start(this,0);
  3509.                 foot_texrow.newline();
  3510.                 ++foot_count;
  3511.             }
  3512.         }
  3513.         break;
  3514.     case LyXParagraph::MARGIN:
  3515.         file += "\\marginpar{\n";
  3516.         break;
  3517.     case LyXParagraph::FIG:
  3518.         if (pextra_type == PEXTRA_FLOATFLT
  3519.             && (!pextra_width.empty()
  3520.             || !pextra_widthp.empty())) {
  3521.             char bufr[80];
  3522.             if (!pextra_width.empty())
  3523.                 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
  3524.                     pextra_width.c_str());
  3525.             else
  3526.                 sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
  3527.                     atoi(pextra_widthp.c_str())/100.0);
  3528.             file += bufr;
  3529.         } else {
  3530.             file += "\\begin{figure}";
  3531.             if (!params->float_placement.empty()) { 
  3532.                 file += '[';
  3533.                 file += params->float_placement;
  3534.                 file += "]\n";
  3535.             } else {
  3536.                 file += '\n';
  3537.             }
  3538.         }
  3539.         break;
  3540.     case LyXParagraph::TAB:
  3541.         file += "\\begin{table}";
  3542.         if (!params->float_placement.empty()) { 
  3543.             file += '[';
  3544.             file += params->float_placement;
  3545.             file += "]\n";
  3546.         } else {
  3547.             file += '\n';
  3548.         }
  3549.         break;
  3550.     case LyXParagraph::WIDE_FIG:
  3551.         file += "\\begin{figure*}";
  3552.         if (!params->float_placement.empty()) { 
  3553.             file += '[';
  3554.             file += params->float_placement;
  3555.             file += "]\n";
  3556.         } else {
  3557.             file += '\n';
  3558.         }
  3559.         break;
  3560.     case LyXParagraph::WIDE_TAB:
  3561.         file += "\\begin{table*}";
  3562.         if (!params->float_placement.empty()) { 
  3563.             file += '[';
  3564.             file += params->float_placement;
  3565.             file += "]\n";
  3566.         } else {
  3567.             file += '\n';
  3568.         }
  3569.         break;
  3570.     case LyXParagraph::ALGORITHM:
  3571.         file += "\\begin{algorithm}\n";
  3572.         break;
  3573.     }
  3574.     texrow.newline();
  3575.    
  3576.     if (footnotekind != LyXParagraph::FOOTNOTE
  3577.         || !footer_in_body) {
  3578.         // Process text for all floats except footnotes in body
  3579.         do {
  3580.             LyXLayout *style = lyxstyle.Style(GetCurrentTextClass(),
  3581.                               par->layout);
  3582.             if (par->IsDummy())
  3583.                 lyxerr.print("ERROR (LyXParagraph::TeXFootnote)");
  3584.             if (style->isEnvironment()) {
  3585.                 par = par->TeXEnvironment(file, texrow,
  3586.                               foot, foot_texrow,
  3587.                               foot_count);
  3588.             } else {
  3589.                 par = par->TeXOnePar(file, texrow,
  3590.                              foot, foot_texrow,
  3591.                              foot_count);
  3592.             }
  3593.             
  3594.             if (par && !par->IsDummy() && par->depth > depth) {
  3595.                 par = par->TeXDeeper(file, texrow,
  3596.                              foot, foot_texrow,
  3597.                              foot_count);
  3598.             }
  3599.         } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
  3600.     } else {
  3601.         // process footnotes > depth 0 or in environments separately
  3602.         // NOTE: Currently don't support footnotes within footnotes
  3603.         //       even though that is possible using the \footnotemark
  3604.         LString dummy;
  3605.         TexRow dummy_texrow;
  3606.         int dummy_count = 0;
  3607.         do {
  3608.             LyXLayout *style = lyxstyle.Style(GetCurrentTextClass(),
  3609.                               par->layout);
  3610.             if (par->IsDummy())
  3611.                 lyxerr.print("ERROR (LyXParagraph::TeXFootnote)");
  3612.             if (style->isEnvironment()) {
  3613.                 par = par->TeXEnvironment(foot, foot_texrow,
  3614.                               dummy, dummy_texrow,
  3615.                               dummy_count);
  3616.             } else {
  3617.                 par = par->TeXOnePar(foot, foot_texrow,
  3618.                              dummy, dummy_texrow,
  3619.                              dummy_count);
  3620.             }
  3621.  
  3622.             if (par && !par->IsDummy() && par->depth > depth) {
  3623.                 par = par->TeXDeeper(foot, foot_texrow,
  3624.                              dummy, dummy_texrow,
  3625.                              dummy_count);
  3626.             }
  3627.         } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
  3628.         if (dummy_count) {
  3629.             lyxerr.print("ERROR (LyXParagraph::TeXFootnote): "
  3630.                      "Footnote in a Footnote -- not supported");
  3631.         }
  3632.     }
  3633.  
  3634.     switch (footnotekind) {
  3635.     case LyXParagraph::FOOTNOTE:
  3636.         if (footer_in_body) {
  3637.             // This helps tell which of the multiple
  3638.             // footnotetexts an error was in.
  3639.             foot += "}%\n";
  3640.             foot_texrow.newline();
  3641.         } else {
  3642.             file += '}';
  3643.         }
  3644.         break;
  3645.     case LyXParagraph::MARGIN:
  3646.         file += '}';
  3647.         break;
  3648.     case LyXParagraph::FIG:
  3649.         if (pextra_type == PEXTRA_FLOATFLT
  3650.             && (!pextra_width.empty()
  3651.             || !pextra_widthp.empty()))
  3652.             file += "\\end{floatingfigure}";
  3653.         else
  3654.             file += "\\end{figure}";
  3655.         break;
  3656.     case LyXParagraph::TAB:
  3657.         file += "\\end{table} ";
  3658.         break;
  3659.     case LyXParagraph::WIDE_FIG:
  3660.         file += "\\end{figure*} ";
  3661.         break;
  3662.     case LyXParagraph::WIDE_TAB:
  3663.         file += "\\end{table*} ";
  3664.         break;
  3665.     case LyXParagraph::ALGORITHM:
  3666.         file += "\\end{algorithm} ";
  3667.         break;
  3668.     }
  3669.     lyxerr.debug(LString("TeXFootnote...done ") +
  3670.              long(par->next), Error::LATEX);
  3671.     return par;
  3672. }
  3673.  
  3674.  
  3675. void LyXParagraph::SetPExtraType(int type, const char *width,const char *widthp)
  3676. {
  3677.     pextra_type = type;
  3678.     pextra_width = width;
  3679.     pextra_widthp = widthp;
  3680.  
  3681.     if (lyxstyle.Style(GetCurrentTextClass(), 
  3682.                        layout)->isEnvironment()) {
  3683.         LyXParagraph
  3684.             *par = this,
  3685.             *ppar = par;
  3686.  
  3687.         while (par && (par->layout == layout) && (par->depth == depth)) {
  3688.             ppar = par;
  3689.             par = par->Previous();
  3690.             if (par)
  3691.                 par = par->FirstPhysicalPar();
  3692.             while (par && par->depth > depth) {
  3693.                 par = par->Previous();
  3694.                 if (par)
  3695.                     par = par->FirstPhysicalPar();
  3696.             }
  3697.         }
  3698.         par = ppar;
  3699.         while (par && (par->layout == layout) && (par->depth == depth)) {
  3700.             par->pextra_type = type;
  3701.             par->pextra_width = width;
  3702.             par->pextra_widthp = widthp;
  3703.             par = par->NextAfterFootnote();
  3704.             if (par && (par->depth > depth))
  3705.                 par->SetPExtraType(type,width,widthp);
  3706.             while (par && ((par->depth > depth) || par->IsDummy()))
  3707.                 par = par->NextAfterFootnote();
  3708.         }
  3709.     }
  3710. }
  3711.  
  3712. void LyXParagraph::UnsetPExtraType()
  3713. {
  3714.     if (pextra_type == PEXTRA_NONE)
  3715.         return;
  3716.     
  3717.     pextra_type = PEXTRA_NONE;
  3718.     pextra_width.erase();
  3719.     pextra_widthp.erase();
  3720.  
  3721.     if (lyxstyle.Style(GetCurrentTextClass(), 
  3722.                        layout)->isEnvironment()) {
  3723.         LyXParagraph
  3724.             *par = this,
  3725.             *ppar = par;
  3726.  
  3727.         while (par && (par->layout == layout) && (par->depth == depth)) {
  3728.             ppar = par;
  3729.             par = par->Previous();
  3730.             if (par)
  3731.                 par = par->FirstPhysicalPar();
  3732.             while (par && par->depth > depth) {
  3733.                 par = par->Previous();
  3734.                 if (par)
  3735.                     par = par->FirstPhysicalPar();
  3736.             }
  3737.         }
  3738.         par = ppar;
  3739.         while (par && (par->layout == layout) && (par->depth == depth)) {
  3740.             par->pextra_type = PEXTRA_NONE;
  3741.             par->pextra_width.erase();
  3742.             par->pextra_widthp.erase();
  3743.             par = par->NextAfterFootnote();
  3744.             if (par && (par->depth > depth))
  3745.                 par->UnsetPExtraType();
  3746.             while (par && ((par->depth > depth) || par->IsDummy()))
  3747.                 par = par->NextAfterFootnote();
  3748.         }
  3749.     }
  3750. }
  3751.