]> git.lyx.org Git - lyx.git/commitdiff
Better error and progress messages for lyxpreview.
authorJulien Rioux <jrioux@lyx.org>
Sun, 11 Sep 2011 18:23:29 +0000 (18:23 +0000)
committerJulien Rioux <jrioux@lyx.org>
Sun, 11 Sep 2011 18:23:29 +0000 (18:23 +0000)
Introduce --debug and --verbose flags to control output. Also, use the
python subprocess module to capture stderr from external commands, thus
bumping the python requirement to version 2.4 or later.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@39660 a592a061-630c-0410-9148-cb99ea01b6c8

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

index f34dbed8b01c9a20a7ae24784065fa96139431a4..6f07d38850a3bf4afd8156cba42f72e51129e08b 100644 (file)
@@ -36,6 +36,7 @@
 #   the images correctly on the screen.
 
 # The script uses several external programs and files:
+# * python 2.4 or later (subprocess module);
 # * A latex executable;
 # * preview.sty;
 # * dvips;
@@ -76,7 +77,7 @@ import glob, os, pipes, re, string, sys
 
 from lyxpreview_tools import copyfileobj, error, filter_pages, find_exe, \
      find_exe_or_terminate, join_metrics_and_rename, latex_commands, \
-     latex_file_re, make_texcolor, mkstemp, run_command, warning, \
+     latex_file_re, make_texcolor, mkstemp, progress, run_command, warning, \
      write_metrics_info
 
 
@@ -277,7 +278,7 @@ def legacy_conversion(argv, skipMetrics = False):
     latex_call = '%s "%s"' % (latex, latex_file)
 
     latex_status, latex_stdout = run_command(latex_call)
-    if latex_status != None:
+    if latex_status:
         warning("%s had problems compiling %s" \
               % (os.path.basename(latex), latex_file))
 
@@ -301,6 +302,9 @@ def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics, gs,
         # pdflatex call
         pdflatex_call = '%s "%s"' % (pdflatex, pdf_latex_file)
         pdflatex_status, pdflatex_stdout = run_command(pdflatex_call)
+        if pdflatex_status:
+            warning("%s had problems compiling %s" \
+                % (os.path.basename(pdflatex), pdf_latex_file))
 
         pdf_file = latex_file_re.sub(".pdf", pdf_latex_file)
 
@@ -312,7 +316,7 @@ def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics, gs,
                     % (gs, gs_device, latex_file_re.sub("", pdf_latex_file), \
                         gs_ext, alpha, alpha, resolution, pdf_file)
         gs_status, gs_stdout = run_command(gs_call)
-        if gs_status != None:
+        if gs_status:
             # Give up!
             warning("Some pages failed with all the possible routes")
         else:
@@ -343,7 +347,7 @@ def legacy_conversion_step2(latex_file, dpi, output_format, skipMetrics = False)
     dvips_failed = False
 
     dvips_status, dvips_stdout = run_command(dvips_call)
-    if dvips_status != None:
+    if dvips_status:
         warning('Failed: %s %s ... looking for PDF' \
             % (os.path.basename(dvips), dvi_file))
         dvips_failed = True
@@ -381,7 +385,7 @@ def legacy_conversion_step2(latex_file, dpi, output_format, skipMetrics = False)
                      gs_ext, alpha, alpha, resolution, pdf_file)
 
         gs_status, gs_stdout = run_command(gs_call)
-        if gs_status != None:
+        if gs_status:
             error("Failed: %s %s" % (os.path.basename(gs), ps_file))
     else:
         # Model for calling gs on each file
@@ -400,9 +404,11 @@ def legacy_conversion_step2(latex_file, dpi, output_format, skipMetrics = False)
         # Call GhostScript for each file
         for file in ps_files:
             i = i + 1
+            progress("Processing page %s, file %s" % (i, file))
             gs_status, gs_stdout = run_command(gs_call % (i, file))
