mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
tex2lyx: support biblatex
(qualified citation lists and multibib not yet supported)
This commit is contained in:
parent
476401a76f
commit
f22213a04f
@ -1046,10 +1046,45 @@ void Preamble::handle_package(Parser &p, string const & name,
|
||||
h_biblio_options = join(options, ",");
|
||||
}
|
||||
|
||||
else if (name == "biblatex") {
|
||||
h_biblio_style = "plainnat";
|
||||
h_cite_engine = "biblatex";
|
||||
h_cite_engine_type = "authoryear";
|
||||
string opt;
|
||||
vector<string>::iterator it =
|
||||
find(options.begin(), options.end(), "natbib");
|
||||
if (it != options.end()) {
|
||||
options.erase(it);
|
||||
h_cite_engine = "biblatex-natbib";
|
||||
} else {
|
||||
opt = process_keyval_opt(options, "natbib");
|
||||
if (opt == "true")
|
||||
h_cite_engine = "biblatex-natbib";
|
||||
}
|
||||
opt = process_keyval_opt(options, "style");
|
||||
if (!opt.empty()) {
|
||||
h_biblatex_citestyle = opt;
|
||||
h_biblatex_bibstyle = opt;
|
||||
} else {
|
||||
opt = process_keyval_opt(options, "citestyle");
|
||||
if (!opt.empty())
|
||||
h_biblatex_citestyle = opt;
|
||||
opt = process_keyval_opt(options, "bibstyle");
|
||||
if (!opt.empty())
|
||||
h_biblatex_bibstyle = opt;
|
||||
}
|
||||
if (!options.empty()) {
|
||||
h_biblio_options = join(options, ",");
|
||||
options.clear();
|
||||
}
|
||||
}
|
||||
|
||||
else if (name == "jurabib") {
|
||||
h_biblio_style = "jurabib";
|
||||
h_cite_engine = "jurabib";
|
||||
h_cite_engine_type = "authoryear";
|
||||
if (!options.empty())
|
||||
h_biblio_options = join(options, ",");
|
||||
}
|
||||
|
||||
else if (name == "bibtopic")
|
||||
@ -1270,8 +1305,14 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
|
||||
os << "\\cite_engine " << h_cite_engine << '\n'
|
||||
<< "\\cite_engine_type " << h_cite_engine_type << '\n'
|
||||
<< "\\biblio_style " << h_biblio_style << "\n"
|
||||
<< "\\use_bibtopic " << h_use_bibtopic << "\n"
|
||||
<< "\\use_indices " << h_use_indices << "\n"
|
||||
<< "\\use_bibtopic " << h_use_bibtopic << "\n";
|
||||
if (!h_biblio_options.empty())
|
||||
os << "\\biblio_options " << h_biblio_options << "\n";
|
||||
if (!h_biblatex_bibstyle.empty())
|
||||
os << "\\biblatex_bibstyle " << h_biblatex_bibstyle << "\n";
|
||||
if (!h_biblatex_citestyle.empty())
|
||||
os << "\\biblatex_citestyle " << h_biblatex_citestyle << "\n";
|
||||
os << "\\use_indices " << h_use_indices << "\n"
|
||||
<< "\\paperorientation " << h_paperorientation << '\n'
|
||||
<< "\\suppress_date " << h_suppress_date << '\n'
|
||||
<< "\\justification " << h_justification << '\n'
|
||||
@ -1566,6 +1607,14 @@ void Preamble::parse(Parser & p, string const & forceclass,
|
||||
p.skip_spaces();
|
||||
}
|
||||
|
||||
else if (t.cs() == "addbibresource")
|
||||
biblatex_bibliographies.push_back(removeExtension(p.getArg('{', '}')));
|
||||
|
||||
else if (t.cs() == "bibliography") {
|
||||
vector<string> bibs = getVectorFromString(p.getArg('{', '}'));
|
||||
biblatex_bibliographies.insert(biblatex_bibliographies.end(), bibs.begin(), bibs.end());
|
||||
}
|
||||
|
||||
else if (t.cs() == "RS@ifundefined") {
|
||||
string const name = p.verbatim_item();
|
||||
string const body1 = p.verbatim_item();
|
||||
|
@ -104,6 +104,8 @@ public:
|
||||
static const char * const polyglossia_languages[];
|
||||
/// the same as polyglossia_languages with .lyx names
|
||||
static const char * const coded_polyglossia_languages[];
|
||||
///
|
||||
std::vector<std::string> biblatex_bibliographies;
|
||||
|
||||
private:
|
||||
///
|
||||
@ -132,6 +134,9 @@ private:
|
||||
std::ostringstream h_preamble;
|
||||
std::string h_backgroundcolor;
|
||||
std::string h_biblio_style;
|
||||
std::string h_biblio_options;
|
||||
std::string h_biblatex_bibstyle;
|
||||
std::string h_biblatex_citestyle;
|
||||
std::string h_bibtex_command;
|
||||
std::string h_boxbgcolor;
|
||||
std::string h_cite_engine;
|
||||
|
@ -102,34 +102,6 @@ Format LaTeX feature LyX feature
|
||||
- cjkangle (angle brackets) \begin_inset Quotes k..
|
||||
526
|
||||
Plural and capitalized refstyles InsetRef
|
||||
528 Biblatex
|
||||
\usepackage{biblatex} \cite_engine biblatex
|
||||
...[...natbib=true...]... \cite_engine biblatex-natbib
|
||||
...[...style=<val>...]... \biblatex_bibstyle <val>
|
||||
\biblatex_citestyle <val>
|
||||
...[...bibstyle=<val>...]... \biblatex_bibstyle <val>
|
||||
...[...citestyle=<val>...]... \biblatex_citestyle <val>
|
||||
...[...<any other opt>...]... \biblio_options <any other opt>
|
||||
\printbibliography[<opts>] \begin_inset CommandInset bibtex
|
||||
biblatexopts "<opts>"
|
||||
\addbibresource{file.bib} \begin_inset CommandInset bibtex
|
||||
[multiple possible!] bibfiles "...,file,..." [NB: strip ext!]
|
||||
\bibliography{file1,file2,...} \begin_inset CommandInset bibtex
|
||||
bibfiles "...,file1,file2,..."
|
||||
\begin_inset CommandInset citation
|
||||
\Cite LatexCmd Cite
|
||||
\cite* LatexCmd citeyear
|
||||
\citeyear LatexCmd citebyear
|
||||
\{T,t}extcite LatexCmd {C,c}itet
|
||||
\{P,p}arencite LatexCmd {C,c}itep
|
||||
\parencite* LatexCmd citeyearpar
|
||||
\{S,s}martcite LatexCmd {F,f}ootcite
|
||||
\{F,f}ootcite LatexCmd {F,f}ootcite
|
||||
\{A,a}utocite LatexCmd {A,a}utocite
|
||||
\citecite[*] LatexCmd citecite[*]
|
||||
\fullcite LatexCmd fullcite
|
||||
\footfullcite LatexCmd footfullcite
|
||||
\supercite LatexCmd supercite
|
||||
531 Biblatex "qualified citation lists"
|
||||
\cites(pre)(post)[pre1][post1]{key1}[pre2][post2]{key2}...
|
||||
\begin_inset CommandInset citation
|
||||
|
@ -874,6 +874,8 @@ bool tex2lyx(idocstream & is, ostream & os, string const & encoding,
|
||||
context.font.language = preamble.defaultLanguage();
|
||||
// parse the main text
|
||||
parse_text(p, ss, FLAG_END, true, context);
|
||||
// check if we need a commented bibtex inset (biblatex)
|
||||
check_comment_bib(ss, context);
|
||||
if (Context::empty)
|
||||
// Empty document body. LyX needs at least one paragraph.
|
||||
context.check_layout(ss);
|
||||
|
@ -49,6 +49,7 @@ std::string translate_len(std::string const &);
|
||||
|
||||
void parse_text(Parser & p, std::ostream & os, unsigned flags, bool outer,
|
||||
Context & context);
|
||||
void check_comment_bib(std::ostream & os, Context & context);
|
||||
|
||||
/*!
|
||||
* Parses a subdocument, usually useful in insets (whence the name).
|
||||
|
@ -184,6 +184,18 @@ char const * const known_jurabib_commands[] = { "cite", "citet", "citep",
|
||||
// "footciteauthor", "footciteyear", "footciteyearpar",
|
||||
"citefield", "citetitle", 0 };
|
||||
|
||||
/*!
|
||||
* biblatex commands.
|
||||
* Known starred forms: \cite*, \citeauthor*, \Citeauthor*, \parencite*, \citetitle*.
|
||||
*/
|
||||
char const * const known_biblatex_commands[] = { "cite", "Cite", "textcite", "Textcite",
|
||||
"parencite", "Parencite", "citeauthor", "Citeauthor", "citeyear", "smartcite", "Smartcite",
|
||||
"footcite", "Footcite", "autocite", "Autocite", "citetitle", "fullcite", "footfullcite",
|
||||
"supercite", 0 };
|
||||
|
||||
// Whether we need to insert a bibtex inset in a comment
|
||||
bool need_commentbib = false;
|
||||
|
||||
/// LaTeX names for quotes
|
||||
char const * const known_quotes[] = { "dq", "guillemotleft", "flqq", "og",
|
||||
"guillemotright", "frqq", "fg", "glq", "glqq", "textquoteleft", "grq", "grqq",
|
||||
@ -2482,6 +2494,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
string bibliographystyle;
|
||||
bool const use_natbib = isProvided("natbib");
|
||||
bool const use_jurabib = isProvided("jurabib");
|
||||
bool const use_biblatex = isProvided("biblatex")
|
||||
&& preamble.citeEngine() != "biblatex-natbib";
|
||||
bool const use_biblatex_natbib = isProvided("biblatex-natbib")
|
||||
|| (isProvided("biblatex") && preamble.citeEngine() == "biblatex-natbib");
|
||||
need_commentbib = use_biblatex || use_biblatex_natbib;
|
||||
string last_env;
|
||||
|
||||
// it is impossible to determine the correct encoding for non-CJK Japanese.
|
||||
@ -3819,6 +3836,157 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
preamble.citeEngine("natbib");
|
||||
}
|
||||
|
||||
else if (use_biblatex
|
||||
&& is_known(t.cs(), known_biblatex_commands)
|
||||
&& ((t.cs() == "cite"
|
||||
|| t.cs() == "citeauthor"
|
||||
|| t.cs() == "Citeauthor"
|
||||
|| t.cs() == "parencite"
|
||||
|| t.cs() == "citetitle")
|
||||
|| p.next_token().asInput() != "*")) {
|
||||
context.check_layout(os);
|
||||
string command = t.cs();
|
||||
if (p.next_token().asInput() == "*") {
|
||||
command += '*';
|
||||
p.get_token();
|
||||
}
|
||||
|
||||
// text before the citation
|
||||
string before;
|
||||
// text after the citation
|
||||
string after;
|
||||
get_cite_arguments(p, true, before, after);
|
||||
|
||||
// These use natbib cmd names in LyX
|
||||
// for inter-citeengine compativility
|
||||
if (command == "citeyear")
|
||||
command = "citebyear";
|
||||
else if (command == "cite*")
|
||||
command = "citeyear";
|
||||
else if (command == "textcite")
|
||||
command = "citet";
|
||||
else if (command == "Textcite")
|
||||
command = "Citet";
|
||||
else if (command == "parencite")
|
||||
command = "citep";
|
||||
else if (command == "Parencite")
|
||||
command = "Citep";
|
||||
else if (command == "parencite*")
|
||||
command = "citeyearpar";
|
||||
else if (command == "smartcite")
|
||||
command = "footcite";
|
||||
else if (command == "Smartcite")
|
||||
command = "Footcite";
|
||||
|
||||
if (before.empty() && after == "[]")
|
||||
// avoid \cite[]{a}
|
||||
after.erase();
|
||||
else if (before == "[]" && after == "[]") {
|
||||
// avoid \cite[][]{a}
|
||||
before.erase();
|
||||
after.erase();
|
||||
}
|
||||
// remove the brackets around after and before
|
||||
if (!after.empty()) {
|
||||
after.erase(0, 1);
|
||||
after.erase(after.length() - 1, 1);
|
||||
after = convert_command_inset_arg(after);
|
||||
}
|
||||
if (!before.empty()) {
|
||||
before.erase(0, 1);
|
||||
before.erase(before.length() - 1, 1);
|
||||
before = convert_command_inset_arg(before);
|
||||
}
|
||||
begin_command_inset(os, "citation", command);
|
||||
os << "after " << '"' << after << '"' << "\n";
|
||||
os << "before " << '"' << before << '"' << "\n";
|
||||
os << "key \""
|
||||
<< convert_command_inset_arg(p.verbatim_item())
|
||||
<< "\"\n"
|
||||
<< "literal \"true\"\n";
|
||||
end_inset(os);
|
||||
// Need to set the cite engine if biblatex is loaded by
|
||||
// the document class directly
|
||||
if (preamble.citeEngine() == "basic")
|
||||
preamble.citeEngine("biblatex");
|
||||
}
|
||||
|
||||
else if (use_biblatex_natbib
|
||||
&& (is_known(t.cs(), known_biblatex_commands)
|
||||
|| is_known(t.cs(), known_natbib_commands))
|
||||
&& ((t.cs() == "cite" || t.cs() == "citet" || t.cs() == "Citet"
|
||||
|| t.cs() == "citep" || t.cs() == "Citep" || t.cs() == "citealt"
|
||||
|| t.cs() == "Citealt" || t.cs() == "citealp" || t.cs() == "Citealp"
|
||||
|| t.cs() == "citeauthor" || t.cs() == "Citeauthor"
|
||||
|| t.cs() == "parencite" || t.cs() == "citetitle")
|
||||
|| p.next_token().asInput() != "*")) {
|
||||
context.check_layout(os);
|
||||
string command = t.cs();
|
||||
if (p.next_token().asInput() == "*") {
|
||||
command += '*';
|
||||
p.get_token();
|
||||
}
|
||||
|
||||
// text before the citation
|
||||
string before;
|
||||
// text after the citation
|
||||
string after;
|
||||
get_cite_arguments(p, true, before, after);
|
||||
|
||||
// These use natbib cmd names in LyX
|
||||
// for inter-citeengine compativility
|
||||
if (command == "citeyear")
|
||||
command = "citebyear";
|
||||
else if (command == "cite*")
|
||||
command = "citeyear";
|
||||
else if (command == "textcite")
|
||||
command = "citet";
|
||||
else if (command == "Textcite")
|
||||
command = "Citet";
|
||||
else if (command == "parencite")
|
||||
command = "citep";
|
||||
else if (command == "Parencite")
|
||||
command = "Citep";
|
||||
else if (command == "parencite*")
|
||||
command = "citeyearpar";
|
||||
else if (command == "smartcite")
|
||||
command = "footcite";
|
||||
else if (command == "Smartcite")
|
||||
command = "Footcite";
|
||||
|
||||
if (before.empty() && after == "[]")
|
||||
// avoid \cite[]{a}
|
||||
after.erase();
|
||||
else if (before == "[]" && after == "[]") {
|
||||
// avoid \cite[][]{a}
|
||||
before.erase();
|
||||
after.erase();
|
||||
}
|
||||
// remove the brackets around after and before
|
||||
if (!after.empty()) {
|
||||
after.erase(0, 1);
|
||||
after.erase(after.length() - 1, 1);
|
||||
after = convert_command_inset_arg(after);
|
||||
}
|
||||
if (!before.empty()) {
|
||||
before.erase(0, 1);
|
||||
before.erase(before.length() - 1, 1);
|
||||
before = convert_command_inset_arg(before);
|
||||
}
|
||||
begin_command_inset(os, "citation", command);
|
||||
os << "after " << '"' << after << '"' << "\n";
|
||||
os << "before " << '"' << before << '"' << "\n";
|
||||
os << "key \""
|
||||
<< convert_command_inset_arg(p.verbatim_item())
|
||||
<< "\"\n"
|
||||
<< "literal \"true\"\n";
|
||||
end_inset(os);
|
||||
// Need to set the cite engine if biblatex is loaded by
|
||||
// the document class directly
|
||||
if (preamble.citeEngine() == "basic")
|
||||
preamble.citeEngine("biblatex-natbib");
|
||||
}
|
||||
|
||||
else if (use_jurabib &&
|
||||
is_known(t.cs(), known_jurabib_commands) &&
|
||||
(t.cs() == "cite" || p.next_token().asInput() != "*")) {
|
||||
@ -4463,6 +4631,46 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
end_inset(os);
|
||||
}
|
||||
|
||||
else if (t.cs() == "printbibliography") {
|
||||
context.check_layout(os);
|
||||
string BibOpts;
|
||||
string bbloptions = p.hasOpt() ? p.getArg('[', ']') : string();
|
||||
vector<string> opts = getVectorFromString(bbloptions);
|
||||
vector<string>::iterator it =
|
||||
find(opts.begin(), opts.end(), "heading=bibintoc");
|
||||
if (it != opts.end()) {
|
||||
opts.erase(it);
|
||||
BibOpts = "bibtotoc";
|
||||
}
|
||||
bbloptions = getStringFromVector(opts);
|
||||
begin_command_inset(os, "bibtex", "bibtex");
|
||||
if (!btprint.empty()) {
|
||||
os << "btprint " << '"' << "btPrintAll" << '"' << "\n";
|
||||
// clear the string because the next BibTeX inset can be without the
|
||||
// \nocite{*} option
|
||||
btprint.clear();
|
||||
}
|
||||
string bibfiles;
|
||||
for (auto const & bf : preamble.biblatex_bibliographies) {
|
||||
if (!bibfiles.empty())
|
||||
bibfiles += ",";
|
||||
bibfiles += normalize_filename(bf);
|
||||
}
|
||||
if (!bibfiles.empty())
|
||||
os << "bibfiles " << '"' << bibfiles << '"' << "\n";
|
||||
// Do we have addcontentsline?
|
||||
if (contentslineContent == "\\refname") {
|
||||
BibOpts = "bibtotoc";
|
||||
// clear string because next BibTeX inset can be without addcontentsline
|
||||
contentslineContent.clear();
|
||||
}
|
||||
os << "options " << '"' << BibOpts << '"' << "\n";
|
||||
if (!bbloptions.empty())
|
||||
os << "biblatexopts " << '"' << bbloptions << '"' << "\n";
|
||||
end_inset(os);
|
||||
need_commentbib = false;
|
||||
}
|
||||
|
||||
else if (t.cs() == "parbox") {
|
||||
// Test whether this is an outer box of a shaded box
|
||||
p.pushPosition();
|
||||
@ -5200,6 +5408,31 @@ string guessLanguage(Parser & p, string const & lang)
|
||||
return use->first;
|
||||
}
|
||||
|
||||
|
||||
void check_comment_bib(ostream & os, Context & context)
|
||||
{
|
||||
if (!need_commentbib)
|
||||
return;
|
||||
// We have a bibliography database, but no bibliography with biblatex
|
||||
// which is completely valid. Insert a bibtex inset in a note.
|
||||
context.check_layout(os);
|
||||
begin_inset(os, "Note Note\n");
|
||||
os << "status open\n";
|
||||
os << "\\begin_layout Plain Layout\n";
|
||||
begin_command_inset(os, "bibtex", "bibtex");
|
||||
string bibfiles;
|
||||
for (auto const & bf : preamble.biblatex_bibliographies) {
|
||||
if (!bibfiles.empty())
|
||||
bibfiles += ",";
|
||||
bibfiles += normalize_filename(bf);
|
||||
}
|
||||
if (!bibfiles.empty())
|
||||
os << "bibfiles " << '"' << bibfiles << '"' << "\n";
|
||||
end_inset(os);// Bibtex
|
||||
os << "\\end_layout\n";
|
||||
end_inset(os);// Note
|
||||
}
|
||||
|
||||
// }])
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user