diff --git a/docs/common/object.ldoc b/docs/common/object.ldoc index df7227630..ed21bedac 100644 --- a/docs/common/object.ldoc +++ b/docs/common/object.ldoc @@ -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 diff --git a/docs/common/wibox.ldoc b/docs/common/wibox.ldoc index a48b75302..44329ec03 100644 --- a/docs/common/wibox.ldoc +++ b/docs/common/wibox.ldoc @@ -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 diff --git a/docs/common/widget.ldoc b/docs/common/widget.ldoc index d2483aff3..b2a3b0eee 100644 --- a/docs/common/widget.ldoc +++ b/docs/common/widget.ldoc @@ -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 diff --git a/docs/config.ld b/docs/config.ld index 76508b46e..2920a6828 100644 --- a/docs/config.ld +++ b/docs/config.ld @@ -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..""..(p.markdown and md("`"..content.."`") or content).."" + end + return ret .. ""..md(params.description).."" + else + if params.name then + ret = ''.. + md("`"..params.name.value.."`").. + " " + end + + if params.type then + ret = ret .. '('.. + md("`"..params.type.value.."`").. + ")" + 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 = ""..md("`"..last.."`").."Fallback when "..md("`"..item.name.."`").. + " isn't set." + + for _, fallback in ipairs({p.fallback1, p.fallback2, p.fallback3, p.fallback4 }) do + ret = ret .. "".. + ""..md("`"..fallback.value.."`").."Fallback when "..md("`"..last.."`").. + " isn't set." + 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. diff --git a/docs/ldoc.css b/docs/ldoc.css index 3e3956415..04aa7ae88 100644 --- a/docs/ldoc.css +++ b/docs/ldoc.css @@ -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 +} diff --git a/docs/ldoc.ltp b/docs/ldoc.ltp index eebb6b436..ea1b4a7e4 100644 --- a/docs/ldoc.ltp +++ b/docs/ldoc.ltp @@ -9,6 +9,17 @@ # if ldoc.custom_css then -- add custom CSS file if configured. # end + + @@ -151,6 +162,11 @@ $(dn) # end $(M(item.summary,item)) + +# if item.inherited then + Inherited from $(item.baseclass) +# end + # end -- for items # last_kind = kind @@ -197,6 +213,9 @@ # if item.display_type then ($(item.display_type)) # end +# if item.inherited then +  · Inherited from $(item.baseclass) +# end # if ldoc.prettify_files and ldoc.is_file_prettified[item.module.file.filename] then line $(item.lineno) # end @@ -204,21 +223,6 @@
$(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) -

$(custom.title or custom[1]):

- -# 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 @@ # end -- if usage +
+ + Click to display more + + + +# 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]) +

$(custom.title or custom[1]):

+ <$(group_begin)> +# if group_header then + +# for _, g in ldoc.ipairs(group_header) do + $(g) +# end -- for g + +# 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)) +# local sub_values, sub_custom = item.get_auto_params(custom[1], value) +# if sub_values then + +# end -- if item.auto_params +# end -- for + +# end -- if tag +# end -- iter tags +# end -- ldoc.custom_tags +
+
# end -- for items # last_kind = kind