Convert PostScript to PDF from D lang calling GhostScript ps2pdf.

I’m learning D. This provides working examples of getopts, concurrency, and a process call.

import std.getopt;
import std.stdio; 
import std.file;
import std.path;
import std.datetime;
import std.algorithm;
import std.array;
import std.conv;
import std.string;
import std.process;
import std.concurrency;

string[] listdir(string path)
{
    return dirEntries(path, "*.ps", SpanMode.shallow)
        .filter!(f => f.isFile)
        .map!(f => buildPath(path, f.name))
        .array;
}

void rip(string path, bool v=false) 
{
	//ps2pdf filename.ps filename.pdf
	string outpath = path.replace(".ps", ".pdf");
	if (v == true) {
		writefln("OUT: %s", outpath);
	}
	auto logFile = File("errors.log", "w");
	auto pid = spawnProcess(["/usr/bin/ps2pdf", path, outpath],
                        std.stdio.stdin,
                        std.stdio.stdout,
                        logFile);
	wait(pid);
}

void main(string[] arguments)
{

	// Get opts
	auto base_path = "/home/username/Documents/postscript";
    bool render = false;
    bool count = false;
    bool verbose = false;
    
	getopt(
		arguments,
		"p|path", &base_path,
		"r|render", &render,
		"c|count", &count,
		"v|verbose", &verbose
	); 
	
	// $./psmerge -p /home/username/Documents/postscript -r -c -v
	StopWatch sw;
	sw.start();
	
	int totalDocs = 0;
	int totalPages = 0;
	if (base_path.exists) {
		
		string[] psfiles = listdir(base_path);
		foreach(ps; psfiles){
			
			if (render == true) {

				auto tid = spawn(&rip, ps, verbose);
				
				if (verbose == true){
					writeln(tid, " \nIN: ", ps);
				}
			}
			
			totalDocs++;
			
			// Count pages.
			if (count == true) {
				// Read file.
				File fileHandle = File(ps, "r");
			   
				while (!fileHandle.eof()) 
				{
					string line = fileHandle.readln();
					if ( canFind(line, "(atend)") ) {
						continue;
					}
					if ( canFind(line, "%%Pages: ") ) {
						
						string[] s = line.split(":");
						auto pgNum = strip(s[1].replace("\r\n",""));
						
						if (verbose == true){
							writeln("Pages: ", pgNum);
						}
						
						auto pgCount = to!long(pgNum);
						totalPages += pgCount;
					}
				}
			}
		}
		writefln("Total Docs: %s", totalDocs);
		writefln("Total Pages: %s", totalPages);
		
		sw.stop();
		writefln("Elapsed: %f seconds", sw.peek().usecs / 1_000_000.0);
	}
}

~ by mohawke on September 9, 2016.