Module:Volume

-- module to form Marvel Database:Volume Template local p = {} local list_of_series = mw.loadData( 'Module:Volume/Series' ) local h = require("Module:HF") local standart = require("Module:StandardizedName") local m_date = require("Module:Date") local design = require("Module:Design") local getArgs = require('Dev:Arguments').getArgs local list_of_canceled_issues

function p.main(frame) local args = getArgs (frame) local exclude = args['exclude'] local pagename = args['category'] or mw.title.getCurrentTitle.text local previous_volume = args['PreviousVol'] local next_volume = args['NextVol'] local volume_logo = args['VolumeLogo'] local publisher = p.lua_publisher(args['Publisher']) local creators = p.lua_creators( args['Creators'] ) or '' local volume_type = args['Type'] or '' local volume_status = args['Status'] or '' local featured = args['Featured'] or '' local storyarcs = args['StoryArcs'] or '' local storylines = args['Storylines'] or '' local crossovers = args['Crossovers'] or '' local notes = args['Notes'] or '' local see_also = args['SeeAlso'] or '' local issue_list = args['IssueList'] or '' local name_info = standart.lua_get_title_volume_issue(pagename, 'Vol') local volume_info = {} local categories = {} local category = '' local dpl_string = '' local parts = {} local above = {} local below = {} local list = {} local first_by_date local last_by_date local i   local s    local top_message1 = '' local top_message2 = '' local top_message3 = '' local navigation = '' local total_issues = 0 local number_of_canceled_issues = 0 local infobox = {} local display_title = pagename local output = {}

list_of_canceled_issues = mw.text.split( frame:preprocess(''), '@@@' )

if not h.isempty(exclude) then exclude = mw.text.split(exclude,";",true) else exclude = {} end

table.insert(categories, 'Comic Lists') -- create list of all issues from category with DPL dpl_string = frame:preprocess( p.lua_dpl_list(pagename)..p.lua_dpl_list(pagename, 500) ) volume_info = p.lua_get_volume_info(dpl_string, exclude) list = volume_info.list first_by_date = volume_info.first_by_date last_by_date = volume_info.last_by_date number_of_canceled_issues = p.lua_get_number_of_canceled_issues(list) -- create top navigation and infobox table.insert(infobox, { left = 'Publisher', right = h.Link(publisher, publisher) } ) volume_status, category = p.lua_get_volume_status(volume_status, first_by_date, last_by_date) table.insert(infobox, { left = 'Status', right = volume_status } ) table.insert(categories, category) table.insert(infobox, { left = 'Dates Published', right = p.lua_dates_published(first_by_date, last_by_date) } ) volume_type, category = p.lua_volume_type(volume_type, #list, last_by_date) table.insert(infobox, { left = 'Type', right = volume_type } ) table.insert(categories, category) total_issues = p.lua_get_number_of_issues(#list, number_of_canceled_issues) table.insert(infobox, { left = 'Total Issues', right = h.Link(':Category:'..pagename, total_issues) } ) table.insert(infobox, { left = 'Creators', right = mw.text.listToText(creators, '\n', '\n') }) featured = p.lua_divide_list(featured) storyarcs = p.lua_divide_list(storyarcs) storylines = p.lua_divide_list(storylines) crossovers = p.lua_divide_list(crossovers) table.insert(infobox, { left = 'Featured', right = mw.text.listToText(featured, '\n', '\n' )}) table.insert(infobox, { left = 'Story arcs', right = mw.text.listToText(storyarcs, '\n', '\n') }) table.insert(infobox, { left = 'Storylines', right = mw.text.listToText(storylines, '\n', '\n') }) table.insert(infobox, { left = 'Crossovers', right = mw.text.listToText(crossovers, '\n', '\n') }) running_years = p.lua_get_running_years(first_by_date, last_by_date, true, volume_status) -- create top message previous_volume, next_volume = p.lua_get_previous_and_next_volume(pagename, previous_volume, next_volume) --top_message1 = p.lua_top_message(pagename, running_years, previous_volume, next_volume, volume_logo, publisher) --top_message2 = p.lua_top_message2(pagename, running_years, previous_volume, next_volume, volume_logo, publisher) top_message3 = p.lua_top_message3(pagename, first_by_date, last_by_date,                                     volume_type, volume_status, total_issues, volume_info.relaunches,                                      previous_volume, next_volume, volume_logo, publisher,                                      creators, featured, storyarcs, storylines, crossovers) --navigation, category = p.lua_navigation(pagename, p.lua_create_infobox(infobox)) --table.insert(categories, category) table.insert(categories, p.lua_volumes_by_number_of_issues(#list) ) -- add publisher category table.insert(categories, publisher) -- add volume debut, relaunch and end categories table.insert(categories, p.lua_volume_debut(first_by_date, volume_status)) if #volume_info.relaunches > 0 then table.insert(categories, 'Relaunched Series') end table.insert(categories, p.lua_volume_end(last_by_date, volume_status)) -- check if Annual if string.find(pagename, 'Annual', 1, true) ~= nil then table.insert(categories, 'Annuals') end -- check if Handbook if string.find(pagename, 'Handbook', 1, true) ~= nil or      string.find(pagename, 'OHOTMU', 1, true) ~= nil or       string.find(pagename, 'OHOTUMU', 1, true) ~= nil then table.insert(categories, 'Handbooks') end -- check if TPB if string.find(pagename, ' TPB ', 1, true) ~= nil or      string.find(pagename, ' HC ', 1, true) ~= nil then table.insert(categories, 'Trade Paperbacks') end -- add comic series (if any) categories = h.lua_concatTables( categories, p.lua_get_comic_series(pagename, featured) )

-- create list of all suitable categories categories = p.lua_create_list_of_categories(categories, name_info.sortname.noissue) -- create gallery of issues for i = 1,9 do       s = args['part'..i]        if not h.isempty(s) then table.insert(parts, tonumber(standart.lua_padded_issue(s))) table.insert(above, args['part'..i..'_above'] or '') table.insert(below, args['part'..i..'_below'] or '') end end if h.isempty(issue_list) then issue_list = p.lua_create_issue_list(list, parts, above, below) end -- add everything to page table.insert(output, top_message3) --table.insert(output, navigation) table.insert(output, issue_list) if not h.isempty(see_also) then table.insert(output, design.lua_header('See Also', 2)..'\n'..see_also) end if not h.isempty(notes) then table.insert(output, design.lua_header('Notes', 2)..'\n'..notes..' '

return design.messagebox( { output } ) end

function p.lua_top_message2(pagename, running_years, previous_volume, next_volume, volume_logo, publisher) local publisher_logo = p.lua_get_publisher_logo(publisher) local function tag_div(text) return tostring(mw.html.create( 'td' )               :css('width', '20px')                :wikitext(text)                :done ) end local tag_td_center local images_category = pagename..'/Images' local output = ''

publisher = ' (published by '..publisher..')' if not h.isempty(volume_logo) then volume_logo = '' end if h.lua_PagesInCategory(images_category, 'files') > 0 then images_category = h.Link(':Category:'..images_category, 'List of images') else images_category = '' end

pagename = h.Link(':Category:'..pagename, pagename)

previous_volume = '' next_volume = ''

volume_logo = volume_logo or publisher_logo

--tag_td_center = ' '..pagename..running_years..publisher..' ' --output = ' '

--pagename = pagename..running_years..publisher tag_td_center = ''..pagename..' '..images_category..' ' pagename = tag_div(previous_volume)..tag_td_center..tag_div(next_volume)

return design.show_hide({ title = volume_logo..' '..pagename, body = 'test', clear = 'right', width = '300px', extrastyle = 'float:right; border-radius:10px;' })..' ' end

function p.lua_top_message3(pagename, first_by_date, last_by_date,                            volume_type, volume_status, total_issues, relaunches,                            previous_volume, next_volume, volume_logo, publisher,                            creators, featured, storyarcs, storylines, crossovers) local message = '' local publisher_logo = p.lua_get_publisher_logo(publisher) local function tag_td(text) return tostring(mw.html.create( 'td' )               :css('width', '15%')                :css('font-size', '80%')                :wikitext(text)                :done ) end local tag_td_center local images_category = pagename..'/Images' local images_category_counter = h.lua_PagesInCategory(images_category, 'files') local issues_and_images = '' local first = m_date.lua_link_to_publication_category(first_by_date.year, first_by_date.month) local last = m_date.lua_link_to_publication_category(last_by_date.year, last_by_date.month) local first2 = first local one_shot = false local v_type local v_status local relaunched_years = {} local s = '' local n   local output = {}

n = #relaunches if n > 0 then for i = 1, n do               table.insert( relaunched_years, h.Link(relaunches[i].pagename, relaunches[i].year) ) end s = ' (with '..n           if n == 1                then s = s..' relaunch in '                else s = s..' relaunches in '            end            relaunched_years = s..mw.text.listToText(relaunched_years)..')' else relaunched_years = '' end

if not h.isempty(first_by_date.year) and not h.isempty(last_by_date.year) and not h.isempty(first_by_date.month) and not h.isempty(last_by_date.month) then if first_by_date.year == last_by_date.year then first2 = string.gsub(first, ', %[(.+)', '') end end

publisher = ' by '..publisher..'' if not h.isempty(volume_logo) then volume_logo = '' else volume_logo = '' end

total_issues = h.Link(':Category:'..pagename, total_issues)

if images_category_counter > 0 then if images_category_counter == 1 then s = ' image' else s = ' images' end images_category = h.Link(':Category:'..images_category, images_category_counter..s)       else images_category = '' end if images_category ~= '' then issues_and_images = total_issues..' • '..images_category else issues_and_images = total_issues end

if not h.isempty(featured) then featured = ' featuring '..mw.text.listToText(featured) else featured = '' end

v_type = string.lower(volume_type) if v_type == 'ongoing series' then s = ' an ' else s = ' a ' end if v_type == 'one shot' then one_shot = true end if volume_status == 'Finished' then v_type = ' was'..s..v_type elseif volume_status == 'Canceled' then v_type = ' is'..s..'canceled '..v_type else v_type = ' is'..s..v_type end v_type = v_type..featured..'.' if not h.isempty(creators) then creators = ' Created by '..mw.text.listToText(creators) else creators = '' end if volume_status == 'Finished' then if one_shot or first == last then v_status = ' was published'..publisher..' in '..first else v_status = ' was published'..publisher..' from '..first2..' to '..last end elseif volume_status == 'Active' then if one_shot or first == last then v_status = ' is published'..publisher..' in '..first else v_status = ' is published'..publisher..' from '..first..' with latest known issue scheduled to be published in '..last end elseif volume_status == 'Announced' then v_status = ' is scheduled to be published'..publisher..' in '..first elseif volume_status == 'Canceled' then v_status = ' was scheduled to be published'..publisher..' in '..first end if creators ~= '' then v_status = ', it'..v_status..relaunched_years..'.' else v_status = ' It'..v_status..relaunched_years..'.' end --storyarcs, storylines, crossovers if not h.isempty(storyarcs) then s = tostring( mw.html.create('span'):css('font-weight','bold'):wikitext('Storyarcs: ') ) storyarcs = s..mw.text.listToText(storyarcs)..', ' else storyarcs = '' end if not h.isempty(storylines) then s = tostring( mw.html.create('span'):css('font-weight','bold'):wikitext('Storylines: ') ) storylines = s..mw.text.listToText(storylines)..', ' else storylines = '' end if not h.isempty(crossovers) then s = tostring( mw.html.create('span'):css('font-weight','bold'):wikitext('Crossovers: ') ) crossovers = s..mw.text.listToText(crossovers) else crossovers = '' end pagename = tostring( mw.html.create('span'):css('font-weight','bold'):wikitext(pagename) )

message = pagename..v_type..creators..v_status--..storyarcs..storylines..crossovers

tag_td_center = ' '..message..' ' table.insert(output, ' ') return design.messagebox( { table.concat(output) } ) end

function p.lua_navigation(pagename, text) local tag_div = mw.html.create('div') :css('display', 'table') :css('margin', '0 auto') :css('width', '95%') :css('border-top', '1px solid lightgrey') :css('border-bottom', '1px solid lightgrey') :css('text-align', 'left') :css('font-size', '14px') :css('padding-top', '5px') :css('padding-bottom', '5px') :done local info = standart.lua_get_title_volume_issue(pagename,'Vol') local link_to_contents = h.Link('Contents', 'Back to title selection') local first_character = string.sub(info.sortname.all, 1, 1) local link_to_first_character = '' local output = '' text = text or '' if string.match(first_character, '%a') == nil then if string.match(first_character, '%d') ~= nil then first_character = '0 9' else first_character = '&' end end

first_character = 'Comics '..first_character link_to_first_character = h.Link(':Category:'..first_character, first_character) output = link_to_contents..' : '..link_to_first_character..' : '..info.noissue..text return tostring( tag_div:wikitext(output) ), first_character end

function p.lua_create_infobox(infobox) local s = '' local output = {}

for i = 1,#infobox do       if not h.isempty(infobox[i]) and not h.isempty(infobox[i].right) then s = design.infobox_line( {left = infobox[i].left, right = infobox[i].right, width_l = '90px', width_r = '150px'} ) table.insert(output, s)       end end output = design.show_hide({               collapsed   = true,                width = '250px',                clear = 'none',                extrastyle  = 'float:right; border-radius:10px;',                title       = 'Volume Information',                 titlestyle = 'text-align: center;',                body        = table.concat(output)            }) return output end

function p.lua_get_volume_status(volume_status, first_by_date, last_by_date) local s = '' local first = first_by_date.sort_date local last = last_by_date.sort_date local current_date = tonumber( m_date.lua_date_converter('now', 'Ym') ) local date_of_last_solicit = tonumber( m_date.lua_date_converter('now + 4 months', 'Ym') ) -- +4 months because pages for new comics normally created shortly after publication of solicitations -- solicitations appear 2 months before the release date -- publication is 2 months after release local output = '' local category = ''

if not h.isempty(volume_status) then s = string.lower(volume_status) if s == 'active' or s == 'active series' then output = 'Active' category = 'Active Series' elseif s == 'finished' or s == 'finished series' then output = 'Finished' category = 'Finished Series' elseif s == 'canceled' or s == 'canceled series' then output = 'Canceled' category = 'Canceled Series' else output = volume_status end elseif first >= current_date then output = 'Announced' category = 'Announced Series' elseif last = date_of_last_solicit then output = 'Active' category = 'Active Series' elseif first_by_date.canceled then output = 'Canceled' category = 'Canceled Series' else output = 'Finished' category = 'Finished Series' end return output, category end

function p.lua_volume_type(volume_type, total_issues, last_by_date) local s = '' local last = last_by_date.sort_date local current_date = tonumber( m_date.lua_date_converter('now + 5 months', 'Ym') ) local output = '' local category = '' total_issues = tonumber(total_issues) if not h.isempty(volume_type) then s = string.lower(volume_type) if s == 'limited' or s == 'limited series' then output = 'Limited Series' category = output elseif s == 'one shot' or s == 'one-shot' then output = 'One Shot' category = 'One Shots' elseif s == 'ongoing' or s == 'ongoing series' then output = 'Ongoing Series' else output = volume_type end elseif total_issues == 1 and last < 99901 and last < current_date then output = 'One Shot' category = 'One Shots' elseif total_issues <= 5 and last < 99901 and last < current_date then output = 'Limited Series' category = output else output = 'Ongoing Series' end return output, category end

function p.lua_creators(creators) local SC = require("Module:StaffCorrection") local creator = '' local corrected = '' local i   local s    local output = {} if not h.isempty(creators) then s = mw.text.split(creators, ';') for i = 1,#s do               creator = h.lua_breaklink(s[i], 1) corrected = SC.Correction(creator) table.insert(output, h.Link(creator, corrected)) end end return output end

function p.lua_dates_published(first_by_date, last_by_date) local first = m_date.lua_link_to_publication_category(first_by_date.year, first_by_date.month) local last = m_date.lua_link_to_publication_category(last_by_date.year, last_by_date.month) local output if first == last then output = first else output = first..' – '..last end return output end

function p.lua_divide_list(list) local link = '' local text = '' local i   local output = {} if not h.isempty(list) then if string.find(list, ';', 1, true) ~= nil then list = mw.text.split(list, ';') for i = 1,#list do                       link = h.lua_breaklink(list[i], 1) text = h.lua_breaklink(list[i], 2) table.insert(output, h.Link(link, text)) end elseif not h.lua_isLink(list) and h.lua_isexists(list) then table.insert(output, h.Link(list, list) ) else table.insert(output, list) end end return output end

function p.lua_create_issue_list(list, parts, above, below) local i   local j    local k    local s = {} local output = {} if h.isempty(parts) then output = { p.lua_create_gallery(list, , ) } else table.insert(parts, tonumber(list[#list].padded_issue) ) k = 1 for i = 1,#parts do               s = {} for j = k,#list do                   if tonumber(list[j].padded_issue) <= parts[i] then table.insert(s, list[j]) else k = j                           break end end table.insert(output, p.lua_create_gallery(s, above[i], below[i]) ) end end return table.concat(output) end

function p.lua_create_gallery(list, above, below) local link = '' local canceled = ' '..design.lua_green('Canceled') local publication_date = '' local output = {} above = above or '' below = below or ''

for i = 1,#list do       publication_date = m_date.lua_link_to_publication_category(list[i].year, list[i].month) if not h.isempty(publication_date) then publication_date = ' ('..publication_date..')' end link = p.lua_link(list[i].pagename) if list[i].canceled then link = link..canceled end table.insert(output, '\n'..list[i].image..'|'..link..list[i].storytitle..publication_date) end output = table.concat(output) output = '' return above..output..below end

function p.lua_transform_string_into_list(str, exclude) local list = {} local info = {} local image = '' local storytitle = '' local year = '' local month = '' local pagename = '' local canceled = false local sort_date = '' local s = '' local output = {} if not h.isempty(str) then list = mw.text.split(str, '@@@', true) for i = 1, #list do               if not h.isempty(list[i]) then s = mw.text.split(list[i], '~', true) pagename = s[1] if not h.isempty(exclude) and exclude[pagename] ~= nil then s = '' else canceled = h.inlist(list_of_canceled_issues, pagename) info = standart.lua_get_title_volume_issue(pagename) image = p.lua_cover(s[2], info) storytitle = p.lua_storytitle(s[3]) year = s[4] or '' month = s[5] or '' if not h.isempty(month) then month = m_date.month({month}) else month = '' end sort_date = p.lua_date_for_sorting(year, month) s ={['pagename'] = pagename, ['image'] = image, ['storytitle'] = storytitle, ['year'] = year, ['month'] = month, ['padded_issue'] = info.padded_issue, ['canceled'] = canceled, ['sort_date'] = sort_date, }                               table.insert(output, s)                        end end end end return output end

function p.lua_dpl_list(pagename, offset) local template = '{Marvel Database:Comic Template}' local image = template..':Image, ' local year = template..':Year, ' local month = template..':Month, ' local storytitle = template..':StoryTitle1, ' local output = {}

table.insert(output, '')

return table.concat(output) end

function p.lua_sort_by_issue(a, b)   local issue1 = a.padded_issue local issue2 = b.padded_issue local output if h.isempty(issue1) or h.isempty(issue2) then output = false else if tonumber(issue1) ~= nil then if tonumber(issue2) ~= nil then output = tonumber(issue1) < tonumber(issue2) else output = true end elseif tonumber(issue2) ~= nil then output = false else output = issue1 < issue2 end end

return output end

function p.lua_sort_by_date(a, b)   if a.sort_date == b.sort_date then return p.lua_sort_by_issue(a, b)       else return a.sort_date < b.sort_date end end

function p.lua_year_for_sorting(year) local output = year if h.isempty(output) then output = '9999' end return output end

function p.lua_month_for_sorting(month) local output = month if h.isempty(output) then output = '1' end return output end

function p.lua_date_for_sorting(year, month) year = p.lua_year_for_sorting(year) month = p.lua_month_for_sorting(month)

return tonumber( m_date.lua_date_converter(month..'-01-'..year, 'Ym') ) end

function p.lua_get_first_and_last_by_date(list_sorted_by_date) local first_by_date local last_by_date if not h.isempty(list_sorted_by_date) then table.sort(list_sorted_by_date, p.lua_sort_by_date) first_by_date = list_sorted_by_date[1] for i = #list_sorted_by_date,1,-1 do               if list_sorted_by_date[i].sort_date < 999901 then last_by_date = list_sorted_by_date[i] break end end end return first_by_date, last_by_date end

function p.lua_get_running_years(first_by_date, last_by_date, link, volume_status) local first_year = first_by_date.year or '' local last_year = last_by_date.year or '' local output = '' if not h.isempty(first_year) and not h.isempty(last_year) then if link then first_year = h.Link(':Category:'..first_year, first_year) last_year = h.Link(':Category:'..last_year, last_year) end if first_year == last_year then if h.isempty(volume_status) or volume_status == 'Active' then output = ' ('..first_year..'–...)' else output = ' ('..first_year..')' end elseif h.isempty(volume_status) or volume_status == 'Active' then output = ' ('..first_year..'–...)' else output = ' ('..first_year..'–'..last_year..')' end end return output end

-- checks if volume title is in list of known comics books series (for example, "Wolverine Comics Books", "Spider-Man Comics Books", etc.) function p.lua_get_comic_series(pagename, featured) local series local title local names = {} local link = '' local text = '' local output = {}

table.insert(names, pagename) if not h.isempty(featured) then for i = 1,#featured do               if not h.isempty(featured[i]) then link = string.gsub(h.lua_breaklink(featured[i], 1), ' %(.-%)', '') text = string.gsub(h.lua_breaklink(featured[i], 2), ' %(.-%)', '') table.insert(names, link) table.insert(names, text) end end end series = list_of_series[pagename] if series == nil then for title, series in pairs(list_of_series) do               for i = 1, #names do                    if string.find(string.lower(names[i]), string.lower(title)..'%A', 1, false) ~= nil then table.insert(output, series) end end end end

return output end

-- return "image", if not empty, otherwise check if main cover or textless cover exists, if not, then return 'No Image Cover.jpg' function p.lua_cover(image, info) local cover = '' local textless = '' local output = ''

if not h.isempty(image) then output = image else cover = info.title_for_files..' Vol '..info.volume..' '..info.issue textless = cover..' Textless.jpg' cover = cover..'.jpg' if h.lua_isexists('File:'..cover) then output = cover elseif h.lua_isexists('File:'..textless) then output = textless else output = 'No Image Cover.jpg' end end return output end

function p.lua_storytitle(storytitle) local output = '' local tag = mw.html.create( 'span' ) :css( 'color', 'grey' ) :css( 'font-style', 'oblique' ) if not h.isempty(storytitle) then output = ' '..tostring( tag:wikitext( '"'..storytitle..'"' ):done ) end return output end

function p.lua_link(pagename) local output = '' local tag = mw.html.create( 'span' ) :css( 'font-weight', 'bold' ) if not h.isempty(pagename) then output = tag:wikitext( standart.lua_standardized_link(pagename, 'Comics') ):done output = tostring(output) end return output end

function p.lua_volume_debut(first_by_date, volume_status) local month = first_by_date.month local year = first_by_date.year local output = '' if volume_status ~= 'Canceled' then if not h.isempty(year) then if not h.isempty(month) then month = month..' ' else month = '' end output = month..year..' Volume Debut' end end return output end

function p.lua_volume_end(last_by_date, volume_status) local month = last_by_date.month local year = last_by_date.year local output = '' if volume_status == 'Finished' then if not h.isempty(year) then if not h.isempty(month) then month = month..' ' else month = '' end output = month..year..' Volume End' end end return output end

function p.lua_create_list_of_categories(categories, sortname) local i   local output = {}

if not h.isempty(categories) then if not h.isempty(sortname) then sortname = '|'..sortname else sortname = '' end for i = 1,#categories do               if not h.isempty(categories[i]) then table.insert(output, '') end end end return table.concat(output) end

-- Template:Cvd -  Comic Volume Description function p.lua_cvd(pagename, dpl_string) local function counter(n) local tag = mw.html.create('span'):css('color', 'grey') local output = '' n = tonumber(n) if not h.isempty(n) then if n == 1 then n = '1 issue' else n = n..' issues' end else n = '' end output = tag:wikitext(n):done return tostring(output) end local running_years local volume_status local info local output = ''

info = p.lua_get_volume_info(dpl_string) volume_status = p.lua_get_volume_status('', info.first_by_date, info.last_by_date) running_years = p.lua_get_running_years(info.first_by_date, info.last_by_date, true, volume_status) output = standart.lua_standardized_link(pagename, 'Comics')

return output..' '..running_years..' '..counter(info.counter) end

function p.cvd(frame) local args = getArgs (frame) local pagename = args[1] dpl_string = frame:preprocess( p.lua_dpl_list(pagename)..p.lua_dpl_list(pagename, 500) ) return p.lua_cvd(pagename, dpl_string) end

return p