Skip to content

Instantly share code, notes, and snippets.

@AntumDeluge
Last active August 16, 2021 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AntumDeluge/719143d918f2b0f879576896c2dbed97 to your computer and use it in GitHub Desktop.
Save AntumDeluge/719143d918f2b0f879576896c2dbed97 to your computer and use it in GitHub Desktop.
LDoc config template for documenting Minetest mods
#!/usr/bin/env bash
# place this file in mod ".ldoc" directory
d_config="$(dirname $(readlink -f $0))"
cd "${d_config}/.."
d_root="$(pwd)"
d_export="${d_export:-${d_root}/docs/reference}"
cmd_ldoc="${d_root}/../ldoc/ldoc.lua"
if test -f "${cmd_ldoc}"; then
if test ! -x "${cmd_ldoc}"; then
chmod +x "${cmd_ldoc}"
fi
else
cmd_ldoc="ldoc"
fi
# clean old files
rm -rf "${d_export}"
# store current branch
main_branch="$(git branch --show-current)"
html_out="<html>\n<head></head>\n\n<body>\n\n<ul>\n"
# generate new doc files
mkdir -p "${d_export}"
for vinfo in $(git tag -l --sort=-v:refname | grep "^v[0-9]"); do
echo -e "\nbuilding ${vinfo} docs ..."
git checkout ${vinfo}
d_temp="${d_config}/temp"
mkdir -p "${d_temp}"
# backward compat
f_config="${d_root}/docs/config.ld"
if test ! -f "${f_config}"; then
f_config="${d_config}/config.ld"
fi
if test ! -f "${f_config}"; then
echo -e "\nLDoc config not available for ${vinfo}, skipping build ..."
continue
fi
"${cmd_ldoc}" --UNSAFE_NO_SANDBOX --multimodule -c "${f_config}" -d "${d_temp}" "${d_root}"; retval=$?
if test ${retval} -ne 0; then
echo -e "\nERROR: doc build for ${vinfo} failed!"
rm -rf "${d_temp}"
continue
fi
if test -d "${d_root}/textures"; then
# copy textures to data directory
echo -e "\ncopying textures ..."
d_data="${d_temp}/data"
mkdir -p "${d_data}"
texture_count=0
for png in $(find "${d_root}/textures" -maxdepth 1 -type f -name "*.png"); do
t_png="${d_data}/$(basename ${png})"
if test -f "${t_png}"; then
echo "WARNING: not overwriting existing file: ${t_png}"
else
cp "${png}" "${d_data}"
texture_count=$((texture_count + 1))
printf "\rcopied ${texture_count} textures"
fi
done
fi
mv "${d_temp}" "${d_export}/${vinfo}"
if test -z ${vcur+x}; then
vcur="${vinfo}"
ln -s "${d_export}/${vinfo}" "${d_export}/current"
ln -s "${d_export}/${vinfo}" "${d_export}/latest"
html_out="${html_out} <li><a href=\"current/\">current</a></li>\n"
html_out="${html_out} <li><a href=\"latest/\">latest</a></li>\n"
fi
html_out="${html_out} <li><a href=\"${vinfo}/\">${vinfo}</a></li>\n"
done
html_out="${html_out}</ul>\n\n</body></html>"
cd "${d_root}"
git checkout ${main_branch}
echo -e "${html_out}" > "${d_export}/index.html"
echo -e "\nDone!"
-- Place this file in mod's ".ldoc" directory
--
-- This configuration requires a customized version of LDoc:
-- https://github.com/AntumDeluge/ldoc/tree/custom
local dofile = import("dofile")
local print = import("print")
local error = import("error")
local type = import("type")
local table = import("table")
local ipairs = import("ipairs")
local pairs = import("pairs")
local string = import("string")
local tostring = import("tostring")
project = ""
title = ""
format = "markdown"
not_luadoc = true
boilerplate = false
wrap = false
--style = true
favicon = "https://www.minetest.net/media/icon.svg"
file = {}
new_type("setting", "Settings")
new_type("chatcmd", "Chat Commands")
new_type("feature", "Features")
new_type("item", "Items")
new_type("tool", "Tools")
new_type("node", "Nodes")
new_type("craft", "Crafting")
alias("craftitem", "item")
local function video_frame(src)
return '<iframe width="560" height="315" src="' .. src
.. '" title="Video Player" frameborder="0"'
.. ' allow="fullscreen;"></iframe>'
end
local tags
tags, custom_tags = dofile(".ldoc/tags.ld")
-- START: handling items to prevent re-parsing
local registered_items = {}
local is_registered = function(item)
if not registered_items[item.type] then return false end
for _, tbl in ipairs(registered_items[item.type]) do
if item == tbl then
return true
end
end
return false
end
local register = function(item)
if not registered_items[item.type] then
registered_items[item.type] = {}
end
if not is_registered(item) then
table.insert(registered_items[item.type], item)
end
end
-- END:
local set_names_hierarchy = function(name, sorted)
local m = modules.by_name[name]
if m then
m.names_hierarchy = sorted
end
end
local format_string = function(value, flags)
local st = '<span style="'
if flags.color then
st = st .. 'color:' .. flags.color .. ';'
end
if flags.size then
st = st .. 'font-size:' .. flags.size .. ';'
end
return st .. '">' .. value:gsub("_", "\\_") .. '</span>'
end
local format_setting_tag = function(desc, value)
return "\n- " .. format_string("`" .. desc .. ":`", {size="80%"}) .. " " .. value
end
local setting_handler = function(item)
local tags = {
{"settype", "type"},
{"default"},
{"min", "minimum value"},
{"max", "maximum value"},
}
local def = {
["settype"] = format_setting_tag("type", "string"),
}
for _, t in ipairs(tags) do
local name = t[1]
local desc = t[2]
if not desc then desc = name end
local value = item.tags[name]
if type(value) == "table" then
if #value > 1 then
local msg = item.file.filename .. " (line " .. item.lineno
.. "): multiple instances of tag \"" .. name .. "\" found"
if error then
error(msg)
elseif print then
print("WARNING: " .. msg)
end
end
if value[1] then
def[name] = format_setting_tag(desc, value[1])
end
end
end
item.description = item.description .. "\n\n**Definition:**\n" .. def.settype
for _, t in ipairs({def.default, def.min, def.max}) do
if t then
item.description = item.description .. t
end
end
registered.settings[item.name] = true
return item
end
local chatcmd_handler = function(item)
for _, p in ipairs(item.params) do
if item.modifiers.param[p].opt then
item.name = item.name .. " [" .. p .. "]"
else
item.name = item.name .. " &lt;" .. p .. "&gt;"
end
end
return item
end
custom_display_name_handler = function(item, default_handler)
if not is_registered(item) then
if item.type == "setting" then
item = setting_handler(item)
elseif item.type == "chatcmd" then
item = chatcmd_handler(item)
end
local parse_tags = {"priv", "note"}
for _, pt in ipairs(parse_tags) do
local tvalues = item.tags[pt]
if tvalues then
local tstring = ""
local title = tags.get_title(pt)
if title then
tstring = tstring .. "\n\n### " .. title .. ":\n"
end
for _, tv in ipairs(tvalues) do
tstring = tstring .. "\n- " .. tags.format(pt, tv)
end
item.description = item.description .. tstring
end
end
end
register(item)
return default_handler(item)
end
local custom_see_links = {
["ObjectRef"] = "https://minetest.gitlab.io/minetest/class-reference/#objectref",
["PlayerMetaRef"] = "https://minetest.gitlab.io/minetest/class-reference/#playermetaref",
["SorageRef"] = "https://minetest.gitlab.io/minetest/class-reference/#storageref",
["NodeMetaRef"] = "https://minetest.gitlab.io/minetest/class-reference/#nodemetaref",
["ItemStackMetaRef"] = "https://minetest.gitlab.io/minetest/class-reference/#itemstackmetaref",
["MetaDataRef"] = "https://minetest.gitlab.io/minetest/class-reference/#metadataref",
["InvRef"] = "https://minetest.gitlab.io/minetest/class-reference/#invref",
["ItemDef"] = "https://minetest.gitlab.io/minetest/definition-tables/#item-definition",
["ToolDef"] = "https://minetest.gitlab.io/minetest/tools/#tools-definition",
["ItemStack"] = "https://minetest.gitlab.io/minetest/class-reference/#itemstack",
["Node"] = "https://minetest.gitlab.io/minetest/nodes/",
["groups"] = "https://minetest.gitlab.io/minetest/groups/",
["entity_damage_mechanism"] = "https://minetest.gitlab.io/minetest/entity-damage-mechanism/",
["vector"] = "https://minetest.gitlab.io/minetest/representations-of-simple-things/#positionvector",
["SoundParams"] = "https://minetest.gitlab.io/minetest/sounds/",
}
local format_custom_see = function(name, section)
local url = custom_see_links[name]
if not url then
url = ""
end
if not name then
name = ""
end
return name, url
end
custom_see_handler("^(ObjectRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(PlayerMetaRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(StorageRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(NodeMetaRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(ItemStackMetaRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(MetaDataRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(InvRef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(ItemDef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(ToolDef)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(groups)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(entity_damage_mechanism)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(ItemStack)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(Node)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(vector)$", function(name, section)
return format_custom_see(name, section)
end)
custom_see_handler("^(SoundParams)$", function(name, section)
return format_custom_see(name, section)
end)
#!/usr/bin/env bash
# Place this file in mod's ".ldoc" directory
d_ldoc="$(dirname $(readlink -f $0))"
d_root="$(dirname ${d_ldoc})"
f_config="${d_ldoc}/config.ld"
d_export="${d_export:-${d_root}/docs/reference}"
cd "${d_root}"
# clean old files
rm -rf "${d_export}"
# create new files
ldoc --UNSAFE_NO_SANDBOX --multimodule -c "${f_config}" -d "${d_export}" "${d_root}"
-- Place this file in mod's ".ldoc" directory
local tags = {}
local tag_list = {}
local custom_tags = {}
local register_tag = function(name, tag)
local new_tag = {name, title=tag.title, hidden=tag.hidden, format=tag.format}
table.insert(custom_tags, new_tag)
tag_list[name] = {title=tag.title, format=tag.format}
end
tags.get_title = function(tname)
local t = tag_list[tname]
if t then
return t.title
end
end
tags.format = function(tname, value)
local t = tag_list[tname]
if t then
if type(t.format) == "function" then
value = t.format(value)
end
end
return value
end
local new_tags = {
["priv"] = {
title = "Required Privileges",
hidden = true,
},
["note"] = {
title = "Notes",
hidden = true,
format = function(value)
return "*" .. value .. "*"
end,
},
["video"] = {
title = "Video",
format = video_frame,
},
["youtube"] = {
title = "Video",
format = function(value)
return video_frame("https://www.youtube.com/embed/" .. value)
end,
},
-- settings
["settype"] = {
title = "Setting Type",
hidden = true,
},
["default"] = {
title = "Default Value",
hidden = true,
},
-- craft items/tools
["img"] = {
title = "Image",
format = function(value)
return "<img src=\"../data/" .. value .. "\" style=\"width:32px; height:32px;\" />"
end,
},
}
for k, v in pairs(new_tags) do
register_tag(k, v)
end
return tags, custom_tags
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment