]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/Preamble.cpp
fix parsing of \def macros (was broken with the spreadsheet template support)
[lyx.git] / src / tex2lyx / Preamble.cpp
index f084ad33a3dd2ae3e7215613a5fb3d89a0b1337f..066da83c809d080628827e037ad1a6f731f3b63f 100644 (file)
@@ -165,6 +165,11 @@ const char * const known_basic_color_codes[] = {"#0000ff", "#000000", "#00ffff",
 const char * const known_if_3arg_commands[] = {"@ifundefined", "IfFileExists",
 0};
 
+/// packages that work only in xetex
+const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
+"fontbook", "fontwrap", "mathspec", "philokalia", "polyglossia", "unisugar",
+"xeCJK", "xecolor", "xecyr", "xeindex", "xepersian", "xunicode", 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';
@@ -313,6 +318,28 @@ void Preamble::suppressDate(bool suppress)
 }
 
 
+void Preamble::registerAuthor(std::string const & name)
+{
+       Author author(from_utf8(name), empty_docstring());
+       author.setUsed(true);
+       authors_.record(author);
+       h_tracking_changes = "true";
+       h_output_changes = "true";
+}
+
+
+Author const & Preamble::getAuthor(std::string const & name) const
+{
+       Author author(from_utf8(name), empty_docstring());
+       for (AuthorList::Authors::const_iterator it = authors_.begin();
+            it != authors_.end(); it++)
+               if (*it == author)
+                       return *it;
+       static Author const dummy;
+       return dummy;
+}
+
+
 void Preamble::add_package(string const & name, vector<string> & options)
 {
        // every package inherits the global options
@@ -421,6 +448,7 @@ Preamble::Preamble() : one_language(true)
        h_tocdepth                = "3";
        h_tracking_changes        = "false";
        h_use_bibtopic            = "false";
+       h_use_indices             = "false";
        h_use_geometry            = "false";
        h_use_amsmath             = "1";
        h_use_default_options     = "false";
@@ -517,6 +545,36 @@ void Preamble::handle_hyperref(vector<string> & options)
 }
 
 
+void Preamble::handle_geometry(vector<string> & options)
+{
+       h_use_geometry = "true";
+       vector<string>::iterator it;
+       // paper orientation
+       if ((it = find(options.begin(), options.end(), "landscape")) != options.end()) {
+               h_paperorientation = "landscape";
+               options.erase(it);
+       }
+       // paper size
+       // keyval version: "paper=letter"
+       string paper = process_keyval_opt(options, "paper");
+       if (!paper.empty())
+               h_papersize = paper + "paper";
+       // alternative version: "letterpaper"
+       handle_opt(options, known_paper_sizes, h_papersize);
+       delete_opt(options, known_paper_sizes);
+       // page margins
+       char const * const * margin = known_paper_margins;
+       for (; *margin; ++margin) {
+               string value = process_keyval_opt(options, *margin);
+               if (!value.empty()) {
+                       int k = margin - known_paper_margins;
+                       string name = known_coded_paper_margins[k];
+                       h_margins += '\\' + name + ' ' + value + '\n';
+               }
+       }
+}
+
+
 void Preamble::handle_package(Parser &p, string const & name,
                               string const & opts, bool in_lyx_preamble)
 {
@@ -524,6 +582,9 @@ void Preamble::handle_package(Parser &p, string const & name,
        add_package(name, options);
        string scale;
 
+       if (is_known(name, known_xetex_packages))
+               xetex = true;
+
        // roman fonts
        if (is_known(name, known_roman_fonts)) {
                h_font_roman = name;
@@ -645,32 +706,33 @@ void Preamble::handle_package(Parser &p, string const & name,
        else if (is_known(name, known_old_language_packages)) {
                // known language packages from the times before babel
                // if they are found and not also babel, they will be used as
-               // cutom language package
+               // custom language package
                h_language_package = "\\usepackage{" + name + "}";
        }
 
-       else if (name == "makeidx")
-               ; // ignore this
-
        else if (name == "prettyref")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "varioref")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "verbatim")
-               ; // ignore this
-
-       else if (name == "nomencl")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "textcomp")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
-       else if (name == "url")
-               ; // ignore this
+       else if (name == "lyxskak") {
+               // ignore this and its options
+               if (!options.empty())
+                       options.clear();
+       }
 
-       else if (name == "color" || name == "subscript" || name == "ulem") {
+       else if (name == "array" || name == "booktabs" || name == "float" ||
+                name == "color" || name == "hhline" || name == "longtable" ||
+                name == "makeidx" || name == "nomencl" || name == "splitidx" ||
+                name == "setspace" || name == "subscript" || name == "ulem" ||
+                name == "url") {
                if (!in_lyx_preamble)
                        h_preamble << package_beg_sep << name
                                   << package_mid_sep << "\\usepackage{"
@@ -678,23 +740,19 @@ void Preamble::handle_package(Parser &p, string const & name,
        }
 
        else if (name == "graphicx")
-               ; // ignore this
-
-       else if (name == "setspace")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "geometry")
-               ; // Ignore this, the geometry settings are made by the \geometry
-                 // command. This command is handled below.
+               handle_geometry(options);
 
        else if (name == "rotfloat")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "wrapfig")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (name == "subfig")
-               ; // ignore this
+               ; // ignore this FIXME: Use the package separator mechanism instead
 
        else if (is_known(name, known_languages))
                h_language = name;
@@ -757,7 +815,7 @@ void Preamble::handle_if(Parser & p, bool in_lyx_preamble)
 }
 
 
