Модуль:Publication

Материал из Викитеки — свободной библиотеки
Перейти к навигации Перейти к поиску
Документация Документация

Реализует функциональность шаблона {{книга}} и {{статья}} средствами Lua.

На Модуль:Publication/Песочница есть функции из w:Модуль:Публикация Википедии, для тамошнего более сложного w:Шаблон:Публикация

local p = {}

-- объект с методами. здесь сборка результата
local tpl = {t = {}}
function tpl:add(s) if type(s) == 'string' then table.insert(self.t, s) 
	elseif type(s) == 'table' then table.insert(self.t, table.concat(s)) end end
function tpl:result() return table.concat(self.t) end

function p.book(frame)
	-- параметры шаблона
	local pargs = frame:getParent().args
	-- mw.logObject(pargs,"pargs")
	local ref = is(pargs['ref'])
	local letter = is(pargs['буква'])
	local author; if is(pargs['автор']) then author = mw.text.trim(pargs['автор']:gsub('<.->', '')) end
	local part = is(pargs['часть'])
	local ilink_part = is(pargs['ссылка часть'])
	local wslink_part = is(pargs['Викитека часть']) or is(pargs['викитека часть'])
	local title = is(pargs['заглавие'])
	local wslink = is(pargs['Викитека']) or is(pargs['викитека'])
	local wplink = is(pargs['Википедия часть']) or is(pargs['википедия'])
	local commonslink = is(pargs['Викисклад']) or is(pargs['викисклад'])
	local ilink = is(pargs['ссылка'])
	local original = is(pargs['оригинал'])
	local volumes = is(pargs['томов'])
	local contributors = is(pargs['ответственный'])
	local nodot = is(pargs['nodot'])
	local edition = is(pargs['издание'])
	local place = is(pargs['город']) or is(pargs['место'])
	local publisher = is(pargs['издательство'])
	local year = is(pargs['год'])
	local volume_as_is = is(pargs['том как есть'])
	local volume = is(pargs['том'])
	local volume_en = is(pargs['volume'])
	local band = is(pargs['band'])
	local pages_as_is = is(pargs['страницы как есть'])
	local pages = is(pargs['страницы'])
	local columns = is(pargs['столбцы'])
	local pagesof_as_is = is(pargs['страниц как есть'])
	local pagesof = is(pargs['страниц'])
	local pages_en = is(pargs['pages'])
	local columns_en = is(pargs['columns'])
	local seite = is(pargs['seite'])
	local kolonnen = is(pargs['kolonnen'])
	local allpages = is(pargs['allpages'])
	local alleseiten = is(pargs['alleseiten'])
	local series = is(pargs['серия'])
	local tirage = is(pargs['тираж'])
	local isbn = is(pargs['isbn']) or is(pargs['ISBN'])
	local doi = is(pargs['doi']) or is(pargs['DOI'])
	
	-- тег и id
	tpl:add('<span class="citation" ')
	if ref then	
		year = year or ''
		letter = letter or ''
		tpl:add('id="'..mw.uri.anchorEncode( ref .. year .. letter )..'"')  
	end
	tpl:add('>')
	
	if author then 
		tpl:add('<i>'..nowrap(author)..'</i>')
		if not endswith_dot(author) then tpl:add('.') end
		tpl:add(' ')
	end
	
	if part then
		tpl:add(link(part, wslink_part, nil, nil, ilink_part))  -- часть, делать ссылкой
		tpl:add(' // ')
	end
	
	if title then tpl:add(link(title, wslink, wplink, commonslink, ilink)) end -- заглавие, делать ссылкой

	if original then tpl:add(' = '..original) end
	
	-- точка, если заголовок не кончается на символы пунктуации
	if not contributors and not volumes and ((title and not endswith_punctuation(title)) or (original and not endswith_punctuation(original))) then 
		tpl:add('.') end
	
	if volumes then tpl:add(' : в '..volumes..' т.') end
	
	-- ответственные
	if contributors then
		tpl:add(' / '..contributors) 
		if not endswith_dot(contributors) then tpl:add('.') end
	end
	
	if edition then tpl:add(' — '..edition..'.') end  -- издание
	
	if place or publisher or year then tpl:add(place_publisher_year(place, publisher, year)) end
	
	if (volume_as_is or volume or volume_en or band) and title then	tpl:add(' — ') end
	if volume_as_is then tpl:add(volume_as_is..'.') 
	elseif volume then tpl:add('Т. '..volume..'.')
	elseif volume_en then tpl:add('Vol. '..volume_en..'.') 
	elseif band then tpl:add('Bd. '..band..'.') 
	end
	
	if pagesof_as_is then tpl:add(' — '..pagesof_as_is..'.') 
	elseif pages then 
		tpl:add(' — С. ')
		if columns then tpl:add('['..pages..'] (стб. '..columns..')')	else tpl:add(pages) end
		tpl:add('.')
	elseif pagesof_as_is then tpl:add(' — '..pagesof_as_is..'.')
	elseif pagesof then tpl:add(' — '..pagesof..' с.') 
	elseif pages_en then
		tpl:add(' — P. ')
		if columns then tpl:add('['..pages_en..'] (col. '..columns..').')	else tpl:add(pages_en) end
	elseif seite then
		tpl:add(' — S. ')
		if kolonnen then tpl:add('['..seite..'] (Kol. '..kolonnen..').') else tpl:add(seite) end
	elseif allpages then tpl:add(' — '..allpages..' p.')
	elseif alleseiten then tpl:add(' — '..alleseiten..' S.') 
	end
		
	if series then tpl:add(' — ('..series..').') end
	if tirage then tpl:add(' — '..tirage..' экз.') end
	if isbn then tpl:add(' — ISBN '..isbn..'.') end
	if doi then tpl:add(' — '..doi) end
	
	 tpl:add('</span>')
	-- mw.logObject(tpl)
	return tpl:result()
end





function p.article(frame)
	-- параметры шаблона
	local pargs = frame:getParent().args
	-- mw.logObject(pargs,"pargs")
	local ref = is(pargs['ref'])
	local author; if is(pargs['автор']) then author = mw.text.trim(pargs['автор']:gsub('<.->', '')) end
	local title = is(pargs['заглавие'])
	local ilink = is(pargs['ссылка'])
	local wslink = is(pargs['Викитека']) or is(pargs['викитека'])
	local wplink = is(pargs['Википедия']) or is(pargs['википедия'])
	local commonslink = is(pargs['Викисклад']) or is(pargs['викисклад'])
	local ilink_ed = is(pargs['ссылка издание'])
	local wslink_ed = is(pargs['Викитека издание']) or is(pargs['викитека издание'])
	local wplink_ed = is(pargs['Википедия издание']) or is(pargs['википедия издание'])
	local commonslink_ed = is(pargs['Викисклад издание']) or is(pargs['викисклад издание'])
	local original = is(pargs['оригинал'])
	local volumes = is(pargs['томов'])
	local contributors = is(pargs['ответственный'])
	local author_edition = is(pargs['автор издания'])
	local edition = is(pargs['издание'])
	local ptype = is(pargs['тип'])
	local place = is(pargs['город']) or is(pargs['место'])
	local publisher = is(pargs['издательство'])
	local year = is(pargs['год'])
	local month = is(pargs['месяц'])
	local day = is(pargs['число']) or is(pargs['день'])
	-- local volume_as_is = is(pargs['том как есть'])
	local volume = is(pargs['том'])
	local volume_en = is(pargs['volume'])
	local band = is(pargs['band'])
	local issue = is(pargs['выпуск'])
	local issue_number = is(pargs['номер'])
	
	-- local pages_as_is = is(pargs['страницы как есть'])
	local pages = is(pargs['страницы'])
	-- local columns = is(pargs['столбцы'])
	-- local pagesof_as_is = is(pargs['страниц как есть'])
	-- local pagesof = is(pargs['страниц'])
	local pages_en = is(pargs['pages'])
	-- local columns_en = is(pargs['columns'])
	-- local seite = is(pargs['seite'])
	-- local kolonnen = is(pargs['kolonnen'])
	-- local allpages = is(pargs['allpages'])
	-- local alleseiten = is(pargs['alleseiten'])
	-- local series = is(pargs['серия'])
	-- local tirage = is(pargs['тираж'])
	local isbn = is(pargs['isbn']) or is(pargs['ISBN'])
	local issn = is(pargs['issn']) or is(pargs['ISSN'])
	local doi = is(pargs['doi']) or is(pargs['DOI'])
	local lang = is(pargs['lang']) or is(pargs['language']) or is(pargs['язык'])
	
	-- тег и id
	tpl:add('<span class="citation" ')
	if ref then	
		year = year or ''
		letter = letter or ''
		tpl:add('id="'..mw.uri.anchorEncode( ref .. year .. letter )..'"')  end
	tpl:add('>')
	
	if author then 
		tpl:add('<i>'..nowrap(author)..'</i>')
		if not endswith_dot(author) then tpl:add('.') end
		tpl:add(' ')
	end
	
	if title then
		tpl:add(link(title, wslink, wplink, commonslink, ilink))  -- заглавие, делать ссылкой если дана
		-- точка, если заголовок не кончается на символы окончания
		if not endswith_punctuation(title) and not original and not contributors then tpl:add('.') end
	end

	if lang then
		local s = 'шаблон:ref-'..lang
	 	if mw.title.new(s).exists then s = ' '..frame:expandTemplate{title=s} else s = ' ('..lang..')' end
	 	tpl:add(s)
 	end
	
	if contributors then tpl:add(' / '..contributors) end
		-- if not endswith_dot(contributors) then tpl:add('.') end

	if original then tpl:add(' = '..original) end
		-- if not  endswith_dot(original) and not volumes then tpl:add('.') end
	
	if author_edition and edition then 
		tpl:add(' // <i>'..author_edition..'</i>'..edition)
	elseif edition then 
		tpl:add(' // <i>'..link(edition, wslink_ed, wplink_ed, commonslink_ed, ilink_ed)..'</i>')
	end
	
	if ptype then tpl:add(' : '..ptype) end
	
	if not endswith_punctuation(title) then tpl:add('.') end
	
	if place or publisher or year then tpl:add(place_publisher_year(place, publisher, year)) end

	if month then 
		if day then
			local d = tonumber(day)
			local m = tonumber(month)
			local s = ''
			if (d>=1 and d <= 31) and (m>=1 and m <= 12) then s = '0000-'..month..'-'..day end
			tpl:add('&nbsp;— '.. mw.getContentLanguage():formatDate('j xg', s))
		end
	end

	if volume then	
		if month then tpl:add(' (т. '..volume) 
		else tpl:add(' — Т. '..volume) end
	end
	if volume_en then	
		if month then tpl:add(' (vol. '..volume_en) 
		else tpl:add(' — Vol. '..volume_en) end
	end
	if band then
		if month then tpl:add(' (bd. '..band) 
		else tpl:add(' — Bd. '..band) end
	end
	if issue then	
		if volume then 
			tpl:add(', вып. '..issue) 
		else
			if month then tpl:add(' (вып. '..issue)
			else tpl:add(' — Вып. '..issue) end
		end
	end
	if issue_number then
		if (volume or volume_en or band) then 
			tpl:add(', № '..issue_number) 
		else
			if month then tpl:add(' (№ '..issue_number)
			else tpl:add(' — № '..issue_number) end
		end
	end
	if (volume or volume_en or band or issue or issue_number) then
		if month then tpl:add(')') end
		tpl:add('.')
	end
	
	
	if pages then 
		tpl:add(' — С. '..pages)
		tpl:add('.')
	elseif pages_en then
		tpl:add(' — P. '..pages_en)
		tpl:add('.')
	end
	
	if isbn then tpl:add(' — ISBN '..isbn..'.') end
	if issn then tpl:add(' — [[ISSN]]  '..issn..'.') end
	if doi then tpl:add(' — '..doi) end
	
	tpl:add('</span>')
	-- mw.logObject(tpl)
	return tpl:result()
