Модул:module documentation
Ин модул ба таври худкор ҳуҷҷатҳоро барои модулҳои дигар тавлид мекунад. Он шарҳҳои дохилиро дар рамзи Луа ва онҳоро ба шакле табдил медиҳад, ки метавонад дар саҳифаи ҳуҷҷатгузорӣ тавассути {{ҳуҷҷатҳои модули}} истифода шавад. Дар асл, ин ҳуҷҷатгузории модул намунаи он дар амал аст!
Бо ин роҳ ҳуҷҷатгузорӣ кардан муфид аст, зеро ин маънои онро дорад, ки ҳуҷҷатҳои функсия/метод дар ду ҷой дастрасанд: дар болои саҳифаи модул (ҳамчун Викиматни муқаррарӣ) ва болои худи функсия (ҳамчун шарҳи Lua). Хар як ба намуди дигари таҳрир мувофиқат мекунад ва бо ин роҳ онҳоро ҳамоҳанг нигоҳ медорад.
Қисмати ҳуҷҷатҳо бо истифода аз синтаксиси шарҳи бисёрсатраи Луа дода мешавад, ки чунин менамояд: --[==[ ... ]==]
. Шумораи аломатҳои баробар одатан бояд ду бошад, то ҳуҷҷатгузорӣ дуруст бошад аз ҷониби {{ҳуҷҷатҳои модул}} . Дар дохили ҳуҷҷатҳо конвенсияҳои зерин метавонанд истифода шаванд:
- Сатрҳои дароз (ҳам дар сархатҳои муқаррарӣ ва ҳам дар ҷузъҳои рӯйхат) метавонанд бо сатрҳои нав ва ихтиёрӣ бо фосилаҳо шикаста шаванд ё ҷадвалҳо (махсусан дар рӯйхатҳо муфид аст, то шарҳи хомро бештар хонда шавад). Дар ин ҳолат, сатри нав табдил дода мешавад ба фосила. Барои шикастани параграфҳо ду сатри навро дар як саф истифода баред. Умуман, тавсия дода мешавад, ки хатҳоро пас аз ҳадди аксар вайрон кунед 120 аломат, барои осон кардани хондани шарҳи хом.
- Зангҳои қолабӣ (бо истифода аз ду қавс) мумкин аст айнан ворид карда шаванд ва васеъ карда мешаванд.
- Қавсҳои ягонаро барои иҳота кардани матни аслӣ истифода бурдан мумкин аст ва ба таври худкор ҳамчун рамзи Lua бо синтаксис таъкид карда мешаванд. Ҷойгиршуда Қавсҳои дохили ин матни аслӣ то даме ки онҳо мутавозинанд, дуруст коркард карда мешаванд. Агар аломати якуми матни аслӣ қавс аст, пеш аз он фосила гузоред (вале на дар охири) ва он сарфи назар карда мешавад.
- Иқтибосҳои ақиб метавонад барои иҳота кардани матни аслӣ истифода шавад, ки бо истифода аз
<code>...</code>
намоиш дода мешавад. Маводи дохили иқтибосҳои бозгашт наметавонанд иқтибоси ақибро дар бар гиранд (ба истиснои номҳои тағирёбандаи ҷойнишини дукарата) хатҳо. - Иқтибосҳои дукарата метавонанд барои иҳота кардани номҳои тағирёбандаи ҷойнишин истифода шаванд, ки бо истифода аз
<var>...</var>
намоиш дода мешаванд. Маводи даруни иқтибосҳои ақиб метавонад танҳо ҳарфҳо, рақамҳо, зерхатҳо, дефисҳо ва нуқтаҳоро дар бар гирад. Одатан, чунин Ҷойгиркунакҳо бояд дар шрифти монофазоӣ нишон дода шаванд, гӯё дар иҳотаи<code>...</code>
. Ин таъсир метавонад бошад бо истифода аз иқтибосҳои сегона ба даст оварда шудааст, ки синтаксиси дукаратаи ақибро дар дохили иқтибоси яккаса самаранок истифода мебарад синтаксис.
Баъзе директиваҳои махсус метавонанд нишондиҳандаи шарҳи бисёрсатрии кушодаро риоя кунанд, агар дар як сатр ҷойгир карда шаванд нишондиҳанда. Аз ҷумла, дар айни замон дастурҳои зерин эътироф карда мешаванд:
- Директиваи
муқаддима:
худ аз худ ба матни муқаддимавӣ ишора мекунад, ки дар аввал пеш аз фаъолият ҷойгир карда мешавад. ҳуҷҷатгузорӣ. Ин барои додани муқаддима/шарҳи умумии модул муфид аст. - Дастури
func: export.function(arg1, arg2, ...)
метавонад ҳангоми ҳуҷҷатгузории функсияе, ки ба таври ғайристандартӣ эълон шудааст (масалан, тавассути метаҷадвал, тавассути функсияи номаълум ё ба таври маҳаллӣ эълоншуда ба ҷадвали "экспорт" таъин карда шудааст ва ғайра). Директива роҳи дилхоҳи пайдоиши функсияро нишон медиҳад ва боқимондаи шарҳ кори функсияро, чун маъмул, тавсиф мекунад.
export.show
[вироиш]function export.show(frame)
The main entrypoint for {{module documentation}} . The frame object can contain 3 optional arguments:
|comment_level=
: The number of equals signs (=) a given section uses. Default: 2 (i.e.--[==[ ... (comment block) ]==]
)- e.g. The value 4 means
--[====[ ... (comment block) ]====]
.
- e.g. The value 4 means
|section_level=
: The header level used for each function/method. Default: 2 (i.e. L2:== ... ==
).|identifier=
: A Lua string pattern. Only the comments of functions whose names match this pattern are used. When not given, all function are accepted.- This is useful when giving object methods, using a pattern such as
^object_name:
.
- This is useful when giving object methods, using a pattern such as
local m_str_utils = require("Module:string utilities")
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 export = {}
--[===[ intro:
Ин модул ба таври худкор ҳуҷҷатҳоро барои модулҳои дигар тавлид мекунад. Он шарҳҳои дохилиро дар рамзи Луа ва
онҳоро ба шакле табдил медиҳад, ки метавонад дар саҳифаи ҳуҷҷатгузорӣ тавассути {{tl|ҳуҷҷатҳои модули}} истифода шавад. Дар асл, ин
ҳуҷҷатгузории модул намунаи он дар амал аст!
Бо ин роҳ ҳуҷҷатгузорӣ кардан муфид аст, зеро ин маънои онро дорад, ки ҳуҷҷатҳои функсия/метод дар ду ҷой дастрасанд:
дар болои саҳифаи модул (ҳамчун Викиматни муқаррарӣ) ва болои худи функсия (ҳамчун шарҳи Lua). Хар як
ба намуди дигари таҳрир мувофиқат мекунад ва бо ин роҳ онҳоро ҳамоҳанг нигоҳ медорад.
Қисмати ҳуҷҷатҳо бо истифода аз синтаксиси шарҳи бисёрсатраи Луа дода мешавад, ки чунин менамояд:
{--[==[ ... ]==]}. Шумораи аломатҳои баробар одатан бояд ду бошад, то ҳуҷҷатгузорӣ дуруст бошад
аз ҷониби {{tl|ҳуҷҷатҳои модул}}. Дар дохили ҳуҷҷатҳо конвенсияҳои зерин метавонанд истифода шаванд:
# Сатрҳои дароз (ҳам дар сархатҳои муқаррарӣ ва ҳам дар ҷузъҳои рӯйхат) метавонанд бо сатрҳои нав ва ихтиёрӣ бо фосилаҳо шикаста шаванд
ё ҷадвалҳо (махсусан дар рӯйхатҳо муфид аст, то шарҳи хомро бештар хонда шавад). Дар ин ҳолат, сатри нав табдил дода мешавад
ба фосила. Барои шикастани параграфҳо ду сатри навро дар як саф истифода баред. Умуман, тавсия дода мешавад, ки хатҳоро пас аз ҳадди аксар вайрон кунед
120 аломат, барои осон кардани хондани шарҳи хом.
# Зангҳои қолабӣ (бо истифода аз ду қавс) мумкин аст айнан ворид карда шаванд ва васеъ карда мешаванд.
# Қавсҳои ягонаро барои иҳота кардани матни аслӣ истифода бурдан мумкин аст ва ба таври худкор ҳамчун рамзи Lua бо синтаксис таъкид карда мешаванд. Ҷойгиршуда
Қавсҳои дохили ин матни аслӣ то даме ки онҳо мутавозинанд, дуруст коркард карда мешаванд. Агар аломати якуми
матни аслӣ қавс аст, пеш аз он фосила гузоред (вале на дар охири) ва он сарфи назар карда мешавад.
# Иқтибосҳои ақиб метавонад барои иҳота кардани матни аслӣ истифода шавад, ки бо истифода аз {<code>...</code>} намоиш дода мешавад. Маводи дохили
иқтибосҳои бозгашт наметавонанд иқтибоси ақибро дар бар гиранд (ба истиснои номҳои тағирёбандаи ҷойнишини дукарата)
хатҳо.
# Иқтибосҳои дукарата метавонанд барои иҳота кардани номҳои тағирёбандаи ҷойнишин истифода шаванд, ки бо истифода аз {<var>...</var>} намоиш дода мешаванд.
Маводи даруни иқтибосҳои ақиб метавонад танҳо ҳарфҳо, рақамҳо, зерхатҳо, дефисҳо ва нуқтаҳоро дар бар гирад. Одатан, чунин
Ҷойгиркунакҳо бояд дар шрифти монофазоӣ нишон дода шаванд, гӯё дар иҳотаи {<code>...</code>}. Ин таъсир метавонад бошад
бо истифода аз иқтибосҳои сегона ба даст оварда шудааст, ки синтаксиси дукаратаи ақибро дар дохили иқтибоси яккаса самаранок истифода мебарад
синтаксис.
Баъзе директиваҳои махсус метавонанд нишондиҳандаи шарҳи бисёрсатрии кушодаро риоя кунанд, агар дар як сатр ҷойгир карда шаванд
нишондиҳанда. Аз ҷумла, дар айни замон дастурҳои зерин эътироф карда мешаванд:
* Директиваи `муқаддима:` худ аз худ ба матни муқаддимавӣ ишора мекунад, ки дар аввал пеш аз фаъолият ҷойгир карда мешавад.
ҳуҷҷатгузорӣ. Ин барои додани муқаддима/шарҳи умумии модул муфид аст.
* Дастури `func: export.<var>function</var>(<var>arg1</var>, <var>arg2</var>, ...)` метавонад ҳангоми ҳуҷҷатгузории
функсияе, ки ба таври ғайристандартӣ эълон шудааст (масалан, тавассути метаҷадвал, тавассути функсияи номаълум ё ба таври маҳаллӣ эълоншуда
ба ҷадвали "экспорт" таъин карда шудааст ва ғайра). Директива роҳи дилхоҳи пайдоиши функсияро нишон медиҳад ва
боқимондаи шарҳ кори функсияро, чун маъмул, тавсиф мекунад.
]===]
local TEMP_LEFT_BRACE = u(0xFFF0)
local TEMP_NEWLINE = u(0xFFF1)
local function format_doc(str)
local code_blocks = {}
local code_blocks_i = 0
local private_use_start = 0x100000
local subbed_str = (str
-- Multiline literal text between backquotes; you can't use <pre> or <syntaxhighlight> because that
-- disables Wikitext parsing for <var>...</var>, italics, <span>...</span> etc. Instead use the trick of
-- putting a space at the beginning of each line, which yields monospace text without disabling Wikitext
-- interpretation.
:gsub("```(.-)```", function(inside)
return inside
-- placeholder variable names between double backquotes; we need to repeat this here to avoid
-- the following pattern for single backquotes from clobbering double backquotes
:gsub("``([A-Za-z0-9_%-. ]+)``", "<var>%1</var>")
-- single backquotes undo monospacing
:gsub("`([^`\n]+)`", '<span style="font-family: sans-serif;">%1</span>')
-- text on the first line should be monospaced
:gsub("^([^\n])", " %1")
-- text after a newline should be monospaced, and temp-escape the newline so later replacements
-- to join continued lines in a paragraph don't take effect
:gsub("\n", TEMP_NEWLINE .. " ")
-- escape { so it won't be interpreted as a code block
:gsub("{", TEMP_LEFT_BRACE)
end)
:gsub("``([A-Za-z0-9_%-. ]+)``", "<var>%1</var>") -- placeholder variable names between double backquotes
:gsub("`([^`\n]+)`", function(inside) -- literal text between backquotes, set using <code>...</code>
-- Escape { so it won't be interpreted as a code block.
inside = inside:gsub("{", TEMP_LEFT_BRACE)
return "<code>" .. inside .. "</code>"
end)
-- {} blocks: blocks of code
-- Escape to avoid removing line breaks.
:gsub("%b{}", function(m0)
local next_char = m0:sub(2, 2)
if next_char == "|" then
-- Wikitable; don't try to parse it as code. But we do want to parse special syntax in them (in
-- particular {...} syntax for embedded code snippets), and if we return nil that won't happen.
-- Instead, we call format_doc() recursively on the innards.
return "{" .. format_doc(m0:sub(2, -2)) .. "}"
end
if next_char == "{" and m0:sub(-2, -2) == "}" then return nil end
local text = "<syntaxhighlight lang=lua" .. (m0:match("\n") and "" or " inline") .. ">" .. m0:sub(2, -2):gsub("^ +", "") .. "</syntaxhighlight>"
-- Prevent any further processing by storing the desired text into the `code_blocks` array and replacing
-- the whole thing with a single private-use-area character.
code_blocks_i = code_blocks_i + 1
code_blocks[code_blocks_i] = text
return u(private_use_start + code_blocks_i)
end)
-- undo escaping of left brace to prevent code block interpretation
:gsub(TEMP_LEFT_BRACE, "{")
-- Join continued lines in a paragraph. We don't want to do that if there are two newlines in a row,
-- and not if the second line begins with whitespace or a certain special characters (#, * or : indicating
-- a list item; | indicating a wikitable item; semicolon for bolded items).
:gsub("([^\n])\n[ \t]*([^ \t\n#*:;|])", "%1 %2")
-- Repeat the previous in case of a single-character line (admittedly rare).
:gsub("([^\n])\n[ \t]*([^ \t\n#*:;|])", "%1 %2")
:gsub("\n[ \t]+%f[*#:;]", "\n") -- remove indentation for list items
:gsub("%f[\n,{]\n%f[^\n*#:;]", "\n\n") -- wiki newlines
:gsub("(\n[ *#:]*)(|?[_%w]+=?):", "%1<code><b>%2</b></code>:") -- parameter names
-- double-underline to indicate types (displayed as italicized underlined)
:gsub("__(.-)__", function(inside)
return "<u><i>" .. inside .. "</i></u>"
end)
-- undo escaping of newline to prevent joining of continued lines
:gsub(TEMP_NEWLINE, "\n"))
-- Put <code>...</code> around <var>...</var> invocations that don't already occur inside of
-- <code>...</code> blocks.
local split_on_code = rsplit(subbed_str, "(<code>.-</code>)")
for i = 1, #split_on_code, 2 do
split_on_code[i] = split_on_code[i]:gsub("(<var>.-</var>)", "<code>%1</code>")
end
subbed_str = concat(split_on_code)
return (subbed_str
-- Undo code-block stashing.
:gsub("\244[\128-\191][\128-\191][\128-\191]", function(char)
return code_blocks[codepoint(char) - private_use_start]
end))
end
--[===[
The main entrypoint for {{tl|module documentation}}. The frame object can contain 3 optional arguments:
* |comment_level=: The number of equals signs (=) a given section uses. Default: 2 (i.e. {--[==[ ... (comment block) ]==]})
*: e.g. The value 4 means {--[====[ ... (comment block) ]====]}.
* |section_level=: The header level used for each function/method. Default: 2 (i.e. L2: {== ... ==}).
* |identifier=: A Lua string pattern. Only the comments of functions whose names match this pattern are used. When not given, all function are accepted.
*: This is useful when giving object methods, using a pattern such as {^object_name:}.
]===]
function export.show(frame)
local args = frame:getParent().args or {}
local comment_level = tonumber(args["comment_level"]) or 2
local function make_comment_pattern(typeid)
if typeid then
typeid = "%s*" .. typeid
else
typeid = ""
end
return "%-%-%[" .. ("="):rep(comment_level) .. "%[" .. typeid .. "\n?(.-)[\t\n]*]" .. ("="):rep(comment_level) .. "]()"
end
local fn_comment_pattern = make_comment_pattern(nil)
local intro_comment_pattern = make_comment_pattern("intro:")
local metafunc_comment_pattern = make_comment_pattern("func:%s*(([^\n(]+)[^\n)]+%))")
local section_mark = ("="):rep(tonumber(args["section_level"]) or 2)
local pattern_identifier = args["identifier"] or ""
local mod_title = mw.title.getCurrentTitle()
if mod_title.text:match("/documentation$") then return "(<i>The generated documentation is located at the module page.</i>)" end
local mod_text = mod_title:getContent()
if not mod_text then return "(<i>The module page does not exist now.</i>)" end
-- This contains function and intro documentation. Each element is a two-element list of {POSITION, DOCS} specifying
-- the generated documentation for a function and the character position in the file where it was found (for sorting
-- purposes).
local docs
local intro_comment = mod_text:match("^.-" .. intro_comment_pattern)
if intro_comment then
docs = { {1, format_doc(intro_comment) }}
else
docs = {}
end
-- Look for actual functions.
for p0, f, fn in mod_text:gmatch("()\n[ \t]*function +(([^\n(]+)[^\n)]+%))") do
if fn:match(pattern_identifier) then
local c = mod_text:sub(1, p0 - 1):match("^.*" .. fn_comment_pattern .. "%s*$")
insert(docs, {p0, section_mark .. fn .. section_mark .. "\n\n" .. "<syntaxhighlight lang=lua inline>function " ..
f .. "</syntaxhighlight>\n\n" .. format_doc(c or
'<strong class="error">This function lacks documentation. Please add a description of its usages, inputs and outputs, ' ..
"or its difference from similar functions, or make it local to remove it from the function list.</strong>" ..
"[[Category:Шаблонҳо ва модулҳое, ки ба ҳуҷҷат ниёз доранд]]")})
end
end
-- Now look for comments with the function declaration inside them (used for metatable functions etc.).
for p0, f, fn, comment in mod_text:gmatch("()" .. metafunc_comment_pattern) do
insert(docs, {p0, section_mark .. fn .. section_mark .. "\n\n" .. "<syntaxhighlight lang=lua inline>function " .. f .. "</syntaxhighlight>\n\n" .. format_doc(comment)})
end
table.sort(docs, function(a, b) return a[1] < b[1] end)
local chunks = {}
for i, decl in ipairs(docs) do
insert(chunks, decl[2])
end
return frame:preprocess(concat(chunks, "\n\n"))
end
return export