Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
This is the file `INTERNALS' of blogme.
This file describes the internals of blogme2, that are quite different
from the internals of (the old) blogme; blogme2 is MUCH cleaner.
Author:  Eduardo Ochs <[email protected]>
Version: 2005sep09
License: GPL
Site:    <http://angg.twu.net/>



The main tables used by blogme
==============================
 _G: Lua globals (<http://www.lua.org/manual/5.0/manual.html#predefined>)
 _W: blogme words
 _P: low-level parsers
 _A: argument-parsing functions for blogme words
 _AA: abbreviations for argument-parsing functions (see `def')
 _V: blogme variables (see "$" and `withvars')



Blogme words (the tables _W and _A)
===================================
Let's examine an example. When blogme processes:
    [HREF http://foo bar]
it expands it to:
    <a href="http://foo">bar</a>

When the blogme evaluator processes a bracketed expression it first
obtains the first "word" of the brexp (called the "head" of the
brexp), that in this case is "HREF"; then it parses and evaluates the
"arguments" of the brexp, and invokes the function associated to the
word "HREF" using those arguments. Different words may have different
ways of parsing and evaluating their arguments; this is like the
distinction in Lisp between functions and special forms, and like the
special words like LIT in Forth. Here are the hairy details: if HREF
is defined by

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

then the "value" of [HREF http://foo bar] will be the same as the
value returned by HREF("http://foo", "bar"), because

  _W["HREF"](_A["HREF"]())

will be the same as:

  HREF(vargs2())

when vargs2 is run the parser is just after the end of the word
"HREF" in the brexp, and running vargs2() there parses the rest of
the brexp and returns two strings, "http://foo" and "bar".

See: (info "(elisp)Function Forms")
and: (info "(elisp)Special Forms")



The blogme parsers (the table _P)
=================================
Blogme has a number of low-level parsers, each one identified by a
string (a "blogme pattern"); the (informal) "syntax" of those blogme
patterns was vaguely inspired by Lua5's syntax for patterns.
(See: <http://www.lua.org/manual/5.0/manual.html#pm>).
In the table below "BP" stands for "blogme pattern".

  BP    Long name/meaning      Corresponding Lua pattern
 -----+----------------------+--------------------------
 "%s" | space char           | "[ \t\n]"
 "%w" | word char            | "[^%[%]]"
 "%c" | normal char          | "[^ \t\n%[%]]"
 "%B" | bracketed expression | "%b[]"
 "%W" | bigword              | "(%w*%b[]*)*" (but not the empty string!)

The low-level parsing functions of blogme are of two kinds (levels):
* Functions in the "parse only" level only succeed or fail. When they
  succeed they return true and advance the global variable `pos'; when
  they fail they return nil and leave pos unchanged (*).
* Functions in the "parse and process" level are like the functions in
  the "parse only" level, but with something extra: when they succeed
  they store in the global variable `val' the "semantic value" of the
  thing that they parsed. When they fail they are allowed to garble
  `val', but they won't change `pos'.
See: (info "(bison)Semantic Values")

These low-level parsing functions are stored in the table `_P', with
the index being the "blogme patterns". They use the global variables
`subj', `pos', `b', `e', and `val'.

An example: running _P["%w+"]() tries to parse a (non-empty) series of
word chars starting at pos; running _P["%w+:string"]() does the same,
but in case of success the semantic value is stored into `val' as a
string -- the comment ":string" in the name of the pattern indicates
that this is a "parse and process" function, and tells something about
how the semantic value is built.

(*): Blogme patterns containing a semicolon (";") violate the
convention that says that patterns that fail do not advance pos.
Parsing "A;B" means first parsing "A", not caring if it succeds or
fails, discarding its semantic value (if any), then parsing "B", and
returning the result of parsing "B". If "A" succeds but "B" fails then
"A;B" will fail, but pos will have been advanced to the end of "A".
"A" is usually "%s*".