]> git.lyx.org Git - features.git/commitdiff
Try even harder to obtain an instant preview
authorEnrico Forestieri <forenr@lyx.org>
Wed, 29 Apr 2015 10:28:51 +0000 (12:28 +0200)
committerEnrico Forestieri <forenr@lyx.org>
Wed, 29 Apr 2015 10:32:54 +0000 (12:32 +0200)
This is a followup commit to 691fdea3 and restores the behavior of the
script as it was intended before 64e0c558, other than taking into account
possible inclusion of files that only pdflatex can process and the
possibility of multiple defined math macros.
The instant previews in the math manual now work again.

lib/scripts/legacy_lyxpreview2ppm.py
lib/scripts/lyxpreview2bitmap.py

index c9c3081af99e85591e307f5807317720972788dd..597883a4aa32ad1ff076967aa7bc3c509e8cb411 100644 (file)
@@ -482,13 +482,13 @@ def legacy_conversion_step3(latex_file, dpi, output_format, dvips_failed, skipMe
             i = i + 1
             progress("Processing page %s, file %s" % (i, file))
             if use_pdftocairo and epstopdf != None:
-                conv_name = "PdfToCairo"
+                conv_name = "pdftocairo"
                 conv_status, conv_stdout = run_command("%s --outfile=%s.pdf %s"
                                                        % (epstopdf, file, file))
                 if not conv_status:
                     conv_status, conv_stdout = run_command(conv_call % (file, i))
             else:
-                conv_name = "Ghostscript"
+                conv_name = "ghostscript"
                 conv_status, conv_stdout = run_command(conv_call % (i, file))
 
             if conv_status:
@@ -498,6 +498,7 @@ def legacy_conversion_step3(latex_file, dpi, output_format, dvips_failed, skipMe
 
     # Pass failed pages to pdflatex
     if len(failed_pages) > 0:
+        warning("Now trying to obtain failed previews through pdflatex")
         legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics,
             use_pdftocairo, conv, gs_device, gs_ext, alpha, resolution,
             output_format)
index b387529189913db45b12b3271009052d6a29bfb3..de4121f2dbca750ea22ed3226c0a8d070ad22d00 100755 (executable)
@@ -159,18 +159,25 @@ def extract_metrics_info(dvipng_stdout):
 
 def fix_latex_file(latex_file):
     documentclass_re = re.compile("(\\\\documentclass\[)(1[012]pt,?)(.+)")
+    newcommandx_re = re.compile("^(\\\\newcommandx)(.+)")
 
     tmp = mkstemp()
 
     changed = 0
     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
+
+        match = newcommandx_re.match(line)
         if match == None:
             tmp.write(line)
             continue
 
         changed = 1
-        tmp.write("%s%s\n" % (match.group(1), match.group(3)))
+        tmp.write("\\providecommandx%s\n" % match.group(2))
 
     if changed:
         copyfileobj(tmp, open(latex_file,"wb"), 1)
@@ -195,15 +202,17 @@ def convert_to_ppm_format(pngtopnm, basename):
 
 # Returns a tuple of:
 # ps_pages: list of page indexes of pages containing PS literals
+# pdf_pages: list of page indexes of pages requiring running pdflatex
 # page_count: total number of pages
-# pages_parameter: parameter for dvipng to exclude pages with PostScript
+# pages_parameter: parameter for dvipng to exclude pages with PostScript/PDF
 def find_ps_pages(dvi_file):
     # latex failed
     # FIXME: try with pdflatex
     if not os.path.isfile(dvi_file):
         error("No DVI output.")
 
-    # Check for PostScript specials in the dvi, badly supported by dvipng
+    # Check for PostScript specials in the dvi, badly supported by dvipng,
+    # and inclusion of PDF/PNG/JPG files. 
     # This is required for correct rendering of PSTricks and TikZ
     dv2dt = find_exe_or_terminate(["dv2dt"])
     dv2dt_call = '%s "%s"' % (dv2dt, dvi_file)
@@ -211,33 +220,47 @@ def find_ps_pages(dvi_file):
     # The output from dv2dt goes to stdout
     dv2dt_status, dv2dt_output = run_command(dv2dt_call)
     psliteral_re = re.compile("^special[1-4] [0-9]+ '(\"|ps:)")
+    pdffile_re = re.compile("^special[1-4] [0-9]+ 'PSfile=.*.(pdf|png|jpg)")
 
-    # Parse the dtl file looking for PostScript specials.
-    # Pages using PostScript specials are recorded in ps_pages and then
-    # used to create a different LaTeX file for processing in legacy mode.
+    # Parse the dtl file looking for PostScript specials and pdflatex files.
+    # Pages using PostScript specials or pdflatex files are recorded in
+    # ps_pages or pdf_pages, respectively, and then used to create a
+    # different LaTeX file for processing in legacy mode.
     page_has_ps = False
+    page_has_pdf = False
     page_index = 0
     ps_pages = []
+    pdf_pages = []
+    ps_or_pdf_pages = []
 
     for line in dv2dt_output.split("\n"):
         # New page
         if line.startswith("bop"):
             page_has_ps = False
+            page_has_pdf = False
             page_index += 1
 
         # End of page
-        if line.startswith("eop") and page_has_ps:
-            # We save in a list all the PostScript pages
-            ps_pages.append(page_index)
+        if line.startswith("eop") and (page_has_ps or page_has_pdf):
+            # We save in a list all the PostScript/PDF pages
+            if page_has_ps:
+                ps_pages.append(page_index)
+            else:
+                pdf_pages.append(page_index)
+            ps_or_pdf_pages.append(page_index)
 
         if psliteral_re.match(line) != None:
             # Literal PostScript special detected!
             page_has_ps = True
 
+        if pdffile_re.match(line) != None:
+            # Inclusion of pdflatex image file detected!
+            page_has_pdf = True
+
     # Create the -pp parameter for dvipng
     pages_parameter = ""
-    if len(ps_pages) > 0 and len(ps_pages) < page_index:
-        # Don't process Postscript pages with dvipng by selecting the
+    if len(ps_or_pdf_pages) > 0 and len(ps_or_pdf_pages) < page_index:
+        # Don't process Postscript/PDF pages with dvipng by selecting the
         # wanted pages through the -pp parameter. E.g., dvipng -pp 4-12,14,64
         pages_parameter = " -pp "
         skip = True
@@ -246,7 +269,7 @@ def find_ps_pages(dvi_file):
         # Use page ranges, as a list of pages could exceed command line
         # maximum length (especially under Win32)
         for index in xrange(1, page_index + 1):
-            if (not index in ps_pages) and skip:
+            if (not index in ps_or_pdf_pages) and skip:
                 # We were skipping pages but current page shouldn't be skipped.
                 # Add this page to -pp, it could stay alone or become the
                 # start of a range.
@@ -255,7 +278,7 @@ def find_ps_pages(dvi_file):
                 last = index
                 # We're not skipping anymore
                 skip = False
-            elif (index in ps_pages) and (not skip):
+            elif (index in ps_or_pdf_pages) and (not skip):
                 # We weren't skipping but current page should be skipped
                 if last != index - 1:
                     # If the start index of the range is the previous page
@@ -270,10 +293,10 @@ def find_ps_pages(dvi_file):
         # Remove the trailing separator
         pages_parameter = pages_parameter.rstrip(",")
         # We've to manage the case in which the last page is closing a range
-        if (not index in ps_pages) and (not skip) and (last != index):
+        if (not index in ps_or_pdf_pages) and (not skip) and (last != index):
                 pages_parameter += "-" + str(index)
 
-    return (ps_pages, page_index, pages_parameter)
+    return (ps_pages, pdf_pages, page_index, pages_parameter)
 
 def main(argv):
     # Set defaults.
@@ -368,7 +391,8 @@ def main(argv):
     progress("Preprocess through lilypond-book: %s" % lilypond)
     progress("Altering the latex file for font size and colors")
 
-    # Omit font size specification in latex file.
+    # Omit font size specification in latex file and make sure multiple
+    # defined macros are not an issue.
     fix_latex_file(latex_file)
 
     if lilypond:
@@ -411,11 +435,7 @@ def main(argv):
                 fg_color, bg_color, latex, pdf_output)
 
     # Compile the latex file.
-    latex_status, latex_stdout = run_latex(latex, latex_file, bibtex)
-    if latex_status:
-        progress("Using the legacy conversion method and pdflatex (latex failed)")
-        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
-            bg_color, "pdflatex", True)
+    run_latex(latex, latex_file, bibtex)
 
     # The dvi output file name
     dvi_file = latex_file_re.sub(".dvi", latex_file)
@@ -434,17 +454,22 @@ def main(argv):
             error("No DVI or PDF output. %s failed." \
                 % (os.path.basename(latex)))
 
-    # Look for PS literals in DVI pages
-    # ps_pages: list of page indexes of pages containing PS literals
+    # Look for PS literals or inclusion of pdflatex files in DVI pages
+    # ps_pages: list of indexes of pages containing PS literals
+    # pdf_pages: list of indexes of pages requiring running pdflatex
     # page_count: total number of pages
     # pages_parameter: parameter for dvipng to exclude pages with PostScript
-    (ps_pages, page_count, pages_parameter) = find_ps_pages(dvi_file)
+    (ps_pages, pdf_pages, page_count, pages_parameter) = find_ps_pages(dvi_file)
 
-    # If all pages need PostScript, directly use the legacy method.
+    # If all pages need PostScript or pdflatex, directly use the legacy method.
     if len(ps_pages) == page_count:
         progress("Using the legacy conversion method (PostScript support)")
         return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
             bg_color, latex, pdf_output)
