Модуль : CiteWeb

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

Модуль обеспечивает работу шаблона {{ cite web }} .

Подробнее об использовании шаблона см. его документацию.

local
 p
 =
 {};


require
(
'strict'
);

local
 listRef
 =
 require
(
'Module:Languages'
).
list_ref
;

local
 boxDate
 =
 require
(
'Module:Calendar'
).
bxDate
;


local
 error_cats
 =
 {

    [
'noname_param'
]
 =
 'К:Википедия:Cite web (некорректное использование: непустой неименованный параметр)'
,

    [
'empty_title'
]
 =
 'К:Википедия:Cite web (некорректное использование: не указан title)'
,

    [
'empty_url'
]
 =
 'К:Википедия:Cite web (некорректное использование: не указан url)'
,

    [
'bad_archive'
]
 =
 'К:Википедия:Cite web (некорректное использование: параметры архивации)'
,

    [
'deadlink'
]
 =
 'К:Википедия:Cite web (недоступные ссылки без архивной копии)'
,

    -- ['bad_lang'] = 'К:Википедия:Cite web (неверный код языка)',

    -- ['deadlink_old'] = 'К:Википедия:Cite web (устаревшие параметры мёртвых ссылок)',

    [
'empty_lang'
]
 =
 'К:Википедия:Cite web (не указан язык)'
,

    [
'bad_url'
]
 =
 'К:Википедия:Cite web (некорректный url)'
,

    [
'webcitation_no'
]
 =
 'К:Википедия:Cite web (заменить webcitation-архив: deadlink no)'
,

    [
'webcitation_yes'
]
 =
 'К:Википедия:Cite web (заменить webcitation-архив: deadlink yes)'
,

}

local
 errors
 =
 {

    [
'noname_param'
]
 =
 '{{error|Все параметры шаблона {{tl|cite web}} должны [[T:cite web#Неименованные_параметры|иметь имя]].}}'
,

    [
'empty_title'
]
 =
 '{{error|Необходимо задать параметр {{code|title{{=}}}} в шаблоне {{tl|cite web}}.}}'
,

    [
'empty_url'
]
 =
 '{{error|Необходимо задать параметр {{code|url{{=}}}} в шаблоне {{tl|cite web}}.}}'
,

    [
'bad_archive'
]
 =
 '{{error|Если в шаблоне {{tl|cite web}} задаётся параметр {{code|archive-url{{=}}}}, должен задаваться и параметр {{code|archive-date{{=}}}}, и наоборот.}}'
,

}

local
 replace_params
 =
 {

    [
'accessdate'
]
 =
 'access-date'
,

    [
'archivedate'
]
 =
 'archive-date'
,

    [
'archiveurl'
]
 =
 'archive-url'
,

    [
'authorlink'
]
 =
 'author-link'
,

    [
'first1'
]
 =
 'first'
,

    [
'last1'
]
 =
 'last'
,

    [
'deadurl'
]
 =
 'deadlink'
,

    [
'dead-url'
]
 =
 'deadlink'
,

    [
'language'
]
 =
 'lang'
,

    [
'datepublished'
]
 =
 'date'
,

    [
'work'
]
 =
 'website'
,

}


-- проверка существования переменной. возврат её, или nil если пустая

local
 function
 is
(
var
)

    if
 (
var
 ==
 ''
 or
 var
 ==
 nil
)
 then
 return
 nil
 else
 return
 var
 end

end


-- замена устаревших аргументов на их аналоги

local
 function
 prepareArgs
(
args
)

    local
 bad_args
 =
 {};

    local
 new_args
 =
 {};

    for
 param
,
 value
 in
 pairs
(
args
)
 do

        if
 is
(
replace_params
[
param
])
 and
 not
 is
(
args
[
replace_params
[
param
]])
 then

            param
 =
 replace_params
[
param
];

        end

        new_args
[
param
]
 =
 value
;

    end

    return
 new_args
,
 bad_args

end


-- добавление скрытого языка

local
 function
 hiddenRef
(
code
)

    return
 '<span class="hidden-ref" style="display:none;">&nbsp;'
 ..
 code
 ..
 '</span>'

end


local
 function
 insertDot
(
str
,
 insert
)

    if
 insert
 ==
 false
 then

        return

    end

    table.insert
