Модуль:Текст

Материал из свободной русской энциклопедии «Традиция»
Перейти к навигации Перейти к поиску

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

--[[
	Dependencies:
--]]
local args_module = require 'Module:SummaryII/args'
local get_args, parse_args = args_module.get, args_module.parse

local ask, set = mw.smw.ask, mw.smw.set

local make_title = mw.title.new
local wikilink = rex_pcre.new '^\\[\\[(?<page>.+?)(?:\\|(?<alias>.*?))?\\]\\]$'

local match, len = mw.ustring.match, mw.ustring.len

local function parse_part (part)
	local page, alias
	
	local start, _, captures = wikilink:tfind (part)
	if start then
		page, alias = captures.page, captures.alias or captures.page
	else
		local title = make_title (part)
		if title then
			page, alias = title.fullText, title.subpageText
		else
			alias = part
		end
	end
	return page, alias
end	-- local function parse_part (part)

local function item (page, alias, toc)

	local link = page and '[[' .. page .. '|' .. alias .. ']]' or alias
	
	return '\n<li>' .. link .. (toc
	   and '\n<div class="tocinsummary" style="padding-left: 0.5em; font-size: smaller; font-style: italic">__TOC__</div>'
	   or '') .. '</li>'
	   
end	-- local function item (page, alias, toc)

local function contents_block (parts, start, finish, nocontent, current, currentno, wrapper)
	local lines = {}
	for no = start, finish do
		if parts [no] then
			local page, alias = parse_part (parts [no])
			local toc = not nocontent and (page == current or alias == current or currentno == no)
			lines [#lines + 1] = item (page, alias, toc)
		end
	end
	return #lines > 0 and ('\n<' .. wrapper .. '>'
						.. table.concat (lines, '\n')
						.. '</' .. wrapper .. '>') or '', toc
end	-- local function contents_block (parts, start, finish, nocontent, current, currentno, wrapper)

local function implement_contents (parts, nocontent, current, currentno)
	if not parts then
		return nil
	end
	local lines = '' --[[.. '<pre>parts = ' .. mw.dumpObject (parts) .. '\nnocontent =  ' .. mw.dumpObject (nocontent)
				.. '\ncurrent =  ' .. mw.dumpObject (current) .. '\ncurrentno =  ' .. mw.dumpObject (currentno) .. '</pre>']]
	local toc
	-- TOC heading:
	if type (parts) == 'table' then
		local last_part = table.maxn (parts)
		if last_part > 0 or parts [-2] or parts [-1] or parts [0] then
			lines = lines .. '<strong class="summarySection">Содержание</strong>'
			
			-- Prefaces:
			local preface_lines
			preface_lines, toc = contents_block (parts, -2, 0, nocontent, current, currentno, 'ul')
			-- Chapters:
			local chapter_lines
			chapter_lines, toc = contents_block (parts, 1, last_part, nocontent, current, currentno, 'ol')
			
			lines = lines .. preface_lines .. chapter_lines
		end -- if last_part > 0 or parts [-2] or parts [-1] or parts [0]
	end	-- if type (parts) == 'table'
	-- Table of contents, if not set yet:
	if not nocontent and not toc then
		lines = lines .. '\n<div class="tocinsummary">__TOC__</div>'
	end
	return lines
end	-- local function implement_contents (parts, nocontent, current, currentno)

-- If a page is a direct subpage:
local function subpage_of (subpage, page)
	return match (subpage, '^/[^/]+$', len (page) + 1) ~= nil
end	-- local function subpage_of (subpage, page)

-- Return only direct subpages of a page:
local function subpages (page, sortby)
	local subpages = ask {'[[-Подстраница::' .. page .. ']]'
						, '?#-=subpage'
						, '?' .. (sortby or '') .. '=no'
						, sort = sortby and sortby .. ','} or {}
	local parts = {}
	for _, row in ipairs (subpages) do
		if sort and subpage_of (row.subpage, page) and row.no and not parts [row.no] then
			parts [row.no] = row.subpage
		end
	end	-- for _, row in ipairs (subpages)
	for _, row in ipairs (subpages) do
		if subpage_of (row.subpage, page) and not parts [row.no] then
			parts [#parts + 1] = row.subpage
		end
	end	-- for _, row in ipairs (subpages)
	return parts
end	-- local function subpages (page, sortby)

local function chapter_params (frame)
	local regex = rex_pcre.new
	local args = parse_args (get_args (frame), {
		['parts / \\1']	= regex '^раздел(\\d+)$'
	  , nocontent		= regex '^безсодержания$'
	  , current			= regex '^раздел$'
	  , currentno		= regex '^№раздела$'
	})
	local parts = args.parts
	local title = mw.title.getCurrentTitle ()
	if not parts or not next (parts) then
		parts = subpages (title.basePageTitle.fullText, 'Номер раздела')
	end	-- if not parts or not next (parts)
	local nocontent = (args.nocontent or '') ~= ''
	local currentno = tonumber (args.currentno)
	local current = title.isSubpage and (args.current or currentno and parts [currentno] or title.fullText)
	-- TO DO: extract initial Arabic and Roman numerals.
	if not currentno then
		for i = -2, table.maxn (parts or {}) do
			if parts [i] and parts [i] == current then
		-- for i, row in pairs (parts or {}) do
			-- if row == current then
				currentno = tonumber (i)
				break
			end
		end	-- for i, row in pairs (parts)
	end	-- if not currentno
	return parts, nocontent, current, currentno
end	-- 	local function chapter_params (frame)
	
local function contents (frame)
	local parts, nocontent, current, currentno = chapter_params (frame)
	return implement_contents (parts, nocontent, current, currentno)
end	-- local function contents (frame)

local function chapter (frame)
	local parts, nocontent, current, currentno = chapter_params (frame)
	if current then
		local title = make_title (current)
		return title and title.isSubpage and title.subpageText or current
	else
		return ''
	end
end	-- local function chapter (frame)

local function set_no (frame)
	local parts, nocontent, current, currentno = chapter_params (frame)
	if currentno then
		set {['Номер раздела']	= currentno}
	end
end	-- local function set_no (frame)
		
return {
	['содержание']	= contents
  , ['раздел']		= chapter
  , ['задать']		= set_no
  , subpages		= subpages
  , ['подстраницы']	= function (frame)
  		return require 'Module:List'.multiline (subpages (frame.args [1], frame.args [2]), '*')
  	end	-- ['подстраницы']	= function (frame)
}	-- return {...}