Module:CodeToText: Difference between revisions

Lighter implementation // via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
Line 2: Line 2:
-- Extracts content snippets from a page using hook markers
-- Extracts content snippets from a page using hook markers
--  
--  
-- Finds content between matching hooks (e.g., 🪝, 📌, 🔖, ⭐) placed at the beginning and end of desired content.
-- Finds content between matching emoji hooks (e.g., 🪝, 📌, 🔖, ⭐) placed at the beginning and end of desired content.
--  
--  
-- Example:
-- Example:
Line 8: Line 8:


local p = {}
local p = {}
-- Cache for extracted snippets (persists during page render)
local snippetCache = {}
-- Helper function to create a cache key from parameters
local function createCacheKey(pageName, hook)
    return pageName .. "|hook=" .. hook
end


function p.showSnippet(frame)
function p.showSnippet(frame)
Line 22: Line 14:
         return "Error: 'page' parameter is required"
         return "Error: 'page' parameter is required"
     end
     end
   
 
     local hook = frame.args.hook
     local hook = frame.args.hook
     if not hook then
     if not hook then
         return "Error: 'hook' parameter is required"
         return "Error: 'hook' parameter is required"
    end
   
    -- Check cache first for previously extracted snippets
    local cacheKey = createCacheKey(pageName, hook)
    if snippetCache[cacheKey] then
        return snippetCache[cacheKey]
     end
     end


Line 44: Line 30:
     end
     end


    local result
     -- Try inline hooks first
   
     local inlineSnippet = content:match(hook .. "(.-)" .. hook)
     -- First, check for hooks on the same line
     if inlineSnippet then
     local inlinePattern = hook .. "(.-)" .. hook
         return inlineSnippet
    local inlineMatch = content:match(inlinePattern)
      
    if inlineMatch then
        -- We found inline hooks: use the content between them
        result = inlineMatch
    else
        -- Look for hooks on different lines
        local lines = {}
        local hookPositions = {}
       
        -- Find hook instances and count lines
        local lineNumber = 0
        for line in content:gmatch("[^\r\n]+") do
            lineNumber = lineNumber + 1
           
            if line:find(hook, 1, true) then
                table.insert(hookPositions, lineNumber)
            end
           
            -- Store all lines for later use
            lines[lineNumber] = line
        end
       
         if #hookPositions < 2 then
            return "Error: Need at least 2 instances of hook '" .. hook .. "' in '" .. pageName .. "'"
        end
       
        -- Extract content between first two hook instances
        local startLine = hookPositions[1]
        local endLine = hookPositions[2]
       
        -- Always exclude the hook lines
        local startIndex = startLine + 1
        local endIndex = endLine - 1
       
        -- Pre-allocate snippet table
        local snippetSize = math.max(0, endIndex - startIndex + 1)
        local snippet = {}
       
        if snippetSize > 0 then
            for i = 1, snippetSize do
                snippet[i] = lines[startIndex + i - 1]
            end
            result = table.concat(snippet, "\n")
        else
            result = ""
        end
     end
     end
      
 
     -- Cache the result before returning
     -- Find block hooks
     snippetCache[cacheKey] = result
    local s, e = content:find(hook, 1, true)
     return result
    if not s then
        return "Error: Need at least 2 instances of hook '" .. hook .. "' in '" .. pageName .. "'"
    end
 
    local s2, e2 = content:find(hook, e + 1, true)
    if not s2 then
        return "Error: Need at least 2 instances of hook '" .. hook .. "' in '" .. pageName .. "'"
    end
 
     -- Extract text between the two hooks, excluding the hook lines
     local snippet = content:sub(e + 1, s2 - 1)
 
    -- Trim leading and trailing newlines
    if snippet:sub(1,1) == "\n" then
        snippet = snippet:sub(2)
    end
    if snippet:sub(-1) == "\n" then
        snippet = snippet:sub(1, -2)
    end
 
     return snippet
end
end


return p
return p