diff --git a/lib/lyx2lyx/lyx_2_5.py b/lib/lyx2lyx/lyx_2_5.py index 9d0486cffb..0adc24d70e 100644 --- a/lib/lyx2lyx/lyx_2_5.py +++ b/lib/lyx2lyx/lyx_2_5.py @@ -118,17 +118,66 @@ def revert_url_escapes(document): document.body[surl : surl + 1] = [m.group(1), "\\backslash", m.group(2)] 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 # supported_versions = ["2.5.0", "2.5"] 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]] ] diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 0241dece7f..0dee0af3ae 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -354,6 +354,7 @@ public: Font const & running_font, string & alien_script, Layout const & style, + InsetLayout const & il, pos_type & i, pos_type end_pos, unsigned int & column) const; @@ -1234,12 +1235,21 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, Font const & running_font, string & alien_script, Layout const & style, + InsetLayout const & il, pos_type & i, pos_type end_pos, unsigned int & column) const { 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() || contains(style.pass_thru_chars, c) || contains(runparams.pass_thru_chars, c)) @@ -3170,8 +3180,8 @@ void Paragraph::latex(BufferParams const & bparams, } } try { - d->latexSpecialChar(os, bparams, rp, running_font, - alien_script, style, i, end_pos, column); + d->latexSpecialChar(os, bparams, rp, running_font, alien_script, + style, inInset().getLayout(), i, end_pos, column); } catch (EncodingException & e) { if (runparams.dryrun) { os << "<" << _("LyX Warning: ")