products/Sources/formale Sprachen/C/Lyx/src image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: ROOT.ML   Sprache: C

Original von: Lyx©

/* This file is part of
 * ======================================================
 * 
 *           LyX, The Document Processor
 *
 *      Copyright (C) 1995 Matthias Ettrich
 *           Copyright (C) 1995-1998 The LyX Team.
 *
 *           This file is Copyright (C) 1996-1998
 *           Lars Gullik Bjønnes
 *
 *======================================================
 */

#include <config.h>

#include <stdlib.h>
#include <unistd.h>

#ifdef __GNUG__
#pragma implementation "buffer.h"
#endif

#include "definitions.h"
#include "buffer.h"
#include "bufferlist.h"
#include "lyx_main.h"
#include "lyx_gui_misc.h"
#include "lyxrc.h"
#include "lyxlex.h"
#include "tex-strings.h"
#include "layout.h"
#include "lyx_cb.h"
#include "minibuffer.h"
#include "lyxfont.h"
#include "formulamacro.h"
#include "lyxinset.h"
#include "inseterror.h"
#include "insetlabel.h"
#include "insetref.h"
#include "inseturl.h"
#include "insetinfo.h"
#include "insetquotes.h"
#include "insetlatex.h"
#include "insetlatexaccent.h"
#include "insetbib.h" 
#include "insetindex.h" 
#include "insetinclude.h"
#include "insettoc.h"
#include "insetlof.h"
#include "insetlot.h"
#include "insetloa.h"
#include "insetparent.h"
#include "insetspecialchar.h"
#include "figinset.h"
#include "filetools.h"
#include "pathstack.h"
#include "LaTeX.h"
#include "Chktex.h"
#include "LyXView.h"
#include "error.h"
#include "LaTeXFeatures.h"
#include "syscall.h"
#include "lyxlib.h"
#include "FileInfo.h"
#include "lyxtext.h"
#include "gettext.h"


//  $Id: buffer.C,v 1.12 1998/10/20 12:48:43 lasgoutt Exp $

#if !defined(lint) && !defined(WITH_WARNINGS)
static char vcid[] = "$Id: buffer.C,v 1.12 1998/10/20 12:48:43 lasgoutt Exp $";
#endif /* lint */


// Uncomment this line to enable a workaround for the weird behaviour
// of the cursor between a displayed inset and last character
// at the upper line. (Alejandro 20.9.96)
// #define BREAK_BEFORE_INSET

/* Lars, when changing this file sometime in the future to a list,
 * please check out the figinsets-sideeffects described at the
 * beginning of figinset.C    Matthias (04.07.1996)
 */



// all these externs should eventually be removed.
extern BufferList bufferlist;
extern void SmallUpdate(signed char);
extern unsigned char GetCurrentTextClass();
extern void BeforeChange();

static const float LYX_FORMAT = 2.15;

extern int tex_code_break_column;

extern void FreeUpdateTimer();


Buffer::Buffer(LString const & file, LyXRC *lyxrc, bool ronly)
{
 filename = file;
 filepath = OnlyPath(file);
 paragraph = NULL;
 text = NULL;
 the_locking_inset = NULL;
 lyx_clean = true;
 bak_clean = true;
 dvi_clean = false;
 dep_clean = NULL;
 read_only = ronly;
 inset_slept = false;
 users = 0;
 lyxvc.setBuffer(this);
 lyxerr.debug("Buffer::Buffer()");
 if (read_only || (lyxrc && lyxrc->use_tempdir)) {
  tmppath = CreateBufferTmpDir();
 } else tmppath.clean();
}


Buffer::~Buffer()
{
 lyxerr.debug("Buffer::~Buffer()");
 // here the buffer should take care that it is
 // saved properly, before it goes into the void.

 // make sure that views using this buffer
 // forgets it.
 if (users)
  users->setBuffer(0);
 
 if (!tmppath.empty()) {
  DestroyBufferTmpDir(tmppath);
 }
 
 LyXParagraph *par = paragraph;
 LyXParagraph *tmppar;
 while (par) {
  tmppar = par->next;
  delete par;
  par = tmppar;
 }
 paragraph = NULL;
 delete text;
}


bool Buffer::saveParamsAsDefaults()
{
 LString fname = AddName(AddPath(user_lyxdir, "templates/"),
    "defaults.lyx");
 Buffer defaults = Buffer(fname);
 
 // Use the current buffer's parameters as default
 defaults.params.Copy(params);
 // add an empty paragraph. Is this enough?
 defaults.paragraph = new LyXParagraph();

 return defaults.writeFile(defaults.filename,false);
}


/// Update window titles of all users
// Should work on a list
void Buffer::updateTitles()
{
 if (users) users->getOwner()->updateWindowTitle();
}


/// Reset autosave timer of all users
// Should work on a list
void Buffer::resetAutosaveTimers()
{
 if (users) users->getOwner()->resetAutosaveTimer();
}


void Buffer::setFileName(LString const & newfile)
{
 filename = MakeAbsPath(newfile);
 filepath = OnlyPath(filename);
 setReadonly(IsFileWriteable(filename) == 0);
 updateTitles();
}

void Buffer::InsetUnlock()
{
 if (the_locking_inset) {
  if (!inset_slept) the_locking_inset->InsetUnlock();
  the_locking_inset = NULL;
  text->FinishUndo();
  inset_slept = false;
 }
}


// Inserts a file into current document
bool Buffer::insertLyXFile(LString const & filen)
 //
 // (c) CHT Software Service GmbH
 // Uwe C. Schroeder
 //
 // Insert a Lyxformat - file into current buffer
 //
 // Moved from lyx_cb.C (Lgb)
{
 if (filen.empty()) return false;

 LString filename = MakeAbsPath(filen);

 // check if file exist
 FileInfo fi(filename);

 if (!fi.exist() || !fi.readable()) {
  WriteAlert(_("Error!"),
      _("Cannot open specified file:"),
      MakeDisplayPath(filename,50));
  return false;
 }
 
 BeforeChange();

 FilePtr myfile(filename, FilePtr::read);
 if (!myfile()) {
  WriteAlert(_("Error!"),
      _("Cannot open specified file:"),
      MakeDisplayPath(filename,50));
  return false;
 }
 LyXLex lex(NULL, 0);
 lex.setFile(myfile);
 int c = fgetc(myfile());
 ungetc(c, myfile);

 bool res = true;

 if (c=='#') {
  lyxerr.debug("Will insert file with header");
  res = readFile(lex, text->cursor.par);
 } else {
  lyxerr.debug("Will insert file without header");
  res = readLyXformat2(lex, text->cursor.par);
 }
 resize();
 return res;
}


//
// Uwe C. Schroeder
// changed to be public and have one parameter
// if par = NULL normal behavior
// else insert behavior
// Returns false if "\the_end" is not read for formats >= 2.13. (Asger)
bool Buffer::readLyXformat2(LyXLex &lex, LyXParagraph *par)
{
 LString tmptok;
 Inset *inset = 0;
 int pos = 0;
 int tmpret, tmpret2;
 char depth = 0; // signed or unsigned?
 LyXParagraph::footnote_flag footnoteflag = LyXParagraph::NO_FOOTNOTE;
 LyXParagraph::footnote_kind footnotekind = LyXParagraph::FOOTNOTE;
 bool the_end_read = false;

 LyXParagraph *return_par = NULL;
 LyXFont font = LyXFont(LyXFont::ALL_INHERIT);

 // If we are inserting, we cheat and get a token in advance
 bool has_token = false;
 LString pretoken;

 if(!par) {
  par = new LyXParagraph();
 } else {
  text->BreakParagraph();
  return_par = text->FirstParagraph();
  pos=0;
  markDirty();
  // We don't want to adopt the parameters from the
  // document we insert, so we skip until the text begins:
  while (lex.IsOK()) {
   lex.nextToken();
   pretoken = lex.GetString();
   if (pretoken == "\\layout") {
    has_token = true;
    break;
   }
  }
 }

 while (lex.IsOK()) {
  if (has_token) {
   has_token = false;
  } else {
   lex.nextToken();
   pretoken = lex.GetString();
  }

  // Profiling show this should give a lot: (Asger)
  LString const token = pretoken;

  if (token.empty())
   continue;
  else if (token[0] != '\\') {
   int n = token.length();
   for (int i=0; i < n; i++) {
    par->InsertChar(pos, token[i]);
    par->SetFont(pos, font);
    pos++;
   }
  } else if (token == "\\i") {
   inset = new InsetLatexAccent;
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\layout") {
   if (!return_par) 
    return_par = par;
   else 
    par = new LyXParagraph(par);
   pos = 0;
   lex.EatLine();
   par->layout =
    lyxstyle.NumberOfLayout(params.textclass,
       lex.GetString());
   if (par->layout == -1) // layout not found
    // use default layout "Standard" (0)
    par->layout = 0;
   // Test whether the layout is obsolete.
   LyXLayout* layout = lyxstyle.Style(params.textclass,
          par->layout); 
   if (!layout->obsoleted_by.empty())
    par->layout = 
     lyxstyle.NumberOfLayout(params.textclass, 
        layout->obsoleted_by);
   par->footnoteflag = footnoteflag;
   par->footnotekind = footnotekind;
   par->depth = depth;
   font = LyXFont(LyXFont::ALL_INHERIT);
  } else if (token == "\\end_float") {
   if (!return_par) 
    return_par = par;
   else 
    par = new LyXParagraph(par);
   footnotekind = LyXParagraph::FOOTNOTE;
   footnoteflag = LyXParagraph::NO_FOOTNOTE;
   pos = 0;
   lex.EatLine();
   par->layout = LYX_DUMMY_LAYOUT;
   font = LyXFont(LyXFont::ALL_INHERIT);
  } else if (token == "\\begin_float") {
   tmpret = lex.FindToken(string_footnotekinds);
   if (tmpret == -1) tmpret++;
   if (tmpret != LYX_LAYOUT_DEFAULT) 
    footnotekind = (LyXParagraph::footnote_kind)tmpret; // bad
   if (footnotekind == LyXParagraph::FOOTNOTE
       || footnotekind == LyXParagraph::MARGIN)
    footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
   else 
    footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
  } else if (token == "\\begin_deeper") {
   depth++;
  } else if (token == "\\end_deeper") {
   if (!depth) {
    lex.printError("\\end_deeper: "
            "depth is already null");
   }
   else
    depth--;
  } else if (token == "\\begin_preamble") {
   params.readPreamble(lex);
  } else if (token == "\\textclass") {
   lex.EatLine();
   params.textclass = lyxstyle.NumberOfClass(lex.GetString());
   if (params.textclass == -1) {
    lex.printError("Unknown textclass `$$Token'");
    params.textclass = 0;
   }
   if (!lyxstyle.Load(params.textclass)) {
    // if the textclass wasn't loaded properly
    // we need to either substitute another
    // or stop loading the file.
    // I can substitute but I don't see how I can
    // stop loading... ideas??  ARRae980418
    WriteAlert(_("Textclass Loading Error!"),
               LString(_("Can't load textclass ")) +
        lyxstyle.NameOfClass(params.textclass),
        _("-- substituting default"));
    params.textclass = 0;
   }
  } else if (token == "\\options") {
   lex.EatLine();
   params.options = lex.GetString();
  } else if (token == "\\language") {
   params.readLanguage(lex);     
  } else if (token == "\\fontencoding") {
   lex.EatLine();
  } else if (token == "\\inputencoding") {
   lex.EatLine();
   params.inputenc = lex.GetString();
  } else if (token == "\\graphics") {
   params.readGraphicsDriver(lex);
  } else if (token == "\\fontscheme") {
   lex.EatLine();
   params.fonts = lex.GetString();
  } else if (token == "\\noindent") {
   par->noindent = true;
  } else if (token == "\\fill_top") {
   par->added_space_top = VSpace::VFILL;
  } else if (token == "\\fill_bottom") {
   par->added_space_bottom = VSpace::VFILL;
  } else if (token == "\\line_top") {
   par->line_top = true;
  } else if (token == "\\line_bottom") {
   par->line_bottom = true;
  } else if (token == "\\pagebreak_top") {
   par->pagebreak_top = true;
  } else if (token == "\\pagebreak_bottom") {
   par->pagebreak_bottom = true;
  } else if (token == "\\start_of_appendix") {
   par->start_of_appendix = true;
  } else if (token == "\\paragraph_separation") {
   tmpret = lex.FindToken(string_paragraph_separation);
   if (tmpret == -1) tmpret++;
   if (tmpret != LYX_LAYOUT_DEFAULT) 
    params.paragraph_separation = tmpret;
  } else if (token == "\\defskip") {
   lex.nextToken();
   params.defskip = VSpace(lex.GetString());
  } else if (token == "\\no_isolatin1") {
   lex.nextToken();
  } else if (token == "\\no_babel") {
   lex.nextToken();
  } else if (token == "\\no_epsfig") {
   lex.nextToken();
  } else if (token == "\\epsfig") { // obsolete
   // Indeed it is obsolete, but we HAVE to be backwards
   // compatible until 0.14, because otherwise all figures
   // in existing documents are irretrivably lost. (Asger)
   params.readGraphicsDriver(lex);
  } else if (token == "\\quotes_language") {
   tmpret = lex.FindToken(string_quotes_language);
   if (tmpret == -1) tmpret++;
   if (tmpret != LYX_LAYOUT_DEFAULT) {
    InsetQuotes::quote_language tmpl =
     InsetQuotes::EnglishQ;
    switch(tmpret) {
    case 0:
     tmpl = InsetQuotes::EnglishQ;
     break;
    case 1:
     tmpl = InsetQuotes::SwedishQ;
     break;
    case 2:
     tmpl = InsetQuotes::GermanQ;
     break;
    case 3:
     tmpl = InsetQuotes::PolishQ;
     break;
    case 4:
     tmpl = InsetQuotes::FrenchQ;
     break;
    case 5:
     tmpl = InsetQuotes::DanishQ;
     break
    }
    params.quotes_language = tmpl;
   }
  } else if (token == "\\quotes_times") {
   lex.nextToken();
   switch(lex.GetInteger()) {
   case 1: 
    params.quotes_times = InsetQuotes::SingleQ; 
    break;
   case 2: 
    params.quotes_times = InsetQuotes::DoubleQ; 
    break;
   }
                } else if (token == "\\papersize") {
                        if (format > 2.13)
                                tmpret = lex.FindToken(string_papersize);
                        else
                                tmpret = lex.FindToken(string_oldpapersize);
   if (tmpret == -1)
                                tmpret++;
                        else
                                params.papersize2 = tmpret;
                } else if (token == "\\paperpackage") {
   tmpret = lex.FindToken(string_paperpackages);
   if (tmpret == -1) {
                                tmpret++;
                                params.paperpackage = PACKAGE_NONE;
                        } else
                                params.paperpackage = tmpret;
  } else if (token == "\\use_geometry") {
   lex.nextToken();
   params.use_geometry = lex.GetInteger();
  } else if (token == "\\use_amsmath") {
   lex.nextToken();
   params.use_amsmath = lex.GetInteger();
  } else if (token == "\\paperorientation") {
   tmpret = lex.FindToken(string_orientation);
   if (tmpret == -1) tmpret++;
   if (tmpret != LYX_LAYOUT_DEFAULT) 
    params.orientation = tmpret;
  } else if (token == "\\paperwidth") {
   lex.next();
   params.paperwidth = lex.GetString();
  } else if (token == "\\paperheight") {
   lex.next();
   params.paperheight = lex.GetString();
  } else if (token == "\\leftmargin") {
   lex.next();
   params.leftmargin = lex.GetString();
  } else if (token == "\\topmargin") {
   lex.next();
   params.topmargin = lex.GetString();
  } else if (token == "\\rightmargin") {
   lex.next();
   params.rightmargin = lex.GetString();
  } else if (token == "\\bottommargin") {
   lex.next();
   params.bottommargin = lex.GetString();
  } else if (token == "\\headheight") {
   lex.next();
   params.headheight = lex.GetString();
  } else if (token == "\\headsep") {
   lex.next();
   params.headsep = lex.GetString();
  } else if (token == "\\footskip") {
   lex.next();
   params.footskip = lex.GetString();
  } else if (token == "\\paperfontsize") {
   lex.nextToken();
   params.fontsize = lex.GetString();
   params.fontsize.strip();
  } else if (token == "\\papercolumns") {
   lex.nextToken();
   params.columns = lex.GetInteger();
  } else if (token == "\\papersides") {
   lex.nextToken();
   params.sides = lex.GetInteger();
  } else if (token == "\\paperpagestyle") {
          lex.nextToken();
   params.pagestyle = lex.GetString();
   params.pagestyle.strip();
  } else if (token == "\\bullet") {
   lex.nextToken();
   int index = lex.GetInteger();
   lex.nextToken();
   int temp_int = lex.GetInteger();
   params.user_defined_bullets[index].setFont(temp_int);
   params.temp_bullets[index].setFont(temp_int);
   lex.nextToken();
   temp_int = lex.GetInteger();
   params.user_defined_bullets[index].setCharacter(temp_int);
   params.temp_bullets[index].setCharacter(temp_int);
   lex.nextToken();
   temp_int = lex.GetInteger();
   params.user_defined_bullets[index].setSize(temp_int);
   params.temp_bullets[index].setSize(temp_int);
   lex.nextToken();
   LString temp_str = lex.GetString();
   if (temp_str != "\\end_bullet") {
    // this element isn't really necessary for
    // parsing but is easier for humans
    // to understand bullets. Put it back and
    // set a debug message?
    lex.printError("\\end_bullet expected, got" + temp_str);
    //how can I put it back?
   }
  } else if (token == "\\bulletLaTeX") {
   lex.nextToken();
   int index = lex.GetInteger();
   lex.next();
   LString temp_str = lex.GetString(), sum_str;
   while (temp_str != "\\end_bullet") {
    // this loop structure is needed when user
    // enters an empty string since the first
    // thing returned will be the \\end_bullet
    // OR
    // if the LaTeX entry has spaces. Each element
    // therefore needs to be read in turn
    sum_str += temp_str;
    lex.next();
    temp_str = lex.GetString();
   }
   params.user_defined_bullets[index].setText(sum_str);
   params.temp_bullets[index].setText(sum_str);
  } else if (token == "\\secnumdepth") {
   lex.nextToken();
   params.secnumdepth = lex.GetInteger();
  } else if (token == "\\tocdepth") {
   lex.nextToken();
   params.tocdepth = lex.GetInteger();
  } else if (token == "\\baselinestretch") { // now obsolete
   lex.nextToken(); // should not be used directly
   // anymore.
   // Will probably keep a kind of support just for
   // compability.
   params.spacing.set(Spacing::Other, lex.GetFloat());
  } else if (token == "\\spacing") {
   lex.next();
   LString tmp = lex.GetString().strip();
   if (tmp == "single") {
    params.spacing.set(Spacing::Single);
   } else if (tmp == "onehalf") {
    params.spacing.set(Spacing::Onehalf);
   } else if (tmp == "double") {
    params.spacing.set(Spacing::Double);
   } else if (tmp == "other") {
    lex.next();
    params.spacing.set(Spacing::Other,
         lex.GetFloat());
   } else {
    lex.printError("Unknown spacing token: '$$Token'");
   }
  } else if (token == "\\float_placement") {
   lex.nextToken();
   params.float_placement = lex.GetString();
  } else if (token == "\\cursor") {
   // this is obsolete, so we just skip it.
   lex.nextToken();
  } else if (token == "\\family") { 
   lex.next();
   font.setLyXFamily(lex.GetString());
  } else if (token == "\\series") {
   lex.next();
   font.setLyXSeries(lex.GetString());
  } else if (token == "\\shape") {
   lex.next();
   font.setLyXShape(lex.GetString());
  } else if (token == "\\size") {
   lex.next();
   font.setLyXSize(lex.GetString());
  } else if (token == "\\latex") {
   lex.next();
   LString tok = lex.GetString();
   // This is dirty, but gone with LyX3. (Asger)
   if (tok == "no_latex")
    font.setLatex(LyXFont::OFF);
   else if (tok == "latex")
    font.setLatex(LyXFont::ON);
   else if (tok == "default")
    font.setLatex(LyXFont::INHERIT);
   else
    lex.printError("Unknown LaTeX font flag "
            "`$$Token'");
  } else if (token == "\\emph") {
   lex.next();
   font.setEmph(font.setLyXMisc(lex.GetString()));
  } else if (token == "\\bar") {
   lex.next();
   LString tok = lex.GetString();
   // This is dirty, but gone with LyX3. (Asger)
   if (tok == "under")
    font.setUnderbar(LyXFont::ON);
   else if (tok == "no")
    font.setUnderbar(LyXFont::OFF);
   else if (tok == "default")
    font.setUnderbar(LyXFont::INHERIT);
   else
    lex.printError("Unknown bar font flag "
            "`$$Token'");
  } else if (token == "\\noun") {
   lex.next();
   font.setNoun(font.setLyXMisc(lex.GetString()));
  } else if (token == "\\color") {
   lex.next();
   font.setLyXColor(lex.GetString());
  } else if (token == "\\align") {
   tmpret = lex.FindToken(string_align);
   if (tmpret == -1) tmpret++;
   if (tmpret != LYX_LAYOUT_DEFAULT) {
    tmpret2 = 1;
    for (; tmpret>0; tmpret--)
     tmpret2 = tmpret2 * 2;
    par->align = tmpret2;
   }
  } else if (token == "\\added_space_top"){
   lex.nextToken();
   par->added_space_top = lex.GetString();
  } else if (token == "\\added_space_bottom") {
   lex.nextToken();
   par->added_space_bottom = lex.GetString();
                } else if (token == "\\pextra_type") {
                        lex.nextToken();
                        par->pextra_type = lex.GetInteger();
                } else if (token == "\\pextra_width") {
                        lex.nextToken();
   par->pextra_width = lex.GetString();
                } else if (token == "\\pextra_widthp") {
                        lex.nextToken();
   par->pextra_widthp = lex.GetString();
                } else if (token == "\\pextra_alignment") {
                        lex.nextToken();
                        par->pextra_alignment = lex.GetInteger();
                } else if (token == "\\pextra_hfill") {
                        lex.nextToken();
                        par->pextra_hfill = lex.GetInteger();
                } else if (token == "\\pextra_start_minipage") {
                        lex.nextToken();
                        par->pextra_start_minipage = lex.GetInteger();
  } else if (token == "\\labelwidthstring") {
   lex.EatLine();
   par->labelwidthstring = lex.GetString();
   /* do not delete this token, it is still needed! */ 
  } else if (token == "\\end_inset") {
   /* simple ignore this. The insets do not have
 *  to read this */

   // but insets should read it, it is a part of
   //the inset isn't it? Lgb.
  } else if (token == "\\begin_inset") {
   lex.next();
   tmptok = lex.GetString();
   /* test the different insets */ 
   if (tmptok == "Quotes") {
    inset = new InsetQuotes;
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "Latex") {
    // This one is on its way out
    lex.EatLine();
    tmptok = lex.GetString().strip();
    //lyxerr.print(LString(tmptok[0]));
    if (tmptok[0] == '\\') {
     // then this latex is a
     // latex command
     InsetCommand *tmpinset =
      new InsetCommand();
     tmpinset->scanCommand(tmptok);
     inset = tmpinset;
    } else {
     // This should not use InsetLaTexDel
     // it should rather insert text into
     // the paragraph and mark it as tex.
     inset = new InsetLatex(tmptok);
    }
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "LatexDel") {
    // This one is on its way out...
    lex.EatLine();
    tmptok = lex.GetString().strip();
    //lyxerr.print(LString(tmptok[0]));
    if (tmptok == "\\tableofcontents") {
     inset = new InsetTOC(this);
    } else if (tmptok == "\\listoffigures") {
     inset = new InsetLOF(this);
    } else if (tmptok == "\\listoftables") {
     inset = new InsetLOT(this);
    } else if (tmptok == "\\listofalgorithms") {
     inset = new InsetLOA(this);
    } else if (tmptok.contains("\\ref{")
        || tmptok.contains("\\pageref{")) {
     LString cont,opt,tmptmptok,cmdname;
     lex.next();
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     lex.next();
     while(lex.IsOK()) {
      tmptmptok=lex.GetString();
      if(tmptmptok[0] == '\\') {
       if( tmptmptok == "\\backslash")
        opt += '\\';
       else
        break;
      }
      else
       opt += tmptmptok;
      opt += ' ';
      lex.next();
     }
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     lex.next();
     while(lex.IsOK()) {
      tmptmptok=lex.GetString();
      if(tmptmptok[0] == '\\') {
       if( tmptmptok == "\\backslash")
        cont += '\\';
       else
        break;
      }
      else
       cont += tmptmptok;
      cont += ' ';
      lex.next();
     }
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     cmdname = "\\";
     if(tmptok.contains("\\ref{"))
      cmdname += LString("ref");
     else
      cmdname += LString("pageref");
     cont.strip();
     opt.strip();
     cmdname += "["  + cont  + "]";
     cmdname += "{"  + opt + "}";
     inset = new InsetRef(cmdname,this);
    } else if (tmptok.contains("\\url{")
        || tmptok.contains("\\htmlurl{")) {
     LString cont,opt,tmptmptok,cmdname;
     lex.next();
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     lex.next();
     while(lex.IsOK()) {
      tmptmptok=lex.GetString();
      if(tmptmptok[0] == '\\') {
       if( tmptmptok == "\\backslash")
        opt += '\\';
       else
        break;
      }
      else
       opt += tmptmptok;
      opt += ' ';
      lex.next();
     }
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     lex.next();
     while(lex.IsOK()) {
      tmptmptok=lex.GetString();
      if(tmptmptok[0] == '\\') {
       if( tmptmptok == "\\backslash")
        cont += '\\';
       else
        break;
      }
      else
       cont += tmptmptok;
      cont += ' ';
      lex.next();
     }
     while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
      lex.next();
     }
     if(tmptok.contains("\\url{"))
      cmdname = LString("url");
     else
      cmdname = LString("htmlurl");
     cont.strip();
     opt.strip();
     inset = new InsetUrl(cmdname,cont,opt);
    } else if (tmptok[0] == '\\') {
     // then this latex del is a
     // latex command
     InsetCommand *tmpinset =
      new InsetCommand();
     tmpinset->scanCommand(tmptok);
     inset = tmpinset;
    } 
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "\\i") {
    inset = new InsetLatexAccent;
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "FormulaMacro") {
    inset = new InsetFormulaMacro;
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "Formula") {
    inset = new InsetFormula;
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "Figure") {
    inset = new InsetFig(100,100, this);
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "Label") {
    // Kept for compability. Remove in 0.13.
    if (lex.EatLine()) {
     LString tmp;
     tmp += "\\label{";
     tmp += lex.GetString();
     tmp += '}';
     inset = new InsetLabel(tmp);
     par->InsertChar(pos, LYX_META_INSET); 
     par->InsertInset(pos, inset);
     par->SetFont(pos, font);
     pos++;
    }
   } else if (tmptok == "Info") {
    inset = new InsetInfo;
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "Include") {
    inset = new InsetInclude(LString(), this);
    inset->Read(lex);
    par->InsertChar(pos, LYX_META_INSET); 
    par->InsertInset(pos, inset);
    par->SetFont(pos, font);
    pos++;
   } else if (tmptok == "LatexCommand") {
    InsetCommand inscmd;
    inscmd.Read(lex);
    if (inscmd.getCmdName()=="cite") {
     inset = new InsetCitation(inscmd.getContents(), inscmd.getOptions());
    } else if (inscmd.getCmdName()=="bibitem") {
     lex.printError("Wrong place for bibitem");
     inset = inscmd.Clone();
    } else if (inscmd.getCmdName()=="BibTeX") {
     inset = new InsetBibtex(inscmd.getContents(), inscmd.getOptions(), this);
    } else if (inscmd.getCmdName()=="index") {
     inset = new InsetIndex(inscmd.getContents());
    } else if (inscmd.getCmdName()=="include") {
     inset = new InsetInclude(inscmd.getContents(), this);
    } else if (inscmd.getCmdName()=="label") {
     inset = new InsetLabel(inscmd.getCommand());
    } else if (inscmd.getCmdName()=="url"
        || inscmd.getCmdName()=="htmlurl") {
     inset = new InsetUrl(inscmd.getCommand());
    } else if (inscmd.getCmdName() == "ref"
        || inscmd.getCmdName() == "pageref") {
     if (!inscmd.getOptions().empty() || !inscmd.getContents().empty()) {
      inset = new InsetRef(inscmd, this);
     }
     /* This condition comes from a temporary solution
   to the latexdel ref inset that was transformed to an empty ref
   inset plus the body surronded by latexdel insets */

     else {
      LString cont,opt,tmptmptok,cmdname;
      lex.next();
      while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
       lex.next();
      }
      lex.next();
      while(lex.IsOK()) {
       tmptmptok=lex.GetString();
       if(tmptmptok[0] == '\\') {
        if( tmptmptok == "\\backslash")
         opt += '\\';
        else
         break;
       }
       else
        opt += tmptmptok;
       opt += ' ';
       lex.next();
      }
      while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
       lex.next();
      }
      lex.next();
      while(lex.IsOK()) {
       tmptmptok=lex.GetString();
       if(tmptmptok[0] == '\\') {
        if( tmptmptok == "\\backslash")
         cont += '\\';
        else
         break;
       }
       else
        cont += tmptmptok;
       cont += ' ';
       lex.next();
      }
      while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
       lex.next();
      }

      cont.strip();
      opt.strip();
      cmdname =  "\\" + inscmd.getCmdName();
      cmdname += "["  + cont  + "]";
      cmdname += "{"  + opt + "}";
      inset = new InsetRef(cmdname,this);
     }
    } else if (inscmd.getCmdName()=="tableofcontents") {
     inset = new InsetTOC(this);
    } else if (inscmd.getCmdName()=="listoffigures") {
     inset = new InsetLOF(this);
    } else if (inscmd.getCmdName()=="listofalgorithms") {
     inset = new InsetLOA(this);
    } else if (inscmd.getCmdName()=="listoftables") {
     inset = new InsetLOT(this);
    } else if (inscmd.getCmdName()=="printindex") {
     inset = new InsetPrintIndex(this);
    } else if (inscmd.getCmdName()=="lyxparent") {
     inset = new InsetParent(inscmd.getContents(),this);
    } else 
     // The following three are only for compatibility
     if (inscmd.getCmdName()=="-") {
      inset = new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
     } else if (inscmd.getCmdName()=="@.") {
      inset = new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
     } else if (inscmd.getCmdName()=="ldots") {
      inset = new InsetSpecialChar(InsetSpecialChar::LDOTS);
     } else
      inset = inscmd.Clone();
          
    if (inset) {
     par->InsertChar(pos, LYX_META_INSET);
     par->InsertInset(pos, inset);
     par->SetFont(pos, font);
     pos++;
    }
   }
  } else if (token == "\\InsetQuotes") {
   inset = new InsetQuotes;
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\InsetLatex") {
   inset = new InsetLatex;
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\InsetLatexDel") {
   lex.printError(_("Warning: Ignoring Old Inset"));
  } else if (token == "\\InsetFormula") {
   inset = new InsetFormula;
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\SpecialChar") {
   inset = new InsetSpecialChar;
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\Figure") {
   inset = new InsetFig(100,100, this);
   inset->Read(lex);
   par->InsertChar(pos, LYX_META_INSET); 
   par->InsertInset(pos, inset);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\newline") {
   par->InsertChar(pos, LYX_META_NEWLINE);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\LyXTable") {
   par->table = new LyXTable(lex);
  } else if (token == "\\hfill") {
   par->InsertChar(pos, LYX_META_HFILL);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\protected_separator") {
   par->InsertChar(pos, LYX_META_PROTECTED_SEPARATOR);
   par->SetFont(pos, font);
   pos++;
  } else if (token == "\\bibitem") {  // ale970302
          if (!par->bibkey)
    par->bibkey = new InsetBibKey;
          par->bibkey->Read(lex);          
  }else if (token == "\\backslash") {
   par->InsertChar(pos, '\\');
   par->SetFont(pos, font);
   pos++;
  }else if (token == "\\the_end") {
   the_end_read = true;
  } else {
   // This should be insurance for the future: (Asger)
   lex.printError("Unknown token `$$Token'. "
           "Inserting as text.");
   int n = token.length();
   for (int i=0; i < n; i++) {
    par->InsertChar(pos, token[i]);
    par->SetFont(pos, font);
    pos++;
   }
  }
 }
   
 if (!return_par)
  return_par = par;

 paragraph = return_par;
 
 return the_end_read;
}


