Módulo:Book

Revisão em 19h12min de 31 de janeiro de 2014 por He7d3r (discussão | contribs) (Esboço de função que reimplementa Template:AutoCat; O laço "Use integer args only" é uma adaptação de um trecho de w:en:Module:Comma separated entries (créditos: Mr. Stradivarius))

Uso

  • ...

Tarefas pendentes

  • Documentar este módulo
  • Conferir os arquivos dos diálogos comunitários para ver o que ainda precisa ser feito...
  • Atualizar Ajuda:Navegação automática
  • ...

Ver também


local collectionPrefix = 'Wikilivros:Livros/'
local arraySearch = function ( needle, haystack )
	for k,v in pairs( haystack ) do
		if v == needle then
			result = k;
		end
	end
	return result;
end

local getBookName = function ( page )
	page = page or mw.title.getCurrentTitle().text
	local pos = mw.ustring.find( page, '/' )
	if pos == nil then
		return page
	else
		return mw.ustring.sub( page, 1, pos - 1 )
	end
end

local getChapterName = function ( page )
	page = page or mw.title.getCurrentTitle().text
	local pos = mw.ustring.find( page, '/' )
	if pos == nil then
		return ''
	else
		return mw.ustring.sub( page, pos + 1 )
	end
end

-- Based on [[Template:AutoCat]]
local categories = function ( page, cats )
	local title = mw.title.new( page or '' ) or mw.title.getCurrentTitle()
	if title.namespace ~= 0 then
		-- This function should be used only for pages from main namespace
		return ''
	end
	local text = title.text
	local parts = mw.text.split( text, '/', true )
	chText = table.concat( parts, '/', 2 )
	local result = {}
	if chText == '' then
		-- This is the index
		table.insert( result, '{{DEFAULTSORT:*' .. text .. '}}' )
		table.insert( result, '[[Categoria:Todos os livros catalogados|' .. text .. ']]'  )
		for i, cat in ipairs( cats or {} ) do
			-- The index should be added to each category which is appropriated to the book
			table.insert( result, '[[Categoria:' .. tostring( cat ) .. ']]' )
		end
		table.insert( result, '[[Categoria:Livro/' .. text .. '|' .. text .. ']]' )
	else
		-- This is a chapter
		for i = 1, #parts-1 do
			local prefix = table.concat( parts, '/', 1, i )
			local subcat = 'Categoria:Livro/' .. prefix
			if mw.title.new( subcat ).exists then
				table.insert( result, '[[' .. subcat .. '|' .. table.concat( parts, '/', i+1 ) .. ']]' )
			else
				break
			end
		end
	end
	return table.concat( result, '\n' )
end

-- Based on parseCollectionLine from https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/Collection.git;a=blob;f=Collection.body.php;hb=f2bd4ee2be12ab3df5f2dcb3bd56ff17247fff66#l793)
-- Get "Book/Title" from a line in any of these formats:
-- :[[Book/Title]]
-- :[[Book/Title|Text]]
-- :[{{fullurl:Book/Title|oldid=12345}} Text]
local getChapterFromLine = function ( line )
	if mw.ustring.sub( line, 1, 1 ) ~= ':' then
	    -- There is no chapter on this line
	    return nil
	end
	line = mw.text.trim( mw.ustring.sub( line, 2, -1 ) )

	local title = mw.ustring.match( line, '^%[%[:?(.-)|.-%]%]$' ) or
		mw.ustring.match( line, '^%[%[:?(.-)%]%]$' ) or
		mw.ustring.match( line, '^%[{{fullurl:(.-)|oldid=.-}}%s+.-%]$' ) or
		''
	return title:gsub( '_',' ' )
end

local getListOfChaptersFromText = function ( str )
	local lines = mw.text.split( str, '[\r\n]+' )
	local i, line, chapter
	local result = {}
	for i, line in ipairs( lines ) do
		chapter = getChapterFromLine( line )
		if chapter and chapter ~= '' then
			table.insert( result, chapter )
		end
	end
	return result
end

local getChapters = function ( collectionPage )
	collectionPage = collectionPage or ( collectionPrefix .. getBookName() )
	local colContent = mw.title.new( collectionPage ):getContent()
	if colContent == nil then
		-- This book doesn't have a collection page
		return {}
	end
	-- FIXME: Optimize the code so it works for large books
	local chapters = getListOfChaptersFromText( mw.ustring.sub( colContent, 1, 18000 ) )
	return chapters
end

local getPrintableVersion = function ( chapters )
	chapters = chapters or getChapters()
	local frame = mw.getCurrentFrame()
	local result = ''
	local i, chapter
	for i, chapter in ipairs( chapters ) do
		if mw.title.new( chapter ).exists then
			result = result ..
				'<h1>[[' .. chapter .. '|' .. getChapterName( chapter ) .. ']]</h1>\n' ..
				frame:expandTemplate{ title = ':' .. chapter } .. '\n\n'
		end
	end
	return result
end

local core = function ( chapters, page, pPosition, relPosition )
	if pPosition == 'first' then
		return chapters[1];
	end
	if pPosition == 'last' then
		return chapters[#chapters];
	end
	if pPosition ~= nil and chapters[pPosition] then
		return chapters[pPosition];
	end
	local cPosition = arraySearch( page, chapters );
	if cPosition == nil then
		return '';
	end
	if pPosition == 'prev' then
		return chapters[cPosition - 1];
	end
	if pPosition == 'next' then
		return chapters[cPosition + 1];
	end
	if relPosition == nil then
		return '';
	end
	return chapters[cPosition + relPosition];
end

return {
	_arraySearch = arraySearch,
	_getBookName = getBookName,
	_getChapterName = getChapterName,
	_getChapterFromLine = getChapterFromLine,
	_getListOfChaptersFromText = getListOfChaptersFromText,
	_getChapters = getChapters,
	_getPrintableVersion = getPrintableVersion,
	_categories = categories,
	_core = core,
	getBookName = function( frame )
		return getBookName( frame.args[1] )
	end,
	getChapterName = function( frame )
		return getChapterName( frame.args[1] )
	end,
	getPrintableVersion = function( frame )
		local bookName = frame.args[1] or getBookName()
		local chapters = getChapters( collectionPrefix .. bookName )
		return getPrintableVersion( chapters )
	end,
	nav = function ( frame )
		local chapters = getChapters( frame.args['list'] )
		-- On page [[*A'B&C"D]], {{PAGENAME}} returns "&#42;A&#39;B&#38;C&amp;#34;D", so decode it first!
		local page = mw.text.decode( frame.args['page'] or mw.title.getCurrentTitle().text );
		local pPosition = frame.args['position'];
		local relPosition = frame.args['relative-position'];
		return core( chapters, page, pPosition, relPosition );
	end,
	cat = function ( frame )
		local cats = {}
		-- Use integer args only
		for k, v in pairs( frame.args ) do
			if type( k ) == 'number'
				and k >= 1
				and math.floor( k ) == k
				and mw.ustring.match( v, '%S' ) -- Remove blank or whitespace values.
				then
				table.insert( cats, mw.text.trim( v ) )
			end
		end
		return categories( nil, cats );
	end
};