Friday, February 05, 2010

Slide Title Extractor Part 3 of 3

I hope this post is better than the last one. I assumed in the last post that you knew common lisp and could follow along. The lines were also long, so some stuff might have been clipped.

Instead of posting the code, as it flows, I am going to try and post it in a way that makes it easier to understand, so I am going to show missing code as "[...]"

I wanted to make it a stand alone executable, so I used ECL, a common lisp that makes it relatively easy to do so. Stand alone is sort of a misnomer, as you always need libraries. If you have them though, it is a very small executable.

Here is the boiler plate stuff, which is actually at the end of the source code, to take the names of the input and output file from the command line and form a stream that we can pass to extract-frame-titles. I have some code that attempts to see if you are testing the code or actually running it from the executable. Next, I use the input file name (*infile-name*) and the output filename (*outfile-name*) to open some streams that I will be pulling chars from or pushing a string into (write-string).

The outline of extract-slide-titles is as follows. I make a scope using the let to hold the output string (out-paragraph). Then I define two helper functions, get-next-chars which gets the next n characters from a stream, and add-char-to-out which appends a character to the variable out-paragraph. Next, I define the three functions that step through the characters in a state machine like manner. decide-next-step is used to decide what to do next if you are not currently checking for a frame title (check-for-frame-title), in a comment (throw-away-until-newline), or storing characters (store-char). At the end, I start the process off by calling decide-next-step.

Ok, so now I need to actually define those functions. I will start with the helper functions.

get-next-chars is really simple. I concatenate the next n characters into a string and return that. The loop returns a list of characters.

add-char-to-out is also very simple. I just append a character to the end of the string.

Now that that is all out of the way, I can define the fun stuff.

decide-next-step is the main loop. I have four things that can happen.
1) I am at the end, where I just add a newline to out-paragraph
2) I am in a comment, therefore I throw-away-until-newline
3) I am at the beginning of a command, so I check if it is a frame title
4) I just need to keep going (decide-next-step)

check-for-frame-title. I check the first two characters to see if they are "f" or "r". I use the and to then check if it is the frame title command. I split that up into two parts, because if the command is "\frame" then I might eat up some characters that I don't want to throw away. If its a "\frametitle" then I store-char, otherwise, I go back to decide-next-step.

store-char just puts the characters into the string until it gets to the end. It does not handle nested commands, but that is where you would add it.

does exactly what you would expect.

Thank you to tail call optimization, for without it, I would have clobbered the stack many moons ago.

No comments: