Move the citation engine machinery to layouts.

Add a new layout syntax CiteEngine to define the citation commands
available for a given citation engine.

Also extend the CiteFormat syntax to allow more customization. This
mechanism, previously used to produce bibliography entries in the
citation GUI based on the BibTeX entrytype, is now also used to
produce the textual labels for citation insets in the buffer view.

Thus citation styles are almost completely customizable by modules.
Modules for the basic, jurabib and natbib engines are implemented.

Layout format incremented to 37.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40820 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Julien Rioux 2012-03-01 00:41:30 +00:00
parent 69b2843d46
commit 1e947e3a18
21 changed files with 979 additions and 781 deletions

View File

@ -1334,6 +1334,7 @@ dist_layouts_DATA =\
layouts/armenian-article.layout \ layouts/armenian-article.layout \
layouts/article.layout \ layouts/article.layout \
layouts/article-beamer.layout \ layouts/article-beamer.layout \
layouts/basic.module \
layouts/beamer.layout \ layouts/beamer.layout \
layouts/bicaption.module \ layouts/bicaption.module \
layouts/book.layout \ layouts/book.layout \
@ -1401,6 +1402,7 @@ dist_layouts_DATA =\
layouts/jsarticle.layout \ layouts/jsarticle.layout \
layouts/jsbook.layout \ layouts/jsbook.layout \
layouts/jss.layout \ layouts/jss.layout \
layouts/jurabib.module \
layouts/kluwer.layout \ layouts/kluwer.layout \
layouts/knitr.module \ layouts/knitr.module \
layouts/latex8.layout \ layouts/latex8.layout \
@ -1423,6 +1425,7 @@ dist_layouts_DATA =\
layouts/mwart.layout \ layouts/mwart.layout \
layouts/mwbk.layout \ layouts/mwbk.layout \
layouts/mwrep.layout \ layouts/mwrep.layout \
layouts/natbib.module \
layouts/noweb.module \ layouts/noweb.module \
layouts/numarticle.inc \ layouts/numarticle.inc \
layouts/numreport.inc \ layouts/numreport.inc \

41
lib/layouts/basic.module Normal file
View File

@ -0,0 +1,41 @@
# \DeclareLyXModule{Default (basic)}
# DescriptionBegin
# Use the basic citation capabilities provided by plain LaTeX.
# DescriptionEnd
# Excludes: jurabib | natbib
# Category: Citation engine
# Author: Julien Rioux <jrioux@lyx.org>
Format 37
CiteEngineType numerical
DefaultBiblio plain
CiteEngine default
cite[]
nocite
End
CiteFormat default
# translatable bits
_notcited not cited
_addtobib Add to bibliography only.
# macros
!open [
!sep ,
!close ]
!cite {%label%[[%label%]][[#%key%]]}%!nextcite%
!nextcite {%next%[[%!sep% %!cite%]]}
!nexthashkey {%next%[[%!sep% #%key%%!nexthashkey%]]}
!nextkey {%next%[[%!sep% %key%%!nextkey%]]}
!textafter {%textafter%[[, %textafter%]]}
# cite styles
cite %!open%{%dialog%[[#ID]][[%!cite%]]}%!textafter%%!close%
nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]}
End

101
lib/layouts/jurabib.module Normal file
View File

@ -0,0 +1,101 @@
# \DeclareLyXModule[jurabib.sty]{Jurabib}
# DescriptionBegin
# Loads the LaTeX package jurabib, a citation engine. Jurabib supports annotations,
# author-year style citations and hyphenation patterns for bibliography entries in
# English, German, French, Dutch, Spanish and Italian.
# DescriptionEnd
# Excludes: basic | natbib
# Category: Citation engine
# Author: Julien Rioux <jrioux@lyx.org>
Format 37
Requires jurabib
CiteEngineType authoryear
DefaultBiblio jurabib
# FIXME: support for these jurabib styles (fileformat)
# citefield []{}
# footcite [][]
# footcitetitle [][]
# footcitet [][]
# footcitep [][]
# footcitealt [][]
# footcitealp [][]
# footciteauthor [][]
# footciteyear [][]
# footciteyearpar [][]
# footfullcite [][]
CiteEngine authoryear
# \cite* is not implemented: use \cite instead, it's the same
cite [][]
citetitle [][]
citet [][]
citep [][]
citealt [][]
citealp [][]
citeauthor [][]
citeyear [][]
citeyearpar [][]
fullcite [][]
nocite
End
CiteFormat authoryear
# translatable bits
_notcited not cited
_addtobib Add to bibliography only.
_fullcite bibliography entry
_bibentry Bibliography entry.
_before before
_shorttitle short title
# macros
!open (
!sep ;
!close )
!cite %!shortauthor%%!textbefore2%%!textafter2%%!nextcite%
!citetitle %!shortauthor%%!textbefore2%%!shorttitle%%!textafter2%%!nextcitetitle%
!citet %!textbefore%%!shortauthor% %!open%%!year%%!textafter%%!close%%!nextcitet%
!citep %!open%%!citealp%%!close%
!citealt %!textbefore%%!shortauthor% %!year%%!textafter%%!nextcitealt%
!citealp %!textbefore%%!shortauthor%, %!year%%!textafter%%!nextcitealp%
!citeauthor %!textbefore%%!shortauthor%%!textafter%%!nextauthor%
!citeyear %!textbefore%%!year%%!textafter%%!nextyear%
!citeyearpar %!textbefore%%!open%%!year%%!close%%!textafter%%!nextyearpar%
!nextcite {%next%[[%!sep% %!shortauthor%%!textafter2%%!nextcite%]]}
!nextcitetitle {%next%[[%!sep% %!shortauthor%%!shorttitle%%!textafter2%%!nextcitetitle%]]}
!nextcitet {%next%[[%!sep% %!citet%]]}
!nextcitealt {%next%[[%!sep% %!citealt%]]}
!nextcitealp {%next%[[%!sep% %!citealp%]]}
!nextauthor {%next%[[%!sep% %!citeauthor%]]}
!nextyear {%next%[[%!sep% %!citeyear%]]}
!nextyearpar {%next%[[%!sep% %!citeyearpar%]]}
!nextkey {%next%[[%!sep% %key%%!nextkey%]]}
!shortauthor {%shortauthor%[[%shortauthor%]][[??]]}
!shorttitle {%shorttitle%[[ %shorttitle%]][[{%dialog%[[ <%_shorttitle%>]]}]]}
!textbefore {%textbefore%[[%textbefore% ]]}
!textbefore2 {%textbefore%[[/%textbefore%]][[{%dialog%[[/<%_before%>]]}]]}
!textafter {%textafter%[[, %textafter%]]}
!textafter2 {%textafter%[[ %textafter%]]}
!year {%year%[[%year%]][[??]]}
# cite styles
cite %!cite%
citetitle %!citetitle%
citet %!citet%
citep %!citep%
citealt %!citealt%
citealp %!citealp%
citeauthor %!citeauthor%
citeyear %!citeyear%
citeyearpar %!citeyearpar%
fullcite {%dialog%[[%_bibentry%]][[%key%%!nextkey% (%_fullcite%)]]}
nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]}
End

100
lib/layouts/natbib.module Normal file
View File

@ -0,0 +1,100 @@
# \DeclareLyXModule[natbib.sty]{Natbib}
# DescriptionBegin
# Loads the LaTeX package natbib, a citation engine. Natbib supports
# both author-year and numerical styles for citations, automatic sorting
# and merging of numerical citations, annotations, capitalization of the
# `van' part of author names, shortened and full author lists, and more.
# DescriptionEnd
# Excludes: basic | jurabib
# Category: Citation engine
# Author: Julien Rioux <jrioux@lyx.org>
Format 37
Requires natbib
CiteEngineType authoryear|numerical
DefaultBiblio plainnat
CiteEngine authoryear
Citet*[][]
Citep*[][]
Citealt*[][]
Citealp*[][]
Citeauthor*[]
citeyear[]
citeyearpar[][]
nocite
End
CiteEngine numerical
Citep*[][]
Citealp*[][]
Citet*[][]
Citealt*[][]
Citeauthor*
citeyearpar[][]
citeyear
nocite
End
CiteFormat default
# translatable bits
_notcited not cited
_addtobib Add to bibliography only.
# macros
!open [
!sep ,
!close ]
!nextauthor {%next%[[%!sep% %!abbrvauthor%%!nextauthor%]]}
!nextkey {%next%[[%!sep% %key%%!nextkey%]]}
!nextyear {%next%[[%!sep% %!year%%!nextyear%]]}
!abbrvauthor {%abbrvauthor%[[%abbrvauthor%]][[??]]}
!textbefore {%textbefore%[[%textbefore% ]]}
!textafter {%textafter%[[, %textafter%]]}
!year {%year%[[%year%]][[??]]}
# cite styles
citet %!citet%%!textafter%%!close%
citealt %!citealt%%!textafter%
citeyearpar %!open%%!textbefore%%!year%%!nextyear%%!textafter%%!close%
nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]}
End
CiteFormat authoryear
!citet %!abbrvauthor% %!open%%!textbefore%%!year%%!nextcitet%
!citealt %!abbrvauthor% %!textbefore%%!year%%!nextcitealt%
!citealp %!abbrvauthor%, %!year%%!nextcitealp%
!nextcitet {%next%[[%!close%%!sep% %!citet%]]}
!nextcitealt {%next%[[%!sep% %!citealt%]]}
!nextcitealp {%next%[[%!sep% %!citealp%]]}
cite %!citet%%!textafter%%!close%
citep %!open%%!textbefore%%!citealp%%!textafter%%!close%
citealp %!textbefore%%!citealp%%!textafter%
citeauthor %!abbrvauthor%%!nextauthor%%!textafter%
citeyear %!year%%!nextyear%%!textafter%
End
CiteFormat numerical
!citet %!abbrvauthor% %!open%%!textbefore%{%dialog%[[#ID]][[#%key%]]}%!nextcitet%
!citealt %!abbrvauthor% %!textbefore%{%dialog%[[#ID]][[#%key%]]}%!nextcitealt%
!hashkey {%dialog%[[#ID]][[#%key%%!nexthashkey%]]}
!nextcitet {%next%[[%!close%%!sep% %!citet%]]}
!nextcitealt {%next%[[%!sep% %!citealt%]]}
!nexthashid {%next%[[%!sep% #ID%!nexthashid%]]}
!nexthashkey {%next%[[%!sep% #%key%%!nexthashkey%]]}
cite %!open%%!textbefore%%!hashkey%%!textafter%%!close%
citep %!open%%!textbefore%%!hashkey%%!textafter%%!close%
citealp %!textbefore%%!hashkey%%!textafter%
citeauthor %!abbrvauthor%%!nextauthor%
citeyear %!year%%!nextyear%
End

View File

@ -125,6 +125,10 @@ import os, re, string, sys
# Incremented to format 36, 7 December 2011, by rgh # Incremented to format 36, 7 December 2011, by rgh
# Added HTMLStyles and AddToHTMLStyles tags. # Added HTMLStyles and AddToHTMLStyles tags.
# Incremented to format 37, 29 February 2012 by jrioux
# Implement the citation engine machinery in layouts.
# Change CiteFormat to CiteFormat (default|authoryear|numerical).
# Do not forget to document format change in Customization # Do not forget to document format change in Customization
# Manual (section "Declaring a new text class"). # Manual (section "Declaring a new text class").
@ -132,7 +136,7 @@ import os, re, string, sys
# development/tools/updatelayouts.sh script to update all # development/tools/updatelayouts.sh script to update all
# layout files to the new format. # layout files to the new format.
currentFormat = 36 currentFormat = 37
def usage(prog_name): def usage(prog_name):
@ -206,6 +210,7 @@ def convert(lines):
re_End = re.compile(r'^(\s*)(End)(\s*)$', re.IGNORECASE) re_End = re.compile(r'^(\s*)(End)(\s*)$', re.IGNORECASE)
re_Provides = re.compile(r'^(\s*)Provides(\S+)(\s+)(\S+)', re.IGNORECASE) re_Provides = re.compile(r'^(\s*)Provides(\S+)(\s+)(\S+)', re.IGNORECASE)
re_CharStyle = re.compile(r'^(\s*)CharStyle(\s+)(\S+)$', re.IGNORECASE) re_CharStyle = re.compile(r'^(\s*)CharStyle(\s+)(\S+)$', re.IGNORECASE)
re_CiteFormat = re.compile(r'^(\s*)(CiteFormat)(?:(\s*)()|(\s+)(default|authoryear|numerical))', re.IGNORECASE)
re_AMSMaths = re.compile(r'^\s*Input ams(?:math|def)s.inc\s*') re_AMSMaths = re.compile(r'^\s*Input ams(?:math|def)s.inc\s*')
re_AMSMathsPlain = re.compile(r'^\s*Input amsmaths-plain.inc\s*') re_AMSMathsPlain = re.compile(r'^\s*Input amsmaths-plain.inc\s*')
re_AMSMathsSeq = re.compile(r'^\s*Input amsmaths-seq.inc\s*') re_AMSMathsSeq = re.compile(r'^\s*Input amsmaths-seq.inc\s*')
@ -317,6 +322,13 @@ def convert(lines):
i += 1 i += 1
continue continue
if format == 36:
match = re_CiteFormat.match(lines[i]);
if match and match.group(4) == "":
lines[i] = match.group(0) + " default"
i += 1
continue
if format == 35: if format == 35:
i += 1 i += 1
continue continue

View File

@ -206,7 +206,7 @@ BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
{} {}
docstring const BibTeXInfo::getAbbreviatedAuthor() const docstring const BibTeXInfo::getAbbreviatedAuthor(bool jurabib_style) const
{ {
if (!is_bibtex_) { if (!is_bibtex_) {
docstring const opt = label(); docstring const opt = label();
@ -226,7 +226,7 @@ docstring const BibTeXInfo::getAbbreviatedAuthor() const
if (author.empty()) { if (author.empty()) {
author = convertLaTeXCommands(operator[]("editor")); author = convertLaTeXCommands(operator[]("editor"));
if (author.empty()) if (author.empty())
return bib_key_; return author;
} }
// FIXME Move this to a separate routine that can // FIXME Move this to a separate routine that can
@ -237,6 +237,14 @@ docstring const BibTeXInfo::getAbbreviatedAuthor() const
vector<docstring> const authors = vector<docstring> const authors =
getVectorFromString(author, from_ascii(" and ")); getVectorFromString(author, from_ascii(" and "));
if (jurabib_style && (authors.size() == 2 || authors.size() == 3)) {
docstring shortauthor = familyName(authors[0])
+ "/" + familyName(authors[1]);
if (authors.size() == 3)
shortauthor += "/" + familyName(authors[2]);
return shortauthor;
}
if (authors.size() == 2) if (authors.size() == 2)
return bformat(_("%1$s and %2$s"), return bformat(_("%1$s and %2$s"),
familyName(authors[0]), familyName(authors[1])); familyName(authors[0]), familyName(authors[1]));
@ -391,7 +399,7 @@ namespace {
docstring BibTeXInfo::expandFormat(string const & format, docstring BibTeXInfo::expandFormat(string const & format,
BibTeXInfo const * const xref, int & counter, Buffer const & buf, BibTeXInfo const * const xref, int & counter, Buffer const & buf,
bool richtext) const bool richtext, docstring before, docstring after, docstring dialog, bool next) const
{ {
// incorrect use of macros could put us in an infinite loop // incorrect use of macros could put us in an infinite loop
static int max_passes = 5000; static int max_passes = 5000;
@ -400,6 +408,7 @@ docstring BibTeXInfo::expandFormat(string const & format,
bool scanning_key = false; bool scanning_key = false;
bool scanning_rich = false; bool scanning_rich = false;
CiteEngineType const engine_type = buf.params().citeEngineType();
string fmt = format; string fmt = format;
// we'll remove characters from the front of fmt as we // we'll remove characters from the front of fmt as we
// deal with them // deal with them
@ -419,19 +428,21 @@ docstring BibTeXInfo::expandFormat(string const & format,
// so we replace the key with its value, which may be empty // so we replace the key with its value, which may be empty
if (key[0] == '!') { if (key[0] == '!') {
// macro // macro
// FIXME: instead of passing the buf, just past the macros
// FIXME: and the language code
string const val = string const val =
buf.params().documentClass().getCiteMacro(key); buf.params().documentClass().getCiteMacro(engine_type, key);
fmt = val + fmt.substr(1); fmt = val + fmt.substr(1);
continue; continue;
} else if (key[0] == '_') { } else if (key[0] == '_') {
// a translatable bit // a translatable bit
string const val = string const val =
buf.params().documentClass().getCiteMacro(key); buf.params().documentClass().getCiteMacro(engine_type, key);
docstring const trans = docstring const trans =
translateIfPossible(from_utf8(val), buf.params().language->code()); translateIfPossible(from_utf8(val), buf.params().language->code());
ret += trans; ret += trans;
} else { } else {
docstring const val = getValueForKey(key, xref); docstring const val = getValueForKey(key, before, after, dialog, xref);
ret += val; ret += val;
} }
} else { } else {
@ -457,11 +468,15 @@ docstring BibTeXInfo::expandFormat(string const & format,
if (newfmt == fmt) // parse error if (newfmt == fmt) // parse error
return _("ERROR!"); return _("ERROR!");
fmt = newfmt; fmt = newfmt;
docstring const val = getValueForKey(optkey, xref); docstring const val = getValueForKey(optkey, before, after, dialog, xref);
if (!val.empty()) if (optkey == "next" && next)
ret += expandFormat(ifpart, xref, counter, buf, richtext); ret += from_utf8(ifpart); // without expansion
else if (!val.empty())
ret += expandFormat(ifpart, xref, counter, buf,
richtext, before, after, dialog, next);
else if (!elsepart.empty()) else if (!elsepart.empty())
ret += expandFormat(elsepart, xref, counter, buf, richtext); ret += expandFormat(elsepart, xref, counter, buf,
richtext, before, after, dialog, next);
// fmt will have been shortened for us already // fmt will have been shortened for us already
continue; continue;
} }
@ -527,8 +542,9 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref,
return info_; return info_;
} }
CiteEngineType const engine_type = buf.params().citeEngineType();
DocumentClass const & dc = buf.params().documentClass(); DocumentClass const & dc = buf.params().documentClass();
string const & format = dc.getCiteFormat(to_utf8(entry_type_)); string const & format = dc.getCiteFormat(engine_type, to_utf8(entry_type_));
int counter = 0; int counter = 0;
info_ = expandFormat(format, xref, counter, buf, richtext); info_ = expandFormat(format, xref, counter, buf, richtext);
@ -538,6 +554,30 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref,
} }
docstring const BibTeXInfo::getLabel(BibTeXInfo const * const xref,
Buffer const & buf, string const & format, bool richtext,
docstring before, docstring after, docstring dialog, bool next) const
{
docstring loclabel_;
/*
if (!is_bibtex_) {
BibTeXInfo::const_iterator it = find(from_ascii("ref"));
label_ = it->second;
return label_;
}
*/
int counter = 0;
loclabel_ = expandFormat(format, xref, counter, buf, richtext,
before, after, dialog, next);
if (!loclabel_.empty())
loclabel_ = convertLaTeXCommands(loclabel_);
return loclabel_;
}
docstring const & BibTeXInfo::operator[](docstring const & field) const docstring const & BibTeXInfo::operator[](docstring const & field) const
{ {
BibTeXInfo::const_iterator it = find(field); BibTeXInfo::const_iterator it = find(field);
@ -555,12 +595,48 @@ docstring const & BibTeXInfo::operator[](string const & field) const
docstring BibTeXInfo::getValueForKey(string const & key, docstring BibTeXInfo::getValueForKey(string const & key,
BibTeXInfo const * const xref) const docstring const & before, docstring const & after, docstring const & dialog,
BibTeXInfo const * const xref) const
{ {
docstring const ret = operator[](key); docstring ret = operator[](key);
if (!ret.empty() || !xref) if (ret.empty() && xref)
ret = (*xref)[key];
if (!ret.empty())
return ret; return ret;
return (*xref)[key]; // some special keys
// FIXME: dialog, textbefore and textafter have nothing to do with this
if (key == "dialog")
return dialog;
else if (key == "entrytype")
return entry_type_;
else if (key == "key")
return bib_key_;
else if (key == "label")
return label_;
else if (key == "abbrvauthor")
// Special key to provide abbreviated author names.
return getAbbreviatedAuthor();
else if (key == "shortauthor")
// When shortauthor is not defined, jurabib automatically
// provides jurabib-style abbreviated author names. We do
// this as well.
return getAbbreviatedAuthor(true);
else if (key == "shorttitle") {
// When shorttitle is not defined, jurabib uses for `article'
// and `periodical' entries the form `journal volume [year]'
// and for other types of entries it uses the `title' field.
if (entry_type_ == "article" || entry_type_ == "periodical")
return operator[]("journal") + " " + operator[]("volume")
+ " [" + operator[]("year") + "]";
else
return operator[]("title");
} else if (key == "textbefore")
return before;
else if (key == "textafter")
return after;
else if (key == "year")
return getYear();
return ret;
} }
@ -679,6 +755,38 @@ docstring const BiblioInfo::getInfo(docstring const & key,
} }
docstring const BiblioInfo::getLabel(vector<docstring> const & keys,
Buffer const & buf, string const & style, bool richtext,
docstring const & before, docstring const & after, docstring const & dialog) const
{
CiteEngineType const engine_type = buf.params().citeEngineType();
DocumentClass const & dc = buf.params().documentClass();
string const & format = dc.getCiteFormat(engine_type, style, "cite");
docstring ret = from_utf8(format);
vector<docstring>::const_iterator key = keys.begin();
vector<docstring>::const_iterator ken = keys.end();
for (; key != ken; ++key) {
BiblioInfo::const_iterator it = find(*key);
BibTeXInfo empty_data;
empty_data.key(*key);
BibTeXInfo & data = empty_data;
BibTeXInfo const * xrefptr = 0;
if (it != end()) {
data = it->second;
docstring const xref = data.getXRef();
if (!xref.empty()) {
BiblioInfo::const_iterator const xrefit = find(xref);
if (xrefit != end())
xrefptr = &(xrefit->second);
}
}
ret = data.getLabel(xrefptr, buf, to_utf8(ret), richtext,
before, after, dialog, key+1 != ken);
}
return ret;
}
bool BiblioInfo::isBibtex(docstring const & key) const bool BiblioInfo::isBibtex(docstring const & key) const
{ {
BiblioInfo::const_iterator it = find(key); BiblioInfo::const_iterator it = find(key);
@ -688,141 +796,25 @@ bool BiblioInfo::isBibtex(docstring const & key) const
} }
vector<docstring> const BiblioInfo::getCiteStrings( vector<docstring> const BiblioInfo::getCiteStrings(
docstring const & key, Buffer const & buf) const vector<docstring> const & keys, vector<CitationStyle> const & styles,
{ Buffer const & buf, bool richtext, docstring const & before,
CiteEngineType const engine_type = buf.params().citeEngineType(); docstring const & after, docstring const & dialog) const
if (engine_type == ENGINE_TYPE_NUMERICAL)
return getNumericalStrings(key, buf);
else
return getAuthorYearStrings(key, buf);
}
vector<docstring> const BiblioInfo::getNumericalStrings(
docstring const & key, Buffer const & buf) const
{ {
if (empty()) if (empty())
return vector<docstring>(); return vector<docstring>();
docstring const author = getAbbreviatedAuthor(key); string style;
docstring const year = getYear(key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<CiteStyle> const & styles = citeStyles(buf.params().citeEngine(),
buf.params().citeEngineType());
vector<docstring> vec(styles.size()); vector<docstring> vec(styles.size());
for (size_t i = 0; i != vec.size(); ++i) { for (size_t i = 0; i != vec.size(); ++i) {
docstring str; style = styles[i].cmd;
vec[i] = getLabel(keys, buf, style, richtext, before, after, dialog);
switch (styles[i]) {
case CITE:
case CITEP:
str = from_ascii("[#ID]");
break;
case NOCITE:
str = _("Add to bibliography only.");
break;
case CITET:
str = author + " [#ID]";
break;
case CITEALT:
str = author + " #ID";
break;
case CITEALP:
str = from_ascii("#ID");
break;
case CITEAUTHOR:
str = author;
break;
case CITEYEAR:
str = year;
break;
case CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
} }
return vec; return vec;
} }
vector<docstring> const BiblioInfo::getAuthorYearStrings(
docstring const & key, Buffer const & buf) const
{
if (empty())
return vector<docstring>();
docstring const author = getAbbreviatedAuthor(key);
docstring const year = getYear(key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<CiteStyle> const & styles = citeStyles(buf.params().citeEngine(),
buf.params().citeEngineType());
vector<docstring> vec(styles.size());
for (size_t i = 0; i != vec.size(); ++i) {
docstring str;
switch (styles[i]) {
case CITE:
// jurabib only: Author/Annotator
// (i.e. the "before" field, 2nd opt arg)
str = author + "/<" + _("before") + '>';
break;
case NOCITE:
str = _("Add to bibliography only.");
break;
case CITET:
str = author + " (" + year + ')';
break;
case CITEP:
str = '(' + author + ", " + year + ')';
break;
case CITEALT:
str = author + ' ' + year ;
break;
case CITEALP:
str = author + ", " + year ;
break;
case CITEAUTHOR:
str = author;
break;
case CITEYEAR:
str = year;
break;
case CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
}
return vec;
}
void BiblioInfo::mergeBiblioInfo(BiblioInfo const & info) void BiblioInfo::mergeBiblioInfo(BiblioInfo const & info)
{ {
bimap_.insert(info.begin(), info.end()); bimap_.insert(info.begin(), info.end());
@ -947,128 +939,38 @@ void BiblioInfo::makeCitationLabels(Buffer const & buf)
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
namespace {
char const * const citeCommands[] = {
"cite", "citet", "citep", "citealt", "citealp",
"citeauthor", "citeyear", "citeyearpar", "nocite" };
unsigned int const nCiteCommands =
sizeof(citeCommands) / sizeof(char *);
CiteStyle const citeStylesArray[] = {
CITE, CITET, CITEP, CITEALT, CITEALP,
CITEAUTHOR, CITEYEAR, CITEYEARPAR, NOCITE };
unsigned int const nCiteStyles =
sizeof(citeStylesArray) / sizeof(CiteStyle);
CiteStyle const citeStylesFull[] = {
CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR };
unsigned int const nCiteStylesFull =
sizeof(citeStylesFull) / sizeof(CiteStyle);
CiteStyle const citeStylesUCase[] = {
CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR };
unsigned int const nCiteStylesUCase =
sizeof(citeStylesUCase) / sizeof(CiteStyle);
} // namespace anon
CitationStyle citationStyleFromString(string const & command) CitationStyle citationStyleFromString(string const & command)
{ {
CitationStyle s; CitationStyle cs;
if (command.empty()) if (command.empty())
return s; return cs;
string cmd = command; string cmd = command;
if (cmd[0] == 'C') { if (cmd[0] == 'C') {
s.forceUpperCase = true; cs.forceUpperCase = true;
cmd[0] = 'c'; cmd[0] = 'c';
} }
size_t const n = cmd.size() - 1; size_t const n = cmd.size() - 1;
if (cmd != "cite" && cmd[n] == '*') { if (cmd[n] == '*') {
s.full = true; cs.fullAuthorList = true;
cmd = cmd.substr(0, n); cmd = cmd.substr(0, n);
} }
char const * const * const last = citeCommands + nCiteCommands; cs.cmd = cmd;
char const * const * const ptr = find(citeCommands, last, cmd); return cs;
if (ptr != last) {
size_t idx = ptr - citeCommands;
s.style = citeStylesArray[idx];
}
return s;
} }
string citationStyleToString(const CitationStyle & s) string citationStyleToString(const CitationStyle & cs)
{ {
string cite = citeCommands[s.style]; string cmd = cs.cmd;
if (s.full) { if (cs.forceUpperCase)
CiteStyle const * last = citeStylesFull + nCiteStylesFull; cmd[0] = 'C';
if (std::find(citeStylesFull, last, s.style) != last) if (cs.fullAuthorList)
cite += '*'; cmd += '*';
} return cmd;
if (s.forceUpperCase) {
CiteStyle const * last = citeStylesUCase + nCiteStylesUCase;
if (std::find(citeStylesUCase, last, s.style) != last)
cite[0] = 'C';
}
return cite;
}
vector<CiteStyle> citeStyles(CiteEngine engine, CiteEngineType engine_type)
{
vector<CiteStyle> styles(0);
if (engine_type == ENGINE_TYPE_AUTHORYEAR) {
switch (engine) {
case ENGINE_BASIC:
styles.push_back(CITE);
break;
case ENGINE_JURABIB:
styles.push_back(CITE);
case ENGINE_NATBIB:
styles.push_back(CITET);
styles.push_back(CITEP);
styles.push_back(CITEALT);
styles.push_back(CITEALP);
styles.push_back(CITEAUTHOR);
styles.push_back(CITEYEAR);
styles.push_back(CITEYEARPAR);
break;
}
} else {
switch (engine) {
case ENGINE_BASIC:
styles.push_back(CITE);
break;
case ENGINE_JURABIB:
styles.push_back(CITE);
case ENGINE_NATBIB:
styles.push_back(CITET);
styles.push_back(CITEALT);
styles.push_back(CITEAUTHOR);
styles.push_back(CITEP);
styles.push_back(CITEALP);
styles.push_back(CITEYEAR);
styles.push_back(CITEYEARPAR);
break;
}
}
styles.push_back(NOCITE);
return styles;
} }
} // namespace lyx } // namespace lyx

View File

@ -27,9 +27,6 @@ namespace lyx {
class Buffer; class Buffer;
/// FIXME: To Citation.cpp?
/// Returns a vector of available Citation styles.
std::vector<CiteStyle> citeStyles(CiteEngine, CiteEngineType);
/// \param latex_str a LaTeX command, "cite", "Citep*", etc /// \param latex_str a LaTeX command, "cite", "Citep*", etc
CitationStyle citationStyleFromString(std::string const & latex_str); CitationStyle citationStyleFromString(std::string const & latex_str);
/// the other way round /// the other way round
@ -54,7 +51,7 @@ public:
/// constructor that sets the entryType /// constructor that sets the entryType
BibTeXInfo(docstring const & key, docstring const & type); BibTeXInfo(docstring const & key, docstring const & type);
/// \return the short form of an authorlist /// \return the short form of an authorlist
docstring const getAbbreviatedAuthor() const; docstring const getAbbreviatedAuthor(bool jurabib_style = false) const;
/// ///
docstring const getYear() const; docstring const getYear() const;
/// ///
@ -63,6 +60,10 @@ public:
/// \param pointer to crossref information /// \param pointer to crossref information
docstring const & getInfo(BibTeXInfo const * const xref, docstring const & getInfo(BibTeXInfo const * const xref,
Buffer const & buf, bool richtext) const; Buffer const & buf, bool richtext) const;
/// \return formatted BibTeX data for a citation label
docstring const getLabel(BibTeXInfo const * const xref,
Buffer const & buf, std::string const & format, bool richtext,
docstring before, docstring after, docstring dialog, bool next = false) const;
/// ///
const_iterator find(docstring const & f) const { return bimap_.find(f); } const_iterator find(docstring const & f) const { return bimap_.find(f); }
/// ///
@ -84,6 +85,8 @@ public:
/// ///
void label(docstring const & d) { label_= d; } void label(docstring const & d) { label_= d; }
/// ///
void key(docstring const & d) { bib_key_= d; }
///
docstring const & label() const { return label_; } docstring const & label() const { return label_; }
/// ///
docstring const & key() const { return bib_key_; } docstring const & key() const { return bib_key_; }
@ -106,7 +109,8 @@ private:
/// to get the data from xref BibTeXInfo object, which would normally /// to get the data from xref BibTeXInfo object, which would normally
/// be the one referenced in the crossref field. /// be the one referenced in the crossref field.
docstring getValueForKey(std::string const & key, docstring getValueForKey(std::string const & key,
BibTeXInfo const * const xref = 0) const; docstring const & before, docstring const & after, docstring const & dialog,
BibTeXInfo const * const xref = 0) const;
/// replace %keys% in a format string with their values /// replace %keys% in a format string with their values
/// called from getInfo() /// called from getInfo()
/// format strings may contain: /// format strings may contain:
@ -122,8 +126,9 @@ private:
/// moreover, keys that look like "%_key%" are treated as translatable /// moreover, keys that look like "%_key%" are treated as translatable
/// so that things like "pp." and "vol." can be translated. /// so that things like "pp." and "vol." can be translated.
docstring expandFormat(std::string const & fmt, docstring expandFormat(std::string const & fmt,
BibTeXInfo const * const xref, int & counter, BibTeXInfo const * const xref, int & counter,
Buffer const & buf, bool richtext) const; Buffer const & buf, bool richtext, docstring before = docstring(),
docstring after = docstring(), docstring dialog = docstring(), bool next = false) const;
/// true if from BibTeX; false if from bibliography environment /// true if from BibTeX; false if from bibliography environment
bool is_bibtex_; bool is_bibtex_;
/// the BibTeX key for this entry /// the BibTeX key for this entry
@ -177,38 +182,24 @@ public:
/// marked in the citation format and escape < and > elsewhere. /// marked in the citation format and escape < and > elsewhere.
docstring const getInfo(docstring const & key, Buffer const & buf, docstring const getInfo(docstring const & key, Buffer const & buf,
bool richtext = false) const; bool richtext = false) const;
/// \return formatted BibTeX data for citation labels.
/// Citation labels can have more than one key.
docstring const getLabel(std::vector<docstring> const & keys,
Buffer const & buf, std::string const & style, bool richtext = false,
docstring const & before = docstring(),
docstring const & after = docstring(),
docstring const & dialog = docstring()) const;
/// Is this a reference from a bibtex database /// Is this a reference from a bibtex database
/// or from a bibliography environment? /// or from a bibliography environment?
bool isBibtex(docstring const & key) const; bool isBibtex(docstring const & key) const;
/** /// Translates the available citation styles into strings for a given
* "Translates" the available Citation Styles into strings for a given key, /// list of keys, using either numerical or author-year style depending
* either numerical or author-year depending upon the active engine. (See /// upon the active engine.
* below for those methods.) std::vector<docstring> const getCiteStrings(std::vector<docstring> const & keys,
*/ std::vector<CitationStyle> const & styles, Buffer const & buf, bool richtext = false,
std::vector<docstring> const docstring const & before = docstring(),
getCiteStrings(docstring const & key, Buffer const & buf) const; docstring const & after = docstring(),
/** docstring const & dialog = docstring()) const;
* "Translates" the available Citation Styles into strings for a given key.
* The returned string is displayed by the GUI.
* [XX] is used in place of the actual reference
* Eg, the vector will contain: [XX], Jones et al. [XX], ...
* User supplies :
* the key,
* the buffer
*/
std::vector<docstring> const
getNumericalStrings(docstring const & key, Buffer const & buf) const;
/**
* "Translates" the available Citation Styles into strings for a given key.
* The returned string is displayed by the GUI.
* Eg, the vector will contain:
* Jones et al. (1990), (Jones et al. 1990), Jones et al. 1990, ...
* User supplies :
* the key,
* the buffer
*/
std::vector<docstring> const
getAuthorYearStrings(docstring const & key, Buffer const & buf) const;
/// Collects the cited entries from buf. /// Collects the cited entries from buf.
void collectCitedEntries(Buffer const & buf); void collectCitedEntries(Buffer const & buf);
/// A list of BibTeX keys cited in the current document, sorted by /// A list of BibTeX keys cited in the current document, sorted by

View File

@ -259,25 +259,6 @@ PackageTranslator const & packagetranslator()
// Cite engine // Cite engine
typedef Translator<string, CiteEngine> CiteEngineTranslator;
CiteEngineTranslator const init_citeenginetranslator()
{
CiteEngineTranslator translator("basic", ENGINE_BASIC);
translator.addPair("natbib", ENGINE_NATBIB);
translator.addPair("jurabib", ENGINE_JURABIB);
return translator;
}
CiteEngineTranslator const & citeenginetranslator()
{
static CiteEngineTranslator translator = init_citeenginetranslator();
return translator;
}
typedef Translator<string, CiteEngineType> CiteEngineTypeTranslator; typedef Translator<string, CiteEngineType> CiteEngineTypeTranslator;
@ -378,7 +359,7 @@ BufferParams::BufferParams()
papersize = PAPER_DEFAULT; papersize = PAPER_DEFAULT;
orientation = ORIENTATION_PORTRAIT; orientation = ORIENTATION_PORTRAIT;
use_geometry = false; use_geometry = false;
cite_engine_ = ENGINE_BASIC; cite_engine_.push_back("basic");
cite_engine_type_ = ENGINE_TYPE_NUMERICAL; cite_engine_type_ = ENGINE_TYPE_NUMERICAL;
biblio_style = "plain"; biblio_style = "plain";
use_bibtopic = false; use_bibtopic = false;
@ -726,9 +707,9 @@ string BufferParams::readToken(Lexer & lex, string const & token,
lex >> use; lex >> use;
use_package(package, packagetranslator().find(use)); use_package(package, packagetranslator().find(use));
} else if (token == "\\cite_engine") { } else if (token == "\\cite_engine") {
string engine; lex.eatLine();
lex >> engine; vector<string> engine = getVectorFromString(lex.getString());
cite_engine_ = citeenginetranslator().find(engine); setCiteEngine(engine);
} else if (token == "\\cite_engine_type") { } else if (token == "\\cite_engine_type") {
string engine_type; string engine_type;
lex >> engine_type; lex >> engine_type;
@ -1037,8 +1018,22 @@ void BufferParams::writeFile(ostream & os) const
for (size_t i = 0; i < packages.size(); ++i) for (size_t i = 0; i < packages.size(); ++i)
os << "\n\\use_package " << packages[i] << ' ' os << "\n\\use_package " << packages[i] << ' '
<< use_package(packages[i]); << use_package(packages[i]);
os << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
<< "\n\\cite_engine_type " << citeenginetypetranslator().find(cite_engine_type_) os << "\n\\cite_engine ";
if (!cite_engine_.empty()) {
LayoutModuleList::const_iterator be = cite_engine_.begin();
LayoutModuleList::const_iterator en = cite_engine_.end();
for (LayoutModuleList::const_iterator it = be; it != en; ++it) {
if (it != be)
os << ',';
os << *it;
}
} else {
os << "basic";
}
os << "\n\\cite_engine_type " << citeenginetypetranslator().find(cite_engine_type_)
<< "\n\\biblio_style " << biblio_style << "\n\\biblio_style " << biblio_style
<< "\n\\use_bibtopic " << convert<string>(use_bibtopic) << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
<< "\n\\use_indices " << convert<string>(use_indices) << "\n\\use_indices " << convert<string>(use_indices)
@ -2024,7 +2019,19 @@ void BufferParams::makeDocumentClass()
if (!baseClass()) if (!baseClass())
return; return;
doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_)); LayoutModuleList mods;
LayoutModuleList::iterator it;
LayoutModuleList::iterator en;
it = layout_modules_.begin();
en = layout_modules_.end();
for (; it != en; it++)
mods.push_back(*it);
it = cite_engine_.begin();
en = cite_engine_.end();
for (; it != en; it++)
mods.push_back(*it);
doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), mods));
if (!local_layout.empty()) { if (!local_layout.empty()) {
TextClass::ReturnValues success = TextClass::ReturnValues success =
@ -2039,7 +2046,8 @@ void BufferParams::makeDocumentClass()
bool BufferParams::moduleCanBeAdded(string const & modName) const bool BufferParams::moduleCanBeAdded(string const & modName) const
{ {
return layout_modules_.moduleCanBeAdded(modName, baseClass()); return cite_engine_.moduleCanBeAdded(modName, baseClass()) &&
layout_modules_.moduleCanBeAdded(modName, baseClass());
} }
@ -2941,19 +2949,75 @@ Encoding const & BufferParams::encoding() const
} }
CiteEngine BufferParams::citeEngine() const bool BufferParams::addCiteEngine(string const & engine)
{ {
// FIXME the class should provide the numerical/ LayoutModuleList::const_iterator it = cite_engine_.begin();
// authoryear choice LayoutModuleList::const_iterator en = cite_engine_.end();
if (documentClass().provides("natbib")) for (; it != en; ++it)
return ENGINE_NATBIB; if (*it == engine)
return cite_engine_; return false;
cite_engine_.push_back(engine);
return true;
} }
void BufferParams::setCiteEngine(CiteEngine cite_engine) bool BufferParams::addCiteEngine(vector<string> const & engine)
{ {
cite_engine_ = cite_engine; vector<string>::const_iterator it = engine.begin();
vector<string>::const_iterator en = engine.end();
bool ret = true;
for (; it != en; ++it)
if (!addCiteEngine(*it))
ret = false;
return ret;
}
string const & BufferParams::defaultBiblioStyle() const
{
return documentClass().defaultBiblioStyle();
}
bool const & BufferParams::fullAuthorList() const
{
return documentClass().fullAuthorList();
}
void BufferParams::setCiteEngine(string const & engine)
{
clearCiteEngine();
addCiteEngine(engine);
}
void BufferParams::setCiteEngine(vector<string> const & engine)
{
clearCiteEngine();
addCiteEngine(engine);
}
vector<string> BufferParams::citeCommands() const
{
static CitationStyle const default_style;
vector<string> commands =
documentClass().citeCommands(citeEngineType());
if (commands.empty())
commands.push_back(default_style.cmd);
return commands;
}
vector<CitationStyle> BufferParams::citeStyles() const
{
static CitationStyle const default_style;
vector<CitationStyle> styles =
documentClass().citeStyles(citeEngineType());
if (styles.empty())
styles.push_back(default_style);
return styles;
} }
} // namespace lyx } // namespace lyx

View File

@ -404,20 +404,37 @@ public:
bool const & use_nonlatexfonts, bool const & use_nonlatexfonts,
LaTeXFeatures & features) const; LaTeXFeatures & features) const;
/// get the appropriate cite engine (natbib handling) /// the cite engine modules
CiteEngine citeEngine() const; LayoutModuleList const & citeEngine() const
/// { return cite_engine_; }
void setCiteEngine(CiteEngine const);
/// the type of cite engine (authoryear or numerical) /// the type of cite engine (authoryear or numerical)
CiteEngineType const & citeEngineType() const CiteEngineType const & citeEngineType() const
{ return cite_engine_type_; } { return cite_engine_type_; }
/// add the module to the cite engine modules
bool addCiteEngine(std::string const &);
/// add the modules to the cite engine modules
bool addCiteEngine(std::vector<std::string> const &);
/// clear the list of cite engine modules
void clearCiteEngine() { cite_engine_.clear(); }
/// set the cite engine module
void setCiteEngine(std::string const &);
/// set the cite engine modules
void setCiteEngine(std::vector<std::string> const &);
/// set the cite engine type /// set the cite engine type
void setCiteEngineType(CiteEngineType const & engine_type) void setCiteEngineType(CiteEngineType const & engine_type)
{ cite_engine_type_ = engine_type; } { cite_engine_type_ = engine_type; }
/// the available citation commands
std::vector<std::string> citeCommands() const;
/// the available citation styles
std::vector<CitationStyle> citeStyles() const;
/// the default BibTeX style file for the document /// the default BibTeX style file for the document
std::string biblio_style; std::string biblio_style;
/// the default BibTeX style file from the TextClass
std::string const & defaultBiblioStyle() const;
/// whether the BibTeX style supports full author lists
bool const & fullAuthorList() const;
/// options for pdf output /// options for pdf output
PDFOptions & pdfoptions(); PDFOptions & pdfoptions();
@ -477,8 +494,8 @@ private:
typedef std::map<std::string, OutputParams::FLAVOR> DefaultFlavorCache; typedef std::map<std::string, OutputParams::FLAVOR> DefaultFlavorCache;
/// ///
mutable DefaultFlavorCache default_flavors_; mutable DefaultFlavorCache default_flavors_;
/// for use with natbib /// the cite engine modules
CiteEngine cite_engine_; LayoutModuleList cite_engine_;
/// the type of cite engine (authoryear or numerical) /// the type of cite engine (authoryear or numerical)
CiteEngineType cite_engine_type_; CiteEngineType cite_engine_type_;
/// ///

View File

@ -12,46 +12,36 @@
#ifndef CITATION_H #ifndef CITATION_H
#define CITATION_H #define CITATION_H
#include <string>
namespace lyx { namespace lyx {
class Buffer; class Buffer;
enum CiteEngine {
ENGINE_BASIC,
ENGINE_NATBIB,
ENGINE_JURABIB
};
enum CiteEngineType { enum CiteEngineType {
ENGINE_TYPE_AUTHORYEAR = 1, ENGINE_TYPE_AUTHORYEAR = 1,
ENGINE_TYPE_NUMERICAL = 2, ENGINE_TYPE_NUMERICAL = 2,
}; };
enum CiteStyle {
CITE,
CITET,
CITEP,
CITEALT,
CITEALP,
CITEAUTHOR,
CITEYEAR,
CITEYEARPAR,
NOCITE
};
class CitationStyle class CitationStyle
{ {
public: public:
/// ///
CitationStyle() : style(CITE), full(false), forceUpperCase(false) {} CitationStyle() : cmd("cite"), forceUpperCase(false), fullAuthorList(false),
textAfter(false), textBefore(false) {}
/// /// the LaTeX command
CiteStyle style; std::string cmd;
/// /// upper casing author prefixes (van -> Van)
bool full;
///
bool forceUpperCase; bool forceUpperCase;
/// expanding the full author list
bool fullAuthorList;
/// supports text after the citation
bool textAfter;
/// supports text before the citation
bool textBefore;
}; };
} // namespace lyx } // namespace lyx

View File

@ -60,7 +60,7 @@ namespace lyx {
// development/updatelayouts.sh script, to update the format of // development/updatelayouts.sh script, to update the format of
// all of our layout files. // all of our layout files.
// //
int const LAYOUT_FORMAT = 36; int const LAYOUT_FORMAT = 37; //jrioux : move citation engine stuff into layouts
namespace { namespace {
@ -147,8 +147,10 @@ TextClass::TextClass()
tocdepth_ = 3; tocdepth_ = 3;
pagestyle_ = "default"; pagestyle_ = "default";
defaultfont_ = sane_font; defaultfont_ = sane_font;
opt_enginetype_ = "authoryear|numerical";
opt_fontsize_ = "10|11|12"; opt_fontsize_ = "10|11|12";
opt_pagestyle_ = "empty|plain|headings|fancy"; opt_pagestyle_ = "empty|plain|headings|fancy";
cite_full_author_list_ = true;
titletype_ = TITLE_COMMAND_AFTER; titletype_ = TITLE_COMMAND_AFTER;
titlename_ = "maketitle"; titlename_ = "maketitle";
loaded_ = false; loaded_ = false;
@ -210,7 +212,11 @@ enum TextClassTags {
TC_PROVIDESMODULE, TC_PROVIDESMODULE,
TC_EXCLUDESMODULE, TC_EXCLUDESMODULE,
TC_HTMLTOCSECTION, TC_HTMLTOCSECTION,
TC_CITEFORMAT TC_CITEENGINE,
TC_CITEENGINETYPE,
TC_CITEFORMAT,
TC_DEFAULTBIBLIO,
TC_FULLAUTHORLIST,
}; };
@ -220,16 +226,20 @@ namespace {
{ "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE }, { "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE },
{ "addtohtmlstyles", TC_ADDTOHTMLSTYLES }, { "addtohtmlstyles", TC_ADDTOHTMLSTYLES },
{ "addtopreamble", TC_ADDTOPREAMBLE }, { "addtopreamble", TC_ADDTOPREAMBLE },
{ "citeengine", TC_CITEENGINE },
{ "citeenginetype", TC_CITEENGINETYPE },
{ "citeformat", TC_CITEFORMAT }, { "citeformat", TC_CITEFORMAT },
{ "classoptions", TC_CLASSOPTIONS }, { "classoptions", TC_CLASSOPTIONS },
{ "columns", TC_COLUMNS }, { "columns", TC_COLUMNS },
{ "counter", TC_COUNTER }, { "counter", TC_COUNTER },
{ "defaultbiblio", TC_DEFAULTBIBLIO },
{ "defaultfont", TC_DEFAULTFONT }, { "defaultfont", TC_DEFAULTFONT },
{ "defaultmodule", TC_DEFAULTMODULE }, { "defaultmodule", TC_DEFAULTMODULE },
{ "defaultstyle", TC_DEFAULTSTYLE }, { "defaultstyle", TC_DEFAULTSTYLE },
{ "excludesmodule", TC_EXCLUDESMODULE }, { "excludesmodule", TC_EXCLUDESMODULE },
{ "float", TC_FLOAT }, { "float", TC_FLOAT },
{ "format", TC_FORMAT }, { "format", TC_FORMAT },
{ "fullauthorlist", TC_FULLAUTHORLIST },
{ "htmlpreamble", TC_HTMLPREAMBLE }, { "htmlpreamble", TC_HTMLPREAMBLE },
{ "htmlstyles", TC_HTMLSTYLES }, { "htmlstyles", TC_HTMLSTYLES },
{ "htmltocsection", TC_HTMLTOCSECTION }, { "htmltocsection", TC_HTMLTOCSECTION },
@ -684,8 +694,27 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
error = !readFloat(lexrc); error = !readFloat(lexrc);
break; break;
case TC_CITEENGINE:
error = !readCiteEngine(lexrc);
break;
case TC_CITEENGINETYPE:
if (lexrc.next())
opt_enginetype_ = rtrim(lexrc.getString());
break;
case TC_CITEFORMAT: case TC_CITEFORMAT:
readCiteFormat(lexrc); error = !readCiteFormat(lexrc);
break;
case TC_DEFAULTBIBLIO:
if (lexrc.next())
cite_default_biblio_style_ = rtrim(lexrc.getString());
break;
case TC_FULLAUTHORLIST:
if (lexrc.next())
cite_full_author_list_ &= lexrc.getBool();
break; break;
case TC_NOCOUNTER: case TC_NOCOUNTER:
@ -913,25 +942,109 @@ void TextClass::readClassOptions(Lexer & lexrc)
} }
void TextClass::readCiteFormat(Lexer & lexrc) bool TextClass::readCiteEngine(Lexer & lexrc)
{ {
int const type = readCiteEngineType(lexrc);
if (type & ENGINE_TYPE_AUTHORYEAR)
cite_styles_[ENGINE_TYPE_AUTHORYEAR].clear();
if (type & ENGINE_TYPE_NUMERICAL)
cite_styles_[ENGINE_TYPE_NUMERICAL].clear();
string def;
bool getout = false;
while (!getout && lexrc.isOK()) {
lexrc.eatLine();
def = lexrc.getString();
def = subst(def, " ", "");
def = subst(def, "\t", "");
if (compare_ascii_no_case(def, "end") == 0) {
getout = true;
continue;
}
string cmd;
CitationStyle cs;
char ichar = def[0];
if (ichar == '#')
continue;
if (ichar == 'C') {
cs.forceUpperCase = true;
def[0] = 'c';
}
size_t const n = def.size();
for (size_t i = 0; i != n; ++i) {
ichar = def[i];
if (ichar == '*')
cs.fullAuthorList = true;
else if (ichar == '[' && cs.textAfter)
cs.textBefore = true;
else if (ichar == '[')
cs.textAfter = true;
else if (ichar != ']')
cmd += ichar;
}
cs.cmd = cmd;
if (type & ENGINE_TYPE_AUTHORYEAR)
cite_styles_[ENGINE_TYPE_AUTHORYEAR].push_back(cs);
if (type & ENGINE_TYPE_NUMERICAL)
cite_styles_[ENGINE_TYPE_NUMERICAL].push_back(cs);
}
return getout;
}
int TextClass::readCiteEngineType(Lexer & lexrc) const
{
int const ENGINE_TYPE_DEFAULT =
ENGINE_TYPE_AUTHORYEAR | ENGINE_TYPE_NUMERICAL;
if (!lexrc.next()) {
lexrc.printError("No cite engine type given for token: `$$Token'.");
return ENGINE_TYPE_DEFAULT;
}
string const type = rtrim(lexrc.getString());
if (compare_ascii_no_case(type, "authoryear") == 0)
return ENGINE_TYPE_AUTHORYEAR;
else if (compare_ascii_no_case(type, "numerical") == 0)
return ENGINE_TYPE_NUMERICAL;
else if (compare_ascii_no_case(type, "default") != 0) {
string const s = "Unknown cite engine type `" + type
+ "' given for token: `$$Token',";
lexrc.printError(s);
}
return ENGINE_TYPE_DEFAULT;
}
bool TextClass::readCiteFormat(Lexer & lexrc)
{
int const type = readCiteEngineType(lexrc);
string etype; string etype;
string definition; string definition;
while (lexrc.isOK()) { while (lexrc.isOK()) {
lexrc.next(); lexrc.next();
etype = lexrc.getString(); etype = lexrc.getString();
if (!lexrc.isOK() || compare_ascii_no_case(etype, "end") == 0) if (compare_ascii_no_case(etype, "end") == 0)
break; break;
if (!lexrc.isOK())
return false;
lexrc.eatLine(); lexrc.eatLine();
definition = lexrc.getString(); definition = lexrc.getString();
char initchar = etype[0]; char initchar = etype[0];
if (initchar == '#') if (initchar == '#')
continue; continue;
if (initchar == '!' || initchar == '_') if (initchar == '!' || initchar == '_') {
cite_macros_[etype] = definition; if (type & ENGINE_TYPE_AUTHORYEAR)
else cite_macros_[ENGINE_TYPE_AUTHORYEAR][etype] = definition;
cite_formats_[etype] = definition; if (type & ENGINE_TYPE_NUMERICAL)
cite_macros_[ENGINE_TYPE_NUMERICAL][etype] = definition;
} else {
if (type & ENGINE_TYPE_AUTHORYEAR)
cite_formats_[ENGINE_TYPE_AUTHORYEAR][etype] = definition;
if (type & ENGINE_TYPE_NUMERICAL)
cite_formats_[ENGINE_TYPE_NUMERICAL][etype] = definition;
}
} }
return true;
} }
@ -1447,24 +1560,60 @@ Layout const & DocumentClass::htmlTOCLayout() const
} }
string const & DocumentClass::getCiteFormat(string const & entry_type) const string const & DocumentClass::getCiteFormat(CiteEngineType const & type,
string const & entry, string const & fallback) const
{ {
static string default_format = "{%author%[[%author%, ]][[{%editor%[[%editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}."; static string default_format = "{%author%[[%author%, ]][[{%editor%[[%editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}.";
map<string, string>::const_iterator it = cite_formats_.find(entry_type); map<CiteEngineType, map<string, string> >::const_iterator itype = cite_formats_.find(type);
if (it != cite_formats_.end()) if (itype == cite_formats_.end())
return it->second; return default_format;
return default_format; map<string, string>::const_iterator it = itype->second.find(entry);
if (it == itype->second.end() && !fallback.empty())
it = itype->second.find(fallback);
if (it == itype->second.end())
return default_format;
return it->second;
} }
string const & DocumentClass::getCiteMacro(string const & macro) const string const & DocumentClass::getCiteMacro(CiteEngineType const & type,
string const & macro) const
{ {
static string empty; static string empty;
map<string, string>::const_iterator it = cite_macros_.find(macro); map<CiteEngineType, map<string, string> >::const_iterator itype = cite_macros_.find(type);
if (it != cite_macros_.end()) if (itype == cite_macros_.end())
return it->second; return empty;
return empty; map<string, string>::const_iterator it = itype->second.find(macro);
if (it == itype->second.end())
return empty;
return it->second;
}
vector<string> const DocumentClass::citeCommands(
CiteEngineType const & type) const
{
vector<CitationStyle> const styles = citeStyles(type);
vector<CitationStyle>::const_iterator it = styles.begin();
vector<CitationStyle>::const_iterator end = styles.end();
vector<string> cmds;
for (; it != end; ++it) {
CitationStyle const cite = *it;
cmds.push_back(cite.cmd);
}
return cmds;
}
vector<CitationStyle> const & DocumentClass::citeStyles(
CiteEngineType const & type) const
{
static vector<CitationStyle> empty;
map<CiteEngineType, vector<CitationStyle> >::const_iterator it = cite_styles_.find(type);
if (it == cite_styles_.end())
return empty;
return it->second;
} }

View File

@ -10,6 +10,7 @@
#ifndef TEXTCLASS_H #ifndef TEXTCLASS_H
#define TEXTCLASS_H #define TEXTCLASS_H
#include "Citation.h"
#include "ColorCode.h" #include "ColorCode.h"
#include "Counters.h" #include "Counters.h"
#include "FloatList.h" #include "FloatList.h"
@ -245,6 +246,8 @@ protected:
bool tex_class_avail_; bool tex_class_avail_;
/// document class prerequisites /// document class prerequisites
mutable std::string prerequisites_; mutable std::string prerequisites_;
/// The possible cite engine types
std::string opt_enginetype_;
/// ///
std::string opt_fontsize_; std::string opt_fontsize_;
/// ///
@ -311,9 +314,15 @@ protected:
/// The maximal TocLevel of sectioning layouts /// The maximal TocLevel of sectioning layouts
int max_toclevel_; int max_toclevel_;
/// Citation formatting information /// Citation formatting information
std::map<std::string, std::string> cite_formats_; std::map<CiteEngineType, std::map<std::string, std::string> > cite_formats_;
/// Citation macros /// Citation macros
std::map<std::string, std::string> cite_macros_; std::map<CiteEngineType, std::map<std::string, std::string> > cite_macros_;
/// The default BibTeX bibliography style file
std::string cite_default_biblio_style_;
/// Whether full author lists are supported
bool cite_full_author_list_;
/// The possible citation styles
std::map<CiteEngineType, std::vector<CitationStyle> > cite_styles_;
private: private:
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// helper routines for reading layout files // helper routines for reading layout files
@ -339,7 +348,11 @@ private:
/// ///
bool readFloat(Lexer &); bool readFloat(Lexer &);
/// ///
void readCiteFormat(Lexer &); bool readCiteEngine(Lexer &);
///
int readCiteEngineType(Lexer &) const;
///
bool readCiteFormat(Lexer &);
}; };
@ -390,6 +403,8 @@ public:
/// ///
Counters & counters() const { return counters_; } Counters & counters() const { return counters_; }
/// ///
std::string const & opt_enginetype() const { return opt_enginetype_; }
///
std::string const & opt_fontsize() const { return opt_fontsize_; } std::string const & opt_fontsize() const { return opt_fontsize_; }
/// ///
std::string const & opt_pagestyle() const { return opt_pagestyle_; } std::string const & opt_pagestyle() const { return opt_pagestyle_; }
@ -439,9 +454,19 @@ public:
/// returns true if the class has a ToC structure /// returns true if the class has a ToC structure
bool hasTocLevels() const; bool hasTocLevels() const;
/// ///
std::string const & getCiteFormat(std::string const & entry_type) const; std::string const & getCiteFormat(CiteEngineType const & type,
std::string const & entry, std::string const & fallback = "") const;
/// ///
std::string const & getCiteMacro(std::string const & macro) const; std::string const & getCiteMacro(CiteEngineType const & type,
std::string const & macro) const;
///
std::vector<std::string> const citeCommands(CiteEngineType const &) const;
///
std::vector<CitationStyle> const & citeStyles(CiteEngineType const &) const;
///
std::string const & defaultBiblioStyle() const { return cite_default_biblio_style_; }
///
bool const & fullAuthorList() const { return cite_full_author_list_; }
protected: protected:
/// Constructs a DocumentClass based upon a LayoutFile. /// Constructs a DocumentClass based upon a LayoutFile.
DocumentClass(LayoutFile const & tc); DocumentClass(LayoutFile const & tc);

View File

@ -504,19 +504,7 @@ QString GuiBibtex::styleFile() const
{ {
// the different bibtex packages have (and need) their // the different bibtex packages have (and need) their
// own "plain" stylefiles // own "plain" stylefiles
CiteEngine const engine = buffer().params().citeEngine(); QString defaultstyle = toqstr(buffer().params().defaultBiblioStyle());
QString defaultstyle;
switch (engine) {
case ENGINE_BASIC:
defaultstyle = "plain";
break;
case ENGINE_NATBIB:
defaultstyle = "plainnat";
break;
case ENGINE_JURABIB:
defaultstyle = "jurabib";
break;
}
QString bst = toqstr(params_["options"]); QString bst = toqstr(params_["options"]);
if (bibtotoc()){ if (bibtotoc()){

View File

@ -54,7 +54,8 @@ using namespace lyx::support;
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
static vector<CiteStyle> citeStyles_; static vector<string> citeCmds_;
static vector<CitationStyle> citeStyles_;
template<typename String> template<typename String>
@ -96,9 +97,9 @@ GuiCitation::GuiCitation(GuiView & lv)
connect(forceuppercaseCB, SIGNAL(clicked()), connect(forceuppercaseCB, SIGNAL(clicked()),
this, SLOT(changed())); this, SLOT(changed()));
connect(textBeforeED, SIGNAL(textChanged(QString)), connect(textBeforeED, SIGNAL(textChanged(QString)),
this, SLOT(changed())); this, SLOT(updateStyles()));
connect(textAfterED, SIGNAL(textChanged(QString)), connect(textAfterED, SIGNAL(textChanged(QString)),
this, SLOT(changed())); this, SLOT(updateStyles()));
connect(findLE, SIGNAL(returnPressed()), connect(findLE, SIGNAL(returnPressed()),
this, SLOT(on_searchPB_clicked())); this, SLOT(on_searchPB_clicked()));
connect(textBeforeED, SIGNAL(returnPressed()), connect(textBeforeED, SIGNAL(returnPressed()),
@ -191,84 +192,50 @@ void GuiCitation::updateControls()
// The main point of separating this out is that the fill*() methods // The main point of separating this out is that the fill*() methods
// called in update() do not need to be called for INTERNAL updates, // called in update() do not need to be called for INTERNAL updates,
// such as when addPB is pressed, as the list of fields, entries, etc, // such as when addPB is pressed, as the list of fields, entries, etc,
// will not have changed. At the moment, however, the division between // will not have changed.
// fillStyles() and updateStyle() doesn't lend itself to dividing the
// two methods, though they should be divisible. That is, we should
// not have to call fillStyles() every time through here.
void GuiCitation::updateControls(BiblioInfo const & bi) void GuiCitation::updateControls(BiblioInfo const & bi)
{ {
QModelIndex idx = selectionManager->getSelectedIndex(); QModelIndex idx = selectionManager->getSelectedIndex();
updateInfo(bi, idx); updateInfo(bi, idx);
setButtons(); selectionManager->update();
textBeforeED->setText(toqstr(params_["before"]));
textAfterED->setText(toqstr(params_["after"]));
fillStyles(bi);
updateStyle();
} }
void GuiCitation::updateFormatting(CiteStyle currentStyle) void GuiCitation::updateFormatting(CitationStyle currentStyle)
{ {
CiteEngine const engine = citeEngine(); bool const force = currentStyle.forceUpperCase;
bool const natbib_engine = engine == ENGINE_NATBIB; bool const full = currentStyle.fullAuthorList &&
bool const basic_engine = engine == ENGINE_BASIC; documentBuffer().params().fullAuthorList();
bool const textbefore = currentStyle.textBefore;
bool const textafter = currentStyle.textAfter;
bool const haveSelection = bool const haveSelection =
selectedLV->model()->rowCount() > 0; selectedLV->model()->rowCount() > 0;
bool const isNocite = currentStyle == NOCITE; forceuppercaseCB->setEnabled(force && haveSelection);
fulllistCB->setEnabled(full && haveSelection);
bool const isCiteyear = textBeforeED->setEnabled(textbefore && haveSelection);
currentStyle == CITEYEAR || textBeforeLA->setEnabled(textbefore && haveSelection);
currentStyle == CITEYEARPAR; textAfterED->setEnabled(textafter && haveSelection);
textAfterLA->setEnabled(textafter && haveSelection);
fulllistCB->setEnabled(natbib_engine && haveSelection && !isNocite
&& !isCiteyear);
forceuppercaseCB->setEnabled(natbib_engine && haveSelection
&& !isNocite && !isCiteyear);
textBeforeED->setEnabled(!basic_engine && haveSelection && !isNocite);
textBeforeLA->setEnabled(!basic_engine && haveSelection && !isNocite);
textAfterED->setEnabled(haveSelection && !isNocite);
textAfterLA->setEnabled(haveSelection && !isNocite);
citationStyleCO->setEnabled(haveSelection); citationStyleCO->setEnabled(haveSelection);
citationStyleLA->setEnabled(haveSelection); citationStyleLA->setEnabled(haveSelection);
} }
void GuiCitation::updateStyle() // Update the styles for the style combo, citationStyleCO, and mark the
// settings as changed. Called upon changing the cited keys (including
// merely reordering the keys) or editing the text before/after fields.
void GuiCitation::updateStyles()
{ {
string const & command = params_.getCmdName(); BiblioInfo const & bi = bibInfo();
updateStyles(bi);
// Find the style of the citekeys changed();
vector<CiteStyle> const & styles = citeStyles_;
CitationStyle const cs = citationStyleFromString(command);
vector<CiteStyle>::const_iterator cit =
std::find(styles.begin(), styles.end(), cs.style);
if (cit != styles.end()) {
fulllistCB->setChecked(cs.full);
forceuppercaseCB->setChecked(cs.forceUpperCase);
} else {
// restore the last used natbib style
if (style_ >= 0 && style_ < citationStyleCO->count()) {
// the necessary update will be performed later
citationStyleCO->blockSignals(true);
citationStyleCO->setCurrentIndex(style_);
citationStyleCO->blockSignals(false);
}
fulllistCB->setChecked(false);
forceuppercaseCB->setChecked(false);
}
updateFormatting(cs.style);
} }
// This one needs to be called whenever citationStyleCO needs // Update the styles for the style combo, citationStyleCO.
// to be updated---and this would be on anything that changes the void GuiCitation::updateStyles(BiblioInfo const & bi)
// selection in selectedLV, or on a general update.
void GuiCitation::fillStyles(BiblioInfo const & bi)
{ {
QStringList selected_keys = selected_model_.stringList(); QStringList selected_keys = selected_model_.stringList();
int curr = selectedLV->model()->rowCount() - 1; int curr = selectedLV->model()->rowCount() - 1;
@ -283,7 +250,7 @@ void GuiCitation::fillStyles(BiblioInfo const & bi)
if (!selectedLV->selectionModel()->selectedIndexes().empty()) if (!selectedLV->selectionModel()->selectedIndexes().empty())
curr = selectedLV->selectionModel()->selectedIndexes()[0].row(); curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
QStringList sty = citationStyles(bi, curr); QStringList sty = citationStyles(bi);
if (sty.isEmpty()) { if (sty.isEmpty()) {
// some error // some error
@ -347,7 +314,6 @@ bool GuiCitation::isSelected(QModelIndex const & idx)
void GuiCitation::setButtons() void GuiCitation::setButtons()
{ {
selectionManager->update();
int const srows = selectedLV->model()->rowCount(); int const srows = selectedLV->model()->rowCount();
applyPB->setEnabled(srows > 0); applyPB->setEnabled(srows > 0);
okPB->setEnabled(srows > 0); okPB->setEnabled(srows > 0);
@ -421,8 +387,9 @@ void GuiCitation::on_entriesCO_currentIndexChanged(int /*index*/)
void GuiCitation::on_citationStyleCO_currentIndexChanged(int index) void GuiCitation::on_citationStyleCO_currentIndexChanged(int index)
{ {
if (index >= 0 && index < citationStyleCO->count()) { if (index >= 0 && index < citationStyleCO->count()) {
vector<CiteStyle> const & styles = citeStyles_; vector<CitationStyle> const & styles = citeStyles_;
updateFormatting(styles[index]); updateFormatting(styles[index]);
changed();
} }
} }
@ -479,19 +446,18 @@ void GuiCitation::apply(int const choice, bool full, bool force,
if (cited_keys_.isEmpty()) if (cited_keys_.isEmpty())
return; return;
vector<CiteStyle> const & styles = citeStyles_; vector<CitationStyle> const & styles = citeStyles_;
if (styles[choice] == NOCITE) {
full = false;
force = false;
before.clear();
after.clear();
}
CitationStyle s; CitationStyle cs = styles[choice];
s.style = styles[choice];
s.full = full; if (!cs.textBefore)
s.forceUpperCase = force; before.clear();
string const command = citationStyleToString(s); if (!cs.textAfter)
after.clear();
cs.forceUpperCase &= force;
cs.fullAuthorList &= full;
string const command = citationStyleToString(cs);
params_.setCmdName(command); params_.setCmdName(command);
params_["key"] = qstring_to_ucs4(cited_keys_.join(",")); params_["key"] = qstring_to_ucs4(cited_keys_.join(","));
@ -522,6 +488,23 @@ void GuiCitation::init()
else else
cited_keys_ = str.split(","); cited_keys_ = str.split(",");
selected_model_.setStringList(cited_keys_); selected_model_.setStringList(cited_keys_);
// Initialize the drop downs
fillEntries(bi);
fillFields(bi);
// Initialize the citation formatting
string const & cmd = params_.getCmdName();
CitationStyle const cs = citationStyleFromString(cmd);
forceuppercaseCB->setChecked(cs.forceUpperCase);
fulllistCB->setChecked(cs.fullAuthorList &&
documentBuffer().params().fullAuthorList());
textBeforeED->setText(toqstr(params_["before"]));
textAfterED->setText(toqstr(params_["after"]));
// Update the interface
updateControls(bi);
updateStyles(bi);
if (selected_model_.rowCount()) { if (selected_model_.rowCount()) {
selectedLV->blockSignals(true); selectedLV->blockSignals(true);
selectedLV->setFocus(); selectedLV->setFocus();
@ -530,25 +513,24 @@ void GuiCitation::init()
QItemSelectionModel::ClearAndSelect); QItemSelectionModel::ClearAndSelect);
selectedLV->blockSignals(false); selectedLV->blockSignals(false);
// set the style combo appropriately // Find the citation style
string const & command = params_.getCmdName(); vector<string> const & cmds = citeCmds_;
vector<CiteStyle> const & styles = citeStyles_; vector<string>::const_iterator cit =
CitationStyle const cs = citationStyleFromString(command); std::find(cmds.begin(), cmds.end(), cs.cmd);
int i = 0;
if (cit != cmds.end())
i = int(cit - cmds.begin());
vector<CiteStyle>::const_iterator cit = // Set the style combo appropriately
std::find(styles.begin(), styles.end(), cs.style); citationStyleCO->blockSignals(true);
if (cit != styles.end()) { citationStyleCO->setCurrentIndex(i);
int const i = int(cit - styles.begin()); citationStyleCO->blockSignals(false);
// the necessary update will be performed later updateFormatting(citeStyles_[i]);
citationStyleCO->blockSignals(true);
citationStyleCO->setCurrentIndex(i);
citationStyleCO->blockSignals(false);
}
} else } else
availableLV->setFocus(); availableLV->setFocus();
fillFields(bi);
fillEntries(bi); applyPB->setEnabled(false);
updateControls(bi); okPB->setEnabled(false);
} }
@ -605,25 +587,31 @@ void GuiCitation::findKey(BiblioInfo const & bi,
} }
QStringList GuiCitation::citationStyles(BiblioInfo const & bi, int sel) QStringList GuiCitation::citationStyles(BiblioInfo const & bi)
{ {
docstring const key = qstring_to_ucs4(cited_keys_[sel]); docstring const before = qstring_to_ucs4(textBeforeED->text());
return to_qstring_list(bi.getCiteStrings(key, documentBuffer())); docstring const after = qstring_to_ucs4(textAfterED->text());
vector<docstring> const keys = to_docstring_vector(cited_keys_);
vector<CitationStyle> styles = citeStyles_;
// FIXME: pass a dictionary instead of individual before, after, dialog, etc.
vector<docstring> ret = bi.getCiteStrings(keys, styles, documentBuffer(),
false, before, after, from_utf8("dialog"));
return to_qstring_list(ret);
} }
void GuiCitation::setCitedKeys() void GuiCitation::setCitedKeys()
{ {
cited_keys_ = selected_model_.stringList(); cited_keys_ = selected_model_.stringList();
updateStyles();
} }
bool GuiCitation::initialiseParams(string const & data) bool GuiCitation::initialiseParams(string const & data)
{ {
InsetCommand::string2params(data, params_); InsetCommand::string2params(data, params_);
CiteEngine const engine = citeEngine(); citeCmds_ = documentBuffer().params().citeCommands();
CiteEngineType const engine_type = citeEngineType(); citeStyles_ = documentBuffer().params().citeStyles();
citeStyles_ = citeStyles(engine, engine_type);
init(); init();
return true; return true;
} }
@ -657,18 +645,6 @@ void GuiCitation::filterByEntryType(BiblioInfo const & bi,
} }
CiteEngine GuiCitation::citeEngine() const
{
return documentBuffer().params().citeEngine();
}
CiteEngineType GuiCitation::citeEngineType() const
{
return documentBuffer().params().citeEngineType();
}
// Escape special chars. // Escape special chars.
// All characters are literals except: '.|*?+(){}[]^$\' // All characters are literals except: '.|*?+(){}[]^$\'
// These characters are literals when preceded by a "\", which is done here // These characters are literals when preceded by a "\", which is done here

View File

@ -57,8 +57,10 @@ private Q_SLOTS:
void on_regexCB_stateChanged(int); void on_regexCB_stateChanged(int);
void on_asTypeCB_stateChanged(int); void on_asTypeCB_stateChanged(int);
void changed(); void changed();
/// /// set the citation keys, mark as changed
void setCitedKeys(); void setCitedKeys();
/// update the styles for the style combo, mark as changed
void updateStyles();
/// performs a limited update, suitable for internal call /// performs a limited update, suitable for internal call
void updateControls(); void updateControls();
@ -93,16 +95,14 @@ private:
void updateInfo(BiblioInfo const & bi, QModelIndex const &); void updateInfo(BiblioInfo const & bi, QModelIndex const &);
/// enable/disable buttons /// enable/disable buttons
void setButtons(); void setButtons();
/// fill the styles combo
void fillStyles(BiblioInfo const & bi);
/// fill the fields combo /// fill the fields combo
void fillFields(BiblioInfo const & bi); void fillFields(BiblioInfo const & bi);
/// fill the entries combo /// fill the entries combo
void fillEntries(BiblioInfo const & bi); void fillEntries(BiblioInfo const & bi);
/// set the styles combo /// set the styles combo
void updateStyle(); void updateStyles(BiblioInfo const & bi);
/// set the formatting widgets /// set the formatting widgets
void updateFormatting(CiteStyle currentStyle); void updateFormatting(CitationStyle currentStyle);
/// ///
void updateControls(BiblioInfo const & bi); void updateControls(BiblioInfo const & bi);
/// ///
@ -123,7 +123,7 @@ private:
); );
/// List of example cite strings /// List of example cite strings
QStringList citationStyles(BiblioInfo const & bi, int); QStringList citationStyles(BiblioInfo const & bi);
/// Set the Params variable for the Controller. /// Set the Params variable for the Controller.
void apply(int const choice, bool const full, bool const force, void apply(int const choice, bool const full, bool const force,
@ -132,10 +132,6 @@ private:
/// ///
void filterByEntryType(BiblioInfo const & bi, void filterByEntryType(BiblioInfo const & bi,
std::vector<docstring> & keyVector, docstring entryType); std::vector<docstring> & keyVector, docstring entryType);
///
CiteEngine citeEngine() const;
///
CiteEngineType citeEngineType() const;
/// Search a given string within the passed keys. /// Search a given string within the passed keys.
/// \return the vector of matched keys. /// \return the vector of matched keys.

View File

@ -202,6 +202,7 @@ char const * packages_gui[][4] =
}; };
vector<string> engine_types_;
vector<pair<string, QString> > pagestyles; vector<pair<string, QString> > pagestyles;
@ -2065,6 +2066,42 @@ void GuiDocument::setNumerical(bool numerical)
} }
void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
{
engine_types_.clear();
int nn = 0;
for (int n = 0; !token(items, '|', n).empty(); ++n) {
nn += 1;
string style = token(items, '|', n);
engine_types_.push_back(style);
}
switch (sel) {
case ENGINE_TYPE_AUTHORYEAR:
biblioModule->citeStyleCO->setCurrentIndex(0);
break;
case ENGINE_TYPE_NUMERICAL:
biblioModule->citeStyleCO->setCurrentIndex(1);
break;
}
biblioModule->citationStyleL->setEnabled(nn > 1);
biblioModule->citeStyleCO->setEnabled(nn > 1);
if (nn != 1)
return;
// If the textclass allows only one of authoryear or numerical,
// we have no choice but to force that engine type.
if (engine_types_[0] == "authoryear")
biblioModule->citeStyleCO->setCurrentIndex(0);
else
biblioModule->citeStyleCO->setCurrentIndex(1);
}
namespace { namespace {
// FIXME unicode // FIXME unicode
// both of these should take a vector<docstring> // both of these should take a vector<docstring>
@ -2297,12 +2334,12 @@ void GuiDocument::applyView()
bp_.use_refstyle = latexModule->refstyleCB->isChecked(); bp_.use_refstyle = latexModule->refstyleCB->isChecked();
// biblio // biblio
bp_.setCiteEngine(ENGINE_BASIC);
if (biblioModule->citeNatbibRB->isChecked()) if (biblioModule->citeNatbibRB->isChecked())
bp_.setCiteEngine(ENGINE_NATBIB); bp_.setCiteEngine("natbib");
else if (biblioModule->citeJurabibRB->isChecked()) else if (biblioModule->citeJurabibRB->isChecked())
bp_.setCiteEngine(ENGINE_JURABIB); bp_.setCiteEngine("jurabib");
else
bp_.setCiteEngine("basic");
if (biblioModule->citeStyleCO->currentIndex()) if (biblioModule->citeStyleCO->currentIndex())
bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL); bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
@ -2707,17 +2744,22 @@ void GuiDocument::paramsToDialog()
latexModule->refstyleCB->setChecked(bp_.use_refstyle); latexModule->refstyleCB->setChecked(bp_.use_refstyle);
// biblio // biblio
string const cite_engine = bp_.citeEngine().list().front();
biblioModule->citeDefaultRB->setChecked( biblioModule->citeDefaultRB->setChecked(
bp_.citeEngine() == ENGINE_BASIC); cite_engine == "basic");
biblioModule->citeJurabibRB->setChecked(
cite_engine == "jurabib");
biblioModule->citeNatbibRB->setChecked( biblioModule->citeNatbibRB->setChecked(
bp_.citeEngine() == ENGINE_NATBIB); cite_engine == "natbib");
biblioModule->citeStyleCO->setCurrentIndex( biblioModule->citeStyleCO->setCurrentIndex(
bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL); bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL);
biblioModule->citeJurabibRB->setChecked( updateEngineType(documentClass().opt_enginetype(),
bp_.citeEngine() == ENGINE_JURABIB); bp_.citeEngineType());
biblioModule->bibtopicCB->setChecked( biblioModule->bibtopicCB->setChecked(
bp_.use_bibtopic); bp_.use_bibtopic);

View File

@ -75,6 +75,7 @@ public:
void updateFontsize(std::string const &, std::string const &); void updateFontsize(std::string const &, std::string const &);
void updateFontlist(); void updateFontlist();
void updateDefaultFormat(); void updateDefaultFormat();
void updateEngineType(std::string const &, CiteEngineType const &);
void updatePagestyle(std::string const &, std::string const &); void updatePagestyle(std::string const &, std::string const &);
bool isChildIncluded(std::string const &); bool isChildIncluded(std::string const &);

View File

@ -1485,24 +1485,38 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
static_cast<InsetCommand const *>(inset); static_cast<InsetCommand const *>(inset);
Buffer const * buf = &bv->buffer(); Buffer const * buf = &bv->buffer();
docstring key = citinset->getParam("key"); string const cmd = citinset->params().getCmdName();
// we can only handle one key currently
if (contains(key, ','))
key = qstring_to_ucs4(toqstr(key).split(',')[0]);
vector<CiteStyle> citeStyleList = citeStyles(buf->params().citeEngine(), docstring const & key = citinset->getParam("key");
buf->params().citeEngineType()); if (key.empty()) {
docstring_list citeStrings = add(MenuItem(MenuItem::Command,
buf->masterBibInfo().getCiteStrings(key, bv->buffer()); qt_("No citations selected!"),
FuncRequest(LFUN_NOACTION)));
return;
}
docstring_list::const_iterator cit = citeStrings.begin(); docstring const & before = citinset->getParam("before");
docstring_list::const_iterator end = citeStrings.end(); docstring const & after = citinset->getParam("after");
size_t const n = cmd.size();
bool const force = cmd[0] == 'C';
bool const full = cmd[n] == '*';
vector<docstring> const keys = getVectorFromString(key);
vector<CitationStyle> const citeStyleList = buf->params().citeStyles();
vector<docstring> citeStrings =
buf->masterBibInfo().getCiteStrings(keys, citeStyleList, bv->buffer(),
false, before, after, from_utf8("dialog"));
vector<docstring>::const_iterator cit = citeStrings.begin();
vector<docstring>::const_iterator end = citeStrings.end();
for (int ii = 1; cit != end; ++cit, ++ii) { for (int ii = 1; cit != end; ++cit, ++ii) {
docstring label = *cit; docstring label = *cit;
CitationStyle cs; CitationStyle cs = citeStyleList[ii - 1];
CiteStyle cst = citeStyleList[ii - 1]; cs.forceUpperCase &= force;
cs.style = cst; cs.fullAuthorList &= full;
addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label), addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
FuncRequest(LFUN_INSET_MODIFY, FuncRequest(LFUN_INSET_MODIFY,
"changetype " + from_utf8(citationStyleToString(cs))))); "changetype " + from_utf8(citationStyleToString(cs)))));

View File

@ -314,8 +314,10 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
void InsetBibitem::collectBibKeys(InsetIterator const & it) const void InsetBibitem::collectBibKeys(InsetIterator const & it) const
{ {
docstring const key = getParam("key"); docstring const key = getParam("key");
docstring const label = getParam("label");
BibTeXInfo keyvalmap(false); BibTeXInfo keyvalmap(false);
keyvalmap.label(bibLabel()); keyvalmap.key(key);
keyvalmap.label(label);
DocIterator doc_it(it); DocIterator doc_it(it);
doc_it.forwardPos(); doc_it.forwardPos();
keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString( keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(

View File

@ -93,6 +93,8 @@ vector<string> const & possibleCiteCommands()
} // anon namespace } // anon namespace
// FIXME: use the citeCommands provided by the TextClass
// instead of possibleCiteCommands defined in this file.
bool InsetCitation::isCompatibleCommand(string const & cmd) bool InsetCitation::isCompatibleCommand(string const & cmd)
{ {
vector<string> const & possibles = possibleCiteCommands(); vector<string> const & possibles = possibleCiteCommands();
@ -142,71 +144,36 @@ docstring InsetCitation::toolTip(BufferView const & bv, int, int) const
namespace { namespace {
// FIXME See the header for the issue.
string defaultCiteCommand(CiteEngine engine, CiteEngineType engine_type)
{
string str;
switch (engine) {
case ENGINE_BASIC:
str = "cite";
break;
case ENGINE_NATBIB:
if (engine_type == ENGINE_TYPE_AUTHORYEAR)
str = "citet";
else
str = "citep";
break;
case ENGINE_JURABIB:
str = "cite";
break;
}
return str;
}
CitationStyle asValidLatexCommand(string const & input, vector<CitationStyle> const valid_styles)
string asValidLatexCommand(string const & input, CiteEngine const engine,
CiteEngineType const engine_type)
{ {
string const default_str = defaultCiteCommand(engine, engine_type); CitationStyle cs = valid_styles[0];
cs.forceUpperCase = false;
cs.fullAuthorList = false;
if (!InsetCitation::isCompatibleCommand(input)) if (!InsetCitation::isCompatibleCommand(input))
return default_str; return cs;
string output; string normalized_input = input;
switch (engine) { string::size_type const n = input.size() - 1;
case ENGINE_BASIC: if (input[0] == 'C')
if (input == "nocite") normalized_input[0] = 'c';
output = input; if (input[n] == '*')
else normalized_input = normalized_input.substr(0, n);
output = default_str;
break;
case ENGINE_NATBIB:
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);
vector<CitationStyle>::const_iterator it = valid_styles.begin();
vector<CitationStyle>::const_iterator end = valid_styles.end();
for (; it != end; ++it) {
CitationStyle this_cs = *it;
if (this_cs.cmd == normalized_input) {
cs = *it;
break; break;
} }
} }
return output; cs.forceUpperCase &= input[0] == 'C';
cs.fullAuthorList &= input[n] == '*';
return cs;
} }
@ -247,21 +214,12 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
if (biblist.empty()) if (biblist.empty())
return docstring(); return docstring();
// the natbib citation-styles docstring const & key = getParam("key");
// CITET: author (year) if (key.empty())
// CITEP: (author,year) return _("No citations selected!");
// CITEALT: author year
// CITEALP: author, year
// CITEAUTHOR: author
// CITEYEAR: year
// CITEYEARPAR: (year)
// jurabib supports these plus
// CITE: author/<before field>
CiteEngine const engine = buffer().params().citeEngine();
CiteEngineType const engine_type = buffer().params().citeEngineType();
// We don't currently use the full or forceUCase fields. // We don't currently use the full or forceUCase fields.
string cite_type = asValidLatexCommand(getCmdName(), engine, engine_type); string cite_type = getCmdName();
if (cite_type[0] == 'C') if (cite_type[0] == 'C')
// If we were going to use them, this would mean ForceUCase // If we were going to use them, this would mean ForceUCase
cite_type = string(1, 'c') + cite_type.substr(1); cite_type = string(1, 'c') + cite_type.substr(1);
@ -270,172 +228,16 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
cite_type = cite_type.substr(0, cite_type.size() - 1); cite_type = cite_type.substr(0, cite_type.size() - 1);
docstring const & before = getParam("before"); docstring const & before = getParam("before");
docstring before_str;
if (!before.empty()) {
// In CITET and CITEALT mode, the "before" string is
// attached to the label associated with each and every key.
// In CITEP, CITEALP and CITEYEARPAR mode, it is attached
// to the front of the whole only.
// In other modes, it is not used at all.
if (cite_type == "citet" ||
cite_type == "citealt" ||
cite_type == "citep" ||
cite_type == "citealp" ||
cite_type == "citeyearpar")
before_str = before + ' ';
// In CITE (jurabib), the "before" string is used to attach
// the annotator (of legal texts) to the author(s) of the
// first reference.
else if (cite_type == "cite")
before_str = '/' + before;
}
docstring const & after = getParam("after"); docstring const & after = getParam("after");
docstring after_str;
// The "after" key is appended only to the end of the whole.
if (cite_type == "nocite")
after_str = " (" + _("not cited") + ')';
else if (!after.empty()) {
after_str = ", " + after;
}
// One day, these might be tunable (as they are in BibTeX).
char op, cp; // opening and closing parenthesis.
const char * sep; // punctuation mark separating citation entries.
if (engine == ENGINE_BASIC) {
op = '[';
cp = ']';
sep = ",";
} else {
op = '(';
cp = ')';
sep = ";";
}
docstring const op_str = ' ' + docstring(1, op);
docstring const cp_str = docstring(1, cp) + ' ';
docstring const sep_str = from_ascii(sep) + ' ';
// FIXME: allow to add cite macros
/*
buffer().params().documentClass().addCiteMacro("!textbefore", to_utf8(before));
buffer().params().documentClass().addCiteMacro("!textafter", to_utf8(after));
*/
docstring label; docstring label;
vector<docstring> keys = getVectorFromString(getParam("key")); vector<docstring> const keys = getVectorFromString(key);
vector<docstring>::const_iterator it = keys.begin(); label = biblist.getLabel(keys, buffer(), cite_type, for_xhtml, before, after);
vector<docstring>::const_iterator end = keys.end();
for (; it != end; ++it) {
// get the bibdata corresponding to the key
docstring const author = biblist.getAbbreviatedAuthor(*it);
docstring const year = biblist.getYear(*it, for_xhtml);
docstring const citenum = for_xhtml ? biblist.getCiteNumber(*it) : *it;
if (author.empty() || year.empty())
// We can't construct a "complex" label without that info.
// So fail safely.
return docstring();
// authors1/<before>; ... ;
// authors_last, <after>
if (cite_type == "cite") {
if (engine == ENGINE_BASIC) {
label += wrapCitation(*it, citenum, for_xhtml) + sep_str;
} else if (engine == ENGINE_JURABIB) {
if (it == keys.begin())
label += wrapCitation(*it, author, for_xhtml) + before_str + sep_str;
else
label += wrapCitation(*it, author, for_xhtml) + sep_str;
}
}
// nocite
else if (cite_type == "nocite") {
label += *it + sep_str;
}
// (authors1 (<before> year); ... ;
// authors_last (<before> year, <after>)
else if (cite_type == "citet") {
switch (engine) {
case ENGINE_NATBIB:
if (engine_type == ENGINE_TYPE_AUTHORYEAR)
label += author + op_str + before_str +
wrapCitation(*it, year, for_xhtml) + cp + sep_str;
else
label += author + op_str + before_str +
wrapCitation(*it, citenum, for_xhtml) + cp + sep_str;
break;
case ENGINE_JURABIB:
label += before_str + author + op_str +
wrapCitation(*it, year, for_xhtml) + cp + sep_str;
break;
case ENGINE_BASIC:
break;
}
}
// author, year; author, year; ...
else if (cite_type == "citep" ||
cite_type == "citealp") {
if (engine_type == ENGINE_TYPE_NUMERICAL) {
label += wrapCitation(*it, citenum, for_xhtml) + sep_str;
} else {
label += wrapCitation(*it, author + ", " + year, for_xhtml) + sep_str;
}
}
// (authors1 <before> year;
// authors_last <before> year, <after>)
else if (cite_type == "citealt") {
switch (engine) {
case ENGINE_NATBIB:
if (engine_type == ENGINE_TYPE_AUTHORYEAR)
label += author + ' ' + before_str +
wrapCitation(*it, year, for_xhtml) + sep_str;
else
label += author + ' ' + before_str + '#' +
wrapCitation(*it, citenum, for_xhtml) + sep_str;
break;
case ENGINE_JURABIB:
label += before_str +
wrapCitation(*it, author + ' ' + year, for_xhtml) + sep_str;
break;
case ENGINE_BASIC:
break;
}
}
// author; author; ...
else if (cite_type == "citeauthor") {
label += wrapCitation(*it, author, for_xhtml) + sep_str;
}
// year; year; ...
else if (cite_type == "citeyear" ||
cite_type == "citeyearpar") {
label += wrapCitation(*it, year, for_xhtml) + sep_str;
}
}
label = rtrim(rtrim(label), sep);
if (!after_str.empty()) {
if (cite_type == "citet") {
// insert "after" before last ')'
label.insert(label.size() - 1, after_str);
} else {
bool const add =
!(engine == ENGINE_NATBIB &&
engine_type == ENGINE_TYPE_NUMERICAL &&
(cite_type == "citeauthor" ||
cite_type == "citeyear"));
if (add)
label += after_str;
}
}
if (!before_str.empty() && (cite_type == "citep" ||
cite_type == "citealp" ||
cite_type == "citeyearpar")) {
label = before_str + label;
}
if (cite_type == "citep" || cite_type == "citeyearpar" ||
(cite_type == "cite" && engine == ENGINE_BASIC) )
label = op + label + cp;
return label; return label;
} }
@ -565,15 +367,15 @@ void InsetCitation::forToc(docstring & os, size_t) const
// Have to overwrite the default InsetCommand method in order to check that // Have to overwrite the default InsetCommand method in order to check that
// the \cite command is valid. Eg, the user has natbib enabled, inputs some // the \cite command is valid. Eg, the user has natbib enabled, inputs some
// citations and then changes his mind, turning natbib support off. The output // citations and then changes his mind, turning natbib support off. The output
// should revert to \cite[]{} // should revert to the default citation command as provided by the citation
// engine, e.g. \cite[]{} for the basic engine.
void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
{ {
CiteEngine cite_engine = buffer().params().citeEngine(); vector<CitationStyle> citation_styles = buffer().params().citeStyles();
CiteEngineType cite_engine_type = buffer().params().citeEngineType(); CitationStyle cs = asValidLatexCommand(getCmdName(), citation_styles);
BiblioInfo const & bi = buffer().masterBibInfo(); BiblioInfo const & bi = buffer().masterBibInfo();
// FIXME UNICODE // FIXME UNICODE
docstring const cite_str = from_utf8( docstring const cite_str = from_utf8(citationStyleToString(cs));
asValidLatexCommand(getCmdName(), cite_engine, cite_engine_type));
if (runparams.inulemcmd) if (runparams.inulemcmd)
os << "\\mbox{"; os << "\\mbox{";
@ -582,9 +384,9 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
docstring const & before = getParam("before"); docstring const & before = getParam("before");
docstring const & after = getParam("after"); docstring const & after = getParam("after");
if (!before.empty() && cite_engine != ENGINE_BASIC) if (!before.empty() && cs.textBefore)
os << '[' << before << "][" << after << ']'; os << '[' << before << "][" << after << ']';
else if (!after.empty()) else if (!after.empty() && cs.textAfter)
os << '[' << after << ']'; os << '[' << after << ']';
if (!bi.isBibtex(getParam("key"))) if (!bi.isBibtex(getParam("key")))
@ -598,21 +400,6 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
} }
void InsetCitation::validate(LaTeXFeatures & features) const
{
switch (features.bufferParams().citeEngine()) {
case ENGINE_BASIC:
break;
case ENGINE_NATBIB:
features.require("natbib");
break;
case ENGINE_JURABIB:
features.require("jurabib");
break;
}
}
string InsetCitation::contextMenuName() const string InsetCitation::contextMenuName() const
{ {
return "context-citation"; return "context-citation";

View File

@ -57,7 +57,7 @@ public:
/// ///
void forToc(docstring &, size_t) const; void forToc(docstring &, size_t) const;
/// ///
void validate(LaTeXFeatures &) const; void validate(LaTeXFeatures &) const {}
/// ///
void updateBuffer(ParIterator const & it, UpdateType); void updateBuffer(ParIterator const & it, UpdateType);
/// ///
@ -70,10 +70,7 @@ public:
//@{ //@{
/// ///
static ParamInfo const & findInfo(std::string const &); static ParamInfo const & findInfo(std::string const &);
// FIXME This is the locus of the design problem we have. ///
// It really ought to do what default_cite_command() does,
// but to do that it needs to know what CiteEngine we are
// using.
static std::string defaultCommand() { return "cite"; } static std::string defaultCommand() { return "cite"; }
/// ///
static bool isCompatibleCommand(std::string const & cmd); static bool isCompatibleCommand(std::string const & cmd);