Le 07/06/2015 12:49, Enrico Forestieri a écrit :
On Sat, Jun 06, 2015 at 08:07:12PM +0100, Guillaume M-M wrote:

lyx-preview-macros2-failure.lyx shows two cases where a macro is forgotten
from the list. The third inset works and is meant as a control. All 3 work
without the patch.

Here I was forgetting to also scan nested insets.

lyx-preview-macros2-lassert.lyx triggers an assertion when preview is
activated. Does not assert without the patch.

Here I did not account for the fact that also the macros defined in the
symbols file are spotted. However, they do not have a valid DataMacro
and this was causing the assert.

Note that there is another bug here, but it is not a regression as it
seems to be like that since ever (I checked with lyx versions since 1.3).
The bug is that when using a symbol defined in the symbols file and this
symbol requires a certain package, this requirement is not taken into
account when generating the tex file for preview and thus latex fails.

Notice that my "thourough test" is basically loading my current paper with
preview on.

I think that your paper is a very valid test case for macros ;)

The attached patch solves all of the above problems (and also the segfault
you report separately) for me. I am also attaching the patch for #9354
accordingly updated. Please test both and report the issues you find.
If your paper pass the tests, I think they are good for stable ;)


Hello again,


I tested the latest stable that seems to include the patches. As I already told Enrico, sorry for the delay as I did not have much free time until now.

Thank you very much, this is really quick now. Thanks also for the timer for generating previews. Also I only had 1 segmentation error, which I could not reproduce unfortunately. It happened after changing from "Instant preview: On" to "No maths" and zooming. But probably it's part of the bigger issues with math macros, and again I could not reproduce.

Here are two examples that still fail.

lyx-bug-undefined.lyx: the macro used in the argument of another macro is not defined. I had many bugs of this style, so let's hope that this one is representative, otherwise I'll come back with more errors.

lyx-bug-renewcommandx4.lyx: here we have again an error where renewcommandx is used while the macro is not defined beforehand. If it is really too error prone to keep track of what has already been defined then it is easy to work around by using \definecommandx:
  \def\definecommandx#1{\providecommand#1{}\renewcommandx#1}
This seems to work at least for the way newcommandx is used in lyx previews (but maybe you have other reasons for distinguishing the cases newcommandx and renewcommandx that I don't understand).

Lastly I see that you prevent loading the microtype package by redefining \usepackage as you described earlier in the thread. While your redefinition of \usepackage seems to be very careful, I still think that passing the option draft to microtype is more reliable in case the user actually uses macros from microtype (in addition there's no need to test whether the user loads microtype).

I don't want to be too much of a PITA so here's a patch to lyxpreview2bitmap.py that integrates my above two suggestions and solves the above two problems. (The bug in lyx-bug-undefined.lyx has to be addressed separately.) Parsing a file using regexps is always delicate so I think it's good that with my patch there are fewer of these. I do not think that I missed any subtlety in the existing code, but in any case you don't need to accept it as is.

Also, lyx-preview-macros-2-lassert.lyx no longer lasserts but on opening the preview is not generated because \Coloneqq is not defined. This looks like the bug that you are referring to in your message where packages for symbols are not properly loaded. But, notice that the preview is correctly generated on a second time, when entering and leaving the math inset. So maybe it's easier to fix than it seemed. But indeed it's not a regression.


Best regards
Guillaume

Attachment: lyx-bug-undefined.lyx
Description: application/lyx

Attachment: lyx-bug-renewcommandx4.lyx
Description: application/lyx

diff --git a/lib/scripts/lyxpreview2bitmap.py b/lib/scripts/lyxpreview2bitmap.py
index a7d7623..fe9bea1 100755
--- a/lib/scripts/lyxpreview2bitmap.py
+++ b/lib/scripts/lyxpreview2bitmap.py
@@ -159,65 +159,35 @@ def extract_metrics_info(dvipng_stdout):
 
 
 def fix_latex_file(latex_file, pdf_output):
-    documentclass_re = re.compile("(\\\\documentclass\[)(1[012]pt,?)(.+)")
-    def_re = re.compile(r"(\\newcommandx|\\global\\long\\def)(\\[a-zA-Z])(.+)")
-    usepackage_re = re.compile("\\\\usepackage")
-    userpreamble_re = re.compile("User specified LaTeX commands")
-    enduserpreamble_re = re.compile("\\\\makeatother")
+    documentclass_re = re.compile("(\\\\documentclass)")
+    documentclass_pt_re = re.compile("(\\\\documentclass\[)(1[012]pt,?)(.+)")
+    def_re = re.compile(r"(\\newcommandx|\\renewcommandx)(\\[a-zA-Z])(.+)")
 
     tmp = mkstemp()
 
-    in_user_preamble = 0
-    usepkg = 0
-    changed = 0
-    macros = []
     for line in open(latex_file, 'r').readlines():
-        match = documentclass_re.match(line)
-        if match != None:
-            changed = 1
-            tmp.write("%s%s\n" % (match.group(1), match.group(3)))
-            continue
-
-        if not pdf_output and not usepkg:
-            if userpreamble_re.search(line) != None:
-                in_user_preamble = 1
-            elif enduserpreamble_re.search(line) != None:
-                in_user_preamble = 0
-            if usepackage_re.match(line) != None and in_user_preamble:
-                usepkg = 1
-                changed = 1
-                tmp.write("\\def\\t@a{microtype}\n")
-                tmp.write("\\let\\oldusepkg\\usepackage\n")
-                tmp.write("\\def\\usepackage{\\@ifnextchar[\\@usepkg{\\@usepkg[]}}\n")
-                tmp.write("\\def\\@usepkg[#1]#2{\\@ifnextchar[")
-                tmp.write("{\\@@usepkg[#1]{#2}}{\\@@usepkg[#1]{#2}[]}}\n")
-                tmp.write("\\def\@@usepkg[#1]#2[#3]{\\def\\t@b{#2}")
-                tmp.write("\\ifx\\t@a\\t@b\\else\\oldusepkg[#1]{#2}[#3]\\fi}\n")
+        if documentclass_re.match(line) != None:
+            tmp.write("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Preview specific LaTeX commands.\n")
+            tmp.write("\\global\\long\\def\\definecommandx#1{\\providecommand#1{}\\renewcommandx#1}\n")
+            if not pdf_output:
+                tmp.write("\\PassOptionsToPackage{draft}{microtype}\n")
+            tmp.write("\n\n")
+            match = documentclass_pt_re.match(line)
+            if match != None:
+                tmp.write("%s%s\n" % (match.group(1), match.group(3)))
+            else:
                 tmp.write(line)
-                continue
+            continue
 
         match = def_re.match(line)
         if match == None:
             tmp.write(line)
-            continue
-
-        macroname = match.group(2)
-        if not macroname in macros:
-            macros.append(macroname)
-            tmp.write(line)
-            continue
-
-        definecmd = match.group(1)
-        if definecmd == "\\global\\long\\def":
-            tmp.write(line)
         else:
-            changed = 1
-            tmp.write("\\renewcommandx%s%s\n" % (match.group(2), match.group(3)))
+            tmp.write("\\definecommandx%s%s\n" % (match.group(2), match.group(3)))
 
-    if changed:
-        copyfileobj(tmp, open(latex_file,"wb"), 1)
+    copyfileobj(tmp, open(latex_file,"wb"), 1)
 
-    return changed
+    return 1
 
 
 def convert_to_ppm_format(pngtopnm, basename):

Reply via email to