<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Amodule_documentation</id>
	<title>Module:module documentation - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Amodule_documentation"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:module_documentation&amp;action=history"/>
	<updated>2026-05-31T10:49:20Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:module_documentation&amp;diff=505079&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local export = {}  local parameters_module = &quot;Module:parameters&quot; local m_str_utils = require(&quot;Module:string utilities&quot;)  local codepoint = m_str_utils.codepoint local concat = table.concat local insert = table.insert local u = m_str_utils.char local rsplit = m_str_utils.split local dump = mw.dumpObject  --[===[ intro: This module automatically generates documentation for other modules. It fetches in-line comments in Lua code and converts them into a form that can be used...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:module_documentation&amp;diff=505079&amp;oldid=prev"/>
		<updated>2026-05-06T15:38:39Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local parameters_module = &amp;quot;Module:parameters&amp;quot; local m_str_utils = require(&amp;quot;Module:string utilities&amp;quot;)  local codepoint = m_str_utils.codepoint local concat = table.concat local insert = table.insert local u = m_str_utils.char local rsplit = m_str_utils.split local dump = mw.dumpObject  --[===[ intro: This module automatically generates documentation for other modules. It fetches in-line comments in Lua code and converts them into a form that can be used...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local parameters_module = &amp;quot;Module:parameters&amp;quot;&lt;br /&gt;
local m_str_utils = require(&amp;quot;Module:string utilities&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local codepoint = m_str_utils.codepoint&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local u = m_str_utils.char&lt;br /&gt;
local rsplit = m_str_utils.split&lt;br /&gt;
local dump = mw.dumpObject&lt;br /&gt;
&lt;br /&gt;
--[===[ intro:&lt;br /&gt;
This module automatically generates documentation for other modules. It fetches in-line comments in Lua code and&lt;br /&gt;
converts them into a form that can be used on a documentation page via {{tl|module documentation}}. This module&amp;#039;s&lt;br /&gt;
documentation is in fact an example of it in action.&lt;br /&gt;
&lt;br /&gt;
It is helpful to do documentation this way, as it means function/method documentation is available in two places:&lt;br /&gt;
at the top of the module page (as conventional Wikitext), and above the function itself (as a Lua comment). Each&lt;br /&gt;
suits a different kind of editing style, and doing it this way keeps them synchronised.&lt;br /&gt;
&lt;br /&gt;
A section of documentation is given using Lua&amp;#039;s multi-line comment syntax, which looks something like this:&lt;br /&gt;
{--[==[ ... ]==]}. The number of equal signs should normally be two in order for the documentation to be properly&lt;br /&gt;
snarfed by {{tl|module documentation}}. The following conventions can be used inside of the documentation:&lt;br /&gt;
# Long lines other than in list items can be broken by newlines optionally followed by spaces or tabs, and long lines&lt;br /&gt;
  in list items can be broken by newlines followed by a space or tab. This is especially useful in lists, to make the&lt;br /&gt;
  raw comment more readable. In such a case, the newline and any following whitespace (i.e. spaces or tabs) is converted&lt;br /&gt;
  to a space. Use two newlines in a row to break paragraphs. In general, it&amp;#039;s recommended to break lines after at most&lt;br /&gt;
  120 characters, to facilitate reading the raw comment.&lt;br /&gt;
# Template calls (using two braces) can be inserted literally and will be expanded.&lt;br /&gt;
# Single braces can be used to surround literal text, and will automatically be syntax-highlighted as Lua code. Nested&lt;br /&gt;
  braces inside of this literal text will be properly handled as long as they&amp;#039;re balanced. If the first character of the&lt;br /&gt;
  literal text is itelf a brace, put a space before it (but not at the end), and it will be ignored.&lt;br /&gt;
# Backquotes can be used to surround literal text, which will be displayed using {&amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;}. The stuff inside of&lt;br /&gt;
  backquotes cannot contain a backquote or extend to multiple lines (see triple backquotes below for this).&lt;br /&gt;
# Double backquotes can be used to surround placeholder variable names, which will be displayed using monospaced italic&lt;br /&gt;
  (using {&amp;lt;code&amp;gt;&amp;lt;var&amp;gt;...&amp;lt;/var&amp;gt;&amp;lt;/code&amp;gt;}, or just {&amp;lt;var&amp;gt;...&amp;lt;/var&amp;gt;} in a monospaced context). The stuff inside of&lt;br /&gt;
  backquotes can only contain letters, numbers, underscores, hyphens and periods.&lt;br /&gt;
# Triple backquotes can be used to delimit a multiline block of literal text, which will be displayed monospaced and&lt;br /&gt;
  will not join lines broken by newline or interpret lists or other special symbols. Inside triple backquotes, double&lt;br /&gt;
  backquotes still work to delimit italicized placeholder variables, and single backquotes can be used to surround text&lt;br /&gt;
  that should &amp;#039;&amp;#039;not&amp;#039;&amp;#039; be monospaced.&lt;br /&gt;
# Outside of a backquote or code block context, use double underscores to surround a type, which is displayed italicized&lt;br /&gt;
  underlined. Only ASCII letters, numbers and underscore can occur inside the double underscores.&lt;br /&gt;
&lt;br /&gt;
Certain special directives can follow the opening multiline comment indicator, if placed on the same line as the&lt;br /&gt;
indicator. In particular, the following directives are currently recognized:&lt;br /&gt;
&lt;br /&gt;
* The directive `intro:` by itself signals introductory text, which will be placed at the beginning, prior to function&lt;br /&gt;
  documentation. This is useful to give a general introduction/overview of the module.&lt;br /&gt;
* The directive `var:` by itself at the beginning of a doc comment preceding a top-level variable definition causes&lt;br /&gt;
  the variable (before the assignment `=` sign) and its documentation to be included in the exported documentation.&lt;br /&gt;
  This is useful for documenting tables of property values and other important settings.&lt;br /&gt;
* The directive `func: export.&amp;lt;var&amp;gt;function&amp;lt;/var&amp;gt;(&amp;lt;var&amp;gt;arg1&amp;lt;/var&amp;gt;, &amp;lt;var&amp;gt;arg2&amp;lt;/var&amp;gt;, ...)` can be used when documenting a&lt;br /&gt;
  function declared in a nonstandard way (e.g. through a metatable, through an anonymous or locally-declared function&lt;br /&gt;
  assigned to the `export` table, etc.). The directive indicates the desired way for the function to appear, and the&lt;br /&gt;
  remainder of the comment describes the function&amp;#039;s operation, as usual.&lt;br /&gt;
]===]&lt;br /&gt;
&lt;br /&gt;
local TEMP_LEFT_BRACE = u(0xFFF0)&lt;br /&gt;
local TEMP_NEWLINE = u(0xFFF1)&lt;br /&gt;
&lt;br /&gt;
local function format_doc(str)&lt;br /&gt;
	local code_blocks = {}&lt;br /&gt;
	local code_blocks_i = 0&lt;br /&gt;
	local private_use_start = 0x100000&lt;br /&gt;
	-- Put a newline at the very beginning and end to facilitate further replacements. We will remove them later.&lt;br /&gt;
	str = &amp;quot;\n&amp;quot; .. str .. &amp;quot;\n&amp;quot;&lt;br /&gt;
	local subbed_str = (str&lt;br /&gt;
		-- Multiline literal text between backquotes; you can&amp;#039;t use &amp;lt;pre&amp;gt; or &amp;lt;syntaxhighlight&amp;gt; because that&lt;br /&gt;
		-- disables Wikitext parsing for &amp;lt;var&amp;gt;...&amp;lt;/var&amp;gt;, italics, &amp;lt;span&amp;gt;...&amp;lt;/span&amp;gt; etc. Instead use the trick of&lt;br /&gt;
		-- putting a space at the beginning of each line, which yields monospace text without disabling Wikitext&lt;br /&gt;
		-- interpretation.&lt;br /&gt;
		:gsub(&amp;quot;```(.-)```&amp;quot;, function(inside)&lt;br /&gt;
			return inside&lt;br /&gt;
				 -- placeholder variable names between double backquotes; we need to repeat this here to avoid&lt;br /&gt;
				 -- the following pattern for single backquotes from clobbering double backquotes&lt;br /&gt;
				:gsub(&amp;quot;``([A-Za-z0-9_%-. ]+)``&amp;quot;, &amp;quot;&amp;lt;var&amp;gt;%1&amp;lt;/var&amp;gt;&amp;quot;)&lt;br /&gt;
				 -- single backquotes undo monospacing&lt;br /&gt;
				:gsub(&amp;quot;`([^`\n]+)`&amp;quot;, &amp;#039;&amp;lt;span style=&amp;quot;font-family: sans-serif;&amp;quot;&amp;gt;%1&amp;lt;/span&amp;gt;&amp;#039;)&lt;br /&gt;
				 -- text on the first line should be monospaced&lt;br /&gt;
				:gsub(&amp;quot;^([^\n])&amp;quot;, &amp;quot; %1&amp;quot;)&lt;br /&gt;
				 -- text after a newline should be monospaced, and temp-escape the newline so later replacements&lt;br /&gt;
				 -- to join continued lines in a paragraph don&amp;#039;t take effect&lt;br /&gt;
				:gsub(&amp;quot;\n&amp;quot;, TEMP_NEWLINE .. &amp;quot; &amp;quot;)&lt;br /&gt;
				-- escape { so it won&amp;#039;t be interpreted as a code block&lt;br /&gt;
				:gsub(&amp;quot;{&amp;quot;, TEMP_LEFT_BRACE)&lt;br /&gt;
		end)&lt;br /&gt;
		:gsub(&amp;quot;``([A-Za-z0-9_%-. ]+)``&amp;quot;, &amp;quot;&amp;lt;var&amp;gt;%1&amp;lt;/var&amp;gt;&amp;quot;) -- placeholder variable names between double backquotes&lt;br /&gt;
		:gsub(&amp;quot;`([^`\n]+)`&amp;quot;, function(inside) -- literal text between backquotes, set using &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt;&lt;br /&gt;
			-- Escape { so it won&amp;#039;t be interpreted as a code block.&lt;br /&gt;
			inside = inside:gsub(&amp;quot;{&amp;quot;, TEMP_LEFT_BRACE)&lt;br /&gt;
			return &amp;quot;&amp;lt;code&amp;gt;&amp;quot; .. inside .. &amp;quot;&amp;lt;/code&amp;gt;&amp;quot;&lt;br /&gt;
		end)&lt;br /&gt;
		 -- {} blocks: blocks of code&lt;br /&gt;
		 -- Escape to avoid removing line breaks.&lt;br /&gt;
		:gsub(&amp;quot;%b{}&amp;quot;, function(m0)&lt;br /&gt;
			local next_char = m0:sub(2, 2)&lt;br /&gt;
			if next_char == &amp;quot;|&amp;quot; then&lt;br /&gt;
				-- Wikitable; don&amp;#039;t try to parse it as code. But we do want to parse special syntax in them (in&lt;br /&gt;
				-- particular {...} syntax for embedded code snippets), and if we return nil that won&amp;#039;t happen.&lt;br /&gt;
				-- Instead, we call format_doc() recursively on the innards.&lt;br /&gt;
				return &amp;quot;{&amp;quot; .. format_doc(m0:sub(2, -2)) .. &amp;quot;}&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			if next_char == &amp;quot;{&amp;quot; and m0:sub(-2, -2) == &amp;quot;}&amp;quot; then return nil end&lt;br /&gt;
			local text = &amp;quot;&amp;lt;syntaxhighlight lang=lua&amp;quot; .. (m0:match(&amp;quot;\n&amp;quot;) and &amp;quot;&amp;quot; or &amp;quot; inline&amp;quot;) .. &amp;quot;&amp;gt;&amp;quot; .. m0:sub(2, -2):gsub(&amp;quot;^ +&amp;quot;, &amp;quot;&amp;quot;) .. &amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&amp;quot;&lt;br /&gt;
			-- Prevent any further processing by storing the desired text into the `code_blocks` array and replacing&lt;br /&gt;
			-- the whole thing with a single private-use-area character.&lt;br /&gt;
			code_blocks_i = code_blocks_i + 1&lt;br /&gt;
			code_blocks[code_blocks_i] = text&lt;br /&gt;
			return u(private_use_start + code_blocks_i)&lt;br /&gt;
		end)&lt;br /&gt;
		-- Undo escaping of left brace to prevent code block interpretation.&lt;br /&gt;
		:gsub(TEMP_LEFT_BRACE, &amp;quot;{&amp;quot;)&lt;br /&gt;
		-- Remove indentation for list items.&lt;br /&gt;
		:gsub(&amp;quot;\n[ \t]+%f[*#:;]&amp;quot;, &amp;quot;\n&amp;quot;)&lt;br /&gt;
		-- Prevent a list item (beginning with #, *, : or ;) from being joined to the next line unless&lt;br /&gt;
		-- the next line starts with whitespace.&lt;br /&gt;
		:gsub(&amp;quot;%f[^\n]([*#:;][^\n]*)\n%f[^\n \t]&amp;quot;, &amp;quot;%1&amp;quot; .. TEMP_NEWLINE)&lt;br /&gt;
		-- Join continued lines in a paragraph. We don&amp;#039;t want to do that if there are two newlines in a row,&lt;br /&gt;
		-- and not if the second line begins with a list item (#, *, : or ;) or | indicating a wikitable&lt;br /&gt;
		-- item. In the process, compress any whitespace indentation at the beginning of the line.&lt;br /&gt;
    	:gsub(&amp;quot;%f[\n]\n[ \t]*([^ \t\n#*:;|])&amp;quot;, &amp;quot; %1&amp;quot;)&lt;br /&gt;
		-- Double-underline to indicate types (displayed as italicized underlined).&lt;br /&gt;
		:gsub(&amp;quot;__([_%w]-)__&amp;quot;, function(inside)&lt;br /&gt;
			return &amp;quot;&amp;lt;u&amp;gt;&amp;lt;i&amp;gt;&amp;quot; .. inside .. &amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/u&amp;gt;&amp;quot;&lt;br /&gt;
		end)&lt;br /&gt;
		-- Undo escaping of newline to prevent joining of continued lines.&lt;br /&gt;
		:gsub(TEMP_NEWLINE, &amp;quot;\n&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
	-- Put &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt; around &amp;lt;var&amp;gt;...&amp;lt;/var&amp;gt; invocations that don&amp;#039;t already occur inside of&lt;br /&gt;
	-- &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt; blocks.&lt;br /&gt;
	local split_on_code = rsplit(subbed_str, &amp;quot;(&amp;lt;code&amp;gt;.-&amp;lt;/code&amp;gt;)&amp;quot;)&lt;br /&gt;
	for i = 1, #split_on_code, 2 do&lt;br /&gt;
		split_on_code[i] = split_on_code[i]:gsub(&amp;quot;(&amp;lt;var&amp;gt;.-&amp;lt;/var&amp;gt;)&amp;quot;, &amp;quot;&amp;lt;code&amp;gt;%1&amp;lt;/code&amp;gt;&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	subbed_str = concat(split_on_code)&lt;br /&gt;
	local retval = (subbed_str&lt;br /&gt;
		-- Undo code-block stashing.&lt;br /&gt;
		:gsub(&amp;quot;\244[\128-\191][\128-\191][\128-\191]&amp;quot;, function(char)&lt;br /&gt;
			return code_blocks[codepoint(char) - private_use_start]&lt;br /&gt;
		-- Remove extra newlines added at beginning and end.&lt;br /&gt;
		end))&lt;br /&gt;
	retval = mw.text.trim(retval)&lt;br /&gt;
	&lt;br /&gt;
	-- mw.log((&amp;quot;Returning: %s&amp;quot;):format(dump(retval)))&lt;br /&gt;
	return retval&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[===[&lt;br /&gt;
The main entrypoint for {{tl|module documentation}}. The frame object can contain 3 optional arguments:&lt;br /&gt;
* {{para|comment_level}}: The number of equals signs (=) a given section uses. Default: 2 (i.e. {--[==[ ... (comment block) ]==]})&lt;br /&gt;
*: e.g. The value 4 means {--[====[ ... (comment block) ]====]}.&lt;br /&gt;
* {{para|section_level}}: The header level used for each function/method. Default: 3 (i.e. L3: {=== ... ===}).&lt;br /&gt;
* {{para|identifier}}: A Lua string pattern. Only the comments of functions whose names match this pattern are used. When not&lt;br /&gt;
  given, all function are accepted.&lt;br /&gt;
*: This is useful when giving object methods, using a pattern such as {^object_name:}.&lt;br /&gt;
]===]&lt;br /&gt;
function export.show(frame)&lt;br /&gt;
	local parent_args = frame:getParent().args&lt;br /&gt;
	&lt;br /&gt;
	local params = {&lt;br /&gt;
		comment_level = {type = &amp;quot;number&amp;quot;, default = 2},&lt;br /&gt;
		section_level = {type = &amp;quot;number&amp;quot;, default = 3},&lt;br /&gt;
		identifier = true,&lt;br /&gt;
		omit_intro = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
	}&lt;br /&gt;
	local args = require(parameters_module).process(parent_args, params)&lt;br /&gt;
	&lt;br /&gt;
	local comment_level = args.comment_level&lt;br /&gt;
	-- `typeid` matches the identifier at the beginning of the comment that marks this comment as of a special type&lt;br /&gt;
	-- that is snarfed by this module. It can be `nil` for regular function comments, which don&amp;#039;t have a preceding&lt;br /&gt;
	-- special identifier (they just have to match in the number of equal signs, which is usually two). This function&lt;br /&gt;
	-- generates a Lua pattern that matches a comment with the right number of equal signs and possibly with the&lt;br /&gt;
	-- special identifier at the beginning. The comment has one or more captures: any captures in `typeid` come at&lt;br /&gt;
	-- the beginning, followed by a capture for the comment text (after any introductory special identifier).&lt;br /&gt;
	local function make_comment_pattern(typeid)&lt;br /&gt;
		if typeid then&lt;br /&gt;
			typeid = &amp;quot;%s*&amp;quot; .. typeid&lt;br /&gt;
		else&lt;br /&gt;
			typeid = &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		return &amp;quot;%-%-%[&amp;quot; .. (&amp;quot;=&amp;quot;):rep(comment_level) .. &amp;quot;%[&amp;quot; .. typeid .. &amp;quot;\n?(.-)[\t\n]*%]&amp;quot; .. (&amp;quot;=&amp;quot;):rep(comment_level) .. &amp;quot;%]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local fn_comment_pattern = make_comment_pattern(nil)&lt;br /&gt;
	local intro_comment_pattern = make_comment_pattern(&amp;quot;intro:&amp;quot;)&lt;br /&gt;
	local metafunc_comment_pattern = make_comment_pattern(&amp;quot;func:%s*(([^\n(]+)[^\n)]+%))&amp;quot;)&lt;br /&gt;
	local var_comment_pattern = make_comment_pattern(&amp;quot;var:&amp;quot;)&lt;br /&gt;
	local section_mark = (&amp;quot;=&amp;quot;):rep(args.section_level)&lt;br /&gt;
	local pattern_identifier = args.identifier or &amp;quot;&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	local mod_title = mw.title.getCurrentTitle()&lt;br /&gt;
	if mod_title.text:match(&amp;quot;/documentation$&amp;quot;) then return &amp;quot;(&amp;lt;i&amp;gt;The generated documentation is located at the module page.&amp;lt;/i&amp;gt;)&amp;quot; end&lt;br /&gt;
	local mod_text = mod_title:getContent()&lt;br /&gt;
	if not mod_text then return &amp;quot;(&amp;lt;i&amp;gt;The module page does not exist now.&amp;lt;/i&amp;gt;)&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	-- This contains function and intro documentation. Each element is a two-element list of {POSITION, DOCS} specifying&lt;br /&gt;
	-- the generated documentation for a function and the character position in the file where it was found (for sorting&lt;br /&gt;
	-- purposes).&lt;br /&gt;
	local docs&lt;br /&gt;
&lt;br /&gt;
	if args.omit_intro then	&lt;br /&gt;
		docs = {}&lt;br /&gt;
	else&lt;br /&gt;
		local intro_comment = mod_text:match(&amp;quot;^.-&amp;quot; .. intro_comment_pattern)&lt;br /&gt;
		if intro_comment then&lt;br /&gt;
			docs = { {1, format_doc(intro_comment) }}&lt;br /&gt;
		else&lt;br /&gt;
			docs = {}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Look for actual functions.&lt;br /&gt;
	for p0, f, fn in mod_text:gmatch(&amp;quot;()\n[ \t]*function +(([^\n(]+)[^\n)]+%))&amp;quot;) do&lt;br /&gt;
		if fn:match(pattern_identifier) then			&lt;br /&gt;
			local c = mod_text:sub(1, p0 - 1):match(&amp;quot;^.*&amp;quot; .. fn_comment_pattern .. &amp;quot;%s*$&amp;quot;)&lt;br /&gt;
			insert(docs, {p0, section_mark .. fn .. section_mark .. &amp;quot;\n\n&amp;quot; .. &amp;quot;&amp;lt;syntaxhighlight lang=lua inline&amp;gt;function &amp;quot; ..&lt;br /&gt;
				f .. &amp;quot;&amp;lt;/syntaxhighlight&amp;gt;\n\n&amp;quot; .. format_doc(c or&lt;br /&gt;
				&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;This function lacks documentation. Please add a description of its usages, inputs and outputs, &amp;#039; ..&lt;br /&gt;
				&amp;quot;or its difference from similar functions, or make it local to remove it from the function list.&amp;lt;/strong&amp;gt;&amp;quot; ..&lt;br /&gt;
				&amp;quot;[[Category:Templates and modules needing documentation]]&amp;quot;)})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Now look for comments with the function declaration inside them (used for metatable functions etc.).&lt;br /&gt;
	for p0, f, fn, comment in mod_text:gmatch(&amp;quot;()&amp;quot; .. metafunc_comment_pattern) do&lt;br /&gt;
		insert(docs, {p0, section_mark .. fn .. section_mark .. &amp;quot;\n\n&amp;quot; .. &amp;quot;&amp;lt;syntaxhighlight lang=lua inline&amp;gt;function &amp;quot; .. f ..&lt;br /&gt;
			&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;\n\n&amp;quot; .. format_doc(comment)})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Now look for variables with var: comments preceding.&lt;br /&gt;
	for p0, comment, p1 in mod_text:gmatch(&amp;quot;()&amp;quot; .. var_comment_pattern .. &amp;quot;()&amp;quot;) do&lt;br /&gt;
		local after_text = mod_text:sub(p1)&lt;br /&gt;
		local first_var = after_text:match(&amp;quot;\n(.-)%s*=&amp;quot;)&lt;br /&gt;
		if not first_var then&lt;br /&gt;
			first_var = (&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Unable to locate variable definition starting at position %s&amp;lt;/strong&amp;gt;&amp;#039;):format(p1)&lt;br /&gt;
		end&lt;br /&gt;
		insert(docs, {p0, section_mark .. first_var .. section_mark .. &amp;quot;\n\n&amp;quot; .. &amp;quot;&amp;lt;syntaxhighlight lang=lua inline&amp;gt;&amp;quot; ..&lt;br /&gt;
			first_var .. &amp;quot;&amp;lt;/syntaxhighlight&amp;gt;\n\n&amp;quot; .. format_doc(comment)})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	table.sort(docs, function(a, b) return a[1] &amp;lt; b[1] end)&lt;br /&gt;
	&lt;br /&gt;
	local chunks = {}&lt;br /&gt;
	for i, decl in ipairs(docs) do&lt;br /&gt;
		insert(chunks, decl[2])&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return frame:preprocess(concat(chunks, &amp;quot;\n\n&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>