Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://anggtwu.net/LUA/Dang1.lua.html
--   http://anggtwu.net/LUA/Dang1.lua
--          (find-angg "LUA/Dang1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-angg "LUA/Dang1.lua"))
-- Used by:
--   (find-angg "LUA/Show2.lua")
--   (find-angg "LUA/CLua1.lua")

-- «.Dang»		(to "Dang")
-- «.Dang-tests»	(to "Dang-tests")


-- "tostring-empty": like tostring, but
-- returns the empty string when o is nil.
-- Used by Dang.__index.eval().
tostringe  = function (o) return o and tostring(o) or "" end


--  ____                    
-- |  _ \  __ _ _ __   __ _ 
-- | | | |/ _` | '_ \ / _` |
-- | |_| | (_| | | | | (_| |
-- |____/ \__,_|_| |_|\__, |
--                    |___/ 
--
-- An object is the class Dang "is" a string whose parts
-- between <<D>>ouble <<ANG>>le brackets "are to be expanded".
--
-- More precisely: each object of the class Dang contains a
-- field .bigstr with a string. When that object is "expanded"
-- by tostring all the parts between double angle brackets
-- in .bigstr are "expanded" by :eval(). The expansion
-- happens every time that the tostring is run, and so the
-- result of the expansion may change.
--
-- Note that I use these conventions:
--   a bigstr is a string that may contain newlines,
--   a str    is a string that does not contain newlines,
--   an s     is the argument for the function f when
--            we run bigstr:gsub(pat, f) or str:gsub(pat, f).
--
-- To understand the details, see the tests below, in:
--   (to "Dang-tests")
-- Based on: (find-angg "LUA/tikz1.lua" "Dang")
-- Uses:     (find-angg "LUA/lua50init.lua" "eval-and-L")
--
-- «Dang»  (to ".Dang")

Dang = Class {
  type = "Dang",
  from = function (bigstr) return Dang {bigstr=bigstr} end,
  __call = function (da,...) return da:tostring(...) end,
  __tostring = function (da) return da:tostring() end,
  __index = {
    code = function (da,s)
        if s:match"^::" then return Code.eval(s:sub(3)) end
        if s:match"^%." then return Code.ve("_ => _."..s:sub(2)) end
        if s:match"^:"  then return Code.ve(s:sub(2)) end
        return Code.expr(s)
      end,
    eval0 = function (da,s,...) return da:code(s)(...) end,
    eval  = function (da,s,...) return tostringe(da:eval0(s,...)) end,
    --
    pat = "<<(.-)>>",
    tostring = function (da,...)
        local args = pack(...)
        local f = function (s) return da:eval(s, myunpack(args)) end
        return (da.bigstr:gsub(da.pat, f))
      end,
  },
}

-- «Dang-tests»  (to ".Dang-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Show2.lua"
da = Dang {}
= da:code    "2+3"
= da:code    "2+3"  ()
= da:eval0  ("2+3")
= da:eval   ("2+3")
= da:code   ".foo"
= da:code   ".foo" ({foo="FOO", bar="BAR"})
= da:eval0 (".foo", {foo="FOO", bar="BAR"})
= da:eval  (".foo", {foo="FOO", bar="BAR"})
= da:code   ":a,b => a+b,a*b"
= da:code   ":a,b => a+b,a*b" (2, 3)
= da:eval0 (":a,b => a+b,a*b", 2, 3)
= da:eval  (":a,b => a+b,a*b", 2, 3)

= Dang.from "a<<2+3>>b"
= Dang.from "_<<2+3>>_<<: a,b => a*b   >>_" (4,5)
= Dang.from "_<<2+3>>_<<. foo          >>_" ({foo="FOO", bar="BAR"})
= Dang.from "_<<2+3>>_<<:: return true >>_"

--]==]







-- Local Variables:
-- coding:  utf-8-unix
-- End: