Juergen Spitzmueller wrote:
>> I've written a little test program (attached) that I think achieves
>> this. Could you have a look?
>
> Neat. AFAICS it does just what we want.
Here's the patch against cvs. Committing now...
--
Angus
Index: src/frontends/controllers/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ChangeLog,v
retrieving revision 1.442
diff -u -p -r1.442 ChangeLog
--- src/frontends/controllers/ChangeLog 14 May 2004 13:13:19 -0000 1.442
+++ src/frontends/controllers/ChangeLog 14 May 2004 15:24:40 -0000
@@ -1,5 +1,11 @@
2004-05-14 Angus Leeming <[EMAIL PROTECTED]>
+ * biblio.[Ch] (asValidLatexCommand): new function which examines
+ the input string to return a latex citation command that is
+ valid for the current citation engine.
+
+2004-05-14 Angus Leeming <[EMAIL PROTECTED]>
+
* ControlCitation.[Ch]: small changes to use the CiteEngine_enum
wrapper class.
Index: src/frontends/controllers/biblio.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/biblio.C,v
retrieving revision 1.65
diff -u -p -r1.65 biblio.C
--- src/frontends/controllers/biblio.C 14 May 2004 13:13:19 -0000 1.65
+++ src/frontends/controllers/biblio.C 14 May 2004 15:24:41 -0000
@@ -30,6 +30,7 @@ using lyx::support::compare_ascii_no_cas
using lyx::support::contains;
using lyx::support::getVectorFromString;
using lyx::support::ltrim;
+using lyx::support::prefixIs;
using lyx::support::rtrim;
using lyx::support::split;
using lyx::support::subst;
@@ -42,6 +43,113 @@ using std::vector;
namespace biblio {
+
+namespace {
+
+vector<string> const init_possible_cite_commands()
+{
+ char const * const pos[] = {
+ "cite",
+ "citet", "citep", "citealt", "citealp",
+ "citeauthor", "citeyear", "citeyearpar",
+ "citet*", "citep*", "citealt*", "citealp*", "citeauthor*",
+ "Citet", "Citep", "Citealt", "Citealp", "Citeauthor",
+ "Citet*", "Citep*", "Citealt*", "Citealp*", "Citeauthor*",
+ "fullcite",
+ "footcite", "footcitet", "footcitep", "footcitealt",
+ "footcitealp", "footciteauthor", "footciteyear",
+ "footciteyearpar",
+ "citefield",
+ "citetitle",
+ "cite*"
+ };
+ size_t const size_pos = sizeof(pos) / sizeof(pos[0]);
+
+ return vector<string>(pos, pos + size_pos);
+}
+
+
+vector<string> const & possible_cite_commands()
+{
+ static vector<string> const pos = init_possible_cite_commands();
+ return pos;
+}
+
+
+bool is_possible_cite_command(string const & input)
+{
+ vector<string> const & possibles = possible_cite_commands();
+ vector<string>::const_iterator const end = possibles.end();
+ return std::find(possibles.begin(), end, input) != end;
+}
+
+
+string const default_cite_command(CiteEngine engine)
+{
+ string str;
+ switch (engine) {
+ case ENGINE_BASIC:
+ str = "cite";
+ break;
+ case ENGINE_NATBIB_AUTHORYEAR:
+ str = "citet";
+ break;
+ case ENGINE_NATBIB_NUMERICAL:
+ str = "citep";
+ break;
+ case ENGINE_JURABIB:
+ str = "cite";
+ break;
+ }
+ return str;
+}
+
+} // namespace anon
+
+
+string const asValidLatexCommand(string const & input,
+ CiteEngine_enum const & engine)
+{
+ string const default_str = default_cite_command(engine);
+ if (!is_possible_cite_command(input))
+ return default_str;
+
+ string output;
+ switch (engine) {
+ case ENGINE_BASIC:
+ output = default_str;
+ break;
+
+ case ENGINE_NATBIB_AUTHORYEAR:
+ case ENGINE_NATBIB_NUMERICAL:
+ if (input == "cite" || input == "citefield" ||
+ input == "citetitle" || input == "cite*")
+ output = default_str;
+ else if (prefixIs(input, "foot"))
+ output = input.substr(4);
+ else
+ output = input;
+ break;
+
+ case ENGINE_JURABIB: {
+ // Jurabib does not support the 'uppercase' natbib style.
+ if (input[0] == 'C')
+ output = string(1, 'c') + input.substr(1);
+ else
+ output = input;
+
+ // Jurabib does not support the 'full' natbib style.
+ string::size_type const n = output.size() - 1;
+ if (output != "cite*" && output[n] == '*')
+ output = output.substr(0, n);
+
+ break;
+ }
+ }
+
+ return output;
+}
+
string const familyName(string const & name)
{
Index: src/frontends/controllers/biblio.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/biblio.h,v
retrieving revision 1.20
diff -u -p -r1.20 biblio.h
--- src/frontends/controllers/biblio.h 14 May 2004 13:13:19 -0000 1.20
+++ src/frontends/controllers/biblio.h 14 May 2004 15:24:41 -0000
@@ -49,6 +49,14 @@ enum Direction {
BACKWARD
};
+
+/** Each citation engine recognizes only a subset of all possible
+ * citation commands. Given a latex command \c input, this function
+ * returns an appropriate command, valid for \c engine.
+ */
+std::string const asValidLatexCommand(std::string const & input,
+ CiteEngine_enum const & engine);
+
/// First entry is the bibliography key, second the data
typedef std::map<std::string, std::string> InfoMap;
Index: src/insets/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/ChangeLog,v
retrieving revision 1.1015
diff -u -p -r1.1015 ChangeLog
--- src/insets/ChangeLog 13 May 2004 20:44:35 -0000 1.1015
+++ src/insets/ChangeLog 14 May 2004 15:24:48 -0000
@@ -1,3 +1,8 @@
+2004-05-14 Angus Leeming <[EMAIL PROTECTED]>
+
+ * insetcite.C (getNatbibLabel, generateLabel, latex): use the
+ new biblio::asValidLatexString function.
+
2004-05-12 Angus Leeming <[EMAIL PROTECTED]>
* insetcite.C: use BufferParams::cite_engine rather than the three
Index: src/insets/insetcite.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcite.C,v
retrieving revision 1.82
diff -u -p -r1.82 insetcite.C
--- src/insets/insetcite.C 14 May 2004 13:13:20 -0000 1.82
+++ src/insets/insetcite.C 14 May 2004 15:24:48 -0000
@@ -80,12 +80,11 @@ string const getNatbibLabel(Buffer const
// CITE: author/<before field>
// We don't currently use the full or forceUCase fields.
- // bool const forceUCase = citeType[0] == 'C';
- bool const full = citeType[citeType.size() - 1] == '*';
-
- string const cite_type = full ?
- ascii_lowercase(citeType.substr(0, citeType.size() - 1)) :
- ascii_lowercase(citeType);
+ string cite_type = biblio::asValidLatexCommand(citeType, engine);
+ if (cite_type[0] == 'C')
+ cite_type = string(1, 'c') + cite_type.substr(1);
+ if (cite_type[cite_type.size() - 1] == '*')
+ cite_type = cite_type.substr(0, cite_type.size() - 1);
string before_str;
if (!before.empty()) {
@@ -270,19 +269,7 @@ string const InsetCitation::generateLabe
string label;
biblio::CiteEngine const engine = buffer.params().cite_engine;
if (engine != biblio::ENGINE_BASIC) {
- string cmd = getCmdName();
- if (cmd == "cite") {
- // We may be "upgrading" from an older LyX version.
- // If, however, we use "cite" because the necessary
- // author/year info is not present in the biblio
- // database, then getNatbibLabel will exit gracefully
- // and we'll call getBasicLabel.
- if (engine == biblio::ENGINE_NATBIB_NUMERICAL)
- cmd = "citep";
- else if (engine == biblio::ENGINE_NATBIB_AUTHORYEAR)
- cmd = "citet";
- }
- label = getNatbibLabel(buffer, cmd, getContents(),
+ label = getNatbibLabel(buffer, getCmdName(), getContents(),
before, after, engine);
}
@@ -343,30 +330,10 @@ int InsetCitation::latex(Buffer const &
OutputParams const &) const
{
biblio::CiteEngine const cite_engine = buffer.params().cite_engine;
+ string const cite_str =
+ biblio::asValidLatexCommand(getCmdName(), cite_engine);
- os << "\\";
- switch (cite_engine) {
- case biblio::ENGINE_BASIC:
- os << "cite";
- break;
- case biblio::ENGINE_NATBIB_AUTHORYEAR:
- case biblio::ENGINE_NATBIB_NUMERICAL:
- os << getCmdName();
- break;
- case biblio::ENGINE_JURABIB:
- {
- // jurabib does not (yet) support "force upper case"
- // and "full author name". Fallback.
- string cmd = getCmdName();
- if (cmd[0] == 'C')
- cmd[0] = 'c';
- size_t n = cmd.size() - 1;
- if (cmd[n] == '*')
- cmd = cmd.substr(0,n);
- os << cmd;
- break;
- }
- }
+ os << "\\" << cite_str;
string const before = getSecOptions();
string const after = getOptions();