Module:CodeToText: Difference between revisions
Appearance
// via Wikitext Extension for VSCode |
// via Wikitext Extension for VSCode |
||
| Line 1: | Line 1: | ||
-- Module:TranscludeModuleCode | -- Module:TranscludeModuleCode | ||
-- Extracts content snippets from a page using | -- Extracts content snippets from a page using hook markers | ||
-- | -- | ||
-- Finds content between matching hooks (e.g., 🪝, 📌, 🔖, ⭐) | -- Finds content between matching hooks (e.g., 🪝, 📌, 🔖, ⭐) placed at the beginning and end of desired content. | ||
-- | -- | ||
-- Example: | -- Example: | ||
| Line 16: | Line 13: | ||
-- Helper function to create a cache key from parameters | -- Helper function to create a cache key from parameters | ||
local function createCacheKey(pageName, hook | local function createCacheKey(pageName, hook) | ||
return pageName .. "|hook=" .. hook | |||
end | end | ||
| Line 31: | Line 24: | ||
local hook = frame.args.hook | local hook = frame.args.hook | ||
if not hook then | |||
return "Error: 'hook' parameter is required" | |||
end | |||
-- Check cache first for previously extracted snippets | -- Check cache first for previously extracted snippets | ||
local cacheKey = createCacheKey(pageName, hook | local cacheKey = createCacheKey(pageName, hook) | ||
if snippetCache[cacheKey] then | if snippetCache[cacheKey] then | ||
return snippetCache[cacheKey] | return snippetCache[cacheKey] | ||
| Line 54: | Line 46: | ||
local result | local result | ||
-- First, check for hooks on the same line | |||
local inlinePattern = hook .. "(.-)" .. hook | |||
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 | end | ||
if #hookPositions < 2 then | -- 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 | end | ||
-- | -- Extract content between first two hook instances | ||
-- | local startLine = hookPositions[1] | ||
local | 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 = {} | local snippet = {} | ||
if snippetSize > 0 then | |||
for i = 1, snippetSize do | |||
snippet[i] = lines[startIndex + i - 1] | |||
snippet[ | |||
end | end | ||
result = table.concat(snippet, "\n") | |||
else | |||
result = "" | |||
end | end | ||
end | end | ||
Revision as of 04:48, 12 April 2025
Documentation for this module may be created at Module:CodeToText/doc
-- Module:TranscludeModuleCode
-- 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.
--
-- Example:
-- {{#invoke:TranscludeModuleCode|showSnippet|page=Module:Example|hook=⭐}}
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)
local pageName = frame.args.page
if not pageName then
return "Error: 'page' parameter is required"
end
local hook = frame.args.hook
if not hook then
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
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 result
-- First, check for hooks on the same line
local inlinePattern = hook .. "(.-)" .. hook
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
-- Cache the result before returning
snippetCache[cacheKey] = result
return result
end
return p