-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tags from JSDoc #363
Comments
@WikiaUsers a patch to expose flag tags and improve exports in your documentation, probably broken:diff --git a/docbunto.lua b/docbunto.lua
index 246fee0..2ec3252 100644
--- a/docbunto.lua
+++ b/docbunto.lua
@@ -3,17 +3,17 @@
-- the form of MediaWiki markup, using `@tag`-prefixed comments embedded
-- in the source code of a Scribunto module. The taglet parser & doclet
-- renderer Docbunto uses are also publicly exposed to other modules.
---
+--
-- Docbunto code items are introduced by a block comment (`--[[]]--`), an
-- inline comment with three hyphens (`---`), or a inline `@tag` comment.
-- The module can use static code analysis to infer variable names, item
-- privacy (`local` keyword), tables (`{}` constructor) and functions
-- (`function` keyword). MediaWiki and Markdown formatting is supported.
---
+--
-- Items are usually rendered in the order they are defined, if they are
-- public items, or emulated classes extending the Lua primitives. There
-- are many customisation options available to change Docbunto behaviour.
---
+--
-- @module docbunto
-- @alias p
-- @require Module:I18n
@@ -329,14 +328,14 @@ end
--- Item export utility.
-- @function export_item
-- @param {table} documentation Package documentation data.
--- @param {string} name Identifier name for item.
--- @param {string} item_no Identifier name for item.
--- @param {string} alias Export alias for item.
--- @param {boolean} factory Whether the documentation item is a factory function.
+-- @param {string} item_reference Identifier name for item.
+-- @param {string} item_index Identifier name for item.
+-- @param {string} item_alias Export alias for item.
+-- @param {boolean} factory_item Whether the documentation item is a factory function.
-- @local
-local function export_item(documentation, name, item_no, alias, factory)
+local function export_item(documentation, item_reference, item_index, item_alias, factory_item)
for _, item in ipairs(documentation.items) do
- if name == item.name then
+ if item_reference == item.name then
item.tags['local'] = nil
item.tags['private'] = nil
@@ -348,17 +347,17 @@ local function export_item(documentation, name, item_no, alias, factory)
item.type = item.type:gsub('variable', 'member')
- if factory then
+ if factory_item then
item.alias =
- documentation.items[item_no].tags['factory'].value ..
- (alias:find('^%[') and '' or (not item.tags['static'] and ':' or '.')) ..
- alias
+ documentation.items[item_index].tags['factory'].value ..
+ (item_alias:find('^%[') and '' or (not item.tags['static'] and ':' or '.')) ..
+ item_alias
else
item.alias =
((documentation.tags['alias'] or {}).value or documentation.name) ..
- (alias:find('^%[') and '' or (documentation.type == 'classmod' and not item.tags['static'] and ':' or '.')) ..
- alias
+ (item_alias:find('^%[') and '' or (documentation.type == 'classmod' and not item.tags['static'] and ':' or '.')) ..
+ item_alias
end
item.hierarchy = mw.text.split((item.alias:gsub('["\']?%]', '')), '[.:%[\'""]+')
@@ -564,19 +563,28 @@ local function render_item(stream, item, options, preop)
if preop then preop(item, options) end
local item_name = item.alias or item.name
+ local item_type = item.type
+
+ for _, name in ipairs(p.tags._subtype_hierarchy) do
+ if item.tags[name] then
+ item_type = item_type .. i18n:msg('separator-dot') .. name
+ end
+ end
+ item_type = i18n:msg('parentheses', item_type)
+
if options.strip and item.export and item.hierarchy then
item_name = item_name:gsub('^[%w_]+[.[]?', '')
end
type_reference(item, options)
- stream:wikitext(';<code id="' .. item_id .. '">' .. item_name .. '</code>' .. i18n:msg('parentheses', item.type)):newline()
+ stream:wikitext(';<code id="' .. item_id .. '">' .. item_name .. '</code>' .. item_type):newline()
if (#(item.summary or '') + #item.description) ~= 0 then
- local sep = #(item.summary or '') ~= 0 and #item.description ~= 0
+ local separator = #(item.summary or '') ~= 0 and #item.description ~= 0
and (item.description:find('^[{:#*]+%s+') and '\n' or ' ')
or ''
- local intro = (item.summary or '') .. sep .. item.description
+ local intro = (item.summary or '') .. separator .. item.description
stream:wikitext(':' .. intro:gsub('\n([{:#*])', '\n:%1'):gsub('\n\n([^=])', '\n:%1')):newline()
end
end
@@ -636,7 +644,7 @@ local function render_tag(stream, name, tag, options, preop)
if tag_el.value:find('\n[{:#*]') and (tag_el.type or (tag_el.modifiers or {})['opt']) then
stream:newline():wikitext(':' .. (options.ulist and '*' or ':') .. (tag_el.value:match('^[*:]+') or ''))
end
-
+
if tag_el.type and (tag_el.modifiers or {})['opt'] then
stream:wikitext(i18n:msg{
key = 'parentheses',
@@ -966,7 +974,7 @@ function p.taglet(modname, options)
documentation.tags = {}
documentation.items = {}
local line_no = 0
- local item_no = 0
+ local item_index = 0
-- Taglet tracking variables.
local start_mode = true
@@ -1008,7 +1016,7 @@ function p.taglet(modname, options)
pragma_mode = tag_name == 'pragma'
export_mode = tag_name == 'export'
special_tag = pragma_mode or export_mode
- local tags, subtokens, sep
+ local tags, subtokens, separator
-- Line counter.
if t.posFirst == 1 then
@@ -1024,10 +1032,10 @@ function p.taglet(modname, options)
table.insert(documentation.comments, t.data)
if comment_mode and not new_tag and not doctag_mode and not comment_brace and not pretty_comment then
- sep = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
+ separator = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
and '\n'
or (#documentation.description ~= 0 and DOCBUNTO_CONCAT or '')
- documentation.description = documentation.description .. sep .. mw.text.trim(comment_tail)
+ documentation.description = documentation.description .. separator .. mw.text.trim(comment_tail)
end
if new_tag and not special_tag then
@@ -1037,10 +1045,10 @@ function p.taglet(modname, options)
elseif doctag_mode and not comment_brace and not pretty_comment then
tags = documentation.tags
if p.tags[tags[#tags].name] == TAG_MULTI then
- sep = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
+ separator = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
and '\n'
or DOCBUNTO_CONCAT
- tags[#tags].value = tags[#tags].value .. sep .. mw.text.trim(comment_tail)
+ tags[#tags].value = tags[#tags].value .. separator .. mw.text.trim(comment_tail)
elseif p.tags[tags[#tags].name] == TAG_MULTI_LINE then
tags[#tags].value = tags[#tags].value .. '\n' .. comment_tail
end
@@ -1050,49 +1058,49 @@ function p.taglet(modname, options)
-- Documentation item detection.
if not start_mode and (new_item or (new_tag and tokens[i - 1].type ~= 'comment')) and not special_tag then
table.insert(documentation.items, {})
- item_no = item_no + 1
- documentation.items[item_no].lineno = line_no
- documentation.items[item_no].code = ''
- documentation.items[item_no].comments = {}
- documentation.items[item_no].description = ''
- documentation.items[item_no].tags = {}
+ item_index = item_index + 1
+ documentation.items[item_index].lineno = line_no
+ documentation.items[item_index].code = ''
+ documentation.items[item_index].comments = {}
+ documentation.items[item_index].description = ''
+ documentation.items[item_index].tags = {}
end
if not start_mode and comment_mode and not new_tag and not doctag_mode and not comment_brace and not pretty_comment then
- sep = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
+ separator = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
and '\n'
- or (#documentation.items[item_no].description ~= 0 and DOCBUNTO_CONCAT or '')
- documentation.items[item_no].description =
- documentation.items[item_no].description ..
- sep ..
+ or (#documentation.items[item_index].description ~= 0 and DOCBUNTO_CONCAT or '')
+ documentation.items[item_index].description =
+ documentation.items[item_index].description ..
+ separator ..
mw.text.trim(comment_tail)
end
if not start_mode and new_tag and not special_tag then
doctag_mode = true
- table.insert(documentation.items[item_no].tags, process_tag(comment_tail))
+ table.insert(documentation.items[item_index].tags, process_tag(comment_tail))
elseif not start_mode and doctag_mode and not comment_brace and not pretty_comment then
- tags = documentation.items[item_no].tags
+ tags = documentation.items[item_index].tags
if p.tags[tags[#tags].name] == TAG_MULTI then
- sep = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
+ separator = mw.text.trim(comment_tail):find('^[{|!}:#*=]+[%s-}]+')
and '\n'
or DOCBUNTO_CONCAT
- tags[#tags].value = tags[#tags].value .. sep .. mw.text.trim(comment_tail)
+ tags[#tags].value = tags[#tags].value .. separator .. mw.text.trim(comment_tail)
elseif p.tags[tags[#tags].name] == TAG_MULTI_LINE then
tags[#tags].value = tags[#tags].value .. '\n' .. comment_tail
end
end
if not start_mode and (comment_mode or doctag_mode) then
- table.insert(documentation.items[item_no].comments, t.data)
+ table.insert(documentation.items[item_index].comments, t.data)
end
-- Export tag support.
if export_mode then
factory_mode = t.posFirst ~= 1
if factory_mode then
- documentation.items[item_no].exports = true
+ documentation.items[item_index].exports = true
else
documentation.exports = true
end
@@ -1100,8 +1108,8 @@ function p.taglet(modname, options)
subtokens = {}
while t and (not factory_mode or (factory_mode and t.data ~= 'end')) do
if factory_mode then
- documentation.items[item_no].code =
- documentation.items[item_no].code ..
+ documentation.items[item_index].code =
+ documentation.items[item_index].code ..
(t.posFirst == 1 and '\n' or '') ..
t.data
end
@@ -1114,33 +1122,33 @@ function p.taglet(modname, options)
end
end
- local sep = {
- ['{'] = true, ['}'] = true;
- [','] = true, [';'] = true;
- }
- local increment = 0
- for index, subtoken in ipairs(subtokens) do
- if
- subtoken.type == 'ident' and
- sep[subtokens[index + 1].data] and
- (subtokens[index - 1].data == '=' or sep[subtokens[index - 1].data])
- then
- local t2, i2, alias = subtoken, index, ''
- if subtokens[index - 1].data == '=' then
- t2, i2 = subtokens[i2 - 2], i2 - 2
+ local separator = { [','] = true, [';'] = true }
+ local brace = { ['{'] = true, ['}'] = true }
+
+ local item_reference, item_alias = '', ''
+ local sequence_index, has_key = 0, false
+ local subtoken, index, terminating_index = subtokens[2], 2, #subtokens - 1
+
+ while not brace[subtoken.data] do
+ if subtoken.data == '=' then
+ has_key = true
+ item_reference, item_alias = item_alias, item_reference
+ elseif not separator[subtoken.data] then
+ if has_key then
+ item_reference = item_reference .. subtoken.data
+ else
+ item_alias = item_alias .. subtoken.data
end
- if not sep[subtokens[index - 1].data] then
- while not sep[t2.data] do
- alias = t2.data .. alias
- t2, i2 = subtokens[i2 - 1], i2 - 1
- end
- end
- if #alias == 0 then
+ elseif separator[subtoken.data] or index == terminating_index then
+ if not has_key then
increment = increment + 1
+ item_reference, item_alias = item_alias, item_reference
alias = '[' .. tostring(increment) .. ']'
end
- export_item(documentation, subtoken.data, item_no, alias, factory_mode)
+ export_item(documentation, item_reference, item_index, item_alias, factory_mode)
+ item_reference, item_alias, has_key = '', '', false
end
+ subtoken, index = subtokens[index + 1], index + 1
end
if not factory_mode then
@@ -1182,15 +1190,15 @@ function p.taglet(modname, options)
end
-- Item data post-processing.
- if item_no ~= 0 then
- documentation.items[item_no].tags = hash_map(documentation.items[item_no].tags)
- documentation.items[item_no].name = extract_name(documentation.items[item_no])
- documentation.items[item_no].type = extract_type(documentation.items[item_no])
- if #documentation.items[item_no].description ~= 0 then
- documentation.items[item_no].summary = match(documentation.items[item_no].description, DOCBUNTO_SUMMARY)
- documentation.items[item_no].description = gsub(documentation.items[item_no].description, DOCBUNTO_SUMMARY .. '%s*', '')
+ if item_index ~= 0 then
+ documentation.items[item_index].tags = hash_map(documentation.items[item_index].tags)
+ documentation.items[item_index].name = extract_name(documentation.items[item_index])
+ documentation.items[item_index].type = extract_type(documentation.items[item_index])
+ if #documentation.items[item_index].description ~= 0 then
+ documentation.items[item_index].summary = match(documentation.items[item_index].description, DOCBUNTO_SUMMARY)
+ documentation.items[item_index].description = gsub(documentation.items[item_index].description, DOCBUNTO_SUMMARY .. '%s*', '')
end
- documentation.items[item_no].description = documentation.items[item_no].description:gsub('%s%s+', '\n\n')
+ documentation.items[item_index].description = documentation.items[item_index].description:gsub('%s%s+', '\n\n')
new_item_code = true
end
@@ -1208,12 +1216,12 @@ function p.taglet(modname, options)
end
-- Item code concatenation.
- if item_no ~= 0 and not doctag_mode and not comment_mode and not return_mode then
- sep = #documentation.items[item_no].code ~= 0 and t.posFirst == 1 and '\n' or ''
- documentation.items[item_no].code = documentation.items[item_no].code .. sep .. t.data
+ if item_index ~= 0 and not doctag_mode and not comment_mode and not return_mode then
+ separator = #documentation.items[item_index].code ~= 0 and t.posFirst == 1 and '\n' or ''
+ documentation.items[item_index].code = documentation.items[item_index].code .. separator .. t.data
-- Code analysis on item head.
- if new_item_code and documentation.items[item_no].code:find('\n') then
- code_static_analysis(documentation.items[item_no])
+ if new_item_code and documentation.items[item_index].code:find('\n') then
+ code_static_analysis(documentation.items[item_index])
new_item_code = false
end
end
@@ -1385,10 +1393,10 @@ function p.doclet(data, options)
-- Documentation lede.
if not options.code and (#(data.summary or '') + #data.description) ~= 0 then
- local sep = #data.summary ~= 0 and #data.description ~= 0
+ local separator = #data.summary ~= 0 and #data.description ~= 0
and (data.description:find('^[{|!}:#*=]+[%s-}]+') and '\n\n' or ' ')
or ''
- local intro = (data.summary or '') .. sep .. data.description
+ local intro = (data.summary or '') .. separator .. data.description
intro = frame:preprocess(maybe_md(intro:gsub('^(' .. codepage .. ')', '<b>%1</b>')))
documentation:wikitext(intro):newline():newline()
end
@@ -1462,10 +1470,10 @@ function p.doclet(data, options)
elseif item.type == 'type' then
codedoc:wikitext('=== <code>' .. (item.alias or item.name) .. '</code> ==='):newline()
if (#(item.summary or '') + #item.description) ~= 0 then
- local sep = #(item.summary or '') ~= 0 and #item.description ~= 0
+ local separator = #(item.summary or '') ~= 0 and #item.description ~= 0
and (item.description:find('^[{:#*=]+[%s-}]+') and '\n\n' or ' ')
or ''
- codedoc:wikitext((item.summary or '') .. sep .. item.description):newline()
+ codedoc:wikitext((item.summary or '') .. separator .. item.description):newline()
end
elseif item.type == 'function' then
@@ -1482,10 +1490,9 @@ function p.doclet(data, options)
elseif
item.type == 'table' or
- item.type ~= nil and (
- item.type:find('^member') or
- item.type:find('^variable')
- )
+ item.type:find('^member') or
+ item.type:find('^variable')
+
then
render_item(codedoc, item, options)
if not options.simple and item.tags['field'] then
@@ -1662,5 +1669,19 @@ p.tags._generic_tags = {
['variable'] = true,
['member'] = true
}
+p.tags._subtype_tags = {
+ ['factory'] = true,
+ ['local'] = true,
+ ['private'] = true,
+ ['constructor'] = true,
+ ['static'] = true
+}
+p.tags._subtype_hierarchy = {
+ 'private',
+ 'local',
+ 'static',
+ 'factory',
+ 'constructor'
+}
return p |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired by something I stumbled on - https://dev.fandom.com/wiki/Global_Lua_Modules/Docbunto#Tags
Tags that could be added:
@member
/@property
for class members@variable
for local variables (accepts type)@note
developer notes@image
for adding an image to a doc item@example
for example files@file
for non executable generics or datastores@require
for dependenciesFeatures to add:
@error
line number can be specified by [number] affixed to the tag.The text was updated successfully, but these errors were encountered: