commit 9d43fd2ae138f73fc565e3018a8ef58d7614b489
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Wed May 15 13:15:08 2024 +0200

    # and % need to be escaped in hyperref URL as well
    
    Also fix some lyx2lyx glitches
    
    This hopefully fixes the test issues.
---
 lib/lyx2lyx/lyx_2_5.py | 58 +++++++++++++++++++++++++-------------------------
 src/Paragraph.cpp      |  8 ++++---
 2 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/lib/lyx2lyx/lyx_2_5.py b/lib/lyx2lyx/lyx_2_5.py
index c574aa2eb9..520cd3f88f 100644
--- a/lib/lyx2lyx/lyx_2_5.py
+++ b/lib/lyx2lyx/lyx_2_5.py
@@ -55,75 +55,73 @@ from parser_tools import (find_end_of_inset, 
find_end_of_layout, find_token, fin
 ###############################################################################
 
 def convert_url_escapes(document):
-    """Unescape # and % in URLs in frames."""
-    if document.textclass not in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']:
+    """Unescape # and % in URLs with hyperref."""
+
+    hyperref = find_token(document.header, "\\use_hyperref true", 0) != -1
+    beamer = document.textclass in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']
+
+    if not hyperref and not beamer:
         return
 
     rurl = re.compile(r'^[%#].*')
     i = 0
     while True:
-        i = find_token(document.body, "\\begin_layout Frame", i + 1)
+        i = find_token(document.body, "\\begin_inset Flex URL", i)
         if i == -1:
             return
-        j = find_end_of_layout(document.body, i)
+        j = find_end_of_inset(document.body, i)
         if j == -1:
-            document.warning("Malformed LyX document: Could not find end of 
Frame layout.")
-            continue
-        k = find_token(document.body, "\\begin_inset Flex URL", i, j)
-        if k == -1:
-            continue
-        l = find_end_of_inset(document.body, k)
-        if l == -1:
             document.warning("Malformed LyX document: Could not find end of 
URL inset.")
+            i += 1
             continue
         while True:
-            surl = find_re(document.body, rurl, k, l)
+            surl = find_re(document.body, rurl, i, j)
             if surl == -1:
+                i = j
                 break
             if document.body[surl - 1] == "\\backslash":
                 del document.body[surl - 1]
-            k = surl
+            i = surl
         
 
 def revert_url_escapes(document):
-    """Unescape # and % in URLs in frames."""
-    if document.textclass not in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']:
+    """Unescape # and % in URLs with hyperref."""
+
+    hyperref = find_token(document.header, "\\use_hyperref true", 0) != -1
+    beamer = document.textclass in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']
+
+    if not hyperref and not beamer:
         return
 
     rurl = re.compile(r'^(.*)([%#].*)')
     i = 0
     while True:
-        i = find_token(document.body, "\\begin_layout Frame", i + 1)
+        i = find_token(document.body, "\\begin_inset Flex URL", i)
         if i == -1:
-            return
-        j = find_end_of_layout(document.body, i)
-        if j == -1:
-            document.warning("Malformed LyX document: Could not find end of 
Frame layout.")
             continue
-        k = find_token(document.body, "\\begin_inset Flex URL", i, j)
-        if k == -1:
-            continue
-        l = find_end_of_inset(document.body, k)
-        if l == -1:
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
             document.warning("Malformed LyX document: Could not find end of 
URL inset.")
+            i += 1
             continue
         while True:
-            surl = find_re(document.body, rurl, k, l)
+            surl = find_re(document.body, rurl, i, j)
             if surl == -1:
+                i = j
                 break
             m = rurl.match(document.body[surl])
             if m:
                 if m.group(1) == "" and document.body[surl - 1] == 
"\\backslash":
                     break
                 document.body[surl : surl + 1] = [m.group(1), "\\backslash", 
m.group(2)]
-            k = surl
+            i = surl
 
 def convert_url_escapes2(document):
     """Unescape backslashes 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']:
+    if i == -1 and document.textclass not in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']:
         return
 
     i = 0
@@ -134,6 +132,7 @@ def convert_url_escapes2(document):
         j = find_end_of_inset(document.body, i)
         if j == -1:
             document.warning("Malformed LyX document: Could not find end of 
URL inset.")
+            i += 1
             continue
         while True:
             bs = find_token(document.body, "\\backslash", i, j)
@@ -148,7 +147,7 @@ def revert_url_escapes2(document):
 
     i = find_token(document.header, "\\use_hyperref true", 0)
    
-    if i != -1 and document.textclass not in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']:
+    if i == -1 and document.textclass not in ['beamer', 'scrarticle-beamer', 
'beamerposter', 'article-beamer']:
         return
 
     i = 0
@@ -159,6 +158,7 @@ def revert_url_escapes2(document):
         j = find_end_of_inset(document.body, i)
         if j == -1:
             document.warning("Malformed LyX document: Could not find end of 
URL inset.")
+            i += 1
             continue
         while True:
             bs = find_token(document.body, "\\backslash", i, j)
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index dd8d66d1fa..a63017db32 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -1243,11 +1243,13 @@ void Paragraph::Private::latexSpecialChar(otexstream & 
os,
 {
        char_type const c = owner_->getUChar(bparams, runparams, i);
 
-       // Special case: URLs with hyperref need to escape backslash (#13012).
+       // Special case: URLs with hyperref need to escape backslash, # and % 
(#13012).
        // Both a layout tag and a dedicated inset seem too much effort for 
this.
-       if (c == '\\' && runparams.use_hyperref && il.latexname() == "url"
+       string const hr_url_escape_chars = "\\#%";
+       if (contains(hr_url_escape_chars, c) && runparams.use_hyperref && 
il.latexname() == "url"
            && il.required().find("url") != il.required().end()) {
-               os << "\\\\";
+               os << "\\";
+               os.put(c);
                return;
        }
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to