Format 26
-CiteFormat
- article %author%, "%title%", {!<i>!}%journal%{!</i>!} {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
+CiteFormat
+ # translatable bits
+ _pptext pp.
+ _edtext ed.
+ _voltext vol.
+ _numtext no.
+ _in in
+
+ # macros
+ !pages {%pages%[[, %_pptext% %pages%]]}
+ !authoredit {%author%[[%author%, ]][[{%editor%[[%editor%, %_edtext%, ]]}]]}
+ !volnum {%volume%[[ %_voltext% %volume%]][[{%number%[[%_numtext% %number%]]}]]}
+ !quotetitle "%title%"
+ !emphtitle {!<i>!}%title%{!</i>!}
+ !emphjournal {!<i>!}%journal%{!</i>!}
+
+ !insomething %author%, %!quotetitle%, %_in%{%editor%[[ %editor%, %_edtext%,]]} {!<i>!}%booktitle%{!</i>!}%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%)%!pages%.{%note%[[ %note%]]}
+
+ article %author%, %!quotetitle%, %!emphjournal% {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%)%!pages%.{%note%[[ %note%]]}
- book {%author%[[%author%, ]][[{%editor%[[%editor%, %ed_text%, ]]}]]}{!<i>!}%title%{!</i>!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
+ book %!authoredit%%!emphtitle%%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
- incollection %author%, \"%title%\", in{%editor%[[ %editor%, %ed_text%,]]} {!<i>!}%booktitle%{!</i>!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
+ incollection %!insomething%
+ inproceedings %!insomething%
thesis %author%, %title% ({%address%[[%address%: ]]}%school%, %year%).{%note%[[ %note%]]}
End
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
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()
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
// 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) {
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;
}
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 == '!'
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_);
/// 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
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;
}
}
}
+string const & DocumentClass::getCiteMacro(string const & macro) const
+{
+ static string empty;
+ map<string, string>::const_iterator it = cite_macros_.find(macro);
+ if (it != cite_macros_.end())
+ return it->second;
+ return empty;
+}
+
+
/////////////////////////////////////////////////////////////////////////
//
// PageSides
int max_toclevel_;
/// Citation formatting information
std::map<std::string, std::string> cite_formats_;
+ /// Citation macros
+ std::map<std::string, std::string> cite_macros_;
private:
///////////////////////////////////////////////////////////////////
// helper routines for reading layout files
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);