]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/text.cpp
InsetParamsDialog: fix Restore button enabling/disabling.
[lyx.git] / src / tex2lyx / text.cpp
index 76d14513d6f1ff10990506df1fb84459bbbefd23..4f5b60e6092292b0f6053ca9d451cc961591f5e9 100644 (file)
@@ -90,14 +90,11 @@ string parse_text_snippet(Parser & p, unsigned flags, const bool outer,
 }
 
 
-char const * const known_latex_commands[] = { "ref", "cite", "label",
- "index", "printindex", "pageref", "url", "vref", "vpageref", "prettyref",
- "eqref", 0 };
+char const * const known_ref_commands[] = { "ref", "pageref", "vref",
+ "vpageref", "prettyref", "eqref", 0 };
 
 /*!
  * natbib commands.
- * We can't put these into known_latex_commands because the argument order
- * is reversed in lyx if there are 2 arguments.
  * The starred forms are also known.
  */
 char const * const known_natbib_commands[] = { "cite", "citet", "citep",
@@ -106,8 +103,6 @@ char const * const known_natbib_commands[] = { "cite", "citet", "citep",
 
 /*!
  * jurabib commands.
- * We can't put these into known_latex_commands because the argument order
- * is reversed in lyx if there are 2 arguments.
  * No starred form other than "cite*" known.
  */
 char const * const known_jurabib_commands[] = { "cite", "citet", "citep",
@@ -257,7 +252,7 @@ bool splitLatexLength(string const & len, string & value, string & unit)
 }
 
 
-/// A simple function to translate a latex length to something lyx can
+/// A simple function to translate a latex length to something LyX can
 /// understand. Not perfect, but rather best-effort.
 bool translate_len(string const & length, string & valstring, string & unit)
 {
@@ -359,6 +354,14 @@ void begin_inset(ostream & os, string const & name)
        os << "\n\\begin_inset " << name;
 }
 
+/*// use this void when format 288 is supported
+void begin_command_inset(ostream & os, string const & name,
+                                                string const & latexname)
+{
+       os << "\n\\begin_inset CommandInset " << name;
+       os << "\nLatexCommand " << latexname << "\n";
+}*/
+
 
 void end_inset(ostream & os)
 {
@@ -436,20 +439,6 @@ Layout const * findLayout(TextClass const & textclass, string const & name)
 void eat_whitespace(Parser &, ostream &, Context &, bool);
 
 
-Layout * captionlayout()
-{
-       static Layout * lay = 0;
-       if (!lay) {
-               lay = new Layout;
-               lay->name_ = from_ascii("Caption");
-               lay->latexname_ = "caption";
-               lay->latextype = LATEX_COMMAND;
-               lay->optionalargs = 1;
-       }
-       return lay;
-}
-
-
 void output_command_layout(ostream & os, Parser & p, bool outer,
                           Context & parent_context,
                           Layout const * newlayout)
@@ -465,17 +454,37 @@ void output_command_layout(ostream & os, Parser & p, bool outer,
        }
        context.check_deeper(os);
        context.check_layout(os);
-       if (context.layout->optionalargs > 0) {
+       unsigned int optargs = 0;
+       while (optargs < context.layout->optargs) {
                eat_whitespace(p, os, context, false);
-               if (p.next_token().character() == '[') {
-                       p.get_token(); // eat '['
-                       begin_inset(os, "OptArg\n");
-                       os << "status collapsed\n\n";
-                       parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
-                       end_inset(os);
-                       eat_whitespace(p, os, context, false);
-               }
+               if (p.next_token().character() != '[') 
+                       break;
+               p.get_token(); // eat '['
+               begin_inset(os, "OptArg\n");
+               os << "status collapsed\n\n";
+               parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
+               end_inset(os);
+               eat_whitespace(p, os, context, false);
+               optargs++;
        }
+#if 0
+       // This is the code needed to parse required arguments, but 
+       // required arguments come into being only much later than the
+       // file format tex2lyx is presently outputting.
+       unsigned int reqargs = 0;
+       while (reqargs < context.layout->reqargs) {
+               eat_whitespace(p, os, context, false);
+               if (p.next_token().character() != '{') 
+                       break;
+               p.get_token(); // eat '{'
+               begin_inset(os, "OptArg\n");
+               os << "status collapsed\n\n";
+               parse_text_in_inset(p, os, FLAG_BRACE_LAST, outer, context);
+               end_inset(os);
+               eat_whitespace(p, os, context, false);
+               reqargs++;
+       }
+#endif
        parse_text(p, os, FLAG_ITEM, outer, context);
        context.check_end_layout(os);
        if (parent_context.deeper_paragraph) {
@@ -656,7 +665,7 @@ void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
                parse_text_in_inset(p, os, flags, outer, parent_context);
                end_inset(os);
 #ifdef PRESERVE_LAYOUT
-               // lyx puts a % after the end of the minipage
+               // LyX puts a % after the end of the minipage
                if (p.next_token().cat() == catNewline && p.next_token().cs().size() > 1) {
                        // new paragraph
                        //handle_comment(os, "%dummy", parent_context);
@@ -1049,11 +1058,10 @@ string const normalize_filename(string const & name)
 /// convention (relative to .lyx file) if it is relative
 void fix_relative_filename(string & name)
 {
-       FileName fname(name);
-       if (fname.isAbsolute())
+       if (FileName::isAbsolute(name))
                return;
 
-       name = to_utf8(makeRelPath(from_utf8(makeAbsPath(name, getMasterFilePath()).absFilename()),
+       name = to_utf8(makeRelPath(from_utf8(makeAbsPath(name, getMasterFilePath()).absFileName()),
                                   from_utf8(getParentFilePath())));
 }
 
@@ -1133,8 +1141,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                Context & context)
 {
        Layout const * newlayout = 0;
-       // store the current selectlanguage to be used after \foreignlanguage
-       string selectlang;
        // Store the latest bibliographystyle (needed for bibtex inset)
        string bibliographystyle;
        bool const use_natbib = used_packages.find("natbib") != used_packages.end();
@@ -1164,6 +1170,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
 
                if (t.character() == ']' && (flags & FLAG_BRACK_LAST))
                        return;
+               if (t.character() == '}' && (flags & FLAG_BRACE_LAST))
+                       return;
 
                //
                // cat codes
@@ -1446,7 +1454,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        }
                        if (optarg) {
                                if (context.layout->labeltype != LABEL_MANUAL) {
-                                       // lyx does not support \item[\mybullet]
+                                       // LyX does not support \item[\mybullet]
                                        // in itemize environments
                                        handle_ert(os, "[", context);
                                        os << s;
@@ -1463,9 +1471,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                else if (t.cs() == "bibitem") {
                        context.set_item();
                        context.check_layout(os);
-                       os << "\\bibitem ";
-                       os << p.getOpt();
-                       os << '{' << p.verbatim_item() << '}' << "\n";
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       os << "label \"" << p.getOptContent() << "\"\n";
+                       os << "key \"" << p.verbatim_item() << "\"\n";
+                       end_inset(os);
                }
 
                else if (t.cs() == "def") {
@@ -1494,9 +1504,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                                else
                                                        simple = false;
                                        } else
-                                               paramtext += p.get_token().asString();
+                                               paramtext += p.get_token().cs();
                                } else {
-                                       paramtext += p.get_token().asString();
+                                       paramtext += p.get_token().cs();
                                        simple = false;
                                }
                        }
@@ -1582,13 +1592,33 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        p.skip_spaces();
                }
 
-               // Special handling for \caption
-               // FIXME: remove this when InsetCaption is supported.
-               else if (context.new_layout_allowed &&
-                        t.cs() == captionlayout()->latexname()) {
-                       output_command_layout(os, p, outer, context, 
-                                             captionlayout());
+               else if (t.cs() == "caption") {
+                       // FIXME: this should get some cleanup. All
+                       // the \begin_layout:s are output by the
+                       // Context class!
+                       p.skip_spaces();
+                       context.check_layout(os);
+                       p.skip_spaces();
+                       begin_inset(os, "Caption\n\n");
+                       os << "\\begin_layout " 
+                          << to_utf8(context.textclass.defaultLayout().name()) 
+                          << '\n';
+                       if (p.next_token().character() == '[') {
+                               p.get_token(); // eat '['
+                               begin_inset(os, "OptArg\n");
+                               os << "status collapsed\n";
+                               parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
+                               end_inset(os);
+                               eat_whitespace(p, os, context, false);
+                       }
+                       parse_text(p, os, FLAG_ITEM, outer, context);
+                       context.check_end_layout(os);
+                       // We don't need really a new paragraph, but
+                       // we must make sure that the next item gets a \begin_layout.
+                       context.new_paragraph(os);
+                       end_inset(os);
                        p.skip_spaces();
+                       os << "\\end_layout\n";
                }
 
                else if (t.cs() == "includegraphics") {
@@ -1782,7 +1812,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                else if (t.cs() == "tableofcontents") {
                        p.skip_spaces();
                        context.check_layout(os);
-                       begin_inset(os, "LatexCommand \\tableofcontents\n");
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
                        end_inset(os);
                        skip_braces(p); // swallow this
                }
@@ -1805,7 +1836,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
 
                else if (t.cs() == "listof") {
                        p.skip_spaces(true);
-                       string const name = p.get_token().asString();
+                       string const name = p.get_token().cs();
                        if (context.textclass.floats().typeExist(name)) {
                                context.check_layout(os);
                                begin_inset(os, "FloatList ");
@@ -1918,6 +1949,17 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        os << "\\lyxline";
                }
 
+               else if (is_known(t.cs(), known_ref_commands)) {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       // LyX cannot handle newlines in a latex command
+                       // FIXME: Move the substitution into parser::getOpt()?
+                       os << subst(p.getOpt(), "\n", " ");
+                       os << "reference " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       end_inset(os);
+               }
+
                else if (use_natbib &&
                         is_known(t.cs(), known_natbib_commands) &&
                         ((t.cs() != "citefullauthor" &&
@@ -1925,19 +1967,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                           t.cs() != "citeyearpar") ||
                          p.next_token().asInput() != "*")) {
                        context.check_layout(os);
-                       // tex                       lyx
-                       // \citet[before][after]{a}  \citet[after][before]{a}
-                       // \citet[before][]{a}       \citet[][before]{a}
-                       // \citet[after]{a}          \citet[after]{a}
-                       // \citet{a}                 \citet{a}
-                       string command = '\\' + t.cs();
+                       string command = t.cs();
                        if (p.next_token().asInput() == "*") {
                                command += '*';
                                p.get_token();
                        }
-                       if (command == "\\citefullauthor")
+                       if (command == "citefullauthor")
                                // alternative name for "\\citeauthor*"
-                               command = "\\citeauthor*";
+                               command = "citeauthor*";
 
                        // text before the citation
                        string before;
@@ -1945,14 +1982,14 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        string after;
                        get_cite_arguments(p, true, before, after);
 
-                       if (command == "\\cite") {
+                       if (command == "cite") {
                                // \cite without optional argument means
                                // \citet, \cite with at least one optional
                                // argument means \citep.
                                if (before.empty() && after.empty())
-                                       command = "\\citet";
+                                       command = "citet";
                                else
-                                       command = "\\citep";
+                                       command = "citep";
                        }
                        if (before.empty() && after == "[]")
                                // avoid \citet[]{a}
@@ -1962,16 +1999,31 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                before.erase();
                                after.erase();
                        }
+                       // remove the brackets around after and before
+                       if (!after.empty()) {
+                               after.erase(0, 1);
+                               after.erase(after.length() - 1, 1);
+                               // LyX cannot handle newlines in the parameter
+                               after = subst(after, "\n", " ");
+                       }
+                       if (!before.empty()) {
+                               before.erase(0, 1);
+                               before.erase(before.length() - 1, 1);
+                               // LyX cannot handle newlines in the parameter
+                               before = subst(before, "\n", " ");
+                       }
                        begin_inset(os, "LatexCommand ");
-                       os << command << after << before
-                          << '{' << p.verbatim_item() << "}\n";
+                       os << t.cs() << "\n";
+                       os << "after " << '"' << after << '"' << "\n";
+                       os << "before " << '"' << before << '"' << "\n";
+                       os << "key " << '"' << p.verbatim_item() << '"' << "\n";
                        end_inset(os);
                }
 
                else if (use_jurabib &&
                         is_known(t.cs(), known_jurabib_commands)) {
                        context.check_layout(os);
-                       string const command = '\\' + t.cs();
+                       string const command = t.cs();
                        char argumentOrder = '\0';
                        vector<string> const & options = used_packages["jurabib"];
                        if (find(options.begin(), options.end(),
@@ -1997,24 +2049,86 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                        "package options if you used an\n"
                                        "earlier jurabib version." << endl;
                        }
+                       if (!after.empty()) {
+                               after.erase(0, 1);
+                               after.erase(after.length() - 1, 1);
+                       }
+                       if (!before.empty()) {
+                               before.erase(0, 1);
+                               before.erase(before.length() - 1, 1);
+                       }
                        begin_inset(os, "LatexCommand ");
-                       os << command << after << before
-                          << '{' << citation << "}\n";
+                       os << t.cs() << "\n";
+                       os << "after " << '"' << after << '"' << "\n";
+                       os << "before " << '"' << before << '"' << "\n";
+                       os << "key " << '"' << citation << '"' << "\n";
                        end_inset(os);
                }
 
-               else if (is_known(t.cs(), known_latex_commands)) {
-                       // This needs to be after the check for natbib and
-                       // jurabib commands, because "cite" has different
-                       // arguments with natbib and jurabib.
+               else if (t.cs() == "cite") {
                        context.check_layout(os);
+                       // LyX cannot handle newlines in a latex command
+                       string after = subst(p.getOptContent(), "\n", " ");
                        begin_inset(os, "LatexCommand ");
-                       os << '\\' << t.cs();
-                       // lyx cannot handle newlines in a latex command
-                       // FIXME: Move the substitution into parser::getOpt()?
-                       os << subst(p.getOpt(), "\n", " ");
-                       os << subst(p.getOpt(), "\n", " ");
-                       os << '{' << subst(p.verbatim_item(), "\n", " ") << "}\n";
+                       os << t.cs() << "\n";
+                       os << "after " << '"' << after << '"' << "\n";
+                       os << "key " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       end_inset(os);
+               }
+
+               else if (t.cs() == "index") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       // LyX cannot handle newlines in a latex command
+                       os << "name " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       end_inset(os);
+               }
+
+               else if (t.cs() == "nomenclature") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       // LyX cannot handle newlines in a latex command
+                       string prefix = subst(p.getOptContent(), "\n", " ");
+                       if (!prefix.empty())
+                               os << "prefix " << '"' << prefix << '"' << "\n";
+                       os << "symbol " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       os << "description " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       end_inset(os);
+               }
+               
+               else if (t.cs() == "label") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       // LyX cannot handle newlines in a latex command
+                       os << "name " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
+                       end_inset(os);
+               }
+
+               else if (t.cs() == "printindex") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       end_inset(os);
+                       skip_braces(p);
+               }
+
+               else if (t.cs() == "printnomenclature") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       end_inset(os);
+                       skip_braces(p);
+               }
+
+               else if (t.cs() == "url") {
+                       context.check_layout(os);
+                       begin_inset(os, "LatexCommand ");
+                       os << t.cs() << "\n";
+                       // LyX cannot handle newlines in a latex command
+                       os << "target " << '"' << subst(p.verbatim_item(), "\n", " ") << '"' << "\n";
                        end_inset(os);
                }
 
@@ -2125,10 +2239,8 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // save the language for the case that a
                        // \foreignlanguage is used 
 
-                       //FIXME: this is wrong, the language should
-                       // be saved in the context. (JMarc)
-                       selectlang = subst(p.verbatim_item(), "\n", " ");
-                       os << "\\lang " << selectlang << "\n";
+                       context.font.language = subst(p.verbatim_item(), "\n", " ");
+                       os << "\\lang " << context.font.language << "\n";
                }
 
                else if (t.cs() == "foreignlanguage") {
@@ -2139,7 +2251,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // has to be parsed (like for \textsf, for
                        // example). 
                        // set back to last selectlanguage
-                       os << "\n\\lang " << selectlang << "\n";
+                       os << "\n\\lang " << context.font.language << "\n";
                }
 
                else if (t.cs() == "inputencoding") {
@@ -2147,6 +2259,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        string const enc = subst(p.verbatim_item(), "\n", " ");
                        p.setEncoding(enc);
                }
+
                else if (t.cs() == "LyX" || t.cs() == "TeX"
                         || t.cs() == "LaTeX") {
                        context.check_layout(os);
@@ -2178,6 +2291,12 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        skip_braces(p);
                }
 
+               else if (t.cs() == "textquotedbl") {
+                       context.check_layout(os);
+                       os << "\"";
+                       skip_braces(p);
+               }
+
                else if (t.cs() == "@" && p.next_token().asInput() == ".") {
                        context.check_layout(os);
                        os << "\\SpecialChar \\@.\n";
@@ -2245,10 +2364,9 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                else if (t.cs() == "=" && (flags & FLAG_TABBING))
                        handle_ert(os, t.asInput(), context);
 
-               else if (t.cs() == "H" || t.cs() == "c" || t.cs() == "^"
-                        || t.cs() == "'" || t.cs() == "`"
-                        || t.cs() == "~" || t.cs() == "." || t.cs() == "=") {
-                       // we need the trim as the LyX parser chokes on such spaces
+               // accents (see Table 6 in Comprehensive LaTeX Symbol List)
+               else if (t.cs().size() == 1 
+                        && contains("\"'.=^`bcdHkrtuv~", t.cs())) {
                        context.check_layout(os);
                        // try to see whether the string is in unicodesymbols
                        docstring rem;
@@ -2281,8 +2399,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        }
                }
 
-               else if (t.cs() == "newline" ||
-                       t.cs() == "linebreak") {
+               else if (t.cs() == "newline") {
                        context.check_layout(os);
                        os << "\n\\" << t.cs() << "\n";
                        skip_braces(p); // eat {}
@@ -2312,7 +2429,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        }
                        if (makeAbsPath(filename, path).exists()) {
                                string const abstexname =
-                                       makeAbsPath(filename, path).absFilename();
+                                       makeAbsPath(filename, path).absFileName();
                                string const abslyxname =
                                        changeExtension(abstexname, ".lyx");
                                fix_relative_filename(filename);
@@ -2345,12 +2462,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                else if (t.cs() == "bibliography") {
                        context.check_layout(os);
                        begin_inset(os, "LatexCommand ");
-                       os << "\\bibtex";
+                       os << "bibtex" << "\n";
+                       os << "bibfiles " << '"' << p.verbatim_item() << '"' << "\n";
                        // Do we have a bibliographystyle set?
-                       if (!bibliographystyle.empty()) {
-                               os << '[' << bibliographystyle << ']';
-                       }
-                       os << '{' << p.verbatim_item() << "}\n";
+                       if (!bibliographystyle.empty())
+                               os << "options " << '"' << bibliographystyle << '"' << "\n";
                        end_inset(os);
                }
 
@@ -2401,7 +2517,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                }
 
                else if (t.cs() == "newpage" ||
-                       t.cs() == "pagebreak" ||
                        t.cs() == "clearpage" ||
                        t.cs() == "cleardoublepage") {
                        context.check_layout(os);