bool Buffer::readFile(LyXLex &lex, LyXParagraph *par)
{
 LString token;

 if (lex.IsOK()) {
  lex.next();
  token = lex.GetString();
  if (token == "\\lyxformat") { // the first token _must_ be...
   lex.next();
   format = lex.GetFloat();
   if (format > 1) {
    if (LYX_FORMAT - format > 0.05) {
     printf(_("Warning: need lyxformat %.2f but found %.2f\n"),
            LYX_FORMAT, format);
    }
    if (format - LYX_FORMAT > 0.05) {
     printf(_("ERROR: need lyxformat %.2f but found %.2f\n"),
            LYX_FORMAT, format);
    }
    bool the_end = readLyXformat2(lex, par);
    // Formats >= 2.13 support "\the_end" marker
    if (format < 2.13)
     the_end = true;
                                // Formats >= 2.14 changed papersize stuff
                                if (format < 2.14) {
                                        setOldPaperStuff();
                                } else {
                                        setPaperStuff();
                                }
    if (!the_end)
     WriteAlert(_("Warning!"),
         _("Reading of document is not complete"),
         _("Maybe the document is truncated"));
    // We simulate a safe reading anyways to allow
    // users to take the chance... (Asger)
    return true;
   } // format < 1
   else {
    WriteAlert(_("ERROR!"),
        _("Old LyX file format found. "
          "Use LyX 0.10.x to read this!"));
    return false;
   }

  } else { // "\\lyxformat" not found
   WriteAlert(_("ERROR!"), _("Not a LyX file!"));
  }
 } else
  WriteAlert(_("ERROR!"), _("Unable to read file!"));
 return false;
}
          

// Returns false if unsuccesful
bool Buffer::writeFile(LString const & filename, bool flag)
{
 // if flag is false writeFile will not create any GUI
 // warnings, only stderr.
 // Needed for autosave in background or panic save (Matthias 120496)

 if (read_only && (filename == this->filename)) {
  // Here we should come with a question if we should
  // perform the write anyway.
  if (flag)
   lyxerr.print(_("Error! Document is read-only: ") + filename);
  else
   WriteAlert(_("Error! Document is read-only: "), filename);
  return false;
 }

 FileInfo finfo(filename);
 if (finfo.exist() && !finfo.writable()) {
  // Here we should come with a question if we should
  // try to do the save anyway. (i.e. do a chmod first)
  if (flag)
   lyxerr.print(_("Error! Cannot write file: ") + filename);
  else
   WriteFSAlert(_("Error! Cannot write file: "), filename);
  return false;
 }

 FilePtr file(filename, FilePtr::truncate);
 if (!file()) {
  if (flag)
   lyxerr.print(_("Error! Cannot write file: ") + filename);
  else
   WriteFSAlert(_("Error! Cannot write file: "), filename);
  return false;
 }
 // The top of the file should not be written by params.
 // collect some very important information
 LString userName(getUserName()) ;

 // write out a comment in the top of the file
 fprintf(file,
  "#This file was created by <%s> %s",
  userName.c_str(),(char*)date());
 fprintf(file,
  "#LyX 1.0 (C) 1995-1999 Matthias Ettrich"
  " and the LyX Team\n");
 
 // at the very beginning the used lyx format
 fprintf(file, "\\lyxformat %.2f\n", LYX_FORMAT);

 // now write out the buffer parameters.
 params.writeFile(file);

 char footnoteflag = 0;
 char depth = 0;

 // this will write out all the paragraphs
 // using recursive descent.
 paragraph->writeFile(file, params, footnoteflag, depth);

 // Write marker that shows file is complete
 fprintf(file, "\n\\the_end\n");
 if (file.close()) {
  if (flag)
   lyxerr.print(_("Error! Could not close file properly: ")
         + filename);
  else
   WriteFSAlert(_("Error! Could not close file properly: "),
         filename);
  return false;
 }
 return true;
}


void Buffer::writeFileAscii(LString const & filename, int linelen) 
{
 FilePtr file(filename, FilePtr::write);
 LyXFont
  font1, font2;
 Inset
  *inset;
 LyXParagraph
  *par = paragraph;
 char
  c,
  footnoteflag = 0,
  depth = 0;

 LString
  fname1,
  tmp;
 
 int
  i,j,h,
  ltype=0,
  ltype_depth=0,
  noparbreak=0,
  islatex=0,
  *clen=NULL,
  actcell=0,
  actpos=0,
  cell=0,
         cells=0,
         currlinelen=0;
 long
  fpos=0;
 bool
  ref_printed = false;
   
   
 if (!file()) {
  WriteFSAlert(_("Error: Cannot write file:"), filename);
  return;
 }
 fname1=TmpFileName();
 while (par) {
  noparbreak = 0;
  islatex = 0;
  if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE ||
      !par->previous ||
      par->previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
  
   /* begins a footnote environment ? */ 
   if (footnoteflag != par->footnoteflag) {
    footnoteflag = par->footnoteflag;
    if (footnoteflag) {
     j=strlen(string_footnotekinds[par->footnotekind])+4;
     if (currlinelen+j > linelen)
      fprintf(file,"\n");
     fprintf(file, "([%s] "
      string_footnotekinds[par->footnotekind]);
     currlinelen += j;
    }
   }
  
   /* begins or ends a deeper area ?*/ 
   if (depth != par->depth) {
    if (par->depth > depth) {
     while (par->depth > depth) {
      depth++;
     }
    }
    else {
     while (par->depth < depth) {
      depth--;
     }
    }
   }
  
   /* First write the layout */
   tmp = lyxstyle.NameOfLayout(params.textclass,par->layout);
   if (tmp == "Itemize") {
    ltype = 1;
    ltype_depth = depth+1;
   } else if (tmp =="Enumerate") {
    ltype = 2;
    ltype_depth = depth+1;
   } else if (strstr(tmp.c_str(),"ection")) {
    ltype = 3;
    ltype_depth = depth+1;
   } else if (strstr(tmp.c_str(),"aragraph")) {
    ltype = 4;
    ltype_depth = depth+1;
   } else if (tmp == "Description") {
    ltype = 5;
    ltype_depth = depth+1;
   } else if (tmp == "Abstract") {
    ltype = 6;
    ltype_depth = 0;
   } else if (tmp == "Bibliography") {
    ltype = 7;
    ltype_depth = 0;
   } else {
    ltype = 0;
    ltype_depth = 0;
   }
  
   /* maybe some vertical spaces */ 

   /* the labelwidthstring used in lists */ 
  
   /* some lines? */ 
  
   /* some pagebreaks? */ 
  
   /* noindent ? */ 
  
   /* what about the alignment */ 
  }
  else {
   /* dummy layout, that means a footnote ended */ 
   footnoteflag = LyXParagraph::NO_FOOTNOTE;
   fprintf(file, ") ");
   noparbreak = 1;
  }
      
  /* It might be a table */ 
  if (par->table){
   if (!lyxrc->ascii_roff_command.empty() &&
                            lyxrc->ascii_roff_command != "none") {
    RoffAsciiTable(file,par);
    par = par->next;
    continue;
   }
   cell = 1;
                        actcell = 0;
   cells = par->table->columns;
   clen = new int [cells];
   memset(clen,0,sizeof(int)*cells);
   for (i = 0, j = 0, h=1; i < par->last; i++, h++) {
    c = par->GetChar(i);
    if (c == LYX_META_INSET) {
     if ((inset = par->GetInset(i))) {
      FilePtr fp(fname1,
          FilePtr::write);
      if (!fp()) {
       WriteFSAlert(_("Error: Cannot open temporary file:"), fname1);
       return;
      }
      inset->Latex(fp,-1);
      h += ftell(fp) - 1;
      remove(fname1.c_str());
     }
    } else if (c == LYX_META_NEWLINE) {
     if (clen[j] < h)
      clen[j] = h;
     h = 0;
     j = (++j) % par->table->NumberOfCellsInRow(actcell);
                                        actcell++;
    }
   }
   if (clen[j] < h)
    clen[j] = h;
  }
      
  font1 = LyXFont(LyXFont::ALL_INHERIT);
                actcell=0;
  for (i = 0,actpos=1; i < par->last; i++, actpos++) {
   if (!i && !footnoteflag && !noparbreak){
    fprintf(file, "\n\n");
    for(j=0; j<depth; j++)
     fprintf(file, " ");
    currlinelen = depth*2;
    switch(ltype) {
    case 0: /* Standart */
    case 4: /* (Sub)Paragraph */
                                case 5: /* Description */
     break;
    case 6: /* Abstract */
     fprintf(file, "Abstract\n\n");
     break;
    case 7: /* Bibliography */
     if (!ref_printed) {
      fprintf(file, "References\n\n");
      ref_printed = true;
     }
     break;
    default:
     fprintf(file,"%s ",par->labelstring.c_str());
     break;
    }
    if (ltype_depth > depth) {
     for(j=ltype_depth-1; j>depth; j--)
      fprintf(file, " ");
     currlinelen += (ltype_depth-depth)*2;
    }
    if (par->table) {
     for(j=0;j<cells;j++) {
      fputc('+',file);
      for(h=0; h<(clen[j]+1); h++)
       fputc('-',file);
     }
     fprintf(file,"+\n");
     for(j=0; j<depth; j++)
      fprintf(file, " ");
     currlinelen = depth*2;
     if (ltype_depth > depth) {
      for(j=ltype_depth; j>depth; j--)
       fprintf(file, " ");
      currlinelen += (ltype_depth-depth)*2;
     }
     fprintf(file,"| ");
    }
   }
   font2 = par->GetFontSettings(i);
   if (font1.latex() != font2.latex()) {
    if (font2.latex() == LyXFont::OFF)
     islatex = 0;
    else
     islatex = 1;
   }
   else {
    islatex = 0;
   }
   c = par->GetChar(i);
   if (islatex)
    continue;
   switch (c) {
   case LYX_META_INSET:
    if ((inset = par->GetInset(i))) {
     fpos = ftell(file);
     inset->Latex(file,-1);
     currlinelen += (ftell(file) - fpos);
     actpos += (ftell(file) - fpos) - 1;
    }
    break;
   case LYX_META_NEWLINE:
    if (par->table) {
     if (par->table->NumberOfCellsInRow(actcell) <= cell) {
      for(j=actpos;j<clen[cell-1];j++)
       fputc(' ',file);
      fprintf(file," |\n");
      for(j=0; j<depth; j++)
       fprintf(file, " ");
      currlinelen = depth*2;
      if (ltype_depth > depth) {
       for(j=ltype_depth; j>depth; j--)
        fprintf(file, " ");
       currlinelen += (ltype_depth-depth)*2;
      }
      for(j=0;j<cells;j++) {
       fputc('+',file);
       for(h=0; h<(clen[j]+1); h++)
        fputc('-',file);
      }
      fprintf(file,"+\n");
      for(j=0; j<depth; j++)
       fprintf(file, " ");
      currlinelen = depth*2;
      if (ltype_depth > depth) {
       for(j=ltype_depth; j>depth; j--)
        fprintf(file, " ");
       currlinelen += (ltype_depth-depth)*2;
      }
      fprintf(file,"| ");
      cell = 1;
     } else {
      for(j=actpos; j<clen[cell-1]; j++)
       fputc(' ',file);
      fprintf(file, " | ");
      cell++;
     }
                                        actcell++;
     currlinelen = actpos = 0;
    } else {
     fprintf(file, "\n");
     for(j=0; j<depth; j++)
      fprintf(file, " ");
     currlinelen = depth*2;
     if (ltype_depth > depth) {
      for(j=ltype_depth; j>depth; j--)
       fprintf(file, " ");
      currlinelen += (ltype_depth-depth)*2;
     }
    }
    break;
   case LYX_META_HFILL: 
    fprintf(file, "\t");
    break;
   case LYX_META_PROTECTED_SEPARATOR:
    fprintf(file, " ");
    break;
   case '\\'
    fprintf(file, "\\");
    break;
   default:
    if (currlinelen > (linelen-10) \
                                    && c==' ' && (i+2 < par->last)) {
     fprintf(file, "\n");
     for(j=0; j<depth; j++)
      fprintf(file, " ");
     currlinelen = depth*2;
     if (ltype_depth > depth) {
      for(j=ltype_depth; j>depth; j--)
       fprintf(file, " ");
      currlinelen += (ltype_depth-depth)*2;
     }
    } else if (c != '\0')
     fprintf(file, "%c", c);
    else if (c == '\0')
     lyxerr.debug("writeAsciiFile: NULL char in structure.");
    currlinelen++;
    break;
   }
  }
  if (par->table) {
   for(j=actpos;j<clen[cell-1];j++)
    fputc(' ',file);
   fprintf(file," |\n");
   for(j=0; j<depth; j++)
    fprintf(file, " ");
   currlinelen = depth*2;
   if (ltype_depth > depth) {
    for(j=ltype_depth; j>depth; j--)
     fprintf(file, " ");
    currlinelen += (ltype_depth-depth)*2;
   }
   for(j=0;j<cells;j++) {
    fputc('+',file);
    for(h=0; h<(clen[j]+1); h++)
     fputc('-',file);
   }
   fprintf(file,"+\n");
   delete [] clen;    
  }      
  par = par->next;
 }
   
 fprintf(file, "\n");
}


