def legacy_conversion_step1(latex_file,
                            dpi,
                            output_format,
                            fg_color,
                            bg_color,
                            latex,
                            pdf_output=False,
                            skipMetrics=False):

    # Move color information, lyx and tightpage options into the latex file.
    if not legacy_latex_file(latex_file, fg_color, bg_color):
        error(
            """Unable to move the color information, and the lyx and tightpage
            options of preview-latex, into the latex file""")

    # Compile the latex file.
    latex_status, latex_stdout = run_latex(latex, latex_file)
    if latex_status:
        progress("Will try to recover from %s failure" % latex)

    if pdf_output:
        return legacy_conversion_step3(latex_file, dpi, output_format, True,
                                       skipMetrics)
    else:
        return legacy_conversion_step2(latex_file, dpi, output_format,
                                       skipMetrics)
def legacy_conversion_step1(latex_file, dpi, output_format, fg_color, bg_color,
                            latex, pdf_output = False, skipMetrics = False):

    # Move color information, lyx and tightpage options into the latex file.
    if not legacy_latex_file(latex_file, fg_color, bg_color):
        error("""Unable to move the color information, and the lyx and tightpage
            options of preview-latex, into the latex file""")

    # Compile the latex file.
    latex_status, latex_stdout = run_latex(latex, latex_file)

    if pdf_output:
        return legacy_conversion_step3(latex_file, dpi, output_format, True, skipMetrics)
    else:
        return legacy_conversion_step2(latex_file, dpi, output_format, skipMetrics)
Example #3
0
def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics, gs,
                               gs_device, gs_ext, alpha, resolution,
                               output_format):

    # Search for pdflatex executable
    pdflatex = find_exe(["pdflatex"])
    if pdflatex == None:
        warning(
            "Can't find pdflatex. Some pages failed with all the possible routes."
        )
    else:
        # Create a new LaTeX file from the original but only with failed pages
        pdf_latex_file = latex_file_re.sub("_pdflatex.tex", latex_file)
        filter_pages(latex_file, pdf_latex_file, failed_pages)

        # pdflatex call
        pdflatex_status, pdflatex_stdout = run_latex(pdflatex, pdf_latex_file)

        pdf_file = latex_file_re.sub(".pdf", pdf_latex_file)

        # GhostScript call to produce bitmaps
        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("", pdf_latex_file), \
                        gs_ext, alpha, alpha, resolution, pdf_file)
        gs_status, gs_stdout = run_command(gs_call)
        if gs_status:
            # Give up!
            warning("Some pages failed with all the possible routes")
        else:
            # We've done it!
            pdf_log_file = latex_file_re.sub(".log", pdf_latex_file)
            pdf_metrics = legacy_extract_metrics_info(pdf_log_file)

            original_bitmap = latex_file_re.sub("%d." + output_format,
                                                pdf_latex_file)
            destination_bitmap = latex_file_re.sub("%d." + output_format,
                                                   latex_file)

            # Join the metrics with the those from dvips and rename the bitmap images
            join_metrics_and_rename(legacy_metrics, pdf_metrics, failed_pages,
                                    original_bitmap, destination_bitmap)
def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics, gs,
    gs_device, gs_ext, alpha, resolution, output_format):

    # Search for pdflatex executable
    pdflatex = find_exe(["pdflatex"])
    if pdflatex == None:
        warning("Can't find pdflatex. Some pages failed with all the possible routes.")
    else:
        # Create a new LaTeX file from the original but only with failed pages
        pdf_latex_file = latex_file_re.sub("_pdflatex.tex", latex_file)
        filter_pages(latex_file, pdf_latex_file, failed_pages)

        # pdflatex call
        pdflatex_status, pdflatex_stdout = run_latex(pdflatex, pdf_latex_file)

        pdf_file = latex_file_re.sub(".pdf", pdf_latex_file)

        # GhostScript call to produce bitmaps
        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("", pdf_latex_file), \
                        gs_ext, alpha, alpha, resolution, pdf_file)
        gs_status, gs_stdout = run_command(gs_call)
        if gs_status:
            # Give up!
            warning("Some pages failed with all the possible routes")
        else:
            # We've done it!
            pdf_log_file = latex_file_re.sub(".log", pdf_latex_file)
            pdf_metrics = legacy_extract_metrics_info(pdf_log_file)

            original_bitmap = latex_file_re.sub("%d." + output_format, pdf_latex_file)
            destination_bitmap = latex_file_re.sub("%d." + output_format, latex_file)

            # Join the metrics with the those from dvips and rename the bitmap images
            join_metrics_and_rename(legacy_metrics, pdf_metrics, failed_pages,
                original_bitmap, destination_bitmap)
Example #5
0
    if dv2dt == None:
        progress("Using the legacy conversion method (dv2dt not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    pngtopnm = ""
    if output_format == "ppm":
        pngtopnm = find_exe(["pngtopnm"])
        if pngtopnm == None:
            progress("Using the legacy conversion method (pngtopnm not found)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                fg_color, bg_color, latex, pdf_output)

    # Compile the latex file.
    error_pages = []
    latex_status, latex_stdout = run_latex(latex, latex_file, bibtex)
    if latex_status:
        warning("trying to recover from failed compilation")
        error_pages = check_latex_log(latex_file_re.sub(".log", latex_file))

    # The dvi output file name
    dvi_file = latex_file_re.sub(".dvi", latex_file)

    # If there's no DVI output, look for PDF and go to legacy or fail
    if not os.path.isfile(dvi_file):
        # No DVI, is there a PDF?
        pdf_file = latex_file_re.sub(".pdf", latex_file)
        if os.path.isfile(pdf_file):
            progress("%s produced a PDF output, fallback to legacy." \
                % (os.path.basename(latex)))
            progress("Using the legacy conversion method (PDF support)")
Example #6
0
def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics,
    use_pdftocairo, conv, gs_device, gs_ext, alpha, resolution, output_format):

    # Search for pdflatex executable
    pdflatex = find_exe(["pdflatex"])
    if pdflatex == None:
        warning("Can't find pdflatex. Some pages failed with all the possible routes.")
    else:
        # Create a new LaTeX file from the original but only with failed pages
        pdf_latex_file = latex_file_re.sub("_pdflatex.tex", latex_file)
        filter_pages(latex_file, pdf_latex_file, failed_pages)

        # pdflatex call
        error_pages = []
        pdflatex_status, pdflatex_stdout = run_latex(pdflatex, pdf_latex_file)
        if pdflatex_status:
            error_pages = check_latex_log(latex_file_re.sub(".log", pdf_latex_file))

        pdf_file = latex_file_re.sub(".pdf", pdf_latex_file)
        latex_file_root = latex_file_re.sub("", pdf_latex_file)

        # Converter call to produce bitmaps
        if use_pdftocairo:
            conv_call = '%s -png -transp -r %d "%s" "%s"' \
                        % (conv, resolution, pdf_file, latex_file_root)
            conv_status, conv_stdout = run_command(conv_call)
            if not conv_status:
                seqnum_re = re.compile("-([0-9]+)")
                for name in glob.glob("%s-*.png" % latex_file_root):
                    match = seqnum_re.search(name)
                    if match != None:
                        new_name = seqnum_re.sub(str(int(match.group(1))), name)
                        os.rename(name, new_name)
        else:
            conv_call = '%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s ' \
                        '-sOutputFile="%s%%d.%s" ' \
                        '-dGraphicsAlphaBit=%d -dTextAlphaBits=%d ' \
                        '-r%f "%s"' \
                        % (conv, gs_device, latex_file_root, \
                            gs_ext, alpha, alpha, resolution, pdf_file)
            conv_status, conv_stdout = run_command(conv_call)

        if conv_status:
            # Give up!
            warning("Some pages failed with all the possible routes")
        else:
            # We've done it!
            pdf_log_file = latex_file_re.sub(".log", pdf_latex_file)
            pdf_metrics = legacy_extract_metrics_info(pdf_log_file)

            # Invalidate metrics for pages that produced errors
            if len(error_pages) > 0:
                for index in error_pages:
                    pdf_metrics.pop(index - 1)
                    pdf_metrics.insert(index - 1, (index, -1.0))

            original_bitmap = latex_file_re.sub("%d." + output_format, pdf_latex_file)
            destination_bitmap = latex_file_re.sub("%d." + output_format, latex_file)

            # Join the metrics with the those from dvips and rename the bitmap images
            join_metrics_and_rename(legacy_metrics, pdf_metrics, failed_pages,
                original_bitmap, destination_bitmap)
Example #7
0
def main(argv):
    # Set defaults.
    dpi = 128
    fg_color = "000000"
    bg_color = "ffffff"
    bibtex = None
    latex = None
    lilypond = False
    lilypond_book = None
    output_format = "png"
    script_name = argv[0]

    # Parse and manipulate the command line arguments.
    try:
        (opts, args) = getopt.gnu_getopt(argv[1:], "dhv", ["bibtex=", "bg=",
            "debug", "dpi=", "fg=", "help", "latex=", "lilypond",
            "lilypond-book=", "png", "ppm", "verbose"])
    except getopt.GetoptError as err:
        error("%s\n%s" % (err, usage(script_name)))

    opts.reverse()
    for opt, val in opts:
        if opt in ("-h", "--help"):
            print(usage(script_name))
            sys.exit(0)
        elif opt == "--bibtex":
            bibtex = [val]
        elif opt == "--bg":
            bg_color = val
        elif opt in ("-d", "--debug"):
            import lyxpreview_tools
            lyxpreview_tools.debug = True
        elif opt == "--dpi":
            try:
                dpi = int(val)
            except:
                error("Cannot convert %s to an integer value" % val)
        elif opt == "--fg":
            fg_color = val
        elif opt == "--latex":
            latex = [val]
        elif opt == "--lilypond":
            lilypond = True
        elif opt == "--lilypond-book":
            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:
        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)

    # 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)

    if lyxpreview_tools.verbose:
        f_out = open('debug.txt', 'a')
        sys.stdout = f_out
        sys.stderr = f_out

    # Echo the settings
    progress("Running Python %s" % str(sys.version_info[:3]))
    progress("Starting %s..." % script_name)
    if os.name == "nt":
        progress("Use win32_modules: %d" % lyxpreview_tools.use_win32_modules)
    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)

    # For python > 2 convert strings to bytes
    if not PY2:
        fg_color = bytes(fg_color, 'ascii')
        bg_color = bytes(bg_color, 'ascii')

    fg_color_dvipng = make_texcolor(fg_color, False)
    bg_color_dvipng = make_texcolor(bg_color, False)

    # For python > 2 convert bytes to string
    if not PY2:
        fg_color_dvipng = fg_color_dvipng.decode('ascii')
        bg_color_dvipng = bg_color_dvipng.decode('ascii')

    # External programs used by the script.
    latex = find_exe_or_terminate(latex or latex_commands)
    bibtex = find_exe(bibtex or bibtex_commands)
    if lilypond:
        lilypond_book = find_exe_or_terminate(lilypond_book or
            ["lilypond-book --safe"])

    # 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("Bibtex command: %s" % bibtex)
    progress("Lilypond-book command: %s" % lilypond_book)
    progress("Preprocess through lilypond-book: %s" % lilypond)
    progress("Altering the latex file for font size and colors")

    # Make sure that multiple defined macros and the microtype package
    # don't cause issues in the latex file.
    fix_latex_file(latex_file, pdf_output)

    if lilypond:
        progress("Preprocess the latex file through %s" % lilypond_book)
        if pdf_output:
            lilypond_book += " --pdf"
        lilypond_book += " --latex-program=%s" % latex.split()[0]

        # Make a copy of the latex file
        lytex_file = latex_file_re.sub(".lytex", latex_file)
        shutil.copyfile(latex_file, lytex_file)

        # Preprocess the latex file through lilypond-book.
        lytex_status, lytex_stdout = run_tex(lilypond_book, lytex_file)

    if pdf_output:
        progress("Using the legacy conversion method (PDF support)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    # This can go once dvipng becomes widespread.
    dvipng = find_exe(["dvipng"])
    if dvipng == None:
        progress("Using the legacy conversion method (dvipng not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    dv2dt = find_exe(["dv2dt"])
    if dv2dt == None:
        progress("Using the legacy conversion method (dv2dt not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    pngtopnm = ""
    if output_format == "ppm":
        pngtopnm = find_exe(["pngtopnm"])
        if pngtopnm == None:
            progress("Using the legacy conversion method (pngtopnm not found)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                fg_color, bg_color, latex, pdf_output)

    # Compile the latex file.
    error_pages = []
    latex_status, latex_stdout = run_latex(latex, latex_file, bibtex)
    latex_log = latex_file_re.sub(".log", latex_file)
    if latex_status:
        progress("Will try to recover from %s failure" % latex)
        error_pages = check_latex_log(latex_log)

    # The dvi output file name
    dvi_file = latex_file_re.sub(".dvi", latex_file)

    # If there's no DVI output, look for PDF and go to legacy or fail
    if not os.path.isfile(dvi_file):
        # No DVI, is there a PDF?
        pdf_file = latex_file_re.sub(".pdf", latex_file)
        if os.path.isfile(pdf_file):
            progress("%s produced a PDF output, fallback to legacy." \
                % (os.path.basename(latex)))
            progress("Using the legacy conversion method (PDF support)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                fg_color, bg_color, latex, True)
        else:
            error("No DVI or PDF output. %s failed." \
                % (os.path.basename(latex)))

    # 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, pdf_pages, page_count, pages_parameter) = find_ps_pages(dvi_file)

    # 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)

    # Retrieve resolution
    resolution = extract_resolution(latex_log, dpi)

    # Run the dvi file through dvipng.
    dvipng_call = '%s -Ttight -depth -height -D %d -fg "%s" -bg "%s" %s "%s"' \
        % (dvipng, resolution, fg_color_dvipng, bg_color_dvipng, pages_parameter, dvi_file)
    dvipng_status, dvipng_stdout = run_command(dvipng_call)

    if dvipng_status:
        warning("%s failed to generate images from %s... fallback to legacy method" \
              % (os.path.basename(dvipng), dvi_file))
        progress("Using the legacy conversion method (dvipng failed)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    # Extract metrics info from dvipng_stdout.
    metrics_file = latex_file_re.sub(".metrics", latex_file)
    dvipng_metrics = extract_metrics_info(dvipng_stdout)

    # If some pages require PostScript pass them to legacy method
    if len(ps_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, ps_pages)

        # Pass the new LaTeX file to the legacy method
        progress("Pages %s include postscript specials" % ps_pages)
        progress("Using the legacy conversion method (PostScript support)")
        legacy_status, legacy_metrics = legacy_conversion_step1(legacy_latex_file,
            dpi, output_format, fg_color, bg_color, latex, pdf_output, 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, 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 require processing with pdflatex" % 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)

    # Invalidate metrics for pages that produced errors
    if len(error_pages) > 0:
        error_count = 0
        for index in error_pages:
            if index not in ps_pages and index not in pdf_pages:
                dvipng_metrics.pop(index - 1)
                dvipng_metrics.insert(index - 1, (index, -1.0))
                error_count += 1
        if error_count:
            warning("Failed to produce %d preview snippet(s)" % error_count)

    # Convert images to ppm format if necessary.
    if output_format == "ppm":
        convert_to_ppm_format(pngtopnm, latex_file_re.sub("", latex_file))

    # Actually create the .metrics file
    write_metrics_info(dvipng_metrics, metrics_file)

    return (0, dvipng_metrics)
Example #8
0
    dv2dt = find_exe(["dv2dt"])
    if dv2dt == None:
        progress("Using the legacy conversion method (dv2dt not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format, fg_color,
            bg_color, latex, pdf_output)

    pngtopnm = ""
    if output_format == "ppm":
        pngtopnm = find_exe(["pngtopnm"])
        if pngtopnm == None:
            progress("Using the legacy conversion method (pngtopnm not found)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                fg_color, bg_color, latex, pdf_output)

    # Compile the latex file.
    latex_status, latex_stdout = run_latex(latex, latex_file, bibtex)
    if latex_status:
      return (latex_status, [])

    # The dvi output file name
    dvi_file = latex_file_re.sub(".dvi", latex_file)

    # If there's no DVI output, look for PDF and go to legacy or fail
    if not os.path.isfile(dvi_file):
        # No DVI, is there a PDF?
        pdf_file = latex_file_re.sub(".pdf", latex_file)
        if os.path.isfile(pdf_file):
            progress("%s produced a PDF output, fallback to legacy." \
                % (os.path.basename(latex)))
            progress("Using the legacy conversion method (PDF support)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
Example #9
0
def main(argv):
    # Set defaults.
    dpi = 128
    fg_color = "000000"
    bg_color = "ffffff"
    bibtex = None
    latex = None
    lilypond = False
    lilypond_book = None
    output_format = "png"
    script_name = argv[0]

    # Parse and manipulate the command line arguments.
    try:
        (opts, args) = getopt.gnu_getopt(argv[1:], "dhv", [
            "bibtex=", "bg=", "debug", "dpi=", "fg=", "help", "latex=",
            "lilypond", "lilypond-book=", "png", "ppm", "verbose"
        ])
    except getopt.GetoptError as err:
        error("%s\n%s" % (err, usage(script_name)))

    opts.reverse()
    for opt, val in opts:
        if opt in ("-h", "--help"):
            print(usage(script_name))
            sys.exit(0)
        elif opt == "--bibtex":
            bibtex = [val]
        elif opt == "--bg":
            bg_color = val
        elif opt in ("-d", "--debug"):
            lyxpreview_tools.debug = True
        elif opt == "--dpi":
            try:
                dpi = int(val)
            except:
                error("Cannot convert %s to an integer value" % val)
        elif opt == "--fg":
            fg_color = val
        elif opt == "--latex":
            latex = [val]
        elif opt == "--lilypond":
            lilypond = True
        elif opt == "--lilypond-book":
            lilypond_book = [val]
        elif opt in ("--png", "--ppm"):
            output_format = opt[2:]
        elif opt in ("-v", "--verbose"):
            lyxpreview_tools.verbose = True

    # Determine input file
    if len(args) != 1:
        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)

    # 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)

    if lyxpreview_tools.verbose:
        f_out = open('verbose.txt', 'a')
        sys.stdout = f_out
        sys.stderr = f_out

    # Echo the settings
    progress("Running Python %s" % str(sys.version_info[:3]))
    progress("Starting %s..." % script_name)
    if os.name == "nt":
        progress("Use win32_modules: %d" % lyxpreview_tools.use_win32_modules)
    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)

    # For python > 2 convert strings to bytes
    if not PY2:
        fg_color = bytes(fg_color, 'ascii')
        bg_color = bytes(bg_color, 'ascii')

    fg_color_dvipng = make_texcolor(fg_color, False)
    bg_color_dvipng = make_texcolor(bg_color, False)

    # For python > 2 convert bytes to string
    if not PY2:
        fg_color_dvipng = fg_color_dvipng.decode('ascii')
        bg_color_dvipng = bg_color_dvipng.decode('ascii')

    # External programs used by the script.
    latex = find_exe_or_terminate(latex or latex_commands)
    bibtex = find_exe(bibtex or bibtex_commands)
    if lilypond:
        lilypond_book = find_exe_or_terminate(lilypond_book
                                              or ["lilypond-book --safe"])

    # 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("Bibtex command: %s" % bibtex)
    progress("Lilypond-book command: %s" % lilypond_book)
    progress("Preprocess through lilypond-book: %s" % lilypond)
    progress("Altering the latex file for font size and colors")

    # Make sure that multiple defined macros and the microtype package
    # don't cause issues in the latex file.
    fix_latex_file(latex_file, pdf_output)

    if lilypond:
        progress("Preprocess the latex file through %s" % lilypond_book)
        if pdf_output:
            lilypond_book += " --pdf"
        lilypond_book += " --latex-program=%s" % latex.split()[0]

        # Make a copy of the latex file
        lytex_file = latex_file_re.sub(".lytex", latex_file)
        shutil.copyfile(latex_file, lytex_file)

        # Preprocess the latex file through lilypond-book.
        lytex_status, lytex_stdout = run_tex(lilypond_book, lytex_file)

    if pdf_output:
        progress("Using the legacy conversion method (PDF support)")
        return legacy_conversion_step1(latex_file, dpi, output_format,
                                       fg_color, bg_color, latex, pdf_output)

    # This can go once dvipng becomes widespread.
    dvipng = find_exe(["dvipng"])
    if dvipng == None:
        progress("Using the legacy conversion method (dvipng not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format,
                                       fg_color, bg_color, latex, pdf_output)

    dv2dt = find_exe(["dv2dt"])
    if dv2dt == None:
        progress("Using the legacy conversion method (dv2dt not found)")
        return legacy_conversion_step1(latex_file, dpi, output_format,
                                       fg_color, bg_color, latex, pdf_output)

    pngtopnm = ""
    if output_format == "ppm":
        pngtopnm = find_exe(["pngtopnm"])
        if pngtopnm == None:
            progress("Using the legacy conversion method (pngtopnm not found)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                                           fg_color, bg_color, latex,
                                           pdf_output)

    # Compile the latex file.
    error_pages = []
    latex_status, latex_stdout = run_latex(latex, latex_file, bibtex)
    latex_log = latex_file_re.sub(".log", latex_file)
    if latex_status:
        progress("Will try to recover from %s failure" % latex)
        error_pages = check_latex_log(latex_log)

    # The dvi output file name
    dvi_file = latex_file_re.sub(".dvi", latex_file)

    # If there's no DVI output, look for PDF and go to legacy or fail
    if not os.path.isfile(dvi_file):
        # No DVI, is there a PDF?
        pdf_file = latex_file_re.sub(".pdf", latex_file)
        if os.path.isfile(pdf_file):
            progress("%s produced a PDF output, fallback to legacy." \
                % (os.path.basename(latex)))
            progress("Using the legacy conversion method (PDF support)")
            return legacy_conversion_step1(latex_file, dpi, output_format,
                                           fg_color, bg_color, latex, True)
        else:
            error("No DVI or PDF output. %s failed." \
                % (os.path.basename(latex)))

    # 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, pdf_pages, page_count,
     pages_parameter) = find_ps_pages(dvi_file)

    # 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)

    # Retrieve resolution
    resolution = extract_resolution(latex_log, dpi)

    # Run the dvi file through dvipng.
    dvipng_call = '%s -Ttight -depth -height -D %d -fg "%s" -bg "%s" %s "%s"' \
        % (dvipng, resolution, fg_color_dvipng, bg_color_dvipng, pages_parameter, dvi_file)
    dvipng_status, dvipng_stdout = run_command(dvipng_call)

    if dvipng_status:
        warning("%s failed to generate images from %s... fallback to legacy method" \
              % (os.path.basename(dvipng), dvi_file))
        progress("Using the legacy conversion method (dvipng failed)")
        return legacy_conversion_step1(latex_file, dpi, output_format,
                                       fg_color, bg_color, latex, pdf_output)

    # Extract metrics info from dvipng_stdout.
    metrics_file = latex_file_re.sub(".metrics", latex_file)
    dvipng_metrics = extract_metrics_info(dvipng_stdout)

    # If some pages require PostScript pass them to legacy method
    if len(ps_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, ps_pages)

        # Pass the new LaTeX file to the legacy method
        progress("Pages %s include postscript specials" % ps_pages)
        progress("Using the legacy conversion method (PostScript support)")
        legacy_status, legacy_metrics = legacy_conversion_step1(
            legacy_latex_file, dpi, output_format, fg_color, bg_color, latex,
            pdf_output, 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, 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 require processing with pdflatex" % 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)

    # Invalidate metrics for pages that produced errors
    if len(error_pages) > 0:
        error_count = 0
        for index in error_pages:
            if index not in ps_pages and index not in pdf_pages:
                dvipng_metrics.pop(index - 1)
                dvipng_metrics.insert(index - 1, (index, -1.0))
                error_count += 1
        if error_count:
            warning("Failed to produce %d preview snippet(s)" % error_count)

    # Convert images to ppm format if necessary.
    if output_format == "ppm":
        convert_to_ppm_format(pngtopnm, latex_file_re.sub("", latex_file))

    # Actually create the .metrics file
    write_metrics_info(dvipng_metrics, metrics_file)

    return (0, dvipng_metrics)
def legacy_conversion_pdflatex(latex_file, failed_pages, legacy_metrics,
                               use_pdftocairo, conv, gs_device, gs_ext, alpha,
                               resolution, output_format):

    error_count = 0

    # Search for pdflatex executable
    pdflatex = find_exe(["pdflatex"])
    if pdflatex == None:
        warning(
            "Can't find pdflatex. Some pages failed with all the possible routes."
        )
        failed_pages = []
    else:
        # Create a new LaTeX file from the original but only with failed pages
        pdf_latex_file = latex_file_re.sub("_pdflatex.tex", latex_file)
        filter_pages(latex_file, pdf_latex_file, failed_pages)

        # pdflatex call
        error_pages = []
        pdflatex_status, pdflatex_stdout = run_latex(pdflatex, pdf_latex_file)
        if pdflatex_status:
            error_pages = check_latex_log(
                latex_file_re.sub(".log", pdf_latex_file))

        pdf_file = latex_file_re.sub(".pdf", pdf_latex_file)
        latex_file_root = latex_file_re.sub("", pdf_latex_file)

        # Converter call to produce bitmaps
        if use_pdftocairo:
            conv_call = '%s -png -transp -r %d "%s" "%s"' \
                        % (conv, resolution, pdf_file, latex_file_root)
            conv_status, conv_stdout = run_command(conv_call)
            if not conv_status:
                seqnum_re = re.compile("-([0-9]+)")
                for name in glob.glob("%s-*.png" % latex_file_root):
                    match = seqnum_re.search(name)
                    if match != None:
                        new_name = seqnum_re.sub(str(int(match.group(1))),
                                                 name)
                        os.rename(name, new_name)
        else:
            conv_call = '%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s ' \
                        '-sOutputFile="%s%%d.%s" ' \
                        '-dGraphicsAlphaBit=%d -dTextAlphaBits=%d ' \
                        '-r%f "%s"' \
                        % (conv, gs_device, latex_file_root, \
                            gs_ext, alpha, alpha, resolution, pdf_file)
            conv_status, conv_stdout = run_command(conv_call)

        if conv_status:
            # Give up!
            warning("Some pages failed with all the possible routes")
            failed_pages = []
        else:
            # We've done it!
            pdf_log_file = latex_file_re.sub(".log", pdf_latex_file)
            pdf_metrics = legacy_extract_metrics_info(pdf_log_file)

            # Invalidate metrics for pages that produced errors
            if len(error_pages) > 0:
                for index in error_pages:
                    pdf_metrics.pop(index - 1)
                    pdf_metrics.insert(index - 1, (index, -1.0))
                    error_count += 1

            original_bitmap = latex_file_re.sub("%d." + output_format,
                                                pdf_latex_file)
            destination_bitmap = latex_file_re.sub("%d." + output_format,
                                                   latex_file)

            # Join the metrics with the those from dvips and rename the bitmap images
            join_metrics_and_rename(legacy_metrics, pdf_metrics, failed_pages,
                                    original_bitmap, destination_bitmap)

    return error_count