(
str
,
 '.'
)

end


local
 function
 needDot
(
source_str
)

    if
 mw
.
ustring
.
find
(
source_str
,
 '[.?!:…]≫?$'
)
 ~=
 nil
 then

        return
 false

    else

        return
 true

    end

end


local
 function
 nowiki
(
text
)

    local
 frame
 =
 mw
.
getCurrentFrame
();

    return
 frame
:
callParserFunction
(
'#tag'
,
 {
 'nowiki'
,
 text
 })

end


local
 function
 replace
(
source_str
,
 pattern
,
 replace
)

    return
 mw
.
ustring
.
gsub
(
source_str
,
 pattern
,
 replace
)

end


-- форматирование даты; в случае ошибки - возврат переданного значения без изменений

local
 function
 formatDate
(
strFormat
,
 txtDateIn
,
 params
)

    local
 txtDateOut
,
 date
,
 status
 =
 boxDate
(
txtDateIn
,
 strFormat
,
 params
)

    if
 status
.
brk
 then

        return
 txtDateIn

    else

        return
 txtDateOut

    end

end


-- отрисовка ошибки по коду

local
 function
 expandError
(
code
)

    return
 mw
.
getCurrentFrame
():
preprocess
(
errors
[
code
])
 ..
 ' '

end


-- отрисовка всех категорий по их кодам

local
 function
 expandCats
(
cats
)

    local
 str
 =
 {};

    local
 frame
 =
 mw
.
getCurrentFrame
();

    for
 _
,
 cat
 in
 pairs
(
cats
)
 do

        table.insert
(
str
,
 '[['
 ..
 error_cats
[
cat
]
 ..
 ']]'
)

    end

    return
 frame
:
preprocess
(
table.concat
(
str
))

end


-- разделение их

local
 function
 splitBySlash
(
string
)

    local
 args
 =
 {};

    local
 iterator
 =
 mw
.
ustring
.
gmatch
(
string
,
 "[^/]+"
);


    for
 w
 in
 iterator
 do

        table.insert
(
args
,
 w
)

    end

    return
 args

end


-- оборачиваем главную ссылку в span с указанным языком (может быть полезно для rtl)

local
 function
 wrapLang
(
link
,
 langs
)

    local
 lang_code
 =
 'und'
;


    if
 is
(
langs
)
 then

        local
 args
 =
 splitBySlash
(
langs
);

        if
 #
args
 ~=
 0
 then

            lang_code
 =
 args
[
1
];

        end

    end


    return
 '<span lang="'
 ..
 lang_code
 ..
 '">'
 ..
 link
 ..
 '</span>'

end


-- обёртка в тег цитирования

local
 function
 wrapCite
(
str
,
 args
)

    if
 is
(
args
[
'ref'
])
 then

        table.insert
(
str
,
 1
,
 '<span class="citation" id="CITEREF'
 ..
 mw
.
uri
.
anchorEncode
(
args
[
'ref'
])
 ..
 '">'
);

        if
 is
(
args
[
'date'
])
 then

            table.insert
(
str
,
 2
,

                '<span class="citation" id="CITEREF'
 ..

                mw
.
uri
.
anchorEncode
(
args
[
'ref'
]
 ..
 formatDate
(
'Y'
,
 args
[
'date'
]))
 ..
 '">'
);

            table.insert
(
str
,
 '</span>'
);

        end

    else

        table.insert
(
str
,
 1
,
 '<span class="citation">'
);

    end


    table.insert
(
str
,
 '</span>'
);

end


-- генерирум список языков (аргумент - список языков через слеш)

local
 function
 refLang
(
lang
)

    local
 args
 =
 splitBySlash
(
lang
);


    local
 frame
 =
 mw
.
getCurrentFrame
();

    frame
.
args
 =
 args


    local
 lang_result
 =
 listRef
(
frame
)

    local
 hidden
 =
 false
;


    if
 #
args
 ==
 1
 and
 args
[
1
]
 ==
 'ru'
 then

        hidden
 =
 true
;

    end


    return
 lang_result
,
 hidden

end


function
 p
.
render
(
frame
)

    local
 str
 =
 {}

    local
 cats
 =
 {}


    local
 pFrame
 =
 frame
:
getParent
();

    local
 args
 =
 mw
.
clone
(
pFrame
.
args
);

    setmetatable
(
args
,
 nil
);


    args
 =
 prepareArgs
(
args
);


    -- Проверки

    -- Проверка отсутствия неименованных параметров

    if
 is
(
args
[
1
])
 or
 is
(
args
[
2
])
 or
 is
(
args
[
3
])
 or
 is
(
args
[
4
])
 or
 is
(
args
[
5
])
 or
 is
(
args
[
6
])
 then

        table.insert
(
str
,
 expandError
(
'noname_param'
));

        table.insert
(
cats
,
 'noname_param'
);

    end


    -- Проверка корректности заполнения параметров archiveurl и archivedate

    if
 (
is
(
args
[
'archive-date'
])
 ~=
 nil
 and
 is
(
args
[
'archive-url'
])
 ==
 nil
)
 or

        (
is
(
args
[
'archive-date'
])
 ==
 nil
 and
 is
(
args
[
'archive-url'
])
 ~=
 nil
)
 then

        table.insert
(
str
,
 expandError
(
'bad_archive'
));

        table.insert
(
cats
,
 'bad_archive'
);

    end


    -- Проверка устаревших параметров мёртвых ссылок

    -- if is(args['dead-url']) or is(args['deadurl']) then

    --     table.insert(cats, error_cats['deadlink_old'])

    -- end


    local
 urlstatus
 =
 'live'
;

    if
 args
[
'url-status'
]
 ==
 'live'
 or
 args
[
'url-status'
]
 ==
 'dead'
 or
 args
[
'url-status'
]
 ==
 'unfit'
 then

        urlstatus
 =
 args
[
'url-status'
]

    elseif
 args
[
'deadlink'
]
 ==
 'yes'
 then

        urlstatus
 =
 'dead'

    elseif
 args
[
'deadlink'
]
 ==
 'unfit'
 then

        urlstatus
 =
 'unfit'

    end


    if
 is
(
args
[
'archive-url'
])
 then

        if
 mw
.
ustring
.
find
(
args
[
'archive-url'
],
 'webcitation.org'
,
 1
,
 true
)
 then

            if
 urlstatus
 ==
 'dead'
 or
 urlstatus
 ==
 'unfit'
 then

                table.insert
(
cats
,
 'webcitation_yes'
)

            else

                table.insert
(
cats
,
 'webcitation_no'
)

            end

        end

    elseif
 urlstatus
 ==
 'dead'
 then

        table.insert
(
cats
,
 'deadlink'
)

    end


    -- Проверка заполнения параметра url

    if
 is
(
args
[
'url'
])
 then

        if
 mw
.
ustring
.
find
(
args
[
'url'
],
 '^https?://'
,
 1
,
 false
)
 ~=
 1
 and

            mw
.
ustring
.
find
(
args
[
'url'
],
 '^ftp://'
,
 1
,
 false
)
 ~=
 1
 or
 mw
.
ustring
.
find
(
args
[
'url'
],
 ' '
,
 1
,
 true
)
 ~=
 nil
 then

            table.insert
(
cats
,
 'bad_url'
)

        end

    else

        table.insert
(
str
,
 expandError
(
'empty_url'
));

        table.insert
(
cats
,
 'empty_url'
)

    end


    -- Проверка заполнения параметра title

    if
 not
 is
(
args
[
'title'
])
 then

        table.insert
(
str
,
 expandError
(
'empty_title'
));

        table.insert
(
cats
,
 'empty_title'
)

    elseif
 not
 is
(
args
[
'lang'
])
 and
 mw
.
ustring
.
find
(
args
[
'title'
],
 '^[0-9А-яЁёXVILC≪≫?“:;,…!???→ 
\194\160\n\226\128\175
%(%)%.%"
\'
?№?%/%|%&%#+-]+$'
)
 ==
 nil
 then

        table.insert
(
cats
,
 'empty_lang'
)

    end


    -- Формирование вывода

    -- Автор

    if
 is
(
args
[
'author'
])
 or
 is
(
args
[
'last'
])
 then

        table.insert
(
str
,
 '<i>'
)


        local
 author
 =
 args
[
'author'
];

        if
 is
(
args
[
'last'
])
 then

            author
 =
 args
[
'last'
]

            if
 is
(
args
[
'first'
])
 then

                author
 =
 author
 ..
 ', '
 ..
 args
[
'first'
]

            end

        elseif
 not
 is
(
args
[
'last2'
])
 and
 not
 is
(
args
[
'coauthors'
])
 then

            author
 =
 replace
(
author
,
 '^(%[*)(.-[^%.%]])(%]*)$'
,
 '%1%2%3.'
)

        end


        if
 is
(
args
[
'author-link'
])
 then

            table.insert
(
str
,
 '[['
 ..
 args
[
'author-link'
]
 ..
 '|'
 ..
 author
 ..
 "]]"
)

        else

            table.insert
(
str
,
 author
)

        end


        -- Дополнительные сведения об авторах

        for
 i
 =
 2
,
 5
 do

            if
 is
(
args
[
'last'
 ..
 i
])
 then

                local
 author
 =
 nowiki
(
';'
)
 ..
 '&#32;'
 ..
 args
[
'last'
 ..
 i
];

                if
 is
(
args
[
'first'
 ..
 i
])
 then

                    author
 =
 author
 ..
 ', '
 ..
 args
[
'first'
 ..
 i
]

                end

                table.insert
(
str
,
 author
)

            end

        end


        if
 is
(
args
[
'coauthors'
])
 then

            table.insert
(
str
,
 nowiki
(
';'
)
 ..
 '&#32;'
 ..
 replace
(
args
[
'coauthors'
],
 '^(.-)%.?$'
,
 '%1.'
)
 ..
 ':&#32;'
)

        end


        table.insert
(
str
,
 '</i>&#32;'
)

    end


    -- Редактор

    if
 is
(
args
[
'editor'
])
 then

        table.insert
(
str
,
 ' '
 ..
 args
[
'editor'
]
 ..
 ':&#32;'
)

    end


    -- URL, заголовок

    local
 link
;

    local
 title
 =
 replace
(
replace
(
args
[
'title'
]
 or
 ''
,
 '%['
,
 '&#91;'
),
 '%]'
,
 '&#93;'
);

    local
 dot
 =
 needDot
(
title
);


    if
 (
urlstatus
 ==
 'dead'
 or
 urlstatus
 ==
 'unfit'
)
 and
 is
(
args
[
'archive-url'
])
 then

        link
 =
 '['
 ..
 (
args
[
'archive-url'
]
 or
 ''
)
 ..
 ' '
 ..
 title
 ..
 ']'

    elseif
 urlstatus
 ==
 'unfit'
 then

        link
 =
 title

    else

        link
 =
 '['
 ..
 (
args
[
'url'
]
 or
 ''
)
 ..
 ' '
 ..
 title
 ..
 ']'

    end

    table.insert
(
str
,
 wrapLang
(
link
,
 args
[
'lang'
]))


    -- Подзаголовок

    if
 is
(
args
[
'subtitle'
])
 then

        insertDot
(
str
,
 dot
)

        table.insert
(
str
,
 '&#32;'
 ..
 args
[
'subtitle'
])

        dot
 =
 needDot
(
args
[
'subtitle'
]);

    end


    -- Отображение названия языка источника

    local
 langs
;

    local
 hidden
 =
 false
;

    if
 is
(
args
[
'lang'
])
 then

        langs
,
 hidden
 =
 refLang
(
args
[
'lang'
]);

    else

        langs
 =
 frame
:
expandTemplate
 {
 title
 =
 'ref-und'
 };

        hidden
 =
 true
;

    end

    if
 hidden
 ==
 true
 then

        langs
 =
 hiddenRef
(
langs
);

    else

        dot
 =
 true
;

    end

    table.insert
(
str
,
 langs
)


    -- Формат источника

    if
 is
(
args
[
'format'
])
 then

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;('
 ..
 args
[
'format'
]
 ..
 ')'
)

    end


    -- Пометка о недоступности

    if
 (
urlstatus
 ==
 'dead'
 or
 urlstatus
 ==
 'unfit'
)
 and
 not
 is
(
args
[
'archive-url'
])
 then

        dot
 =
 true
;

        table.insert
(
str
,

            frame
:
expandTemplate
 {
 title
 =
 'ref-info'
,

                args
 =
 {
 'недоступная ссылка&nbsp;? [//web.archive.org/web/*/'
 ..

                args
[
'url'
]
 ..
 ' <i>история</i>]'
 }
 })

    end


    -- Название сайта или проекта

    if
 is
(
args
[
'website'
])
 then

        insertDot
(
str
,
 dot
)

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;<i>'
 ..
 args
[
'website'
]
 ..
 '</i>'
)

    end


    -- Страницы

    if
 is
(
args
[
'pages'
])
 then

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;'
 ..
 args
[
'pages'
])

    end


    -- Страница

    if
 is
(
args
[
'page'
])
 then

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;'
 ..
 args
[
'page'
])

    end


    -- Место, издательство

    if
 is
(
args
[
'publisher'
])
 then

        insertDot
(
str
,
 dot
)

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;'
);

        if
 is
(
args
[
'location'
])
 then

            table.insert
(
str
,
 args
[
'location'
]
 ..
 ':&#32;'
)

        end

        table.insert
(
str
,
 args
[
'publisher'
])

    end


    -- Дата

    if
 is
(
args
[
'date'
])
 then

        dot
 =
 true
;

        table.insert
(
str
,
 '&#32;('
 ..
 formatDate
(
'j xg Y'
,
 args
[
'date'
])
 ..
 ')'
)

    elseif
 is
(
args
[
'year'
])
 then

        dot
 =
 true
;

        if
 is
(
args
[
'month'
])
 then

            table.insert
(
str
,
 '&#32;('
 ..
 args
[
'month'
]
 ..
 ' '
 ..
 args
[
'year'
]
 ..
 ')'
)

        else

            table.insert
(
str
,
 '&#32;('
 ..
 args
[
'year'
]
 ..
 ')'
)

        end

    end


    -- Точка

    insertDot
(
str
,
 dot
)


    -- DOI

    if
 is
(
args
[
'doi'
])
 then

        table.insert
(
str
,

            '&#32;[[Идентификатор цифрового объекта|doi]]:[http://dx.doi.org/'
 ..

            args
[
'doi'
]
 ..
 ' '
 ..
 args
[
'doi'
]
 ..
 '].'
)

    end


    -- Описание

    if
 is
(
args
[
'description'
])
 then

        table.insert
(
str
,
 '&nbsp;? '
 ..
 args
[
'description'
])

        insertDot
(
str
,
 needDot
(
args
[
'description'
]))

    end


    -- Цитата

    if
 is
(
args
[
'quote'
])
 then

        table.insert
(
str
,
 '&nbsp;? ≪'
 ..
 args
[
'quote'
]
 ..
 '≫'
)

        insertDot
(
str
,
 needDot
(
args
[
'quote'
]))

    end


    -- Дата обращения

    if
 is
(
args
[
'access-date'
])
 then

        table.insert
(
str
,
 '&#32;Дата обращения: '
 ..

            formatDate
(
'j xg Y'
,
 args
[
'access-date'
])
 ..
 '.'
)

    end


    -- Дата архивирования

    if
 is
(
args
[
'archive-date'
])
 and
 is
(
args
[
'archive-url'
])
 then

        if
 urlstatus
 ==
 'live'
 then

            table.insert
(
str
,

                '&#32;['
 ..

                args
[
'archive-url'
]
 ..

                ' Архивировано] '
 ..

                formatDate
(
'j xg Y'
,
 args
[
'archive-date'
])
 ..
 ' года.'
)

        elseif
 urlstatus
 ==
 'unfit'
 then

            table.insert
(
str
,

                '&#32;Архивировано '
 ..

                formatDate
(
'j xg Y'
,
 args
[
'archive-date'
])
 ..
 ' года.'
)

        else

            table.insert
(
str
,

                '&#32;Архивировано из ['
 ..

                args
[
'url'
]
 ..

                ' оригинала] '
 ..

                formatDate
(
'j xg Y'
,
 args
[
'archive-date'
])
 ..
 ' года.'
)

        end

    end


    wrapCite
(
str
,
 args
);


    if
 #
cats
 ~=
 0
 and
 mw
.
title
.
getCurrentTitle
():
inNamespace
(
0
)
 then

        table.insert
(
str
,
 expandCats
(
cats
));

    end


    return
 table.concat
(
str
)

end


return
 p
;