Module:LinkParser: Difference between revisions
Appearance
minor rev // via Wikitext Extension for VSCode |
// via Wikitext Extension for VSCode |
||
| (9 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
-- | --[[ | ||
* Name: LinkParser | |||
* Author: Mark W. Datysgeld | |||
* Description: Comprehensive link handling module for both external links and internal wiki links with caching | |||
* Notes: URL normalization (protocol stripping, www removal); wiki link extraction, preservation, and automatic application; caching for both link types; supports autoWikiLink field configuration; preserves wiki links during processing | |||
]] | |||
local p = {} | local p = {} | ||
---------------------------------- | -------------------------------------------------------------------------------- | ||
-- | -- Caching and Utilities | ||
---------------------------------- | -------------------------------------------------------------------------------- | ||
-- Cache for processed URLs and wiki links (non-persistent) | |||
local stripCache = {} | |||
local wikiLinkCache = {} | |||
-------------------------------------------------------------------------------- | |||
-- External Link Processing | |||
-------------------------------------------------------------------------------- | |||
-- Strip URL protocol, www prefix, and trailing slash | |||
function p.strip(link) | function p.strip(link) | ||
-- | -- Input validation | ||
link = link:gsub("^%a+://", "") | if not link or link == "" then | ||
return link | |||
end | |||
-- Check cache first for previously processed URLs | |||
return | if stripCache[link] then | ||
return stripCache[link] | |||
end | |||
-- Chain operations to minimize string allocations | |||
local result = link:gsub("^%a+://", ""):gsub("^www%.", ""):gsub("/$", "") | |||
-- Cache the result before returning | |||
stripCache[link] = result | |||
return result | |||
end | end | ||
---------------------------------- | -------------------------------------------------------------------------------- | ||
-- | -- Creates MediaWiki link: [ originalURL strippedDisplayText ] | ||
-------------------------------------------------------------------------------- | |||
---------------------------------- | |||
function p.render(frame) | function p.render(frame) | ||
local | -- Input validation | ||
if not frame or not frame.getParent then | |||
return "" | |||
end | |||
local parent = frame:getParent() | |||
if not parent or not parent.args then | |||
return "" | |||
end | |||
local args = parent.args | |||
local rawLink = args["link"] or "" | local rawLink = args["link"] or "" | ||
if rawLink == "" then | |||
-- Skip empty links | |||
if not rawLink or rawLink == "" then | |||
return "" | return "" | ||
end | end | ||
-- | -- Clean URL for display | ||
local displayText = p.strip(rawLink) | local displayText = p.strip(rawLink) | ||
-- | -- Format as [ rawLink displayText ] | ||
return string.format("[%s %s]", rawLink, displayText) | return string.format("[%s %s]", rawLink, displayText) | ||
end | |||
-------------------------------------------------------------------------------- | |||
-- Wiki Link Processing | |||
-------------------------------------------------------------------------------- | |||
-- Process wiki links in different modes (extract, strip, check) | |||
-- @param value Wiki link to process | |||
-- @param mode Processing mode: "extract", "strip", or "check" | |||
-- @return Processed value or boolean based on mode | |||
function p.processWikiLink(value, mode) | |||
mode = mode or "extract" | |||
if not value or value == "" then | |||
return mode == "check" and false or value | |||
end | |||
local cacheKey = value .. ":" .. mode | |||
if wikiLinkCache[cacheKey] ~= nil then | |||
return wikiLinkCache[cacheKey] | |||
end | |||
-- A single regex to capture the page name and optional display text | |||
local pageName, displayText = value:match("^%[%[([^|]+)|?(.*)%]%]$") | |||
if mode == "check" then | |||
local isWikiLink = (pageName ~= nil) | |||
wikiLinkCache[cacheKey] = isWikiLink | |||
return isWikiLink | |||
end | |||
if not pageName then | |||
wikiLinkCache[cacheKey] = value | |||
return value | |||
end | |||
-- If displayText is empty, it means the format was [[PageName]], so use pageName | |||
if displayText == "" then | |||
displayText = pageName | |||
end | |||
local result | |||
if mode == "extract" then | |||
result = pageName | |||
elseif mode == "strip" then | |||
result = displayText | |||
else | |||
result = pageName -- Default to extract for unknown modes | |||
end | |||
wikiLinkCache[cacheKey] = result | |||
return result | |||
end | |||
-- Extract page name from wiki link | |||
-- @param value Wiki link to process | |||
-- @return Extracted page name | |||
function p.extractFromWikiLink(value) | |||
return p.processWikiLink(value, "extract") | |||
end | |||
-- Add wiki links based on field config | |||
-- @param value Value to process | |||
-- @param field Field configuration | |||
-- @return Value with wiki links if needed | |||
function p.applyWikiLinkHandling(value, field) | |||
-- Skip invalid values | |||
if not value or type(value) ~= "string" or value == "" then | |||
return value | |||
end | |||
-- Add wiki links if autoWikiLink is true | |||
-- Prevents stripping by later processing | |||
if field.autoWikiLink and not value:match("%[%[.-%]%]") then | |||
return "[[" .. value .. "]]" | |||
end | |||
return value | |||
end | |||
-- Preserve wiki links in processed values | |||
-- Keeps original if links were lost during processing | |||
-- @param originalValue Value before processing | |||
-- @param processedValue Value after processing | |||
-- @param preserveWikiLinks Whether to keep wiki links | |||
-- @return Value with links preserved if needed | |||
function p.preserveWikiLinks(originalValue, processedValue, preserveWikiLinks) | |||
-- Skip non-string values | |||
if type(originalValue) ~= "string" or type(processedValue) ~= "string" then | |||
return processedValue | |||
end | |||
-- Restore original if links were lost | |||
if preserveWikiLinks and | |||
originalValue:match("%[%[.-%]%]") and | |||
not processedValue:match("%[%[.-%]%]") then | |||
return originalValue | |||
end | |||
return processedValue | |||
end | end | ||
return p | return p | ||
Latest revision as of 03:09, 25 August 2025
Documentation for this module may be created at Module:LinkParser/doc
--[[
* Name: LinkParser
* Author: Mark W. Datysgeld
* Description: Comprehensive link handling module for both external links and internal wiki links with caching
* Notes: URL normalization (protocol stripping, www removal); wiki link extraction, preservation, and automatic application; caching for both link types; supports autoWikiLink field configuration; preserves wiki links during processing
]]
local p = {}
--------------------------------------------------------------------------------
-- Caching and Utilities
--------------------------------------------------------------------------------
-- Cache for processed URLs and wiki links (non-persistent)
local stripCache = {}
local wikiLinkCache = {}
--------------------------------------------------------------------------------
-- External Link Processing
--------------------------------------------------------------------------------
-- Strip URL protocol, www prefix, and trailing slash
function p.strip(link)
-- Input validation
if not link or link == "" then
return link
end
-- Check cache first for previously processed URLs
if stripCache[link] then
return stripCache[link]
end
-- Chain operations to minimize string allocations
local result = link:gsub("^%a+://", ""):gsub("^www%.", ""):gsub("/$", "")
-- Cache the result before returning
stripCache[link] = result
return result
end
--------------------------------------------------------------------------------
-- Creates MediaWiki link: [ originalURL strippedDisplayText ]
--------------------------------------------------------------------------------
function p.render(frame)
-- Input validation
if not frame or not frame.getParent then
return ""
end
local parent = frame:getParent()
if not parent or not parent.args then
return ""
end
local args = parent.args
local rawLink = args["link"] or ""
-- Skip empty links
if not rawLink or rawLink == "" then
return ""
end
-- Clean URL for display
local displayText = p.strip(rawLink)
-- Format as [ rawLink displayText ]
return string.format("[%s %s]", rawLink, displayText)
end
--------------------------------------------------------------------------------
-- Wiki Link Processing
--------------------------------------------------------------------------------
-- Process wiki links in different modes (extract, strip, check)
-- @param value Wiki link to process
-- @param mode Processing mode: "extract", "strip", or "check"
-- @return Processed value or boolean based on mode
function p.processWikiLink(value, mode)
mode = mode or "extract"
if not value or value == "" then
return mode == "check" and false or value
end
local cacheKey = value .. ":" .. mode
if wikiLinkCache[cacheKey] ~= nil then
return wikiLinkCache[cacheKey]
end
-- A single regex to capture the page name and optional display text
local pageName, displayText = value:match("^%[%[([^|]+)|?(.*)%]%]$")
if mode == "check" then
local isWikiLink = (pageName ~= nil)
wikiLinkCache[cacheKey] = isWikiLink
return isWikiLink
end
if not pageName then
wikiLinkCache[cacheKey] = value
return value
end
-- If displayText is empty, it means the format was [[PageName]], so use pageName
if displayText == "" then
displayText = pageName
end
local result
if mode == "extract" then
result = pageName
elseif mode == "strip" then
result = displayText
else
result = pageName -- Default to extract for unknown modes
end
wikiLinkCache[cacheKey] = result
return result
end
-- Extract page name from wiki link
-- @param value Wiki link to process
-- @return Extracted page name
function p.extractFromWikiLink(value)
return p.processWikiLink(value, "extract")
end
-- Add wiki links based on field config
-- @param value Value to process
-- @param field Field configuration
-- @return Value with wiki links if needed
function p.applyWikiLinkHandling(value, field)
-- Skip invalid values
if not value or type(value) ~= "string" or value == "" then
return value
end
-- Add wiki links if autoWikiLink is true
-- Prevents stripping by later processing
if field.autoWikiLink and not value:match("%[%[.-%]%]") then
return "[[" .. value .. "]]"
end
return value
end
-- Preserve wiki links in processed values
-- Keeps original if links were lost during processing
-- @param originalValue Value before processing
-- @param processedValue Value after processing
-- @param preserveWikiLinks Whether to keep wiki links
-- @return Value with links preserved if needed
function p.preserveWikiLinks(originalValue, processedValue, preserveWikiLinks)
-- Skip non-string values
if type(originalValue) ~= "string" or type(processedValue) ~= "string" then
return processedValue
end
-- Restore original if links were lost
if preserveWikiLinks and
originalValue:match("%[%[.-%]%]") and
not processedValue:match("%[%[.-%]%]") then
return originalValue
end
return processedValue
end
return p