]> git.lyx.org Git - features.git/commitdiff
*** Extend preview scripts to also handle PDF output (bug 2165) ***
authorJürgen Spitzmüller <spitz@lyx.org>
Wed, 2 Jul 2008 14:42:04 +0000 (14:42 +0000)
committerJürgen Spitzmüller <spitz@lyx.org>
Wed, 2 Jul 2008 14:42:04 +0000 (14:42 +0000)
* src/PreviewLoader.cpp:
- add conditions for preview with pdf output

* lib/scripts/legacy_lyxpreview2ppm.py:
- if no dvi preview file is available, check for a PDF file
  and process that, if found
- also produce png output, if requested.

* lib/scripts/lyxpreview2bitmap.py:
- if no dvi preview file is available, check for a PDF file
  and process that, if found

*  lib/scripts/lyxpreview_tools.py:
- move some common functions here

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

lib/scripts/legacy_lyxpreview2ppm.py
lib/scripts/lyxpreview2bitmap.py
lib/scripts/lyxpreview_tools.py
src/graphics/PreviewLoader.cpp

index f4f13a92233f01e3374c66b3c86e16c484a055a3..cf73897d675b3c294b9cbf31c140e7b42e8dba71 100644 (file)
@@ -56,7 +56,7 @@
 import glob, os, pipes, re, string, sys
 
 from lyxpreview_tools import copyfileobj, error, find_exe, \
-     find_exe_or_terminate, mkstemp, run_command
+     find_exe_or_terminate, make_texcolor, mkstemp, run_command, warning
 
 # Pre-compiled regular expression.
 latex_file_re = re.compile("\.tex$")
@@ -168,25 +168,34 @@ def extract_resolution(log_file, dpi):
     return dpi * (10.0 / fontsize) * (1000.0 / magnification)
 
 
-def legacy_latex_file(latex_file, fg_color, bg_color):
-    use_preview_re = re.compile("(\\\\usepackage\[[^]]+)(\]{preview})")
+def legacy_latex_file(latex_file, fg_color, bg_color, bg_color_gr):
+    use_preview_dvi_re = re.compile("(\s*\\\\usepackage\[[^]]+)(dvips\]{preview})")
+    use_preview_pdf_re = re.compile("(\s*\\\\usepackage\[[^]]+)(pdftex\]{preview})")
 
     tmp = mkstemp()
 
     success = 0
     try:
         for line in open(latex_file, 'r').readlines():
-            match = use_preview_re.match(line)
+            match = use_preview_dvi_re.match(line)
             if match == None:
-                tmp.write(line)
+                match = use_preview_pdf_re.match(line)
+                if match == None:
+                    tmp.write(line)
+                    continue
+                success = 1
+                tmp.write("  \\usepackage{color}\n" \
+                      "  \\pagecolor[rgb]{%s}\n" \
+                      "%s\n" \
+                      % (bg_color_gr, match.group()))
                 continue
 
             success = 1
