All Downloads are FREE. Search and download functionalities are using the official Maven repository.

texry-maven-plugin-0.2.src.main.java.com.texry.maven.Compiler Maven / Gradle / Ivy

/**
 * Copyright (c) 2009-2012, TeXry.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met: 1) Redistributions of source code must retain the above
 * copyright notice, this list of conditions and the following
 * disclaimer. 2) Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution. 3) Neither the name of the TeXry.com nor
 * the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.texry.maven;

import com.ymock.util.Logger;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

/**
 * Compiler.
 *
 * 

This class is immutable and thread-safe. * * @author Yegor Bugayenko ([email protected]) * @version $Id: Compiler.java 100 2012-03-26 04:36:37Z [email protected] $ */ @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") final class Compiler { /** * Temp dir to use. */ private final transient File temp; /** * Public ctor. * @param dir Temporary directory to use * @throws IOException If some error inside */ public Compiler(final File dir) throws IOException { this.temp = dir; if (!this.temp.exists()) { this.temp.mkdir(); } } /** * Compile source and produce output. * @param src The source to compile * @return The output * @throws IOException If some error */ public Output compile(final Source src) throws IOException { final File dir = new File(this.temp, src.name()); if (dir.exists()) { Logger.info(this, "Source '%s' doesn't require re-compiling", src); } else { dir.mkdir(); this.copy(src, dir); this.process(src, dir); } return new Output(new File(dir, String.format("%s.png", src.name()))); } /** * Copy files from source to temp directory. * @param src The source to compile * @param dir The directory to copy to * @throws IOException If some error */ @SuppressWarnings("PMD.UseConcurrentHashMap") private void copy(final Source src, final File dir) throws IOException { final Map files = src.files(); for (String path : files.keySet()) { final File file = new File(dir, path); file.getParentFile().mkdirs(); FileUtils.copyURLToFile(files.get(path), file); } Logger.debug( this, "#copy('%s', '%s'): copied %d files: %[list]s", src, dir, files.size(), files.keySet() ); } /** * Process files in the directory. * @param src The source to use * @param dir The directory to process * @throws IOException If some error */ private void process(final Source src, final File dir) throws IOException { final String cmd = String.format( // @checkstyle LineLength (12 lines) // @checkstyle StringLiteralsConcatenation (11 lines) "'%s' -halt-on-error -interaction=nonstopmode '%s.tex'" + " && '%s' -o %2$s.ps %2$s.dvi &&" + " echo quit" + "| '%s' -q -dNOPAUSE -sDEVICE=ppmraw -sOutputFile=- -r300 %2$s.ps" + "| '%s' -bgcolor rgb:ff/ff/ff -falias -fgcolor rgb:00/00/00 -weight 0.6" + "| '%s' -white" + "| '%s' 0.5" + "| '%s' -interlace > '%2$s.png'", this.bin("latex"), src.name(), this.bin("dvips"), this.bin("gs"), this.bin("pnmalias"), this.bin("pnmcrop"), this.bin("pnmscale"), this.bin("pnmtopng") ); final ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", cmd); builder.directory(dir); Logger.debug( this, "#process('%s', '%s'): running: '%s'", src, dir, cmd ); final Process process = builder.start(); FileUtils.write( new File(dir, "_output.log"), IOUtils.toString(process.getInputStream()) ); int status; try { status = process.waitFor(); } catch (java.lang.InterruptedException ex) { Thread.currentThread().interrupt(); throw new IOException(ex); } if (status != 0) { final File error = new File(dir, "_error.log"); FileUtils.write( error, IOUtils.toString(process.getErrorStream()) ); Logger.error( this, "Compilation failed with code #%d:\n%s", status, FileUtils.readFileToString(error) ); throw new IOException( String.format( "Failed in '%s', see %s/_error.log for more details", src, dir ) ); } } /** * Find binary and return its full name. * @param name Short name * @return Full name * @throws IOException If some error */ private File bin(final String name) throws IOException { final String[] paths = new String[] { "/bin", "/usr/bin", "/usr/local/bin", "/opt/local/bin", "/sbin", "/usr/sbin", "/usr/local/sbin", "/opt/local/sbin", }; File file = null; for (String path : paths) { final File bin = new File(path, name); if (bin.exists() && bin.isFile()) { file = bin; break; } } if (file == null) { throw new IOException( String.format( "Failed to find executable of '%s'", name ) ); } return file; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy