Quick
index
main
eev
eepitch
maths
angg
blogme
dednat6
littlelangs
PURO
(C2,C3,C4,
 λ,ES,
 GA,MD,
 Caepro,
 textos,
 Chapa 1)

emacs
lua
(la)tex
maxima
 qdraw
git
lean4
agda
forth
squeak
icon
tcl
tikz
fvwm
debian
irc
contact

BlogMe3 as Lua classes

I started to learn Lua in 2000, and one of the first "serious" things that I did with it was an extensible HTML generator called BlogMe, that replaced my previous HTML generator written in Tcl, called TH. I rewrote BlogMe several times, and now - 2023 - most of my HTML files are still generated with blogme3, that is, ahem, a mess. The source files of blogme3 are here - blogme3/ - and in 2007 I made this attempt to document it... that is quite bad, too.

Fast forward to 2023. I started to rewrite the core of blogme3 as just three classes, all defined with eoo.lua. The classes are:

(find-angg "LUA/BlogMe3.lua" "BlogMe")
(find-angg "LUA/BlogMe3.lua" "BlogMeShort")
(find-angg "LUA/BlogMe3.lua" "BlogMeDef")

The old blogme3 used lots of functions and lots of global variables. Look:

(find-blogme3 "brackets.lua")
(find-blogme3 "definers.lua")

In the new "blogme3 with classes" - let me refer to it as "BlogMe3.lua", with some of the letters in the file name in uppercase - I reduced all those globals to just:

  • the classes BlogMe, BlogMeShort, and BlogMeDef,
  • the functions def, def_, bdef, and bdef_,
  • the tables _B, _A, and _AA.

Here is a short explanation of each of the tables:

  • _B: like _G, but blogme "words" look here first,
  • _A: the argument parser for each blogme "word",
  • _AA: the shorthands for argument parsers, used by def and friends.

Most blogme "words" are defined using def, def_, bdef, and bdef_. For example:

def  [[ HREF  2   tgt,body  "<a href=\"$tgt\">$body</a>" ]]
def  [[ lua:  1Q  code      eval(code)                   ]]
bdef [[ P     1Q  code      P(code)                      ]]

If we just run these calls to the functions def and bdef they will define the blogme "words" "HREF", "lua:", and "P"; the "code" for HREF and lua: will be stored in _G, and the "code" for "P" will be stored in _B. Both def and bdef - and also def_ and bdef_ - return objects of the class BlogMeDef; the class BlogMeDef defines a __tostring metamethod, and if we run this eepitch block,

 (eepitch-lua51)
 (eepitch-kill)
 (eepitch-lua51)
ee_dofile "~/LUA/BlogMe3.lua"
= def  [[ HREF  2   tgt,body  "<a href=\"$tgt\">$body</a>" ]]
= def  [[ lua:  1Q  code      eval(code)                   ]]
= bdef [[ P     1Q  code      P(code)                      ]]

The last part of each "print" shows the field body1 of the BlogMeDef object, that contains the code that the "def"s and the "bdef" execute after manipulating the "body" of the definition and the "shorthand for the argument parser" in several ways:

And this test block show how different parsers parse parts of a BlogMe object, and what they return:

-- From: (find-angg "LUA/BlogMe3.lua" "BlogMe-highlevel-tests")

 (eepitch-lua51)
 (eepitch-kill)
 (eepitch-lua51)
ee_dofile "~/LUA/BlogMe3.lua"
def [[ IT  1 str  "<i>$str</i>"    ]]
def [[ EM  1 str  "<em>$str</em>"  ]]

= IT("foo")
bm = BlogMe.from [[ abc[IT de]fg  hi ]]
bm:runats(1, [[ readqlist
                readqrest
                readqqrest
                readqqqrest
                readqword   ]])
bm:runats(1, [[ readvlist
                readvrest
                readvvrest
                readvvvrest
                readvword   ]])

Here is a screenshot:

Note that the parsers with "q"s in their names return "quoted" versions of what they parse, like Lisp's QUOTE, macros, and special forms, and the parsers with "v"s in their names return the "values" of what they parse - they evaluate the "[...]" blocks.


1. Try it!

 (eepitch-shell)
 (eepitch-kill)
 (eepitch-shell)
rm -Rv /tmp/luademo/
mkdir  /tmp/luademo/
cd     /tmp/luademo/
wget http://anggtwu.net/LUA/lua50init.lua
wget http://anggtwu.net/LUA/BlogMe3.lua
# (find-fline "/tmp/luademo/")

 (setenv "LUA_INIT" "@/tmp/luademo/lua50init.lua")
 (find-anchor "/tmp/luademo/BlogMe3.lua")
 (find-anchor "/tmp/luademo/BlogMe3.lua" "def-tests")
 (find-anchor "/tmp/luademo/BlogMe3.lua" "BlogMe-highlevel-tests")


2. What's missing

I haven't started to port my .blogme files to BlogMe3.lua yet! These are the main things that I still need to integrate with BlogMe3.lua:

http://anggtwu.net/htmlize.html
(find-angg "blogme3/anggdefs.lua")
(find-angg "blogme3/options.lua")
(find-angg "blogme3/sandwiches.lua")
(find-angg "blogme3/sandwiches-defs.lua")