Links between citations and bibliography entries were broken in XHTML

output, due to failure to clean the ids in the new citation stuff.

I've solved this by allowing the citation format information to contain
keys of the form "clean:key". This signals that we are to apply the
html::cleanAttr() function to the key before returning it. I.e., we
strip non-alphanumeric stuff, basically.
This commit is contained in:
Richard Heck 2013-03-27 15:46:32 -04:00
parent 54cff4129f
commit 4df02801a6
5 changed files with 60 additions and 48 deletions

View File

@ -27,7 +27,7 @@ CiteFormat default
!sep ,
!close ]
!startlink {!<a href='#LyXCite-%key%'>!}
!startlink {!<a href='#LyXCite-%clean:key%'>!}
!endlink {!</a>!}
!cite %!startlink%{%label%[[%label%]][[#%key%]]}%!endlink%%!nextcite%

View File

@ -58,7 +58,7 @@ CiteFormat authoryear
!sep ;
!close )
!startlink {!<a href='#LyXCite-%key%'>!}
!startlink {!<a href='#LyXCite-%clean:key%'>!}
!endlink {!</a>!}
!cite %!startlink%%!shortauthor%%!endlink%%!textbefore2%%!textafter2%%!nextcite%

View File

@ -49,7 +49,7 @@ CiteFormat default
!sep ,
!close ]
!startlink {!<a href='#LyXCite-%key%'>!}
!startlink {!<a href='#LyXCite-%clean:key%'>!}
!endlink {!</a>!}
!nextauthor {%next%[[%!sep% %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%]]}

View File

@ -20,6 +20,7 @@
#include "Encoding.h"
#include "InsetIterator.h"
#include "Language.h"
#include "output_xhtml.h"
#include "Paragraph.h"
#include "TextClass.h"
#include "TocBackend.h"
@ -653,56 +654,67 @@ docstring const & BibTeXInfo::operator[](string const & field) const
}
docstring BibTeXInfo::getValueForKey(string const & key, Buffer const & buf,
docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
docstring const & before, docstring const & after, docstring const & dialog,
BibTeXInfo const * const xref) const
{
string key = oldkey;
bool cleanit = false;
if (prefixIs(oldkey, "clean:")) {
key = oldkey.substr(6);
cleanit = true;
}
docstring ret = operator[](key);
if (ret.empty() && xref)
ret = (*xref)[key];
if (!ret.empty())
return ret;
// some special keys
// FIXME: dialog, textbefore and textafter have nothing to do with this
if (key == "dialog")
return dialog;
else if (key == "entrytype")
return entry_type_;
else if (key == "key")
return bib_key_;
else if (key == "label")
return label_;
else if (key == "abbrvauthor")
// Special key to provide abbreviated author names.
return getAbbreviatedAuthor(buf, false);
else if (key == "shortauthor")
// When shortauthor is not defined, jurabib automatically
// provides jurabib-style abbreviated author names. We do
// this as well.
return getAbbreviatedAuthor(buf, true);
else if (key == "shorttitle") {
// When shorttitle is not defined, jurabib uses for `article'
// and `periodical' entries the form `journal volume [year]'
// and for other types of entries it uses the `title' field.
if (entry_type_ == "article" || entry_type_ == "periodical")
return operator[]("journal") + " " + operator[]("volume")
+ " [" + operator[]("year") + "]";
else
return operator[]("title");
} else if (key == "bibentry") {
// Special key to provide the full bibliography entry: see getInfo()
CiteEngineType const engine_type = buf.params().citeEngineType();
DocumentClass const & dc = buf.params().documentClass();
string const & format = dc.getCiteFormat(engine_type, to_utf8(entry_type_));
int counter = 0;
return expandFormat(format, xref, counter, buf,
docstring(), docstring(), docstring(), false);
} else if (key == "textbefore")
return before;
else if (key == "textafter")
return after;
else if (key == "year")
return getYear();
if (ret.empty()) {
// some special keys
// FIXME: dialog, textbefore and textafter have nothing to do with this
if (key == "dialog")
ret = dialog;
else if (key == "entrytype")
ret = entry_type_;
else if (key == "key")
ret = bib_key_;
else if (key == "label")
ret = label_;
else if (key == "abbrvauthor")
// Special key to provide abbreviated author names.
ret = getAbbreviatedAuthor(buf, false);
else if (key == "shortauthor")
// When shortauthor is not defined, jurabib automatically
// provides jurabib-style abbreviated author names. We do
// this as well.
ret = getAbbreviatedAuthor(buf, true);
else if (key == "shorttitle") {
// When shorttitle is not defined, jurabib uses for `article'
// and `periodical' entries the form `journal volume [year]'
// and for other types of entries it uses the `title' field.
if (entry_type_ == "article" || entry_type_ == "periodical")
ret = operator[]("journal") + " " + operator[]("volume")
+ " [" + operator[]("year") + "]";
else
ret = operator[]("title");
} else if (key == "bibentry") {
// Special key to provide the full bibliography entry: see getInfo()
CiteEngineType const engine_type = buf.params().citeEngineType();
DocumentClass const & dc = buf.params().documentClass();
string const & format = dc.getCiteFormat(engine_type, to_utf8(entry_type_));
int counter = 0;
ret = expandFormat(format, xref, counter, buf,
docstring(), docstring(), docstring(), false);
} else if (key == "textbefore")
ret = before;
else if (key == "textafter")
ret = after;
else if (key == "year")
ret = getYear();
}
LYXERR0(ret);
if (cleanit)
return html::cleanAttr(ret);
return ret;
}

View File

@ -221,7 +221,7 @@ inline docstring wrapCitation(docstring const & key,
return content;
// we have to do the escaping here, because we will ultimately
// write this as a raw string, so as not to escape the tags.
return "<a href='#LyXCite-" + key + "'>" +
return "<a href='#LyXCite-" + html::cleanAttr(key) + "'>" +
html::htmlize(content, XHTMLStream::ESCAPE_ALL) + "</a>";
}