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

-- This is a backup of one of my old versions of "mystring" that
-- didn't use classes. Compare with:
--   (find-angg "LUA/lua50init.lua" "Tos")
--   (find-angg "LUA/tos.lua")
--   (find-angg "LUA/tos2.lua")
--
-- (defun e () (interactive) (find-angg "LUA/tos3.lua"))

-- «.mysortedpairs»		(to "mysortedpairs")
-- «.mytostringk2»		(to "mytostringk2")

tos_compare_pairs = function (pair1, pair2)
    local key1,  key2  = pair1.key,  pair2.key
    local type1, type2 = type(key1), type(key2)
    if type1 == type2 then
      if type1 == "number" then return key1 < key2 end
      if type1 == "string" then return key1 < key2 end
      return tostring(key1) < tostring(key2)  -- fast
    else
      return type1 < type2   -- numbers before strings before tables, etc
    end
  end
tos_sorted_pairs = function (T)
    local Tpairs = {}
    for key,val in pairs(T) do
      table.insert(Tpairs, {key=key, val=val})
    end
    return sorted(Tpairs, tos_compare_pairs)
  end
tos_table_orig = function (T, sep)
    return "{"..mapconcat(tos_pair, tos_sorted_pairs(T), sep or ", ").."}"
  end
tos_table = tos_table_orig
tos = function (o)
    local t = type(o)
    if t=="number" then return tostring(o) end
    if t=="string" then return format("%q", o) end
    if t=="table"  then return tos_table(o) end
    return "<"..tostring(o)..">"
  end
tos_key = tos              -- change this to print string keys differently
tos_pair = function (pair)
    return tos_key(pair.key).."="..tos(pair.val)
  end

mysort = tos_sorted_pairs   -- compatibility
mytostring = tos            -- compatibility
mytostring_arg = function (T, sep)
    return mapconcat(tos, T, sep or " ", T.n)
  end

-- Tools for building extensions
tos_good_string_key = function (key)
    return type(key) == "string" and key:match("^[A-Za-z_][A-Za-z_0-9]*$")
  end
tos_has_tostring = function (o)
    return getmetatable(T) and getmetatable(T).__tostring
  end
tos_has_eootype = function (o)
    return type(o) == "table" and getmetatable(o) and getmetatable(o).type
  end

mytostringk = mytostring   -- change this to print string keys differently

mytostring_arg = function (arg, sep)
    local images = {}
    for i=1,arg.n do images[i] = mytostring(arg[i]) end
    return table.concat(images, sep or " ")
  end

-- mytostring_arg({n=4, nil, 22, 33, nil})
-->                   "<nil> 22 33 <nil>"

-- «mysortedpairs»  (to ".mysortedpairs")
-- This is useful in iteractive scripts. The name is bad, I know.
-- (find-pilw3m "7.1.html" "simple iterator")
mysortedpairs = function (T)
    local T = mysort(T)
    local i,n = 0,#T
    return function ()
        i = i + 1
        if i <= n then return T[i].key,T[i].val end
      end
  end

-- «mytostringk2»  (to ".mytostringk2")
-- Experimental. Usage:
--   mytostringk = mytostringk2
mytostringk2 = function (o)
    if type(o) == "string" and o:match("^[A-Za-z_][A-Za-z_0-9]*$") then
      return o
    else
      return mytostring(o)
    end
  end



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