Модуль:Progression

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

Модуль для отрисовки различных прогрессбаров.

Отрисовывает прогрессбар с заданным прогрессом. Реализовывает шаблон {{Progression}}.

Прогресс может быть задан тремя способами:

  • Одним параметром — процентом выполнения:
    {{#invoke:Progression|basic|25}} (выполнено на 25 %)
  • Двумя параметрами — текущим и желаемым значением:
    {{#invoke:Progression|basic|100|400}} (выполнено 100 из 400 — то есть 25 %)
  • Тремя параметрами — текущим, желаемым и стартовым значением:
    {{#invoke:Progression|basic|200|500|100}} (значение со 100 поднято до 200 при цели в 500 — то есть выполнено 25 % работы)
    {{#invoke:Progression|basic|300|0|400}} (значение с 400 опущено до 300 при цели в 0 — то есть выполнено 25 % работы)

Другие параметры

задача или task Описание работы, отобразится в заголовке прогрессбара.
ширина или width Ширина прогрессбара (по умолчанию — половина ширины экрана).
обновлять или refresh Если задано, прогрессбар будет автоматически обновляться раз в сутки через механизм {{очищать кэш}}.

Прогрессбар наполнения или очистки категории. Реализует шаблон {{Шкала наполнения категории}}.

Первый параметр — название категории (если модуль включён на страницу отслеживаемой категории, его можно опустить). Опциональный параметр тип/type указывает тип включаемых в категорию страниц (см. справку ключевого слова PAGESINCATEGORY), по умолчанию — pages. Остальные параметры аналогичны функции basic, второй параметр (целевое значение) обязателен.

Прогрессбар наполнения или очистки страницы (по размеру страницы).

Первый параметр — название страницы (если модуль включён на отслеживаемую страницу, его можно опустить). Остальные параметры аналогичны функции basic, второй параметр (целевое значение) обязателен.

Прогрессбар наполнения или очистки страницы (по количеству вхождений указанной подстроки).

Первый параметр — название страницы (если модуль включён на отслеживаемую страницу, его можно опустить). В параметре паттерн/pattern указывается искомый паттерн; по-умолчанию модуль будет считать элементы списка (\n#[^#*:][^\n]+); справку по используемым в LUA паттернам можно почитать на этой странице. Остальные параметры аналогичны функции basic, второй параметр (целевое значение) обязателен.

local getArgs = require( 'Module:Arguments' ).getArgs
local lang = mw.getLanguage( 'ru' )

local p = {}

local function error( message )
    local tag = mw.html.create( 'strong' )
        :addClass( 'error' )
        :wikitext( 'Шкала выполнения не показана: ' .. message )

    return tostring( tag )
end

local function render( progress, task, width )
    progress = math.floor( progress * 10 + 0.5 ) / 10
    result = '{| role="presentation" style="width:' .. ( width or '50%' ) .. '; margin: 0 auto; background: transparent; color: inherit"\n'
    result = result .. '|style="text-align:center;"| '
    if task ~= nil then
        result = result .. task .. ': '
    end
    result = result .. '<span style="font-size: 120%;"><b>' .. lang:formatNum( progress ) .. '&nbsp;%</b></span> завершено\n'
    result = result .. '|-\n|\n'

    if progress < 1 then
        progress = 1
    elseif progress > 100 then
        progress = 100
    end

    result = result .. '{| role="presentation" style="border:1px solid var(--border-color-interactive, #72777d); height:10px; width:100%; border-spacing: 1px;"\n'
    if progress ~= 0 then
        result = result .. '|style="background: var(--color-success, #14866d); width: ' .. progress .. '%"|\n'
    end
    if progress ~= 100 then
        result = result .. '|style="background: var(--background-color-neutral, #eaecf0);" |\n'
    end
    result = result .. '|}\n'

    result = result .. '|}'

    return result
end

local function calculate_progress( starting, goal, current )
    local result = 100 * (current - starting) / (goal - starting)
    if result < 0 then
        result = 0
    end
    return math.floor( result * 10 + 0.5 ) / 10
end

local function parse_and_render( args )
    if args[1] == nil then
        return error( 'текущий прогресс не задан' )
    end
    if args[2] == nil then
        return error( 'целевое значение не задано' )
    end

    local current = tonumber( args[1] )
    local goal = tonumber( args[2] )
    local starting = tonumber( args[3] or 0 )

    if starting == goal then
        return error( 'стартовое и целевое значения совпадают' )
    end

    local width = args['ширина'] or args['width']
    local task = args['задача'] or args['task']

    local result = render( calculate_progress( starting, goal, current ), task, width )
    if args['обновлять'] or args['refresh'] then
        result = result .. frame:expandTemplate{ title = 'очищать кэш' }
    end
    return result
end

function p.basic( frame )
    local args = getArgs( frame )
    args[2] = args[2] or 100 -- целевое значение по-умолчанию 100
    return parse_and_render( args )
end

function p.category( frame )
    local args = getArgs( frame )

    local type = args['тип'] or args['type'] or 'pages'
    local category = args[1]
    local current_page = mw.title.getCurrentTitle()
    local category_is_current_page = false

    if category == nil then
        if current_page.namespace == 14 then
            category = current_page.text
            category_is_current_page = true
        else
            return error( 'категория не задана' )
        end
    else
        local category_page = mw.title.new( 'Категория:' .. category, 14 )
        if not category_page.exists then
            return error( 'категория не существует' )
        end
        category_is_current_page = mw.title.equals( category_page, current_page )
    end

    local current = mw.site.stats.pagesInCategory( category, type )

    args[1] = current

    if not (args['задача'] or args['task']) then
        local task
        local goal = tonumber( args[2] )
        local starting = tonumber( args[3] or 0 )

        if goal == 0 then
            task = 'Очистить '
            if category_is_current_page then
                task = task .. 'эту категорию'
            else
                task = task .. 'категорию «[[:Категория: ' .. category .. '|' .. category .. ']]»'
            end
            task = task .. ' (было ' .. lang:formatNum( starting ) .. ')'
        else
            task = lang:formatNum( goal ) .. '&nbsp;' .. lang:convertPlural( goal, 'страница', 'страницы', 'страниц' ) .. ' в '
            if category_is_current_page then
                task = task .. 'этой категории'
            else
                task = task .. 'категории «[[:Категория: ' .. category .. '|' .. category .. ']]»'
            end
            if starting ~= 0 then
                task = task .. ' (было ' .. lang:formatNum( starting ) .. ')'
            end
        end

        args['задача'] = task
    end

    return parse_and_render( args )
end

function p.pagesize( frame )
    local args = getArgs( frame )

    local pagename = args[1]
    local pageobj

    if pagename == nil then
        pageobj = mw.title.getCurrentTitle()
    else
        pageobj = mw.title.new( pagename )
        if not pageobj.exists then
            return error( 'страница не существует' )
        end
    end

    args[1] = string.len( pageobj:getContent() )

    return parse_and_render( args )
end

function p.count( frame )
    local args = getArgs( frame )

    local pagename = args[1]
    local pageobj

    if pagename == nil then
        pageobj = mw.title.getCurrentTitle()
    else
        pageobj = mw.title.new( pagename )
        if not pageobj.exists then
            return error( 'страница не существует' )
        end
    end
    local pagetext = pageobj:getContent()

    local pattern = args['паттерн'] or args['pattern'] or '\n#[^#*:][^\n]+'

    pagetext, args[1] = mw.ustring.gsub(pagetext, pattern, "")

    return parse_and_render( args )
end

return p