Merge pull request #2924 from Elv13/extend_doc

Extend the documentation with new custom tags.
This commit is contained in:
Emmanuel Lepage Vallée 2019-11-27 14:07:11 -05:00 committed by GitHub
commit e411500dda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 517 additions and 15 deletions

View File

@ -3,6 +3,7 @@
-- @tparam string name The name of the signal.
-- @tparam function func The callback that should be disconnected.
-- @method disconnect_signal
-- @baseclass gears.object
--- Emit a signal.
--
@ -11,11 +12,13 @@
-- function receives the object as first argument and then any extra
-- arguments that are given to emit_signal().
-- @method emit_signal
-- @baseclass gears.object
--- Connect to a signal.
-- @tparam string name The name of the signal.
-- @tparam function func The callback to call when the signal is emitted.
-- @method connect_signal
-- @baseclass gears.object
--- Connect to a signal weakly.
--
@ -28,3 +31,4 @@
-- @tparam string name The name of the signal.
-- @tparam function func The callback to call when the signal is emitted.
-- @method weak_connect_signal
-- @baseclass gears.object

View File

@ -4,6 +4,7 @@
--
-- * *property::border_width*
--
-- @baseclass wibox
-- @property border_width
-- @param integer
@ -29,6 +30,7 @@
--
-- * *property::border_color*
--
-- @baseclass wibox
-- @property border_color
-- @param string
@ -38,6 +40,7 @@
--
-- * *property::ontop*
--
-- @baseclass wibox
-- @property ontop
-- @param boolean
@ -47,6 +50,7 @@
--
-- * *property::cursor*
--
-- @baseclass wibox
-- @property cursor
-- @param string
-- @see mouse
@ -57,6 +61,7 @@
--
-- * *property::visible*
--
-- @baseclass wibox
-- @property visible
-- @param boolean
@ -66,6 +71,7 @@
--
-- * *property::opacity*
--
-- @baseclass wibox
-- @property opacity
-- @tparam number opacity (between 0 and 1)
@ -75,6 +81,7 @@
--
-- * *property::type*
--
-- @baseclass wibox
-- @property type
-- @param string
-- @see client.type
@ -85,6 +92,7 @@
--
-- * *property::x*
--
-- @baseclass wibox
-- @property x
-- @param integer
@ -94,6 +102,7 @@
--
-- * *property::y*
--
-- @baseclass wibox
-- @property y
-- @param integer
@ -103,6 +112,7 @@
--
-- * *property::width*
--
-- @baseclass wibox
-- @property width
-- @param width
@ -112,11 +122,13 @@
--
-- * *property::height*
--
-- @baseclass wibox
-- @property height
-- @param height
--- The wibox screen.
--
-- @baseclass wibox
-- @property screen
-- @param screen
@ -126,10 +138,12 @@
--
-- * *property::drawable*
--
-- @baseclass wibox
-- @property drawable
-- @tparam drawable drawable
--- The widget that the `wibox` displays.
-- @baseclass wibox
-- @property widget
-- @param widget
@ -139,6 +153,7 @@
--
-- * *property::window*
--
-- @baseclass wibox
-- @property window
-- @param string
-- @see client.window
@ -149,6 +164,7 @@
--
-- * *property::shape_bounding*
--
-- @baseclass wibox
-- @property shape_bounding
-- @param surface._native
@ -158,6 +174,7 @@
--
-- * *property::shape_clip*
--
-- @baseclass wibox
-- @property shape_clip
-- @param surface._native
@ -167,6 +184,7 @@
--
-- * *property::shape_input*
--
-- @baseclass wibox
-- @property shape_input
-- @param surface._native
@ -177,6 +195,7 @@
--
-- * *property::shape*
--
-- @baseclass wibox
-- @property shape
-- @tparam gears.shape shape
@ -192,35 +211,41 @@
--
-- * *property::input_passthrough*
--
-- @baseclass wibox
-- @property input_passthrough
-- @param[opt=false] boolean
-- @see shape_input
--- Get or set mouse buttons bindings to a wibox.
--
-- @baseclass wibox
-- @param buttons_table A table of buttons objects, or nothing.
-- @method buttons
--- Get or set wibox geometry. That's the same as accessing or setting the x,
-- y, width or height properties of a wibox.
--
-- @baseclass wibox
-- @param A table with coordinates to modify.
-- @return A table with wibox coordinates and geometry.
-- @method geometry
--- Get or set wibox struts.
--
-- @baseclass wibox
-- @param strut A table with new strut, or nothing
-- @return The wibox strut in a table.
-- @method struts
-- @see client.struts
--- The default background color.
-- @baseclass wibox
-- @beautiful beautiful.bg_normal
-- @param color
-- @see bg
--- The default foreground (text) color.
-- @baseclass wibox
-- @beautiful beautiful.fg_normal
-- @param color
-- @see fg
@ -228,9 +253,11 @@
--- Set a declarative widget hierarchy description.
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
-- @param args An array containing the widgets disposition
-- @baseclass wibox
-- @method setup
--- The background of the wibox.
-- @baseclass wibox
-- @param c The background to use. This must either be a cairo pattern object,
-- nil or a string that gears.color() understands.
-- @property bg
@ -241,12 +268,14 @@
-- If `image` is a function, it will be called with `(context, cr, width, height)`
-- as arguments. Any other arguments passed to this method will be appended.
-- @param image A background image or a function
-- @baseclass wibox
-- @property bgimage
-- @see gears.surface
--- The foreground (text) of the wibox.
-- @param c The foreground to use. This must either be a cairo pattern object,
-- nil or a string that gears.color() understands.
-- @baseclass wibox
-- @property fg
-- @param color
-- @see gears.color
@ -258,4 +287,5 @@
-- @treturn table A sorted table of widgets positions. The first element is the biggest
-- container while the last is the topmost widget. The table contains *x*, *y*,
-- *width*, *height* and *widget*.
-- @baseclass wibox
-- @method find_widgets

