]> git.lyx.org Git - features.git/commitdiff
Rework InsetCommandParams interface and file storage
authorGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Tue, 17 Oct 2006 21:07:16 +0000 (21:07 +0000)
committerGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Tue, 17 Oct 2006 21:07:16 +0000 (21:07 +0000)
* src/insets/insetcommandparams.[Ch]:
(operator[]): New, access a parameter
(clear): New, clear all parameters
(info_): New, stire info about this command
(cmdname): Rename to name_
(contents, options, sec_options): Replace with params_. Parameters
are now stored as docstring.
(findInfo): New factor for command info for all commands
(read, write): Use new syntax
(parameter set and get methods): reimplemenmt for new parameter storage

* src/insets/insetcommand.h
(getParam): New, get a parameter
(setParam): New, set a parameter
(parameter set and get methods): Adjust to InsetCommandParams changes

* src/insets/insetbibitem.[Ch]
(write): Remove, not needed anymore
(directWrite): ditto

* src/insets/insetbibitem.C
(InsetBibitem::read): Use InsetCommand::read

* src/insets/insetref.C
(InsetRef::latex): Use new InsetCommandParams interface

* src/mathed/InsetMathHull.C
(InsetMathHull::doDispatch): ditto

* src/text3.C
(LyXText::dispatch): ditto

* src/factory.C
(createInset): Create InsetCommandParams with command name
(readInset): ditto
(readInset): Remove error message for bibitem, since bibitem is
now a normal command inset

* src/buffer.C: Bump file format number

* src/frontends/controllers/ControlCommand.[Ch]
(ControlCommand): take an additional command name parameter

* src/text.C
(readParToken): Remove code for \bibitem

* lib/lyx2lyx/LyX.py: Bump latest file format number

* lib/lyx2lyx/lyx_1_5.py
(convert_bibitem, convert_commandparams): new, convert to new format
(revert_commandparams): new, convert to old format

* development/FORMAT: document new format

* many other files: Adjust to the changes above

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15357 a592a061-630c-0410-9148-cb99ea01b6c8

31 files changed:
development/FORMAT
lib/lyx2lyx/LyX.py
lib/lyx2lyx/lyx_1_5.py
po/POTFILES.in
src/buffer.C
src/factory.C
src/frontends/controllers/ControlBibtex.C
src/frontends/controllers/ControlCitation.C
src/frontends/controllers/ControlCommand.C
src/frontends/controllers/ControlCommand.h
src/frontends/controllers/ControlInclude.C
src/frontends/controllers/ControlRef.C
src/frontends/controllers/ControlToc.C
src/frontends/gtk/Dialogs.C
src/frontends/qt3/Dialogs.C
src/frontends/qt4/Dialogs.C
src/insets/insetbibitem.C
src/insets/insetbibitem.h
src/insets/insetbibtex.C
src/insets/insetcite.h
src/insets/insetcommand.C
src/insets/insetcommand.h
src/insets/insetcommandparams.C
src/insets/insetcommandparams.h
src/insets/insetfloatlist.C
src/insets/insetinclude.C
src/insets/insetlabel.C
src/insets/insetref.C
src/mathed/InsetMathHull.C
src/text.C
src/text3.C

index 281fecc89b2278502566694c3b75599eb6f68088..724c4ed3e8a4b487b9a17519ac4a9bdb94ccb510 100644 (file)
@@ -1,6 +1,34 @@
 LyX file-format changes
 -----------------------§
 
+2006-10-15  Georg Baum  <Georg.Baum@post.rwth-aachen.de>
+
+       * format incremented to 252: changed command inset syntax
+
+       Old:
+
+       \begin_inset LatexCommand \cmdname[opt1][opt2]{arg}
+       preview true
+       \end_inset
+
+       and
+
+       \bibitem [opt1]{arg}
+
+
+       New:
+
+       \begin_inset LatexCommand cmdname
+       name1 "opt1"
+       name2 "opt2"
+       name3 "arg"
+       preview true
+       \end_inset
+
+       The order of the parameters and for each parameter the name and
+       optional/required bit is now stored in InsetCommandParams.
+
+
 2006-10-03  Jürgen Spitzmüller  <j.spitzmueller@gmx.de>
 
        * format incremented to 251: save show_label param for charstyles.
index d137b95f908dd171340dbf938ed790b41ef86755..fab9b56302b8337283a2ede64562af76c519e01d 100644 (file)
@@ -73,7 +73,7 @@ format_relation = [("0_06",    [200], generate_minor_versions("0.6" , 4)),
                    ("1_2",     [220], generate_minor_versions("1.2" , 4)),
                    ("1_3",     [221], generate_minor_versions("1.3" , 7)),
                    ("1_4", range(222,246), generate_minor_versions("1.4" , 3)),
-                   ("1_5", range(246,252), generate_minor_versions("1.5" , 0))]
+                   ("1_5", range(246,253), generate_minor_versions("1.5" , 0))]
 
 
 def formats_list():
index becf3ae60fabbd85f1c4437750bc3ccc832673c2..caf60550033a432b4a998ecbbd9add86dd5cc7d3 100644 (file)
@@ -253,6 +253,193 @@ def revert_cs_label(document):
         i = i + 1
 
 
