Для документации этого модуля может быть создана страница Модуль:Lsafe/Документация

local p = {}

function p.link ( frame )
	local args = mw.getCurrentFrame():getParent().args
	args[2] = is(args[2])
	if not args[1] then return end -- пустой шаблон
	local _title = mw.title.getCurrentTitle()
	local title, pagename = args[1], _title.text
	local nameparts, articlename, linkname
	if string.find( title, '/' ) then 
		nameparts = mw.text.split ( title, '/' )
		articlename = nameparts[2]
		if articlename == 'ДО' or articlename == 'ВТ' then articlename = nameparts[3] or articlename end
		linkname = '/' .. table.concat( nameparts, '/', 2 )
	elseif string.find( pagename, '/' ) then 
		nameparts = mw.text.split ( pagename, '/' )
		articlename = title
		local flag1, flag2
		if nameparts[2] == 'ДО' or nameparts[2] == 'ВТ' then flag1 = nameparts[2] end
		if nameparts[#nameparts] == 'ДО' then flag2 = nameparts[#nameparts] end
		if flag1 then 
			linkname = '/' .. flag1 .. '/' .. articlename
		elseif flag2 then 
			linkname = '/' .. articlename .. '/' .. flag2
		else 
			linkname = '/' .. articlename
		end
	else
		return args[2] or args[1] -- no article name
	end
	
	linkname = mw.ustring.gsub( linkname, '%s+', ' ' )
	articlename = mw.ustring.gsub( articlename, '%s+', ' ' )
	local linktext = args[2] or articlename
	local dictname = nameparts[1]; local pre = { dictname }
	
	if _title.namespace ~= 0 then
		if _title.namespace == 104 then
			return '[[' .. nameparts[1] .. linkname .. '|' .. linktext .. ']]'
		else
			return '[[' .. linkname .. '|' .. linktext .. ']]'
		end
	end
	
	
	if dictname == 'БЭЮ1' or dictname == 'БЭЮ2' then dictname = 'БЭЮ'; pre = { 'БЭЮ', 'БЭЮ1', 'БЭЮ2' } end
	for _, n in ipairs( pre ) do
		local linkname = n .. linkname
		if mw.title.new( linkname ).exists then return '[[' .. linkname .. '|' .. linktext .. ']]' end
	end
	
	local dictpath = 'Модуль:Отексте/' .. dictname
	local dict
	if mw.title.new( dictpath ).exists then dict = mw.loadData( dictpath ) else return linktext end
	local body = dict.body or { dict }
	local pre = dict.prefixes or { dictname }
	for i, d in ipairs( body ) do
		local listroot, listnum = d.listroot.default, d.listnum
		local sname = mw.ustring.gsub ( articlename, '[Йй]', 'и~' )
		sname = mw.ustring.toNFD ( sname )
		sname = mw.ustring.gsub ( mw.ustring.gsub ( sname, "[^%w,(~]", "" ), "^%p", "" )
		sname = mw.ustring.gsub ( sname, 'и~', 'й' )
		local lang = mw.language.new (mw.language.getContentLanguage().code)
		sname = lang:ucfirst ( lang:lc (sname) )
		mw.logObject(sname,'sname')
		for j, _ in ipairs( listnum ) do 
			if sname >= listnum[j][1] and (listnum[j+1] == nil or sname < listnum[j+1][1]) then
				local map = listnum[j][2]
				for _, n in ipairs( map ) do
					local title = mw.title.new( listroot .. n )
					if title.exists then 
						local text = title:getContent()
						if text then 
							local pat = "{{%s*Статья в словнике%s*|%s*" .. escapePattern( articlename ) .. "%s*|[^{}]*}}"
							local foundstr = mw.ustring.match( text, pat )
							local prefix = pre[i] or pre[1]
							if foundstr then return '[[' .. prefix .. linkname .. '|' .. linktext .. ']][[Категория:Ссылки на статьи, которые требуется создать]]' end
						end
					end
				end
			end
		end
	end
	return frame:expandTemplate{ title='comment', args = { linktext, 'Статья «' .. pre[1] .. linkname .. '» отсутствует в словниках' } } .. '[[Категория:Ссылки на статьи, отсутствующие в словниках]]'
end

-- escape certain characters in regex patterns
function escapePattern( pattern_str )
	return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end

-- проверка переменной, возврат её или nil если пустая
function is(var)
	if (var == '' or var == nil) then return nil  else return var end
end

return p