-            tmp.write("%s,dvips,tightpage%s\n\n" \
-                      "\\AtBeginDocument{\\AtBeginDvi{%%\n" \
-                      "\\special{!userdict begin/bop-hook{//bop-hook exec\n" \
-                      "<%s%s>{255 div}forall setrgbcolor\n" \
-                      "clippath fill setrgbcolor}bind def end}}}\n" \
+            tmp.write("%stightpage,%s\n" \
+                      "  \\AtBeginDocument{\\AtBeginDvi{%%\n" \
+                      "  \\special{!userdict begin/bop-hook{//bop-hook exec\n" \
+                      "  <%s%s>{255 div}forall setrgbcolor\n" \
+                      "  clippath fill setrgbcolor}bind def end}}}\n" \
                       % (match.group(1), match.group(2), fg_color, bg_color))
 
     except:
@@ -226,21 +235,17 @@ def legacy_conversion(argv):
     dpi = string.atoi(argv[2])
 
     output_format = argv[3]
-    if output_format != "ppm":
-        error("This script will generate ppm format images only.")
 
     fg_color = argv[4]
     bg_color = argv[5]
+    bg_color_gr = make_texcolor(argv[5], True)
 
     # External programs used by the script.
-    path = string.split(os.environ["PATH"], os.pathsep)
-    latex   = find_exe_or_terminate(["pplatex", "platex", "latex2e", "latex"], path)
-    dvips   = find_exe_or_terminate(["dvips"], path)
-    gs      = find_exe_or_terminate(["gswin32c", "gs"], path)
-    pnmcrop = find_exe(["pnmcrop"], path)
+    path  = string.split(os.environ["PATH"], os.pathsep)
+    latex = find_exe_or_terminate(["latex", "pplatex", "platex", "latex2e"], path)
 
     # Move color information into the latex file.
-    if not legacy_latex_file(latex_file, fg_color, bg_color):
+    if not legacy_latex_file(latex_file, fg_color, bg_color, bg_color_gr):
         error("Unable to move color info into the latex file")
 
     # Compile the latex file.
@@ -251,15 +256,29 @@ def legacy_conversion(argv):
         error("%s failed to compile %s" \
               % (os.path.basename(latex), latex_file))
 
+    return legacy_conversion_step2(latex_file, dpi, output_format)
+
+
+def legacy_conversion_step2(latex_file, dpi, output_format):
+    # External programs used by the script.
+    path    = string.split(os.environ["PATH"], os.pathsep)
+    dvips   = find_exe_or_terminate(["dvips"], path)
+    gs      = find_exe_or_terminate(["gswin32c", "gs"], path)
+    pnmcrop = find_exe(["pnmcrop"], path)
+
     # Run the dvi file through dvips.
     dvi_file = latex_file_re.sub(".dvi", latex_file)
     ps_file  = latex_file_re.sub(".ps",  latex_file)
+    pdf_file  = latex_file_re.sub(".pdf", latex_file)
 
     dvips_call = '%s -o "%s" "%s"' % (dvips, ps_file, dvi_file)
+    dvips_failed = False
 
     dvips_status, dvips_stdout = run_command(dvips_call)
     if dvips_status != None:
-        error("Failed: %s %s" % (os.path.basename(dvips), dvi_file))
+        warning('Failed: %s %s ... looking for PDF' \
+            % (os.path.basename(dvips), dvi_file))
+        dvips_failed = True
 
     # Extract resolution data for gs from the log file.
     log_file = latex_file_re.sub(".log", latex_file)
@@ -271,13 +290,27 @@ def legacy_conversion(argv):
     if resolution > 150:
         alpha = 2
 
+    gs_device = "png16m"
+    gs_ext = "png"
+    if output_format == "ppm":
+        gs_device = "pnmraw"
+        gs_ext = "ppm"
+
     # Generate the bitmap images
-    gs_call = '%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pnmraw ' \
-              '-sOutputFile="%s%%d.ppm" ' \
+    gs_call = '%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s ' \
+              '-sOutputFile="%s%%d.%s" ' \
               '-dGraphicsAlphaBit=%d -dTextAlphaBits=%d ' \
               '-r%f "%s"' \
-              % (gs, latex_file_re.sub("", latex_file), \
-                 alpha, alpha, resolution, ps_file)
+              % (gs, gs_device, latex_file_re.sub("", latex_file), \
+                 gs_ext, alpha, alpha, resolution, ps_file)
+
+    if dvips_failed:
+        gs_call = '%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s ' \
+                  '-sOutputFile="%s%%d.%s" ' \
+                  '-dGraphicsAlphaBit=%d -dTextAlphaBits=%d ' \
+                  '-r%f "%s"' \
+                  % (gs, gs_device, latex_file_re.sub("", latex_file), \
+                     gs_ext, alpha, alpha, resolution, pdf_file)
 
     gs_status, gs_stdout = run_command(gs_call)
     if gs_status != None:
index b629b15231934dc0e582be6ca0d10e0d76906255..2defeee601e425547ad56ba308d25c89eb8b9786 100755 (executable)
 
 import glob, os, re, string, sys
 
-from legacy_lyxpreview2ppm import legacy_conversion
+from legacy_lyxpreview2ppm import legacy_conversion, \
+     legacy_conversion_step2
 
-from lyxpreview_tools import error, find_exe, \
-     find_exe_or_terminate, run_command
+from lyxpreview_tools import copyfileobj, error, find_exe, \
+     find_exe_or_terminate, make_texcolor, mkstemp, run_command, warning
 
 
 # Pre-compiled regular expressions.
-hexcolor_re = re.compile("^[0-9a-fA-F]{6}$")
 latex_file_re = re.compile("\.tex$")
 
 
@@ -64,18 +64,6 @@ def usage(prog_name):
            % prog_name
 
 
-def make_texcolor(hexcolor):
-    # Test that the input string contains 6 hexadecimal chars.
-    if not hexcolor_re.match(hexcolor):
-        error("Cannot convert color '%s'" % hexcolor)
-
-    red   = float(string.atoi(hexcolor[0:2], 16)) / 255.0
-    green = float(string.atoi(hexcolor[2:4], 16)) / 255.0
-    blue  = float(string.atoi(hexcolor[4:6], 16)) / 255.0
-
-    return "rgb %f %f %f" % (red, green, blue)
-
-
 def extract_metrics_info(dvipng_stdout, metrics_file):
     metrics = open(metrics_file, 'w')
 # "\[[0-9]+" can match two kinds of numbers: page numbers from dvipng
@@ -117,6 +105,37 @@ def extract_metrics_info(dvipng_stdout, metrics_file):
     return success
 
 
+def color_pdf(latex_file, bg_color):
+    use_preview_pdf_re = re.compile("(\s*\\\\usepackage\[[^]]+)(pdftex\]{preview})")
+
+    tmp = mkstemp()
+
+    success = 0
+    try:
+        for line in open(latex_file, 'r').readlines():
+            match = use_preview_pdf_re.match(line)
+            if match == None:
+                tmp.write(line)
+                continue
+            success = 1
+            tmp.write("  \\usepackage{color}\n" \
+                  "  \\pagecolor[rgb]{%s}\n" \
+                  "%s\n" \
+                  % (bg_color, match.group()))
+            continue
+
+    except:
+        # Unable to open the file, but do nothing here because
+        # the calling function will act on the value of 'success'.
+        warning('Warning in color_pdf! Unable to open "%s"' % latex_file)
+        warning(`sys.exc_type` + ',' + `sys.exc_value`)
+
+    if success:
+        copyfileobj(tmp, open(latex_file,"wb"), 1)
+
+    return success
+
+
 def convert_to_ppm_format(pngtopnm, basename):
     png_file_re = re.compile("\.png$")
 
@@ -145,30 +164,32 @@ def main(argv):
         os.chdir(dir)
 
     dpi = string.atoi(argv[3])
-    fg_color = make_texcolor(argv[4])
-    bg_color = make_texcolor(argv[5])
+    fg_color = make_texcolor(argv[4], False)
+    bg_color = make_texcolor(argv[5], False)
+
+    bg_color_gr = make_texcolor(argv[5], True)
 
     # External programs used by the script.
     path = string.split(os.environ["PATH"], os.pathsep)
-    latex = find_exe_or_terminate(["pplatex", "platex", "latex2e", "latex"], path)
+    latex = find_exe_or_terminate(["latex", "pplatex", "platex", "latex2e"], path)
 
     # This can go once dvipng becomes widespread.
     dvipng = find_exe(["dvipng"], path)
     if dvipng == None:
-        if output_format == "ppm":
-            # 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.
-            vec = [ argv[0], argv[2], argv[3], argv[1], argv[4], argv[5] ]
-            return legacy_conversion(vec)
-        else:
-            error("The old 'dvi->ps->ppm' conversion requires "
-                  "ppm as the output format")
+        # 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.
+        vec = [ argv[0], argv[2], argv[3], argv[1], argv[4], argv[5] ]
+        return legacy_conversion(vec)
 
     pngtopnm = ""
     if output_format == "ppm":
         pngtopnm = find_exe_or_terminate(["pngtopnm"], path)
 
+    # Move color information for PDF into the latex file.
+    if not color_pdf(latex_file, bg_color_gr):
+        error("Unable to move color info into the latex file")
+
     # Compile the latex file.
     latex_call = '%s "%s"' % (latex, latex_file)
 
@@ -184,8 +205,9 @@ def main(argv):
 
     dvipng_status, dvipng_stdout = run_command(dvipng_call)
     if dvipng_status != None:
-        error("%s failed to generate images from %s" \
+        warning("%s failed to generate images from %s ... looking for PDF" \
               % (os.path.basename(dvipng), dvi_file))
+        return legacy_conversion_step2(latex_file, dpi, output_format)
 
     # Extract metrics info from dvipng_stdout.
     metrics_file = latex_file_re.sub(".metrics", latex_file)
index bab609706ad92e8df8cfe848e9af5c8ecf0db426..73dbc9a1f46cb8bf572869b1a300f2d573fbb9f9 100644 (file)
@@ -11,7 +11,7 @@
 #   Paul A. Rubin, rubin@msu.edu.
 
 # A repository of the following functions, used by the lyxpreview2xyz scripts.
-# copyfileobj, error, find_exe, find_exe_or_terminate, mkstemp,
+# copyfileobj, error, find_exe, find_exe_or_terminate, make_texcolor, mkstemp,
 # run_command, warning
 
 import os, re, string, sys, tempfile
@@ -43,6 +43,22 @@ def error(message):
     sys.exit(1)
 
 
+def make_texcolor(hexcolor, graphics):
+    # Test that the input string contains 6 hexadecimal chars.
+    hexcolor_re = re.compile("^[0-9a-fA-F]{6}$")
+    if not hexcolor_re.match(hexcolor):
+        error("Cannot convert color '%s'" % hexcolor)
+
+    red   = float(string.atoi(hexcolor[0:2], 16)) / 255.0
+    green = float(string.atoi(hexcolor[2:4], 16)) / 255.0
+    blue  = float(string.atoi(hexcolor[4:6], 16)) / 255.0
+
+    if graphics:
+        return "%f,%f,%f" % (red, green, blue)
+    else:
+        return "rgb %f %f %f" % (red, green, blue)
+
+
 def find_exe(candidates, path):
     for prog in candidates:
         for directory in path:
index 3c3fd9d38a43ff059084b220c1ac4f00a84af0cc..1a478a81ac10ea44e5b2cbee03c7161240d82e89 100644 (file)
@@ -717,8 +717,19 @@ void PreviewLoader::Impl::dumpPreamble(odocstream & os) const
 
        // Use the preview style file to ensure that each snippet appears on a
        // fresh page.
+       // Also support PDF output (automatically generated e.g. when
+       // \usepackage[pdftex]{hyperref} is used.
        os << "\n"
-          << "\\usepackage[active,delayed,dvips,showlabels,lyx]{preview}\n"
+          << "\\newif\\ifpdf\n"
+          << "\\ifx\\pdfoutput\\undefined\n"
+          << "\\else\\ifx\\pdfoutput\\relax\n"
+          << "\\else\\ifnum0=\\pdfoutput\n"
+          << "\\else\\pdftrue\\fi\\fi\\fi\n"
+          << "\\ifpdf\n"
+          << "  \\usepackage[active,delayed,tightpage,showlabels,lyx,pdftex]{preview}\n"
+          << "\\else\n"
+          << "  \\usepackage[active,delayed,showlabels,lyx,dvips]{preview}\n"
+          << "\\fi\n"
           << "\n";
 }