void Buffer::makeLaTeXFile(LString const & filename, 
      LString const & original_path,
      bool nice, bool only_body)
{
 lyxerr.debug("makeLaTeXFile...", Error::LATEX);
 params.textclass = GetCurrentTextClass();
 niceFile = nice; // this will be used by Insetincludes.
 if (nice) 
  tex_code_break_column = lyxrc->ascii_linelen;
 else
  tex_code_break_column = 0;

        LyXTextClass *tclass = lyxstyle.TextClass(params.textclass);
  
 FilePtr file(filename, FilePtr::write);
 if (!file()) {
  WriteFSAlert(_("Error: Cannot write file:"),filename);
  return;
 }

 // validate the buffer.
 lyxerr.debug(" Validating buffer...", Error::LATEX);
 LaTeXFeatures features(tclass->number_of_defined_layouts);
 validate(features);
 lyxerr.debug(" Buffer validation done.", Error::LATEX);
 
 texrow.reset();
 // The starting paragraph of the coming rows is the 
 // first paragraph of the document. (Asger)
 texrow.start(paragraph, 0);

 LString userName(getUserName());
 LString LFile;
 
 if (!only_body) {
  LFile += "%% This LaTeX-file was created by <";
  LFile += userName + "> " + (char*)date();
  LFile += "%% LyX 1.0 (C) 1995-1999 by Matthias Ettrich and the LyX Team\n";
  LFile += "\n%% Do not edit this file unless you know what you are doing.\n";
  texrow.newline();
  texrow.newline();
  texrow.newline();
  texrow.newline();
 }
 lyxerr.debug("lyx header finished");
 // There are a few differences between nice LaTeX and usual files:
 // usual is \batchmode, uses \listfiles and has a 
 // special input@path to allow the including of figures
 // with either \input or \includegraphics (what figinsets do).
 // batchmode is not set if there is a tex_code_break_column.
 // In this case somebody is interested in the generated LaTeX,
 // so this is OK. input@path is set when the actual parameter
 // original_path is set. This is done for usual tex-file, but not
 // for nice-latex-file. (Matthias 250696)
 if (!only_body) {
  if (!nice){
   // code for usual, NOT nice-latex-file
   LFile += "\\batchmode\n"// changed
   // from \nonstopmode
   texrow.newline();
   LFile += "\\listfiles\n";
   texrow.newline();
  }
  if (!original_path.empty()) {
   LFile += "\\makeatletter\n";
   texrow.newline();
   LFile += "\\def\\input@path{{" + original_path
     + "/}}\n";
   texrow.newline();
   LFile += "\\makeatother\n";
   texrow.newline();
  }
  
  LFile += "\\documentclass";
  
  LString options; // the document class options.
  
  if (tclass->opt_fontsize.tokenPos('|',params.fontsize) >= 0) {
   // only write if existing in list (and not default)
   options += params.fontsize;
   options += "pt,";
  }
  
  
  if (!params.use_geometry &&
      (params.paperpackage == PACKAGE_NONE)) {
   switch (params.papersize) {
   case PAPER_A4PAPER:
    options += "a4paper,";
    break;
   case PAPER_USLETTER:
    options += "letterpaper,";
    break;
   case PAPER_A5PAPER:
    options += "a5paper,";
    break;
   case PAPER_B5PAPER:
    options += "b5paper,";
    break;
   case PAPER_EXECUTIVEPAPER:
    options += "executivepaper,";
    break;
   case PAPER_LEGALPAPER:
    options += "legalpaper,";
    break;
   }
  }

  // if needed
  if (params.sides != tclass->sides) {
   if (params.sides == 2)
    options += "twoside,";
   else
    options += "oneside,";
  }

  // if needed
  if (params.columns != tclass->columns) {
   if (params.columns == 2)
    options += "twocolumn,";
   else
    options += "onecolumn,";
  }

  if (!params.use_geometry && params.orientation == ORIENTATION_LANDSCAPE)
   options += "landscape,";
  
  // language should be a parameter to \documentclass
  if (params.language != "default") {
   options += params.language + ',';
  }
  
  // the user-defined options
  if (!params.options.empty()) {
   options += params.options + ',';
  }
  
  if (!options.empty()){
   options.strip(',');
   LFile += '[';
   LFile += options;
   LFile += ']';
  }
  
  LFile += '{';
  LFile += lyxstyle.LatexnameOfClass(params.textclass);
  LFile += "}\n";
  texrow.newline();
  // end of \documentclass defs
  
  // this one is not per buffer
  if (lyxrc->fontenc != "default") {
   LFile += "\\usepackage[" + lyxrc->fontenc
     + "]{fontenc}\n";
   texrow.newline();
  }
  if (params.inputenc != "default") {
   LFile += "\\usepackage[" + params.inputenc
     + "]{inputenc}\n";
   texrow.newline();
  }
  if (params.fonts != "default") {
   LFile += "\\usepackage{" + params.fonts + "}\n";
   texrow.newline();
  }
  
  /* at the very beginning the text parameters */
  if (params.paperpackage != PACKAGE_NONE) {
   switch (params.paperpackage) {
   case PACKAGE_A4:
    LFile += "\\usepackage{a4}\n";
    texrow.newline();
    break;
   case PACKAGE_A4WIDE:
    LFile += "\\usepackage{a4wide}\n";
    texrow.newline();
    break;
   case PACKAGE_WIDEMARGINSA4:
    LFile += "\\usepackage[widemargins]{a4}\n";
    texrow.newline();
    break;
   }
  }
  if (params.use_geometry) {
   LFile += "\\usepackage{geometry}\n";
   texrow.newline();
   LFile += "\\geometry{verbose";
   if (params.orientation == ORIENTATION_LANDSCAPE)
    LFile += ",landscape";
   switch (params.papersize2) {
   case VM_PAPER_CUSTOM:
    if (!params.paperwidth.empty())
     LFile += ",paperwidth="
       + params.paperwidth;
    if (!params.paperheight.empty())
     LFile += ",paperheight="
       + params.paperheight;
    break;
   case VM_PAPER_USLETTER:
    LFile += ",letterpaper";
    break;
   case VM_PAPER_USLEGAL:
    LFile += ",legalpaper";
    break;
   case VM_PAPER_USEXECUTIVE:
    LFile += ",executivepaper";
    break;
   case VM_PAPER_A3:
    LFile += ",a3paper";
    break;
   case VM_PAPER_A4:
    LFile += ",a4paper";
    break;
   case VM_PAPER_A5:
    LFile += ",a5paper";
    break;
   case VM_PAPER_B3:
    LFile += ",b3paper";
    break;
   case VM_PAPER_B4:
    LFile += ",b4paper";
    break;
   case VM_PAPER_B5:
    LFile += ",b5paper";
    break;
   }
   if (!params.topmargin.empty())
    LFile += ",tmargin=" + params.topmargin;
   if (!params.bottommargin.empty())
    LFile += ",bmargin=" + params.bottommargin;
   if (!params.leftmargin.empty())
    LFile += ",lmargin=" + params.leftmargin;
   if (!params.rightmargin.empty())
    LFile += ",rmargin=" + params.rightmargin;
   if (!params.headheight.empty())
    LFile += ",headheight=" + params.headheight;
   if (!params.headsep.empty())
    LFile += ",headsep=" + params.headsep;
   if (!params.footskip.empty())
    LFile += ",footskip=" + params.footskip;
   LFile += "}\n";
   texrow.newline();
  }
  if (params.use_amsmath
      && !lyxstyle.LatexnameOfClass(params.textclass).prefixIs("ams")) {
   LFile += "\\usepackage{amsmath}\n";
  }

  if (tclass->opt_pagestyle.tokenPos('|',params.pagestyle) >= 0) {
   if (params.pagestyle == "fancy") {
    LFile += "\\usepackage{fancyhdr}\n";
    texrow.newline();
   }
   LFile += "\\pagestyle{" + params.pagestyle + "}\n";
   texrow.newline();
  }

  // We try to load babel late, in case it interferes
  // with other packages.
  if (params.language != "default") {
   LFile += "\\usepackage{babel}\n";
   texrow.newline();
  }

  if (params.secnumdepth != tclass->secnumdepth) {
   LFile += "\\setcounter{secnumdepth}{";
   LFile += params.secnumdepth;
   LFile += "}\n";
   texrow.newline();
  }
  if (params.tocdepth != tclass->tocdepth) {
   LFile += "\\setcounter{tocdepth}{";
   LFile += params.tocdepth;
   LFile += "}\n";
   texrow.newline();
  }
  
  if (params.paragraph_separation) {
   switch (params.defskip.kind()) {
   case VSpace::SMALLSKIP: 
    LFile += "\\setlength\\parskip{\\smallskipamount}\n";
    break;
   case VSpace::MEDSKIP:
    LFile += "\\setlength\\parskip{\\medskipamount}\n";
    break;
   case VSpace::BIGSKIP:
    LFile += "\\setlength\\parskip{\\bigskipamount}\n";
    break;
   case VSpace::LENGTH:
    LFile += "\\setlength\\parskip{"
      + params.defskip.length().asLatexString()
      + "}\n";
    break;
   default// should never happen // Then delete it.
    LFile += "\\setlength\\parskip{\\medskipamount}\n";
    break;
   }
   texrow.newline();
   
   LFile += "\\setlength\\parindent{0pt}\n";
   texrow.newline();
  }

  // Write out what we've generated so far...and reset LFile
  fwrite(LFile.c_str(), sizeof(char), LFile.length(), file);
  LFile.clean(); 

  // Now insert the LyX specific LaTeX commands...
  LString preamble, tmppreamble;

  // The optional packages;
  preamble = features.getPackages(params);

  // this might be useful...
  preamble += "\n\\makeatletter\n\n";

  // Some macros LyX will need
  tmppreamble = features.getMacros(params);

  if (!tmppreamble.empty()) {
   preamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
    "LyX specific LaTeX commands.\n"
    + tmppreamble + '\n';
  }

  // the text class specific preamble 
  tmppreamble = features.getTClassPreamble(params);
  if (!tmppreamble.empty()) {
   preamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
    "Textclass specific LaTeX commands.\n"
    + tmppreamble + '\n';
  }

  /* the user-defined preamble */
  if (!params.preamble.empty()) {
   preamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
    "User specified LaTeX commands.\n"
    + params.preamble + '\n';
  }

  preamble += "\\makeatother\n\n";

  // Itemize bullet settings need to be last in case the user
  // defines their own bullets that use a package included
  // in the user-defined preamble -- ARRae
  for (int i = 0; i < 4; ++i) {
   if (params.user_defined_bullets[i] != ITEMIZE_DEFAULTS[i]) {
    preamble += "\\renewcommand\\labelitemi";
    switch (i) {
     // `i' is one less than the item to modify
    case 0:
     break;
    case 1:
     preamble += 'i';
     break;
    case 2:
     preamble += "ii";
     break;
    case 3:
     preamble += 'v';
     break;
    }
    preamble += "[0]{" + params.user_defined_bullets[i].getText() + "}\n";
   }
  }

  for (int j = preamble.countChar('\n'); j-- ;) {
   texrow.newline();
  }

  // A bit faster than printing a char at a time I think.
  fwrite(preamble.c_str(), sizeof(char),
         preamble.length(), file);

  // make the body.
  LFile += "\\begin{document}\n\n";
  texrow.newline();
  texrow.newline();
 } // only_body
 lyxerr.debug("preamble finished, now the body.");
 
 bool was_title = false;
 bool already_title = false;
 LString ftnote;
 TexRow ft_texrow;
 int ftcount = 0;
 int loop_count = 0;

 LyXParagraph *par = paragraph;

 // if only_body
 while (par) {
  ++loop_count;
  if (par->IsDummy())
   lyxerr.debug("Error in MakeLateXFile.", Error::LATEX);
  LyXLayout * layout = lyxstyle.Style(params.textclass,
          par->layout);
     
         if (layout->intitle) {
   if (already_title) {
    lyxerr.print("Error in MakeLatexFile: You"
          " should not mix title layouts"
          " with normal ones.");
   } else
    was_title = true;
         } else if (was_title && !already_title) {
   LFile += "\\maketitle\n";
   texrow.newline();
   already_title = true;
   was_title = false;      
  }
  // We are at depth 0 so we can just use
  // ordinary \footnote{} generation
  // flag this with ftcount
  ftcount = -1;
  if (layout->isEnvironment()
                    || par->pextra_type != PEXTRA_NONE) {
   par = par->TeXEnvironment(LFile, texrow,
        ftnote, ft_texrow, ftcount);
  } else {
   par = par->TeXOnePar(LFile, texrow,
          ftnote, ft_texrow, ftcount);
  }

  // Write out what we've generated...and reset LFile
  if (ftcount >= 1) {
   if (ftcount > 1) {
    LFile += "\\addtocounter{footnote}{-";
    LFile += ftcount - 1;
    LFile += '}';
   }
   LFile += ftnote;
   texrow += ft_texrow;
   ftnote.clean();
   ft_texrow.reset();
   ftcount = 0;
  }
  if (loop_count == 2) {
   // fwrite()ing every second time through the loop
   // gains a few extra % of speed; going higher than
   // 2 will slow things down again.  I'll look at
   // LFile.length() in a future revision.  ARRae
   fwrite(LFile.c_str(), sizeof(char),
          LFile.length(), file);
   LFile.clean();
   loop_count = 0;
  }
 }

 if (!only_body) {
  LFile += "\\end{document}\n";
  texrow.newline();
 
  lyxerr.debug("makeLaTeXFile...done", Error::LATEX);
 } else {
  lyxerr.debug("LaTeXFile for inclusion made.", Error::LATEX);
 }

 // Just to be sure. (Asger)
 texrow.newline();

 // Write out what we've generated...and reset LFile
 fwrite(LFile.c_str(), sizeof(char), LFile.length(), file);
 LFile.clean();

 // tex_code_break_column's value is used to decide
 // if we are in batchmode or not (within mathed_write()
 // in math_write.C) so we must set it to a non-zero
 // value when we leave otherwise we save incorrect .lyx files.
 tex_code_break_column = lyxrc->ascii_linelen;

 if (file.close()) {
  WriteFSAlert(_("Error! Could not close file properly:"), filename);
 }
 lyxerr.debug("Finished making latex file.");
}


bool Buffer::isLatex()
{
 return lyxstyle.TextClass(params.textclass)->output_type == LATEX;
}


bool Buffer::isLinuxDoc()
{
 return lyxstyle.TextClass(params.textclass)->output_type == LINUXDOC;
}


void Buffer::sgmlOpenTag(FILE * file,int depth,LString & latexname)
{
 static char *space[] = {" "," "," "," "," "," "," ",
    " "," "," "," "};

 fprintf(file,"\n%s<%s>",space[depth],latexname.c_str());
}


void Buffer::sgmlCloseTag(FILE * file,int depth,LString & latexname)
{
 static char *space[] = {" "," "," "," "," "," "," ",
    " "," "," "," "};

 fprintf(file,"\n%s",space[depth],latexname.c_str());
}


void Buffer::makeLinuxDocFile(LString const & filename, int column)
{
 LyXParagraph *par = paragraph;

 LString top_element=lyxstyle.LatexnameOfClass(params.textclass);
 LString environment_stack[10];
        LString item_name;

 int depth=0;              /* paragraph depth */

 FilePtr file(filename, FilePtr::write);
 tex_code_break_column = column; 

 if (!file()) {
  WriteAlert(_("LYX_ERROR:"), _("Cannot write file"), filename);
  return;
 }
   
 //ResetTexRow();
 texrow.reset();
   
 if (params.preamble.empty()) {
  fprintf(file, "\n\n");
 }
 else {
  fprintf(file, "\n\n"
   params.preamble.c_str() );
 }

        LString userName(getUserName());
 fprintf(file, "\n", userName.c_str(), (char *)date());

 if(params.options.empty())
  sgmlOpenTag(file,0,top_element);
 else {
  LString top = top_element;
  top += " ";
  top += params.options;
  sgmlOpenTag(file,0,top);
 }

 while (par) {
  if (par->IsDummy()) {
   lyxerr.debug("Error in MakeLinuxDocFile.");
   par = par->next;
                } else {
   int desc_on=0;            /* description mode*/

   LyXLayout *style=lyxstyle.Style(GetCurrentTextClass(), par->layout);

   par->AutoDeleteInsets();

   /* treat <toc> as a special case for compatibility with old code */
   if (par->GetChar(0) == LYX_META_INSET) {
           Inset *inset = par->GetInset(0);
    char  lyx_code = inset->LyxCode();
    if (lyx_code ==Inset::TOC_CODE){
                                        LString temp= "toc";
                                        sgmlOpenTag(file, depth, temp);

     par = par->next;
     linuxDocHandleFootnote(file, par);
     continue;
    }
   }

   /* environment tag closing */
   for( ;depth > par->depth; depth--) {
                                sgmlCloseTag(file,depth,environment_stack[depth]);
    environment_stack[depth]="";
   }

   /* write opening SGML tags */
   switch(style->latextype) {
   case LATEX_PARAGRAPH:
           if(depth == par->depth && environment_stack[depth]!="") {
                                        sgmlCloseTag(file,depth,environment_stack[depth]);
            environment_stack[depth] = "";
     if(depth) 
             depth--;
     else
             fprintf(file,"

"
);
    }
                                sgmlOpenTag(file,depth,style->latexname);
    break;

   case LATEX_COMMAND:
          if (depth!=0)
           LinuxDocError(par, 0, _("Error : Wrong depth for LatexType Command.\n"));

                               if (environment_stack[depth]!=""){
           sgmlCloseTag(file,depth,environment_stack[depth]);
                                       fprintf(file, "

"
);
                               }

          environment_stack[depth]="";
                               sgmlOpenTag(file,depth, style->latexname);
          break;

   case LATEX_ENVIRONMENT:
   case LATEX_ITEM_ENVIRONMENT:
          if(depth == par->depth && environment_stack[depth]!=style->latexname && 
           environment_stack[depth]!= "") {

                                       sgmlCloseTag(file,depth,environment_stack[depth]);
           environment_stack[depth] = "";
          }
          if (depth < par->depth) {
           depth = par->depth;
           environment_stack[depth] = "";
          }
          if (environment_stack[depth] != style->latexname) {
                                       if(depth==0) {
                                               LString temp="p";
                                               sgmlOpenTag(file,depth,temp);
                                       }
           environment_stack[depth]= style->latexname;
                                       sgmlOpenTag(file,depth,environment_stack[depth]);
          }
          if(style->latextype == LATEX_ENVIRONMENT) break;

          desc_on =(style->labeltype == LABEL_MANUAL);

                               if(desc_on)
                                       item_name="tag";
                               else
           item_name="item";

                               sgmlOpenTag(file,depth+1,item_name);
          break;
   default:
           sgmlOpenTag(file,depth,style->latexname);
    break;
   }

   SimpleLinuxDocOnePar(file, par, desc_on);
 
   /* write closing SGML tags */
   switch(style->latextype) {
   case LATEX_COMMAND:
   case LATEX_ENVIRONMENT:
   case LATEX_ITEM_ENVIRONMENT:
           break;
   default:
    sgmlCloseTag(file,depth,style->latexname);
    break;
   }

   par = par->next;

   linuxDocHandleFootnote(file,par);
  }
 }
   
 
 /* Close open tags */
 for(;depth>0;depth--)
         sgmlCloseTag(file,depth,environment_stack[depth]);

 if(environment_stack[depth] != "")
         sgmlCloseTag(file,depth,environment_stack[depth]);

 fprintf(file, "\n\n");
 sgmlCloseTag(file,0,top_element);

 if (file.close()) {
  WriteFSAlert(_("Error! Could not close file properly:"),
        filename);
 }
}


void Buffer::linuxDocHandleFootnote(FILE *file,LyXParagraph* &par)
{
 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
  fprintf(file," ");
  SimpleLinuxDocOnePar(file, par, 0);
  fprintf(file,"\n");
  par = par->next;
 }
}


/* push a tag in a style stack */
void Buffer::push_tag(FILE *file, char const *tag,
        int& pos, char stack[5][3])
{
 int j;

 /* pop all previous tags */
 for (j=pos; j>=0; j--)
  fprintf(file, "", stack[j]); 

 /* add new tag */
 sprintf(stack[++pos], "%s", tag);

 /* push all tags */
 for (j=0; j<=pos; j++)
  fprintf(file, "<%s>", stack[j]);
}


// pop a tag from a style stack
void Buffer::pop_tag(FILE *file, char const * tag,
       int& pos, char stack[5][3])
{
 int j;

 // pop all tags till specified one
 for (j=pos; (j>=0) && (strcmp(stack[j], tag)); j--)
  fprintf(file, "", stack[j]);

 // closes the tag
 fprintf(file, "", tag);

 // push all tags, but the specified one
 for (j=j+1; j<=pos; j++) {
  fprintf(file, "<%s>", stack[j]);
  strcpy(stack[j-1], stack[j]);
 }
 pos --;
}


/* handle internal paragraph parsing -- layout already processed */

// checks, if newcol chars should be put into this line
// writes newline, if necessary.
static
void linux_doc_line_break(FILE *file, unsigned int &colcount, const unsigned int newcol)
{
 colcount += newcol;
 if (colcount > lyxrc->ascii_linelen) {
  fprintf(file, "\n");
  colcount = newcol; // assume write after this call
 }
}


void Buffer::SimpleLinuxDocOnePar(FILE *file, LyXParagraph *par, int desc_on) 
{
 LyXFont font1,font2;
 char c;
 Inset *inset;
 int main_body, j;
 LyXLayout * style = lyxstyle.Style(params.textclass, par->GetLayout());

 bool is_tt = false;               // typewriter font flag 
 bool is_bf = false;               // bold font flag 
 bool is_em = false;               // emphasis (italic) font flag 

 int stack_num = -1;          // style stack position 
 char stack[5][3];          // style stack 
        unsigned int char_line_count = 5;     // Heuristic choice ;-) 

 if (style->labeltype != LABEL_MANUAL)
  main_body = 0;
 else
  main_body = par->BeginningOfMainBody();

 /* gets paragraph main font */
 if (main_body > 0)
  font1 = style->labelfont;
 else
  font1 = style->font;

  
 /* parsing main loop */
 for (int i = 0; i < par->last; i++) {

  /* handle quote tag */
  if (i == main_body && !par->IsDummy()) {
   if (main_body > 0)
    font1 = style->font;
  }

  font2 = par->getFont(i);

  /* handle <tt> tag */
  if (font1.family() != font2.family()) {
          if (font2.family() == LyXFont::TYPEWRITER_FAMILY) {
           push_tag(file, "tt", stack_num, stack);
    is_tt = true;
   } else if (is_tt) {
           pop_tag(file, "tt", stack_num, stack);
    is_tt = false;
   }
  }

--> --------------------

--> maximum size reached

--> --------------------

¤ Dauer der Verarbeitung: 0.135 Sekunden  (vorverarbeitet)  ¤





Druckansicht
unsichere Verbindung
Druckansicht
sprechenden Kalenders

Eigene Datei ansehen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff