<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://massarn.com/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ARedirectChecker</id>
	<title>Модуль:RedirectChecker - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://massarn.com/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ARedirectChecker"/>
	<link rel="alternate" type="text/html" href="https://massarn.com/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:RedirectChecker&amp;action=history"/>
	<updated>2026-10-15T01:40:49Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://massarn.com/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:RedirectChecker&amp;diff=2349&amp;oldid=prev</id>
		<title>Buto: Новая страница: «-- -- Checks redirects to sections for their target -- Also checks if a page is a redirect page -- -- Adds tracking categories in both cases -- require( &#039;strict&#039; ) local p = {}  local getArgs = require( &#039;Module:Arguments&#039; ).getArgs local delink local escapePattern = require( &#039;Module:String&#039; )._escapePattern  -- Module:RedirectChecker/config.json local config = mw.loadJsonData( &#039;Module:RedirectChecker/config.json&#039; )  local anchorTemplates = config[ &#039;ancho...»</title>
		<link rel="alternate" type="text/html" href="https://massarn.com/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:RedirectChecker&amp;diff=2349&amp;oldid=prev"/>
		<updated>2026-10-14T19:16:30Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «-- -- Checks redirects to sections for their target -- Also checks if a page is a redirect page -- -- Adds tracking categories in both cases -- require( &amp;#039;strict&amp;#039; ) local p = {}  local getArgs = require( &amp;#039;Module:Arguments&amp;#039; ).getArgs local delink local escapePattern = require( &amp;#039;Module:String&amp;#039; )._escapePattern  -- &lt;a href=&quot;/w/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:RedirectChecker/config.json&quot; title=&quot;Модуль:RedirectChecker/config.json&quot;&gt;Module:RedirectChecker/config.json&lt;/a&gt; local config = mw.loadJsonData( &amp;#039;Module:RedirectChecker/config.json&amp;#039; )  local anchorTemplates = config[ &amp;#039;ancho...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--&lt;br /&gt;
-- Checks redirects to sections for their target&lt;br /&gt;
-- Also checks if a page is a redirect page&lt;br /&gt;
--&lt;br /&gt;
-- Adds tracking categories in both cases&lt;br /&gt;
--&lt;br /&gt;
require( &amp;#039;strict&amp;#039; )&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local getArgs = require( &amp;#039;Module:Arguments&amp;#039; ).getArgs&lt;br /&gt;
local delink&lt;br /&gt;
local escapePattern = require( &amp;#039;Module:String&amp;#039; )._escapePattern&lt;br /&gt;
&lt;br /&gt;
-- [[Module:RedirectChecker/config.json]]&lt;br /&gt;
local config = mw.loadJsonData( &amp;#039;Module:RedirectChecker/config.json&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local anchorTemplates = config[ &amp;#039;anchorTemplates&amp;#039; ]&lt;br /&gt;
&lt;br /&gt;
local function isEmpty( str )&lt;br /&gt;
	return str == nil or str == &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getConfigVal( key )&lt;br /&gt;
	if not isEmpty( config[ key ] ) then&lt;br /&gt;
		return config[ key ]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return error( &amp;#039;RedirectChecker: config needs to be fixed.&amp;#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- [[Module:RedirectChecker/config.json]] has templates that create IDs in a list&lt;br /&gt;
local function isValidTemplate( str )&lt;br /&gt;
	if type( anchorTemplates ) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, val in ipairs( anchorTemplates ) do&lt;br /&gt;
		if mw.ustring.find( str, &amp;#039;{{&amp;#039; .. val ) ~= nil then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getError( str )&lt;br /&gt;
	return string.format( &amp;#039;&amp;lt;div class=&amp;quot;error&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;%s&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;[[Category:%s]]&amp;#039;, str, getConfigVal( &amp;#039;errorCat&amp;#039; ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function escape( text )&lt;br /&gt;
	-- Account for &amp;amp;nbsp; (or Unicode variant of it)&lt;br /&gt;
	return ( escapePattern( text ):gsub( &amp;#039;&amp;amp;nbsp;&amp;#039;, &amp;#039; &amp;#039; ):gsub( &amp;#039;%s&amp;#039;, &amp;#039;%%s&amp;#039; ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function escapeRepl( text )&lt;br /&gt;
	-- Replace % to %% to avoid %1, %2, %3 being treated as groups&lt;br /&gt;
	return ( mw.ustring.gsub( text, &amp;#039;%%&amp;#039;, &amp;#039;%%%&amp;#039; ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parse( frame, text )&lt;br /&gt;
	if isEmpty( text ) then&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Break references to not display them&lt;br /&gt;
	local result = text:gsub( &amp;#039;%&amp;lt;(%/?)ref(.-)%&amp;gt;&amp;#039;, &amp;#039;`%1ref%2`&amp;#039; )&lt;br /&gt;
	return mw.text.killMarkers( frame:preprocess( result ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Separate function for testing&lt;br /&gt;
function p._parse( anchor, content, frame )&lt;br /&gt;
	if frame == nil then&lt;br /&gt;
		frame = mw.getCurrentFrame()&lt;br /&gt;
	end&lt;br /&gt;
	if isEmpty( content ) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Find a heading of any level matching anchor&lt;br /&gt;
	local headingPattern = &amp;#039;=%s*&amp;#039; .. escape( anchor ) .. &amp;#039;%s*=&amp;#039;&lt;br /&gt;
	local heading = mw.ustring.match( content, headingPattern )&lt;br /&gt;
	if heading ~= nil then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Convert all headings to plain text and try again&lt;br /&gt;
	delink = require( &amp;#039;Module:Delink&amp;#039; )._delink&lt;br /&gt;
	for capture in mw.ustring.gmatch( content, &amp;#039;\n=+[^\n]+=+&amp;#039; ) do&lt;br /&gt;
		-- Convert replacement only into plain text&lt;br /&gt;
		local before = escapeRepl( capture )&lt;br /&gt;
		local r = before:gsub( &amp;#039;%&amp;lt;%/?su[pb]%&amp;gt;&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
			:gsub( &amp;#039;(=+)%s*\&amp;#039;+(.-)\&amp;#039;+%s*%1&amp;#039;, &amp;#039;%1 %2 %1&amp;#039; )&lt;br /&gt;
		&lt;br /&gt;
		if capture:find( &amp;#039;%[&amp;#039; ) or capture:find( &amp;#039;%{&amp;#039; ) then&lt;br /&gt;
			r = parse( frame, r )&lt;br /&gt;
			r = delink( { r } )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if before ~= r then&lt;br /&gt;
			content = mw.ustring.gsub( content, escape( capture ), r )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	heading = mw.ustring.match( content, headingPattern )&lt;br /&gt;
	if heading ~= nil then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Preprocess templates and try to find an ID&lt;br /&gt;
	if type( anchorTemplates ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		for capture in content:gmatch( &amp;#039;{{[^}]+}}&amp;#039; ) do&lt;br /&gt;
			if isValidTemplate( capture ) then&lt;br /&gt;
				content = mw.ustring.gsub( content, escape( capture ), escapeRepl( parse( frame, capture ) ) )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	local id = mw.ustring.match( content, &amp;#039; id=&amp;quot;?&amp;#039; .. escape( anchor ) .. &amp;#039;&amp;quot;?&amp;#039; )&lt;br /&gt;
	if id ~= nil then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Try to find HTML heading tag&lt;br /&gt;
	local hX = mw.ustring.match( content, &amp;#039;%&amp;lt;(h[1-6])%&amp;gt;%s*&amp;#039; .. escapePattern( anchor ) .. &amp;#039;%s*&amp;lt;/%1&amp;gt;&amp;#039; )&lt;br /&gt;
	if hX ~= nil then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main( page, frame )&lt;br /&gt;
	local mwTitle = mw.title.new( page )&lt;br /&gt;
	if mwTitle == nil or not mwTitle.exists then&lt;br /&gt;
		return false, getError( string.format( getConfigVal( &amp;#039;errorMissing&amp;#039; ), page ) )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local target = mwTitle.redirectTarget&lt;br /&gt;
	if target == false then&lt;br /&gt;
		return false, getError( string.format( getConfigVal( &amp;#039;errorNotRedirect&amp;#039; ), page ) )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local anchor = target.fragment&lt;br /&gt;
	if isEmpty( anchor ) then&lt;br /&gt;
		return false, getError( string.format( getConfigVal( &amp;#039;errorNoSection&amp;#039; ), page ) )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return p._parse( anchor, target:getContent(), frame )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main( frame )&lt;br /&gt;
	local args = getArgs( frame )&lt;br /&gt;
	&lt;br /&gt;
	local result, err = p._main( args.page or mw.title.getCurrentTitle().fullText, frame )&lt;br /&gt;
	if result == true then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return string.format( &amp;#039;%s[[Category:%s]]&amp;#039;, err or &amp;#039;&amp;#039;, getConfigVal( &amp;#039;brokenSectionCat&amp;#039; ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Buto</name></author>
	</entry>
</feed>