DocBook: implementation of LATEX_BIB_ENVIRONMENT.

Fixes endless loops when such environments were used.

Add Kornel's test case that triggers an infinite loop when generating as DocBook 5
This commit is contained in:
Thibaut Cuvelier 2020-07-25 04:48:33 +02:00
parent b9c1fe1bac
commit 5de60e3c77
5 changed files with 325 additions and 6 deletions

View File

@ -0,0 +1,134 @@
#LyX 2.4 created this file. For more info see https://www.lyx.org/
\lyxformat 598
\begin_document
\begin_header
\save_transient_properties true
\origin unavailable
\textclass simplecv
\use_default_options false
\maintain_unincluded_children no
\language english
\language_package default
\inputencoding utf8
\fontencoding auto
\font_roman "lmodern" "default"
\font_sans "default" "default"
\font_typewriter "default" "default"
\font_math "auto" "auto"
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_roman_osf false
\font_sans_osf false
\font_typewriter_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\use_microtype false
\use_dash_ligatures false
\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\float_placement class
\float_alignment class
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_package amsmath 1
\use_package amssymb 1
\use_package cancel 1
\use_package esint 1
\use_package mathdots 1
\use_package mathtools 1
\use_package mhchem 1
\use_package stackrel 1
\use_package stmaryrd 1
\use_package undertilde 1
\cite_engine basic
\cite_engine_type default
\biblio_style plain
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\justification true
\use_refstyle 0
\use_minted 0
\use_lineno 0
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 0
\tocdepth 0
\paragraph_separation indent
\paragraph_indentation default
\is_math_indent 0
\math_numbering_side default
\quotes_style english
\dynamic_quotes 0
\papercolumns 1
\papersides 1
\paperpagestyle default
\tablestyle default
\tracking_changes false
\output_changes false
\change_bars false
\postpone_fragile_content false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\docbook_table_output 0
\end_header
\begin_body
\begin_layout Title
William Shakespeare
\end_layout
\begin_layout Section
Publications
\end_layout
\begin_layout Bibliography
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "first"
literal "true"
\end_inset
First Folio.
\end_layout
\begin_layout Bibliography
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "second"
literal "true"
\end_inset
Second Folio.
\end_layout
\begin_layout Bibliography
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "third"
literal "true"
\end_inset
Third Folio.
\end_layout
\end_body
\end_document

View File

@ -0,0 +1,111 @@
#LyX 2.4 created this file. For more info see https://www.lyx.org/
\lyxformat 598
\begin_document
\begin_header
\save_transient_properties true
\origin unavailable
\textclass simplecv
\use_default_options false
\maintain_unincluded_children no
\language english
\language_package default
\inputencoding utf8
\fontencoding auto
\font_roman "lmodern" "default"
\font_sans "default" "default"
\font_typewriter "default" "default"
\font_math "auto" "auto"
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_roman_osf false
\font_sans_osf false
\font_typewriter_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\use_microtype false
\use_dash_ligatures false
\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\float_placement class
\float_alignment class
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_package amsmath 1
\use_package amssymb 1
\use_package cancel 1
\use_package esint 1
\use_package mathdots 1
\use_package mathtools 1
\use_package mhchem 1
\use_package stackrel 1
\use_package stmaryrd 1
\use_package undertilde 1
\cite_engine basic
\cite_engine_type default
\biblio_style plain
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\justification true
\use_refstyle 0
\use_minted 0
\use_lineno 0
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 0
\tocdepth 0
\paragraph_separation indent
\paragraph_indentation default
\is_math_indent 0
\math_numbering_side default
\quotes_style english
\dynamic_quotes 0
\papercolumns 1
\papersides 1
\paperpagestyle default
\tablestyle default
\tracking_changes false
\output_changes false
\change_bars false
\postpone_fragile_content false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\docbook_table_output 0
\end_header
\begin_body
\begin_layout Title
William Shakespeare
\end_layout
\begin_layout Section
Publications
\end_layout
\begin_layout Bibliography
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "firstref"
literal "true"
\end_inset
First Folio.
Me.
1623..
\end_layout
\end_body
\end_document

View File

