-----------------------
+2017-02-04 Jürgen Spitzmüller <spitz@lyx.org>
+ * Format incremented to 533: Support for multiple bibliographies
+ - New buffer param \multibib {none|part|chapter|section|subsetion}
+ LaTeX support either via biblatex option "refsection" or bibtopic's
+ btUnit environment.
+ - New btprint value "bibbysection" of CommandInset bibtex:
+ outputs \bibbysection instead of \printbibliography.
+
2017-01-28 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 532: literal command inset parameter.
With this, inset command params with ParamInfo::HANDLING_LATEXIFY
biblatex = False
if engine in ["biblatex", "biblatex-natbib"]:
biblatex = True
- document.header[i] = "\cite_engine natbib"
+ document.header[i] = "\\cite_engine natbib"
# 3. Store and remove new document headers
bibstyle = ""
del document.body[k]
+
+def revert_multibib(document):
+ " Revert multibib support "
+
+ # 1. Get cite engine
+ engine = "basic"
+ i = find_token(document.header, "\\cite_engine", 0)
+ if i == -1:
+ document.warning("Malformed document! Missing \\cite_engine")
+ else:
+ engine = get_value(document.header, "\\cite_engine", i)
+
+ # 2. Do we use biblatex?
+ biblatex = False
+ if engine in ["biblatex", "biblatex-natbib"]:
+ biblatex = True
+
+ # 3. Store and remove multibib document header
+ multibib = ""
+ i = find_token(document.header, "\\multibib", 0)
+ if i != -1:
+ multibib = get_value(document.header, "\\multibib", i)
+ del document.header[i]
+
+ if not multibib:
+ return
+
+ # 4. The easy part: Biblatex
+ if biblatex:
+ i = find_token(document.header, "\\biblio_options", 0)
+ if i == -1:
+ k = find_token(document.header, "\\use_bibtopic", 0)
+ if k == -1:
+ # this should not happen
+ document.warning("Malformed LyX document! No \\use_bibtopic header found!")
+ return
+ document.header[k-1 : k-1] = ["\\biblio_options " + "refsection=" + multibib]
+ else:
+ biblio_options = get_value(document.header, "\\biblio_options", i)
+ if biblio_options:
+ biblio_options += ","
+ biblio_options += "refsection=" + multibib
+ document.header[i] = "\\biblio_options " + biblio_options
+
+ # Bibtex insets
+ i = 0
+ while (True):
+ i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Can't find end of bibtex inset at line %d!!" %(i))
+ i += 1
+ continue
+ btprint = get_quoted_value(document.body, "btprint", i, j)
+ if btprint != "bibbysection":
+ i += 1
+ continue
+ opts = get_quoted_value(document.body, "biblatexopts", i, j)
+ # change btprint line
+ k = find_token(document.body, "btprint", i, j)
+ if k != -1:
+ document.body[k] = "btprint \"btPrintCited\""
+ # Insert ERT \\bibbysection and wrap bibtex inset to a Note
+ pcmd = "bibbysection"
+ if opts:
+ pcmd += "[" + opts + "]"
+ repl = ["\\begin_inset ERT", "status open", "", "\\begin_layout Plain Layout",\
+ "", "", "\\backslash", pcmd, "\\end_layout", "", "\\end_inset", "", "",\
+ "\\end_layout", "", "\\begin_layout Standard", "\\begin_inset Note Note",\
+ "status open", "", "\\begin_layout Plain Layout" ]
+ repl += document.body[i:j+1]
+ repl += ["", "\\end_layout", "", "\\end_inset", "", ""]
+ document.body[i:j+1] = repl
+ j += 27
+
+ i = j + 1
+ return
+
+ # 5. More tricky: Bibtex/Bibtopic
+ k = find_token(document.header, "\\use_bibtopic", 0)
+ if k == -1:
+ # this should not happen
+ document.warning("Malformed LyX document! No \\use_bibtopic header found!")
+ return
+ document.header[k] = "\\use_bibtopic true"
+
+ # Possible units. This assumes that the LyX name follows the std,
+ # which might not always be the case. But it's as good as we can get.
+ units = {
+ "part" : "Part",
+ "chapter" : "Chapter",
+ "section" : "Section",
+ "subsection" : "Subsection",
+ }
+
+ if multibib not in units.keys():
+ document.warning("Unknown multibib value `%s'!" % nultibib)
+ return
+ unit = units[multibib]
+ btunit = False
+ i = 0
+ while (True):
+ i = find_token(document.body, "\\begin_layout " + unit, i)
+ if i == -1:
+ break
+ if btunit:
+ document.body[i-1 : i-1] = ["\\begin_layout Standard",
+ "\\begin_inset ERT", "status open", "",
+ "\\begin_layout Plain Layout", "", "",
+ "\\backslash",
+ "end{btUnit}", "\\end_layout",
+ "\\begin_layout Plain Layout", "",
+ "\\backslash",
+ "begin{btUnit}"
+ "\\end_layout", "", "\\end_inset", "", "",
+ "\\end_layout", ""]
+ i += 21
+ else:
+ document.body[i-1 : i-1] = ["\\begin_layout Standard",
+ "\\begin_inset ERT", "status open", "",
+ "\\begin_layout Plain Layout", "", "",
+ "\\backslash",
+ "begin{btUnit}"
+ "\\end_layout", "", "\\end_inset", "", "",
+ "\\end_layout", ""]
+ i += 16
+ btunit = True
+ i += 1
+
+ if btunit:
+ i = find_token(document.body, "\\end_body", i)
+ document.body[i-1 : i-1] = ["\\begin_layout Standard",
+ "\\begin_inset ERT", "status open", "",
+ "\\begin_layout Plain Layout", "", "",
+ "\\backslash",
+ "end{btUnit}"
+ "\\end_layout", "", "\\end_inset", "", "",
+ "\\end_layout", ""]
+
+
##
# Conversion hub
#
[529, []],
[530, []],
[531, []],
- [532, [convert_literalparam]]
+ [532, [convert_literalparam]],
+ [533, []],
]
revert = [
+ [532, [revert_multibib]],
[531, [revert_literalparam]],
[530, [revert_qualicites]],
[529, [revert_bibpackopts]],
params().biblio_opts.erase();
params().biblatex_bibstyle.erase();
params().biblatex_citestyle.erase();
+ params().multibib.erase();
for (int i = 0; i < 4; ++i) {
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
use_geometry = false;
biblio_style = "plain";
use_bibtopic = false;
+ multibib = string();
use_indices = false;
save_transient_properties = true;
track_changes = false;
biblatex_citestyle = trim(lex.getString());
} else if (token == "\\use_bibtopic") {
lex >> use_bibtopic;
+ } else if (token == "\\multibib") {
+ lex >> multibib;
} else if (token == "\\use_indices") {
lex >> use_indices;
} else if (token == "\\tracking_changes") {
os << "\n\\biblatex_bibstyle " << biblatex_bibstyle;
if (!biblatex_citestyle.empty())
os << "\n\\biblatex_citestyle " << biblatex_citestyle;
+ if (!multibib.empty())
+ os << "\n\\multibib " << multibib;
os << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
<< "\n\\use_indices " << convert<string>(use_indices)
delim = ",";
}
}
+ if (!multibib.empty()) {
+ opts += delim + "refsection=" + multibib;
+ delim = ",";
+ }
if (bibtexCommand() == "bibtex8"
|| prefixIs(bibtexCommand(), "bibtex8 ")) {
opts += delim + "backend=bibtex8";
void use_package(std::string const & p, Package u);
/// All packages that can be switched on or off
static std::map<std::string, std::string> const & auto_packages();
+ /// Do we use the bibtopic package?
+ bool useBibtopic() const { return (use_bibtopic || !multibib.empty()) && !useBiblatex(); }
/// Split bibliography?
- bool useBibtopic() const { return use_bibtopic && !useBiblatex(); }
+ bool splitbib() const { return use_bibtopic; }
/// Set split bibliography
- void bibtopic(bool const b) { use_bibtopic = b; }
+ void splitbib(bool const b) { use_bibtopic = b; }
+ /// Do we have multiple bibliographies (by chapter etc.)?
+ std::string multibib;
/// Split the index?
bool use_indices;
/// Save transient properties?
encoding(enc), free_spacing(false), use_babel(false), use_polyglossia(false),
use_indices(false), use_japanese(false), linelen(0), depth(0),
exportdata(new ExportData), inDisplayMath(false), wasDisplayMath(false),
- inComment(false), inTableCell(NO), inFloat(NONFLOAT),
+ inComment(false), openbtUnit(false), inTableCell(NO), inFloat(NONFLOAT),
inIndexEntry(false), inIPA(false), inDeletedInset(0),
changeOfDeletedInset(Change::UNCHANGED),
par_begin(0), par_end(0), lastid(-1), lastpos(0), isLastPar(false),
*/
bool inComment;
+ /** Whether a btUnit (for multiple biblographies) is open.
+ */
+ bool openbtUnit;
+
/** Whether we are in a table cell.
* For newline, it matters whether its content is aligned or not.
*/
bibtocCB->setChecked(bibtotoc() && !bibtopic);
bibtocCB->setEnabled(!bibtopic);
- if (!bibtopic && btPrintCO->count() == 3)
- btPrintCO->removeItem(1);
- else if (bibtopic && btPrintCO->count() < 3)
- btPrintCO->insertItem(1, qt_("all uncited references", 0));
+ btPrintCO->clear();
+ btPrintCO->addItem(qt_("all cited references"), toqstr("btPrintCited"));
+ if (bibtopic)
+ btPrintCO->addItem(qt_("all uncited references"), toqstr("btPrintNotCited"));
+ btPrintCO->addItem(qt_("all references"), toqstr("btPrintAll"));
+ if (usingBiblatex() && !buffer().masterParams().multibib.empty())
+ btPrintCO->addItem(qt_("all reference units"), toqstr("bibbysection"));
- docstring const & btprint = params_["btprint"];
- int btp = 0;
- if ((bibtopic && btprint == from_ascii("btPrintNotCited")) ||
- (!bibtopic && btprint == from_ascii("btPrintAll")))
- btp = 1;
- else if (bibtopic && btprint == from_ascii("btPrintAll"))
- btp = 2;
-
- btPrintCO->setCurrentIndex(btp);
+ btPrintCO->setCurrentIndex(btPrintCO->findData(toqstr(params_["btprint"])));
// Only useful for biblatex
biblatexOptsLA->setVisible(biblatex);
params_["biblatexopts"] = qstring_to_ucs4(biblatexOptsLE->text());
- int btp = btPrintCO->currentIndex();
-
- if (usingBibtopic()) {
- // bibtopic allows three kinds of sections:
- // 1. sections that include all cited references of the database(s)
- // 2. sections that include all uncited references of the database(s)
- // 3. sections that include all references of the database(s), cited or not
- switch (btp) {
- case 0:
- params_["btprint"] = from_ascii("btPrintCited");
- break;
- case 1:
- params_["btprint"] = from_ascii("btPrintNotCited");
- break;
- case 2:
- params_["btprint"] = from_ascii("btPrintAll");
- break;
- }
- } else {
- switch (btp) {
- case 0:
- params_["btprint"] = docstring();
- break;
- case 1:
- // use \nocite{*}
- params_["btprint"] = from_ascii("btPrintAll");
- break;
- }
- }
+ params_["btprint"] = qstring_to_ucs4(btPrintCO->itemData(btPrintCO->currentIndex()).toString());
}
this, SLOT(citeStyleChanged()));
connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
this, SLOT(biblioChanged()));
+ connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
+ this, SLOT(biblioChanged()));
connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
this, SLOT(bibtexChanged(int)));
connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
else
bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
- bp_.bibtopic(biblioModule->bibtopicCB->isChecked());
+ bp_.splitbib(biblioModule->bibtopicCB->isChecked());
+
+ bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
+ biblioModule->bibunitsCO->currentIndex()).toString());
bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
biblioModule->citeStyleCO->setCurrentIndex(
biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
- biblioModule->bibtopicCB->setChecked(
- bp_.useBibtopic());
+ biblioModule->bibtopicCB->setChecked(bp_.splitbib());
+
+ biblioModule->bibunitsCO->clear();
+ biblioModule->bibunitsCO->addItem(qt_("No"), QString());
+ if (documentClass().hasLaTeXLayout("part"))
+ biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
+ if (documentClass().hasLaTeXLayout("chapter"))
+ biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
+ if (documentClass().hasLaTeXLayout("section"))
+ biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
+ if (documentClass().hasLaTeXLayout("subsection"))
+ biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
+
+ int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
+ if (mbpos != -1)
+ biblioModule->bibunitsCO->setCurrentIndex(mbpos);
+ else
+ biblioModule->bibunitsCO->setCurrentIndex(0);
updateEngineDependends();
<rect>
<x>0</x>
<y>0</y>
- <width>545</width>
- <height>481</height>
+ <width>534</width>
+ <height>482</height>
</rect>
</property>
<property name="windowTitle">
<string>Select this if you want to split your bibliography into sections</string>
</property>
<property name="text">
- <string>Secti&oned bibliography</string>
+ <string>Subdivided bibli&ography</string>
</property>
</widget>
</item>
</item>
</layout>
</item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QLabel" name="bibunitsLA">
+ <property name="text">
+ <string>&Multiple bibliographies:</string>
+ </property>
+ <property name="buddy">
+ <cstring>bibunitsCO</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="bibunitsCO">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Generate a bibliography per defined unit.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>
style = split(style, bibtotoc, char_type(','));
}
+ docstring const btprint = getParam("btprint");
if (!usingBiblatex()) {
tip += _("Style File:");
tip += "<ul><li>" + (style.empty() ? _("none") : style) + "</li></ul>";
tip += _("Lists:") + " ";
- docstring btprint = getParam("btprint");
if (btprint == "btPrintAll")
tip += _("all references");
else if (btprint == "btPrintNotCited")
tip += _("included in TOC");
}
} else {
- if (toc)
- tip += _("Included in TOC");
+ tip += _("Lists:") + " ";
+ if (btprint == "bibbysection")
+ tip += _("all reference units");
+ else if (btprint == "btPrintAll")
+ tip += _("all references");
+ else
+ tip += _("all cited references");
+ if (toc) {
+ tip += ", ";
+ tip += _("included in TOC");
+ }
if (!getParam("biblatexopts").empty()) {
if (toc)
tip += "<br />";
// 4. \end{btSect}
// With Biblatex:
// \printbibliography[biblatexopts]
+ // or
+ // \bibbysection[biblatexopts] - if btprint is "bibbysection"
string style = to_utf8(getParam("options")); // maybe empty! and with bibtotoc
string bibtotoc;
docstring btprint = getParam("btprint");
if (btprint == "btPrintAll")
os << "\\nocite{*}\n";
- os << "\\printbibliography";
+ if (btprint == "bibbysection" && !buffer().masterParams().multibib.empty())
+ os << "\\bibbysection";
+ else
+ os << "\\printbibliography";
if (!opts.empty())
os << "[" << opts << "]";
os << "\n";
void latexParagraphs(Buffer const & buf,
Text const & text,
otexstream & os,
- OutputParams const & runparams,
+ OutputParams const & runparams_in,
string const & everypar)
{
+ OutputParams runparams = runparams_in;
LASSERT(runparams.par_begin <= runparams.par_end,
{ os << "% LaTeX Output Error\n"; return; } );
was_title = false;
}
+ if (layout.isCommand() && !layout.latexname().empty()
+ && layout.latexname() == bparams.multibib) {
+ if (runparams.openbtUnit)
+ os << "\\end{btUnit}\n";
+ if (!bparams.useBiblatex()) {
+ os << '\n' << "\\begin{btUnit}\n";
+ runparams.openbtUnit = true;
+ }
+ }
if (!layout.isEnvironment() && par->params().leftIndent().zero()) {
// This is a standard top level paragraph, TeX it and continue.
}
}
+ if (runparams.openbtUnit)
+ os << "\\end{btUnit}\n";
+
// if "auto end" is switched off, explicitly close the language at the end
// but only if the last par is in a babel or polyglossia language
string const lang_end_command = runparams.use_polyglossia ?
posttextlist "key1 post1\tab key2 post2..."
Same for:
\Cites, \textcites, \Textcites, \parencites, \Parencites, \smartcites, \Smartcites, \autocites, Autocites
+533 Multibib support
+ \begin{btUnit}...\end{btUnit} \multibib {none|part|chapter|section|subsetion}
+ (if a part, chapter, section etc.
+ follows the \begin...)
+ \usepackage[refsection=<val> \multibib <val>
+ \bibbysection[<opts>] \begin_inset CommandInset bibtex
+ biblatexopts "<opts>"
+ btprint "bibbysection"
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 532 // gb/spitz add literal command inset parameter
-#define LYX_FORMAT_TEX2LYX 532
+#define LYX_FORMAT_LYX 533 // spitz: multibib
+#define LYX_FORMAT_TEX2LYX 533
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER