diff --git a/CMakeLists.txt b/CMakeLists.txt
index 370f611d4..c05a7fbc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -292,7 +292,7 @@ if(GENERATE_DOC)
configure_file(${SOURCE_DIR}/docs/ldoc.ltp ${BUILD_DIR}/docs COPYONLY)
add_custom_target(ldoc ALL
- DEPENDS ${BUILD_DIR}/doc/index.html
+ DEPENDS ${BUILD_DIR}/doc/index.html DOC_EXAMPLES_PPOSTPROCESS_CLEANUP
)
if (STRICT_TESTS)
diff --git a/build-utils/check_for_invalid_requires.lua b/build-utils/check_for_invalid_requires.lua
index 1c9cd29c7..d0adad300 100755
--- a/build-utils/check_for_invalid_requires.lua
+++ b/build-utils/check_for_invalid_requires.lua
@@ -62,7 +62,10 @@ local allowed_deps = {
naughty = true,
},
-- TODO: Get rid of these
- ["gears.surface"] = { ["wibox.hierarchy"] = true },
+ ["gears.surface"] = {
+ ["wibox.hierarchy"] = true,
+ beautiful = true,
+ },
}
-- Turn "foo.bar.baz" into "foo.bar". Returns nil if there is nothing more to
diff --git a/dbus.c b/dbus.c
index f339fcddc..97069858c 100644
--- a/dbus.c
+++ b/dbus.c
@@ -19,7 +19,14 @@
*
*/
-/** awesome D-Bus API
+/** A deprecated low-level D-Bus API **DO NOT USE**.
+ *
+ * `lgi.GDBus` is always better. This module will eventually be removed.
+ * If it ever breaks due to an upstream API change, it wont be fixed.
+ *
+ * It still exists for compatibility reasons since some user have used it
+ * in the past.
+ *
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @module dbus
@@ -798,10 +805,10 @@ luaA_dbus_disconnect_signal(lua_State *L)
* @param path A string with the dbus path.
* @param interface A string with the dbus interface.
* @param method A string with the dbus method name.
- * @param type_1st_arg type of 1st argument
- * @param value_1st_arg value of 1st argument
- * @param type_2nd_arg type of 2nd argument
- * @param value_2nd_arg value of 2nd argument
+ * @param type_1st_arg Type of 1st argument
+ * @param value_1st_arg Value of 1st argument
+ * @param type_2nd_arg Type of 2nd argument
+ * @param value_2nd_arg Value of 2nd argument
* ... etc
* @function emit_signal
*/
diff --git a/docs/05-awesomerc.md.lua b/docs/05-awesomerc.md.lua
index 50965a470..d49fee9cb 100644
--- a/docs/05-awesomerc.md.lua
+++ b/docs/05-awesomerc.md.lua
@@ -324,6 +324,8 @@ rc_lua:close()
table.insert(output_script, "-- @script rc.lua")
+table.insert(output_script, "-- @usebeautiful beautiful.awesome_icon")
+table.insert(output_script, "-- @usebeautiful beautiful.wallpaper")
rc_script = assert(io.open(rc_script, "w"))
rc_script:write(table.concat(output_script, "\n"))
diff --git a/docs/89-NEWS.md b/docs/89-NEWS.md
index 18d315cb1..4e19739fe 100644
--- a/docs/89-NEWS.md
+++ b/docs/89-NEWS.md
@@ -76,6 +76,10 @@ This document was last updated at commit v4.3-197-g9085ed631.
old behavior, use `awful.rules.rules = {}; awful.rules.rules = my_new_rules`.
* `client:relative_move()` now default `nil` values to zero. The previous
behavior made no sense.
+ * The tasklist and taglist widgets are no longer directly an instance of
+ it's main layout. Use the `base_layout` property to access the layout.
+ This allows to replace the layout at runtime. The previous behavior
+ was undocumented.
# Awesome window manager framework version 4.3 changes
diff --git a/docs/common/client_theme.ldoc b/docs/common/client_theme.ldoc
index 672b41b37..f62085619 100644
--- a/docs/common/client_theme.ldoc
+++ b/docs/common/client_theme.ldoc
@@ -344,6 +344,21 @@
* @see request::border
*/
+/**
+ * The client border width for the fullscreen clients.
+ *
+ * This is the fallback if the more stateful version, like
+ * `beautiful.border_width_fullscreen_urgent` isn't set.
+ *
+ * @beautiful beautiful.border_width_fullscreen
+ * @param integer
+ * @see request::border
+ * @see beautiful.border_width_fullscreen_active
+ * @see beautiful.border_width_fullscreen_normal
+ * @see beautiful.border_width_fullscreen_urgent
+ * @see beautiful.border_width_fullscreen_new
+ */
+
/**
* The client opacity for the normal clients.
*
@@ -391,7 +406,6 @@
*
* @beautiful beautiful.opacity_floating_normal
* @param[opt=1] number
- * @see request::border
*/
/**
@@ -424,6 +438,21 @@
* @see request::border
*/
+/**
+ * The client opacity for the floating clients.
+ *
+ * A number between 0 and 1. This is the fallback if the more stateful
+ * variables, like `beautiful.opacity_floating_new` are not set.
+ *
+ * @beautiful beautiful.opacity_floating
+ * @param[opt=1] number
+ * @see request::border
+ * @see beautiful.opacity_floating_normal
+ * @see beautiful.opacity_floating_active
+ * @see beautiful.opacity_floating_urgent
+ * @see beautiful.opacity_floating_new
+ */
+
/**
* The client opacity for the normal maximized clients.
*
@@ -431,7 +460,6 @@
*
* @beautiful beautiful.opacity_maximized_normal
* @param[opt=1] number
- * @see request::border
*/
/**
@@ -463,6 +491,22 @@
* @param[opt=1] number
* @see request::border
*/
+
+/**
+ * The client opacity for the maximized clients.
+ *
+ * A number between 0 and 1. This is the fallback if a more stateful
+ * variable, like `beautiful.opacity_maximized_urgent`, isn't set.
+ *
+ * @beautiful beautiful.opacity_maximized
+ * @param[opt=1] number
+ * @see request::border
+ * @see beautiful.opacity_maximized_normal
+ * @see beautiful.opacity_maximized_active
+ * @see beautiful.opacity_maximized_urgent
+ * @see beautiful.opacity_maximized_new
+ */
+
/**
* The client opacity for the normal fullscreen clients.
*
@@ -470,7 +514,6 @@
*
* @beautiful beautiful.opacity_fullscreen_normal
* @param[opt=1] number
- * @see request::border
*/
/**
@@ -503,4 +546,21 @@
* @see request::border
*/
+/**
+ * The client opacity for the fullscreen clients.
+ *
+ * A number between 0 and 1. This is the fallback if the variables
+ * for more stateful versions, like `beautiful.opacity_fullscreen_urgent`,
+ * are not set.
+ *
+ * @beautiful beautiful.opacity_fullscreen
+ * @param[opt=1] number
+ * @see request::border
+ * @see beautiful.opacity_fullscreen_new
+ * @see beautiful.opacity_fullscreen_urgent
+ * @see beautiful.opacity_fullscreen_active
+ * @see beautiful.opacity_fullscreen_normal
+ */
+
+
/*
diff --git a/docs/common/cobject.ldoc b/docs/common/cobject.ldoc
index b8bf3d6f2..f449d4752 100644
--- a/docs/common/cobject.ldoc
+++ b/docs/common/cobject.ldoc
@@ -1,9 +1,11 @@
*/
/** Disconnect from a signal.
+ *
* @tparam string name The name of the signal.
* @tparam function func The callback that should be disconnected.
* @staticfct disconnect_signal
+ * @noreturn
*/
/** Emit a signal.
@@ -13,12 +15,14 @@
* function receives the object as first argument and then any extra
* arguments that are given to emit_signal().
* @staticfct emit_signal
+ * @noreturn
*/
/** Connect to a signal.
* @tparam string name The name of the signal.
* @tparam function func The callback to call when the signal is emitted.
* @staticfct connect_signal
+ * @noreturn
*/
/*
diff --git a/docs/common/fixed.ldoc b/docs/common/fixed.ldoc
index 359fd2ad7..365b161f9 100644
--- a/docs/common/fixed.ldoc
+++ b/docs/common/fixed.ldoc
@@ -68,6 +68,7 @@
--- Reset the layout. This removes all widgets from the layout.
-- @method reset
+-- @noreturn
-- @emits widget::reset
-- @emitstparam widget::reset widget self The layout.
-- @interface layout
diff --git a/docs/common/notification_rules_index.ldoc b/docs/common/notification_rules_index.ldoc
index 35fc30f79..1387c2fdb 100644
--- a/docs/common/notification_rules_index.ldoc
+++ b/docs/common/notification_rules_index.ldoc
@@ -37,6 +37,7 @@
--
The widget template used to represent the notification
--
diff --git a/docs/common/object.ldoc b/docs/common/object.ldoc
index ed21bedac..8eb477e1c 100644
--- a/docs/common/object.ldoc
+++ b/docs/common/object.ldoc
@@ -3,6 +3,8 @@
-- @tparam string name The name of the signal.
-- @tparam function func The callback that should be disconnected.
-- @method disconnect_signal
+-- @treturn boolean `true` when the function was disconnected or `false` if it
+-- wasn't found.
-- @baseclass gears.object
--- Emit a signal.
@@ -12,12 +14,14 @@
-- function receives the object as first argument and then any extra
-- arguments that are given to emit_signal().
-- @method emit_signal
+-- @noreturn
-- @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
+-- @noreturn
-- @baseclass gears.object
--- Connect to a signal weakly.
@@ -31,4 +35,5 @@
-- @tparam string name The name of the signal.
-- @tparam function func The callback to call when the signal is emitted.
-- @method weak_connect_signal
+-- @noreturn
-- @baseclass gears.object
diff --git a/docs/common/signals.ldoc b/docs/common/signals.ldoc
index 2c636169b..b8f1a9439 100644
--- a/docs/common/signals.ldoc
+++ b/docs/common/signals.ldoc
@@ -10,7 +10,8 @@
--
-- @tparam string name The name of the signal
-- @tparam function func The function to attach
--- @function naughty.connect_signal
+-- @noreturn
+-- @staticfct naughty.connect_signal
-- @usage naughty.connect_signal("added", function(notif)
-- -- do something
-- end)
@@ -18,10 +19,11 @@
--- Emit a module signal.
-- @tparam string name The signal name.
-- @param ... The signal callback arguments
--- @function naughty.emit_signal
+-- @noreturn
+-- @staticfct naughty.emit_signal
--- Disconnect a signal from a source.
-- @tparam string name The name of the signal
-- @tparam function func The attached function
--- @function naughty.disconnect_signal
+-- @staticfct naughty.disconnect_signal
-- @treturn boolean If the disconnection was successful
diff --git a/docs/common/wibox.ldoc b/docs/common/wibox.ldoc
index dc46c6ea8..ea9d40f7c 100644
--- a/docs/common/wibox.ldoc
+++ b/docs/common/wibox.ldoc
@@ -2,7 +2,9 @@
--
-- @baseclass wibox
-- @property border_width
--- @param integer
+-- @tparam[opt=0] integer border_width
+-- @propertyunit pixel
+-- @negativeallowed false
-- @propemits false false
--- Border color.
@@ -25,21 +27,22 @@
--
-- @baseclass wibox
-- @property border_color
--- @param string
+-- @tparam[opt=beautiful.fg_normal] string border_color
-- @propemits false false
--- On top of other windows.
--
-- @baseclass wibox
-- @property ontop
--- @param boolean
+-- @tparam[opt=false] boolean ontop
-- @propemits false false
--- The mouse cursor.
--
-- @baseclass wibox
-- @property cursor
--- @param string
+-- @tparam[opt=nil] string|nil cursor
+-- @propertytype nil Do not change the mouse cursor.
-- @see mouse
-- @propemits false false
@@ -47,21 +50,23 @@
--
-- @baseclass wibox
-- @property visible
--- @param boolean
+-- @tparam[opt=false] boolean visible
-- @propemits false false
--- The opacity of the wibox, between 0 and 1.
--
-- @baseclass wibox
-- @property opacity
--- @tparam number opacity (between 0 and 1)
+-- @tparam[opt=true] number opacity
+-- @rangestart 0.0
+-- @rangestop 1.0
-- @propemits false false
--- The window type (desktop, normal, dock, ...).
--
-- @baseclass wibox
-- @property type
--- @param string
+-- @tparam[opt=""] string type
-- @see client.type
-- @propemits false false
@@ -69,38 +74,49 @@
--
-- @baseclass wibox
-- @property x
--- @param integer
+-- @tparam[opt=0] integer x
+-- @propertyunit pixel
+-- @negativeallowed true
-- @propemits false false
--- The y coordinates.
--
-- @baseclass wibox
-- @property y
--- @param integer
+-- @tparam[opt=0] integer y
+-- @propertyunit pixel
+-- @negativeallowed true
-- @propemits false false
--- The width of the wibox.
--
-- @baseclass wibox
-- @property width
--- @param width
+-- @tparam[opt=1] integer width
+-- @propertyunit pixel
+-- @rangestart 1
+-- @negativeallowed false
-- @propemits false false
--- The height of the wibox.
--
-- @baseclass wibox
-- @property height
--- @param height
+-- @tparam[opt=1] integer height
+-- @propertyunit pixel
+-- @rangestart 1
+-- @negativeallowed false
-- @propemits false false
--- The wibox screen.
--
-- @baseclass wibox
-- @property screen
--- @param screen
+-- @tparam screen screen
+-- @propertydefault The screen which contains `0x0`.
-- @propemits true false
---- The wibox's `drawable`.
+-- The wibox's `drawable`.
--
-- @baseclass wibox
-- @property drawable
@@ -110,14 +126,15 @@
--- The widget that the `wibox` displays.
-- @baseclass wibox
-- @property widget
--- @param widget
+-- @tparam[opt=nil] widget|nil widget
-- @propemits true false
--- The X window id.
--
-- @baseclass wibox
-- @property window
--- @param string
+-- @tparam string window
+-- @propertydefault Autogenerated.
-- @see client.window
-- @propemits false false
@@ -129,7 +146,8 @@
--
-- @baseclass wibox
-- @property shape_bounding
--- @param surface._native
+-- @tparam surface._native shape_bounding
+-- @propertydefault Fill all pixels.
-- @propemits false false
-- @see shape
@@ -140,7 +158,8 @@
--
-- @baseclass wibox
-- @property shape_clip
--- @param surface._native
+-- @tparam surface._native shape_clip
+-- @propertydefault Fill all pixels.
-- @propemits false false
-- @see shape
@@ -152,7 +171,8 @@
--
-- @baseclass wibox
-- @property shape_input
--- @param surface._native
+-- @tparam surface._native shape_input
+-- @propertydefault Fill all pixels.
-- @propemits false false
-- @see input_passthrough
@@ -160,7 +180,7 @@
--
-- @baseclass wibox
-- @property shape
--- @tparam gears.shape shape
+-- @tparam[opt=gears.shape.rectangle] shape shape
-- @propemits true false
-- @see gears.shape
@@ -174,7 +194,7 @@
--
-- @baseclass wibox
-- @property input_passthrough
--- @param[opt=false] boolean
+-- @tparam[opt=false] boolean input_passthrough
-- @see shape_input
-- @propemits true false
@@ -182,15 +202,17 @@
--
-- @baseclass wibox
-- @property buttons
--- @param buttons_table A table of buttons objects, or nothing.
+-- @tparam[opt={}] table buttons A table of buttons objects, or nothing.
+-- @tablerowtype A list of `awful.button`s.
-- @propemits false false
--- 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.
+-- @tparam[opt=nil] table|nil geo A table with coordinates to modify. If
+-- nothing is specified, it only returns the current geometry.
+-- @treturn table A table with wibox coordinates and geometry.
-- @method geometry
-- @emits property::geometry When the geometry change.
-- @emitstparam property::geometry table geo The geometry table.
@@ -205,36 +227,18 @@
-- the side of the screen).
--
-- @baseclass wibox
--- @param strut A table with new strut, or nothing
-- @return The wibox strut in a table.
-- @method struts
+-- @tparam table struts A table with new strut, or nothing.
-- @see client.struts
-- @emits property::struts
---- The default background color.
---
--- The background color can be transparent. If there is a
--- compositing manager such as compton, then it will be
--- real transparency and may include blur (provided by the
--- compositor). When there is no compositor, it will take
--- a picture of the wallpaper and blend it.
---
--- @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
-
--- 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
+-- @noreturn
--- The background of the wibox.
--
@@ -246,8 +250,8 @@
--
-- @baseclass wibox
-- @property bg
--- @tparam c The background to use. This must either be a cairo pattern object,
--- nil or a string that gears.color() understands.
+-- @tparam[opt=beautiful.bg_normal] color bg The background to use. This
+-- must either be a cairo pattern object, nil or a string that gears.color() understands.
-- @see gears.color
-- @propemits true false
-- @usebeautiful beautiful.bg_normal The default (fallback) bg color.
@@ -257,18 +261,17 @@
-- 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.
--
--- @tparam gears.suface|string|function image A background image or a function.
-- @baseclass wibox
-- @property bgimage
+-- @tparam[opt=nil] image|nil bgimage
-- @see gears.surface
-- @propemits true false
--- The foreground (text) of the wibox.
--- @tparam color 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
+-- @tparam[opt=beautiful.fg_normal] color fg
-- @see gears.color
-- @propemits true false
-- @usebeautiful beautiful.fg_normal The default (fallback) fg color.
diff --git a/docs/common/widget.ldoc b/docs/common/widget.ldoc
index 36e994d5f..7330059b6 100644
--- a/docs/common/widget.ldoc
+++ b/docs/common/widget.ldoc
@@ -11,41 +11,58 @@
--- Get or set the children elements.
-- @property children
--- @tparam table children The children.
+-- @tparam table children
+-- @tablerowtype A list of `widget`s.
-- @baseclass wibox.widget
+-- @see all_children
--- Get all direct and indirect children widgets.
-- This will scan all containers recursively to find widgets
-- Warning: This method it prone to stack overflow id the widget, or any of its
-- children, contain (directly or indirectly) itself.
-- @property all_children
--- @tparam table children The children.
+-- @tparam table all_children
+-- @tablerowtype A list of `widget`s.
-- @baseclass wibox.widget
+-- @see children
--- 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
+-- @tparam table args An array containing the widgets disposition
-- @method setup
+-- @noreturn
-- @baseclass wibox.widget
--- Force a widget height.
-- @property forced_height
--- @tparam number|nil height The height (`nil` for automatic)
+-- @tparam number|nil forced_height
+-- @propertytype nil Let the layout decide the height. Usually using the widget
+-- native height.
+-- @propertytype number Enforce a number of pixels.
+-- @negativeallowed false
-- @baseclass wibox.widget
+-- @see forced_width
--- Force a widget width.
-- @property forced_width
--- @tparam number|nil width The width (`nil` for automatic)
+-- @tparam number|nil forced_width
+-- @propertytype nil Let the layout decide the width. Usually using the widget
+-- native width.
+-- @propertytype number Enforce a number of pixels.
+-- @negativeallowed false
-- @baseclass wibox.widget
+-- @see forced_height
--- The widget opacity (transparency).
-- @property opacity
--- @tparam[opt=1] number opacity The opacity (between 0 and 1)
+-- @tparam[opt=1] number opacity.
+-- @rangestart 0.0
+-- @rangestop 1.0
-- @baseclass wibox.widget
--- The widget visibility.
-- @property visible
--- @param boolean
+-- @tparam[opt=true] boolean visible
-- @baseclass wibox.widget
--- The widget buttons.
@@ -53,13 +70,15 @@
-- The table contains a list of `awful.button` objects.
--
-- @property buttons
--- @param table
+-- @tparam[opt={}] table buttons
-- @see awful.button
+-- @tablerowtype A list of `awful.button`.
-- @baseclass wibox.widget
--- Add a new `awful.button` to this widget.
-- @tparam awful.button button The button to add.
-- @method add_button
+-- @noreturn
-- @baseclass wibox.widget
--- Emit a signal and ensure all parent widgets in the hierarchies also
@@ -69,6 +88,7 @@
-- @param ... Other arguments
-- @baseclass wibox.widget
-- @method emit_signal_recursive
+-- @noreturn
--- When the layout (size) change.
-- This signal is emitted when the previous results of `:layout()` and `:fit()`
@@ -96,7 +116,7 @@
-- @tparam number button The button number.
-- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift)
-- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
+-- @{wibox:find_widgets} for the position that the mouse hit.
-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
-- the widget.
-- @tparam widget find_widgets_result.widget The widget being displayed.
@@ -127,7 +147,7 @@
-- @tparam number button The button number.
-- @tparam table mods The modifiers (mod4, mod1 (alt), Control, Shift)
-- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
+-- @{wibox:find_widgets} for the position that the mouse hit.
-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
-- the widget.
-- @tparam widget find_widgets_result.widget The widget being displayed.
@@ -152,7 +172,7 @@
-- @signal mouse::enter
-- @tparam table self The current object instance itself.
-- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
+-- @{wibox:find_widgets} for the position that the mouse hit.
-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
-- the widget.
-- @tparam widget find_widgets_result.widget The widget being displayed.
@@ -177,7 +197,7 @@
-- @signal mouse::leave
-- @tparam table self The current object instance itself.
-- @tparam table find_widgets_result The entry from the result of
--- @{wibox.drawable:find_widgets} for the position that the mouse hit.
+-- @{wibox:find_widgets} for the position that the mouse hit.
-- @tparam wibox.drawable find_widgets_result.drawable The drawable containing
-- the widget.
-- @tparam widget find_widgets_result.widget The widget being displayed.
diff --git a/docs/config.ld b/docs/config.ld
index 2e51ce765..8ab55afe1 100644
--- a/docs/config.ld
+++ b/docs/config.ld
@@ -1,24 +1,27 @@
local args = ...
+local ldoc = nil
+-- luacheck: globals new_type
-- Configuration file for ldoc
-project='awesome'
-title='awesome API documentation'
-description='API documentation for awesome, a highly configurable X window manager (version @AWESOME_VERSION@).'
+project='awesome' -- luacheck: globals project
+title='awesome API documentation' -- luacheck: globals title
+description='API documentation for awesome, a highly configurable X window manager (version @AWESOME_VERSION@).' -- luacheck: globals description
--- More on it: https://github.com/stevedonovan/LDoc/blob/master/doc/doc.md#markdown-support
-format='discount'
-dir='../doc'
+format='discount' -- luacheck: globals format
+dir='../doc' -- luacheck: globals dir
-- Make the docs prettier
-pretty='lua'
-style=true
-template=true
-backtick_references=true
-merge=true
-use_markdown_titles=true
-wrap=true
+pretty='lua' -- luacheck: globals pretty
+style=true -- luacheck: globals style
+template=true -- luacheck: globals template
+backtick_references=true -- luacheck: globals backtick_references
+merge=true -- luacheck: globals merge
+use_markdown_titles=true -- luacheck: globals use_markdown_titles
+wrap=true -- luacheck: globals wrap
+
+ -- luacheck: globals full_description
full_description = [[
Welcome to the documentation for the Awesome window manager. Below you find an
overview of the individual parts which links to the full documentation.
@@ -31,23 +34,25 @@ should be useful for you.
### Default configuration components name:
-
## Major libraries
@@ -90,50 +95,903 @@ topics={
'89-NEWS.md',
}
+-- Rather han copy paste this hundreds of time, unify these special type
+-- descriptions.
+local type_fallback_description = {
+ image = {
+ "string Interpreted as a path to an image file." ,
+ "string A valid SVG content." ,
+ "cairo A cairo image surface: Directly used as-is." ,
+ "librsvg A librsvg handle object: Directly used as-is." ,
+ "nil Unset the image." ,
+ },
+ color = {
+ "string An hexadecimal color code, such as `\"#ff0000\"` for red." ,
+ "string A color name, such as `\"red\"`." ,
+ "table A [gradient table](../theme_related_libraries/gears.color.html)." ,
+ "cairo.pattern Any valid [Cairo pattern](https://cairographics.org/manual/cairo-cairo-pattern-t.html)." ,
+ "cairo.pattern A texture build from an image by [gears.color.create\\_png\\_pattern](../theme_related_libraries/gears.color.html#create_png_pattern)" ,
+ },
+ shape = {
+ "gears.shape Like `gears.shape.circle`",
+ "function This can be used for custom shapes or to set parameters of existing shapes.",
+ },
+ screen = {
+ "screen A valid screen object such as retured by `awful.screen.focused()` or `mouse.screen`.",
+ "integer A screen global id. Avoid using this since they are unsorted.",
+ "string The `\"primary\"` value is also valid.",
+ },
+ font = {
+ "string A Pango [font description](../widgets/wibox.widget.textbox.html#font).",
+ "string An [XFT string](https://wiki.archlinux.org/title/X_Logical_Font_Description), such as `\"-*-dejavu sans mono-medium-r-normal--*-80-*-*-*-*-iso10646-1\"`.",
+
+ },
+ template = {
+ "table A table containing a widget tree definition. WARNING: This is really a table"..
+ " and **NOT** a widget object. Use the `widget = come.class.here` to define the "..
+ " topmost class rather than construct an instance."
+ },
+ placement = {
+ "function A custom callback to generate *and set* the geometry.",
+ "placement Any of the `awful.placement` function or constructs."
+ }
+}
+
+-- Document the "common" function prototypes. Some common types, such as
+-- the client layouts, the shapes and placements are just glorified functions.
+local callback_fallback_description = {
+ shape = {
+ {"functionparam", "cairo.context", "cr", "A [Cairo context](https://cairographics.org/manual/cairo-cairo-t.html)"},
+ {"functionparam", "number", "width", "The area width."},
+ {"functionparam", "number", "height", "The area height."},
+ },
+ placement = {
+ {"functionreturn", "table", "A table with an `x`, `y`, `width` and `height` keys."},
+ {"functionparam", "object", "obj", "Any object with a `geometry` property or method."},
+ {"functionparam", "table", "args", "The `placement` arguments. See `awful.placement` for a complete list."},
+ },
+}
+
+-- Try to use a single name for common types. For example, mixing `color` and
+-- `gears.color` (which is *not* a type) is confusing. It also allows the
+-- type description to be auto-generated from `type_fallback_description`.
+local type_name_linting = {
+ ["gears.color"] = "color",
+ ["gears.shape"] = "shape",
+ ["wibox.widget"] = "widget",
+ ["gears.surface"] = "image",
+ ["surface"] = "image",
+ ["awful.placement"] = "placement",
+ ["double"] = "number",
+ ["float"] = "number",
+ ["bool"] = "boolean",
+}
+
+local metadata_tags = {
+ "propertyunit", "rangestart", "rangestop", "negativeallowed",
+}
+
+local databases, named_tags, item_id, is_init = {}, {}, 1, false
+local all_theme_vars, delayed_collect = nil, {}
+
+local function collect_item_common(tab, mod, item)
+ tab[item.name] = tab[item.name] or {}
+
+ local var = tab[item.name]
+ var[mod.name] = var[mod.name] or {}
+ var[mod.name][#var[mod.name] + 1] = item
+end
+
+--- Add another custom tag **value** to an existing item.
+-- @tparam string tag_data The raw/unparsed string for the
+-- tag. It will be parsed like any other tags.
+local function add_custom_tag_common(item, tag_name, meta_tag, tag_data)
+ item.tags = item.tags or {}
+
+ item.tags[tag_name] = item.tags[tag_name] or {}
+
+ item.tags[tag_name][#item.tags[tag_name] + 1] = tag_data
+
+ if meta_tag.collect_callback then
+ delayed_collect[#delayed_collect+1] = {item, item.module, tag_name, tag_data}
+ end
+end
+
+-- Wrap the global `new_type` to allow us to extend what types can do, the
+-- same is done below for custom tags.
+local function create_type(args)
+ new_type(args.name, args.title, args.project_level, args.subfield_title)
+
+ databases[args.name] = databases[args.name] or {}
+ databases[args.name].collect = args.collect_callback
+ databases[args.name].finish = args.finish_callback
+
+ return args
+end
+
+-- Add the @usebeautiful from the optional/default value.
+local function auto_add_usebeautiful(item)
+ local vars, var_names = {}, {}
+
+ -- Datamine the default values to autogenerate the @usebeautiful.
+ for parm in ldoc.modules.iter(item.params) do
+ for p in ldoc.modules.iter(item:subparam(parm)) do
+ local def = item:default_of_param(p)
+
+ if def and def ~= true then
+ for var in def:gmatch("beautiful[.][a-z_]+") do
+ if not var_names[var] then
+ vars[#vars+1] = var
+ end
+ var_names[var] = true
+ end
+ end
+ end
+ end
+
+ for _, var in ipairs(vars) do
+ named_tags.usebeautiful:add_to_item(item, var)
+ end
+end
+
+-- Handle both manually specified callback prototypes and common ones.
+local function parse_properties_function_metadata(item, types)
+ local raw_input = item.tags["functionnoparam"] and {} or item.tags["functionparam"]
+ local raw_output = item.tags["functionnoreturn"] and {} or item.tags["functionreturn"]
+ local fallback, input, output = true, {}, {}
+
+ for _, arg in ipairs(raw_input or {}) do
+ input[#input+1] = item.parsed_tags["functionparam"][arg]
+ fallback = false
+ end
+
+ for _, ret in ipairs(raw_output or {}) do
+ output[#output+1] = item.parsed_tags["functionreturn"][ret]
+ fallback = false
+ end
+
+ local has_in = #input > 0 or item.tags["functionnoparam"] ~= nil
+ local has_out = #output > 0 or item.tags["functionnoreturn"] ~= nil
+
+ if fallback then
+ for type in pairs(types) do
+ if callback_fallback_description[type] then
+ for _, row in ipairs(callback_fallback_description[type]) do
+ local dest = row[1] == "functionparam" and input or output
+
+ dest[#dest+1] = {
+ description = row[#row],
+ type = row[2] and {value = row[2]},
+ name = row[3] and {value = row[3]},
+ }
+ end
+
+ -- Assume the fallback is correct.
+ has_out, has_in = true, true
+ break
+ end
+ end
+ end
+
+ return {
+ input = input,
+ output = output,
+ has_input = has_in,
+ has_output = has_out,
+ }
+end
+
-- The first stereotype are the constructors.
-new_type("constructorfct", "Constructors", false, "Parameters")
-new_type("constructorfct2", "ldoc_skip", false, "Parameters")
+create_type {
+ name = "constructorfct",
+ title = "Constructors",
+ project_level = false,
+ subfield_title = "Parameters",
+ collect_callback = auto_add_usebeautiful,
+}
+
+-- Some constructors like `awful.key` have both a named parameter
+-- syntax and a multiple function parameter syntax.
+create_type {
+ name = "constructorfct2",
+ title = "ldoc_skip",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- Hack to get the functions on top of the signals and properties
-new_type("function", "Functions", false, "Parameters")
+create_type {
+ name = "function",
+ title = "Functions",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- For "classes", use an explicit type for static functions. This allows
-- @function and its implicit cousin to be banned in the CI.
-new_type("staticfct", "Static module functions", false, "Parameters")
+create_type {
+ name = "staticfct",
+ title = "Static module functions",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- Documentation for objects properties
-new_type("property", "Object properties", false, "Type constraints")
+create_type {
+ name = "property",
+ title = "Object properties",
+ project_level = false,
+ subfield_title = "Type constraints",
+ collect_callback = auto_add_usebeautiful,
+ finish_callback = function(item)
+ -- All properties need to have a type. Otherwise they don't render
+ -- properly. Also, because typed properties are kind of the point of
+ -- switching to ldoc in the first place.
+ if (not item.params) or not item.params[1] then
+ print(
+ "WARNING: The ".. item.name .." property from "..item.module.name.." is missing it's type."
+ )
+ return
+ end
+
+ local _, sublist = item:subparam(item.params[1])
+ local type = item:type_of_param(item.params[1])
+
+ -- Force people to use @tparam because it is easier to lint and allows
+ -- multiple types.
+ if (not type) or type == "" then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name.." either "..
+ " doesn't have a type or uses @param instead of @tparam. @tparam is required"..
+ " because it allows multi-type and better default value handling."
+ )
+ end
+
+ if type_name_linting[type] then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " type is `"..type.."`, please use `"..type_name_linting[type].."`."
+ )
+ end
+
+ -- One of the repeated problem we have is the first word of the
+ -- description being removed because it is used as the property name.
+ -- This "rule" might be stupid, but it prevents it from accidentally
+ -- happening again.
+ if item.params[1] ~= item.name:match("[.]?("..item.params[1]..")$") then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name.." @tparam name"..
+ " doesn't match the property name. For linting purpose, please fix this."
+ )
+ end
+
+ local def = item:default_of_param(item.params[1])
+
+ -- Check the default value for obvious mistakes.
+ if def then
+ -- Detect the blatant missing quote marks for string. This is important
+ -- to differentiate variables from string literals.
+ if type == "string" and def:sub(1,1) ~= '"' and def:sub(-1) ~= '"' and not def:find(".") then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " is a string, but the default value is not quoted."
+ )
+ end
+
+ -- If the default value is `nil`, then the property must be nullable.
+ if def == "nil" and not type:find("nil") then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " default value is `nil`, but the type doesn't allow it"
+ )
+ end
+
+ if type == "boolean" and (not (def == "true" or def == "false")) and (not def:find(".")) then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " is a boolean, but is neither `true`, `false` or an alias"
+ )
+ end
+
+ item:add_metadata("Default value", ("%s"):format(def))
+ else
+ -- Properties should have a default value. If they don't or if the
+ -- default depends on the context, then `opt=nil` should be used to
+ -- mute this warning.
+ local auto_opt = nil
+
+ -- Extract the default value from other metadata.
+ if item.tags["propbeautiful"] and item.tags["propbeautiful"][1] then
+ auto_opt = "beautiful."..(item.module.name.."_"..item.name):gsub("[.]", "_")
+ elseif item.tags["usebeautiful"] and item.tags["usebeautiful"][1] then
+ auto_opt = item.tags["usebeautiful"][1]:match("[^ ]+")
+ end
+
+ -- This adds a default value. It works for LDoc 1.4.5, but is a
+ -- private API and might break in the future.
+ if item.tags["propertydefault"] and item.tags["propertydefault"][1] then
+ item:add_metadata(
+ "Default value",
+ ldoc.markup(item.tags["propertydefault"][1])
+ )
+ elseif auto_opt then
+ local mods = item.modifiers[item.parameter]
+
+ if mods then
+ mods[item.params[1]].opt = auto_opt
+ end
+
+ item:add_metadata("Default value", ("%s"):format(auto_opt))
+ elseif not sublist then
+ -- The default could not be determined automatically, it requires
+ -- an explicit `opt=`.
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name,
+ "doesn't have a default value. Add `[opt=value]` to the @tparam"
+ )
+ end
+ end
+
+ local prop_types, prop_type_names, fallback_callback = {}, {}, false
+
+ -- Type validation.
+ do
+ -- Handle the case where a property has multiple types.
+ local metatypes, table_args = {}, {}
+ local prop_has_nil, prop_has_obj = false, false
+
+ -- Make a copy of the table to avoid recursion.
+ for _, t in ipairs(item.tags["propertytype"] or {}) do
+ metatypes[#metatypes+1] = t
+ end
+
+ for t in item:type_of_param(item.params[1]):gmatch('[^|]+') do
+ if type_name_linting[t] then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " type is '"..t.."'. Please use `"..type_name_linting[t].."'"
+ )
+ end
+
+ if not prop_type_names[t] then
+ prop_types[#prop_types+1] = t
+ end
+ prop_type_names[t] = true
+ fallback_callback = fallback_callback or callback_fallback_description[t]
+ prop_has_nil = prop_has_nil or t == "nil"
+ prop_has_obj = prop_has_obj or (t:find('.') and not t:sub(1,5) == "gears")
+ end
+
+ if item.tags["propbeautiful"]
+ and item.tags["propbeautiful"][1]
+ and not prop_type_names["nil"] then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " uses `@propbeautiful`, yet, doesn't have `nil` as a type."
+ )
+ end
+
+ if #item.params == 0 then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " is missing it's `@tparam` section. Please add it."
+ )
+ elseif #item.params > 1 then
+ for i=2, #item.params do
+ local splitted = {}
+
+ for part in item.params[i]:gmatch("[^.]+") do
+ splitted[#splitted+1] = part
+ end
+
+ if #splitted == 1 then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " has a `@tparam` named \""..item.params[i].."\". The only"..
+ " valid name is \"..item.name\""
+ )
+ else
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " has a `@tparam` named \""..item.params[i].."\". This is"..
+ " not valid. It should be `@tparam[opt=...] "..item.name..
+ "."
+ )
+ end
+ end
+ end
+
+ -- Some properties are table with fixed keys.
+ local param,sublist = item:subparam(item.params[1])
+ if sublist then
+ for _, sub_param in pairs(param) do
+ local splitted = {}
+
+ for part in sub_param:gmatch("[^.]+") do
+ splitted[#splitted+1] = part
+ end
+
+ -- The first part should match the property name. If it doesn't,
+ -- then it's unclear what it is.
+ if splitted[1] ~= item.name then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " has additional @tparams with unclear meaning. Please"..
+ " use `@tparam[opt=...] type property_name.subparam Desc...`"
+ )
+ else
+ local rebuilt_name = ""
+
+ for i=2, #splitted do
+ rebuilt_name = rebuilt_name .. ((#rebuilt_name > 0) and "." or "") .. splitted[i]
+ end
+
+ table_args[#table_args+1] = {
+ name = rebuilt_name,
+ default = item:default_of_param(sub_param),
+ type = item:type_of_param(sub_param),
+ description = item.params.map[sub_param],
+ }
+ end
+ end
+ end
+
+ if prop_has_obj and not prop_has_nil then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " has an object type, however it doesn't define the behavior"..
+ " or `nil` (or lack `@nonnullable`)"
+ )
+ end
+
+ local type_map = {}
+
+ for _, typeinfo in ipairs(metatypes) do
+ local parsed = item.parsed_tags["propertytype"][typeinfo]
+ type_map[parsed.typename.value] = type_map[parsed.typename.value] or {}
+ type_map[parsed.typename.value][#type_map[parsed.typename.value]+1] = parsed
+ end
+
+ local warnings = {}
+
+ -- Check if every possible type is described.
+ for _, t in ipairs(prop_types) do
+ if not type_map[t] then
+ -- Auto add description for common types.
+ if type_fallback_description[t] then
+ for _, entry in ipairs(type_fallback_description[t]) do
+ metatypes[#metatypes+1] = entry
+ named_tags.propertytype:add_to_item(item, entry)
+ type_map[t] = type_map[t] or {}
+ type_map[t][#type_map[t]+1] = entry
+ end
+ elseif #prop_types > 1 then
+ local warn = "WARNING: Property", item.name .." from "..item.module.name..
+ " has the undescribed object type \""..t.."\", please add"..
+ " one (or more) `@propertytype "..t.." ` tag."
+ warnings[t] = warnings[t] or {}
+ warnings[t][#warnings[t]+1] = warn
+ end
+ end
+ end
+
+ -- Autofill the meaning of `nil` when there is a fallback `beautiful`
+ -- variable.
+ if prop_type_names["nil"]
+ and (not type_map["nil"])
+ and item.tags["propbeautiful"]
+ and item.tags["propbeautiful"][1] then
+ local modname = item.module.name:gmatch("[^.]+$")()
+ local fallback = "beautiful."..(modname.."_"..item.name):gsub("[.]", "_")
+ local entry = "nil Fallback to the current value of `"..fallback.."`."
+ named_tags.propertytype:add_to_item(item, entry)
+ metatypes[#metatypes+1] = entry
+
+ warnings["nil"] = nil
+ end
+
+ for _, warn in ipairs(warnings) do
+ print(warn)
+ end
+
+ local mt_by_type = {}
+
+ -- Add the metatype section
+ if #metatypes > 0 then
+ local mt = item:add_metadata("Type description")
+
+ for _, typeinfo in ipairs(metatypes) do
+ local parsed = item.parsed_tags["propertytype"][typeinfo]
+ local tmt = mt:add_metadata(
+ ""..parsed.typename.value.."",
+ ldoc.markup(parsed.description)
+ )
+ mt_by_type[parsed.typename.value] = mt_by_type[parsed.typename.value] or {}
+ mt_by_type[parsed.typename.value][#mt_by_type[parsed.typename.value]+1] = tmt
+ end
+ end
+
+ if #table_args > 0 then
+ local mt = mt_by_type["table"] and mt_by_type["table"][1] or item:add_metadata("Table keys")
+ for _, key in ipairs(table_args) do
+ mt:add_metadata(
+ key.name,
+ ldoc.markup(key.description),
+ key.type
+ )
+ end
+ end
+
+ -- Add the function callback parameters section.
+ if prop_type_names["function"] or fallback_callback then
+ local fp = (mt_by_type["function"] and mt_by_type["function"][1] or item):add_metadata("Function prototype")
+
+ local prototype = parse_properties_function_metadata(item, prop_type_names)
+
+ if not prototype.has_input then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " needs either `@functionparam` or `@functionnoparam` if there"..
+ " is none."
+ )
+ elseif #prototype.input == 0 then
+ fp:add_metadata("Parameters:", "The function has no parameters")
+ else
+ local fparams = fp:add_metadata("Parameters")
+ for _, parsed in ipairs(prototype.input) do
+ if (not parsed.name) or (not parsed.type) then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " has a `@functionparam` improperly formatted. The format is "..
+ "` [description]`."
+ )
+ else
+ fparams:add_metadata(
+ parsed.name.value,
+ ldoc.markup(parsed.description),
+ parsed.type.value
+ )
+ end
+ end
+ end
+
+ args = item.tags["functionnoreturn"] and {} or item.tags["functionreturn"]
+
+ if not prototype.has_output then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " needs either `@functionreturn` or `@functionnoreturn` if there"..
+ " is none."
+ )
+ elseif #prototype.output == 0 then
+ fp:add_metadata("Return", "The function returns nothing.")
+ elseif #prototype.output == 1 then
+ fp:add_metadata("Return", ldoc.markup(prototype.output[1].description), prototype.output[1].type.value)
+ else
+ local md = fp:add_metadata("Return")
+ for _, parsed in ipairs(prototype.output) do
+ md:add_metadata(
+ "",
+ ldoc.markup(parsed.description),
+ parsed.type.value
+ )
+ end
+ end
+ end
+
+ -- Handle the case where the table is a list.
+ if #prop_types == 1 and prop_types[1] == "table"
+ and #(item.tags["tablerowtype"] or {}) == 0
+ and #table_args == 0 then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " needs either `@tablerowtype` or additional `@tparam`."
+ )
+ elseif #(item.tags["tablerowtype"] or {}) > 0 then
+ local mt = item:add_metadata("Table content", ldoc.markup(item.tags["tablerowtype"][1]))
+
+ for _, key in ipairs(item.tags["tablerowkey"] or {}) do
+ local parsed = item.parsed_tags["tablerowkey"][key]
+ local type, val, desc = parsed.type.value, parsed.name.value, parsed.description
+ mt:add_metadata(""..val.."", ldoc.markup(desc), type)
+ end
+ end
+ end
+
+ -- Allow the template to be shorter by using a for-loop.
+ local has_start, has_allow_negative = false, false
+ for _, mt in ipairs(metadata_tags) do
+ local tag_desc = named_tags[mt]
+
+ if item.tags[mt] and item.tags[mt][1] then
+ has_start = has_start or mt == "rangestart"
+ has_allow_negative = has_allow_negative or mt == "negativeallowed"
+ local title = tag_desc.title or mt
+ item:add_metadata(title, ldoc.markup(item.tags[mt][1]))
+ end
+ end
+
+ if (prop_type_names["number"] or prop_type_names["integer"]) and not (has_start or has_allow_negative) then
+ print(
+ "WARNING: Property", item.name .." from "..item.module.name..
+ " has numeric type, please add either `@rangestart` or `@negativeallowed false`."
+ )
+ end
+
+ local tdesc = item.params.map[item.params[1]] and item.params.map[item.params[1]] or ""
+
+ -- Auto add the description for "simple" boolean.
+ if #prop_types == 1 and prop_types[1] == "boolean" and tdesc == "" then
+ tdesc = "`true` or `false`."
+ end
+
+ -- Handle custom type description and string "enum".
+ if #(item.tags["propertyvalue"] or {}) > 0 or tdesc ~= "" then
+
+ local mt = item:add_metadata("Valid values", ldoc.markup(tdesc))
+
+ local values, found_default = item.tags["propertyvalue"] or {}, false
+
+ for _, enum_val in ipairs(values) do
+ local parsed = item.parsed_tags["propertyvalue"][enum_val]
+ local val, desc = parsed.value.value, parsed.description
+
+ if val:sub(1,1) ~= '"' or val:sub(#val,#val) ~= '"' then
+ print(
+ "WARNING: Value `"..val.."` from property ".. item.name
+ .." from module "..item.module.name.. "should be a quoted string."
+ )
+ end
+
+ found_default = found_default or val == def
+
+ mt:add_metadata(""..val.."", ldoc.markup(desc))
+ end
+
+ if def and #values > 0 and def:sub(1,9) ~= "beautiful" and not found_default then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " has some `@propertyvalue`, but the default value is not among them."
+ )
+ end
+ end
+
+ -- @return is not displayed for properties, something important
+ -- might have been written there, so it's better to block it
+ if item.tags["return"] or item.tags["treturn"] then
+ print(
+ "WARNING: Property ".. item.name .." from "..item.module.name..
+ " has a `@return`, it is not rendered. Remove it."
+ )
+ end
+ end
+}
+
-- Documentation for objects deprecated properties
-new_type("deprecatedproperty", "Deprecated object properties", false, "Type constraints")
+create_type {
+ name = "deprecatedproperty",
+ title = "Deprecated object properties",
+ project_level = false,
+ subfield_title = "Type constraints",
+}
+
+-- Documentation for objects deprecated methods
+create_type {
+ name = "deprecatedmethod",
+ title = "Deprecated object methods",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- Use a custom type for the methods to bypass the faulty ldoc built-in detection.
-- (yes, the space after Methods *is* on purpose to avoid clashing with ldoc
-- internal "methods" concept)
-new_type("method", "Object methods ", false, "Parameters")
--- New type for signals
-new_type("signal", "Signals", false, "Arguments")
+create_type {
+ name = "method",
+ title = "Object methods ",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
+-- New type for signals.
+local all_signals
+all_signals = create_type {
+ name = "signal",
+ title = "Signals",
+ project_level = false,
+ subfield_title = "Arguments",
+ collection = {},
+ collect_callback = function(item, mod)
+ collect_item_common(all_signals.collection, mod, item)
+ end,
+}
+
-- Deprecated signals.
-new_type("deprecatedsignal", "Deprecated signals", false, "Arguments")
+create_type {
+ name = "deprecatedsignal",
+ title = "Deprecated signals",
+ project_level = false,
+ subfield_title = "Arguments",
+}
+
-- New type for signals connections
-new_type("signalhandler", "Request handlers", false, "Arguments")
+create_type {
+ name = "signalhandler",
+ title = "Request handlers",
+ project_level = false,
+ subfield_title = "Arguments",
+}
+
-- Allow objects to define a set of beautiful properties affecting them
-new_type("beautiful", "Theme variables", false, "Type constraints")
+all_theme_vars = create_type {
+ name = "beautiful",
+ title = "Theme variables",
+ project_level = false,
+ subfield_title = "Type constraints",
+ collection = {},
+ collect_callback = function(item, mod)
+ if item.name:sub(1,4) ~= "beau" then
+ -- This would be a bug.
+ if item.name:match("[.]") then
+ print("WANRING: A beautiful variable is called `", item.name, "`. This name is invalid.")
+ end
+
+ -- This happens because the `ldoc` messes with the name. All variables
+ if item.module.name == "beautiful" then
+ item.name = "beautiful." .. item.name
+ else
+ print(
+ "WARNING: All theme variable need a `beautiful.` prefix. It appears",
+ item.name,
+ " lacks it"
+ )
+ end
+ end
+
+ collect_item_common(all_theme_vars.collection, mod, item)
+
+ -- Those are global variables, there can be only one per name.
+ if all_theme_vars.collection[item.name] then
+ local mod = pairs(all_theme_vars.collection[item.name])(all_theme_vars.collection[item.name])
+
+ if mod ~= item.module.name then
+ print("ERROR: "..item.name, "from", item.module.name, "is already defined in module ", mod)
+ end
+ end
+ end,
+ finish_callback = function(item)
+ if not item.tags["beautiful_used_by"] then
+ -- Every variable should be consumed by something. Better "park" some
+ -- variable in the constructors than leave them disconnected from the
+ -- global model.
+ print("WARNING: ", item.name, "is not used by anything, add @usebeautiful or @propbeautiful")
+ else
+ local prop, mn = nil, item.module.name:match("[.]?([^.]+)$")
+ -- If there is a property with the corresponding name and it doesn't
+ -- mention the `beautiful` variable, that's nearly always a bug.
+ for kind, items in item.module.kinds() do
+ if kind == "Object properties" then
+ for k in items do
+ for k2,v2 in k do
+ if item.name:match("[.]"..mn.."_"..k2.name.."$") then
+ prop = k2
+ break
+ end
+ if prop then break end
+ end
+ break
+ end
+ end
+ end
+
+ if prop then
+ local mention = false
+
+ if prop.tags.propbeautiful then mention = true end
+
+ if (not mention) and prop:default_of_param(prop.params[1]) == item.name then
+ mention = true
+ end
+
+ for _, v in ipairs((not mention) and prop.tags.usebeautiful or {}) do
+ local parsed = prop.parsed_tags.usebeautiful[v]
+ if parsed.name.value == item.name then
+ mention = true
+ break
+ end
+ end
+
+ if not mention then
+ print(
+ "WARNING: `"..item.name.. "` from `"..item.module.name.."` "..
+ "seems to match a property called `"..prop.name.."`. However, "..
+ "there is no mention of this `beautiful` "..
+ "variable in its documentation. Please add `@propbeautiful` or "..
+ "`[opt="..item.module.name.."]"
+ )
+ end
+ end
+ end
+ end
+}
+
-- Put deprecated methods in their own section
-new_type("deprecated", "Deprecated functions", false, "Parameters")
+create_type {
+ name = "deprecated",
+ title = "Deprecated functions",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- For the legacy stateless layout related functions
-new_type("legacylayout", "Layout related functions", false, "Parameters")
+create_type {
+ name = "legacylayout",
+ title = "Layout related functions",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- Have a category for the client layouts
-new_type("clientlayout", "Client layouts", false, "Parameters")
+create_type {
+ name = "clientlayout",
+ title = "Client layouts",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- Source functions for the taglist/tasklist/layoutlist
-new_type("sourcefunction", "List source functions", false)
+create_type {
+ name = "sourcefunction",
+ title = "List source functions",
+ project_level = false,
+}
+
-- Document some callback prototypes
-new_type("callback", "Callback functions prototype", false, "Parameters")
+create_type {
+ name = "callback",
+ title = "Callback functions prototype",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- gears.matcher / awful.rules sources
-new_type("rulesources", "Rule sources", false, "Parameters")
+create_type {
+ name = "rulesources",
+ title = "Rule sources",
+ project_level = false,
+ subfield_title = "Parameters",
+}
+
-- gears.matcher / awful.rules rule components
-new_type("rulecomponent", "Rule components", false, "Type")
+create_type {
+ name = "rulecomponent",
+ title = "Rule components",
+ project_level = false,
+ subfield_title = "Type",
+}
+
-- Filter functions for the taglist/tasklist/layoutlist
-new_type("filterfunction", "List filters", false)
+create_type {
+ name = "filterfunction",
+ title = "List filters",
+ project_level = false,
+}
+
-- Extra client properties available only in awful.rules/spawn constructs
-new_type("clientruleproperty", "Extra properties available in the rules", false, "Type")
+create_type {
+ name = "clientruleproperty",
+ title = "Extra properties available in the rules",
+ project_level = false,
+ subfield_title = "Type",
+}
+
-- Extra *matching* properties for rules.
-new_type("matchingproperty", "Extra matching properties used in rules", false, "Type")
+create_type {
+ name = "matchingproperty",
+ title = "Extra matching properties used in rules",
+ project_level = false,
+ subfield_title = "Type",
+}
-- Simulate the default "params" parser format, except the optional "[]" section
-- needs a space.
@@ -220,16 +1078,18 @@ local function default_format_callback(self, params, _, md)
end
-- Generate a format function.
-local function default_format(self, callback)
+local function default_format(self, callback, name)
return function(raw, item, md)
- return (callback or default_format_callback)(
- self, parse_custom_tags(raw, self.params or {}), item, md
- )
+ local p = name and item.parsed_tags and item.parsed_tags[name] and item.parsed_tags[name][raw]
+
+ if not p then
+ p = parse_custom_tags(raw, self.params or {})
+ end
+
+ return (callback or default_format_callback)(self, p, 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.
@@ -246,9 +1106,28 @@ add_custom_tag = function(args)
custom_tags = custom_tags or {}
+ databases[name] = databases[name] or {}
+ databases[name].collect = args.collect_callback
+
local f = args.format
- args.format = default_format(args, f)
+ args.format = default_format(args, f, name)
+
+ function args:add_to_item(item, tag_value)
+ add_custom_tag_common(item, name, args, tag_value)
+
+ local parsed = parse_custom_tags(tag_value, args.params or {})
+
+ if parsed then
+ item.parsed_tags = item.parsed_tags or {}
+ item.parsed_tags[name] = item.parsed_tags[name] or {}
+ item.parsed_tags[name][tag_value] = parsed
+ end
+
+ item.has_show_more = item.has_show_more or (not args.hidden)
+
+ return parsed
+ end
custom_tags[#custom_tags+1] = args
named_tags[name] = args
@@ -284,7 +1163,17 @@ add_custom_tag {
{
name = "name"
}
- }
+ },
+ collect_callback = function(item, mod, tag, value)
+ local parsed = parse_custom_tags(value, named_tags.emits.params)
+
+ all_signals.collection[parsed.name.value] = all_signals.collection[parsed.name.value] or {}
+
+ local var = all_signals.collection[parsed.name.value]
+
+ var[mod.name] = var[mod.name] or {}
+ var[mod.name][#var[mod.name] + 1] = item
+ end
}
-- Avoid repetitive boilerplate code for property signals.
@@ -345,7 +1234,25 @@ add_custom_tag {
name = "name",
markdown = true,
}
- }
+ },
+ collect_callback = function(item, mod, tag, value)
+ local params = parse_custom_tags(value, named_tags.usebeautiful.params)
+
+ if all_theme_vars.collection[params.name.value] then
+ local sig_mods = all_theme_vars.collection[params.name.value]
+ local _, themed_items = pairs(sig_mods)(sig_mods)
+ local themed_item = themed_items[1]
+
+ named_tags.beautiful_used_by:add_to_item(themed_item, item.name.." "..item.summary)
+
+ -- Auto fill the description if its empty.
+ if (not params.description) or params.description == "" then
+ params.description = themed_item.summary
+ end
+ else
+ print("WARNING: Could not find theme variable", params.name.value)
+ end
+ end
}
-- For all properties which have a standard `@beautiful` variable for them
@@ -376,6 +1283,18 @@ add_custom_tag {
end
return ret
+ end,
+ finish_callback = function(item, raw, params, modules)
+ local modname = item.module.name:gmatch("[^.]+$")()
+ local name = "beautiful."..(modname.."_"..item.name):gsub("[.]", "_")
+
+ if all_theme_vars.collection[name] then
+ local sig_mods = all_theme_vars.collection[name]
+ local _, themed_items = pairs(sig_mods)(sig_mods)
+ local themed_item = themed_items[1]
+
+ named_tags.beautiful_used_by:add_to_item(themed_item, item.name.." "..item.summary)
+ end
end
}
@@ -472,7 +1391,6 @@ add_custom_tag {
add_custom_tag {
name = "hidden",
hidden = true,
- auto_subtags = false
}
-- Mark the item as readonly.
@@ -483,6 +1401,212 @@ add_custom_tag {
hidden = true,
auto_subtags = false
}
+
+-- Forces every method and function to have either `@treturn` or `@noreturn`.
+-- This avoids the many case where the return value was forgotten.
+add_custom_tag {
+ name = "noreturn",
+ hidden = true,
+ auto_subtags = false
+}
+
+-- When a property cannot be `nil` or a function/method cannot return `nil`.
+add_custom_tag {
+ name = "nonnullable",
+ hidden = true,
+ auto_subtags = false
+}
+
+-- When properties are integers, the value usually has a meaning, like the PID,
+-- apoint or a pixel.
+add_custom_tag {
+ name = "propertyunit",
+ title = "Unit",
+ hidden = true,
+ auto_subtags = false
+}
+
+-- Some string properties are de-facto enums. Only a small set of value is valid.
+-- This tag provides a consistent rendering for such properties.
+add_custom_tag {
+ name = "propertyvalue",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "value" },
+ },
+}
+
+-- Some defaults are not values. They are either algorithms, chains od fallbacks
+-- or somehow inherited. `ldoc` `opt` can only parse single "words", thus a new
+-- tag is needed for textual description of the default value.
+add_custom_tag {
+ name = "propertydefault",
+ hidden = true,
+ auto_subtags = false,
+}
+
+-- Some properties have multiple possible types. Some also might support multiple
+-- "logical type" for the same datatype. For example `string` can be a path or
+-- some CSS/SVG or an integer have different meaning for positive vs.
+-- negative/zeroed.
+--
+-- This tag helps document those nuances.
+add_custom_tag {
+ name = "propertytype",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "typename" },
+ },
+}
+
+-- Some values, mostly bytes, have a minimum and maximum value.
+add_custom_tag {
+ name = "rangestart",
+ title = "Minimum value",
+ hidden = true,
+ auto_subtags = false
+}
+add_custom_tag {
+ name = "rangestop",
+ title = "Maximum value",
+ hidden = true,
+ auto_subtags = false
+}
+add_custom_tag {
+ name = "negativeallowed",
+ title = "Negative allowed",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "allowed" },
+ },
+}
+
+-- A lot of properties have the `table` value. Lua tables can be anything from
+-- "struct" to list to objects. For lists, then the type of the row needs to
+-- be specified.
+add_custom_tag {
+ name = "tablerowtype",
+ title = "Table content",
+ hidden = true,
+ auto_subtags = false,
+}
+add_custom_tag {
+ name = "tablerowkey",
+ title = "Row keys",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "type" },
+ { name = "name" },
+ },
+}
+
+-- When a `@property` takes a `function` value, then the function arguments
+-- much be provided. If there is none, then `@functionnoparam` must be explicitly
+-- specified. Same for the return value(s).
+add_custom_tag {
+ name = "functionnoparam",
+ hidden = true,
+ auto_subtags = false,
+}
+add_custom_tag {
+ name = "functionparam",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "type" },
+ { name = "name" },
+ },
+}
+add_custom_tag {
+ name = "functionnoreturn",
+ hidden = true,
+ auto_subtags = false,
+}
+add_custom_tag {
+ name = "functionreturn",
+ hidden = true,
+ auto_subtags = false,
+ params = {
+ { name = "type" },
+ },
+}
+
+add_custom_tag {
+ name = "signalhandler",
+ hidden = false,
+ title = "Request handler",
+ auto_subtags = false,
+ params = {
+ { name = "source" },
+ },
+ format = function(self, params, item, md)
+ return ldoc.markup("`"..params.source.value.."`") .. " " .. params.description
+ end
+}
+
+add_custom_tag {
+ name = "beautiful_used_by",
+ hidden = false,
+ title = "Used by",
+ auto_subtags = false,
+ params = {
+ { name = "source" },
+ },
+ format = function(self, params, item, md)
+ return ldoc.markup("`"..params.source.value.."`") .. " " .. params.description
+ end
+}
+
+-- Auto generate some code for replacing request handlers.
+add_custom_tag {
+ name = "sourcesignal",
+ title = "Source signal",
+ hidden = false,
+ params = {
+ { name = "class" },
+ { name = "signal" },
+ },
+ format = function(self, params, item, md)
+ return ldoc.markup("`"..params.signal.value.."` from the `"..params.class.value.."` module.")..
+ " This code allows to disconnect this handler and implement your own:"
+ end,
+ finish_callback = function(item, raw, params, modules)
+ if all_signals.collection[params.signal.value] then
+ local sig_mods = all_signals.collection[params.signal.value]
+ local _, signal_items = pairs(sig_mods)(sig_mods)
+ local signal_item = signal_items[1]
+
+ -- Auto generate some code.
+ local code = "-- Disconnect the original handler.\n"
+ code = code .. signal_item.module.name .. ".disconnect_signal('".. params.signal.value .."', "..item.name..")\n\n"
+ code = code .. "-- Connect a custom handler.\n"
+ code = code .. signal_item.module.name .. ".connect_signal('".. params.signal.value .."', function("
+
+
+ if signal_item.type == "signal" then
+ for idx, parm in ipairs(signal_item.params) do
+ code = code .. parm .. (idx == #signal_item.params and "" or ", ")
+ end
+
+ code = code .. ")\n -- code here\nend)"
+
+ named_tags.signalhandler:add_to_item(signal_item, item.name.." "..item.summary)
+ end
+
+ item.tag_extra_data = item.tag_extra_data or {}
+ item.tag_extra_data["sourcesignal"] = item.tag_extra_data["sourcesignal"] or {}
+ item.tag_extra_data["sourcesignal"][raw] = item.tag_extra_data["sourcesignal"][raw] or {}
+ item.tag_extra_data["sourcesignal"][raw].usage = ldoc.prettify(code)
+
+ item.has_show_more = true
+ end
+ end
+}
+
-- More fitting section names
kind_names={topic='Documentation', module='Libraries', script='Sample files'}
@@ -510,7 +1634,6 @@ file = {
'../selection.c',
'../spawn.c',
'../xkb.c',
- '../common/luaobject.c',
'../objects/client.c',
'../objects/drawable.c',
'../objects/screen.c',
@@ -569,6 +1692,7 @@ file = {
'../lib/wibox/layout/rotate.lua',
'../lib/wibox/layout/scroll.lua',
'../lib/wibox/widget/background.lua',
+ '../lib/wibox/drawable.lua',
}
}
@@ -581,26 +1705,65 @@ local function wrap_modname(str, item)
end
local named_args = {
- [ "(args)" ] = true,
- [ "([args])" ] = true,
- [ "([args=nil])" ] = true,
- [ "([args={}])" ] = true
+ [ "(args)" ] = true,
+ [ "([args])" ] = true,
+ [ "([args=nil])" ] = true,
+ [ "([args={}])" ] = true,
+ [ '(args)' ] = true,
+}
+
+-- Some values come from external sources, we can't enforce the naming conventions
+-- on them. So far, they are all keyboard related.
+local param_name_whitelist = {
+ Mod2 = true, Lock = true, Control = true, Mod1 = true, ISO_Level3_Shift = true,
+ Mod4 = true, Insert = true, Delete = true, Next = true, Prior = true, Left = true,
+ Up = true, Right = true, Down = true, KP_End = true, KP_Down = true,
+ KP_Next = true, KP_Left = true, KP_Begin = true, KP_Right = true,
+ KP_Home = true, KP_Up = true, KP_Prior = true, KP_Insert = true, KP_Delete = true,
+ KP_Divide = true, KP_Multiply = true, KP_Subtract = true, KP_Add = true,
+ KP_Enter = true, Escape = true, Tab = true, space = true, Return = true,
+ XF86MonBrightnessUp = true, XF86MonBrightnessDown = true,
+ XF86AudioRaiseVolume = true, XF86AudioLowerVolume = true, XF86AudioMute = true,
+ XF86AudioPlay = true, XF86AudioPrev = true, XF86AudioNext = true, XF86AudioStop = true,
}
-- Sections which are hidden by default, but visible when clicked.
local summarize = {
- emits = {index = 1, title = "signal" , count = true },
- propemits = {index = 2, title = "signal" , count = true },
- usebeautiful = {index = 3, title = "theme variable" , count = true },
- propbeautiful = {index = 4, title = "theme variable" , count = true },
- request = {index = 5, title = "permission" , count = true },
- classsignal = {index = 6, title = "Class level only", count = false},
+ is_deprecated = {index = 1, title = "deprecated" , count = false},
+ emits = {index = 2, title = "signal" , count = true },
+ propemits = {index = 3, title = "signal" , count = true },
+ usebeautiful = {index = 4, title = "theme variable" , count = true },
+ propbeautiful = {index = 5, title = "theme variable" , count = true },
+ request = {index = 6, title = "permission" , count = true },
+ classsignal = {index = 7, title = "Class level only", count = false},
+ readonly = {index = 8, title = "read only" , count = false},
}
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"}},
request = { "table class='widget_list' border=1", "table", "tr", "tr", {"Class", "Permission", "Context", "Default", "Description"}},
+ sourcesignal = { "div", "div", "span", "span" }
+}
+
+--- If the title is short and descritive, there is no point to bloat it.
+--
+-- That test is mostly to catch empty or lazy description (such as the module
+-- name and nothing else).
+local short_title_whitelist = {
+ [ "rc.lua" ] = true,
+ [ "naughty.action" ] = true,
+ [ "naughty.layout.box" ] = true,
+ [ "naughty.widget.title" ] = true,
+ [ "theme.lua" ] = true,
+ [ "wibox.container.margin" ] = true,
+ [ "wibox.container.arcchart"] = true,
+ [ "wibox.widget.checkbox" ] = true,
+ [ "wibox.widget.imagebox" ] = true,
+ [ "wibox.widget.separator" ] = true,
+ [ "wibox.widget.progressbar"] = true,
+ [ "naughty" ] = true,
+ [ "xproperties" ] = true,
}
-- Use the first word of the subtag content to map it to its tag.
@@ -630,7 +1793,7 @@ local function generate_summary(item)
end
end
- local ret, has_show_more = {}, false
+ local ret, has_show_more = {}, item.has_show_more or false
for k, v in ipairs(tgs) do
if v.count > 0 then
@@ -643,9 +1806,6 @@ local function generate_summary(item)
has_show_more = v.showcount or has_show_more
end
end
- if item.tags.readonly then
- ret[#ret+1] = {title = "read only"}
- end
item.extra_summary = #ret > 0 and ret or nil
item.has_show_more = has_show_more
@@ -664,7 +1824,7 @@ local function init_custom_types(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 = {}, {}, {}
+ item.delims, item.auto_usage, item.auto_params, item.metadata = {}, {}, {}, {}
local to_rm = {}
@@ -716,22 +1876,42 @@ local function init_custom_types(item)
-- Allow the template to fetch the right sub-tags.
function item.get_auto_params(tag, value)
+ local extra = (item.tag_extra_data and item.tag_extra_data[tag] and item.tag_extra_data[tag][value]) or {}
+
-- 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"]
+ return item.auto_params[tag.."tparam_override"], named_tags[tag.."tparam"], extra
end
- if not item.auto_params[tag.."tparam"] then return nil, nil end
+ local parsed = nil
- local parsed = parse_custom_tags(value, named_tags[tag].params)
+ if item.parsed_tags and item.parsed_tags[tag] and item.parsed_tags[tag][value] then
+ parsed = item.parsed_tags[tag][value]
+ end
+
+ if not item.auto_params[tag.."tparam"] then return nil, nil, extra end
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"]
+ return item.auto_params[tag.."tparam"][parsed.name.value], named_tags[tag.."tparam"], extra
end
- return nil, nil
+ return nil, nil, extra
end
+ -- Recursive way to annotate property-like objects.
+ local amt
+ amt = function(self, title, description, datatype)
+ self.metadata[#self.metadata+1] = {
+ title = title,
+ datatype = datatype,
+ description = description,
+ metadata = {},
+ add_metadata = amt
+ }
+ return self.metadata[#self.metadata]
+ end
+ item.add_metadata = amt
+
item.is_init = true
end
@@ -741,6 +1921,7 @@ local function wrap_args(item)
-- Display named args with `{}` and ordered args with `()`
if named_args[item.args] then
+ item.is_named_call = true
return "{[args]}"
end
@@ -776,8 +1957,7 @@ local function pipe_to_or(s)
end
-- Parse the magic parameters to type in something the template eats.
-local function sanitize_type(item, ldoc)
-
+local function sanitize_type(item)
for parm in ldoc.modules.iter(item.params) do
local t = item:type_of_param(parm)
@@ -806,9 +1986,37 @@ local function sanitize_type(item, ldoc)
item.display_type = "N/A"
end
+-- Detect error prone markdown formatting.
+local function detect_markdown_footguns(string)
+ for line in string:gmatch("[^\n]*") do
+ if line:sub(1,4) ~= " " then
+ local is_tick = false
+
+ -- Detect unquoted code with 2 underscores. They will render as italic,
+ -- which is definitively not wanted. Add "`" to fix.
+ for part in line:gmatch("[^`]*") do
+ if not is_tick then
+ local count = 0
+
+ for under in part:gmatch("[^\\]_") do
+ count = count + 1
+ end
+
+ if count > 1 then
+ return false
+ end
+ end
+
+ is_tick = not is_tick
+ end
+ end
+ end
+
+ return true
+end
-- Add parentheses when there is alternative return types.
-local function generate_return_tuple(item, group, ldoc)
+local function generate_return_tuple(item, group)
local tuple = {}
for r in group:iter() do
@@ -839,7 +2047,7 @@ local function generate_return_tuple(item, group, ldoc)
end
-- Create a return type string.
-local function sanitize_return_type(item, ldoc)
+local function sanitize_return_type(item)
local groups = item.retgroups
@@ -861,11 +2069,184 @@ local function sanitize_return_type(item, ldoc)
end
item.display_type = item.display_type .. ""
+ elseif not item.tags["noreturn"] then
+ print(
+ "WARNING:", item.name, "from", item.module.name,
+ "doesn't have a return value or @noreturn"
+ )
end
item.compact_signature = true
end
+-- Traverse the entire doc and reverse-map the links between our custom
+-- tags and the content it is pointing toward. From that, we add some
+-- "consumers"/"providers" tables to each (relevant) item.
+local function global_init(_ldoc)
+ ldoc = _ldoc
+
+ if is_init then return end
+ is_init = true
+
+ local module_by_name = {}
+
+ -- First pass, gather the providers.
+ for _, mod in ipairs(ldoc.modules) do
+ module_by_name[mod.name] = mod
+
+ if mod.type ~= "topic" and ((not mod.summary) or mod.summary == "" or mod.summary:lower():sub(1,8) == "awesome") then
+ print("WARNING: Each module needs a good summary as its first line", mod.name, "doesn't")
+ end
+
+ local sum_count = 0
+
+ for line in (mod.summary or ""):gmatch("[^\n]*") do
+ sum_count = sum_count + 1
+ end
+
+ if sum_count > 1 and #mod.summary > 120 then
+ print("WARNING:", mod.name, "summary has to be only 1 line.")
+ end
+
+ if mod.summary and #mod.summary < 30 and not short_title_whitelist[mod.name] then
+ print("WARNING:", mod.name, "summary is too short.")
+ end
+
+ for tag, values in pairs(mod.tags) do
+ for _, value in ipairs(values.gmatch and {values} or values) do
+ -- Collect instances of some types.
+ if databases[tag] and databases[tag].collect then
+ delayed_collect[#delayed_collect+1] = {mod, mod, tag, value}
+ end
+ end
+ end
+
+ for kind, items in mod.kinds() do
+ for item in items() do
+ -- Decorate the item with our customizations.
+ init_custom_types(item)
+
+ -- print(item.description)
+
+ if item.summary and not detect_markdown_footguns(item.summary) then
+ print(
+ "WARNING: "..item.name.." from "..item.module.name.." seems to have"..
+ " ambiguous markdown in its summary, probably underscores. Please either"..
+ " use '`' or HTML."
+ )
+ end
+
+ -- Collect instances of some types.
+ if databases[item.type] and databases[item.type].collect then
+ databases[item.type].collect(item, mod)
+ end
+
+ for tag, values in pairs(item.tags) do
+ for _, value in ipairs(values.gmatch and {values} or values) do
+ -- Collect instances of some types.
+ if databases[tag] and databases[tag].collect then
+ delayed_collect[#delayed_collect+1] = {item, mod, tag, value}
+ end
+ end
+ end
+
+ -- Lint the parameters too.
+ for parm in ldoc.modules.iter(item.params) do
+ local first = parm:match("^[ ]*(.)")
+
+ -- If the first letter of a parameter is capital, the type is probably missing.
+ -- That's what happen if you rename @param to @tparam without actually adding the type.
+ if first and first ~= first:lower() and parm:upper() ~= parm and not param_name_whitelist[parm] then
+ print(
+ "ERROR: Parameter "..parm.." from ".. item.name .. " ".. item.module.name..
+ " starts with a capital letter. This is forbidden."
+ )
+ end
+
+ for p in ldoc.modules.iter(item:subparam(parm)) do
+ local desc = item.params.map[p]
+
+ if not detect_markdown_footguns(desc) then
+ print(
+ "WARNING: Always use '`' to encapsulate code in the parameters." ..
+ p .. " from " .. item.name .. " " .. item.module.name .. " contains " ..
+ "some ambiguous markup. If this is a false positive, use HTML."
+ )
+ end
+
+ -- It *sometime* works, but is at risk if being interpreted as code by markdown.
+ if desc:match("^ [ ]+") then
+ print(
+ "WARNING: ", item.name, "from", item.module.name, "has a parameter description "..
+ "with leading spaces. This will not render correctly", "'"..desc.."'"
+ )
+ end
+
+ first = desc:match("^[ ]*([a-z])")
+
+ if first and first ~= first:upper() then
+ print("WARNING: Sentences starts with a capital letter. Please fix", item.module.name, item.name)
+ end
+
+ --TODO convert @propbeautiful to @usebeautiful and lint them
+ --TODO check the module summary.
+ end
+ end
+ end
+ end
+ end
+
+ -- Second pass, collect the custom tags. This is delayed because
+ -- the tags depend on the items. Not all items have been processed if
+ -- this was called during the first pass. Also, collect callbacks can
+ -- themselves create more delayed_collect entries recursively.
+ for _, to_collect in ipairs(delayed_collect) do
+ databases[to_collect[3]].collect(to_collect[1], to_collect[2], to_collect[3], to_collect[4])
+ end
+
+ -- Third pass, parse every custom tags and fill the consumers tables.
+ for _, mod in ipairs(ldoc.modules) do
+ for kind, items in mod.kinds() do
+ for item in items() do
+ for tag_name, values in pairs(item.tags) do
+ for _, tag in ipairs(values.gmatch and {values} or values) do
+ local parsed = named_tags[tag_name]
+ and named_tags[tag_name].params
+ and parse_custom_tags(tag, named_tags[tag_name].params)
+
+ -- Allow the tags to, ie, auto-generate some extra content.
+ if named_tags[tag_name] and named_tags[tag_name].finish_callback then
+ named_tags[tag_name].finish_callback(item, tag, parsed, module_by_name)
+ end
+
+ -- Save the parsed content to be used in get_auto_params.
+ if parsed then
+ item.parsed_tags = item.parsed_tags or {}
+ item.parsed_tags[tag_name] = item.parsed_tags[tag_name] or {}
+ item.parsed_tags[tag_name][tag] = parsed
+ end
+ end
+ end
+
+ -- Mostly for linting.
+ if databases[item.type] and databases[item.type].finish then
+ databases[item.type].finish(item, mod, module_by_name)
+ end
+ end
+ end
+ end
+end
+
+-- Work around the fact that tag/awful.tag client/awful.client pages
+-- are merged.
+local function compare_module_name(input, module)
+ for _, mod in ipairs { module, "awful."..module } do
+ if input:sub(1, #mod) == mod then return true end
+ end
+
+ return false
+end
+
local no_prefix = {
property = true,
signal = true,
@@ -889,6 +2270,8 @@ local add_mod = {
staticfct = true,
deprecated = true,
field = true,
+ signalhandler = true,
+ table = true,
}
-- Add the arguments.
@@ -896,6 +2279,9 @@ local add_args = {
constructorfct = true,
constructorfct2 = true,
staticfct = true,
+ signalhandler = true,
+ callback = true,
+ deprecated = true,
}
-- Add a type column to the summary and type field in the description.
@@ -911,31 +2297,59 @@ local display_type = {
-- Add the `-> ret_type` annotation.
local display_return_type = {
- method = true,
- staticfct = true,
+ method = true,
+ deprecatedmethod = true,
+ staticfct = true,
}
-- Show return values.
local show_return = {
- ["function"] = true,
- constructorfct = true,
- constructorfct2 = true,
- legacylayout = true,
- staticfct = true,
- method = true,
- deprecated = true,
+ ["function"] = true,
+ constructorfct = true,
+ constructorfct2 = true,
+ legacylayout = true,
+ staticfct = true,
+ method = true,
+ deprecated = true,
+ deprecatedmethod = true,
}
-- The different type of deprecation.
local is_deprecated = {
deprecated = true,
deprecatedproperty = true,
+ deprecatedmethod = true,
deprecatedsignal = true,
}
custom_display_name_handler = function(item, default_handler)
+ item.global_init = global_init
+
+ if is_deprecated[item.type] then
+ item.tags.is_deprecated = {true}
+ end
+
init_custom_types(item)
+ -- Do not use the default handler. It encodes the parameters using
+ -- the optchain convention. Not everybody is confortable with this.
+ -- It is also unreadable.
+ item.args = ""
+
+ if item.params then
+ item.args = "("
+ for key, line in ipairs(item.params) do
+ local name, comment = item:split_param(line)
+ local def = item:default_of_param(line)
+ if def then
+ item.args = item.args .. '' .. name .. "" .. (key < #item.params and ", " or "")
+ else
+ item.args = item.args .. name .. (key < #item.params and ", " or "")
+ end
+ end
+ item.args = item.args .. ")"
+ end
+
local ret = default_handler(item)
-- Edit the input so the template is notified.
@@ -968,18 +2382,16 @@ custom_display_name_handler = function(item, default_handler)
-- have "just" `bar`. Given we use constructors from metatables, we have no
-- choice but to use the full function name. It also makes copy/paste easier.
if add_mod[item.type] then
+ local is_field = item.type == "field" or item.type == "tfield"
+
if (not ret:find(".", 1, true)) and (not ret:find(":", 1, true)) then
ret = item.module.name .. "." .. ret
- elseif item.type == "field" and ret:sub(1, #item.module.name) ~= item.module.name then
+ elseif is_field and not compare_module_name(ret, item.module.name) then
ret = item.module.name .. "." .. ret
end
end
- if is_deprecated[item.type] then
- return ret .. " [deprecated]"
- end
-
- if item.type == "method" then
+ if item.type:match("method") then
ret = render_methods(item)
end
diff --git a/docs/images/client_geo.svg b/docs/images/client_geo.svg
index 34c970a2b..88da6ae53 100644
--- a/docs/images/client_geo.svg
+++ b/docs/images/client_geo.svg
@@ -67,11 +67,11 @@
inkscape:connector-curvature="0"
id="path6072"
d="m 58.889889,0.75 402.388891,0 0,238.5 -402.388891,0 z"
- style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:10, 4;stroke-dashoffset:1;stroke-opacity:0.26666703"
+ class=".svg_stroke" style="fill:none;stroke:currentcolor;;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:10, 4;stroke-dashoffset:1;stroke-opacity:0.26666703"
sodipodi:nodetypes="ccccc" />
Top titlebarLeft titlebarRight titlebarShape clip outline
@@ -353,27 +353,27 @@
inkscape:connector-curvature="0"
id="path6355"
d="m 445.91815,214.03874 3.33912,0 0,8.64241 -3.33912,0"
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:0.50971645;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:0.87379962;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ class=".svg_fill" style="opacity:1;fill:currentcolor;;fill-opacity:1;stroke:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ class=".svg_fill" style="opacity:1;fill:currentcolor;;fill-opacity:1;stroke:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ class=".svg_fill" style="opacity:1;fill:currentcolor;;fill-opacity:1;stroke:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ class=".svg_fill" style="opacity:1;fill:currentcolor;;fill-opacity:1;stroke:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ class=".svg_fill" style="opacity:1;fill:currentcolor;;fill-opacity:1;stroke:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
diff --git a/docs/images/progressbar.svg b/docs/images/progressbar.svg
index ade0797ef..ac8ef2d0f 100644
--- a/docs/images/progressbar.svg
+++ b/docs/images/progressbar.svg
@@ -76,115 +76,115 @@
style="fill:#a800ff;fill-opacity:0.49019602;fill-rule:nonzero;stroke:#ffff00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />
margins.leftpaddings.rightmargins.bottompaddings.leftcolorbackground_colorborder_colorbar_border_widthpaddings.topmargins.rightborder_width
+ class=".svg_stroke" style="fill:none;stroke:currentcolor;;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:10, 4;stroke-dashoffset:1;stroke-opacity:0.26666703" />
+ class=".svg_stroke" style="fill:none;stroke:currentcolor;;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:10, 4;stroke-dashoffset:1;stroke-opacity:0.2" />
@@ -90,21 +90,21 @@
inkscape:connector-curvature="0"
id="path7597"
d="m 427.60318,224.3777 10.21376,0 0,15.32064 -10.14227,0"
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="cccc" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.36000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
Gaps
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ class=".svg_stroke" style="fill:none;fill-rule:evenodd;stroke:currentcolor;;stroke-width:1.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
Screen area
+
+
+
diff --git a/docs/ldoc.css b/docs/ldoc.css
index 9857bcfb2..9576dc0f9 100644
--- a/docs/ldoc.css
+++ b/docs/ldoc.css
@@ -25,22 +25,43 @@ hr {
tt {
font-family: monospace;
}
+
span.parameter {
font-family: monospace;
font-weight: bold;
color: rgb(99, 115, 131);
}
-span.parameter:after {
- content:":";
+
+span.optional_param {
+ font-style: italic;
+ color: rgb(143, 166, 230);
}
-span.types:before {
- content:"(";
+
+.types {
+ white-space: pre;
}
-span.types:after {
- content:")";
+
+td span.types {
+ flex-flow: nowrap;
+ display: inline-flex;
+ width: 100%;
}
+
+td span.inline_types {
+ color: #a4c7ff;
+ flex-flow: nowrap;
+ width: 100%;
+}
+
.type {
- font-weight: bold; font-style:italic
+ flex-basis: auto;
+ font-weight: bold;
+ font-style:italic;
+ pointer-events: none;
+ text-decoration: none;
+ color: #008fee;
+ text-align: center;
+ flex-grow: 1;
}
p.name {
@@ -51,7 +72,12 @@ kbd,
p code,
ol code,
ul code,
-dd > code {
+dd > code,
+td code,
+span.default_value,
+.see_also_description code,
+.important_box code
+{
background-color: #eaedf587;
padding-left: 3px;
padding-right: 3px;
@@ -64,15 +90,39 @@ dd > code {
margin-right: 5px;
}
+#main {
+ display: flex;
+}
+
#navigation {
- float: left;
+ --sidebar-width: 14em;
+ --sidebar-toggle-width: 24px;
+
background-color: white;
border-right: 1px solid #d3dbec;
border-bottom: 1px solid #d3dbec;
- width: 14em;
- vertical-align: top;
+ width: var(--sidebar-width);
overflow: visible;
+
+ margin-left: calc(-1 * var(--sidebar-width) + var(--sidebar-toggle-width));
+ transition: margin-left 0.2s ease-out;
+}
+
+#navigation.open {
+ margin-left: 0;
+}
+
+@media (hover: hover) {
+ #navigation:hover {
+ margin-left: 0;
+ }
+}
+
+@media all and (min-width: 768px) {
+ #navigation {
+ margin-left: 0;
+ }
}
#navigation br {
@@ -99,6 +149,10 @@ dd > code {
margin-bottom: 0px;
}
+#content {
+ overflow: hidden;
+}
+
#content h1 {
background-color: #2c3e67;
color: white;
@@ -133,6 +187,7 @@ dd > code {
margin-left: 15px;
margin-bottom: 5px;
border-bottom: solid 1px #bcd;
+ font-weight: normal;
}
#content h4 {
@@ -141,11 +196,11 @@ dd > code {
border-bottom: solid 1px #bcd;
}
-#content pre {
+#content pre, .auto_genenerated_code {
margin: 15px;
}
-pre {
+pre, .auto_genenerated_code {
background-color: rgb(50, 55, 68);
color: white;
border-radius: 3px;
@@ -185,10 +240,6 @@ table.index td {
margin: 0px 3px 0px -1em;
}
-#content {
- margin-left: 14em;
-}
-
#content p {
padding-left: 15px;
padding-right: 15px;
@@ -209,6 +260,56 @@ table th, table td {
padding: 2px;
}
+.important_box {
+ padding-left: 40px;
+ min-height: 32px;
+ max-width: 640px;
+ vertical-align: middle;
+ background-image: url("images/warning_icon.svg");
+ background-size: 32px 32px;
+ background-repeat: no-repeat;
+ background-position: left center;
+ margin-top: 15px;
+ margin-bottom: 5px;
+ margin-left: 10px;
+}
+
+.see_also, .see_also td, .see_also th {
+ border-style: hidden !important;
+ padding-left: 5pt;
+ padding-right: 5pt;
+}
+
+.see_also tr td:nth-of-type(1) {
+ display: list-item;
+ list-style-type: disc;
+ list-style-position: inside;
+}
+
+.see_also tr:hover {
+ background-color: #f7fbff;
+}
+
+.see_also tr th {
+ color: rgb(168, 168, 168);
+ padding-top: 15px;
+ padding-bottom: 4px;
+ font-weight: normal;
+ text-decoration: none;
+ font-style:italic;
+ font-size: 85%;
+}
+
+.see_also_description {
+ max-width: 640px;
+}
+
+.see_also_sublist td:nth-of-type(1) {
+ margin-left: 10px;
+ padding-left: 15px;
+ border-left: 1px solid rgb(200, 200, 200) !important;
+}
+
.widget_list td {
padding-top: 10px;
padding-bottom: 10px;
@@ -280,12 +381,17 @@ table th, table td {
#about {
padding: 15px;
- padding-left: 16em;
background-color: white;
border-top: 1px solid #d3dbec;
border-bottom: 1px solid #d3dbec;
}
+@media all and (min-width: 768px) {
+ #about {
+ padding-left: calc(14em + 15px);
+ }
+}
+
table.module_list, table.function_list {
border-width: 1px;
border-style: solid;
@@ -301,26 +407,22 @@ table.module_list td, table.function_list td {
padding-bottom: 5px;
}
table.module_list td.name, table.function_list td.name {
- background-color: white;
min-width: 200px;
border-left-width: 0px;
border-right-width: 0px;
}
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 {
- background-color: white;
border-left-width: 0px;
border-right-width: 0px;
}
table.function_list td.inheritance {
- background-color: white;
border-right-width: 0px;
border-left-width: 0px;
color: #a4c7ff;
@@ -337,8 +439,15 @@ span.inheritance {
font-weight: normal;
}
+span.not_applicable {
+ color: rgb(200, 200, 200);
+ font-style:italic;
+ font-size: 85%;
+ text-align: center;
+ display: block;
+}
+
.summarytype {
- background-color: white;
color: #a4c7ff;
font-size: 85%;
border-left: none;
@@ -346,14 +455,18 @@ span.inheritance {
text-align: right;
}
-span.chips--readonly {
+span.chips {
border: 1px solid #9db9f3;
border-radius: 25px;
- padding: 1px 3px;
- font-size: 70%;
+ padding-left: 5pt;
+ padding-right: 5pt;
+ padding-top: 1pt;
+ padding-bottom: 1pt;
+ font-size: 85%;
color: #9db9f3;
background-color: #FFF;
margin-left: 10px;
+ vertical-align: middle;
}
table.function_list .function_args /*.function_modname*/ {
@@ -382,7 +495,6 @@ table.function_list .function_named_args {
}
table.function_list td.baseclass {
- background-color: white;
color: #a4c7ff;
min-width: 200px;
border-left: none;
@@ -417,7 +529,7 @@ dl.function dd {
margin-bottom: 15px;
}
-#content dl.function dd h3 {
+#content dl.function dd h3, .see_also i {
margin-top: 0px;
margin-left: 0px;
padding-left: 0px;
@@ -538,6 +650,8 @@ pre .url { color: #272fc2; text-decoration: underline; }
/* Inheritance diagram */
.inheritance .inheritance__level {
list-style: none;
+ padding-top: 0px;
+ padding-left: 30px;
}
.inheritance .inheritance__level--root {
@@ -563,3 +677,81 @@ pre .url { color: #272fc2; text-decoration: underline; }
.extra-header__section {
flex-grow: 1;
}
+
+.summary_row {
+ background-color: white;
+}
+
+.summary_row:hover {
+ background-color: #f7fbff;
+}
+
+/* CSS for beautiful.fg_normal */
+.svg_stroke, .svg_fill {
+ color: black;
+}
+
+#content > .components-relationship {
+ margin-left: 15px;
+ margin-right: 15px;
+}
+
+.components-relationship--diagrams {
+ display: flex;
+ flex-direction: column;
+}
+
+.components-relationship--diagram {
+ flex-grow: 1;
+ flex-basis: 100%;
+}
+
+.components-relationship--diagram > table {
+ margin: 0;
+ width: 100%;
+}
+
+.components-relationship--diagram + .components-relationship--diagram {
+ margin-top: 15px;
+}
+
+/* on wide displays, put both diagrams next to each other */
+@media all and (min-width: 1100px) {
+ .components-relationship--diagrams {
+ flex-direction: row;
+ }
+
+ .components-relationship--diagram {
+ flex-grow: 1;
+ flex-basis: 50%;
+ }
+
+ .components-relationship--diagram + .components-relationship--diagram {
+ margin-top: 0;
+ margin-left: 15px;
+ }
+}
+
+.components-relationship--legend {
+ color: #00000044;
+ margin-top: 15px;
+}
+
+.img-object {
+ max-width: 100%;
+ padding: 5px;
+}
+
+.copy-link {
+ font-size: 9px;
+ padding: 2px;
+ border-radius: 9px;
+ vertical-align: middle;
+ text-decoration: none;
+}
+.copy-link--success {
+ background-color: green;
+}
+.copy-link--failure {
+ background-color: red;
+}
diff --git a/docs/ldoc.ltp b/docs/ldoc.ltp
index 2c518e306..e7cf8b4ec 100644
--- a/docs/ldoc.ltp
+++ b/docs/ldoc.ltp
@@ -24,25 +24,27 @@
-
-
-
-
-
-
-
-
# local no_spaces = ldoc.no_spaces
# local use_li = ldoc.use_li
# local display_name = ldoc.display_name
# local iter = ldoc.modules.iter
-# local function un_cmake(s) return s:gsub(";", ";"):gsub(""", '"') end
+# local function un_cmake(s) return s:gsub(";", ";"):gsub(""", '"'):gsub('"', '"') end
# local function M(txt,item) return ldoc.markup(txt and un_cmake(txt) or nil,item,ldoc.plain) end
# local nowrap = ldoc.wrap and '' or 'nowrap'
# local html_space = function(s) return s:gsub(" ", "%%20") end
# local no_underscores = function(s) return s:gsub("_", " ") end
+# local get_item = function(mod, name) for item in iter(mod.items) do if item.name == name then return item end end; return name == "" and mod or nil end
+
+# -- Poke a hole to allow config.ld code to have a global initialization.
+# for m in iter(ldoc.modules) do
+# if #m.items > 0 then
+# display_name(m.items[1])
+# m.items[1].global_init(ldoc)
+# break
+# end
+# end
# --------- modules hierarchy -------------
# local hierarchy = {}
@@ -74,7 +76,7 @@
# local myitems = {}
# for item in items() do
# myitems[#myitems + 1] = item
-# end
+# end
# all_module_kinds[#all_module_kinds + 1] = { kind = kind, items = myitems }
# end
# local filtered_kinds = { "Constructors", "Static module functions",
@@ -121,7 +123,6 @@
-
$(ldoc.project)
# if not ldoc.single and module then -- reference back to project index
@@ -147,7 +148,7 @@
# if ldoc.no_summary and module and not ldoc.one then -- bang out the functions on the side
# for kind, items in module.kinds() do
# if not kind:match("^ldoc_skip") then
-
$(kind)dasdasd
+
$(kind)
# end
# for item in items() do
@@ -180,7 +181,7 @@
# if ldoc.body then -- verbatim HTML as contents; 'non-code' entries
- $(ldoc.body)
+ $(un_cmake(ldoc.body))
# elseif module then -- module documentation
Module: $(module.name)
$(M(module.summary,module))
@@ -280,7 +281,7 @@
# local dn = display_name(item)
# local inherited = (item.baseclass ~= module.name)
# if item.sanitize_type then item.sanitize_type(item, ldoc) end
-
+
# if item.display_type and not item.compact_signature then
$(M(item.summary,item))
-# if item.tags.readonly then
- read only
-# end
-# if inherited then
- Inherited from $(item.baseclass)
-
+# if item.tags.is_deprecated then
+ Deprecated
# end
+# if item.tags.readonly then
+ Read only
+# end
+# if inherited then
+ Inherited from $(item.baseclass)
+# end
+
# end end -- for items
# last_kind = kind
@@ -345,7 +349,7 @@
# end
# for item in iter(k.items) do if not item.tags.hidden then
-
+ 🔗$(display_name(item))
# if item.display_inheritance then
@@ -373,40 +377,106 @@
$(M(ldoc.descript(item),item))
-# if show_parms and item.params and #item.params > 0 and not item.hide_params then
+# if kind == "Object properties" and item.params[1] and #item.metadata > 0 then
+
Constraints:
+
+
+# local current_level
+# current_level = function(metadata, level)
+# for _, metadata in ldoc.ipairs(metadata, level) do
+
+
+
+ $(metadata.title)$(#(metadata.metadata or {}) > 0 and ":" or "")
+
+# if metadata.datatype then
+ ($(metadata.datatype))
+# end
+
+# if metadata.description and not metadata.description:match("^[\t\n ]*$") then
+
: $(metadata.description)
+# end
+
+# current_level(metadata.metadata, level + 1)
+# end
+# end --current_level
+# current_level(item.metadata or {}, 0)
+
+
+# elseif 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
$(subnames):
# end
-
+# local has_optional, has_named_call = false, false
+# for parm in iter(item.params) do
+# local param,sublist = item:subparam(parm)
+# has_named_call = has_named_call or (sublist and item.is_named_call)
+# for p in iter(param) do
+# local def = item:default_of_param(p)
+# has_optional = has_optional or (def and def ~= true)
+# end
+# end
+# if has_named_call then
+
+ Note: This $(item.kind) uses named parameters calling convention. It
+ means you call it with $(M('`{}`')) and omit the parantheses. For example,
+ calling this will all default argument would be $(item.name){}.
+ This is a Lua shortcut syntax equivalent to $(item.name)({}).
+ args is only a placeholder name for the "lone table argument"
+ used in named parameters calls.
+
+# end
+
+
+
Name
+
+
Type(s)
+
Description
+# if has_optional then
+
Default value
+# end
+
# for parm in iter(item.params) do
# local param,sublist = item:subparam(parm)
# if sublist then
-
$(sublist)$(M(item.params.map[sublist],item))
-
+# local def = item:default_of_param(sublist)
+
+
$(sublist)
+
$(def and 'Optional' or '')
+
table
+
$(M(item.params.map[sublist],item))
+# if has_optional then
+# if def and def ~= true then
+
$(def)
+# elseif def then
+
Undefined
+# else
+
Not applicable
+# end
+# end
+
# end
# for p in iter(param) do
# local name,tp,def = item:display_name_of(p), ldoc.typename(item:type_of_param(p)), item:default_of_param(p)
-
$(name)
-# if tp ~= '' then
- $(tp)
+
+
$(name)
+
$(def and 'Optional' or '')
+
$(tp)
+
$(M(item.params.map[p],item))
+# if has_optional then
+# if def and def ~= true then
+
$(def)
+# elseif def then
+
Undefined
+# else
+
Not applicable
# end
- $(M(item.params.map[p],item))
-# if def == true then
- (optional)
-# elseif def then
- (default$(def))
-# end
-# if item:readonly(p) then
- readonly
-# end
-
-# end
-# if sublist then
-
+# end
+
# end
# end -- for
-
+
# end -- if params
# if show_return and item.retgroups then local groups = item.retgroups
@@ -444,11 +514,21 @@
# if item.see then
# local li,il = use_li(item.see)
See also:
-
-# for see in iter(item.see) do
- $(li)$(see.label)$(il)
+
+# for see in iter(item.see) do
+# local see_item = see.mod and get_item(see.mod, see.name)
+# local see_mod = (see_item and see.mod and see.mod ~= item.module and see.mod.name ~= see_item.name) and "("..see.mod.name..")" or ""
+
+# if see_item or see.name == "" then
+ $(see.name == "" and "module" or (see_item and see_item.kind))
+# end
+
+
# end -- for
-
+
# end -- if see
# if item.usage then
@@ -487,7 +567,7 @@
# 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)
+# local sub_values, sub_custom, extra_data = item.get_auto_params(custom[1], value)
# if sub_values then
# for _, value in ldoc.ipairs(sub_values) do
@@ -495,6 +575,12 @@
# end -- for auto_params
# end -- if item.auto_params
+# if extra_data.usage then
+
+
+
$(extra_data.usage)
+# end -- extra_data.usage
+
# end -- for
$(group_end)>
# end -- if tag
@@ -537,5 +623,78 @@
generated by LDoc $(ldoc.version)