-            if gs_status != None:
+            if gs_status:
                 # gs failed, keep track of this
+                warning("Ghostscript failed on page %s, file %s" % (i, file))
                 failed_pages.append(i)
 
     # Pass failed pages to pdflatex
index 72e6322242638b09a564a51119397b06d472c09a..69d0317eb59f8309be4e87d7f77f5b6829679634 100755 (executable)
@@ -16,6 +16,7 @@
 # png or ppm image files, one per previewed snippet.
 
 # Pre-requisites:
+# * python 2.4 or later (subprocess module);
 # * A latex executable;
 # * preview.sty;
 # * dvipng;
 #   --lilypond:    Preprocess through lilypond-book. Default is false.
 #   --lilypond-book=<exe>:
 #                  The converter for lytex files. Default is lilypond-book.
+#
+#   -d, --debug    Show the output from external commands.
+#   -h, --help     Show an help screen and exit.
+#   -v, --verbose  Show progress messages.
 
 # Decomposing TEXFILE's name as DIR/BASE.tex, this script will,
 # if executed successfully, leave in DIR:
@@ -77,8 +82,8 @@ from legacy_lyxpreview2ppm import legacy_conversion, \
 
 from lyxpreview_tools import copyfileobj, error, filter_pages, find_exe, \
      find_exe_or_terminate, join_metrics_and_rename, latex_commands, \
-     latex_file_re, make_texcolor, mkstemp, pdflatex_commands, run_command, \
-     warning, write_metrics_info
+     latex_file_re, make_texcolor, mkstemp, pdflatex_commands, progress, \
+     run_command, warning, write_metrics_info
 
 
 def usage(prog_name):
@@ -86,7 +91,6 @@ def usage(prog_name):
 Usage: %s <options> <input file>
 
 Options:
-  -h, --help:    Show this help and exit
   --dpi=<res>:   Resolution per inch (default: 128)
   --png, --ppm:  Select the output format (default: png)
   --fg=<color>:  Foreground color (default: black, ie '000000')
@@ -96,6 +100,10 @@ Options:
   --lilypond-book=<exe>:
                  The executable for lilypond-book (default: lilypond-book)
 
