模块:Module toc

来自决策链云智库
Zeroclanzhang讨论 | 贡献2023年7月14日 (五) 15:05的版本 (创建页面,内容为“-- Imported from: https://runescape.wiki/w/Module:Module%20toc -- <nowiki> local p = {} local function getNewlineLocations( content ) local locs = {} local pos = 0 repeat pos = string.find( content, '\n', pos + 1, true ) table.insert( locs, pos ) until not pos return locs end local function findLineNumber( pos, newLineLocs ) local max = #newLineLocs local min = 1 repeat local i = math.ceil( (max + mi…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

This module is used to generate a table of content consists of functions of a Lua module. See Module:Module toc on RuneScape Wiki for more details.


-- Imported from: https://runescape.wiki/w/Module:Module%20toc

-- <nowiki>
local p = {}

local function getNewlineLocations( content )
    local locs = {}
    local pos = 0

    repeat
        pos = string.find( content, '\n', pos + 1, true )
        table.insert( locs, pos )
    until not pos

    return locs
end

local function findLineNumber( pos, newLineLocs )
    local max = #newLineLocs
    local min = 1

    repeat
        local i = math.ceil( (max + min) / 2 )
        if newLineLocs[i] < pos then
            min = i
        elseif newLineLocs[i] >= pos then
            max = i
        end
    until newLineLocs[i] > pos and (newLineLocs[i - 1] or 0) < pos

    return max
end

local function getFunctionLocations( content )
    local locs = {}
    local newLineLocs = getNewlineLocations( content )

    local start = 0
    repeat
        local name
        name, start = string.match( content, '%sfunction%s+([^%s%(]+)%s*%(()', start + 1 )
        if start then
            table.insert( locs, { name=name, line = findLineNumber( start, newLineLocs ) } )
        end
    until not start

    start = 0
    repeat
        local name
        name, start = string.match( content, '%s([^%s=])%s*=%s*function%s*%(()', start + 1 )
        if start then
            table.insert( locs, { name=name, line = findLineNumber( start, newLineLocs ) } )
        end
    until not start

    return locs
end

function p.main()
    local title = mw.title.getCurrentTitle()
    local moduleName = string.gsub( title.text, '/[Dd]oc$', '' )

    if title.namespace ~= 828 then
        return ''
    end

    local fullModuleName = string.gsub( title.fullText, '/[Dd]oc$', '' )
    local content = mw.title.new( fullModuleName ):getContent()

    if not content then
        return ''
    end

    local function substMutilineComment( match )
        local lineCount = #getNewlineLocations( match )
        return string.rep( '\n', lineCount ) or ''
    end

    content = content:gsub( '(%-%-%[(=-)%[.-%]%2%])', substMutilineComment ):gsub( '%-%-[^\n]*', '' ) -- Strip comments
    local functionLocs = getFunctionLocations( content )

    table.sort( functionLocs, function(lhs, rhs) return lhs.line < rhs.line end )

    if #functionLocs == 0 then
        return ''
    end

    local res = {}
    for _, func in ipairs( functionLocs ) do
        table.insert( res, string.format( 'L %d &mdash; [%s#L-%d %s]', func.line, title:fullUrl():gsub( '/[Dd]oc$', '' ), func.line,  func.name ) )
    end

    local tbl = mw.html.create( 'table' ):addClass( 'wikitable mw-collapsible mw-collapsed' )
    tbl:tag( 'tr' )
            :tag( 'th' ):wikitext( 'Function list' ):done()
        :tag( 'tr' )
            :tag( 'td' ):wikitext( table.concat( res, '<br>' ) )

    return tostring( tbl )
end

return p
-- </nowiki>