@ -343,6 +343,13 @@ void InsetBibitem::updateBuffer(ParIterator const & it, UpdateType utype, bool c
}
void InsetBibitem::docbook(XMLStream & xs, OutputParams const &) const
{
// Nothing to do: everything is implemented in makeParagraphBibliography.
return;
}
docstring InsetBibitem::xhtml(XMLStream & xs, OutputParams const &) const
{
// FIXME XHTML
@ -352,7 +359,7 @@ docstring InsetBibitem::xhtml(XMLStream & xs, OutputParams const &) const
// handle jumping to ids. If we don't do that, though, we can just put the
// id into the span tag.
string const attrs =
"id='LyXCite-" + to_utf8(xml::cleanAttr(getParam("key"))) + "'";
"id='LyXCite-" + to_utf8(xml::cleanAttr(getParam("key"))) + "'";
xs << xml::CompTag("a", attrs);
xs << xml::StartTag("span", "class='bibitemlabel'");
xs << bibLabel();

View File

@ -60,6 +60,8 @@ public:
///
docstring xhtml(XMLStream &, OutputParams const &) const;
///
void docbook(XMLStream &, OutputParams const &) const;
///
void collectBibKeys(InsetIterator const &, support::FileNameList &) const;
/// update the counter of this inset
void updateBuffer(ParIterator const &, UpdateType, bool const deleted = false);
@ -74,12 +76,11 @@ public:
///
static bool isCompatibleCommand(std::string const & s)
{ return s == "bibitem"; }
///
docstring bibLabel() const;
///@}
private:
///
docstring bibLabel() const;
/// \name Private functions inherited from Inset class
//@{
///

View File

@ -26,6 +26,7 @@
#include "TextClass.h"
#include "insets/InsetBibtex.h"
#include "insets/InsetBibitem.h"
#include "insets/InsetLabel.h"
#include "insets/InsetNote.h"
@ -303,6 +304,69 @@ ParagraphList::const_iterator findEndOfEnvironment(
}
ParagraphList::const_iterator makeParagraphBibliography(
Buffer const &buf,
XMLStream &xs,
OutputParams const &runparams,
Text const &text,
ParagraphList::const_iterator const & pbegin,
ParagraphList::const_iterator const & pend)
{
auto const begin = text.paragraphs().begin();
auto const end = text.paragraphs().end();
// Find the paragraph *before* pbegin.
ParagraphList::const_iterator pbegin_before = begin;
if (pbegin != begin) {
ParagraphList::const_iterator pbegin_before_next = begin;
++pbegin_before_next;
while (pbegin_before_next != pbegin) {
++pbegin_before;
++pbegin_before_next;
}
}
ParagraphList::const_iterator par = pbegin;
// If this is the first paragraph in a bibliography, open the bibliography tag.
if (pbegin != begin && pbegin_before->layout().latextype != LATEX_BIB_ENVIRONMENT) {
xs << xml::StartTag("bibliography");
xs << xml::CR();
}
// Generate the required paragraphs.
for (; par != pend; ++par) {
// Start the precooked bibliography entry. This is very much like opening a paragraph tag.
// Don't forget the citation ID!
docstring attr;
for (auto i = 0; i < par->size(); ++i) {
if (par->getInset(0)->lyxCode() == BIBITEM_CODE) {
const auto * bibitem = dynamic_cast<const InsetBibitem*>(par->getInset(i));
attr = from_utf8("id='") + bibitem->bibLabel() + from_utf8("'");
break;
}
}
xs << xml::StartTag(from_utf8("bibliomixed"), attr);
// Generate the entry.
par->simpleDocBookOnePar(buf, xs, runparams, text.outerFont(distance(begin, par)), true, true, 0);
// End the precooked bibliography entry.
xs << xml::EndTag("bibliomixed");
xs << xml::CR();
}
// If this is the last paragraph in a bibliography, close the bibliography tag.
if (par == end || par->layout().latextype != LATEX_BIB_ENVIRONMENT) {
xs << xml::EndTag("bibliography");
xs << xml::CR();
}
return pend;
}
ParagraphList::const_iterator makeParagraphs(
Buffer const &buf,
XMLStream &xs,
@ -534,7 +598,8 @@ ParagraphList::const_iterator makeEnvironment(
par = makeParagraphs(buf, xs, runparams, text, par, send);
break;
case LATEX_BIB_ENVIRONMENT:
// Handled in InsetBibtex.
send = findLastParagraph(par, pend);
par = makeParagraphBibliography(buf, xs, runparams, text, par, send);
break;
case LATEX_COMMAND:
++par;
@ -605,7 +670,8 @@ pair<ParagraphList::const_iterator, ParagraphList::const_iterator> makeAny(
break;
}
case LATEX_BIB_ENVIRONMENT: {
// Handled in InsetBibtex.
send = findLastParagraph(par, pend);
par = makeParagraphBibliography(buf, xs, ourparams, text, par, send);
break;
}
case LATEX_PARAGRAPH: {