summaryrefslogtreecommitdiff
path: root/lupin.lua
blob: c2ba662ee88259f23a245aa2c7623e2728e18e41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
posix = require 'posix'
require 'corz'

local function printf(...) print(string.format(...)) end

local function setfenv(fn, env)
  local i = 1
  while true do
    local name = debug.getupvalue(fn, i)
    if name == "_ENV" then
      debug.upvaluejoin(fn, i, (function()
        return env
      end), 1)
      break
    elseif not name then
      break
    end

    i = i + 1
  end

  return fn
end


local html = {}
function html.label(label)
  printf("<label>%s</label>", label)
end
function html.orz(k, v)
  printf("<img class='orz' data-name=%s src='%s' data-uri='/orz/'>", k, v)
  printf("<input name='%s' value='%s' type='hidden'>", k, v)
end
function html.date(k, v, s)
  printf("<input type=date name=%s size=%s value='%s'>", k, s or 10, v or '')
end
function html.text(k, v, s)
  printf("<input type=text name=%s size=%s value='%s'>", k, s or 18, v or '')
end
function html.hidden(k, v)
  printf("<input type=hidden name=%s value='%s'>", k, v)
end
function html.textarea(k, v, r, c)
  c = c or 72
  r = r or 16
  printf("<textarea name=%s cols=%s rows=%s>%s</textarea>", k, c, r, v or '')
end
function html.print(s)
  printf("%s", s)
end
function html.select(k, options, selected)
  local p = ""
  printf("<select name='%s'>", k)
  for k,v in pairs(options) do
    if selected and selected == tostring(v) then
      p = "selected "
    end
    printf("<option %svalue='%s'>%s</option>", p, v, v)
    p = ""
  end
  print("</select>")
end
function html.submit(value)
  printf("<input type=submit value='%s'>", value)
end
function html.p(...)
  printf("<p>%s", ... or '')
end
function html.h1(...)
  printf("<h1>%s</h1>", ... or '')
end

help = { html = html, os = os, posix = posix, pairs = pairs }

lupin = {}
lupin.blueprints = {}
lupin.blueprints.default = {
  purestrain = function(body, data)
    print(data.title)
    if data.type ~= "default" then
      printf("# type: %s", data.type)
    end
    data.title = nil
    data.type = nil
    print(body)
    for key, value in pairs(data) do
      print(("# %s: %s"):format(key, value))
    end
  end,
  form = function(body, data)
    help.form.text('overskrift', data.title)
  end,
  html = function(body, data)
    if data.mode == "title" then
      printf("<h2>%s</h2>", data.title)
      return
    elseif data.mode == "full" then
      printf("<h1>%s</h1>", data.title)
    end
    printf(corz.marxup(body, io.stdout))
    if not next(data) then return end
    print("<dl>")
    for key, value in pairs(data) do
      printf("<dt>%s</dt><dd>%s</dd>", key, value)
    end
    print("</dl>")
  end
}
function help.blueprint(id)
  return setmetatable({ id = id }, { __index = lupin.blueprints.default })
end

function lupin.loadblueprints(path)
  local blueprints = posix.glob(path .. "/*.lua")
  if blueprints then
    for i, file in pairs(blueprints) do
      local chunk = loadfile(file)
      setfenv(chunk, help)
      local blueprint = chunk()
      lupin.blueprints[blueprint.id] = blueprint
    end
  end
end

function lupin.transform(format, env, mode)
  local raw, data = "", {}

  if env then
    data.type = os.getenv("POST_type") or "default"
    data.title = os.getenv("POST_title") or "default"
    raw = os.getenv("POST_text") or ""
    raw = raw:match("(.-)%s*$")
    if lupin.blueprints[data.type] and lupin.blueprints[data.type].env then
      lupin.blueprints[data.type].env(data)
    end
  else
    for line in io.lines() do
      if line:match("^#") then
        local key, value = line:match("^#%s*(.-):%s*(.+)")
        if key and value then data[key] = value end
      else
        if not data.title then
          data.title = line
        else
          raw = raw .. line .. "\n"
        end
      end
    end
    data.type = data.type or "default"
  end
  data.mode = mode
  if data.mode == "short" then
    raw = raw:match("[^\r\n]+")
  end
  lupin.blueprints[data.type][format](raw, data)
end