Jump to content

Module:CodeToText: Difference between revisions

// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
Line 1: Line 1:
-- Module:TranscludeModuleCode
-- Module:TranscludeModuleCode
-- Extracts a snippet of lines from a specified page using either:
-- Extracts a snippet of content from a specified page using either:
-- 1. A defined line range (from/to parameters)
-- 1. A defined line range (from/to parameters)
-- 2. Hook markers like emojis (startHook/endHook parameters)
-- 2. Hook markers like emojis (hook parameter)
-- Optionally removes a given token (like a leading comment --) from each line.
-- The module finds content between matching instances of the same hook.


local p = {}
local p = {}


function p.showSnippet(frame)
function p.showSnippet(frame)
     local pageName = frame.args.page or 'Module:Sandbox'
     local pageName = frame.args.page
     local startHook = frame.args.startHook
    if not pageName then
     local endHook = frame.args.endHook
        return "Error: 'page' parameter is required"
    end
      
     local hook = frame.args.hook
     local includeHook = frame.args.includeHook == 'true'
     local includeHook = frame.args.includeHook == 'true'
    local debug = frame.args.debug == 'true'
      
      
     -- Fallback to line numbers if hooks aren't provided
     -- Fallback to line numbers if hook isn't provided
     local fromLine = tonumber(frame.args.from) or 1
     local fromLine = tonumber(frame.args.from) or 1
     local toLine  = tonumber(frame.args.to)  or fromLine
     local toLine  = tonumber(frame.args.to)  or fromLine
Line 33: Line 37:


     local snippet = {}
     local snippet = {}
    local debugInfo = {}
      
      
     -- If hooks are provided, use them to extract the snippet
     -- If hook is provided, use it to extract the snippet
     if startHook then
     if hook then
         local startIndex, endIndex = nil, nil
         local hookPositions = {}
          
          
         -- Find the start hook
         -- Find all instances of the hook
         for i, line in ipairs(lines) do
         for i, line in ipairs(lines) do
             if line:find(startHook, 1, true) then
             if line:find(hook, 1, true) then
                 startIndex = i
                 table.insert(hookPositions, i)
                 break
                if debug then
                    table.insert(debugInfo, "Found hook at line " .. i .. ": " .. line)
                end
            elseif debug then
                 table.insert(debugInfo, "Line " .. i .. " (no hook): " .. line:sub(1, 30) .. (line:len() > 30 and "..." or ""))
             end
             end
         end
         end
          
          
         -- Find the end hook if provided
         if #hookPositions < 2 then
        if endHook and startIndex then
             local errorMsg = "Error: Need at least 2 instances of hook '" .. hook .. "' in '" .. pageName .. "'"
             for i = startIndex + 1, #lines do
            if debug then
                 if lines[i]:find(endHook, 1, true) then
                 errorMsg = errorMsg .. "\n\nDebug info:\n" .. table.concat(debugInfo, "\n")
                    endIndex = i
                    break
                end
             end
             end
            return errorMsg
         end
         end
          
          
         -- Extract the snippet based on hooks
         -- Extract content between first two hook instances
         if startIndex then
        local startLine = hookPositions[1]
            local snippetStart = includeHook and startIndex or startIndex + 1
        local endLine = hookPositions[2]
            local snippetEnd = endIndex
          
           
        local startIndex = includeHook and startLine or startLine + 1
            if not endIndex then
        local endIndex = includeHook and endLine or endLine - 1
                -- If no end hook is found or provided, include all lines after the start hook
       
                snippetEnd = #lines
        for i = startIndex, endIndex do
            elseif not includeHook then
            table.insert(snippet, lines[i])
                snippetEnd = endIndex - 1
        end
            end
          
           
        if debug then
            for i = snippetStart, snippetEnd do
            table.insert(snippet, "\n-- Debug info:")
                table.insert(snippet, lines[i])
             table.insert(snippet, "-- Found " .. #hookPositions .. " hook instances")
            end
            table.insert(snippet, "-- Extracting content between lines " .. startIndex .. " and " .. endIndex)
         else
             return "Start hook '" .. startHook .. "' not found in '" .. pageName .. "'"
         end
         end
     else
     else
Line 79: Line 84:
             table.insert(snippet, lines[i])
             table.insert(snippet, lines[i])
         end
         end
    end
    if frame.args.remove then
        local removeToken = frame.args.remove
        local escaped = removeToken:gsub("([^%w])", "%%%1")
        local pattern = "^" .. escaped .. "%s*"
        for i, line in ipairs(snippet) do
              snippet[i] = line:gsub(pattern, "")
        end
     end
     end



Revision as of 23:02, 3 April 2025

Documentation for this module may be created at Module:CodeToText/doc

-- Module:TranscludeModuleCode
-- Extracts a snippet of content from a specified page using either:
-- 1. A defined line range (from/to parameters)
-- 2. Hook markers like emojis (hook parameter)
-- The module finds content between matching instances of the same hook.

local p = {}

function p.showSnippet(frame)
    local pageName = frame.args.page
    if not pageName then
        return "Error: 'page' parameter is required"
    end
    
    local hook = frame.args.hook
    local includeHook = frame.args.includeHook == 'true'
    local debug = frame.args.debug == 'true'
    
    -- Fallback to line numbers if hook isn't provided
    local fromLine = tonumber(frame.args.from) or 1
    local toLine   = tonumber(frame.args.to)   or fromLine

    local titleObj = mw.title.new(pageName)
    if not titleObj then
        return "Failed to create mw.title object for '" .. pageName .. "'"
    end

    local content = titleObj:getContent()
    if not content then
        return "No content for '" .. pageName .. "'"
    end

    local lines = {}
    for line in content:gmatch("[^\r\n]+") do
        table.insert(lines, line)
    end

    local snippet = {}
    local debugInfo = {}
    
    -- If hook is provided, use it to extract the snippet
    if hook then
        local hookPositions = {}
        
        -- Find all instances of the hook
        for i, line in ipairs(lines) do
            if line:find(hook, 1, true) then
                table.insert(hookPositions, i)
                if debug then
                    table.insert(debugInfo, "Found hook at line " .. i .. ": " .. line)
                end
            elseif debug then
                table.insert(debugInfo, "Line " .. i .. " (no hook): " .. line:sub(1, 30) .. (line:len() > 30 and "..." or ""))
            end
        end
        
        if #hookPositions < 2 then
            local errorMsg = "Error: Need at least 2 instances of hook '" .. hook .. "' in '" .. pageName .. "'"
            if debug then
                errorMsg = errorMsg .. "\n\nDebug info:\n" .. table.concat(debugInfo, "\n")
            end
            return errorMsg
        end
        
        -- Extract content between first two hook instances
        local startLine = hookPositions[1]
        local endLine = hookPositions[2]
        
        local startIndex = includeHook and startLine or startLine + 1
        local endIndex = includeHook and endLine or endLine - 1
        
        for i = startIndex, endIndex do
            table.insert(snippet, lines[i])
        end
        
        if debug then
            table.insert(snippet, "\n-- Debug info:")
            table.insert(snippet, "-- Found " .. #hookPositions .. " hook instances")
            table.insert(snippet, "-- Extracting content between lines " .. startIndex .. " and " .. endIndex)
        end
    else
        -- Fallback to line number-based extraction
        for i = fromLine, math.min(toLine, #lines) do
            table.insert(snippet, lines[i])
        end
    end

    return table.concat(snippet, "\n")
end

return p