View File

@ -7,10 +7,12 @@
-- @return The parent layout
-- @return The path between self and widget
-- @method index
-- @baseclass wibox.widget
--- Get or set the children elements.
-- @property children
-- @tparam table children The children.
-- @baseclass wibox.widget
--- Get all direct and indirect children widgets.
-- This will scan all containers recursively to find widgets
@ -18,27 +20,33 @@
-- children, contain (directly or indirectly) itself.
-- @property all_children
-- @tparam table children The children.
-- @baseclass wibox.widget
--- Set a declarative widget hierarchy description.
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
-- @param args An array containing the widgets disposition
-- @method setup
-- @baseclass wibox.widget
--- Force a widget height.
-- @property forced_height
-- @tparam number|nil height The height (`nil` for automatic)
-- @baseclass wibox.widget
--- Force a widget width.
-- @property forced_width
-- @tparam number|nil width The width (`nil` for automatic)
-- @baseclass wibox.widget
--- The widget opacity (transparency).
-- @property opacity
-- @tparam[opt=1] number opacity The opacity (between 0 and 1)
-- @baseclass wibox.widget
--- The widget visibility.
-- @property visible
-- @param boolean
-- @baseclass wibox.widget
--- The widget buttons.
--
@ -47,10 +55,12 @@
-- @property buttons
-- @param table
-- @see awful.button
-- @baseclass wibox.widget
--- Add a new `awful.button` to this widget.
-- @tparam awful.button button The button to add.
-- @function add_button
-- @baseclass wibox.widget
--- Emit a signal and ensure all parent widgets in the hierarchies also
-- forward the signal. This is useful to track signals when there is a dynamic
@ -58,6 +68,7 @@
-- @tparam string signal_name
-- @param ... Other arguments
-- @method emit_signal_recursive
-- @baseclass wibox.widget
--- When the layout (size) change.
-- This signal is emitted when the previous results of `:layout()` and `:fit()`
@ -65,6 +76,7 @@
-- must return the same result when called with the same arguments.
-- @signal widget::layout_changed
-- @see widget::redraw_needed
-- @baseclass wibox.widget
--- When the widget content changed.
-- This signal is emitted when the content of the widget changes. The widget will
@ -72,6 +84,7 @@
-- `:layout()` and `:fit()` would still return the same results as before.
-- @signal widget::redraw_needed
-- @see widget::layout_changed
-- @baseclass wibox.widget
--- When a mouse button is pressed over the widget.
-- @signal button::press
@ -101,6 +114,7 @@
-- @tparam number find_widgets_result.widget_height The exact height of the widget
-- in its local coordinate system.
-- @see mouse
-- @baseclass wibox.widget
--- When a mouse button is released over the widget.
-- @signal button::release
@ -130,6 +144,7 @@
-- @tparam number find_widgets_result.widget_height The exact height of the widget
-- in its local coordinate system.
-- @see mouse
-- @baseclass wibox.widget
--- When the mouse enter a widget.
-- @signal mouse::enter
@ -153,6 +168,7 @@
-- @tparam number find_widgets_result.widget_height The exact height of the widget
-- in its local coordinate system.
-- @see mouse
-- @baseclass wibox.widget
--- When the mouse leave a widget.
-- @signal mouse::leave
@ -176,3 +192,4 @@
-- @tparam number find_widgets_result.widget_height The exact height of the widget
-- in its local coordinate system.
-- @see mouse
-- @baseclass wibox.widget

View File

@ -93,6 +93,257 @@ new_type("filterfunction", "List filters", false)
-- Extra client properties available only in awful.rules/spawn constructs
new_type("clientruleproperty", "Extra properties available in awful.rules and awful.spawn", false, "Type")
-- Simulate the default "params" parser format, except the optional "[]" section
-- needs a space.
local function parse_custom_tags(text, params)
text = text:gmatch("[ ]*(.*)$")()
local raw_extra = ""
if text:sub(1,1) == '[' then
local count = 1
-- Find the matching ']'
for i=2, text:len() do
local char = text:sub(i,i)
if char == '[' then
count = count + 1
elseif char == ']' then
count = count - 1
end
raw_extra = raw_extra..char
if count == 0 then
text = text:sub(i+2)
break
end
end
end
-- Split the remaining text into words.
local words, values, description = {}, {}, {}
for word in text:gmatch("[^ \n\r]*") do
if word ~= "" then
words[#words+1] = word
end
end
for idx, word in ipairs(words) do
if idx <= #params then
local name = params[idx].name
values[name] = {
name = name,
title = params[idx].title or name,
value = word
}
else
description[#description+1] = word
values.description = values.description and
values.description.." "..word or
word
end
end
return values
end
-- Mimic the template classes.
local function default_format_callback(self, params, _, md)
local ret = ""
if self.table then
-- All columns are mandatory
for _, p in ipairs(self.params) do
local content = params[p.name] and params[p.name].value or ""
ret = ret.."<td>"..(p.markdown and md("`"..content.."`") or content).."</td>"
end
return ret .. "<td>"..md(params.description).."</td>"
else
if params.name then
ret = '<span class="parameter">'..
md("`"..params.name.value.."`")..
"</span> "
end
if params.type then
ret = ret .. '<span class="parameter">('..
md("`"..params.type.value.."`")..
")</span>"
end
return ret.." "..md(params.description)
end
end
-- Generate a format function.
local function default_format(self, callback)
return function(raw, item, md)
return (callback or default_format_callback)(
self, parse_custom_tags(raw, self.params or {}), item, md
)
end
end
local named_tags, item_id = {}, 1
-- Add a new @something which can be used in any types.
-- @tparam table args
-- @tparam string args.name The name.
-- @tparam string args.hidden Show in the doc or for internal use only.
-- @tparam table args.table Show the items in a table rather than a list. The
-- content is the list of header names.
-- @tparam table args.params The parameters (table with name, tilte, format).
-- @tparam boolean[opt=true] args.auto_subtags Create the usage and tparams subtags.
local add_custom_tag
add_custom_tag = function(args)
local name = args.name
args.name, args[1] = nil, name
custom_tags = custom_tags or {}
local f = args.format
args.format = default_format(args, f)
custom_tags[#custom_tags+1] = args
named_tags[name] = args
-- Auto create @name_tparams and @name_usage for each custom tags.
if args.auto_subtags ~= false then
add_custom_tag {
name = name.."tparam",
auto_params = true,
parent = args,
auto_subtags = false,
params = {
{ name = "type" },
{ name = "name" },
}
}
add_custom_tag {
name = name.."usage",
auto_usage = true,
parent = args,
auto_subtags = false,
}
end
end
-- When a type will request a permission.
-- @emits class signal Message[...]
add_custom_tag {
name = "emits",
title = "Emit signals",
hidden = false,
params = {
{
name = "name"
}
}
}
-- Avoid repetitive boilerplate code for property signals.
-- Add true if the signal has the value or false if it doesn't.
-- @propemits true/false true/false description[...]
add_custom_tag {
name = "propemits",
title = "Emit signals:",
hidden = false,
params = {{name = "new_value"}, {name = "old_value"}},
format = function(self, params, item, md)
-- Add an automatic fallback description.
local description = params.description ~= "" and params.description or
"When the `"..item.name.."` value changes."
local new_value = params.new_value.value == "true"
local old_value = params.old_value.value == "true"
-- Add the sub-tags.
local subs = {}
item.auto_params["propemitstparam_override"] = subs
-- The first argument is always the object which changes.
subs[1] = item.module.name.." self ".." The object which changed ("..
"useful when connecting many object to the same callback)."
-- Most signals also have the new value.
if new_value then
local type = item.params[1] or "unknown"
subs[2] = type.." ".."v The new value."
end
-- Some also have the old value.
if old_value then
local type = item.params[1] or "unknown"
subs[3] = type.." ".."v The new value."
end
local new_params = {
name = { name = name, value = "property::"..item.name },
description = params.description
}
return default_format_callback(self, new_params, item, md)
end
}
-- List the beautiful variables used by the method or property fallbacks.
-- @usebeautiful beautiful.varname usage[...]
add_custom_tag {
name = "usebeautiful",
title = "Consumed theme variables",
hidden = false,
table = {
"Variable", "Usage"
},
params = {
{
name = "name",
markdown = true,
}
}
}
-- For all properties which have a standard `@beautiful` variable for them
-- @propbeautiful fallback1 fallback2 fallback3 fallback4
add_custom_tag {
name = "propbeautiful",
title = "Consumed theme variables",
params = {
{ name = "fallback1" },
{ name = "fallback2" },
{ name = "fallback3" },
{ name = "fallback4" },
},
table = {
"Variable", "Usage"
},
format = function(self, p, item, md)
local modname = item.module.name:gmatch("[^.]+$")()
local last = "beautiful."..(modname.."_"..item.name):gsub("[.]", "_")
local ret = "<td>"..md("`"..last.."`").."</td><td>Fallback when "..md("`"..item.name.."`")..
" isn't set.</td>"
for _, fallback in ipairs({p.fallback1, p.fallback2, p.fallback3, p.fallback4 }) do
ret = ret .. "</tr><tr>"..
"<td>"..md("`"..fallback.value.."`").."</td><td>Fallback when "..md("`"..last.."`")..
" isn't set.</td>"
last = fallback.value
end
return ret
end
}
-- Define the base class where a method/property is implemented.
-- @baseclass my_module.my_submodule.my_baseclass
add_custom_tag {
name = "baseclass",
hidden = true
}
-- More fitting section names
kind_names={topic='Documentation', module='Libraries', script='Sample files'}
@ -191,6 +442,141 @@ local named_args = {
[ "([args={}])" ] = true
}
-- Sections which are hidden by default, but visible when clicked.
local summarize = {
emits = {index = 1, title = "Signals" },
propemits = {index = 2, title = "Signals" },
usebeautiful = {index = 3, title = "Theme variables"},
propbeautiful = {index = 4, title = "Theme variables"}
}
local delimiter_for_tag = {
usebeautiful = { "table class='widget_list' border=1", "table", "tr", "tr", {"Theme variable", "Usage"}},
propbeautiful = { "table class='widget_list' border=1", "table", "tr", "tr", {"Theme variable", "Usage"}},
}
-- Use the first word of the subtag content to map it to its tag.
local function sort_subtags(item, tag, subtag, values)
local ret = {}
for _, value in ipairs(values) do
local parsed = parse_custom_tags(value, {{name = "maps_to"}})
ret[parsed.maps_to.value] = ret[parsed.maps_to.value] or {}
ret[parsed.maps_to.value][#ret[parsed.maps_to.value]+1] = parsed.description
end
return ret
end
-- Gather a summary of the tags hidden by default .
local function generate_summary(item)
local tgs = {}
for k, v in pairs(summarize) do
tgs[v.index] = {title=v.title, count=0}
end
for tag, value in pairs(item.tags) do
if summarize[tag] then
tgs[summarize[tag].index].count = tgs[summarize[tag].index].count + 1
end
end
local ret = {}
for k, v in ipairs(tgs) do
if v.count > 0 then
ret[#ret+1] = v
end
end
item.extra_summary = #ret > 0 and ret or nil
end
-- We have custom types, sub-types and different rendering.
--
-- To avoid added too much business logic in the template, handle this now.
-- Note that this works because the name handler is called when doing the table
-- of content, which is before any custom types is used.
local function init_custom_types(item)
if item.is_init then return end
generate_summary(item)
-- Give each item an unique identifier so the JavaScript can locate them.
item.uid, item_id = item_id, item_id + 1
item.delims, item.auto_usage, item.auto_params = {}, {}, {}
local to_rm = {}
for tag, values in pairs(item.tags) do
-- Remove the sub-tags so they don't get rendered as top level ones.
if named_tags[tag] and named_tags[tag].auto_usage then
item.auto_usage[tag] = sort_subtags(
item, named_tags[tag].parent, named_tags[tag], values
)
to_rm[#to_rm+1] = tag
elseif named_tags[tag] and named_tags[tag].auto_params then
item.auto_params[tag] = sort_subtags(
item, named_tags[tag].parent, named_tags[tag], values
)
to_rm[#to_rm+1] = tag
end
end
-- Remove from the top-level tag list.
for _, rm in ipairs(to_rm) do
item.tags[rm] = nil
end
-- Set the item base class.
if item.tags["baseclass"] then
item.baseclass = item.tags["baseclass"][1]
end
if not item.baseclass and item.module then
item.baseclass = item.module.name
end
-- Some methods and properties can be inherited from parent classes.
-- in those case, they need the explicit `@baseclass` tag.
item.inherited = item.baseclass and item.module
and item.module.name ~= item.baseclass
function item.get_delim(tag)
if delimiter_for_tag[tag] then
return delimiter_for_tag[tag][1],
delimiter_for_tag[tag][2],
delimiter_for_tag[tag][3],
delimiter_for_tag[tag][4],
delimiter_for_tag[tag][5]
else
return "ul", "ul", "li", "li", nil
end
end
-- Allow the template to fetch the right sub-tags.
function item.get_auto_params(tag, value)
-- Makes auto-generated subtags easier to implement.
if item.auto_params[tag.."tparam_override"] then
return item.auto_params[tag.."tparam_override"], named_tags[tag.."tparam"]
end
if not item.auto_params[tag.."tparam"] then return nil, nil end
local parsed = parse_custom_tags(value, named_tags[tag].params)
if parsed.name and item.auto_params[tag.."tparam"][parsed.name.value] then
return item.auto_params[tag.."tparam"][parsed.name.value], named_tags[tag.."tparam"]
end
return nil, nil
end
item.is_init = true
end
-- Wrap the arguments for the CSS highlight.
local function wrap_args(item)
if not item.args then return "" end
@ -300,6 +686,8 @@ local show_return = {
}
custom_display_name_handler = function(item, default_handler)
init_custom_types(item)
local ret = default_handler(item)
-- Edit the input so the template is notified.

View File

@ -288,6 +288,7 @@ table.module_list td.summary, table.function_list td.summary {
background-color: white;
width: 100%;
border-left-width: 0px;
border-right: none;
}
table.function_list td.shortname {
@ -334,6 +335,19 @@ table.function_list .function_named_args {
text-decoration-color: #bbd3ff;
}
table.function_list td.baseclass {
background-color: white;
color: #a4c7ff;
min-width: 200px;
border-left: none;
border-right: none;
text-align: right;
}
.baseclass {
font-size: 85%;
}
dl.function {
margin-right: 15px;
margin-left: 15px;
@ -429,3 +443,11 @@ pre .url { color: #272fc2; text-decoration: underline; }
background-repeat:no-repeat;
color:transparent;
}
/* Hide some extra documentation noise by default */
.hide_extra {
display: none
}
.show_more {
display: default
}

View File

@ -9,6 +9,17 @@
# if ldoc.custom_css then -- add custom CSS file if configured.
<link rel="stylesheet" href="$(ldoc.custom_css)" type="text/css" />
# end
<script>
function show_extra(id) {
var cur = document.getElementById(id).className
if (cur == "hide_extra")
document.getElementById(id).className = "show_more"
else
document.getElementById(id).className = "hide_extra"
}
</script>
</head>
<body>
@ -151,6 +162,11 @@
<td class="name" $(nowrap)><a href="#$(item.name)">$(dn)</a></td>
# end
<td class="summary">$(M(item.summary,item))</td>
<td class="baseclass" $(nowrap)>
# if item.inherited then
Inherited from $(item.baseclass)
# end
</td>
</tr>
# end -- for items
# last_kind = kind
@ -197,6 +213,9 @@
# if item.display_type then
<span class="proptype">($(item.display_type))</span>
# end
# if item.inherited then
<span class="baseclass" $(nowrap)>&nbsp;&middot;&nbsp;Inherited from $(item.baseclass)</span>
# end
# if ldoc.prettify_files and ldoc.is_file_prettified[item.module.file.filename] then
<a style="float:right;" href="$(ldoc.source_ref(item))">line $(item.lineno)</a>
# end
@ -204,21 +223,6 @@
<dd>
$(M(ldoc.descript(item),item))
# if ldoc.custom_tags then
# for custom in iter(ldoc.custom_tags) do
# local tag = item.tags[custom[1]]
# if tag and not custom.hidden then
# local li,il = use_li(tag)
<h3>$(custom.title or custom[1]):</h3>
<ul>
# for value in iter(tag) do
$(li)$(custom.format and custom.format(value) or M(value))$(il)
# end -- for
# end -- if tag
</ul>
# end -- iter tags
# end
# if show_parms and item.params and #item.params > 0 and not item.hide_params then
# local subnames = module.kinds:type_of(item).subnames
# if subnames then
@ -307,6 +311,43 @@
</ul>
# end -- if usage
<br />
<a class="deprecated_h2" onclick="show_extra('$("item"..item.uid)')">
Click to display more
</a>
<span id=item$(item.uid) class="hide_extra">
# if ldoc.custom_tags then
# for custom in iter(ldoc.custom_tags) do
# local tag = item.tags[custom[1]]
# if tag and not custom.hidden then
# local group_begin, group_end, row_type_begin, row_type_end, group_header = item.get_delim(custom[1])
<h3>$(custom.title or custom[1]):</h3>
<$(group_begin)>
# if group_header then
<tr style='font-weight: bold;'>
# for _, g in ldoc.ipairs(group_header) do
<th>$(g)</th>
# end -- for g
</tr>
# end -- if group_header then
# for value in iter(tag) do
<$(row_type_begin)>$(custom.format and custom.format(value, item, M) or M(value))</$(row_type_end)>
# local sub_values, sub_custom = item.get_auto_params(custom[1], value)
# if sub_values then
<ul>
# for _, value in ldoc.ipairs(sub_values) do
<li>$(sub_custom.format(value, item, M))</li>
# end -- for auto_params
</ul>
# end -- if item.auto_params
# end -- for
</$(group_end)>
# end -- if tag
# end -- iter tags
# end -- ldoc.custom_tags
</span>
</dd>
# end -- for items
# last_kind = kind