+def convert_bibitem(document):
+    """ Convert
+\bibitem [option]{argument}
+
+to
+
+\begin_inset LatexCommand bibitem
+label "option"
+key "argument"
+
+\end_inset
+
+This must be called after convert_commandparams.
+"""
+    regex = re.compile(r'\S+\s*(\[[^\[\{]*\])?(\{[^}]*\})')
+    i = 0
+    while 1:
+        i = find_token(document.body, "\\bibitem", i)
+        if i == -1:
+            break
+        match = re.match(regex, document.body[i])
+        option = match.group(1)
+        argument = match.group(2)
+        lines = ['\\begin_inset LatexCommand bibitem']
+       if not option == None:
+            lines.append('label "%s"' % option[1:-1].replace('"', '\\"'))
+        lines.append('key "%s"' % argument[1:-1].replace('"', '\\"'))
+        lines.append('')
+        lines.append('\\end_inset')
+        document.body[i:i+1] = lines
+        i = i + 1
+
+
+commandparams_info = {
+    # command : [option1, option2, argument]
+    "bibitem" : ["label", "", "key"],
+    "bibtex" : ["options", "btprint", "bibfiles"],
+    "cite"        : ["after", "before", "key"],
+    "citet"       : ["after", "before", "key"],
+    "citep"       : ["after", "before", "key"],
+    "citealt"     : ["after", "before", "key"],
+    "citealp"     : ["after", "before", "key"],
+    "citeauthor"  : ["after", "before", "key"],
+    "citeyear"    : ["after", "before", "key"],
+    "citeyearpar" : ["after", "before", "key"],
+    "citet*"      : ["after", "before", "key"],
+    "citep*"      : ["after", "before", "key"],
+    "citealt*"    : ["after", "before", "key"],
+    "citealp*"    : ["after", "before", "key"],
+    "citeauthor*" : ["after", "before", "key"],
+    "Citet"       : ["after", "before", "key"],
+    "Citep"       : ["after", "before", "key"],
+    "Citealt"     : ["after", "before", "key"],
+    "Citealp"     : ["after", "before", "key"],
+    "Citeauthor"  : ["after", "before", "key"],
+    "Citet*"      : ["after", "before", "key"],
+    "Citep*"      : ["after", "before", "key"],
+    "Citealt*"    : ["after", "before", "key"],
+    "Citealp*"    : ["after", "before", "key"],
+    "Citeauthor*" : ["after", "before", "key"],
+    "citefield"   : ["after", "before", "key"],
+    "citetitle"   : ["after", "before", "key"],
+    "cite*"       : ["after", "before", "key"],
+    "hfill" : ["", "", ""],
+    "index"      : ["", "", "name"],
+    "printindex" : ["", "", "name"],
+    "label" : ["", "", "name"],
+    "eqref"     : ["name", "", "reference"],
+    "pageref"   : ["name", "", "reference"],
+    "prettyref" : ["name", "", "reference"],
+    "ref"       : ["name", "", "reference"],
+    "vpageref"  : ["name", "", "reference"],
+    "vref"      : ["name", "", "reference"],
+    "tableofcontents" : ["", "", "type"],
+    "htmlurl" : ["name", "", "target"],
+    "url"     : ["name", "", "target"]}
+
+
+def convert_commandparams(document):
+    """ Convert
+
+ \begin_inset LatexCommand \cmdname[opt1][opt2]{arg}
+ \end_inset
+
+ to
+
+ \begin_inset LatexCommand cmdname
+ name1 "opt1"
+ name2 "opt2"
+ name3 "arg"
+ \end_inset
+
+ name1, name2 and name3 can be different for each command.
+"""
+    # \begin_inset LatexCommand bibitem was not the official version (see
+    # convert_bibitem()), but could be read in, so we convert it here, too.
+
+    # FIXME: Handle things like \command[foo[bar]]{foo{bar}}
+    # we need a real parser here.
+    regex = re.compile(r'\\([^\[\{]+)(\[[^\[\{]*\])?(\[[^\[\{]*\])?(\{[^}]*\})?')
+    i = 0
+    while 1:
+        i = find_token(document.body, "\\begin_inset LatexCommand", i)
+        if i == -1:
+            break
+        command = document.body[i][26:].strip()
+        match = re.match(regex, command)
+        name = match.group(1)
+        option1 = match.group(2)
+        option2 = match.group(3)
+        argument = match.group(4)
+        lines = ["\\begin_inset LatexCommand %s" % name]
+        if option1 != None:
+            if commandparams_info[name][0] == "":
+                document.warning("Ignoring invalid option `%s' of command `%s'." % (option1[1:-1], name))
+            else:
+                lines.append('%s "%s"' % (commandparams_info[name][0], option1[1:-1].replace('"', '\"')))
+        if option2 != None:
+            if commandparams_info[name][1] == "":
+                document.warning("Ignoring invalid second option `%s' of command `%s'." % (option2[1:-1], name))
+            else:
+                lines.append('%s "%s"' % (commandparams_info[name][1], option2[1:-1].replace('"', '\"')))
+        if argument != None:
+            if commandparams_info[name][2] == "":
+                document.warning("Ignoring invalid argument `%s' of command `%s'." % (argument[1:-1], name))
+            else:
+                lines.append('%s "%s"' % (commandparams_info[name][2], argument[1:-1].replace('"', '\"')))
+        document.body[i:i+1] = lines
+        i = i + 1
+
+
+def revert_commandparams(document):
+    regex = re.compile(r'(\S+)\s+(.+)')
+    i = 0
+    while 1:
+        i = find_token(document.body, "\\begin_inset LatexCommand", i)
+        if i == -1:
+            break
+        name = document.body[i].split()[2]
+        j = find_end_of_inset(document.body, i + 1)
+        preview_line = ""
+        option1 = ""
+        option2 = ""
+        argument = ""
+        for k in range(i + 1, j):
+            match = re.match(regex, document.body[k])
+            if match:
+                pname = match.group(1)
+                pvalue = match.group(2)
+                if pname == "preview":
+                    preview_line = document.body[k]
+                elif (commandparams_info[name][0] != "" and
+                      pname == commandparams_info[name][0]):
+                    option1 = pvalue.strip('"').replace('\\"', '"')
+                elif (commandparams_info[name][1] != "" and
+                      pname == commandparams_info[name][1]):
+                    option2 = pvalue.strip('"').replace('\\"', '"')
+                elif (commandparams_info[name][2] != "" and
+                      pname == commandparams_info[name][2]):
+                    argument = pvalue.strip('"').replace('\\"', '"')
+            elif document.body[k].strip() != "":
+                document.warning("Ignoring unknown contents `%s' in command inset %s." % (document.body[k], name))
+        if name == "bibitem":
+            if option1 == "":
+                lines = ["\\bibitem {%s}" % argument]
+            else:
+                lines = ["\\bibitem [%s]{%s}" % (option1, argument)]
+        else:
+            if option1 == "":
+                if option2 == "":
+                    lines = ["\\begin_inset LatexCommand \\%s{%s}" % (name, argument)]
+                else:
+                    lines = ["\\begin_inset LatexCommand \\%s[][%s]{%s}" % (name, option2, argument)]
+            else:
+                if option2 == "":
+                    lines = ["\\begin_inset LatexCommand \\%s[%s]{%s}" % (name, option1, argument)]
+                else:
+                    lines = ["\\begin_inset LatexCommand \\%s[%s][%s]{%s}" % (name, option1, option2, argument)]
+        if name != "bibitem":
+            if preview_line != "":
+                lines.append(preview_line)
+            lines.append('')
+            lines.append('\\end_inset')
+        document.body[i:j+1] = lines
+        i = j + 1
+
+
 ##
 # Conversion hub
 #
@@ -263,9 +450,11 @@ convert = [[246, []],
            [248, []],
            [249, [convert_utf8]],
            [250, []],
-           [251, []]]
+           [251, []],
+           [252, [convert_commandparams, convert_bibitem]]]
 
-revert =  [[250, [revert_cs_label]],
+revert =  [[251, [revert_commandparams]],
+           [250, [revert_cs_label]],
            [249, []],
            [248, [revert_utf8]],
            [247, [revert_booktabs]],
index 9b82a90ab8c07949ae3e32d436e1510cbc80da80..f30b5acd1a269226f629c7a17c603a3aef3d7962 100644 (file)
@@ -137,6 +137,7 @@ src/frontends/qt4/QBranch.C
 src/frontends/qt4/QBranches.C
 src/frontends/qt4/QChanges.C
 src/frontends/qt4/QCharacter.C
+src/frontends/qt4/QCitationDialog.C
 src/frontends/qt4/QCommandBuffer.C
 src/frontends/qt4/QDelimiterDialog.C
 src/frontends/qt4/QDocument.C
@@ -163,6 +164,7 @@ src/frontends/qt4/QTabular.C
 src/frontends/qt4/QTabularCreate.C
 src/frontends/qt4/QTexinfo.C
 src/frontends/qt4/QThesaurus.C
+src/frontends/qt4/QTocDialog.C
 src/frontends/qt4/QVSpace.C
 src/frontends/qt4/QWrap.C
 src/frontends/qt4/Qt2BC.h
index bdc4b6fbada8f7dc9596840821719de1a8d3a630..b14f3be740a917c1f783edc7ac25bd728190d7e0 100644 (file)
@@ -144,7 +144,7 @@ using std::string;
 
 namespace {
 
-int const LYX_FORMAT = 251;
+int const LYX_FORMAT = 252;
 
 } // namespace anon
 
index 484bfcf25c02e3f4207f5468f611949ccc7c7cfe..22f8fa9d57a8671f9b5677174ec9c4ccd88cc10a 100644 (file)
@@ -211,19 +211,19 @@ InsetBase * createInset(BufferView * bv, FuncRequest const & cmd)
                string const name = cmd.getArg(0);
 
                if (name == "bibitem") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetBibitem(icp);
 
                } else if (name == "bibtex") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetBibtex(icp);
 
                } else if (name == "citation") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp("cite");
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetCitation(icp);
@@ -252,36 +252,36 @@ InsetBase * createInset(BufferView * bv, FuncRequest const & cmd)
                        return inset.release();
 
                } else if (name == "include") {
-                       InsetCommandParams iip;
+                       InsetCommandParams iip(name);
                        InsetIncludeMailer::string2params(lyx::to_utf8(cmd.argument()), iip);
                        return new InsetInclude(iip);
 
                } else if (name == "index") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetIndex(icp);
 
                } else if (name == "label") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetLabel(icp);
 
                } else if (name == "ref") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetRef(icp, *bv->buffer());
 
                } else if (name == "toc") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp("tableofcontents");
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetTOC(icp);
 
                } else if (name == "url") {
-                       InsetCommandParams icp;
+                       InsetCommandParams icp(name);
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()),
                                                          icp);
                        return new InsetUrl(icp);
