I've always wanted a magic wordprocessor. Something that helps me organize my thoughts and build ideas organically, rather than spend all of my time worrying about formatting. Something for the internet / cloud age. Given that Microsoft Word hasn't fundamentally changed in over a decade (or possibly two), we aren't likely to get such software from them. Instead, I decided to play around with some ideas using my new favorite programming tool: OMeta.

OMeta

OMeta's story starts with compilers. Compilers are built of many phases: lexing, parsing, applying optimizations, then generating machine code. OMeta's creator, Alessandro Warth, realized that these are all essentially the same thing, pattern matching. The only difference is whether you are matching a stream of characters, tokens, or parts of a tree. Alex created a single language that lets you match over objects (ie: anything) to implement all parts of the compiler using a single tool.

OMeta is that single tool: a domain specific programming language for creating pattern matchers. More properly, it is a language extension that can be laid on top of an existing host language. I am using OmetaJS, an extension to JavaScript. The wonderful thing about OMeta is that it's easier to use and extend than dedicated parser generators like Antlr or Yacc because you always have the host language available to do whatever computation you need.

Editor Demo

As my first experiment with OMeta, and new wordprocessors, I created a simple Markdown editor. You type raw text into the left side of the screen and see your properly styled text on the right side. But this editor has a trick up it's sleeve. You can type simple math expressions inside curly braces the editor will evaluate it for you.

Play with the editor here

Here's what the OMeta code looks like:


ometa Foo {
    //white space
    toEOL = (~seq('\n') char)*:t '\n' -> t.join(""),
    
    //headers
    h1 = "#"   ' ' toEOL:t -> tag("h1",t),
    h2 = "##"  ' ' toEOL:t -> tag("h2",t),
    h3 = "###" ' ' toEOL:t -> tag("h3",t),

    
    //paragraph
    paraend   = seq('\n\n'),
    para      = (expr|strong|em| (~paraend char))+:t -> tag("p",t.join("")),
    text   =      (~seq('\n\n') char)*:t      -> t.join(""),
    strong = "**" (~seq('**')   char)*:t "**" -> tag("strong",t.join("")),
    em     = "*"  (~seq('*')    char)*:t "*"  -> tag("em",t.join("")),
    expr    = "{"  exp:t "}"  -> tag("b",t),
    
    //code block
    codeblock = fromTo("```\n", "```\n"):t -> tag("pre",tag("code",esc(t))),
    
    //inline expressions
    num = :n -> parseInt(n),
    term = num,
    expadd = term:a "+" term:b -> (a+b),
    expmul = term:a "*" term:b -> (a*b),
    expsub = term:a "-" term:b -> (a-b),
    expdiv = term:a "/" term:b -> (a/b),
    exp = (expmul|expdiv|expadd|expsub):e -> (" "+e+"") ,
    
    //pull it all together
    line = space* (h3|h2|h1|codeblock|para):t space* -> t,
    top = line*,
    
    END
};

This editor only understands simple two term arithmetic but it could easily be expanded with variables and more complex functions.

Much like a painter or musician, sometimes I an idea forms in my head and will not let me rest until it comes out. Usually such an idea is an algorithm or graphics demo, but this time it came in the form of a game; a game which will not quiet until born.

To that end I present to you: Budu Budu Tiki Mon's Super Christmas Adventure, an NES style RPG playable in your browser.

I've always been a fan of NES/SNES era RPGs, the Final Fantasy series in particular. Though fun to play they are also easily parodied due to common tropes through out the games. Each takes place in a different universe with different characters, but they always have a helper named Cid, a flying vehicle of some sort, ridiculous weapons, twisting plots, and backstabbing villans. As I said, ripe for parody. And what better genre of parody than Christmas Movies

Silly characters, a princess to save, amusing dialog, and great chiptunes (gratefully borrowed from 8bit peoples). This is just a prelude of a full game. SCA contains a small overworld, two villages, and a dungeon. If there is interest I'd love to turn it into a full game.

I want to stress that the prelude is in no way finished. The game engine is rife with bugs, some characters are missing dialog, and the graphics need further tweaks. There simply wasn't enough time to polish it before the holidays. Such is the life of a toddler father. Please tweet me any issues and I'll fix'em ASAP.

Have a Very Merry Christmas!