Properly escape backslash in URLs with hyperref (#13012)

This commit is contained in:
Juergen Spitzmueller 2024-05-13 09:17:30 +02:00
parent ed62816eb6
commit 52d31155c1
2 changed files with 63 additions and 4 deletions

View File

@ -118,17 +118,66 @@ def revert_url_escapes(document):
document.body[surl : surl + 1] = [m.group(1), "\\backslash", m.group(2)] document.body[surl : surl + 1] = [m.group(1), "\\backslash", m.group(2)]
k = surl k = surl
def convert_url_escapes2(document):
"""Unescape / in URLs with hyperref."""
i = find_token(document.header, "\\use_hyperref true", 0)
if i != -1 and document.textclass not in ['beamer', 'scrarticle-beamer', 'beamerposter', 'article-beamer']:
return
i = 0
while True:
i = find_token(document.body, "\\begin_inset Flex URL", i + 1)
if i == -1:
return
j = find_end_of_inset(document.body, i)
if j == -1:
document.warning("Malformed LyX document: Could not find end of URL inset.")
continue
while True:
bs = find_token(document.body, "\\backslash", i, j)
if bs == -1:
break
if document.body[bs + 2] == "\\backslash":
del document.body[bs + 2]
i = bs + 1
def revert_url_escapes2(document):
"""Escape / in URLs with hyperref."""
i = find_token(document.header, "\\use_hyperref true", 0)
if i != -1 and document.textclass not in ['beamer', 'scrarticle-beamer', 'beamerposter', 'article-beamer']:
return
i = 0
while True:
i = find_token(document.body, "\\begin_inset Flex URL", i + 1)
if i == -1:
return
j = find_end_of_inset(document.body, i)
if j == -1:
document.warning("Malformed LyX document: Could not find end of URL inset.")
continue
while True:
bs = find_token(document.body, "\\backslash", i, j)
if bs == -1:
break
document.body[bs] = "\\backslash\\backslash"
i = bs + 1
## ##
# Conversion hub # Conversion hub
# #
supported_versions = ["2.5.0", "2.5"] supported_versions = ["2.5.0", "2.5"]
convert = [ convert = [
[621, [convert_url_escapes]] [621, [convert_url_escapes, convert_url_escapes2]]
] ]
revert = [[620, [revert_url_escapes]] revert = [[620, [revert_url_escapes2, revert_url_escapes]]
] ]

View File

@ -354,6 +354,7 @@ public:
Font const & running_font, Font const & running_font,
string & alien_script, string & alien_script,
Layout const & style, Layout const & style,
InsetLayout const & il,
pos_type & i, pos_type & i,
pos_type end_pos, pos_type end_pos,
unsigned int & column) const; unsigned int & column) const;
@ -1234,12 +1235,21 @@ void Paragraph::Private::latexSpecialChar(otexstream & os,
Font const & running_font, Font const & running_font,
string & alien_script, string & alien_script,
Layout const & style, Layout const & style,
InsetLayout const & il,
pos_type & i, pos_type & i,
pos_type end_pos, pos_type end_pos,
unsigned int & column) const unsigned int & column) const
{ {
char_type const c = owner_->getUChar(bparams, runparams, i); char_type const c = owner_->getUChar(bparams, runparams, i);
// Special case: URLs with hyperref need to escape backslash (#13012).
// Both a layout tag and a dedicated inset seem too much effort for this.
if (c == '\\' && runparams.use_hyperref && il.latexname() == "url"
&& il.required().find("url") != il.required().end()) {
os << "\\\\";
return;
}
if ((style.pass_thru || runparams.pass_thru || runparams.find_effective() if ((style.pass_thru || runparams.pass_thru || runparams.find_effective()
|| contains(style.pass_thru_chars, c) || contains(style.pass_thru_chars, c)
|| contains(runparams.pass_thru_chars, c)) || contains(runparams.pass_thru_chars, c))
@ -3170,8 +3180,8 @@ void Paragraph::latex(BufferParams const & bparams,
} }
} }
try { try {
d->latexSpecialChar(os, bparams, rp, running_font, d->latexSpecialChar(os, bparams, rp, running_font, alien_script,
alien_script, style, i, end_pos, column); style, inInset().getLayout(), i, end_pos, column);
} catch (EncodingException & e) { } catch (EncodingException & e) {
if (runparams.dryrun) { if (runparams.dryrun) {
os << "<" << _("LyX Warning: ") os << "<" << _("LyX Warning: ")