Hacking an ancient braille printer – Part 2, translation and formatting

In this previous post I explained how I was able to send data to an ancient 1980s-era heavy-metal braille embosser. After experimenting with several different forms to text, I quickly discovered that any kind of page meta data (margins, etc.) would cause it to wig out. Also, just plain carriage returns (regardless of convention) would cause it to skip an entire line, wasting a lot of space.

I needed to come up with a way to remove line breaks and page breaks from documents and convert them to padded fixed-width 42-character lines, with a form feed every 25 lines for the tractor feed. I experimented with this by hand it the results seemed successful, so I threw together a simple text file formatting console application. This isn’t the most beautiful or optimized piece of code, but it worked after the first draft and build so I’m happy with it. I’ve included it at the bottom of this post.

So usage goes like this:

embosser1

Write or paste the text of the document you want to emboss into OpenOffice Writer. Then use the very nice odt2braille plugin to convert it to contracted grade 2 braille in ASCII (.brl) format.

embosser2

The file you get would work fine with a modern printer/embosser, but now we need to beat it into the proper shape for our iron-age equipment.

embosser0

After which we get something like this:

embosser3

Now we can use rawprint to send the data straight to the parallel port with no meta data. The final bug I had to overcome was occasionally random line breaks and page feeds. I discovered that simply power-cycling the embosser between each job caused this problem to go away. Some sort of buffer isn’t getting cleared otherwise. All in all the whole process only takes about one minute from start to finish. Then the embosser itself takes about a minute to loudly spit out a page. I was pretty happy with the results, as was my wife. This will get a lot of use in the future, without having to drop several thousand for a modern machine.

embosser5

static void Main(string[] args)
{
    if(args.Length < 3 || args.Length > 3)
    {
        Console.WriteLine("Usage: EbosserFormat input.txt output.txt singlespace|doublespace");
        return;
    }

    string inputFile = args[0];
    string outputFile = args[1];
    string flag = args[2];

    bool doubleSpace = false;
    if (flag == "doublespace")
        doubleSpace = true;
    
    string contents = File.ReadAllText(inputFile);

    List<string> lines = new List<string>(contents.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None));
    List<string> outputLines = new List<string>();

    int lineCount = 1;
    int pageCount = 1;
    foreach (var line in lines)
    {
        string line2 = line.Trim().Replace("\f", "");
        if(line2.Length > 42)
            Console.WriteLine("Warning: Line " + lineCount.ToString() + " was more than 42 characters long. It will be broken in the output.");

        outputLines.Add(line2.PadRight(42));

        if (doubleSpace)
        {
            outputLines.Add("".PadRight(42));
            lineCount++;
        }

        // If we just added line 25 of a page, then we need a page break to advance the printer feed forward to the next page
        if (lineCount % 25 == 0)
        {
            outputLines.Add("\f");
            pageCount++;
        }

        lineCount++;
    }

    string outputContents = "";
    foreach(var line in outputLines)
    {
        outputContents += line;
    }

    File.WriteAllText(outputFile, outputContents);

    Console.WriteLine("File " + outputFile + " written.");
    Console.WriteLine(lineCount.ToString() + " lines on " + pageCount.ToString() + " pages.");
}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>