Module:Wn/bn/Text length

Documentation for this module may be created at Module:Wn/bn/Text length/doc

local p = {}

local function truncateText(text, length)
    if #text <= length then
        return text
    end
    
    local cut_text = mw.ustring.sub(text, 1, length)
    local last_char = mw.ustring.sub(cut_text, -1)
    
    -- If the last character is not a letter or number, remove it
    if not mw.ustring.match(last_char, "[%w]") then
        cut_text = mw.ustring.sub(cut_text, 1, -2)
    end
    
    -- Ensure we're not cutting in the middle of a word
    local last_space = mw.ustring.match(cut_text, ".*%s()")
    if last_space and (length - last_space) < 5 then
        cut_text = mw.ustring.sub(cut_text, 1, last_space - 1)
    end
    
    return cut_text
end

local function applyFading(text, fade_length)
    local result = mw.ustring.sub(text, 1, -fade_length - 1)
    local fade_text = mw.ustring.sub(text, -fade_length)
    
    for i = 1, #fade_text do
        local char = mw.ustring.sub(fade_text, i, i)
        local opacity = 1 - (i / fade_length) * 0.7
        result = result .. string.format('<span style="opacity:%.2f;">%s</span>', math.max(0.3, opacity), char)
    end
    
    return result
end

function p.main(frame)
    local args = frame.args
    local length = tonumber(args.length) or 100
    local text = args.text or ""
    local fade = args.fade ~= "no"
    local link = args.link or ""
    
    local truncated_text = truncateText(text, length)
    
    if #text <= length then
        return text
    end
    
    local result
    if fade then
        local fade_length = math.min(30, math.floor(#truncated_text / 10))
        result = applyFading(truncated_text, fade_length)
    else
        result = truncated_text
    end
    
    local ellipsis
    if link ~= "" then
        ellipsis = string.format('<span style="color:#888;">[[%s|...]]</span>', link)
    else
        ellipsis = '<span style="color:#888;">...</span>'
    end
    
    return result .. ' ' .. ellipsis
end

return p