Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
This is the `README' file of BlogMe.
Copyright 2005 Eduardo Ochs <[email protected]>
Author:        Eduardo Ochs <[email protected]>
Version:       2005feb26
License: GPL (I'll add the complete headers later)
Latest: http://angg.twu.net/blogme/README

VERY IMPORTANT (added in 2005aug25): this README describes -- VERY
imprecisely -- blogme.lua, but I have just finished rewriting
blogme.lua, and I now declare that the original blogme.lua is UGLY &
OBSOLETE. Blogme2 consists of the files whose names start with
"blogme2" at <http://angg.twu.net/blogme/>, plus the doc file
<http://angg.twu.net/blogme/INTERNALS>, and edrxlib.lua.



The "language" that blogme.lua accepts is extensible and can deal with
input having a lot of explicit mark-up, like this,

    [HLIST2 Items:
      [HREF http://foo/bar a link]
      [HREF http://another/link]
      [IT Italic text]
      [BF Boldface]
    ]

and conceivably also with input with a lot of _implicit_ mark-up and
with control structures, like these examples (which haven't been
implemented yet):

    [BLOGME
      Tuesday, February 15, 2005

      I usually write my notes in plain text files using Emacs; in
      these files "["s and "]"s can appear unquoted, urls appear
      anywhere without any special markup (like http://angg.twu.net/)
      and should be recognized and htmlized to links, some lines are
      dates or "anchors" and should be treated in special ways, the
      number of blank lines between paragraphs matter, in text
      paragraphs maybe _this markup_ should mean bold or italic, and
      there may be links to images that should be inlined, etc etc
      etc.
    ]

    [IF somecondition [(then this)]
                      [(else this)]
    ]

We also support executing blocks of Lua code on-the-fly, like this:

    [lua:
       -- we can put any block of Lua code here
       -- as long as its "["s and "]"s are balanced
    ]

The trick is simple. In this language there is only one special
syntactical construct, "[...]". We only have four classes of
characters "[", "]", whitespace, and "word"; "[...]" blocks in the
text are treated specially, and we use Lua's "%b[]" regexp-ish
construct to skip over the body of a "[...]" quickly, skipping over
all balanced "[]" pairs inside. The first "word" of such a block (we
call it the "head" of the block) determines how to deal with the
"rest" of the block.

To "evaluate" an expression like

    [HREF http://foo/bar a link]

we only parse its "head" - "HREF" - and then we run the Lua function
called HREF. It is up to that function HREF to parse what comes after
the head (the "rest"); HREF may evaluate the []-expressions in the
rest, or use the rest without evaluations, or even ignore the rest
completely. After the execution of HREF the parsing resumes from the
point after the associated "]".

Actually the evaluation process is a bit more sophisticated than that.
Instead of executing just HREF() we use an auxiliary table, _GETARGS,
and we execute:

    HREF(_GETARGS["HREF"]())

_GETARGS["HREF"] returns a function, vargs2, that uses the rest to
produce arguments for HREF. Running vargs2() in that situation returns

    "http://foo/bar", "a link"

and HREF is called as HREF("http://foo/bar", "a link"). So, to define
HREF as a head all we would need to do ("would" because it's already
defined) is:

    HREF = function (url, text)
        return "<a href=\""..url.."\">"..text.."</a>"
      end
    _GETARGS["HREF"] = vargs2

Defining new heads is so common - and writing out the full Lua code
for a new head, as above, is so boring - that there are several tools
to help us with that. I will explain only one of them, "def":

    def [[ HREF 2 url,text  "<a href=\"$url\">$text</a>" ]]

"def" is a lua function taking one argument, a string; it splits that
string into its three first "words" (delimited by blanks) and a
"rest"; here is its definition:

    restspecs = {
      ["1"]=vargs1,    ["2"]=vargs2,    ["3"]=vargs3,    ["4"]=vargs4,
      ["1L"]=vargs1_a, ["2L"]=vargs2_a, ["3L"]=vargs3_a, ["4L"]=vargs4_a
    }
    def = function (str)
        local _, __, name, restspec, arglist, body =
          string.find (str, "^%s*([^%s]+)%s+([^%s]+)%s+([^%s]+)%s(.*)")
        _G[name] = lambda(arglist, undollar(body))
        _GETARGS[name] = restspecs[restspec] or _G[restspec]
          or error("Bad restspec: "..name)
      end

The first "word" ("name") is the name of the head that we're defining;
the second "word" ("restspec") determines the _GETARGS function for
that head, and it may be either a special string (one of the ones
registered in the table "restspecs") or the name of a global function.

More later.






#*
# Download and unpack:
rm -Rv ~/blogme/
mkdir  ~/blogme/
cd     ~/blogme/
wget http://201.8.6.142/tmp/blogme.tgz
tar -xvzf blogme.tgz

#*
# Test:
cd ~/blogme/
time lua50 blogme.lua -o index.html -i index.blogme

#*
# Pack:
cd ~/blogme/
tar -cvzf /var/www/tmp/blogme.tgz README blogme.lua edrxlib.lua index.blogme

#*