diff --git a/lib/layouts/stdciteformats.inc b/lib/layouts/stdciteformats.inc
index 6247a647fa..a5e4dd97a0 100644
--- a/lib/layouts/stdciteformats.inc
+++ b/lib/layouts/stdciteformats.inc
@@ -4,12 +4,30 @@
Format 26
-CiteFormat
- article %author%, "%title%", {!!}%journal%{!!} {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
-
- book {%author%[[%author%, ]][[{%editor%[[%editor%, %ed_text%, ]]}]]}{!!}%title%{!!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
+CiteFormat
+ # translatable bits
+ _pptext pp.
+ _edtext ed.
+ _voltext vol.
+ _numtext no.
+ _in in
- incollection %author%, \"%title%\", in{%editor%[[ %editor%, %ed_text%,]]} {!!}%booktitle%{!!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
+ # macros
+ !pages {%pages%[[, %_pptext% %pages%]]}
+ !authoredit {%author%[[%author%, ]][[{%editor%[[%editor%, %_edtext%, ]]}]]}
+ !volnum {%volume%[[ %_voltext% %volume%]][[{%number%[[%_numtext% %number%]]}]]}
+ !quotetitle "%title%"
+ !emphtitle {!!}%title%{!!}
+ !emphjournal {!!}%journal%{!!}
+
+ !insomething %author%, %!quotetitle%, %_in%{%editor%[[ %editor%, %_edtext%,]]} {!!}%booktitle%{!!}%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%)%!pages%.{%note%[[ %note%]]}
+
+ article %author%, %!quotetitle%, %!emphjournal% {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%)%!pages%.{%note%[[ %note%]]}
+
+ book %!authoredit%%!emphtitle%%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
+
+ incollection %!insomething%
+ inproceedings %!insomething%
thesis %author%, %title% ({%address%[[%address%: ]]}%school%, %year%).{%note%[[ %note%]]}
End
diff --git a/po/lyx_pot.py b/po/lyx_pot.py
index 0ac580ad17..842040776d 100755
--- a/po/lyx_pot.py
+++ b/po/lyx_pot.py
@@ -92,10 +92,14 @@ def layouts_l10n(input_files, output, base):
EndI18nPreamble = re.compile(r'\s*End(Lang)|(Babel)Preamble\s*$')
I18nString = re.compile(r'_\(([^\)]+)\)')
CounterFormat = re.compile(r'\s*PrettyFormat\s+"?(.*)"?')
-
+ CiteFormat = re.compile(r'\s*CiteFormat')
+ KeyVal = re.compile(r'^\s*_\w+\s+(.*)$')
+ End = re.compile(r'\s*End')
+
for src in input_files:
readingDescription = False
readingI18nPreamble = False
+ readingCiteFormats = False
descStartLine = -1
descLines = []
lineno = 0
@@ -179,6 +183,18 @@ def layouts_l10n(input_files, output, base):
string = res.group(1)
writeString(out, src, base, lineno, string)
continue
+ res = CiteFormat.search(line)
+ if res != None:
+ readingCiteFormats = True
+ res = End.search(line)
+ if res != None and readingCiteFormats:
+ readingCiteFormats = False
+ if readingCiteFormats:
+ res = KeyVal.search(line)
+ if res != None:
+ val = res.group(1)
+ writeString(out, src, base, lineno, val)
+
out.close()
diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp
index e7ff51e6d9..4ee075e596 100644
--- a/src/BiblioInfo.cpp
+++ b/src/BiblioInfo.cpp
@@ -395,17 +395,27 @@ namespace {
docstring BibTeXInfo::expandFormat(string const & format,
- BibTeXInfo const * const xref, bool richtext) const
+ BibTeXInfo const * const xref, Buffer const & buf,
+ bool richtext) const
{
+ // incorrect use of macros could put us in an infinite loop
+ static int max_passes = 1000;
docstring ret; // return value
string key;
bool scanning_key = false;
bool scanning_rich = false;
+ int passes = 0;
string fmt = format;
// we'll remove characters from the front of fmt as we
// deal with them
while (fmt.size()) {
+ if (passes++ > max_passes) {
+ LYXERR0("Recursion limit reached while parsing `"
+ << format << "'.");
+ return _("ERROR!");
+ }
+
char_type thischar = fmt[0];
if (thischar == '%') {
// beginning or end of key
@@ -413,14 +423,27 @@ docstring BibTeXInfo::expandFormat(string const & format,
// end of key
scanning_key = false;
// so we replace the key with its value, which may be empty
- docstring const val = getValueForKey(key, xref);
- ret += val;
- key.clear();
+ if (key[0] == '!') {
+ // macro
+ string const val =
+ buf.params().documentClass().getCiteMacro(key);
+ fmt = val + fmt.substr(1);
+ continue;
+ } else if (key[0] == '_') {
+ // a translatable bit
+ string const val =
+ buf.params().documentClass().getCiteMacro(key);
+ ret += _(val);
+ } else {
+ docstring const val = getValueForKey(key, xref);
+ ret += val;
+ }
} else {
// beginning of key
+ key.clear();
scanning_key = true;
}
- }
+ }
else if (thischar == '{') {
// beginning of option?
if (scanning_key) {
@@ -440,9 +463,9 @@ docstring BibTeXInfo::expandFormat(string const & format,
fmt = newfmt;
docstring const val = getValueForKey(optkey, xref);
if (!val.empty())
- ret += expandFormat(ifpart, xref, richtext);
+ ret += expandFormat(ifpart, xref, buf, richtext);
else if (!elsepart.empty())
- ret += expandFormat(elsepart, xref, richtext);
+ ret += expandFormat(elsepart, xref, buf, richtext);
// fmt will have been shortened for us already
continue;
}
@@ -453,7 +476,8 @@ docstring BibTeXInfo::expandFormat(string const & format,
continue;
}
}
- // we are here if the '{' was at the end of the format. hmm.
+ // we are here if '{' was not followed by % or !.
+ // So it's just a character.
ret += thischar;
}
else if (scanning_rich && thischar == '!'
@@ -497,7 +521,7 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref,
DocumentClass const & dc = buf.params().documentClass();
string const & format = dc.getCiteFormat(to_utf8(entry_type_));
- info_ = expandFormat(format, xref, richtext);
+ info_ = expandFormat(format, xref, buf, richtext);
if (!info_.empty())
info_ = convertLaTeXCommands(info_);
diff --git a/src/BiblioInfo.h b/src/BiblioInfo.h
index fffb81c639..05b61f64cb 100644
--- a/src/BiblioInfo.h
+++ b/src/BiblioInfo.h
@@ -117,8 +117,9 @@ private:
/// material intended only for rich text (HTML) output should be
/// wrapped in "{!" and "!}". it will be removed if richtext is
/// false.
- docstring expandFormat(std::string const & fmt,
- BibTeXInfo const * const xref, bool richtext) const;
+ docstring expandFormat(std::string const & fmt,
+ BibTeXInfo const * const xref,
+ Buffer const & buf, bool richtext) const;
/// true if from BibTeX; false if from bibliography environment
bool is_bibtex_;
/// the BibTeX key for this entry
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index ee43150547..6bc0bc0c8e 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -863,7 +863,13 @@ void TextClass::readCiteFormat(Lexer & lexrc)
break;
lexrc.eatLine();
definition = lexrc.getString();
- cite_formats_[etype] = definition;
+ char initchar = etype[0];
+ if (initchar == '#')
+ continue;
+ if (initchar == '!' || initchar == '_')
+ cite_macros_[etype] = definition;
+ else
+ cite_formats_[etype] = definition;
}
}
@@ -1361,6 +1367,16 @@ string const & DocumentClass::getCiteFormat(string const & entry_type) const
}
+string const & DocumentClass::getCiteMacro(string const & macro) const
+{
+ static string empty;
+ map::const_iterator it = cite_macros_.find(macro);
+ if (it != cite_macros_.end())
+ return it->second;
+ return empty;
+}
+
+
/////////////////////////////////////////////////////////////////////////
//
// PageSides
diff --git a/src/TextClass.h b/src/TextClass.h
index 52074751bd..04816c5b7f 100644
--- a/src/TextClass.h
+++ b/src/TextClass.h
@@ -306,6 +306,8 @@ protected:
int max_toclevel_;
/// Citation formatting information
std::map cite_formats_;
+ /// Citation macros
+ std::map cite_macros_;
private:
///////////////////////////////////////////////////////////////////
// helper routines for reading layout files
@@ -429,6 +431,8 @@ public:
bool hasTocLevels() const;
///
std::string const & getCiteFormat(std::string const & entry_type) const;
+ ///
+ std::string const & getCiteMacro(std::string const & macro) const;
protected:
/// Constructs a DocumentClass based upon a LayoutFile.
DocumentClass(LayoutFile const & tc);