Generalize the protection of brackets in citation arguments

Whenever an argument delimiter is used inside the argument, the argument
needs to be grouped, that is

\cites({text (text) text})

or

\cite[{text [text] text}]

This fixes the original case reported in #2751 which is independent
from the general issue that the pre- and postnote field take literal
code.
This commit is contained in:
Juergen Spitzmueller 2017-01-22 10:27:06 +01:00
parent 4666cb15ec
commit fd8b4aebb0

View File

@ -312,6 +312,15 @@ inline docstring wrapCitation(docstring const & key,
html::htmlize(content, XHTMLStream::ESCAPE_ALL) + "</a>"; html::htmlize(content, XHTMLStream::ESCAPE_ALL) + "</a>";
} }
docstring protectArgument(docstring & arg, char const l = '[',
char const r = ']')
{
if (contains(arg, l) || contains(arg, r))
// protect brackets
arg = '{' + arg + '}';
return arg;
}
} // anonymous namespace } // anonymous namespace
@ -571,24 +580,17 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
docstring before = getParam("before"); docstring before = getParam("before");
docstring after = getParam("after"); docstring after = getParam("after");
if (!before.empty() && cs.textBefore) { if (!before.empty() && cs.textBefore) {
if (qualified) { if (qualified)
if (contains(before, '(') || contains(before, ')')) os << '(' << protectArgument(before, '(', ')')
// protect parens << ")(" << protectArgument(after, '(', ')') << ')';
before = '{' + before + '}'; else
if (contains(after, '(') || contains(after, ')')) os << '[' << protectArgument(before) << "]["
// protect parens << protectArgument(after) << ']';
after = '{' + after + '}';
os << '(' << before << ")(" << after << ')';
} else
os << '[' << before << "][" << after << ']';
} else if (!after.empty() && cs.textAfter) { } else if (!after.empty() && cs.textAfter) {
if (qualified) { if (qualified)
if (contains(after, '(') || contains(after, ')')) os << '(' << protectArgument(after, '(', ')') << ')';
// protect parens else
after = '{' + after + '}'; os << '[' << protectArgument(after) << ']';
os << '(' << after << ')';
} else
os << '[' << after << ']';
} }
if (!bi.isBibtex(key)) if (!bi.isBibtex(key))
@ -599,12 +601,13 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist")); map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist")); map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
for (docstring const & k: keys) { for (docstring const & k: keys) {
docstring const bef = pres[k]; docstring bef = pres[k];
docstring const aft = posts[k]; docstring aft = posts[k];
if (!bef.empty()) if (!bef.empty())
os << '[' << bef << "][" << aft << ']'; os << '[' << protectArgument(bef)
<< "][" << protectArgument(aft) << ']';
else if (!aft.empty()) else if (!aft.empty())
os << '[' << aft << ']'; os << '[' << protectArgument(aft) << ']';
os << '{' << k << '}'; os << '{' << k << '}';
} }
} else } else