+  -d, --debug:   Show the output from external commands
+  -h, --help:    Show this help screen and exit
+  -v, --verbose: Show progress messages
+
 The colors are hexadecimal strings, eg 'faf0e6'."""
     return msg % prog_name
 
@@ -200,7 +208,7 @@ def fix_latex_file(latex_file):
     if changed:
         copyfileobj(tmp, open(latex_file,"wb"), 1)
 
-    return
+    return changed
 
 
 def convert_to_ppm_format(pngtopnm, basename):
@@ -211,7 +219,7 @@ def convert_to_ppm_format(pngtopnm, basename):
 
         p2p_cmd = '%s "%s"' % (pngtopnm, png_file)
         p2p_status, p2p_stdout = run_command(p2p_cmd)
-        if p2p_status != None:
+        if p2p_status:
             error("Unable to convert %s to ppm format" % png_file)
 
         ppm = open(ppm_file, 'w')
@@ -313,11 +321,11 @@ def main(argv):
 
     # Parse and manipulate the command line arguments.
     try:
-        (opts, args) = getopt.gnu_getopt(argv[1:], "h", ["bg=",
+        (opts, args) = getopt.gnu_getopt(argv[1:], "dhv", ["bg=", "debug",
             "dpi=", "fg=", "help", "latex=", "lilypond", "lilypond-book=",
-            "png", "ppm"])
-    except getopt.GetoptError:
-        error(usage(script_name))
+            "png", "ppm", "verbose"])
+    except getopt.GetoptError, err:
+        error("%s\n%s" % (err, usage(script_name)))
 
     opts.reverse()
     for opt, val in opts:
@@ -326,6 +334,9 @@ def main(argv):
             sys.exit(0)
         elif opt == "--bg":
             bg_color = val
+        elif opt in ("-d", "--debug"):
+            import lyxpreview_tools
+            lyxpreview_tools.debug = True
         elif opt == "--dpi":
             try:
                 dpi = string.atoi(val)
@@ -341,12 +352,29 @@ def main(argv):
             lilypond_book = [val]
         elif opt in ("--png", "--ppm"):
             output_format = opt[2:]
+        elif opt in ("-v", "--verbose"):
+            import lyxpreview_tools
+            lyxpreview_tools.verbose = True
 
+    # Determine input file
     if len(args) != 1:
-        error(usage(script_name))
+        err = "A single input file is required, %s given" % (len(args) or "none")
+        error("%s\n%s" % (err, usage(script_name)))
 
     input_path = args[0]
     dir, latex_file = os.path.split(input_path)
+
+    # Echo the settings
+    progress("Starting %s..." % script_name)
+    progress("Output format: %s" % output_format)
+    progress("Foreground color: %s" % fg_color)
+    progress("Background color: %s" % bg_color)
+    progress("Resolution (dpi): %s" % dpi)
+    progress("File to process: %s" % input_path)
+
+    # Check for the input file
+    if not os.path.exists(input_path):
+        error('File "%s" not found.' % input_path)
     if len(dir) != 0:
         os.chdir(dir)
 
@@ -364,10 +392,18 @@ def main(argv):
     # These flavors of latex are known to produce pdf output
     pdf_output = latex in pdflatex_commands
 
+    progress("Latex command: %s" % latex)
+    progress("Latex produces pdf output: %s" % pdf_output)
+    progress("Lilypond-book command: %s" % lilypond_book)
+    progress("Preprocess through lilypond-book: %s" % lilypond)
+    progress("Altering the latex file for font size and colors")
+
     # Omit font size specification in latex file.
-    fix_latex_file(latex_file)
+    if not fix_latex_file(latex_file):
+        warning("Unable to remove font size from the latex file")
 
     if lilypond:
+        progress("Preprocess the latex file through %s" % lilypond_book)
         if pdf_output:
             lilypond_book += ' --pdf'
 
@@ -379,7 +415,7 @@ def main(argv):
         lytex_call = '%s --safe --latex-program=%s "%s"' % (lilypond_book,
             latex, lytex_file)
         lytex_status, lytex_stdout = run_command(lytex_call)
-        if lytex_status != None:
+        if lytex_status:
             warning("%s failed to compile %s" \
                 % (os.path.basename(lilypond_book), lytex_file))
 
@@ -389,6 +425,7 @@ def main(argv):
         # The data is input to legacy_conversion in as similar
         # as possible a manner to that input to the code used in
         # LyX 1.3.x.
+        progress("Using the legacy conversion method (dvipng not found)")
         vec = [ script_name, input_path, str(dpi), output_format, fg_color, bg_color, latex ]
         return legacy_conversion(vec)
 
@@ -398,13 +435,13 @@ def main(argv):
 
     # Move color information for PDF into the latex file.
     if not color_pdf(latex_file, bg_color_gr, fg_color_gr):
-        error("Unable to move color info into the latex file")
+        warning("Unable to move color info into the latex file")
 
     # Compile the latex file.
     latex_call = '%s "%s"' % (latex, latex_file)
 
     latex_status, latex_stdout = run_command(latex_call)
-    if latex_status != None:
+    if latex_status:
         warning("%s had problems compiling %s" \
               % (os.path.basename(latex), latex_file))
 
@@ -421,8 +458,8 @@ def main(argv):
         # No DVI, is there a PDF?
         pdf_file = latex_file_re.sub(".pdf", latex_file)
         if os.path.isfile(pdf_file):
-            warning("%s produced a PDF output, fallback to legacy." % \
-                (os.path.basename(latex)))
+            progress("%s produced a PDF output, fallback to legacy." \
+                (os.path.basename(latex)))
             return legacy_conversion_step2(latex_file, dpi, output_format)
         else:
             error("No DVI or PDF output. %s failed." \
@@ -437,6 +474,7 @@ def main(argv):
     # If all pages need PostScript, directly use the legacy method.
     if len(ps_pages) == page_count:
         vec = [ script_name, input_path, str(dpi), output_format, fg_color, bg_color, latex ]
+        progress("Using the legacy conversion method (PostScript support)")
         return legacy_conversion(vec)
 
     # Run the dvi file through dvipng.
@@ -444,10 +482,11 @@ def main(argv):
         % (dvipng, dpi, fg_color_dvipng, bg_color_dvipng, pages_parameter, dvi_file)
     dvipng_status, dvipng_stdout = run_command(dvipng_call)
 
-    if dvipng_status != None:
+    if dvipng_status:
         warning("%s failed to generate images from %s... fallback to legacy method" \
               % (os.path.basename(dvipng), dvi_file))
         # FIXME: skip unnecessary dvips trial in legacy_conversion_step2
+        progress("Using the legacy conversion method (dvipng failed)")
         return legacy_conversion_step2(latex_file, dpi, output_format)
 
     # Extract metrics info from dvipng_stdout.
@@ -464,6 +503,8 @@ def main(argv):
         # Pass the new LaTeX file to the legacy method
         vec = [ script_name, latex_file_re.sub("_legacy.tex", input_path),
                 str(dpi), output_format, fg_color, bg_color, latex ]
+        progress("Pages %s include postscript specials" % ps_pages)
+        progress("Using the legacy conversion method (PostScript support)")
         legacy_metrics = legacy_conversion(vec, True)[1]
 
         # Now we need to mix metrics data from dvipng and the legacy method
index 7be2459f3d148788d4e0f8c818992a972e5c7706..b24f9721559e9db300c0bc733705236d9851b11a 100644 (file)
 
 # A repository of the following functions, used by the lyxpreview2xyz scripts.
 # copyfileobj, error, find_exe, find_exe_or_terminate, make_texcolor, mkstemp,
-# run_command, warning
+# progress, run_command, warning
 
-import os, re, string, sys, tempfile
+# Requires python 2.4 or later (subprocess module).
 
+import os, re, string, subprocess, sys, tempfile
+
+
+# Control the output to stdout
+debug = False
+verbose = False
 
 # Known flavors of latex
 latex_commands = ("latex", "pplatex", "platex", "latex2e")
@@ -48,12 +54,18 @@ if os.name == "nt":
         use_win32_modules = 0
 
 
+def progress(message):
+    global verbose
+    if verbose:
+        sys.stdout.write("Progress: %s\n" % message)
+
+
 def warning(message):
-    sys.stderr.write(message + '\n')
+    sys.stderr.write("Warning: %s\n" % message)
 
 
 def error(message):
-    sys.stderr.write(message + '\n')
+    sys.stderr.write("Error: %s\n" % message)
     sys.exit(1)
 
 
@@ -99,10 +111,14 @@ def find_exe_or_terminate(candidates):
 
 
 def run_command_popen(cmd):
-    handle = os.popen(cmd, 'r')
-    cmd_stdout = handle.read()
-    cmd_status = handle.close()
-
+    pipe = subprocess.Popen(cmd, shell=True, close_fds=True, stdin=subprocess.PIPE, \
+        stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
+    cmd_stdout = pipe.communicate()[0]
+    cmd_status = pipe.returncode
+
+    global debug
+    if debug:
+        sys.stdout.write(cmd_stdout)
     return cmd_status, cmd_stdout
 
 
@@ -150,10 +166,14 @@ def run_command_win32(cmd):
     if win32process.GetExitCodeProcess(process):
         return -3, ""
 
-    return None, data
+    global debug
+    if debug:
+        sys.stdout.write(data)
+    return 0, data
 
 
 def run_command(cmd):
+    progress("Running %s" % cmd)
     if use_win32_modules:
         return run_command_win32(cmd)
     else: