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.
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;
+}
+
docstring before = getParam("before");
docstring after = getParam("after");
if (!before.empty() && cs.textBefore) {
docstring before = getParam("before");
docstring after = getParam("after");
if (!before.empty() && cs.textBefore) {
- if (qualified) {
- if (contains(before, '(') || contains(before, ')'))
- // protect parens
- before = '{' + before + '}';
- if (contains(after, '(') || contains(after, ')'))
- // protect parens
- after = '{' + after + '}';
- os << '(' << before << ")(" << after << ')';
- } else
- os << '[' << before << "][" << after << ']';
+ if (qualified)
+ os << '(' << protectArgument(before, '(', ')')
+ << ")(" << protectArgument(after, '(', ')') << ')';
+ else
+ os << '[' << protectArgument(before) << "]["
+ << protectArgument(after) << ']';
} else if (!after.empty() && cs.textAfter) {
} else if (!after.empty() && cs.textAfter) {
- if (qualified) {
- if (contains(after, '(') || contains(after, ')'))
- // protect parens
- after = '{' + after + '}';
- os << '(' << after << ')';
- } else
- os << '[' << after << ']';
+ if (qualified)
+ os << '(' << protectArgument(after, '(', ')') << ')';
+ else
+ os << '[' << protectArgument(after) << ']';
map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
for (docstring const & k: keys) {
map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
for (docstring const & k: keys) {
- docstring const bef = pres[k];
- docstring const aft = posts[k];
+ docstring bef = pres[k];
+ docstring aft = posts[k];
- os << '[' << bef << "][" << aft << ']';
+ os << '[' << protectArgument(bef)
+ << "][" << protectArgument(aft) << ']';
- os << '[' << aft << ']';
+ os << '[' << protectArgument(aft) << ']';
os << '{' << k << '}';
}
} else
os << '{' << k << '}';
}
} else