local getArgs = require('Module:Arguments').getArgs
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 function getArgNums(args)
-- Returns an array containing the keys of all positional arguments that contain data (i.e. non-whitespace values).
local nums = {}
for k, v in pairs(args) do
if v and type(k) == 'number' then
table.insert(nums, k)
end
end
table.sort(nums)
return nums
end
-- [[Predefinição:NOMEDOLIVRO]]
local getBookName = function ( page )
page = page or mw.title.getCurrentTitle().text
local pos = mw.ustring.find( page, '/' )
if pos == nil then
return page
end
return mw.ustring.sub( page, 1, pos - 1 )
end
-- [[Predefinição:NOMEDOCAPÍTULO]]
local getChapterName = function ( page )
page = page or mw.title.getCurrentTitle().text
local pos = mw.ustring.find( page, '/' )
if pos == nil then
return ''
end
return mw.ustring.sub( page, pos + 1 )
end
-- [[Predefinição:EXISTBASEPAGENAME]]
local getExistingBasePageName = function ( page )
if not page or page == '' then
page = mw.title.getCurrentTitle().text
end
local parts = mw.text.split( page, '/', true )
if #parts == 1 then
return page
end
for i = #parts-1, 1, -1 do
local base = table.concat( parts, '/', 1, i )
if mw.title.new( base ).exists then
return base
end
end
return table.concat( parts, '/', 1, #parts-1 )
end
-- [[Predefinição:EXISTSUBPAGENAME]]
local getExistingSubPageName = function ( page )
if not page or page == '' then
page = mw.title.getCurrentTitle().text
end
local parts = mw.text.split( page, '/', true )
if #parts == 1 then
return page
end
for i = #parts-1, 1, -1 do
local base = table.concat( parts, '/', 1, i )
if mw.title.new( base ).exists then
return table.concat( parts, '/', i + 1 )
end
end
return parts[ #parts ]
end
-- Based on [[Template:AutoCat]]
local categories = function ( args )
local title = mw.title.new( args['página'] 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 == '' and #parts == 1 then
-- This is the index
table.insert( result, '[[Categoria:Todos os livros catalogados|' .. text .. ']]' )
local argNums = getArgNums( args )
for i, num in ipairs( argNums ) do
-- The index should be added to each category which is appropriated to the book
table.insert( result, '[[Categoria:' .. tostring( args[num] ) .. '|*' .. text .. ']]' )
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 or i == 1 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
-- FIXME: Implement a limit on the number of chapters (Collection uses 500 by default)
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
local navbar = function( page )
local page = page or mw.title.getCurrentTitle().text
local bookName = getBookName( page )
local chapters = getChapters( collectionPrefix .. bookName )
local prevCh = core( chapters, page, 'prev' )
local nextCh = core( chapters, page, 'next' )
local ul = mw.html.create( 'ul' )
:addClass( 'auto-nav' )
:tag('li')
:addClass( 'auto-nav-index' )
:tag('a')
-- FIXME: {{Acima|2}}
:attr( 'title', 'Acima: ' .. bookName )
-- FIXME: {{Acima}}
:attr( 'href', tostring( mw.uri.localUrl( bookName ) ) )
-- FIXME: {{Acima|2}}
:wikitext( bookName )
:done()
:done()
local a
if prevCh ~= '' then
a = ul
:tag('li')
:addClass( 'auto-nav-prev' )
:tag('a')
-- FIXME: {{Anterior|2}}
:attr( 'title', 'Anterior: ' .. prevCh )
-- FIXME: {{Anterior}}
:attr( 'href', tostring( mw.uri.localUrl( prevCh ) ) )
-- FIXME: {{Anterior|2}}
:wikitext( prevCh )
if not mw.title.new( prevCh ).exists then
a:addClass( 'new' )
end
end
if nextCh ~= '' then
a = ul
:tag('li')
:addClass( 'auto-nav-next' )
:tag('a')
-- FIXME: {{Anterior|2}}
:attr( 'title', 'Posterior: ' .. nextCh )
-- FIXME: {{Anterior}}
:attr( 'href', tostring( mw.uri.localUrl( nextCh ) ) )
-- FIXME: {{Anterior|2}}
:wikitext( nextCh )
if not mw.title.new( nextCh ).exists then
a:addClass( 'new' )
end
end
return tostring( ul )
end
return {
_arraySearch = arraySearch,
_getBookName = getBookName,
_getChapterName = getChapterName,
_getExistingBasePageName = getExistingBasePageName,
_getExistingSubPageName = getExistingSubPageName,
_getChapterFromLine = getChapterFromLine,
_getListOfChaptersFromText = getListOfChaptersFromText,
_getChapters = getChapters,
_getPrintableVersion = getPrintableVersion,
_categories = categories,
_navbar = navbar,
_core = core,
getBookName = function( frame )
local args = getArgs( frame )
return getBookName( args[1] )
end,
getChapterName = function( frame )
local args = getArgs( frame )
return getChapterName( args[1] )
end,
getExistingBasePageName = function( frame )
local args = getArgs( frame )
return getExistingBasePageName( args[1] )
end,
getExistingSubPageName = function( frame )
local args = getArgs( frame )
return getExistingSubPageName( 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 "*A'B&C&#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 args = getArgs( frame, {
valueFunc = function (key, value)
if not value then
return nil
end
value = mw.text.trim( value or '' )
if ( type(key) == 'number' and value ~= '' ) or key == 'página' then
return value
end
end
} )
return categories( args );
end
};