]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/Preamble.cpp
Compile fix after change 4b64aaf, replace missing constructor for C-string with docst...
[lyx.git] / src / tex2lyx / Preamble.cpp
index 613cbbb8c1e89c384462fd012c88f1257e0436f0..a52927f2a2b43812494dba4db4bad095682c0dc1 100644 (file)
@@ -185,9 +185,6 @@ const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb",
 "rotfloat", "splitidx", "setspace", "subscript", "textcomp", "tipa", "tipx",
 "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xunicode", 0};
 
-// used for the handling of \newindex
-int index_number = 0;
-
 // codes used to remove packages that are loaded automatically by LyX.
 // Syntax: package_beg_sep<name>package_mid_sep<package loading code>package_end_sep
 const char package_beg_sep = '\001';
@@ -460,7 +457,8 @@ string remove_braces(string const & value)
 
 
 Preamble::Preamble() : one_language(true), explicit_babel(false),
-       title_layout_found(false), h_font_cjk_set(false)
+       title_layout_found(false), index_number(0), h_font_cjk_set(false),
+       h_use_microtype(false)
 {
        //h_backgroundcolor;
        //h_boxbgcolor;
@@ -473,16 +471,22 @@ Preamble::Preamble() : one_language(true), explicit_babel(false),
        //h_float_placement;
        //h_fontcolor;
        h_fontencoding            = "default";
-       h_font_roman              = "default";
-       h_font_sans               = "default";
-       h_font_typewriter         = "default";
-       h_font_math               = "auto";
+       h_font_roman[0]           = "default";
+       h_font_roman[1]           = "default";
+       h_font_sans[0]            = "default";
+       h_font_sans[1]            = "default";
+       h_font_typewriter[0]      = "default";
+       h_font_typewriter[1]      = "default";
+       h_font_math[0]            = "auto";
+       h_font_math[1]            = "auto";
        h_font_default_family     = "default";
        h_use_non_tex_fonts       = false;
        h_font_sc                 = "false";
        h_font_osf                = "false";
-       h_font_sf_scale           = "100";
-       h_font_tt_scale           = "100";
+       h_font_sf_scale[0]        = "100";
+       h_font_sf_scale[1]        = "100";
+       h_font_tt_scale[0]        = "100";
+       h_font_tt_scale[1]        = "100";
        //h_font_cjk
        h_graphics                = "default";
        h_default_output_format   = "default";
@@ -530,6 +534,7 @@ Preamble::Preamble() : one_language(true), explicit_babel(false),
        h_secnumdepth             = "3";
        h_shortcut[0]             = "idx";
        h_spacing                 = "single";
+       h_save_transient_properties = "true";
        h_suppress_date           = "false";
        h_textclass               = "article";
        h_tocdepth                = "3";
@@ -539,6 +544,7 @@ Preamble::Preamble() : one_language(true), explicit_babel(false),
        h_use_geometry            = "false";
        h_use_default_options     = "false";
        h_use_hyperref            = "false";
+       h_use_microtype           = false;
        h_use_refstyle            = false;
        h_use_packages["amsmath"]    = "1";
        h_use_packages["amssymb"]    = "0";
@@ -668,7 +674,8 @@ void Preamble::handle_geometry(vector<string> & options)
 
 
 void Preamble::handle_package(Parser &p, string const & name,
-                              string const & opts, bool in_lyx_preamble)
+                              string const & opts, bool in_lyx_preamble,
+                              bool detectEncoding)
 {
        vector<string> options = split_options(opts);
        add_package(name, options);
@@ -684,25 +691,25 @@ void Preamble::handle_package(Parser &p, string const & name,
 
        // roman fonts
        if (is_known(name, known_roman_fonts))
-               h_font_roman = name;
+               h_font_roman[0] = name;
 
        if (name == "fourier") {
-               h_font_roman = "utopia";
+               h_font_roman[0] = "utopia";
                // when font uses real small capitals
                if (opts == "expert")
                        h_font_sc = "true";
        }
 
        if (name == "garamondx") {
-               h_font_roman = "garamondx";
+               h_font_roman[0] = "garamondx";
                if (opts == "osfI")
                        h_font_osf = "true";
        }
 
        if (name == "libertine") {
-               h_font_roman = "libertine";
+               h_font_roman[0] = "libertine";
                // this automatically invokes biolinum
-               h_font_sans = "biolinum";
+               h_font_sans[0] = "biolinum";
                if (opts == "osf")
                        h_font_osf = "true";
                else if (opts == "lining")
@@ -710,7 +717,7 @@ void Preamble::handle_package(Parser &p, string const & name,
        }
 
        if (name == "libertine-type1") {
-               h_font_roman = "libertine";
+               h_font_roman[0] = "libertine";
                // NOTE: contrary to libertine.sty, libertine-type1
                // does not automatically invoke biolinum
                if (opts == "lining")
@@ -721,11 +728,11 @@ void Preamble::handle_package(Parser &p, string const & name,
 
        if (name == "mathdesign") {
                if (opts.find("charter") != string::npos)
-                       h_font_roman = "md-charter";
+                       h_font_roman[0] = "md-charter";
                if (opts.find("garamond") != string::npos)
-                       h_font_roman = "md-garamond";
+                       h_font_roman[0] = "md-garamond";
                if (opts.find("utopia") != string::npos)
-                       h_font_roman = "md-utopia";
+                       h_font_roman[0] = "md-utopia";
                if (opts.find("expert") != string::npos) {
                        h_font_sc = "true";
                        h_font_osf = "true";
@@ -733,22 +740,22 @@ void Preamble::handle_package(Parser &p, string const & name,
        }
 
        else if (name == "mathpazo")
-               h_font_roman = "palatino";
+               h_font_roman[0] = "palatino";
 
        else if (name == "mathptmx")
-               h_font_roman = "times";
+               h_font_roman[0] = "times";
 
        // sansserif fonts
        if (is_known(name, known_sans_fonts)) {
-               h_font_sans = name;
+               h_font_sans[0] = name;
                if (options.size() >= 1) {
-                       if (scale_as_percentage(opts, h_font_sf_scale))
+                       if (scale_as_percentage(opts, h_font_sf_scale[0]))
                                options.clear();
                }
        }
 
        if (name == "biolinum-type1") {
-               h_font_sans = "biolinum";
+               h_font_sans[0] = "biolinum";
                // biolinum can have several options, e.g. [osf,scaled=0.97]
                string::size_type pos = opts.find("osf");
                if (pos != string::npos)
@@ -760,16 +767,16 @@ void Preamble::handle_package(Parser &p, string const & name,
                // fourier can be set as roman font _only_
                // fourier as typewriter is handled in handling of \ttdefault
                if (name != "fourier") {
-                       h_font_typewriter = name;
+                       h_font_typewriter[0] = name;
                        if (options.size() >= 1) {
-                               if (scale_as_percentage(opts, h_font_tt_scale))
+                               if (scale_as_percentage(opts, h_font_tt_scale[0]))
                                        options.clear();
                        }
                }
        }
 
        if (name == "libertineMono-type1") {
-               h_font_typewriter = "libertine-mono";
+               h_font_typewriter[0] = "libertine-mono";
        }
 
        // font uses old-style figure
@@ -778,33 +785,33 @@ void Preamble::handle_package(Parser &p, string const & name,
 
        // math fonts
        if (is_known(name, known_math_fonts))
-               h_font_math = name;
+               h_font_math[0] = name;
 
        if (name == "newtxmath") {
                if (opts.empty())
-                       h_font_math = "newtxmath";
+                       h_font_math[0] = "newtxmath";
                else if (opts == "garamondx")
-                       h_font_math = "garamondx-ntxm";
+                       h_font_math[0] = "garamondx-ntxm";
                else if (opts == "libertine")
-                       h_font_math = "libertine-ntxm";
+                       h_font_math[0] = "libertine-ntxm";
                else if (opts == "minion")
-                       h_font_math = "minion-ntxm";
+                       h_font_math[0] = "minion-ntxm";
        }
 
        if (name == "iwona")
                if (opts == "math")
-                       h_font_math = "iwona-math";
+                       h_font_math[0] = "iwona-math";
 
        if (name == "kurier")
                if (opts == "math")
-                       h_font_math = "kurier-math";
+                       h_font_math[0] = "kurier-math";
 
        // after the detection and handling of special cases, we can remove the
        // fonts, otherwise they would appear in the preamble, see bug #7856
        if (is_known(name, known_roman_fonts) || is_known(name, known_sans_fonts)
                ||      is_known(name, known_typewriter_fonts) || is_known(name, known_math_fonts))
                ;
-
+       //"On". See the enum Package in BufferParams.h if you thought that "2" should have been "42"
        else if (name == "amsmath" || name == "amssymb" || name == "cancel" ||
                 name == "esint" || name == "mhchem" || name == "mathdots" ||
                 name == "mathtools" || name == "stackrel" ||
@@ -905,9 +912,11 @@ void Preamble::handle_package(Parser &p, string const & name,
                        string const encoding = options.back();
                        Encoding const * const enc = encodings.fromLaTeXName(
                                encoding, Encoding::inputenc, true);
-                       if (!enc)
-                               cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl;
-                       else {
+                       if (!enc) {
+                               if (!detectEncoding)
+                                       cerr << "Unknown encoding " << encoding
+                                            << ". Ignoring." << std::endl;
+                       } else {
                                if (!enc->unsafe() && options.size() == 1 && one_language == true)
                                        h_inputencoding = enc->name();
                                p.setEncoding(enc->iconvName());
@@ -1006,6 +1015,13 @@ void Preamble::handle_package(Parser &p, string const & name,
                                h_options += ',' + join(options, ",");
                }
        }
+       else if (name == "microtype") {
+               //we internally support only microtype without params
+               if (options.empty())
+                       h_use_microtype = true;
+               else
+                       h_preamble << "\\usepackage[" << opts << "]{microtype}";
+       }
 
        else if (!in_lyx_preamble) {
                if (options.empty())
@@ -1022,7 +1038,7 @@ void Preamble::handle_package(Parser &p, string const & name,
        }
 
        // We need to do something with the options...
-       if (!options.empty())
+       if (!options.empty() && !detectEncoding)
                cerr << "Ignoring options '" << join(options, ",")
                     << "' of package " << name << '.' << endl;
 
@@ -1096,6 +1112,7 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
           << "\\lyxformat " << LYX_FORMAT << '\n'
           << "\\begin_document\n"
           << "\\begin_header\n"
+          << "\\save_transient_properties " << h_save_transient_properties << "\n"
           << "\\origin " << origin << "\n"
           << "\\textclass " << h_textclass << "\n";
        string const raw = subdoc ? empty_string() : h_preamble.str();
@@ -1138,19 +1155,24 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
           << "\\language_package " << h_language_package << "\n"
           << "\\inputencoding " << h_inputencoding << "\n"
           << "\\fontencoding " << h_fontencoding << "\n"
-          << "\\font_roman " << h_font_roman << "\n"
-          << "\\font_sans " << h_font_sans << "\n"
-          << "\\font_typewriter " << h_font_typewriter << "\n"
-          << "\\font_math " << h_font_math << "\n"
+          << "\\font_roman \"" << h_font_roman[0]
+          << "\" \"" << h_font_roman[1] << "\"\n"
+          << "\\font_sans \"" << h_font_sans[0] << "\" \"" << h_font_sans[1] << "\"\n"
+          << "\\font_typewriter \"" << h_font_typewriter[0]
+          << "\" \"" << h_font_typewriter[1] << "\"\n"
+          << "\\font_math \"" << h_font_math[0] << "\" \"" << h_font_math[1] << "\"\n"
           << "\\font_default_family " << h_font_default_family << "\n"
           << "\\use_non_tex_fonts " << (h_use_non_tex_fonts ? "true" : "false") << '\n'
           << "\\font_sc " << h_font_sc << "\n"
           << "\\font_osf " << h_font_osf << "\n"
-          << "\\font_sf_scale " << h_font_sf_scale << "\n"
-          << "\\font_tt_scale " << h_font_tt_scale << '\n';
+          << "\\font_sf_scale " << h_font_sf_scale[0]
+          << ' ' << h_font_sf_scale[1] << '\n'
+          << "\\font_tt_scale " << h_font_tt_scale[0]
+          << ' ' << h_font_tt_scale[1] << '\n';
        if (!h_font_cjk.empty())
                os << "\\font_cjk " << h_font_cjk << '\n';
-       os << "\\graphics " << h_graphics << '\n'
+       os << "\\use_microtype " << h_use_microtype << '\n'
+          << "\\graphics " << h_graphics << '\n'
           << "\\default_output_format " << h_default_output_format << "\n"
           << "\\output_sync " << h_output_sync << "\n";
        if (h_output_sync == "1")
@@ -1164,13 +1186,13 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
           << "\\use_hyperref " << h_use_hyperref << '\n';
        if (h_use_hyperref == "true") {
                if (!h_pdf_title.empty())
-                       os << "\\pdf_title \"" << h_pdf_title << "\"\n";
+                       os << "\\pdf_title " << Lexer::quoteString(h_pdf_title) << '\n';
                if (!h_pdf_author.empty())
-                       os << "\\pdf_author \"" << h_pdf_author << "\"\n";
+                       os << "\\pdf_author " << Lexer::quoteString(h_pdf_author) << '\n';
                if (!h_pdf_subject.empty())
-                       os << "\\pdf_subject \"" << h_pdf_subject << "\"\n";
+                       os << "\\pdf_subject " << Lexer::quoteString(h_pdf_subject) << '\n';
                if (!h_pdf_keywords.empty())
-                       os << "\\pdf_keywords \"" << h_pdf_keywords << "\"\n";
+                       os << "\\pdf_keywords " << Lexer::quoteString(h_pdf_keywords) << '\n';
                os << "\\pdf_bookmarks " << h_pdf_bookmarks << "\n"
                      "\\pdf_bookmarksnumbered " << h_pdf_bookmarksnumbered << "\n"
                      "\\pdf_bookmarksopen " << h_pdf_bookmarksopen << "\n"
@@ -1183,7 +1205,7 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
                if (!h_pdf_pagemode.empty())
                        os << "\\pdf_pagemode " << h_pdf_pagemode << '\n';
                if (!h_pdf_quoted_options.empty())
-                       os << "\\pdf_quoted_options \"" << h_pdf_quoted_options << "\"\n";
+                       os << "\\pdf_quoted_options " << Lexer::quoteString(h_pdf_quoted_options) << '\n';
        }
        os << "\\papersize " << h_papersize << "\n"
           << "\\use_geometry " << h_use_geometry << '\n';
@@ -1251,6 +1273,13 @@ void Preamble::parse(Parser & p, string const & forceclass,
 {
        // initialize fixed types
        special_columns_['D'] = 3;
+       parse(p, forceclass, false, tc);
+}
+
+
+void Preamble::parse(Parser & p, string const & forceclass,
+                     bool detectEncoding, TeX2LyXDocClass & tc)
+{
        bool is_full_document = false;
        bool is_lyx_file = false;
        bool in_lyx_preamble = false;
@@ -1266,11 +1295,19 @@ void Preamble::parse(Parser & p, string const & forceclass,
        }
        p.reset();
 
+       if (detectEncoding && !is_full_document)
+               return;
+
        while (is_full_document && p.good()) {
+               if (detectEncoding && h_inputencoding != "auto" &&
+                   h_inputencoding != "default")
+                       return;
+
                Token const & t = p.get_token();
 
 #ifdef FILEDEBUG
-               cerr << "t: " << t << "\n";
+               if (!detectEncoding)
+                       cerr << "t: " << t << '\n';
 #endif
 
                //
@@ -1305,7 +1342,8 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        if (comment.size() > magicXeLaTeX.size()
                                  && comment.substr(0, magicXeLaTeX.size()) == magicXeLaTeX
                                  && h_inputencoding == "auto") {
-                               cerr << "XeLaTeX comment found, switching to UTF8\n";
+                               if (!detectEncoding)
+                                       cerr << "XeLaTeX comment found, switching to UTF8\n";
                                h_inputencoding = "utf8";
                        }
                        smatch sub;
@@ -1357,7 +1395,7 @@ void Preamble::parse(Parser & p, string const & forceclass,
                else if (t.cs() == "setmainfont") {
                        // we don't care about the option
                        p.hasOpt() ? p.getOpt() : string();
-                       h_font_roman = p.getArg('{', '}');
+                       h_font_roman[1] = p.getArg('{', '}');
                }
 
                else if (t.cs() == "setsansfont" || t.cs() == "setmonofont") {
@@ -1377,12 +1415,12 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        }
                        if (t.cs() == "setsansfont") {
                                if (!scale.empty())
-                                       h_font_sf_scale = scale;
-                               h_font_sans = p.getArg('{', '}');
+                                       h_font_sf_scale[1] = scale;
+                               h_font_sans[1] = p.getArg('{', '}');
                        } else {
                                if (!scale.empty())
-                                       h_font_tt_scale = scale;
-                               h_font_typewriter = p.getArg('{', '}');
+                                       h_font_tt_scale[1] = scale;
+                               h_font_typewriter[1] = p.getArg('{', '}');
                        }
                }
 
@@ -1401,9 +1439,9 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        // check the case that a standard color is used
                        if (space.empty() && is_known(argument, known_basic_colors)) {
                                h_fontcolor = rgbcolor2code(argument);
-                               preamble.registerAutomaticallyLoadedPackage("color");
+                               registerAutomaticallyLoadedPackage("color");
                        } else if (space.empty() && argument == "document_fontcolor")
-                               preamble.registerAutomaticallyLoadedPackage("color");
+                               registerAutomaticallyLoadedPackage("color");
                        // check the case that LyX's document_fontcolor is defined
                        // but not used for \color
                        else {
@@ -1423,7 +1461,7 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        if (is_known(argument, known_basic_colors)) {
                                h_backgroundcolor = rgbcolor2code(argument);
                        } else if (argument == "page_backgroundcolor")
-                               preamble.registerAutomaticallyLoadedPackage("color");
+                               registerAutomaticallyLoadedPackage("color");
                        // check the case that LyX's page_backgroundcolor is defined
                        // but not used for \pagecolor
                        else {
@@ -1528,19 +1566,19 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        // font settings
                        if (name == "\\rmdefault")
                                if (is_known(body, known_roman_fonts)) {
-                                       h_font_roman = body;
+                                       h_font_roman[0] = body;
                                        p.skip_spaces();
                                        in_lyx_preamble = true;
                                }
                        if (name == "\\sfdefault")
                                if (is_known(body, known_sans_fonts)) {
-                                       h_font_sans = body;
+                                       h_font_sans[0] = body;
                                        p.skip_spaces();
                                        in_lyx_preamble = true;
                                }
                        if (name == "\\ttdefault")
                                if (is_known(body, known_typewriter_fonts)) {
-                                       h_font_typewriter = body;
+                                       h_font_typewriter[0] = body;
                                        p.skip_spaces();
                                        in_lyx_preamble = true;
                                }
@@ -1552,9 +1590,12 @@ void Preamble::parse(Parser & p, string const & forceclass,
                                in_lyx_preamble = true;
                        }
 
-                       // remove the lyxdot definition that is re-added by LyX
+                       // remove LyX-specific definitions that are re-added by LyX
                        // if necessary
-                       if (name == "\\lyxdot") {
+                       // \lyxline is an ancient command that is converted by tex2lyx into
+                       // a \rule therefore remove its preamble code
+                       if (name == "\\lyxdot" || name == "\\lyxarrow"
+                           || name == "\\lyxline" || name == "\\LyX") {
                                p.skip_spaces();
                                in_lyx_preamble = true;
                        }
@@ -1645,16 +1686,18 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        vector<string>::const_iterator end = vecnames.end();
                        for (; it != end; ++it)
                                handle_package(p, trimSpaceAndEol(*it), options,
-                                              in_lyx_preamble);
+                                              in_lyx_preamble, detectEncoding);
                }
 
                else if (t.cs() == "inputencoding") {
                        string const encoding = p.getArg('{','}');
                        Encoding const * const enc = encodings.fromLaTeXName(
                                encoding, Encoding::inputenc, true);
-                       if (!enc)
-                               cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl;
-                       else {
+                       if (!enc) {
+                               if (!detectEncoding)
+                                       cerr << "Unknown encoding " << encoding
+                                            << ". Ignoring." << std::endl;
+                       } else {
                                if (!enc->unsafe())
                                        h_inputencoding = enc->name();
                                p.setEncoding(enc->iconvName());
@@ -1684,13 +1727,13 @@ void Preamble::parse(Parser & p, string const & forceclass,
                        string const body = p.verbatim_item();
                        string const opt3 = p.getFullOpt();
 
-                       add_known_theorem(name, opt1, !opt2.empty(),
-                               from_utf8("\\newtheorem{" + name + '}' +
-                                         opt1 + opt2 + '{' + body + '}' + opt3));
+                       string const complete = "\\newtheorem{" + name + '}' +
+                                         opt1 + opt2 + '{' + body + '}' + opt3;
+
+                       add_known_theorem(name, opt1, !opt2.empty(), from_utf8(complete));
 
                        if (!in_lyx_preamble)
-                               h_preamble << "\\newtheorem{" << name << '}'
-                                          << opt1 << opt2 << '{' << '}' << opt3;
+                               h_preamble << complete;
                }
 
                else if (t.cs() == "def") {
@@ -1937,6 +1980,16 @@ void Preamble::parse(Parser & p, string const & forceclass,
 }
 
 
+string Preamble::parseEncoding(Parser & p, string const & forceclass)
+{
+       TeX2LyXDocClass dummy;
+       parse(p, forceclass, true, dummy);
+       if (h_inputencoding != "auto" && h_inputencoding != "default")
+               return h_inputencoding;
+       return "";
+}
+
+
 string babel2lyx(string const & language)
 {
        char const * const * where = is_known(language, known_languages);