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 / layout.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  31KB  |  1,311 lines

  1. /* This file is part of
  2.  * ======================================================
  3.  * 
  4.  *           LyX, The Document Processor
  5.  *      
  6.  *        Copyright (C) 1995 Matthias Ettrich
  7.  *          Copyright (C) 1995-1998 The LyX Team.
  8.  *
  9.  *======================================================*/
  10.  
  11. /* Change log:
  12.  * 
  13.  *  14/11/1995,   Pascal AndrΘ <andre@via.ecp.fr>
  14.  *  Modified for external style definition. 
  15.  * 
  16.  *  15/11/1995,   Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
  17.  *  Modified to use binary search and a small pseudo lexical analyzer.
  18.  *  
  19.  *  29/03/1996,  Dirk Niggeman
  20.  *  Created classes LyXTextClass & LyXLayout.
  21.  * 
  22.  *  30/03/1996,  asierra
  23.  *  Created class LyxLex and improved the lexical analyzer. 
  24.  */
  25.  
  26. #include <config.h>
  27.  
  28. #ifdef __GNUG__
  29. #pragma implementation
  30. #endif
  31.  
  32. #include "definitions.h"
  33. #include <stdlib.h>
  34. #include "layout.h"
  35. #include "lyxlex.h"
  36. #include "filetools.h"
  37. #include "lyx_gui_misc.h"
  38. #include "error.h"
  39. #include "gettext.h"
  40.  
  41. //     $Id: layout.C,v 1.1.1.1 1998/04/23 16:02:52 larsbj Exp $    
  42.  
  43. #if !defined(lint) && !defined(WITH_WARNINGS)
  44. static char vcid[] = "$Id: layout.C,v 1.1.1.1 1998/04/23 16:02:52 larsbj Exp $";
  45. #endif /* lint */
  46.  
  47. /* Global variable: textclass table */
  48. LyXTextClassList lyxstyle;
  49.  
  50. // Reads the style files
  51. void LyXSetStyle()
  52. {
  53.     lyxerr.debug("LyXSetStyle: parsing configuration...");
  54.     
  55.     if (!lyxstyle.Read()) {
  56.         lyxerr.print("LyXSetStyle: an error occured during parsing.");
  57.         lyxerr.print("             Exiting.");
  58.         exit(1);
  59.     }
  60.  
  61.     lyxerr.debug("LyXSetStyle: configuration parsed.");
  62. }
  63.  
  64.  
  65. //  The order of the LayoutTags enum is no more important. [asierra300396]
  66. /* tags indexes */
  67. enum _LayoutTags {
  68.     LT_ALIGN, LT_ALIGNPOSSIBLE, LT_MISC,
  69.     LT_BLOCK, LT_MARGIN,
  70.     LT_BOTTOMSEP, LT_CENTER, LT_CENTERED_TOP_ENVIRONMENT, LT_COLUMNS,
  71.     LT_COPYSTYLE, LT_OBSOLETEDBY,
  72.     LT_COMMAND, LT_COUNTER_CHAPTER, LT_COUNTER_ENUMI, LT_COUNTER_ENUMII,
  73.     LT_COUNTER_ENUMIII, LT_COUNTER_ENUMIV, LT_COUNTER_PARAGRAPH,
  74.     LT_COUNTER_SECTION, LT_COUNTER_SUBPARAGRAPH, LT_COUNTER_SUBSECTION,
  75.     LT_COUNTER_SUBSUBSECTION, LT_DEFAULTFONT, LT_DYNAMIC, LT_EMPTY,
  76.     LT_END, LT_ENVIRONMENT, LT_ENVIRONMENT_DEFAULT, LT_FAMILY,
  77.     LT_FANCYHDR, LT_FILL_BOTTOM, LT_FILL_TOP, LT_FIRST_COUNTER,
  78.     LT_FIRST_DYNAMIC, LT_FONT, LT_FREE_SPACING, LT_HEADINGS, LT_INPUT,
  79.     LT_ITEM_ENVIRONMENT, LT_ITEMSEP, LT_KEEPEMPTY,
  80.     LT_LABEL_BOTTOMSEP, LT_LABELFONT, LT_TEXTFONT,
  81.     LT_LABELINDENT, LT_LABELSEP, LT_LABELSTRING, LT_LABELTYPE,
  82.     LT_LATEXNAME, LT_LATEXPARAM, LT_LATEXTYPE, LT_LAYOUT, LT_LEFT,
  83.     LT_LEFTMARGIN,
  84.     LT_LIST_ENVIRONMENT , LT_MANUAL, LT_MAXCOUNTER, 
  85.     LT_NEED_PROTECT, LT_NEWLINE,
  86.     LT_NEXTNOINDENT, LT_NO_LABEL, LT_NOSTYLE,
  87.     LT_PAGESTYLE, LT_PARAGRAPH,
  88.     LT_PARINDENT, LT_PARSEP, LT_PARSKIP, LT_PLAIN, LT_PREAMBLE, LT_RIGHT,
  89.     LT_RIGHT_ADDRESS_BOX, LT_RIGHTMARGIN, LT_SENSITIVE, LT_SIDES,
  90.     LT_SPACING, LT_SPACING_SINGLE, LT_SPACING_ONEHALF,
  91.     LT_SPACING_DOUBLE, LT_OTHER,  LT_CLASSOPTIONS, LT_FONTSIZE,
  92.     LT_STATIC, LT_STYLE, LT_TOP_ENVIRONMENT, LT_TOPSEP, LT_BIBLIO,
  93.         LT_INTITLE, LT_SECNUMDEPTH, LT_TOCDEPTH,
  94.     LT_LAST
  95. };
  96.  
  97.  
  98. // This table is sorted alphabetically [asierra 30March96]
  99. static keyword_item layoutTags[LT_LAST-1] = {
  100.     { "align",            LT_ALIGN },
  101.     { "alignpossible",        LT_ALIGNPOSSIBLE },
  102.     { "bibliography",        LT_BIBLIO },
  103.     { "block",            LT_BLOCK },
  104.     { "bottomsep",            LT_BOTTOMSEP },
  105.     { "center",            LT_CENTER },
  106.     { "centered_top_environment",    LT_CENTERED_TOP_ENVIRONMENT },
  107.         { "classoptions",               LT_CLASSOPTIONS },
  108.     { "columns",            LT_COLUMNS },
  109.     { "command",            LT_COMMAND },
  110.     { "copystyle",                  LT_COPYSTYLE },
  111.     { "counter_chapter",        LT_COUNTER_CHAPTER },
  112.     { "counter_enumi",        LT_COUNTER_ENUMI },
  113.     { "counter_enumii",        LT_COUNTER_ENUMII },
  114.     { "counter_enumiii",        LT_COUNTER_ENUMIII },
  115.     { "counter_enumiv",        LT_COUNTER_ENUMIV },
  116.     { "counter_paragraph",        LT_COUNTER_PARAGRAPH },
  117.     { "counter_section",        LT_COUNTER_SECTION },
  118.     { "counter_subparagraph",    LT_COUNTER_SUBPARAGRAPH },
  119.     { "counter_subsection",        LT_COUNTER_SUBSECTION },
  120.     { "counter_subsubsection",    LT_COUNTER_SUBSUBSECTION },
  121.     { "defaultfont",         LT_DEFAULTFONT },
  122.     { "double",                     LT_SPACING_DOUBLE },
  123.     { "dynamic",            LT_DYNAMIC },
  124.     { "empty",            LT_EMPTY },
  125.     { "end",            LT_END },
  126.     { "environment",        LT_ENVIRONMENT },
  127.     { "environment_default",    LT_ENVIRONMENT_DEFAULT },
  128.     { "fancyhdr",            LT_FANCYHDR },
  129.     { "fill_bottom",        LT_FILL_BOTTOM },
  130.     { "fill_top",            LT_FILL_TOP },
  131.     { "first_counter",              LT_FIRST_COUNTER },
  132.     { "first_dynamic",              LT_FIRST_DYNAMIC },
  133.     { "font",                      LT_FONT },
  134.     { "fontsize",                      LT_FONTSIZE },
  135.     { "freespacing",           LT_FREE_SPACING },
  136.     { "headings",                  LT_HEADINGS },
  137.     { "input",             LT_INPUT },
  138.     { "intitle",                    LT_INTITLE },
  139.     { "item_environment",         LT_ITEM_ENVIRONMENT },
  140.     { "itemsep",                   LT_ITEMSEP },
  141.     { "keepempty",                  LT_KEEPEMPTY },
  142.     { "labelbottomsep",             LT_LABEL_BOTTOMSEP },
  143.     { "labelfont",                 LT_LABELFONT },
  144.     { "labelindent",               LT_LABELINDENT },
  145.     { "labelsep",                  LT_LABELSEP },
  146.     { "labelstring",               LT_LABELSTRING },
  147.     { "labeltype",                 LT_LABELTYPE },
  148.     { "latexname",                 LT_LATEXNAME },
  149.     { "latexparam",            LT_LATEXPARAM },    //arrae970411
  150.     { "latextype",                 LT_LATEXTYPE },
  151.     { "layout",                    LT_LAYOUT },
  152.     { "left",                      LT_LEFT },
  153.     { "leftmargin",                LT_LEFTMARGIN },
  154.     { "list_environment",         LT_LIST_ENVIRONMENT },
  155.     { "manual",                    LT_MANUAL },
  156.     { "margin",                    LT_MARGIN },
  157.     { "maxcounter",                LT_MAXCOUNTER },
  158.     { "needprotect",                LT_NEED_PROTECT },
  159.     { "newline",            LT_NEWLINE },
  160.     { "nextnoindent",        LT_NEXTNOINDENT },
  161.     { "no_label",            LT_NO_LABEL },
  162.     { "nostyle",                    LT_NOSTYLE },
  163.     { "obsoletedby",                LT_OBSOLETEDBY },
  164.     { "onehalf",                    LT_SPACING_ONEHALF },
  165.     { "other",                      LT_OTHER },
  166.     { "pagestyle",            LT_PAGESTYLE },
  167.     { "paragraph",            LT_PARAGRAPH },
  168.     { "parindent",            LT_PARINDENT },
  169.     { "parsep",            LT_PARSEP },
  170.     { "parskip",            LT_PARSKIP },
  171.     { "plain",            LT_PLAIN },
  172.     { "preamble",                   LT_PREAMBLE },
  173.     { "right",            LT_RIGHT },
  174.     { "right_address_box",        LT_RIGHT_ADDRESS_BOX },
  175.     { "rightmargin",        LT_RIGHTMARGIN },
  176.     { "secnumdepth",                LT_SECNUMDEPTH },
  177.     { "sensitive",            LT_SENSITIVE },
  178.     { "sides",            LT_SIDES },
  179.     { "single",                     LT_SPACING_SINGLE },
  180.     { "spacing",                    LT_SPACING },
  181.     { "static",            LT_STATIC },
  182.     { "style",            LT_STYLE },
  183.     { "textfont",                   LT_TEXTFONT },
  184.     { "tocdepth",                   LT_TOCDEPTH },
  185.     { "top_environment",        LT_TOP_ENVIRONMENT },
  186.     { "topsep",            LT_TOPSEP }
  187. };
  188.  
  189.  
  190. /* ******************************************************************* */
  191.  
  192. // Constructor for layout
  193. LyXLayout::LyXLayout ()
  194. {
  195.     margintype = MARGIN_STATIC;
  196.     latextype = LATEX_PARAGRAPH;
  197.     intitle = false;
  198.     needprotect = false;
  199.     keepempty = false;
  200.     font = LyXFont(LyXFont::ALL_INHERIT);
  201.     labelfont = LyXFont(LyXFont::ALL_INHERIT);
  202.     resfont = LyXFont(LyXFont::ALL_SANE);
  203.     reslabelfont = LyXFont(LyXFont::ALL_SANE);
  204.     nextnoindent = false;
  205.     parskip = 0.0;
  206.     itemsep = 0;
  207.     topsep = 0.0;
  208.     bottomsep = 0.0;
  209.     labelbottomsep = 0.0;
  210.     parsep = 0;
  211.     align = LYX_ALIGN_BLOCK;
  212.     alignpossible = LYX_ALIGN_BLOCK;
  213.     labeltype = LABEL_NO_LABEL;
  214.     // Should or should not. That is the question.
  215.     // spacing.set(Spacing::OneHalf);
  216.     fill_top = false;
  217.     fill_bottom = false;
  218.     newline_allowed = true;
  219.     free_spacing = false;
  220. }
  221.  
  222.  
  223. LyXLayout::~LyXLayout ()
  224. {
  225. }
  226.  
  227.  
  228. void LyXLayout::Copy (LyXLayout const &l)
  229. {
  230.     name = l.name;
  231.     obsoleted_by = l.obsoleted_by;
  232.     margintype = l.margintype;
  233.     latextype = l.latextype;
  234.     intitle = l.intitle;
  235.     needprotect = l.needprotect;
  236.     keepempty = l.keepempty;
  237.     latexname = l.latexname;
  238.     latexparam = l.latexparam;   //arrae970411
  239.     preamble = l.preamble;
  240.     font = l.font;
  241.     labelfont = l.labelfont;
  242.     resfont = l.resfont;
  243.     reslabelfont = l.reslabelfont;
  244.     nextnoindent = l.nextnoindent;
  245.     leftmargin = l.leftmargin;
  246.     rightmargin = l.rightmargin;
  247.     labelsep = l.labelsep;
  248.     labelindent = l.labelindent;
  249.     parindent = l.parindent;
  250.     parskip = l.parskip;
  251.     itemsep = l.itemsep;
  252.     topsep = l.topsep;
  253.     bottomsep = l.bottomsep;
  254.     labelbottomsep = l.labelbottomsep;
  255.     parsep = l.parsep;
  256.     align = l.align;
  257.     alignpossible = l.alignpossible;
  258.     labeltype = l.labeltype;
  259.     spacing = l.spacing;
  260.     labelstring = l.labelstring;
  261.     fill_top = l.fill_top;
  262.     fill_bottom = l.fill_bottom;
  263.     newline_allowed = l.newline_allowed;
  264.     free_spacing = l.free_spacing;
  265. }
  266.  
  267.  
  268. /* Reads a layout definition from file */
  269. bool LyXLayout::Read (LyXLex & lexrc, LyXLayoutList * list)
  270. {
  271.     bool error = false;
  272.     bool finished = false;
  273.     
  274.     /* parse style section */
  275.     while (!finished && lexrc.IsOK() && !error) {
  276.         switch(lexrc.lex()) {
  277.  
  278.         case -2:
  279.             break;
  280.  
  281.         case -1:        /* parse error */
  282.             lexrc.printError("Unknown tag `$$Token'");
  283.             error = true;
  284.             break;
  285.  
  286.         case LT_END:        /* end of structure */
  287.             finished = true;
  288.             break;
  289.  
  290.         case LT_COPYSTYLE:     // initialize with a known style
  291.                 if (lexrc.next()) {
  292.                     LyXLayout * layout = list->GetLayout(lexrc.GetString());
  293.                 if (layout) {
  294.                     LString tmpname = name;
  295.                     Copy(*layout);
  296.                     name = tmpname;
  297.                 } else {
  298.                     lexrc.printError("Cannot copy unknown "
  299.                                                  "style `$$Token'");
  300.                 }
  301.             }
  302.             break;
  303.  
  304.         case LT_OBSOLETEDBY:     // replace with a known style
  305.                 if (lexrc.next()) {
  306.                     LyXLayout * layout = list->GetLayout(lexrc.GetString());
  307.                 if (layout) {
  308.                     LString tmpname = name;
  309.                     Copy(*layout);
  310.                     name = tmpname;
  311.                     if (obsoleted_by.empty())
  312.                         obsoleted_by = lexrc.GetString();
  313.                 } else {
  314.                     lexrc.printError("Cannot replace with" 
  315.                              " unknown style "
  316.                              "`$$Token'");
  317.                 }
  318.             }
  319.             break;
  320.  
  321.         case LT_MARGIN:        /* margin style definition */
  322.                
  323.             switch(lexrc.lex()) {
  324.             case LT_STATIC:
  325.                 margintype = MARGIN_STATIC;
  326.                 break;
  327.             case LT_MANUAL:
  328.                 margintype = MARGIN_MANUAL;
  329.                 break;
  330.             case LT_DYNAMIC:
  331.                 margintype = MARGIN_DYNAMIC;
  332.                 break;
  333.             case LT_FIRST_DYNAMIC:
  334.                 margintype = MARGIN_FIRST_DYNAMIC;
  335.                 break;
  336.             case LT_RIGHT_ADDRESS_BOX:
  337.                 margintype = MARGIN_RIGHT_ADDRESS_BOX;
  338.                 break;
  339.             default:
  340.                 lexrc.printError("Unknown margin type `$$Token'");
  341.                 break;
  342.             }
  343.             break;
  344.  
  345.         case LT_LATEXTYPE:    /* latex style definition */
  346.                 switch (lexrc.lex()) {
  347.             case LT_PARAGRAPH:
  348.                 latextype=LATEX_PARAGRAPH;
  349.                 break;
  350.             case LT_COMMAND:
  351.                 latextype=LATEX_COMMAND;
  352.                 break;
  353.             case LT_ENVIRONMENT:
  354.                 latextype=LATEX_ENVIRONMENT;
  355.                 break;
  356.             case LT_ITEM_ENVIRONMENT:
  357.                 latextype=LATEX_ITEM_ENVIRONMENT;
  358.                 break;
  359.             case LT_LIST_ENVIRONMENT:
  360.                 latextype=LATEX_LIST_ENVIRONMENT;
  361.                 break;
  362.             default:
  363.                 lexrc.printError("Unknown latextype `$$Token'");
  364.                 break;
  365.             }
  366.             break;
  367.  
  368.         case LT_INTITLE:
  369.             intitle = lexrc.next() && lexrc.GetInteger();
  370.             break;
  371.             
  372.         case LT_NEED_PROTECT:
  373.             needprotect = lexrc.next() && lexrc.GetInteger();
  374.             break;
  375.             
  376.         case LT_KEEPEMPTY:
  377.             keepempty = lexrc.next() && lexrc.GetInteger();
  378.             break;
  379.  
  380.         case LT_FONT:
  381.             font.lyxRead(lexrc);
  382.             labelfont=font;
  383.             break;
  384.  
  385.         case LT_TEXTFONT:
  386.             font.lyxRead(lexrc);
  387.             break;
  388.  
  389.         case LT_LABELFONT:
  390.             labelfont.lyxRead(lexrc);
  391.             break;
  392.  
  393.         case LT_NEXTNOINDENT:    /* indent next paragraph ? */
  394.             if (lexrc.next() && lexrc.GetInteger())
  395.                 nextnoindent = true;
  396.             else
  397.                 nextnoindent = false;
  398.             break;
  399.  
  400.         case LT_LATEXNAME:    /* latex name */
  401.                 if (lexrc.next())
  402.                         latexname = lexrc.GetString();
  403.             break;
  404.                         
  405.                 //arrae970411
  406.         case LT_LATEXPARAM:    /* latex parameter */
  407.             if (lexrc.next())
  408.                 latexparam = lexrc.GetString();
  409.             break;
  410.  
  411.         case LT_PREAMBLE:
  412.             preamble = lexrc.getLongString("EndPreamble");
  413.             break;
  414.  
  415.         case LT_LABELTYPE:    /* label type */
  416.                 switch (lexrc.lex()) {
  417.             case LT_NO_LABEL:
  418.                 labeltype = LABEL_NO_LABEL;
  419.                 break;
  420.             case LT_MANUAL:
  421.                 labeltype = LABEL_MANUAL;
  422.                 break;
  423.             case LT_TOP_ENVIRONMENT:
  424.                 labeltype = LABEL_TOP_ENVIRONMENT;
  425.                 break;
  426.             case LT_CENTERED_TOP_ENVIRONMENT:
  427.                 labeltype = LABEL_CENTERED_TOP_ENVIRONMENT;
  428.                 break;
  429.             case LT_STATIC:
  430.                 labeltype = LABEL_STATIC;
  431.                 break;
  432.             case LT_SENSITIVE:
  433.                 labeltype = LABEL_SENSITIVE;
  434.                 break;
  435.             case LT_COUNTER_CHAPTER:
  436.                 labeltype = LABEL_COUNTER_CHAPTER;
  437.                 break;
  438.             case LT_COUNTER_SECTION:
  439.                 labeltype = LABEL_COUNTER_SECTION;
  440.                 break;
  441.             case LT_COUNTER_SUBSECTION:
  442.                 labeltype = LABEL_COUNTER_SUBSECTION;
  443.                 break;
  444.             case LT_COUNTER_SUBSUBSECTION:
  445.                 labeltype = LABEL_COUNTER_SUBSUBSECTION;
  446.                 break;
  447.             case LT_COUNTER_PARAGRAPH:
  448.                 labeltype = LABEL_COUNTER_PARAGRAPH;
  449.                 break;
  450.             case LT_COUNTER_SUBPARAGRAPH:
  451.                 labeltype = LABEL_COUNTER_SUBPARAGRAPH;
  452.                 break;
  453.             case LT_COUNTER_ENUMI:
  454.                 labeltype = LABEL_COUNTER_ENUMI;
  455.                 break;
  456.             case LT_COUNTER_ENUMII:
  457.                 labeltype = LABEL_COUNTER_ENUMII;
  458.                 break;
  459.             case LT_COUNTER_ENUMIII:
  460.                 labeltype = LABEL_COUNTER_ENUMIII;
  461.                 break;
  462.             case LT_COUNTER_ENUMIV:
  463.                 labeltype = LABEL_COUNTER_ENUMIV;
  464.                 break;
  465.             case LT_BIBLIO:
  466.                 labeltype = LABEL_BIBLIO;
  467.                 break;
  468.             default:
  469.                 lexrc.printError("Unknown labeltype `$$Token'");
  470.             }
  471.             break;
  472.  
  473.         case LT_LEFTMARGIN:    /* left margin type */
  474.                 if (lexrc.next())
  475.                 leftmargin = lexrc.GetString();
  476.             break;            
  477.  
  478.         case LT_RIGHTMARGIN:    /* right margin type */
  479.             if (lexrc.next())
  480.                 rightmargin = lexrc.GetString();
  481.             break;
  482.  
  483.         case LT_LABELINDENT:    /* label indenting flag */
  484.             if (lexrc.next())
  485.                 labelindent = lexrc.GetString();
  486.             break;
  487.  
  488.         case LT_PARINDENT:    /* paragraph indent. flag */
  489.             if (lexrc.next())
  490.                 parindent = lexrc.GetString();
  491.             break;
  492.  
  493.         case LT_PARSKIP:    /* paragraph skip size */
  494.             if (lexrc.next())
  495.                 parskip = lexrc.GetFloat();
  496.             break;
  497.  
  498.         case LT_ITEMSEP:    /* item separation size */
  499.             if (lexrc.next())
  500.                 itemsep = lexrc.GetFloat();
  501.             break;
  502.  
  503.         case LT_TOPSEP:        /* top separation size */
  504.             if (lexrc.next())
  505.                 topsep = lexrc.GetFloat();
  506.             break;
  507.  
  508.         case LT_BOTTOMSEP:    /* bottom separation size */
  509.             if (lexrc.next())
  510.                 bottomsep = lexrc.GetFloat();
  511.             break;
  512.  
  513.         case LT_LABEL_BOTTOMSEP:/* label bottom separation size */
  514.             if (lexrc.next())
  515.                 labelbottomsep = lexrc.GetFloat();
  516.             break;
  517.  
  518.         case LT_LABELSEP:    /* label separator */
  519.             if (lexrc.next()) {
  520.                 labelsep = lexrc.GetString();
  521.                 labelsep.subst('x', ' ');
  522.             }
  523.             break;
  524.  
  525.         case LT_PARSEP:        /* par. separation size */
  526.             if (lexrc.next())
  527.                 parsep = lexrc.GetFloat();
  528.             break;
  529.  
  530.         case LT_FILL_TOP:    /* fill top flag */
  531.             if (lexrc.next())
  532.                 fill_top = lexrc.GetInteger();
  533.             break;
  534.  
  535.         case LT_FILL_BOTTOM:    /* fill bottom flag */
  536.             if (lexrc.next())
  537.                 fill_bottom = lexrc.GetInteger();
  538.             break;
  539.  
  540.         case LT_NEWLINE:    /* newlines allowed ? */
  541.             if (lexrc.next())
  542.                 newline_allowed = lexrc.GetInteger();
  543.             break;
  544.  
  545.         case LT_ALIGN:        /* paragraph align */
  546.             switch (lexrc.lex()) {
  547.             case LT_BLOCK:
  548.                 align = LYX_ALIGN_BLOCK;
  549.                 break;
  550.             case LT_LEFT:
  551.                 align = LYX_ALIGN_LEFT;
  552.                 break;
  553.             case LT_RIGHT:
  554.                 align = LYX_ALIGN_RIGHT;
  555.                 break;
  556.             case LT_CENTER:
  557.                 align = LYX_ALIGN_CENTER;
  558.                 break;
  559.             case LT_LAYOUT:
  560.                 align = LYX_ALIGN_LAYOUT;
  561.                 break;
  562.             default:
  563.                 lexrc.printError("Unknown alignment `$$Token'");
  564.             }
  565.             break;
  566.  
  567.         case LT_ALIGNPOSSIBLE:    /* paragraph allowed align */
  568.         {    alignpossible = 0;
  569.               
  570.         int lineno = lexrc.GetLineNo();
  571.         do {
  572.             switch (lexrc.lex()) {
  573.             case LT_BLOCK:
  574.                 alignpossible |= LYX_ALIGN_BLOCK;
  575.                 break;
  576.             case LT_LEFT:
  577.                 alignpossible |= LYX_ALIGN_LEFT;
  578.                 break;
  579.             case LT_RIGHT:
  580.                 alignpossible |= LYX_ALIGN_RIGHT;
  581.                 break;
  582.             case LT_CENTER:
  583.                 alignpossible |= LYX_ALIGN_CENTER;
  584.                 break;
  585.             case LT_LAYOUT:
  586.                 alignpossible |= LYX_ALIGN_LAYOUT;
  587.                 break;
  588.             default:
  589.                 lexrc.printError("Unknown alignment `$$Token'");
  590.  
  591.             }
  592.         } while (lineno==lexrc.GetLineNo());
  593.         break;
  594.         }
  595.  
  596.         case LT_LABELSTRING:    /* label string definition */
  597.             if (lexrc.next())
  598.                 labelstring = lexrc.GetString();
  599.             break;
  600.  
  601.         case LT_FREE_SPACING:    /* Allow for free spacing. */
  602.             if (lexrc.next())
  603.                 free_spacing = lexrc.GetInteger();
  604.             break;
  605.  
  606.         case LT_SPACING: // setspace.sty
  607.             switch(lexrc.lex()) {
  608.             case LT_SPACING_SINGLE:
  609.                 spacing.set(Spacing::Single);
  610.                 //spacing_value = 1.0;
  611.                 break;
  612.             case LT_SPACING_ONEHALF:
  613.                 spacing.set(Spacing::Onehalf);
  614.                 //spacing_value = 1.25;
  615.                 break;
  616.             case LT_SPACING_DOUBLE:
  617.                 spacing.set(Spacing::Double);
  618.                 //spacing_value = 1.667;
  619.                 break;
  620.             case LT_OTHER:
  621.                 lexrc.next();
  622.                 spacing.set(Spacing::Other, lexrc.GetFloat());
  623.                 break;
  624.             default:
  625.                 lexrc.printError("Unknown spacing `$$Token'");
  626.             }
  627.             break;
  628.         default:        /* context error */
  629.             lexrc.printError("Tag `$$Token' is not "
  630.                      "allowed in layout");
  631.             error = true;
  632.             break;
  633.         }
  634.     }
  635.  
  636.     return error;
  637. }
  638.  
  639. /* ******************************************************************* */
  640.  
  641. LyXLayoutList::LyXLayoutList()
  642. {
  643.     l = NULL;
  644.     eol = NULL;
  645.     num_layouts = 0;
  646. }
  647.  
  648.  
  649. LyXLayoutList::~LyXLayoutList()
  650. {
  651.     //don't do anything. the layouts will be extracted by ToAr.
  652.     //destruction is done by Clean in emergencies
  653. }
  654.  
  655.  
  656. int LyXLayoutList::GetNum ()
  657. {
  658.     return num_layouts;
  659. }
  660.  
  661.  
  662. void LyXLayoutList::Add (LyXLayout *lay)
  663. {
  664.     LyXLayoutL * tmp = new LyXLayoutL;
  665.     tmp->layout = lay;
  666.     tmp->next = NULL;
  667.     if (!eol) l = tmp; 
  668.     else eol->next = tmp;
  669.     eol = tmp;
  670.     num_layouts++;
  671. }
  672.  
  673.  
  674. bool LyXLayoutList::Delete (LString const &name)
  675. {
  676.     LyXLayoutL * layoutl = l;
  677.     while(layoutl) {
  678.           if (layoutl->layout && layoutl->layout->name == name) {
  679.             delete layoutl->layout;
  680.             layoutl->layout = NULL; // not sure it is necessary
  681.             num_layouts--;
  682.             return true;
  683.         }
  684.         layoutl = layoutl->next;
  685.     }
  686.     return false;
  687. }
  688.  
  689.  
  690. LyXLayout * LyXLayoutList::GetLayout (LString const &name)
  691. {
  692.     LyXLayoutL * layoutl = l;
  693.     while(layoutl) {
  694.           if (layoutl->layout && layoutl->layout->name == name) 
  695.             return layoutl->layout;
  696.         layoutl = layoutl->next;
  697.     }
  698.     return NULL;
  699. }
  700.  
  701.  
  702. LyXLayout * LyXLayoutList::ToAr ()
  703. {
  704.     LyXLayoutL * lp, * op;
  705.     int idx = 0;
  706.     LyXLayout* ar = new LyXLayout [num_layouts];
  707.     lp = l;
  708.     while (lp) {
  709.         if (lp->layout) {
  710.             ar[idx].Copy (*lp->layout);
  711.             idx++;
  712.             delete lp->layout;
  713.         }
  714.         op = lp;
  715.         lp = lp->next;
  716.         delete op;
  717.     }
  718.     return ar;
  719. }
  720.  
  721.  
  722. //wipe up any dead layouts
  723. void LyXLayoutList::Clean ()
  724. {
  725.     LyXLayoutL * lp, * op;
  726.     lp = l;
  727.     while (lp) {
  728.         delete lp->layout;
  729.         op = lp;
  730.         lp = lp->next;
  731.         delete op;
  732.     }
  733. }
  734.  
  735. /* ******************************************************************* */
  736.  
  737. LyXTextClass::LyXTextClass(LString const &fn, LString const &cln,
  738.                LString const &desc)
  739. {
  740.     name = fn;
  741.     latexname = cln;
  742.     description = desc;
  743.     style = NULL;
  744.     columns = 1;
  745.     sides = 1;
  746.     secnumdepth = 3;
  747.     tocdepth = 3;
  748.     pagestyle = "default";
  749.     maxcounter = LABEL_COUNTER_CHAPTER;
  750.     defaultfont = LyXFont(LyXFont::ALL_SANE);
  751.     number_of_defined_layouts = 0;
  752.     opt_fontsize = "10|11|12";
  753.     opt_pagestyle = "empty|plain|headings|fancy";
  754.     loaded = false;
  755. }
  756.  
  757.  
  758. // This is not a proper copy.
  759. // It just references the style rather than copying it!
  760. void LyXTextClass::Copy (LyXTextClass const &l)
  761. {
  762.     name = l.name;
  763.     latexname = l.latexname;
  764.     description = l.description;
  765.     preamble = l.preamble;
  766.     options = l.options;
  767.     if (style) delete style;
  768.     style = l.style; //just aliases NO COPY
  769.     number_of_defined_layouts = l.number_of_defined_layouts;
  770.     columns = l.columns;
  771.     sides = l.sides;
  772.     secnumdepth = l.secnumdepth;
  773.     tocdepth = l.tocdepth;
  774.     pagestyle = l.pagestyle;
  775.     maxcounter = l.maxcounter;
  776.     defaultfont = l.defaultfont;
  777.         opt_fontsize = l.opt_fontsize;
  778.         opt_pagestyle = l.opt_pagestyle;
  779.         loaded = l.loaded;
  780.  
  781.     leftmargin = l.leftmargin;
  782.     rightmargin = l.rightmargin;
  783.       
  784. }
  785.  
  786.  
  787. LyXTextClass::~LyXTextClass()
  788. {
  789.     //we can't delete the style here because otherwise 
  790.     //our list classes wouldn't work
  791. }
  792.  
  793.  
  794. /* Reads a textclass structure from file */
  795. int LyXTextClass::Read (LString const &filename, LyXLayoutList *list)
  796. {
  797.     if (!list)
  798.         lyxerr.debug("Reading textclass "
  799.                  + MakeDisplayPath(filename), Error::TCLASS);
  800.     else 
  801.         lyxerr.debug("Reading input file "
  802.                  + MakeDisplayPath(filename), Error::TCLASS);
  803.  
  804.     LyXLex lexrc(layoutTags, sizeof(layoutTags)/sizeof(keyword_item));
  805.     bool error = false;
  806.  
  807.         lexrc.setFile(filename);
  808.     if (!lexrc.IsOK()) return -2; 
  809.  
  810.     LyXLayoutList * l;
  811.     LyXLayout * tmpl;
  812.  
  813.     if (list) 
  814.         l = list;
  815.     else 
  816.         l = new LyXLayoutList;
  817.  
  818.     /* parsing */
  819.     while (lexrc.IsOK() && !error) {
  820.         switch(lexrc.lex()) {
  821.         case -2:
  822.             break;
  823.  
  824.         case -1:                                 
  825.             lexrc.printError("Unknown tag `$$Token'");
  826.             error = true;
  827.             break;
  828.             
  829.         case LT_INPUT: // Include file
  830.                 if (lexrc.next()) {
  831.                     LString tmp = LibFileSearch("layouts",
  832.                                 lexrc.GetString(), 
  833.                                 "layout");
  834.                 
  835.                 if (Read(tmp, l)) {
  836.                     lexrc.printError("Error reading input"
  837.                              "file: "+tmp);
  838.                     error = true;
  839.                 }
  840.             }
  841.             break;
  842.  
  843.         case LT_STYLE:
  844.             if (lexrc.next()) {
  845.                 LString name = lexrc.GetString();
  846.                 bool is_new = false;
  847.  
  848.                 name.subst('_',' ');
  849.                 tmpl = l->GetLayout(name);
  850.                 if (!tmpl) {
  851.                     is_new = true;
  852.                     tmpl = new LyXLayout;
  853.                     tmpl->name = name;
  854.                 }
  855.  
  856.                 lyxerr.debug("  Reading style "+tmpl->name, Error::TCLASS);
  857.  
  858.                 if (!tmpl->Read(lexrc, l)) {
  859.                     // Resolve fonts
  860.                     tmpl->resfont = tmpl->font;
  861.                     tmpl->resfont.realize(defaultfont);
  862.                     tmpl->reslabelfont = tmpl->labelfont;
  863.                     tmpl->reslabelfont.realize(defaultfont);
  864.                     if (is_new) {
  865.                         l->Add (tmpl);
  866.                         // NB! we don't delete because 
  867.                         // we just pass it in.... 
  868.                     }
  869.                 } else {
  870.                         lexrc.printError(
  871.                                    "Error parsing style `"
  872.                                +tmpl->name+'\'');
  873.                     error = true;
  874.                     if (is_new) {
  875.                         delete tmpl;  
  876.                         //we delete dead ones here
  877.                     }
  878.                 }
  879.             }
  880.             else {
  881.                 lexrc.printError("No name given for style: `$$Token'.");
  882.                 error = true;
  883.             }
  884.             break;
  885.  
  886.         case LT_NOSTYLE:
  887.             if (lexrc.next()) {
  888.                 LString style = lexrc.GetString();
  889.                 if (!l->Delete(style.subst('_', ' ')))
  890.                     lexrc.printError("Cannot delete style `$$Token'");
  891.             }
  892.             break;
  893.  
  894.         case LT_COLUMNS:
  895.             if (lexrc.next())
  896.                 columns = lexrc.GetInteger();
  897.             break;
  898.             
  899.         case LT_SIDES:
  900.             if (lexrc.next())
  901.                 sides = lexrc.GetInteger();
  902.             break;
  903.             
  904.         case LT_PAGESTYLE:
  905.                 lexrc.next();
  906.             pagestyle = lexrc.GetString();
  907.             pagestyle.strip();
  908.             break;
  909.             
  910.         case LT_DEFAULTFONT:
  911.             defaultfont.lyxRead(lexrc);
  912.             if (!defaultfont.resolved()) {
  913.                 lexrc.printError("Warning: defaultfont should "
  914.                          "be fully instantiated!");
  915.                 defaultfont.realize(LyXFont::ALL_SANE);
  916.             }
  917.             break;
  918.  
  919.         case LT_MAXCOUNTER:
  920.             switch (lexrc.lex()) {
  921.             case LT_COUNTER_CHAPTER:
  922.                 maxcounter = LABEL_COUNTER_CHAPTER;
  923.                 break;
  924.             case LT_COUNTER_SECTION:
  925.                 maxcounter = LABEL_COUNTER_SECTION;
  926.                 break;
  927.             case LT_COUNTER_SUBSECTION:
  928.                 maxcounter = LABEL_COUNTER_SUBSECTION;
  929.                 break;
  930.             case LT_COUNTER_SUBSUBSECTION:
  931.                 maxcounter = LABEL_COUNTER_SUBSUBSECTION;
  932.                 break;
  933.             case LT_COUNTER_PARAGRAPH:
  934.                 maxcounter = LABEL_COUNTER_PARAGRAPH;
  935.                 break;
  936.             case LT_COUNTER_SUBPARAGRAPH:
  937.                 maxcounter = LABEL_COUNTER_SUBPARAGRAPH;
  938.                 break;
  939.             case LT_COUNTER_ENUMI:
  940.                 maxcounter = LABEL_COUNTER_ENUMI;
  941.                 break;
  942.             case LT_COUNTER_ENUMII:
  943.                 maxcounter = LABEL_COUNTER_ENUMII;
  944.                 break;
  945.             case LT_COUNTER_ENUMIII:
  946.                 maxcounter = LABEL_COUNTER_ENUMIII;
  947.                 break;
  948.             case LT_COUNTER_ENUMIV:
  949.                 maxcounter = LABEL_COUNTER_ENUMIV;
  950.                 break;
  951.             }
  952.             break;
  953.  
  954.         case LT_SECNUMDEPTH:
  955.             lexrc.next();
  956.             secnumdepth = lexrc.GetInteger();
  957.             break;
  958.  
  959.         case LT_TOCDEPTH:
  960.             lexrc.next();
  961.             tocdepth = lexrc.GetInteger();
  962.             break;
  963.  
  964.      // First step to support options 
  965.             case LT_CLASSOPTIONS:
  966.             {
  967.                     bool getout = true;
  968.                     while (getout && lexrc.IsOK()) { 
  969.                 switch (lexrc.lex()) {
  970.                 case LT_FONTSIZE:
  971.                     lexrc.next();
  972.                     opt_fontsize = lexrc.GetString();
  973.                     opt_fontsize.strip();
  974.                     break;
  975.                 case LT_PAGESTYLE:
  976.                     lexrc.next();
  977.                     opt_pagestyle = lexrc.GetString(); 
  978.                     opt_pagestyle.strip();
  979.                     break;
  980.                 case LT_OTHER:
  981.                     lexrc.next();
  982.                     options = lexrc.GetString();
  983.                     break;
  984.                 case LT_END: getout = false; break;
  985.                 default:
  986.                     lexrc.printError("Out of context tag `$$Token'");
  987.                     break;
  988.                 }
  989.             }
  990.                 break;
  991.         }
  992.  
  993.         case LT_PREAMBLE:
  994.             preamble = lexrc.getLongString("EndPreamble");
  995.             break;
  996.  
  997.         case LT_LEFTMARGIN:    /* left margin type */
  998.                 if (lexrc.next())
  999.                 leftmargin = lexrc.GetString();
  1000.             break;            
  1001.  
  1002.         case LT_RIGHTMARGIN:    /* right margin type */
  1003.             if (lexrc.next())
  1004.                 rightmargin = lexrc.GetString();
  1005.             break;
  1006.  
  1007.         default:
  1008.             lexrc.printError("Out of context tag `$$Token'");
  1009.             break;
  1010.         }
  1011.     }    
  1012.  
  1013.     if (!list) { // we are at top level here.
  1014.         if (error) {
  1015.             number_of_defined_layouts = 0;
  1016.             l->Clean(); //wipe any we may have found
  1017.             delete l;
  1018.         }
  1019.         else {
  1020.             style = l->ToAr();
  1021.             number_of_defined_layouts = l->GetNum();
  1022.             delete l;
  1023.         }
  1024.         lyxerr.debug("Finished reading textclass " 
  1025.                  + MakeDisplayPath(filename), Error::TCLASS);
  1026.     }
  1027.     else
  1028.         lyxerr.debug("Finished reading input file " 
  1029.                  + MakeDisplayPath(filename), Error::TCLASS);
  1030.  
  1031.     return error;
  1032. }
  1033.  
  1034.  
  1035. // Load textclass info if not loaded yet
  1036. void LyXTextClass::load()
  1037. {
  1038.     if (loaded)
  1039.         return;
  1040.  
  1041.     // Read style-file
  1042.     LString real_file = LibFileSearch("layouts", name, "layout");
  1043.  
  1044.     if (Read(real_file)) {
  1045.         lyxerr.print("Error reading `"
  1046.                  + MakeDisplayPath(real_file) + '\'');
  1047.         lyxerr.print("(Check `" + name + "')");
  1048.         lyxerr.print("Check your installation and "
  1049.                  "try Options/Reconfigure...");
  1050.     }
  1051.     loaded = true;
  1052. }
  1053.  
  1054. /* ******************************************************************* */
  1055.  
  1056. LyXTextClassList::LyXTextClassList()
  1057. {
  1058.     l = 0;
  1059.     ar = 0;
  1060.     num_textclass = 0;
  1061. }
  1062.  
  1063.  
  1064. LyXTextClassList::~LyXTextClassList()
  1065. {
  1066.     // The textclass list is in ar.
  1067.     if (ar) {
  1068.         delete [] ar;
  1069.     }
  1070. }
  1071.  
  1072.  
  1073. // Gets textclass number from name
  1074. signed char LyXTextClassList::NumberOfClass(LString const &textclass) 
  1075. {
  1076.     int i = 0;
  1077.    
  1078.     while (i < num_textclass && textclass != ar[i].name)
  1079.         i++;
  1080.    
  1081.     if (i >= num_textclass)
  1082.         i = -1;
  1083.  
  1084.     return i;
  1085. }
  1086.  
  1087.  
  1088. // Gets layout structure from style number and textclass number
  1089. LyXLayout *LyXTextClassList::Style(char textclass, char layout) 
  1090. {
  1091.     ar[textclass].load();
  1092.  
  1093.     if (layout < ar[textclass].number_of_defined_layouts)
  1094.         return &ar[textclass].style[layout];
  1095.     else {
  1096.         return &ar[textclass].style[0];
  1097.     };
  1098. }
  1099.  
  1100.  
  1101. // Gets layout number from name and textclass number
  1102. char LyXTextClassList::NumberOfLayout(char textclass, LString const &name) 
  1103. {
  1104.     ar[textclass].load();
  1105.  
  1106.     int i = 0;
  1107.     while (i < ar[textclass].number_of_defined_layouts 
  1108.            && name != ar[textclass].style[i].name)
  1109.         i++;
  1110.  
  1111.     if (i >= ar[textclass].number_of_defined_layouts) {
  1112.         if (name == "dummy")
  1113.             i = LYX_DUMMY_LAYOUT;
  1114.         else
  1115.             // so that we can detect if the layout doesn't exist.
  1116.             i = -1; // not found
  1117.     } 
  1118.     return i;
  1119. }
  1120.  
  1121.  
  1122. // Gets a layout (style) name from layout number and textclass number
  1123. LString LyXTextClassList::NameOfLayout(char textclass, char layout) 
  1124. {
  1125.     ar[textclass].load();
  1126.  
  1127.     if (layout < ar[textclass].number_of_defined_layouts)
  1128.         return ar[textclass].style[layout].name;
  1129.     else if (layout == LYX_DUMMY_LAYOUT)
  1130.         return "dummy";
  1131.     else
  1132.         return "@@end@@";
  1133. }
  1134.  
  1135.  
  1136. // Gets a textclass name from number
  1137. LString LyXTextClassList::NameOfClass(char number) 
  1138. {
  1139.     if (num_textclass == 0) { 
  1140.         if (number == 0) return "dummy";
  1141.         else return "@@end@@";
  1142.     }
  1143.     if (number < num_textclass)
  1144.         return ar[number].name;
  1145.     else
  1146.         return "@@end@@";
  1147. }
  1148.  
  1149. // Gets a textclass latexname from number
  1150. LString LyXTextClassList::LatexnameOfClass(char number) 
  1151. {
  1152.     ar[number].load();
  1153.  
  1154.     if (num_textclass == 0) { 
  1155.         if (number == 0) return "dummy";
  1156.         else return "@@end@@";
  1157.     }
  1158.     if (number < num_textclass)
  1159.         return ar[number].latexname;
  1160.     else
  1161.         return "@@end@@";
  1162. }
  1163.  
  1164. // Gets a textclass description from number
  1165. LString LyXTextClassList::DescOfClass(char number) 
  1166. {
  1167.     if (num_textclass == 0) { 
  1168.         if (number == 0) return "dummy";
  1169.         else return "@@end@@";
  1170.     }
  1171.     if (number < num_textclass)
  1172.         return ar[number].description;
  1173.     else
  1174.         return "@@end@@";
  1175. }
  1176.  
  1177.  
  1178. // Gets a textclass structure from number
  1179. LyXTextClass * LyXTextClassList::TextClass(char textclass) 
  1180. {
  1181.     ar[textclass].load();
  1182.     if (textclass < num_textclass)
  1183.         return &ar[textclass];
  1184.     else
  1185.         return &ar[0];
  1186. }
  1187.  
  1188.  
  1189. void LyXTextClassList::Add (LyXTextClass *t)
  1190. {
  1191.     LyXTextClassL ** h = &l;
  1192.     char const *desc = t->description.c_str();
  1193.     while (*h && strcasecmp((*h)->textclass->description.c_str(),desc)<0)
  1194.         h = &((*h)->next);
  1195.     LyXTextClassL * tmp = new LyXTextClassL;
  1196.     tmp->textclass = t;
  1197.     tmp->next = *h;
  1198.     *h = tmp;
  1199.     num_textclass++;
  1200. }
  1201.  
  1202.  
  1203. void LyXTextClassList::ToAr ()
  1204. {
  1205.     LyXTextClassL * lp, *op;
  1206.     int idx = 0;
  1207.     ar = new LyXTextClass [num_textclass];
  1208.     lp = l;
  1209.     while (lp) {
  1210.         ar[idx].Copy (*lp->textclass);
  1211.         idx++;
  1212.         delete lp->textclass; // note we don't delete layouts
  1213.                       // here at all 
  1214.         op = lp;
  1215.         lp = lp->next;
  1216.         delete op;
  1217.     }
  1218. }
  1219.  
  1220.  
  1221. // Reads LyX textclass definitions according to textclass config file
  1222. bool LyXTextClassList::Read ()
  1223. {
  1224.     LyXLex lex(NULL, 0);
  1225.     LString real_file = LibFileSearch("", "textclass.lst");
  1226.     lyxerr.debug("Reading textclasses from "+real_file,Error::TCLASS);
  1227.  
  1228.     if (real_file.empty()) {
  1229.         lyxerr.print("LyXTextClassList::Read: unable to find "
  1230.                   "textclass file  `" +
  1231.                   MakeDisplayPath(real_file, 1000) + "'. Exiting.");
  1232.  
  1233.         WriteAlert(_("LyX wasn't able to find it's layout descriptions!"),
  1234.                _("Check that the file \"textclass.lst\""),
  1235.                _("is installed correctly. Sorry, has to exit :-("));
  1236.         return false;
  1237.         // This causes LyX to end... Not a desirable behaviour. Lgb
  1238.         // What do you propose? That the user gets a file dialog
  1239.         // and is allowed to hunt for the file? (Asger)
  1240.     }
  1241.  
  1242.     lex.setFile(real_file);
  1243.     
  1244.     if (!lex.IsOK()) {
  1245.         lyxerr.print("LyXTextClassList::Read: unable to open "
  1246.                   "textclass file  `" +
  1247.                   MakeDisplayPath(real_file, 1000) + '\'');
  1248.         lyxerr.print("Check your installation. LyX can't continue.");
  1249.          return false;
  1250.     }
  1251.     bool finished = false;
  1252.     LString fname, clname, desc;
  1253.     LyXTextClass * tmpl;
  1254.  
  1255.     // Parse config-file
  1256.     while (lex.IsOK() && !finished) {
  1257.         switch (lex.lex()) {
  1258.         case LyXLex::LEX_FEOF:
  1259.             finished = true;
  1260.             break;
  1261.         default:
  1262.             fname = lex.GetString();
  1263.             lyxerr.debug("Fname: " + fname, Error::TCLASS);
  1264.             if (lex.next()) {
  1265.                 clname = lex.GetString();
  1266.                 lyxerr.debug("Clname: " + clname,
  1267.                          Error::TCLASS);
  1268.                 if (lex.next()) {
  1269.                           desc = lex.GetString();
  1270.                           lyxerr.debug("Desc: " + desc,
  1271.                                Error::TCLASS);
  1272.                           // This code is run when we have
  1273.                           // fname, clname and desc
  1274.                           tmpl =new LyXTextClass(fname,
  1275.                                      clname,
  1276.                                      desc);
  1277.                           Add (tmpl);
  1278.                           if (lyxerr.
  1279.                           debugging(Error::TCLASS)) {
  1280.                                 tmpl->load();
  1281.                           }
  1282.                 }
  1283.             }
  1284.         }
  1285.     }
  1286.     
  1287.     if (num_textclass == 0)
  1288.         return false;
  1289.     else { 
  1290.         ToAr();
  1291.         return true;
  1292.     }
  1293. }
  1294.  
  1295. // Load textclass
  1296. /* Returns false if this fails */
  1297. bool LyXTextClassList::Load (char const textclass)
  1298. {
  1299.     bool result = 1;
  1300.     
  1301.     if (textclass < num_textclass) {
  1302.         ar[textclass].load();
  1303.         if (!ar[textclass].number_of_defined_layouts) {
  1304.             result = 0;
  1305.         }
  1306.     } else {
  1307.         result = 0;
  1308.     }
  1309.     return result;
  1310. }
  1311.