Marvel Database
(test)
No edit summary
Line 278: Line 278:
 
local categories = {}
 
local categories = {}
 
local output = {}
 
local output = {}
  +
 
genres = p.lua_divide_list(genres, false)
+
if not h.isempty(genres)
if genres ~= {}
 
 
then
 
then
  +
genres = p.lua_divide_list(genres, false)
 
for i = 1, #genres do
 
for i = 1, #genres do
 
s = genres[i]..' Genre Volumes'
 
s = genres[i]..' Genre Volumes'

Revision as of 14:14, 17 July 2020

Documentation for this module may be created at Module:Volume Template/doc

-- 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

function p.main(frame)
    local args = getArgs (frame)
    local pagename = args['category'] or mw.title.getCurrentTitle().text
    local previous_volume = args['PreviousVol'] 
    local next_volume = args['NextVol']
    local volume_type = args['Type'] or ''
    local volume_status = args['Status'] or ''
    local relaunches = {}
    local issue_list = args['IssueList'] or ''
    local publisher = p.lua_get_publisher(args['Publisher'])
    local name_info = standart.lua_get_title_volume_issue(pagename, 'Vol')
    local volume_type_category = ''
    local volume_status_category = ''
    local genres
    local genres_categories
    local list_of_canceled_issues
    local categories = {}
    local category = ''
    local dpl_string = ''
    local list = {}
    local first_by_date
    local last_by_date
    local next_issue
    local top_message = ''
    local total_issues = 0
    local number_of_canceled_issues = 0
    local display_title = pagename
    local images_category = pagename..'/Images'
    local output = {}

    -- create list of all issues from category with DPL
    dpl_string = frame:preprocess( p.lua_dpl_list(pagename, _, false)..p.lua_dpl_list(pagename, 500, false) )
    list_of_canceled_issues = mw.text.split( frame:preprocess('{{#dpl:|category = Canceled Comics|namespace = 0|mode = userformat|listseparators = ,%PAGE%,@@@}}'), '@@@' )
    list = p.lua_transform_dpl_string_into_list(dpl_string, args['exclude'], list_of_canceled_issues)
    
    -- add gallery of issues
    if h.isempty(issue_list)
        then issue_list = p.lua_create_issue_list(list, args)
    end
    
    -- add top message
    first_by_date, last_by_date, next_issue = p.lua_get_first_and_last_by_date(list)
    volume_type, volume_type_category = p.lua_get_volume_type(volume_type, #list, last_by_date, pagename)
    volume_status, volume_status_category = p.lua_get_volume_status(volume_status, first_by_date, last_by_date)
    relaunches = p.lua_get_relaunches(list, args['relaunches'])
    genres, genres_categories = p.lua_get_genres(args['genres'])
    number_of_canceled_issues = p.lua_get_number_of_canceled_issues(list)
    total_issues = p.lua_get_number_of_issues(#list, number_of_canceled_issues)
    previous_volume, next_volume = p.lua_get_previous_and_next_volume(name_info, previous_volume, next_volume)
    
    top_message = p.lua_top_message(pagename, first_by_date, last_by_date, next_issue, genres,
                                    volume_type, volume_status, total_issues, relaunches, publisher,
                                    previous_volume, next_volume, args)
    

    -- add categories
    if h.lua_isexists('Category:'..pagename) == false and h.lua_PagesInCategory(pagename, 'pages') > 0
        then table.insert(categories, 'Volume Category Needed')
    end
    if h.lua_isexists('Category:'..images_category) == false and h.lua_PagesInCategory(images_category, 'files') > 0
        then table.insert(categories, 'Volume Images Category Needed')
    end
    table.insert(categories, 'Comic Lists')
    table.insert(categories, p.lua_volume_by_title(name_info.sortname.title) )
    table.insert(categories, publisher)
    table.insert(categories, volume_type_category)
    table.insert(categories, volume_status_category)
    table.insert(categories, genres_categories)
    if relaunches ~= ''
        then table.insert(categories, 'Relaunched Series')
    end
    table.insert(categories, p.lua_volumes_by_number_of_issues(#list) )
    table.insert(categories, p.lua_volume_debut(first_by_date, volume_status))
    table.insert(categories, p.lua_volume_end(last_by_date, volume_status))
    categories = h.lua_concatTables( categories, p.lua_get_comic_series(pagename, featured) )
    categories = h.lua_create_list_of_categories(categories, name_info.sortname.noissue)

    -- add everything to page
    running_years = p.lua_get_running_years(first_by_date, last_by_date, volume_status)
    display_title = '{{DISPLAYTITLE:'..pagename..running_years..'}}'
    table.insert(output, display_title)
    table.insert(output, top_message)
    table.insert(output, issue_list)
    table.insert(output, design.lua_add_section(args['SeeAlso'], 'See Also') )
    table.insert(output, design.lua_add_section(args['Notes'], 'Notes') )
    table.insert(output, '<references/>')
    table.insert(output, categories)

    return frame:preprocess( table.concat(output) )
end


function p.lua_volume_by_title(pagename)
    local first_letter = ''
    local output = ''
    
    first_letter = string.sub(pagename,1,1)
    if string.match(first_letter, '%d') ~= nil
        then output = 'Comics 0-9'
        elseif string.match(first_letter, '%a') ~= nil
            then output = 'Comics '..first_letter
        else output = 'Comics &'
    end
    
    return output
end

function p.lua_volumes_by_number_of_issues(total_issues)
    local first
    local last
    local i
    local output = ''
    
    if total_issues == 1
        then return ''
        elseif total_issues >=2 and total_issues <= 9
            then output = 'Volumes with 2 to 9 issues'
        else
            for i = 1,99 do
                first = tonumber(i..0)
                last = tonumber(i..9)
                if total_issues >=first and total_issues <= last
                    then output = 'Volumes with '..first..' to '..last..' issues'
                end
            end
    end
    
    return output
end


function p.lua_get_number_of_canceled_issues(list)
    local output = 0
    
    for i = 1, #list do
        if list[i].canceled
            then output = output + 1
        end
    end
    
    return output
end


function p.lua_get_number_of_issues(total_issues, number_of_canceled_issues)
    local text
    local n
    local output
    
    if number_of_canceled_issues > 0
        then 
            if total_issues == number_of_canceled_issues
                then 
                    if total_issues > 1
                        then text = ' issues (all canceled)'
                        else text = ' issue (canceled)'
                    end
                    output = number_of_canceled_issues..text
                else 
                    n = total_issues - number_of_canceled_issues
                    if n > 1
                        then text = ' issues'
                    end
                    output = n..text..' (+'..number_of_canceled_issues..' canceled)'
            end
        else 
            if total_issues > 1
                then text = ' issues'
                else text = ' issue'
            end
            output = total_issues..text
    end
    
    return output
end


function p.lua_get_publisher(publisher)
    local output = 'Marvel Comics'
    
    if not h.isempty(publisher) 
        then output = h.lua_breaklink(publisher, 1)
    end
    
    return output
end


function p.lua_get_previous_and_next_volume(name_info, previous_volume, next_volume)
    local function link_to_volume(volume, previous)
        local arrow
        local output
        if volume ~= '' and previous == true
            then
                arrow = '[[File:Red Previous-icon.png|15px|link='..volume..']] '
                output = arrow..h.Link(volume, 'Previous Volume')
		elseif volume ~= ''
			then
                arrow = ' [[File:Red Next-icon.png|15px|link='..volume..']]'
                output = h.Link(volume, 'Next Volume')..arrow
        end
        return output
    end
    local function get_volume(volume, volume_n)
        local output = ''
        if not h.isempty(volume)
            then output = h.lua_breaklink(previous_volume, 1)
            elseif volume_n ~= '' and h.lua_isexists(volume_n)
                then output = volume_n
        end
        return output
    end
    local s1 = ''
    local s2 = ''
    local volume = tonumber(name_info.volume)
    
    if volume ~= nil
        then 
            s1 = name_info.title..' Vol '..tostring(volume-1)
            s2 = name_info.title..' Vol '..tostring(volume+1)
    end
    previous_volume = link_to_volume(get_volume(previous_volume, s1), true)
    next_volume = link_to_volume(get_volume(next_volume, s2), false)

    return previous_volume, next_volume
end


function p.lua_get_relaunches(list, relaunches)
    local i
    local j
    local n
    local s
    local output = {}
    
    if not h.isempty(relaunches)
        then
            relaunches = p.lua_divide_list(relaunches, false)
            
            for i = 1, #list do
                for j = 1, #relaunches do
                    if list[i].pagename == relaunches[j]
                        then table.insert(output, h.Link(list[i].pagename, list[i].year))
                    end
                end
            end
    end
    
    n = #output
    if n > 0
        then
            s = ' (with '..n
            if n == 1
                then s = s..' relaunch in '
                else s = s..' relaunches in '
            end
            --output = s..mw.text.listToText(output)..')'
            output = mw.text.listToText(output)
        else 
            output = ''
    end

    return output
end

function p.lua_get_genres(genres)
    local i
    local s
    local categories = {}
    local output = {}

    if not h.isempty(genres)
        then
            genres = p.lua_divide_list(genres, false)
            for i = 1, #genres do
                s = genres[i]..' Genre Volumes'
                table.insert(categories, s)
                s = h.lua_link_to_category(s, genres[i])
                table.insert(output, s)
            end
            output = mw.text.listToText(output, ',', ',')
        else
            s = 'Superhero Genre Volumes'
            table.insert(categories, s)
            s = h.lua_link_to_category(s, 'Superhero')
            output = s
    end
    
    return output, categories
end
    

function p.lua_get_logo(volume_logo, publisher)
    local output = 'Marvel Logo.png'
    
    if not h.isempty(volume_logo) 
        then output = volume_logo
        elseif publisher ~= 'Marvel Comics'
            then 
                if h.lua_isexists('File:'..publisher..'.png')
                    then output = publisher..'.png'
                    elseif h.lua_isexists('File:'..publisher..'.jpg')
                        then output = publisher..'.jpg'
                end
    end

    return '<td style="width: 20%; padding-right: 10px; text-align: center;">[[File:'..output..'|180px|center]]</td>'
end


function p.lua_top_message(pagename, first_by_date, last_by_date, next_issue, genres,
                            volume_type, volume_status, total_issues, relaunches, publisher,
                            previous_volume, next_volume, args)
    local function tag_td(text, width, font_size)
        return tostring(mw.html.create( 'td' )
                :css('width', width)
                :css('font-size', font_size)
                --:css('border', '1px solid black')
                :wikitext(text)
                :done() )
    end
    local function add_field(label, value)
        local output = nil
        if not h.isempty(value)
            then output = design.lua_span(label..': ').bold..value..'<br>'
        end
        return output
    end
    local volume_logo = p.lua_get_logo(args['VolumeLogo'], publisher)
    local featured = p.lua_divide_list(args['Featured'] or '', true)
    local message = ''
    local second_row = {}
    local first_link = first_by_date.link
    local last_link = last_by_date.link
    local one_shot = false
    local dates
    local rows = {}
    local s = nil
    local n
    local width = 80
    local output = {}
    
    
    if volume_type == 'One Shot'
        then one_shot = true
    end

    if volume_status == 'Finished'
        then
            if one_shot or first_link == last_link
                then dates = first_link
                elseif first_by_date.year ~= '' 
                       and first_by_date.year == last_by_date.year 
                       and first_by_date.month ~= ''
                    then dates = first_by_date.month..'—'..last_link
                    else dates = first_link..'—'..last_link
            end
        elseif volume_status == 'Active' or volume_status == 'Announced'
            then 
                if one_shot
                    then dates = first_link
                    else dates = first_link..'—onwards'
                end
                if volume_status == 'Announced'
                    then s = 'Announced Publication Date'
                end
        elseif volume_status == 'Canceled'
            then 
                dates = first_by_date.release_date
                if h.isempty(dates)
                    then dates = first_link
                end
                s = 'Intended Publication Date'
    end

    table.insert(rows, add_field('Publisher', h.Link(publisher) ) )
    table.insert(rows, add_field('Type', volume_type..' (Solo)') )
    table.insert(rows, add_field('Genre', genres) )
    table.insert(rows, add_field('Featuring', mw.text.listToText(featured)) )
    message = tag_td(table.concat(rows), 'auto', '85%')
    
    rows = {}
    table.insert(rows, add_field('Status', volume_status) )
    table.insert(rows, add_field(s or 'Publication Date', dates) )
    table.insert(rows, add_field('Relaunched in', relaunches) )
    
    if volume_status == 'Active' and next_issue ~= ''
        then
            s = standart.lua_standardized_link(next_issue.pagename, 'Comics')
            s = h.Link(next_issue.pagename, string.match(s, '(#.+)]]'))
            if next_issue.release_date ~= ''
                then s = s..' ('..next_issue.release_date..')'
                else s = s..' ('..next_issue.link..')'
            end
            table.insert(rows, add_field('Next Release', s) )
    end
    
    if last_by_date.release_date ~= '' and last_by_date.released == false
        then 
            s = standart.lua_standardized_link(last_by_date.pagename, 'Comics')
            s = h.Link(last_by_date.pagename, string.match(s, '(#.+)]]'))
            s = s..' ('..last_by_date.release_date..')'
            table.insert(rows, add_field('Latest Solicited Issue', s) )
    end
    message = message..tag_td(table.concat(rows), 'auto', '85%')

    --n = math.ceil(#rows/2)
    
    --s = ''
    --for i = 1, n do
    --    s = s..rows[i]
    --end
    --message = tag_td(table.concat(rows), 'auto', '85%')
    
    --s = ''
    --for i = n+1, #rows do
    --    s = s..rows[i]
    --end
    --message = message..tag_td(s, tostring(width/2)..'%', '85%')
    
    --if volume_logo ~= ''
    --    then width = 100
    --end
    width = 'width: auto'
    table.insert(output, '<table align="center" style="'..width..'; text-align:left;"><tr>'..volume_logo..message..'</tr>')
    table.insert(output, '</table>')
    table.insert(output, '<table align="center" style="width: 100%; text-align:center;">')
    
    table.insert(second_row, h.lua_link_to_category(pagename, total_issues))
    table.insert(second_row, p.lua_get_number_of_images(pagename))
    second_row = mw.text.listToText(second_row, '&nbsp;•&nbsp;', '&nbsp;•&nbsp;')
    previous_volume = tag_td(previous_volume, '20%', '100%')
    next_volume = tag_td(next_volume, '20%', '100%')
    table.insert(output, '<tr>'..previous_volume..'<td style="width:60%;">'..second_row..'</td>'..next_volume..'</tr>')
    table.insert(output, '</table>')

    return design.messagebox( { table.concat(output), padding = '10px' } )
end


function p.lua_get_number_of_images(pagename)
    local images_category = pagename..'/Images'
    local images_category_counter = h.lua_PagesInCategory(images_category, 'files')
    local output = ' images'
    
    if images_category_counter > 0
        then 
            if images_category_counter == 1
                then output = ' image'
            end
            output = h.lua_link_to_category(images_category, images_category_counter..output)
    end
    
    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 and first_by_date.released == false
            then
                output = 'Announced'
                category = 'Announced Series'
        elseif last < 999901 and 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_get_volume_type(volume_type, total_issues, last_by_date, pagename)
    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 < 999901 and last < current_date
            then 
                output = 'One Shot'
                category = 'One Shots'
        elseif total_issues <= 5 and last < 999901 and last < current_date
            then 
                output = 'Limited Series'
                category = output
        else output = 'Ongoing Series'
    end
    
    -- the following variants override any previous value
    -- check if Annual
    if string.find(pagename, 'Annual', 1, true) ~= nil
        then
            if output == 'One Shot'
                then output = 'Annual'
                else output = 'Annual Series' 
            end
            category = '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
            if output == 'One Shot'
                then output = 'Handbook'
                else output = 'Handbook Series' 
            end
            category = 'Handbooks'
    end
    
    -- check if TPB 
    if string.find(pagename, ' TPB ', 1, true) ~= nil or
       string.find(pagename, ' HC ', 1, true) ~= nil
        then 
            output = 'Trade Paperback Edition'
            category = 'Trade Paperbacks'
    end

    return output, category
end


function p.lua_divide_list(list, return_links)
    local link = ''
    local text = ''
    local s
    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
                        s = mw.text.trim(list[i])
                        if return_links
                            then
                                link = h.lua_breaklink(s, 1)
                                text = h.lua_breaklink(s, 2)
                                s = h.Link(link, text)
                        end
                        table.insert(output, s)
                    end
                elseif not h.lua_isLink(list) and h.lua_isexists(list)
                    then
                        list = mw.text.trim(list)
                        if return_links
                            then s = h.Link(list, list)
                            else s = list
                        end
                        table.insert(output, s)
                    else table.insert(output, mw.text.trim(list))
            end
    end
    
    return output
end


function p.lua_create_issue_list(list, args)
    local parts = {}
    local above = {}
    local below = {}
    local i
    local j
    local k
    local s = {}
    local output = {}
    
    for i = 1,9 do
        s = args['part'..i]
        if not h.isempty(s)
            then table.insert(parts, tonumber(standart.lua_padded_issue(s)))
        end
        table.insert(above, args['part'..i..'_above'] or '')
        table.insert(below, args['part'..i..'_below'] or '')
    end
    
    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 s
    local output = {}
    above = above or ''
    below = below or ''

    for i = 1,#list do
        s = p.lua_link_dates_storytitle(list[i])
        table.insert(output, '\n'..list[i].image..'{{!}}'..s)
    end
    output = table.concat(output)
    output = '{{#tag:gallery|'..output..'|position=center|captionalign=center|hideaddbutton=true}}'
    
    return above..output..below
end


function p.lua_transform_dpl_string_into_list(dpl_string, exclude, list_of_canceled_issues)
    local list = {}
    local issue_info = {}
    local image = ''
    local storytitle = ''
    local release_date = ''
    local pagename = ''
    local canceled = false
    local sort_date = ''
    local month
    local year
    local link
    local s = ''
    local output = {}
    
    if not h.isempty(dpl_string) and dpl_string ~= 'no_resultsno_results'
        then
            dpl_string = string.gsub(dpl_string, 'no_results', '')
            list = mw.text.split(dpl_string, '@@@', true)
            
            if not h.isempty(exclude)
                then exclude = mw.text.split(exclude, ";", true)
                else exclude = nil
            end
            
            for i = 1, #list do
                if not h.isempty(list[i])
                    then
                        s = mw.text.split(list[i], '~', true)
                        pagename = s[1]
                        if exclude ~= nil and exclude[pagename] ~= nil
                            then s = ''
                            else
                                canceled = h.inlist(list_of_canceled_issues, pagename)
                                issue_info = standart.lua_get_title_volume_issue(pagename)
                                year = s[2]
                                month = m_date.get_month_name({s[3]}) or ''
                                image = p.lua_cover(s[4], issue_info)
                                release_date = s[5] or ''
                                storytitle = s[6]
                                if h.isempty(year)
                                    then year = ''
                                end
                                _, _, link = m_date.lua_get_publication_category(year, month)
                                sort_date = p.lua_get_sort_date(year, month)
                                s ={['pagename'] = pagename, 
                                    ['image'] = image, 
                                    ['storytitle'] = storytitle, 
                                    ['year'] = year,
                                    ['month'] = month, 
                                    ['release_date'] = release_date,
                                    ['link'] = link,
                                    ['padded_issue'] = issue_info.padded_issue,
                                    ['canceled'] = canceled,
                                    ['sort_date'] = sort_date,
                                }
                                table.insert(output, s)
                        end
                end
            end
        table.sort(output, p.lua_sort_by_issue)
    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 release_date = template..':ReleaseDate, '
    local story_title = template..':StoryTitle1'
    local secseparators = '%PAGE%~,~,,~,,~,,~,,@@@'
    local output = {}

    table.insert(output, '{{#dpl:')
    table.insert(output, '|categorymatch = '..pagename)
    table.insert(output, '|namespace = 0')
    table.insert(output, '|include = '..year..month..image..release_date..story_title)
    table.insert(output, '|mode = userformat')
    table.insert(output, '|secseparators = '..secseparators)
    table.insert(output, '|noresultsheader = no_results')
    table.insert(output, '|allowcachedresults = true')
    if not h.isempty(offset)
        then table.insert(output, '|offset ='..offset)
    end
    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_get_sort_date(year, month)
    if h.isempty(year)
        then year = '9999'
    end
    month = m_date.get_month_number({month}) or '01'

    return tonumber(year..month)
end


function p.lua_get_first_and_last_by_date(list)
    local function get_release_date_info(release_date)
        local released = true
        local output = ''
        
        if not h.isempty(release_date)
            then 
                release_date = m_date.lua_date_converter2(release_date, 'F j, Y')
                released = m_date.lua_date_comparison(release_date)
                output = release_date
        end
        
        return output, released
    end
    local list_sorted_by_date = {}
    local first_by_date
    local last_by_date = ''
    local next_issue = ''
    local j
    local release_date
    local released
    local info
    
    if not h.isempty(list)
        then
            list_sorted_by_date = mw.clone(list)
            table.sort(list_sorted_by_date, p.lua_sort_by_date)
            first_by_date = list_sorted_by_date[1]
            info = m_date.lua_get_publication_date_info(first_by_date.year, first_by_date.month)
            first_by_date.published = info.published
            first_by_date.release_date, first_by_date.released = get_release_date_info(first_by_date.release_date)

            if #list_sorted_by_date == 1
                then last_by_date = first_by_date
                else
                    for i = #list_sorted_by_date,1,-1 do
                        if list_sorted_by_date[i].sort_date < 999901 and not list_sorted_by_date[i].canceled
                            then 
                                last_by_date = list_sorted_by_date[i]
                                j = i
                                break
                        end
                    end
                    
                    if last_by_date == ''
                        then last_by_date = first_by_date
                        else
                            info = m_date.lua_get_publication_date_info(last_by_date.year, last_by_date.month)
                            last_by_date.published = info.published
                            last_by_date.release_date, last_by_date.released = get_release_date_info(last_by_date.release_date)
                    end
                    
                    if not last_by_date.released and not last_by_date.published
                        then
                            for i = j, 1, -1 do
                                release_date = list_sorted_by_date[i].release_date
                                if not h.isempty(release_date)
                                    then
                                        release_date, released = get_release_date_info(release_date)
                                        if released == true
                                            then 
                                                next_issue = list_sorted_by_date[i+1]
                                                next_issue.release_date = release_date
                                                next_issue.released = released
                                        end
                                    else
                                        info = m_date.lua_get_publication_date_info(last_by_date.year, last_by_date.month)
                                        if info.published == true
                                            then 
                                                next_issue = list_sorted_by_date[i+1]
                                                next_issue.published = true
                                        end
                                end
                                
                                if next_issue ~= ''
                                    then break
                                end
                            end
                    end
            end
    end
    
    return first_by_date, last_by_date, next_issue
end


function p.lua_get_running_years(first_by_date, last_by_date, volume_status)
    local first_year = first_by_date.year
    local last_year = last_by_date.year
    local output = ''
    
    if first_year ~= '' and last_year ~= ''
        then
            if volume_status == 'Canceled'
                then output = volume_status
                elseif volume_status == 'Active'
                    then output = first_year..'–...'
                elseif first_year == last_year
                    then output = first_year
                else output = first_year..'–'..last_year
            end
            output = tostring( mw.html.create('span')
                :css('font-size', '80%')
                :css('font-style', 'italic')
                :css('font-family', 'monospace')
                :wikitext(' ('..output..')') 
            )
    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, issue_info)
    local cover = ''
    local textless = ''
    local output = ''

    if not h.isempty(image)
        then output = image
        else
            cover = issue_info.filename.all
            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', 'italic' )
                
    if not h.isempty(storytitle)
        then 
            storytitle = string.gsub(storytitle, '"', '')
            output = '<br />'..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 year ~= ''
                then
                    if month ~= ''
                        then month = 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 year ~= ''
                then
                    if month ~= ''
                        then month = month..' '
                    end
                    output = month..year..' Volume End'
            end
    end
    
    return output
end


function p.lua_link_dates_storytitle(issue_info)
    local publication_date = issue_info.link
    local release_date = issue_info.release_date
    local dates = ''
    local link = p.lua_link(issue_info.pagename)
    local storytitle = p.lua_storytitle(issue_info.storytitle)
    local s1
    local s2
    local output

    if not h.isempty(publication_date)
        then publication_date = '<br />'..design.lua_span('Cover date: ').bold..publication_date
        else publication_date = ''
    end
    if not h.isempty(release_date)
        then 
            s1 = m_date.lua_date_converter2(release_date, 'F j, Y')
            --s2 = 'Week '..m_date.lua_date_converter(s1, 'W')..', '..string.match(s1, '%d%d%d%d')
            --release_date = h.lua_link_to_category(s2, s1)
            release_date = '<br />'..design.lua_span('Release date: ').bold..s1
        else release_date = ''
    end

    if issue_info.canceled 
        then dates = '<br />Canceled'
        else dates = release_date..publication_date
    end

    output = storytitle..dates

    if output ~= ''
        then output = tostring(mw.html.create('span')
                        :css('font-size', '80%')
                        :css('font-family', 'monospace')
                        :wikitext(output)
                        :done()
                    )
    end

    output = '<center>'..tostring(mw.html.create('div')
                        :css('line-height', '90%')
                        :wikitext(link..output)
                        :done()
                    )..'</center>'

    return output
end


return p