From: Jürgen Spitzmüller Date: Wed, 2 Jul 2008 14:42:04 +0000 (+0000) Subject: *** Extend preview scripts to also handle PDF output (bug 2165) *** X-Git-Tag: 1.6.10~4252 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=01c71419d9e8e21fab0dfcd6363b31b53f61faf7;p=lyx.git *** Extend preview scripts to also handle PDF output (bug 2165) *** * 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 --- diff --git a/lib/scripts/legacy_lyxpreview2ppm.py b/lib/scripts/legacy_lyxpreview2ppm.py index f4f13a9223..cf73897d67 100644 --- a/lib/scripts/legacy_lyxpreview2ppm.py +++ b/lib/scripts/legacy_lyxpreview2ppm.py @@ -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: diff --git a/lib/scripts/lyxpreview2bitmap.py b/lib/scripts/lyxpreview2bitmap.py index b629b15231..2defeee601 100755 --- a/lib/scripts/lyxpreview2bitmap.py +++ b/lib/scripts/lyxpreview2bitmap.py @@ -47,14 +47,14 @@ 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) diff --git a/lib/scripts/lyxpreview_tools.py b/lib/scripts/lyxpreview_tools.py index bab609706a..73dbc9a1f4 100644 --- a/lib/scripts/lyxpreview_tools.py +++ b/lib/scripts/lyxpreview_tools.py @@ -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: diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp index 3c3fd9d38a..1a478a81ac 100644 --- a/src/graphics/PreviewLoader.cpp +++ b/src/graphics/PreviewLoader.cpp @@ -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"; }