From 2202c781f70b3e047d10033f558181e149948480 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 25 Jan 2018 10:55:00 -0500 Subject: [PATCH] Add a dfhack.script_help() function to assist scripts --- docs/Lua API.rst | 6 +++++ library/lua/dfhack.lua | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 520ac243a..d79924cc1 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -3777,6 +3777,12 @@ Note that this function lets errors propagate to the caller. This is intended to only allow scripts that take appropriate action when used as a module to be loaded. +* ``dfhack.script_help([name, [extension]])`` + + Returns the contents of the embedded documentation of the specified script. + ``extension`` defaults to "lua", and ``name`` defaults to the name of the + script where this function was called. + Enabling and disabling scripts ============================== diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua index 340b6ce64..6acbe27e8 100644 --- a/library/lua/dfhack.lua +++ b/library/lua/dfhack.lua @@ -562,6 +562,61 @@ function dfhack.run_script_with_env(envVars, name, flags, ...) return script_code(...), env end +local function current_script_name() + local frame = 1 + while true do + local info = debug.getinfo(frame, 'f') + if not info then break end + if info.func == dfhack.run_script_with_env then + local i = 1 + while true do + local name, value = debug.getlocal(frame, i) + if not name then break end + if name == 'name' then + return value + end + i = i + 1 + end + break + end + frame = frame + 1 + end +end + +function dfhack.script_help(script_name, extension) + script_name = script_name or current_script_name() + extension = extension or 'lua' + local full_name = script_name .. '.' .. extension + local path = dfhack.internal.findScript(script_name .. '.' .. extension) + or error("Could not find script: " .. full_name) + local begin_seq, end_seq + if extension == 'rb' then + begin_seq = '=begin' + end_seq = '=end' + else + begin_seq = '[====[' + end_seq = ']====]' + end + local f = io.open(path) or error("Could not open " .. path) + local in_help = false + local help = '' + for line in f:lines() do + if line:endswith(begin_seq) then + in_help = true + elseif in_help then + if line:endswith(end_seq) then + break + end + if line ~= script_name and line ~= ('='):rep(#script_name) then + help = help .. line .. '\n' + end + end + end + f:close() + help = help:gsub('^\n+', ''):gsub('\n+$', '') + return help +end + local function _run_command(...) args = {...} if type(args[1]) == 'table' then