end

	

-- ***********

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

-- выбор приоритетной переменной из двух. если есть обе - первой. если нет обоих - ''
function onevar(var1,var2)
    if (var1 and var1 ~= '') then return var1  elseif (var2 and var2 ~= '') then return var2  else return '' end
end

-- создание ссылки на ВТ, ВП, Commons, интернет
function link(anchor, wslink, wplink, commonslink, inetlink)
	if is(anchor) then
		if     is(wslink) 	then return '[[s:ru:'..wslink..'|'..anchor..']]'
		elseif is(wplink) 	then return '[[w:ru:'..wplink..'|'..anchor..']]'
		elseif is(commonslink) then return '[[commons:'..commonslink..'|'..anchor..']]'
		elseif is(inetlink) then return '['..inetlink..' '..anchor..']'
		else return anchor end
	end
end

-- место, издательство, год
function place_publisher_year(place, publisher, year)
	local t = {}; function add(s) table.insert(t, s) end
	if place or publisher or year then 
		add(' — ')
		if place and publisher and year then add(place..': '..publisher..', '..year)
		elseif place and publisher then add(place..': '..publisher)
		elseif place and year then add(place..', '..year)
		elseif publisher and year then add(publisher..', '..year)
		elseif place then add(place)
		elseif publisher then add(publisher)
		elseif year then add(year)
		end
		add('.')
		return table.concat(t)
	else return ''
	end
end

function nowrap(s) return '<span style="white-space: nowrap;">'..s..'</span>' end

function endswith_dot(s) if s and mw.ustring.sub(s, -1, -1) == '.' then return true end end
function endswith_punctuation(s) if s and mw.ustring.find(s, '[!?.]', -1) then return true end end

return p