@@ -344,10 +344,12 @@ InsetBase * readInset(LyXLex & lex, Buffer const & buf)
 
        // test the different insets
        if (tmptok == "LatexCommand") {
-               InsetCommandParams inscmd;
-               inscmd.read(lex);
+               lex.next();
+               string const cmdName = lex.getString();
+               lex.pushToken(cmdName);
 
-               string const cmdName = inscmd.getCmdName();
+               InsetCommandParams inscmd(cmdName);
+               inscmd.read(lex);
 
                // This strange command allows LyX to recognize "natbib" style
                // citations: citet, citep, Citet etc.
@@ -360,7 +362,6 @@ InsetBase * readInset(LyXLex & lex, Buffer const & buf)
                if (compare_ascii_no_case(cmdName.substr(0,4), "cite") == 0) {
                        inset.reset(new InsetCitation(inscmd));
                } else if (cmdName == "bibitem") {
-                       lex.printError("Wrong place for bibitem");
                        inset.reset(new InsetBibitem(inscmd));
                } else if (cmdName == "bibtex") {
                        inset.reset(new InsetBibtex(inscmd));
index 57d01358a47de508695ceb777aaa5dfd569fe749..9d7f71f8fdfc8ff795d157079475b56bfc526f5a 100644 (file)
@@ -44,7 +44,7 @@ namespace frontend {
 
 
 ControlBibtex::ControlBibtex(Dialog & d)
-       : ControlCommand(d, "bibtex")
+       : ControlCommand(d, "bibtex", "bibtex")
 {}
 
 
index a040adb92b44298537c097c18a3697f31a349c09..2ea86ee45a88ed820b2639989fa4814b8d2934ac 100644 (file)
@@ -28,7 +28,7 @@ vector<biblio::CiteStyle> ControlCitation::citeStyles_;
 
 
 ControlCitation::ControlCitation(Dialog & d)
-       : ControlCommand(d, "citation")
+       : ControlCommand(d, "cite", "citation")
 {}
 
 
index 0fa8df22f8f6c62e0e8c3ab2cb899d2d1428ecb0..20ceb87a0e946c9d1f187d2390312704a3f54089 100644 (file)
@@ -21,8 +21,9 @@ using std::string;
 namespace lyx {
 namespace frontend {
 
-ControlCommand::ControlCommand(Dialog & dialog, string const & lfun_name)
-       : Dialog::Controller(dialog),
+ControlCommand::ControlCommand(Dialog & dialog, string const & command_name,
+                               string const & lfun_name)
+       : Dialog::Controller(dialog), params_(command_name),
          lfun_name_(lfun_name)
 {}
 
@@ -38,7 +39,7 @@ bool ControlCommand::initialiseParams(string const & data)
 
 void ControlCommand::clearParams()
 {
-       params_ = InsetCommandParams();
+       params_.clear();
 }
 
 
index b7f99d15a2d58fd305b8dc631fb24a93addf5e44..35dee58f1dd40b16521e9c2b3389e8140ea12121 100644 (file)
@@ -26,9 +26,11 @@ class ControlCommand : public Dialog::Controller {
 public:
        /** LFUN_INSET_APPLY requires a name, "citation", "ref" etc so that
            it knows what to do with the rest of the contents.
-           An empty name indicates that no action will occur on 'Apply'.
+           An empty \p lfun_name indicates that no action will occur on
+           'Apply'.
         */
-       ControlCommand(Dialog &, std::string const & lfun_name = std::string());
+       ControlCommand(Dialog &, std::string const & command_name,
+                      std::string const & lfun_name);
        ///
        InsetCommandParams & params() { return params_; }
        ///
index 5c6e2292aef277e7b24b9a33ff7efb04e6b2cd72..e213b478b0ecdfe28742bb1c2b7692dd97b460e8 100644 (file)
@@ -42,7 +42,7 @@ using support::onlyPath;
 namespace frontend {
 
 ControlInclude::ControlInclude(Dialog & parent)
-       : Dialog::Controller(parent)
+       : Dialog::Controller(parent), params_("include")
 {}
 
 
@@ -55,7 +55,7 @@ bool ControlInclude::initialiseParams(string const & data)
 
 void ControlInclude::clearParams()
 {
-       params_ = InsetCommandParams();
+       params_.clear();
 }
 
 
index 958500d62a552771cb9cbec2c9fe2cd479d842b0..426cd7bf50f3038083432656538c244fc27422d9 100644 (file)
@@ -32,7 +32,7 @@ using support::makeDisplayPath;
 namespace frontend {
 
 ControlRef::ControlRef(Dialog & d)
-       : ControlCommand(d, "ref")
+       : ControlCommand(d, "ref", "ref")
 {}
 
 
index 6b2a14937b43c82248657b6c511bcaa2696b053c..b12d5ce89ebd8f10ddab9d376b300bc409985077 100644 (file)
@@ -29,7 +29,7 @@ namespace frontend {
 
 
 ControlToc::ControlToc(Dialog & d)
-       : ControlCommand(d, "toc")
+       : ControlCommand(d, "tableofcontents", "toc")
 {}
 
 
index 1e94b38a74e240423d2b2f5d8ebd005f37370f14..1b23991f9b83f80e161c1cbf0b14a5542269365b 100644 (file)
@@ -185,7 +185,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "bibitem") {
                dialog->bc().view(new GBC(dialog->bc()));
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new GBibItem(*dialog));
                dialog->bc().bp(new OkCancelReadOnlyPolicy);
        } else if (name == "bibtex") {
@@ -260,7 +260,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
        } else if (name == "index") {
                dialog->bc().view(new GBC(dialog->bc()));
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                // FIXME UNICODE
                dialog->setView(new GText(*dialog,
                                          lyx::to_utf8(_("Index Entry")),
@@ -268,7 +268,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "label") {
                dialog->bc().view(new GBC(dialog->bc()));
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                // FIXME UNICODE
                dialog->setView(new GText(*dialog,
                                          lyx::to_utf8(_("Label")),
@@ -548,7 +548,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "url") {
                dialog->bc().view(new GBC(dialog->bc()));
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new GUrl(*dialog));
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "vspace") {
index cb78724ffe928ba1b4e616f16df23ed53750440c..28b4bff7091b3224f309c6e16509ddecf9c75e53 100644 (file)
@@ -150,7 +150,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QAbout(*dialog));
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "bibitem") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QBibitem(*dialog));
                dialog->bc().bp(new OkCancelReadOnlyPolicy);
        } else if (name == "bibtex") {
@@ -214,13 +214,13 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QInclude(*dialog));
                dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
        } else if (name == "index") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QIndex(*dialog,
                                           _("Index Entry"),
                                           qt_("&Keyword:")));
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "label") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QIndex(*dialog,
                                           _("Label"),
                                           qt_("&Label:")));
@@ -296,7 +296,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QToc(*dialog));
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "url") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QURL(*dialog));
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "vspace") {
index ed12343b84a34a39cf05170a26878e8bf047ee8b..bf6d81717ddd0e1485fe03f19d95cc847e16840f 100644 (file)
@@ -146,7 +146,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QAbout(*dialog));
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "bibitem") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QBibitem(*dialog));
                dialog->bc().bp(new OkCancelReadOnlyPolicy);
        } else if (name == "bibtex") {
@@ -211,13 +211,13 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QInclude(*dialog));
                dialog->bc().bp(new OkApplyCancelReadOnlyPolicy);
        } else if (name == "index") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QIndex(*dialog,
                                           _("Index Entry"),
                                           qt_("&Keyword:")));
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "label") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new QIndex(*dialog,
                                           _("Label"),
                                           qt_("&Label:")));
@@ -295,7 +295,7 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
                dialog->setView(new QTocDialog(*dialog, qtoc));
                dialog->bc().bp(new OkCancelPolicy);
        } else if (name == "url") {
-               dialog->setController(new ControlCommand(*dialog, name));
+               dialog->setController(new ControlCommand(*dialog, name, name));
                dialog->setView(new UrlView(*dialog));
                dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
        } else if (name == "vspace") {
index 6e4ac9f54585a03a4a0320c1db94337a27db0e8a..1a973127d1e6f771b83a0b243a11127d97b740d9 100644 (file)
@@ -57,7 +57,7 @@ void InsetBibitem::doDispatch(LCursor & cur, FuncRequest & cmd)
        switch (cmd.action) {
 
        case LFUN_INSET_MODIFY: {
-               InsetCommandParams p;
+               InsetCommandParams p("bibitem");
                InsetCommandMailer::string2params("bibitem", lyx::to_utf8(cmd.argument()), p);
                if (p.getCmdName().empty()) {
                        cur.noUpdate();
@@ -82,27 +82,9 @@ void InsetBibitem::setCounter(int c)
 }
 
 
-// I'm sorry but this is still necessary because \bibitem is used also
-// as a LyX 2.x command, and lyxlex is not enough smart to understand
-// real LaTeX commands. Yes, that could be fixed, but would be a waste
-// of time cause LyX3 won't use lyxlex anyway.  (ale)
-void InsetBibitem::write(Buffer const &, std::ostream & os) const
+void InsetBibitem::read(Buffer const & buf, LyXLex & lex)
 {
-       os << "\n\\bibitem ";
-       if (!getOptions().empty())
-               os << '[' << getOptions() << ']';
-       os << '{' << getContents() << "}\n";
-}
-
-
-// This is necessary here because this is written without begin_inset
-// This should be changed!!! (Jug)
-void InsetBibitem::read(Buffer const &, LyXLex & lex)
-{
-       if (lex.eatLine())
-               scanCommand(lex.getString());
-       else
-               lex.printError("InsetCommand: Parse error: `$$Token'");
+       InsetCommand::read(buf, lex);
 
        if (prefixIs(getContents(), key_prefix)) {
                int const key = convert<int>(getContents().substr(key_prefix.length()));
index d98ae8f8a2cf123fdd68640a0a307f353aadcc9d..35015a1fa63fd5ec1e5b945b88ae4affc17dc714 100644 (file)
@@ -24,10 +24,6 @@ class InsetBibitem : public InsetCommand {
 public:
        ///
        InsetBibitem(InsetCommandParams const &);
-       /** Currently \bibitem is used as a LyX2.x command,
-           so we need this method.
-       */
-       void write(Buffer const &, std::ostream &) const;
        ///
        void read(Buffer const &, LyXLex & lex);
        ///
@@ -36,8 +32,6 @@ public:
        EDITABLE editable() const { return IS_EDITABLE; }
        ///
        InsetBase::Code lyxCode() const { return InsetBase::BIBITEM_CODE; }
-       /// keep .lyx format compatible
-       bool directWrite() const { return true; }
        ///
        void setCounter(int);
        ///
index 13e0cc78240779317cf8385628ae08d6bec47570..3760f8f8af3faa62fb30a28358d5e20824bb797d 100644 (file)
@@ -86,7 +86,7 @@ void InsetBibtex::doDispatch(LCursor & cur, FuncRequest & cmd)
        switch (cmd.action) {
 
        case LFUN_INSET_MODIFY: {
-               InsetCommandParams p;
+               InsetCommandParams p("bibtex");
                InsetCommandMailer::string2params("bibtex", lyx::to_utf8(cmd.argument()), p);
                if (!p.getCmdName().empty()) {
                        setParams(p);
index b66947db36859e51af9cbd933328f773f9c264fe..4a05147a11aa209a3f591de112142ae0bcd77289 100644 (file)
@@ -58,7 +58,7 @@ private:
        class Cache {
        public:
                ///
-               Cache() : engine(lyx::biblio::ENGINE_BASIC) {}
+               Cache() : engine(lyx::biblio::ENGINE_BASIC), params("cite") {}
                ///
                lyx::biblio::CiteEngine engine;
                ///
index 59c9c0a7fa2dbc242d0ba6745e958c2c872f2ebb..12f6f386fa899a803ba454cfd1107e3bd6780bef 100644 (file)
@@ -31,7 +31,7 @@ using std::ostringstream;
 
 InsetCommand::InsetCommand(InsetCommandParams const & p,
                           string const & mailer_name)
-       : p_(p.getCmdName(), p.getContents(), p.getOptions(), p.getSecOptions()),
+       : p_(p),
          mailer_name_(mailer_name),
          updateButtonLabel_(true)
 {}
@@ -100,7 +100,7 @@ void InsetCommand::doDispatch(LCursor & cur, FuncRequest & cmd)
                break;
 
        case LFUN_INSET_MODIFY: {
-               InsetCommandParams p;
+               InsetCommandParams p(p_.getCmdName());
                InsetCommandMailer::string2params(mailer_name_, lyx::to_utf8(cmd.argument()), p);
                if (p.getCmdName().empty())
                        cur.noUpdate();
@@ -172,7 +172,7 @@ void InsetCommandMailer::string2params(string const & name,
                                       string const & in,
                                       InsetCommandParams & params)
 {
-       params = InsetCommandParams();
+       params.clear();
        if (in.empty())
                return;
 
index 42edb946da1fa27fcf8dc70b954ebb63615b71af..7a98c8d2be0a2a4802ccdb2c7af8460ece336934 100644 (file)
@@ -45,6 +45,7 @@ public:
        virtual void read(Buffer const &, LyXLex & lex)
                { p_.read(lex); }
        /// Can remove one InsetBibKey is modified
+       /// FIXME remove
        void scanCommand(std::string const & c) { p_.scanCommand(c); };
        ///
        virtual int latex(Buffer const &, std::ostream &,
@@ -60,20 +61,31 @@ public:
 
        ///
        InsetCommandParams const & params() const { return p_; }
-       ///
-       std::string const getContents() const { return p_.getContents(); }
-       ///
+       /// FIXME remove
+       std::string const getContents() const { return p_.getContents(); }
+       /// FIXME remove
        void setContents(std::string const & c)
        {
                updateButtonLabel_ = true;
                p_.setContents(c);
        }
        ///
-       virtual void replaceContents(std::string const & from, std::string const & to);
-       ///
-       std::string const & getOptions() const { return p_.getOptions(); }
+       void setParam(std::string const & name, lyx::docstring const & value)
+       {
+               updateButtonLabel_ = true;
+               p_[name] = value;
+       }
        ///
-       std::string const & getSecOptions() const { return p_.getSecOptions(); }
+       lyx::docstring const & getParam(std::string const & name) const
+       {
+               return p_[name];
+       }
+       /// FIXME remove
+       virtual void replaceContents(std::string const & from, std::string const & to);
+       /// FIXME remove
+       std::string const getOptions() const { return p_.getOptions(); }
+       /// FIXME remove
+       std::string const getSecOptions() const { return p_.getSecOptions(); }
        ///
        RenderButton & button() const { return button_; }
 
index ddb78faef0b7f9cd438ca2136a3dd4b64c2d4771..80bb576d5ab8c1aa362e1774d4a75c26aa22a205 100644 (file)
@@ -4,6 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Angus Leeming
+ * \author Georg Baum
  *
  * Full author contact details are available in file CREDITS.
  */
 #include "debug.h"
 #include "lyxlex.h"
 
+#include "support/lstrings.h"
+
+#include <boost/assert.hpp>
+
+
+using lyx::docstring;
+using lyx::support::findToken;
 
 using std::string;
 using std::endl;
 using std::ostream;
 
 
-InsetCommandParams::InsetCommandParams()
-{}
+InsetCommandParams::InsetCommandParams(string const & name)
+       : name_(name), preview_(false)
+{
+       info_ = findInfo(name);
+       BOOST_ASSERT(info_);
+       params_.resize(info_->n);
+}
+
+
+InsetCommandParams::CommandInfo const *
+InsetCommandParams::findInfo(std::string const & name)
+{
+       // No parameter may be named "preview", because that is a required
+       // flag for all commands.
+
+       // InsetBibitem
+       if (name == "bibitem") {
+               static const char * const paramnames[] = {"label", "key", ""};
+               static const bool isoptional[] = {true, false};
+               static const CommandInfo info = {2, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetBibtex
+       if (name == "bibtex") {
+               static const char * const paramnames[] =
+                               {"options", "btprint", "bibfiles", ""};
+               static const bool isoptional[] = {true, true, false};
+               static const CommandInfo info = {3, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetCitation
+       // FIXME: Use is_possible_cite_command() in
+       // src/frontends/controllers/biblio.C, see comment in src/factory.C.
+       if (name == "cite" || name == "citet" || name == "citep" || name == "citealt" ||
+           name == "citealp" || name == "citeauthor" || name == "citeyear" ||
+           name == "citeyearpar" || name == "citet*" || name == "citep*" ||
+           name == "citealt*" || name == "citealp*" ||
+           name == "citeauthor*" || name == "Citet" || name == "Citep" ||
+           name == "Citealt" || name == "Citealp" || name == "Citeauthor" ||
+           name == "Citet*" || name == "Citep*" || name == "Citealt*" ||
+           name == "Citealp*" || name == "Citeauthor*" ||
+           name == "citefield" || name == "citetitle" || name == "cite*") {
+               // standard cite does only take one argument if jurabib is
+               // not used, but jurabib extends this to two arguments, so
+               // we have to allow both here. InsetCitation takes care that
+               // LaTeX output is nevertheless correct.
+               static const char * const paramnames[] =
+                               {"after", "before", "key", ""};
+               static const bool isoptional[] = {true, true, false};
+               static const CommandInfo info = {3, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetFloatlist
+       if (name == "floatlist") {
+               static const char * const paramnames[] = {"type", ""};
+               static const bool isoptional[] = {false};
+               static const CommandInfo info = {1, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetHfill
+       if (name == "hfill") {
+               static const char * const paramnames[] = {""};
+               static const CommandInfo info = {0, paramnames, 0};
+               return &info;
+       }
+
+       // InsetInclude
+       if (name == "include" || name == "input" || name == "verbatiminput" ||
+           name == "verbatiminput*") {
+               static const char * const paramnames[] = {"filename", ""};
+               static const bool isoptional[] = {false};
+               static const CommandInfo info = {1, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetIndex, InsetPrintIndex, InsetLabel
+       if (name == "index" || name == "printindex" || name == "label") {
+               static const char * const paramnames[] = {"name", ""};
+               static const bool isoptional[] = {false};
+               static const CommandInfo info = {1, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetRef
+       if (name == "eqref" || name == "pageref" || name == "vpageref" ||
+           name == "vref" || name == "prettyref" || name == "ref") {
+               static const char * const paramnames[] =
+                               {"name", "reference", ""};
+               static const bool isoptional[] = {true, false};
+               static const CommandInfo info = {2, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetTOC
+       if (name == "tableofcontents") {
+               static const char * const paramnames[] = {"type", ""};
+               static const bool isoptional[] = {false};
+               static const CommandInfo info = {1, paramnames, isoptional};
+               return &info;
+       }
+
+       // InsetUrl
+       if (name == "htmlurl" || name == "url") {
+               static const char * const paramnames[] =
+                               {"name", "target", ""};
+               static const bool isoptional[] = {true, false};
+               static const CommandInfo info = {2, paramnames, isoptional};
+               return &info;
+       }
+
+       return 0;
+}
 
 
-InsetCommandParams::InsetCommandParams(string const & n,
-                                       string const & c,
-                                       string const & o,
-                                       string const & s)
-       : cmdname(n), contents(c), options(o), sec_options(s),
-       preview_(false)
-{}
+void InsetCommandParams::setCmdName(string const & name)
+{
+       name_ = name;
+       CommandInfo const * const info = findInfo(name);
+       BOOST_ASSERT(info);
+       ParamVector params(info->n);
+       // Overtake parameters with the same name
+       for (size_t i = 0; i < info_->n; ++i) {
+               int j = findToken(info->paramnames, info_->paramnames[i]);
+               if (j >= 0)
+                       params[j] = params_[i];
+       }
+       info_ = info;
+       std::swap(params, params_);
+}
 
 
 void InsetCommandParams::scanCommand(string const & cmd)
@@ -108,24 +238,32 @@ void InsetCommandParams::scanCommand(string const & cmd)
 
 void InsetCommandParams::read(LyXLex & lex)
 {
-       string token;
-
-       if (lex.eatLine()) {
-               token = lex.getString();
-               scanCommand(token);
-       } else {
-               lex.printError("InsetCommand: Parse error: `$$Token'");
+       if (lex.isOK()) {
+               lex.next();
+               name_ = lex.getString();
+               info_ = findInfo(name_);
+               if (!info_)
+                       lex.printError("InsetCommand: Unknown inset name `$$Token'");
        }
 
+       string token;
        while (lex.isOK()) {
                lex.next();
                token = lex.getString();
                if (token == "\\end_inset")
                        break;
+               // FIXME Why is preview_ read but not written?
                if (token == "preview") {
                        lex.next();
                        preview_ = lex.getBool();
+                       continue;
                }
+               int const i = findToken(info_->paramnames, token);
+               if (i >= 0) {
+                       lex.next(true);
+                       params_[i] = lex.getDocString();
+               } else
+                       lex.printError("Unknown parameter name `$$Token' for command " + name_);
        }
        if (token != "\\end_inset") {
                lex.printError("Missing \\end_inset at this point. "
@@ -136,33 +274,151 @@ void InsetCommandParams::read(LyXLex & lex)
 
 void InsetCommandParams::write(ostream & os) const
 {
-       os << "LatexCommand " << getCommand() << "\n";
+       os << "LatexCommand " << name_ << '\n';
+       for (size_t i = 0; i < info_->n; ++i)
+               if (!params_[i].empty())
+                       // FIXME UNICODE
+                       os << info_->paramnames[i] << ' '
+                          << LyXLex::quoteString(lyx::to_utf8(params_[i]))
+                          << '\n';
 }
 
 
 string const InsetCommandParams::getCommand() const
 {
-       string s;
-       if (!getCmdName().empty()) s += '\\' + getCmdName();
-       if (!getOptions().empty()) s += '[' + getOptions() + ']';
-       if (!getSecOptions().empty()) {
-               // for cases like \command[][sec_option]{arg}
-               if (getOptions().empty()) s += "[]";
-       s += '[' + getSecOptions() + ']';
+       docstring s = '\\' + lyx::from_ascii(name_);
+       for (size_t i = 0; i < info_->n; ++i) {
+               if (info_->optional[i]) {
+                       if (params_[i].empty()) {
+                               // We need to write this parameter even if
+                               // it is empty if nonempty optional parameters
+                               // follow before the next required parameter.
+                               for (size_t j = i + 1; j < info_->n; ++j) {
+                                       if (!info_->optional[j])
+                                               break;
+                                       if (!params_[j].empty()) {
+                                               s += "[]";
+                                               break;
+                                       }
+                               }
+                       } else
+                               s += '[' + params_[i] + ']';
+               } else
+                       s += '{' + params_[i] + '}';
        }
-       s += '{' + getContents() + '}';
-       return s;
+       return lyx::to_utf8(s);
+}
+
+
+std::string const InsetCommandParams::getOptions() const
+{
+       for (size_t i = 0; i < info_->n; ++i)
+               if (info_->optional[i])
+                       return lyx::to_utf8(params_[i]);
+       lyxerr << "Programming error: get nonexisting option in "
+              << name_ << " inset." << endl;; 
+       return string();
+}
+
+
+std::string const InsetCommandParams::getSecOptions() const
+{
+       bool first = true;
+       for (size_t i = 0; i < info_->n; ++i)
+               if (info_->optional[i]) {
+                       if (first)
+                               first = false;
+                       else
+                               return lyx::to_utf8(params_[i]);
+               }
+       // Happens in InsetCitation
+       lyxerr << "Programming error: get nonexisting second option in "
+              << name_ << " inset." << endl;; 
+       return string();
+}
+
+
+std::string const InsetCommandParams::getContents() const
+{
+       for (size_t i = 0; i < info_->n; ++i)
+               if (!info_->optional[i])
+                       return lyx::to_utf8(params_[i]);
+       BOOST_ASSERT(false);
+       return string();
+}
+
+
+void InsetCommandParams::setOptions(std::string const & o)
+{
+       for (size_t i = 0; i < info_->n; ++i)
+               if (info_->optional[i]) {
+                       params_[i] = lyx::from_utf8(o);
+                       return;
+               }
+       lyxerr << "Programming error: set nonexisting option in "
+              << name_ << " inset." << endl;; 
+}
+
+
+void InsetCommandParams::setSecOptions(std::string const & s)
+{
+       bool first = true;
+       for (size_t i = 0; i < info_->n; ++i)
+               if (info_->optional[i]) {
+                       if (first)
+                               first = false;
+                       else {
+                               params_[i] = lyx::from_utf8(s);
+                               return;
+                       }
+               }
+       // Happens in InsetCitation
+       lyxerr << "Programming error: set nonexisting second option in "
+              << name_ << " inset." << endl;; 
+}
+
+
+void InsetCommandParams::setContents(std::string const & c)
+{
+       for (size_t i = 0; i < info_->n; ++i)
+               if (!info_->optional[i]) {
+                       params_[i] = lyx::from_utf8(c);
+                       return;
+               }
+       BOOST_ASSERT(false);
+}
+
+
+docstring const & InsetCommandParams::operator[](string const & name) const
+{
+       int const i = findToken(info_->paramnames, name);
+       BOOST_ASSERT(i >= 0);
+       return params_[i];
+}
+
+
+docstring & InsetCommandParams::operator[](string const & name)
+{
+       int const i = findToken(info_->paramnames, name);
+       BOOST_ASSERT(i >= 0);
+       return params_[i];
+}
+
+
+void InsetCommandParams::clear()
+{
+       for (size_t i = 0; i < info_->n; ++i)
+               params_[i].clear();
 }
 
 
 bool operator==(InsetCommandParams const & o1,
                InsetCommandParams const & o2)
 {
-       return o1.getCmdName() == o2.getCmdName()
-               && o1.getContents() == o2.getContents()
-               && o1.getOptions() == o2.getOptions()
-               && o1.getSecOptions() == o2.getSecOptions()
-               && o1.preview() == o2.preview();
+       return o1.name_ == o2.name_ &&
+              o1.info_ == o2.info_ &&
+              o1.params_ == o2.params_ &&
+              o1.preview_ == o2.preview_;
 }
 
 
index d6c5b1074814b12523fd03af6f237ea97d31f5d8..97f871ba92399b6c812e7d07281c7e74efcf551c 100644 (file)
@@ -5,6 +5,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Angus Leeming
+ * \author Georg Baum
  *
  * Full author contact details are available in file CREDITS.
  */
 #ifndef INSETCOMMANDPARAMS_H
 #define INSETCOMMANDPARAMS_H
 
-#include <string>
+#include "support/docstring.h"
+
 #include <iosfwd>
+#include <vector>
 
 
 class LyXLex;
@@ -21,53 +24,74 @@ class LyXLex;
 
 class InsetCommandParams {
 public:
-       ///
-       InsetCommandParams();
-       ///
-       explicit InsetCommandParams(std::string const & n,
-                           std::string const & c = std::string(),
-                           std::string const & o = std::string(),
-                           std::string const & s = std::string());
+       /// Construct parameters for command \p name. \p name must be known.
+       explicit InsetCommandParams(std::string const & name);
        ///
        void read(LyXLex &);
        /// Parse the command
+       /// FIXME remove
        void scanCommand(std::string const &);
        ///
        void write(std::ostream &) const;
        /// Build the complete LaTeX command
        std::string const getCommand() const;
-       ///
-       std::string const & getCmdName() const { return cmdname; }
-       ///
-       std::string const & getOptions() const { return options; }
-       ///
-       std::string const & getSecOptions() const { return sec_options; }
-       ///
-       std::string const & getContents() const { return contents; }
-       ///
-       void setCmdName(std::string const & n) { cmdname = n; }
-       ///
-       void setOptions(std::string const & o) { options = o; }
-       ///
-       void setSecOptions(std::string const & s) { sec_options = s; }
-       ///
-       void setContents(std::string const & c) { contents = c; }
+       /// Return the command name
+       std::string const & getCmdName() const { return name_; }
+       /// FIXME remove
+       std::string const getOptions() const;
+       /// FIXME remove
+       std::string const getSecOptions() const;
+       /// FIXME remove
+       std::string const getContents() const;
+       /// Set the name to \p n. This must be a known name. All parameters
+       /// are cleared except those that exist also in the new command.
+       /// What matters here is the parameter name, not position.
+       void setCmdName(std::string const & n);
+       /// FIXME remove
+       void setOptions(std::string const &);
+       /// FIXME remove
+       void setSecOptions(std::string const &);
+       /// FIXME remove
+       void setContents(std::string const &);
+       /// get parameter \p name
+       lyx::docstring const & operator[](std::string const & name) const;
+       /// set parameter \p name
+       lyx::docstring & operator[](std::string const & name);
        ///
        bool preview() const { return preview_; }
        ///
        void preview(bool p) { preview_ = p; }
+       /// Clear the values of all parameters
+       void clear();
 
 private:
        ///
-       std::string cmdname;
-       ///
-       std::string contents;
-       ///
-       std::string options;
-       ///
-       std::string sec_options;
+       struct CommandInfo {
+               /// Number of parameters
+               size_t n;
+               /// Parameter names. paramnames[n] must be "".
+               char const * const * paramnames;
+               /// Tells whether a parameter is optional
+               bool const * optional;
+       };
+       /// Get information for command \p name.
+       /// Returns 0 if the command is not known.
+       static CommandInfo const * findInfo(std::string const & name);
+       /// Description of all command properties
+       CommandInfo const * info_;
+       /// The name of this command as it appears in .lyx and .tex files
+       std::string name_;
+       ///
+       typedef std::vector<lyx::docstring> ParamVector;
+       /// The parameters (both optional and required ones). The order is
+       /// the same that is required for LaTeX output. The size of params_
+       /// is always info_->n.
+       ParamVector params_;
        ///
        bool preview_;
+       ///
+       friend bool operator==(InsetCommandParams const &,
+                       InsetCommandParams const &);
 };
 
 
index d7e538c18e355bb57e486aae8ea281f3c1c4a5e8..0d8b3b93cc987d2477369cbdc2b523f395b253aa 100644 (file)
@@ -36,12 +36,12 @@ using std::ostream;
 
 
 InsetFloatList::InsetFloatList()
-       : InsetCommand(InsetCommandParams(), "toc")
+       : InsetCommand(InsetCommandParams("floatlist"), "toc")
 {}
 
 
 InsetFloatList::InsetFloatList(string const & type)
-       : InsetCommand(InsetCommandParams(), "toc")
+       : InsetCommand(InsetCommandParams("floatlist"), "toc")
 {
        setCmdName(type);
 }
index e904a40a09e38f79a034ece5e0f8c48d32d85895..a25756aedeeec5fb8f8c3823031f4668260e3f84 100644 (file)
@@ -126,7 +126,7 @@ void InsetInclude::doDispatch(LCursor & cur, FuncRequest & cmd)
        switch (cmd.action) {
 
        case LFUN_INSET_MODIFY: {
-               InsetCommandParams p;
+               InsetCommandParams p("include");
                InsetIncludeMailer::string2params(lyx::to_utf8(cmd.argument()), p);
                if (!p.getCmdName().empty()) {
                        set(p, cur.buffer());
@@ -761,7 +761,7 @@ string const InsetIncludeMailer::inset2string(Buffer const &) const
 void InsetIncludeMailer::string2params(string const & in,
                                       InsetCommandParams & params)
 {
-       params = InsetCommandParams();
+       params.clear();
        if (in.empty())
                return;
 
index 8cf00afa7614e2edc6bd6e4a67e88be0239eba85..53b53e29b8d2e24581f52f2d48e7b20812b7eecc 100644 (file)
@@ -64,7 +64,7 @@ void InsetLabel::doDispatch(LCursor & cur, FuncRequest & cmd)
        switch (cmd.action) {
 
        case LFUN_INSET_MODIFY: {
-               InsetCommandParams p;
+               InsetCommandParams p("label");
                InsetCommandMailer::string2params("label", lyx::to_utf8(cmd.argument()), p);
                if (p.getCmdName().empty()) {
                        cur.noUpdate();
index 6b321f523baa1d214ee7c5710aa7653eb30edcfd..2955e7205554d77205b9236ac109319113456a44 100644 (file)
@@ -87,12 +87,10 @@ docstring const InsetRef::getScreenLabel(Buffer const &) const
 int InsetRef::latex(Buffer const &, ostream & os,
                    OutputParams const &) const
 {
-       if (getOptions().empty())
-               os << escape(getCommand());
-       else {
-               InsetCommandParams p(getCmdName(), getContents(), "");
-               os << escape(p.getCommand());
-       }
+       // Don't output p_["name"], this is only used in docbook
+       InsetCommandParams p(getCmdName());
+       p["reference"] = getParam("reference");
+       os << escape(p.getCommand());
        return 0;
 }
 
index 095bf92dd6acffe60008e3876d96e55a2842f25f..4a640da966943ebef6204bfaaef9a912401e2b90 100644 (file)
@@ -1089,15 +1089,14 @@ void InsetMathHull::doDispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_LABEL_INSERT: {
                recordUndoInset(cur);
                row_type r = (type_ == hullMultline) ? nrows() - 1 : cur.row();
-               string old_label = label(r);
-               string const default_label =
-                       (lyxrc.label_init_length >= 0) ? "eq:" : "";
+               docstring old_label = lyx::from_utf8(label(r));
+               docstring const default_label = lyx::from_ascii(
+                       (lyxrc.label_init_length >= 0) ? "eq:" : "");
                if (old_label.empty())
                        old_label = default_label;
-               string const contents = cmd.argument().empty() ?
-                       old_label : lyx::to_utf8(cmd.argument());
 
-               InsetCommandParams p("label", contents);
+               InsetCommandParams p("label");
+               p["name"] = cmd.argument().empty() ? old_label : cmd.argument();
                string const data = InsetCommandMailer::params2string("label", p);
 
                if (cmd.argument().empty())
@@ -1113,7 +1112,7 @@ void InsetMathHull::doDispatch(LCursor & cur, FuncRequest & cmd)
                //lyxerr << "arg: " << lyx::to_utf8(cmd.argument()) << endl;
                string const name = cmd.getArg(0);
                if (name == "label") {
-                       InsetCommandParams p;
+                       InsetCommandParams p("label");
                        InsetCommandMailer::string2params(name, lyx::to_utf8(cmd.argument()), p);
                        string str = p.getContents();
                        recordUndoInset(cur);
index 73171abbbcc3900026139d92550191d78444da81..fd3b8a04c5200d706c9b166f58d01953471c22a6 100644 (file)
@@ -314,11 +314,6 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
                auto_ptr<InsetBase> inset(new InsetTabular(buf));
                inset->read(buf, lex);
                par.insertInset(par.size(), inset.release(), font, change);
-       } else if (token == "\\bibitem") {
-               InsetCommandParams p("bibitem", "dummy");
-               auto_ptr<InsetBibitem> inset(new InsetBibitem(p));
-               inset->read(buf, lex);
-               par.insertInset(par.size(), inset.release(), font, change);
        } else if (token == "\\hfill") {
                par.insertInset(par.size(), new InsetHFill, font, change);
        } else if (token == "\\lyxline") {
index 7de85b6c6f754e8a00d32d917d6b7ae7ec0ec152..8497102986b1298143607be72791a763ce189a4a 100644 (file)
@@ -1099,11 +1099,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
        }
 
        case LFUN_LABEL_INSERT: {
+               InsetCommandParams p("label");
                // Try to generate a valid label
-               string const contents = cmd.argument().empty() ?
-                       cur.getPossibleLabel() : lyx::to_utf8(cmd.argument());
-
-               InsetCommandParams p("label", contents);
+               p["name"] = (cmd.argument().empty()) ?
+                       // FIXME UNICODE
+                       lyx::from_utf8(cur.getPossibleLabel()) :
+                       cmd.argument();
                string const data = InsetCommandMailer::params2string("label", p);
 
                if (cmd.argument().empty()) {