-bool Preamble::writeLyXHeader(ostream & os)
+bool Preamble::writeLyXHeader(ostream & os, bool subdoc)
 {
        // translate from babel to LyX names
        h_language = babel2lyx(h_language);
@@ -789,13 +847,18 @@ bool Preamble::writeLyXHeader(ostream & os)
        else if (is_known(h_language, known_english_quotes_languages))
                h_quotes_language = "english";
 
+       if (contains(h_float_placement, "H"))
+               registerAutomaticallyLoadedPackage("float");
+       if (h_spacing != "single" && h_spacing != "default")
+               registerAutomaticallyLoadedPackage("setspace");
+
        // output the LyX file settings
        os << "#LyX file created by tex2lyx " << PACKAGE_VERSION << "\n"
           << "\\lyxformat " << LYX_FORMAT << '\n'
           << "\\begin_document\n"
           << "\\begin_header\n"
           << "\\textclass " << h_textclass << "\n";
-       string const raw = h_preamble.str();
+       string const raw = subdoc ? empty_string() : h_preamble.str();
        if (!raw.empty()) {
                os << "\\begin_preamble\n";
                for (string::size_type i = 0; i < raw.size(); ++i) {
@@ -880,6 +943,7 @@ bool Preamble::writeLyXHeader(ostream & os)
           << "\\use_undertilde " << h_use_undertilde << "\n"
           << "\\cite_engine " << h_cite_engine << "\n"
           << "\\use_bibtopic " << h_use_bibtopic << "\n"
+          << "\\use_indices " << h_use_indices << "\n"
           << "\\paperorientation " << h_paperorientation << '\n'
           << "\\suppress_date " << h_suppress_date << '\n'
           << "\\use_refstyle " << h_use_refstyle << '\n';
@@ -910,10 +974,9 @@ bool Preamble::writeLyXHeader(ostream & os)
           << "\\html_math_output " << h_html_math_output << "\n"
           << "\\html_css_as_file " << h_html_css_as_file << "\n"
           << "\\html_be_strict " << h_html_be_strict << "\n"
+          << authors_
           << "\\end_header\n\n"
           << "\\begin_body\n";
-       // clear preamble for subdocuments
-       h_preamble.str("");
        return true;
 }
 
@@ -1003,17 +1066,22 @@ void Preamble::parse(Parser & p, string const & forceclass,
                }
 
                else if (t.cs() == "color") {
+                       string const space =
+                               (p.hasOpt() ? p.getOpt() : string());
                        string argument = p.getArg('{', '}');
                        // check the case that a standard color is used
-                       if (is_known(argument, known_basic_colors)) {
+                       if (space.empty() && is_known(argument, known_basic_colors)) {
                                h_fontcolor = rgbcolor2code(argument);
                                preamble.registerAutomaticallyLoadedPackage("color");
-                       } else if (argument == "document_fontcolor")
+                       } else if (space.empty() && argument == "document_fontcolor")
                                preamble.registerAutomaticallyLoadedPackage("color");
                        // check the case that LyX's document_fontcolor is defined
                        // but not used for \color
                        else {
-                               h_preamble << t.asInput() << '{' << argument << '}';
+                               h_preamble << t.asInput();
+                               if (!space.empty())
+                                       h_preamble << space;
+                               h_preamble << '{' << argument << '}';
                                // the color might already be set because \definecolor
                                // is parsed before this
                                h_fontcolor = "";
@@ -1079,6 +1147,11 @@ void Preamble::parse(Parser & p, string const & forceclass,
                                h_font_default_family = family.erase(0,1);
                        }
 
+                       // remove the lyxdot definition that is re-added by LyX
+                       // if necessary
+                       if (name == "\\lyxdot")
+                               in_lyx_preamble = true;
+
                        // Add the command to the known commands
                        add_known_command(name, opt1, !opt2.empty(), from_utf8(body));
 
@@ -1142,7 +1215,7 @@ void Preamble::parse(Parser & p, string const & forceclass,
                                opts.erase(it);
                        }
                        // paper sizes
-                       // some size options are know to any document classes, other sizes
+                       // some size options are known to any document classes, other sizes
                        // are handled by the \geometry command of the geometry package
                        handle_opt(opts, known_class_paper_sizes, h_papersize);
                        delete_opt(opts, known_class_paper_sizes);
@@ -1262,32 +1335,8 @@ void Preamble::parse(Parser & p, string const & forceclass,
                }
 
                else if (t.cs() == "geometry") {
-                       h_use_geometry = "true";
                        vector<string> opts = split_options(p.getArg('{', '}'));
-                       vector<string>::iterator it;
-                       // paper orientation
-                       if ((it = find(opts.begin(), opts.end(), "landscape")) != opts.end()) {
-                               h_paperorientation = "landscape";
-                               opts.erase(it);
-                       }
-                       // paper size
-                       handle_opt(opts, known_paper_sizes, h_papersize);
-                       delete_opt(opts, known_paper_sizes);
-                       // page margins
-                       char const * const * margin = known_paper_margins;
-                       int k = -1;
-                       for (; *margin; ++margin) {
-                               k += 1;
-                               // search for the "=" in e.g. "lmargin=2cm" to get the value
-                               for(size_t i = 0; i != opts.size(); i++) {
-                                       if (opts.at(i).find(*margin) != string::npos) {
-                                               string::size_type pos = opts.at(i).find("=");
-                                               string value = opts.at(i).substr(pos + 1);
-                                               string name = known_coded_paper_margins[k];
-                                               h_margins += "\\" + name + " " + value + "\n";
-                                       }
-                               }
-                       }
+                       handle_geometry(opts);
                }
 
                else if (t.cs() == "definecolor") {