+    elif len(pdf_pages) == page_count:
+        progress("Using the legacy conversion method (PDF support)")
+        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
+            bg_color, "pdflatex", True)
 
     # Run the dvi file through dvipng.
     dvipng_call = '%s -Ttight -depth -height -D %d -fg "%s" -bg "%s" %s "%s"' \
@@ -483,6 +508,27 @@ def main(argv):
         join_metrics_and_rename(dvipng_metrics, legacy_metrics, ps_pages,
             original_bitmap, destination_bitmap)
 
+    # If some pages require running pdflatex pass them to legacy method
+    if len(pdf_pages) > 0:
+        # Create a new LaTeX file just for the snippets needing
+        # the legacy method
+        legacy_latex_file = latex_file_re.sub("_legacy.tex", latex_file)
+        filter_pages(latex_file, legacy_latex_file, pdf_pages)
+
+        # Pass the new LaTeX file to the legacy method
+        progress("Pages %s include pdflatex image files" % pdf_pages)
+        progress("Using the legacy conversion method (PDF support)")
+        legacy_status, legacy_metrics = legacy_conversion_step1(legacy_latex_file,
+            dpi, output_format, fg_color, bg_color, "pdflatex", True, True)
+
+        # Now we need to mix metrics data from dvipng and the legacy method
+        original_bitmap = latex_file_re.sub("%d." + output_format, legacy_latex_file)
+        destination_bitmap = latex_file_re.sub("%d." + output_format, latex_file)
+
+        # Join metrics from dvipng and legacy, and rename legacy bitmaps
+        join_metrics_and_rename(dvipng_metrics, legacy_metrics, pdf_pages,
+            original_bitmap, destination_bitmap)
+
     # Convert images to ppm format if necessary.
     if output_format == "ppm":
         convert_to_ppm_format(pngtopnm, latex_file_re.sub("", latex_file))