diff options
author | sanine <sanine.not@pm.me> | 2023-09-18 05:11:05 +0000 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-09-18 05:11:05 +0000 |
commit | 3425c3c435a000b14103a0055fd913ccb855b734 (patch) | |
tree | 2efbb0599104d3794f5c0604d71ac16bf97368d2 /yarrow-ui.cgi | |
parent | bfcc2e759807a692d8e0353e3bbecd109175032b (diff) |
implement basic ui
Diffstat (limited to 'yarrow-ui.cgi')
-rwxr-xr-x | yarrow-ui.cgi | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/yarrow-ui.cgi b/yarrow-ui.cgi index 37c2f87..9a1d134 100755 --- a/yarrow-ui.cgi +++ b/yarrow-ui.cgi @@ -6,7 +6,156 @@ local b64 = require '3rdparty.base64' local json = require '3rdparty.json' -local img = h('img', { style='color: white', src='https://sanine.net/utils/yarrow/yarrow.cgi?statistics=eyJzdHIiOjE3LCJocCI6IjM5ICg2ZDggKyAxMikiLCJ3aXMiOjEzLCJhYyI6IjE3IChuYXR1cmFsIGFybW9yLCBzaGllbGQpIiwiY29uIjoxNSwiaW50IjoxMiwic3BlZWQiOiIzMCBmdC4iLCJhY3Rpb25zIjpbeyJuYW1lIjoiV2FyaGFtbWVyIiwidmFsdWUiOiIqTWVsZWUgV2VhcG9uIEF0dGFjazoqICs1IHRvIGhpdCwgcmVhY2ggNSBmdC4sIG9uZSB0YXJnZXQuICpIaXQ6KiA3ICgxZDggKyAzKSBibHVkZ2VvbmluZyBkYW1hZ2Ugb3IgOCAoMWQxMCArIDMpIGJsdWRnZW9uaW5nIGRhbWFnZSBpZiB1c2VkIHdpdGggdHdvIGhhbmRzIHRvIG1ha2UgYSBtZWxlZSBhdHRhY2ssIHBsdXMgMyAoMWQ2KSBmaXJlIGRhbWFnZS4ifV0sInNpemUiOiJtZWRpdW0iLCJ0eXBlIjoiZWxlbWVudGFsIiwiY2hhIjoxMCwibGVnZW5kYXJ5Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGRlYXRoIHR5cmFudCBjYW4gdGFrZSAzIGxlZ2VuZGFyeSBhY3Rpb25zLCB1c2luZyB0aGUgRXllIFJheSBvcHRpb24gYmVsb3cuIEl0IGNhbiB0YWtlIG9ubHkgb25lIGxlZ2VuZGFyeSBhY3Rpb24gYXQgYSB0aW1lIGFuZCBvbmx5IGF0IHRoZSBlbmQgb2YgYW5vdGhlciBjcmVhdHVyZSdzIHR1cm4uIFRoZSB0eXJhbnQgcmVnYWlucyBzcGVudCBsZWdlbmRhcnkgYWN0aW9ucyBhdCB0aGUgc3RhcnQgb2YgaXRzIHR1cm4uIiwiYWN0aW9ucyI6W3sibmFtZSI6IkV5ZSBSYXkiLCJ2YWx1ZSI6IlRoZSBkZWF0aCB0eXJhbnQgdXNlcyBvbmUgcmFuZG9tIGV5ZSByYXkuIn1dfSwiaW1tdW5pdGllcyI6ImZpcmUsIHBvaXNvbiIsInRyYWl0cyI6W3sibmFtZSI6IkhlYXRlZCBCb2R5IiwidmFsdWUiOiJBIGNyZWF0dXJlIHRoYXQgdG91Y2hlcyB0aGUgYXplciBvciBoaXRzIGl0IHdpdGggYSBtZWxlZSBhdHRhY2sgd2hpbGUgd2l0aGluIDUgZmVldCBvZiBpdCB0YWtlcyA1ICgxZDEwKSBmaXJlIGRhbWFnZS4ifSx7Im5hbWUiOiJIZWF0ZWQgV2VhcG9ucyIsInZhbHVlIjoiV2hlbiB0aGUgYXplciBoaXRzIHdpdGggYSBtZXRhbCBtZWxlZSB3ZWFwb24sIGl0IGRlYWxzIGFuZCBleHRyYSAzICgxZDYpIGZpcmUgZGFtYWdlIChpbmNsdWRlZCBpbiB0aGUgYXR0YWNrKS4ifSx7Im5hbWUiOiJJbGx1bWluYXRpb24iLCJ2YWx1ZSI6IlRoZSBhemVyIHNoZWRzIGJyaWdodCBsaWdodCBpbiBhIDEwPWZvb3QgcmFkaXVzIGFuZCBkaW0gbGlnaHQgZm9yIGFuIGFkZGl0aW9uYWwgMTAgZmVldC4ifV0sImFsaWdubWVudCI6Imxhd2Z1bCBuZXV0cmFsIiwic2F2aW5nX3Rocm93cyI6IkNvbiArNCIsIm5hbWUiOiJBemVyIiwiY29uZGl0aW9uX2ltbXVuaXRpZXMiOiJwb2lzb25lZCIsImxhbmd1YWdlcyI6IklnbmFuIiwic2Vuc2VzIjoicGFzc2l2ZSBQZXJjZXB0aW9uIDExIiwiZGV4IjoxMiwiY3IiOiIyICg0NTAgWFApIn0=' }) +-- get statistics +local metavars = marigold.get_metavars() +local query = marigold.decode_query(metavars.query_string or '') +local function query_retrieve(key, default) + local key = 'stat_'..key + if query[key] ~= '' then return query[key] + else return default + end +end +local stat = { + name = query_retrieve('name', 'Name'), + alignment = query_retrieve('alignment', 'neutral'), + size = query_retrieve('size', 'medium'), + type = query_retrieve('type', 'creature'), + + ac = query_retrieve('ac', '0'), + hp = query_retrieve('hp', '0'), + speed = query_retrieve('speed', '0 ft.'), + + str = query_retrieve('str', '10'), + dex = query_retrieve('dex', '10'), + con = query_retrieve('con', '10'), + int = query_retrieve('int', '10'), + wis = query_retrieve('wis', '10'), + cha = query_retrieve('cha', '10'), + + saving_throws = (query.stat_saving_throws ~= '' and query.stat_saving_throws) or '', + vulnerabilities = (query.stat_vulnerabilities ~= '' and query.stat_vulnerabilities) or '', + resistances = (query.stat_reistances ~= '' and query.stat_reistances) or '', + immunities = (query.stat_immunities ~= '' and query.stat_immunities) or '', + condition_immunities = (query.stat_condition_immunities ~= '' and query.stat_condition_immunities) or '', + languages = (query.stat_languages ~= '' and query.stat_languages) or '', + cr = (query.stat_cr ~= '' and query.stat_cr) or '', + + traits = (query.stat_traits ~= '' and query.stat_traits) or [[@New Trait +Add a named trait with an at sign. All lines following until the next at sign +will be part of the trait description! + +@Second Trait +This is a different trait. +]], + actions = (query.stat_actions ~= '' and query.stat_actions) or [[ +@New Action +Actions (and reactions and legendary actions) use the same syntax as traits. As well, +in all of them you can add *italics* and **bold** text! +]], + reactions = (query.stat_reactions ~= '' and query.stat_reactions) or '', + legendary_description = (query.stat_legendary_description ~= '' and query.stat_legendary_description) or '', + legendary = (query.stat_legendary ~= '' and query.stat_legendary) or '', +} + + + +-- stats yarrow query conversion +local function parse_traits(str) + local tbl = {} + for name, value in string.gmatch(str, '@([^@]-)\n([^@]+)') do + table.insert(tbl, {name=name, value=value}) + end + return tbl +end +local function convert(stats) + local tbl = {} + for k, v in pairs(stats) do + if v ~= '' then + tbl[k] = v + end + end + tbl.traits = parse_traits(stats.traits) + tbl.actions = parse_traits(stats.actions) + tbl.actions = parse_traits(stats.actions) + if stats.legendary ~= '' then + tbl.legendary = {} + tbl.legendary.description = stats.legendary_description + tbl.legendary.actions = parse_traits(stats.legendary) + end + return json.encode(tbl) +end + + +-- form helpers +local function text_input(label, name, value) + local tbl = {} + tbl['for'] = name + return h('div', { class='inputdiv', + h('label', label, tbl), + h('input', { type='text', id=name, name=name, value=value }), + }) +end +local function textarea(label, name, value, height) + local tbl = {} + tbl['for'] = name + return h('div', { class='inputdiv', + h('label', label, tbl), + h('textarea', value, { id=name, name=name, style=(height and 'height:'..height) or nil }), + }) +end + + +-- stats form +local form_basic = h('form', { style="width:100%; max-width: 30em; margin: auto; padding: 3em 0;", + text_input('Name', 'stat_name', stat.name), + text_input('Alignment', 'stat_alignment', stat.alignment), + text_input('Size', 'stat_size', stat.size), + text_input('Type', 'stat_type', stat.type), + h('br'), + + text_input('Armor Class', 'stat_ac', stat.ac), + text_input('Hit Points', 'stat_hp', stat.hp), + text_input('Speed', 'stat_speed', stat.speed), + h('br'), + + text_input('STR', 'stat_str', stat.str), + text_input('DEX', 'stat_dex', stat.dex), + text_input('CON', 'stat_con', stat.dex), + text_input('INT', 'stat_int', stat.int), + text_input('WIS', 'stat_wis', stat.wis), + text_input('CHA', 'stat_cha', stat.cha), + h('br'), + + text_input('Saving Throws', 'stat_saving_throws', stat.saving_throws), + text_input('Damage Vulnerabilities', 'stat_vulnerabilities', stat.vulnerabilities), + text_input('Damage Resistances', 'stat_resistances', stat.resistances), + text_input('Damage Immunities', 'stat_immunities', stat.immunities), + text_input('Condition Immunities', 'stat_condition_immunities', stat.condition_immunities), + text_input('Senses', 'stat_senses', stat.senses), + text_input('Languages', 'stat_languages', stat.languages), + text_input('Challenge', 'stat_cr', stat.cr), + h('br'), + + textarea('Additional Traits', 'stat_traits', stat.traits, '20em'), + h('br'), + textarea('Actions', 'stat_actions', stat.actions, '20em'), + h('br'), + textarea('Reactions', 'stat_reactions', stat.reactions, '20em'), + h('br'), + textarea('Legendary Action Text', 'stat_legendary_description', stat.legendary_description, '5em'), + textarea('Legendary Actions', 'stat_legendary', stat.legendary, '20em'), + h('br'), + h('div', { style='text-align:center', + h('button', 'Update', { type='submit' }), + }) +}) + + +local img = h('div', { style='text-align: center', + h('img', { style="max-width:500px", width='90%', src='yarrow.cgi?statistics='..b64.encode(convert(stat)) }), + h('br'), + h('a', 'image permalink', { id="permalink", href='yarrow.cgi?statistics='..b64.encode(convert(stat)) }), +}) local head = h('head', { @@ -16,7 +165,14 @@ local head = h('head', { h('link', { rel='stylesheet', href='style.css' }), }) + +local traits = parse_traits(stat.traits) +local traits_elements = {} +for _, t in ipairs(traits) do + table.insert(traits_elements, h('p', string.format('%s -> %s', t.name, t.value))) +end local body = h('body', { + form_basic, img, }) |