Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- -*- mode: lua -*-
-- This is the `withdef.lua' file of BlogMe.
-- Copyright 2005 Eduardo Ochs <edrx@mat.puc-rio.br>
-- Author:        Eduardo Ochs <edrx@mat.puc-rio.br>
-- Version:       2005aug25
-- License: GPL (I'll add the complete headers later)
-- Latest: http://angg.twu.net/blogme/withdef.lua
--
-- This is not a standalone file! To use it include this in a blogme
-- script (NOT in a blogme2 script):
--   [lua: require "withdef.lua" ]
-- One of the first things that blogme.lua does is to add the
-- directory where blogme.lua was found to the include path, so if
-- this file is in the same dir as blogme.lua then everything should
-- work.
--
-- Blogme2 comes with these functions by default. Do not "require"
-- this file!

--For debugging (this line is Lua code!):
-- def [[ MYP  1L arr      "!", PP(arr) ]]

-- I'm not sure: Do I need to save the "e" for vrest_q before
-- running vargs4_q?
vrest_q = function () parse("_*"); return substring(pos, e) end
vargs1_q = function () return vrest_q() end
vargs2_q = function () return vword(), vrest_q() end
vargs3_q = function () return vword(), vword(), vrest_q() end
vargs4_q = function () return vword(), vword(), vword(), vrest_q() end
restspecs["1Q"] = vargs1_q
restspecs["2Q"] = vargs2_q
restspecs["3Q"] = vargs3_q
restspecs["4Q"] = vargs4_q


----------[ WITH (and its friends $ and list) ]----------

-- Our "WITH" is similar to Lisp's "let".
-- Example of use:
--   [WITH [list a valueofa b valueofb]
--     a is [$ a], b is [$ b];
--     [WITH [list a othervalueofa b othervalueofb]
--       inside the sub-"WITH": a is [$ a], b is [$ b];]
--     outside again, a is [$ a], b is [$ b].
--   ]
-- The above gets expanded to this (modulo whitespace):
--   a is valueofa, b is valueofb;
--     inside the sub-"WITH": a is othervalueofa, b is othervalueofb;
--   outside again, a is valueofa, b is valueofb.
--
_VARS = {}
def [[ $    1  varname  _VARS[varname] or ""]]
def [[ list 1L arr      arr ]]
withvars = function (plist, code)
    local _PREVVARS = {}
    for i=1,getn(plist),2 do
      local varname, value = plist[i], plist[i+1]
      tinsert(_PREVVARS, {varname, _VARS[varname]})
      _VARS[varname] = value
    end
    local result = code()
    for i=getn(_PREVVARS),1,-1 do
      local varname, value = _PREVVARS[i][1], _PREVVARS[i][2]
      _VARS[varname] = value
    end
    return result
  end
_G["WITH"] = function () return withvars(vword(), vrest) or "" end
setgetargs(nop, "WITH")



----------[ tools needed by DEF ]----------

-- (find-blogme "blogme.lua" "def")
-- (find-blogme "blogme.lua" "vargs2")
-- (find-blogme "blogme.lua" "blogme_test")
-- (find-blogme "blogme.lua" "vparse")

withsubj = function (newsubj, code)
    local oldsubj, oldpos = subj, pos
    subj, pos = newsubj, 0
    local result = code()
    subj, pos = oldsubj, oldpos
    return result
  end
withvars_expand = function (plist, text)
    return withvars(plist, function () return
        withsubj(text, vparse)
      end)
  end
zip = function (arr1, arr2)
    local arr12 = {}
    for i=1,getn(arr1) do
      tinsert(arr12, arr1[i])
      tinsert(arr12, arr2[i])
    end
    return arr12
  end


----------[ DEF itself ]----------

-- This:
--   [DEF HREF   2 url,text   <a href="[$ url]">[$ str]</a>]
-- runs as something like this:
--   HREF = function (url, text)
--       return withvars_expand({"url", url, "text", text},
--         "<a href=\"[$ url]\">[$ str]</a>")
--     end
--   _GETARGS["HREF"] = vargs2
-- Here's how to understand how the definition of "DEF", below,
-- works. First we transform the above into:
--   local wordname = "HREF"
--   local argparser = vargs2
--   local argnamelist = {"url", "text"}
--   local text = "<a href=\"[$ url]\">[$ str]</a>"
--   _G[wordname] = function (...)
--       return withvars_expand(zip(argnamelist, arg), text)
--     end
--   _GETARGS[wordname] = argparser
-- And now it's easy to write the word DEF:
--
DEF = function (wordname, argparser_spec, argnames, text)
    local argparser = restspecs[argparser_spec] or _G[argparser_spec]
    local argnamelist = split(argnames, "([^,]+)")
    _G[wordname] = function (...)
        return withvars_expand(zip(argnamelist, arg), text)
      end
    _GETARGS[wordname] = argparser
    return ""
  end
setgetargs(vargs4_q, "DEF")




-- Local Variables:
-- coding:             raw-text-unix
-- modes:              (fundamental-mode lua-mode)
-- ee-anchor-format:   "\n%s = function"
-- End: