Interested Article - CiteGost
- 2021-05-15
- 1
Модуль предназначен для автоматизированного оформления библиографических записей согласно руководствам русскоязычной Википедии ( ВП:БИБГРАФ ). В статьях модуль используется посредством шаблона-обёртки {{ Источник информации }} .
Общий формат
authors . title : subtitle [ contentType ] = origin : в volumesCount т. : workType : info : Пер. с англ. / Ил.: illustrators ; пер.: translators ; гл. ред.: editorInChief ; ред.: editors // publishedIn : publishedInSubtitle = publishedInOrigin : Пер. с англ. / Гл. ред.: publishedInEditorInChief ; ред.: publishedInEditors . — edition . — location : publisher , 2000, 25 января . — Т. volume , вып. issue : issueTitle . — Статья articleId . — pages или pagesCount с. — ( series ). — ( comment ). — Дата обновления: 27 марта 4000. — Дата обращения: 26 февраля 3000. — ISSN . — ISBN isbn . — doi : . — PMID . — PMC . — S2SIC .
Примерный формат библиографической записи в общем виде
:-
область заглавия и сведений об ответственности;
- основное заглавие документа;
- общее обозначение материала;
- сведения, относящиеся к заглавию;
- сведения об ответственности (авторы, переводчики, редакторы);
-
область издания, отделяемая двумя косыми чертами:
- сведения об издании (например, журнал, в котором опубликована статья, или издание книги);
- сведения об ответственности, относящиеся к изданию
-
область выходных данных:
- выходные данные (место издания, издатель, дата издания);
-
область физической характеричстики:
- специфическое обозначение материала (например, компакт-диск) и количество физических единиц (количество страниц) или местоположение информации в документе (том, выпуск, страницы);
-
область серии, заключаемая в круглые скобки:
- заглавие серии и сведения, относящиеся к заглавию;
- сведения об ответственности, относящиеся к серии;
- идентификаторы, относящиеся к серии;
- примечания;
- идентификаторы документа.
Параметры
Основными полями шаблона для заполнения являются идентификаторы элементов Викиданных и идентификатор работы в рамках издания, по которым будет загружена информация об источниках. Остальные поля заполняются, если автоматически получить информацию для данных полей невозможно.
Параметр | Описание | Тип | Статус | |
---|---|---|---|---|
Q-идентификатор работы |
entity
|
Q-идентификатор элемента Викиданных, обозначающий работу, из него автоматически будут загружены данные о работе |
Строковый (без форматирования) | предложенный |
Q-идентификатор издания |
publishedInEntity
|
Q-идентификатор элемента Викиданных, обозначающего издание, из него автоматически будут загружены данные об издании |
Строковый (без форматирования) | предложенный |
Q-идентификатор темы |
topicEntity
|
Q-идентификатор элемента Викиданных, обозначающего тему, идентифицирующую работу в издании (необходим для получения информации о работе и формирования ссылки на неё) |
Строковый (без форматирования) | предложенный |
Идентификатор работы |
id
|
Идентификатор работы в рамках издания, который уникальным образом идентифицирует работу в издании (необходим для формирования ссылки на работу) |
Строковый (без форматирования) | предложенный |
Заглавие |
title
|
Название статьи, книги или документа |
Строковый (без форматирования) | необязательный |
Подзаголовок |
subtitle
|
Подзаголовок, обычно выводимый под заглавием; альтернативные заголовок |
Строковый (без форматирования) | необязательный |
Название оригинала |
origin
|
Параллельный заголовок, в котором отражено название оригинала (в случае перевода) |
Строковый (без форматирования) | необязательный |
Ссылка на оригинал |
originUrl
|
Ссылка (URL) на оригинал работы |
Строковый (без форматирования) | необязательный |
Код языка оригинала |
originLang
|
Двузначный код языка оригинала |
Строковый (без форматирования) | необязательный |
Тип содержимого |
contentType
|
Тип содержимого согласно п. 5.2.3.2 ГОСТ 7.1—2003
|
Строковый (без форматирования) | необязательный |
Тип работы |
workType
|
К какому типу относится работа, например, учебное пособие, словарь, энциклопедия и т. д. |
Строковый (без форматирования) | необязательный |
Дополнительная информация |
info
|
Дополнительная информация, относящаяся к заглавию |
Строковый (без форматирования) | необязательный |
Количество томов |
volumesCount
|
Количество томов многотомного издания |
Число | необязательный |
Авторы |
authors
|
Список авторов, разделённых запятой |
Строковый (без форматирования) | необязательный |
Иллюстраторы |
illustrators
|
Список иллюстраторов, разделённых запятой |
Строковый (без форматирования) | необязательный |
Главный редактор |
editorInChief
|
Главный редактор, координирующий других редакторов |
Строковый (без форматирования) | необязательный |
Редакторы |
editors
|
Список редакторов, разделённых запятой |
Строковый (без форматирования) | необязательный |
Переводчики |
translators
|
Список переводчиков, разделённых запятой |
Строковый (без форматирования) | необязательный |
Код языка работы |
lang
|
Двузначный код языка, на котором выполнена работа |
Строковый (без форматирования) | необязательный |
Заглавие издания |
publishedIn
|
Название книги, журнала, сайта |
Строковый (без форматирования) | необязательный |
Подзаголовок издания |
publishedInSubtitle
|
Подзаголовок издания, обычно выводимый под заглавием; альтернативные заголовок |
Строковый (без форматирования) | необязательный |
Название оригинала издания |
publishedInOrigin
|
Параллельный заголовок, в котором отражено название оригинала издания (в случае перевода) |
Строковый (без форматирования) | необязательный |
Код языка оригинала издания |
publishedInOriginLang
|
Двузначный код языка оригинала издания |
Строковый (без форматирования) | необязательный |
Авторы издания |
publishedInAuthors
|
Список авторов издания, разделённых запятой |
Строковый (без форматирования) | необязательный |
Иллюстраторы издания |
publishedInIllustrators
|
Список иллюстраторов издания, разделённых запятой |
Строковый (без форматирования) | необязательный |
Главный редактор издания |
publishedInEditorInChief
|
Главный редактор издания, координирующий других редакторов |
Строковый (без форматирования) | необязательный |
Редакторы издания |
publishedInEditors
|
Список редакторов издания, разделённых запятой |
Строковый (без форматирования) | необязательный |
Переводчики издания |
publishedInTranslators
|
Список переводчиков издания, разделённых запятой |
Строковый (без форматирования) | необязательный |
Код языка издания |
publishedInLang
|
Двузначный код языка издания |
Строковый (без форматирования) | необязательный |
Место публикации |
location
|
Место, где работа или издание были опубликованы (город) |
Строковый (без форматирования) | необязательный |
Издатель |
publisher
|
Название издателя, опубликовавшего работу или издание |
Строковый (без форматирования) | необязательный |
Дата публикации |
date
|
Дата, когда работа или издание были опубликованы |
Дата | необязательный |
Том |
volume
|
Том, в котором работа опубликована |
Строковый (без форматирования) | необязательный |
Заглавие тома |
volumeTitle
|
Заглавие отдельного тома издания многотомной работы |
Строковый (без форматирования) | необязательный |
Выпуск |
issue
|
Выпуск, в котором работа опубликована |
Число | необязательный |
Заглавие выпуск |
issueTitle
|
Заглавие выпуска, в котором работа опубликована или на который формируется библиографическая запись |
Строковый (без форматирования) | необязательный |
Идентификатор статьи |
articleId
|
Идентификатор (номер) статьи, которым иногда обозначают электронные ресурсы |
Строковый (без форматирования) | необязательный |
Страницы работы |
pages
|
Страницы работы изи издания, к которым делается отсылка |
Строковый (без форматирования) | необязательный |
Количество страниц |
pagesCount
|
Количество страниц работы (в случае книги) |
Строковый (без форматирования) | необязательный |
Комментарий |
comment
|
Комментарий к работе, отображаемый в конце библиографической записи в круглых скобках |
Строковый (без форматирования) | необязательный |
Дата последнего обновления |
lastUpdate
|
Дата, когда работа последний раз была обновлена или пересмотрена (в случае периодически изменяемых интернет-страниц) |
Строковый (без форматирования) | необязательный |
Дата обращения |
accessDate
|
Дата, когда к интернет-ресурсу был осуществлён доступ для использования в качестве источника или формирования библиографической записи |
Строковый (без форматирования) | необязательный |
ISSN |
issn
|
Международные стандартные сериальные номера, перечисленные через запятую и идентифицирующий издание (журнал) |
Строковый (без форматирования) | необязательный |
ISBN |
isbn
|
Международные стандартные книжные номера, перечисленные через запятую и позволяющие найти книгу по библиотечным каталогам |
Строковый (без форматирования) | необязательный |
Идентификатор PubMed |
pmid
|
Уникальный идентификатор научной работы в базе данных PubMed |
Строковый (без форматирования) | необязательный |
Идентификатор PubMed Central |
pmc
|
Уникальный идентификатор научной работы в базе данных PubMed Central |
Строковый (без форматирования) | необязательный |
Идентификатор OCLC |
oclc
|
Уникальный идентификатор работы в каталоге Online Computer Library Center (WorldCat). Отображается, если отсутствуют ISBN и PMID |
Строковый (без форматирования) | необязательный |
Использование
Данный модуль не предназначен для использования в статьях напрямую. Использовать в статьях можно только обёртки над данным модулем.
Более подробная документация по особенностям модуля доступна в русскоязычной обёртке над ним — шаблоне {{ Источник информации }} .
Тесты
✅ Тесты пройдены.
Примеры
Статьи в научных журналах
Источник | Комментарий |
---|---|
Casotti G. : [ англ. ] : [ 17 марта 2022] / G. Casotti, K. K. Lindberg, E. J. Braun // American journal of physiology. Regulatory, integrative and comparative physiology . — 2000, 1 November . — Vol. 279, iss. 5. — P. R1722—30. — ISSN , . — doi : . — PMID . — WD . | Статья в научном журнале, автоматическое получение полей полей |
Giovanni Casotti . : [ англ. ] : [ 17 марта 2022] / Giovanni Casotti, Kimberly K. Lindberg, Eldon J. Braun // American Journal of Physiology-Regulatory, Integrative and Comparative Physiology. — 2000, 1 November . — Vol. 279, iss. 5. — P. R1722–R1730. — ISSN . — doi : . — PMID . | Статья в научном журнале, ручное заполнение полей |
Casotti G. : [ англ. ] : [ 17 марта 2022] / G. Casotti, K. K. Lindberg, E. J. Braun // American journal of physiology. Regulatory, integrative and comparative physiology . — 2000, 1 November . — Vol. 279, iss. 5. — P. R1722—30. — ISSN , . — doi : . — PMID . — WD . | Статья в научном журнале, автоматическое получение полей полей, русифицированное отображение |
Abdalla M. A. : [ англ. ] : [ 26 июля 2022] // Heliyon . — 2020, 2 January . — Vol. 6, iss. 1. — Article e03139. — ISSN . — doi : . — PMID . — WD . | Статья в научном журнале, у которой указан PMC, автоматическое получение полей |
: [ англ. ] : [ 3 марта 2022] / B. S. de Bakker, M. J. B. van den Hoff, P. D. Vize, R. J. Oostra // Integrative and Comparative Biology . — 2019, 1 July . — Vol. 59, iss. 1. — P. 29—47. — ISSN , . — doi : . — PMID . — WD . | Статья в научном журнале с 4 авторами, автоматическое получение полей |
: [ англ. ] / Z. Munn , M. Peters , C. Stern [et al.] // BMC Medical Research Methodology . — 2018, 19 November . — Vol. 18, iss. 1. — P. 143. — ISSN . — doi : . — PMID . — WD . | Статья в научном журнале с 5 авторами, часть из которых известна в Викиданных, автоматическое получение полей |
: [ англ. ] / Anna Herforth, Mary Arimond, Cristina Álvarez-Sánchez [et al.] // Advances in nutrition . — 2019, 1 July . — Vol. 10, iss. 4. — P. 590—605. — ISSN , . — doi : . — PMID . — WD . | Статья в научном журнале с 5 авторами, часть из которых известна в Викиданных, автоматическое получение полей |
Книги и их разделы
Источник | Комментарий |
---|---|
Kriz W. : [ англ. ] / W. Kriz, B. Kaissling // : Physiology and pathophysiology : in 2 vols. / Ed.: R. J. Alpern [et al.] . — Fifth edition. — Amsterdam : Academic Press , 2012, 31 December . — Vol. 1. — P. 595—691. — ISBN 978-0-12-381463-0 , 978-0-12-381462-3 . — WD . | Раздел книги, автоматическое заполнение части полей |
Wilhelm Kriz. : [ англ. ] / Wilhelm Kriz., Brigitte Kaissling // : in 2 vols. / Ed.: Robert J. Alpern [et al.] . — Fifth Edition. — Amsterdam : Academic Press, 2012. — Vol. 1. — P. 595—691. — ISBN 978-0-12-381463-0 . | Раздел книги, заполнение полей вручную |
Саган К. Мир, полный демонов : Наука — как свеча во тьме = The Demon-Haunted World : Science as a Candle in the Dark : Пер. с англ. / Пер.: Л. Сумм ; ред.: Артур Кляницкий. — 5-е изд. — М. : Альпина нон-фикшн , 2019. — 538 с. — ISBN 978-5-91671-874-4 . — WD . | Книга с явным указанием языка и года издания, автоматическое получение полей |
Саган К. Мир, полный демонов : Наука — как свеча во тьме = The Demon-Haunted World : Science as a Candle in the Dark : Пер. с англ. / Пер.: Л. Сумм ; ред.: Артур Кляницкий. — 5-е изд. — М. : Альпина нон-фикшн , 2019. — С. 1—100. — ISBN 978-5-91671-874-4 . — WD . | Книга с заданием конкретных страниц, автоматическое получение полей |
Саган К. Глава 1. Самое драгоценное // Мир, полный демонов : Наука — как свеча во тьме = The Demon-Haunted World : Пер. с англ. / К. Саган; Ред.: Артур Кляницкий. — 5-е изд. — М. : Альпина нон-фикшн , 2019. — С. 15—40. — ISBN 978-5-91671-874-4 . — WD . | Глава книги, автоматическое получение полей |
Sagan C. The Demon-Haunted World : Science as a Candle in the Dark : [ англ. ]. — NYC , 1997, 25 February . — 457 p. — ISBN 978-0-345-40946-1 . — WD . | Книга на английском, автоматическое получение полей |
Агеенко Ф. Л. : [словарь]. — М. : Мир и Образование , 2010. — 880 с. — ISBN 978-5-94666-588-9 . — WD . | Книга, у которой в Викиданных указана ссылка, автоматическое получение полей |
Веракса Н. Е. : учебное пособие / Н. Е. Веракса, А. Н. Веракса . — М. : МОЗАИКА-СИНТЕЗ, 2012. — 336 с. — ISBN 978-5-4315-0097-8 . — WD . | Книга, у которой в Викиданных указана ссылка, автоматическое получение полей |
. Т. «Животные». — 2-ое издание. — М. : ФГБУ «ВНИИ Экология», 2021. — 1128 с. — (Красная книга Российской Федерации). — ISBN 978-5-6047425-0-1 . — WD . | Книга, у которой том имеет название, автоматическое получение полей |
Документы
Источник | Комментарий |
---|---|
. — 2008, 28 апреля . — (Система стандартов по информации, библиотечному и издательскому делу). — WD . | ГОСТ, автоматическое получение полей |
Статьи через идентификаторы в рамках издания
Источник | Комментарий |
---|---|
The Editors of Encyclopaedia Britannica . : [ англ. ] : [ 2 июня 2022] // Encyclopædia Britannica : online encyclopedia. — Дата обновления: 22 августа 2022. — Дата обращения: 23 октября 2022. | Автоматическое заполнение полей по идентификаторам из викиданных |
: [ англ. ] : [ 9 апреля 2022] // Planetary Image Archive . — JPL , 2022, 5 April . — Дата обращения: 23 октября 2022. | Автоматическое заполнение полей по идентификаторам из викиданных |
: [ 4 октября 2022] // . — Большая российская энциклопедия , 2016, 1 апреля . | Статья без автора, автоматическое заполнение полей по идентификаторам из викиданных |
Нефрон // . — Большая российская энциклопедия , 2016, 1 апреля . — WD . | Статья, у которой значится автор, автоматическое заполнение полей по идентификаторам из викиданных |
Нефрон // Большая российская энциклопедия : в 35 т. / Гл. ред.: Ю. С. Осипов. — М. : Большая российская энциклопедия . — WD . | Статья из печатной БРЭ, у которой значится автор, автоматическое заполнение полей по идентификаторам из викиданных |
Котляков В. М. : [ 2 ноября 2022] / В. М. Котляков, А. И. Данилов, Н. А. Божко // . — Большая российская энциклопедия , 2016, 1 апреля . | Статья, у которой значатся несколько авторов, автоматическое заполнение полей по идентификаторам из викиданных |
Крупные издания
Источник | Комментарий |
---|---|
. — Большая российская энциклопедия , 2016, 1 апреля . — WD . | БРЭ, электронная версия |
: в 35 т. / Гл. ред.: Ю. С. Осипов. — М. : Большая российская энциклопедия , 2004—2017. — WD . | БРЭ, печатная версия |
Видеоматериалы
Источник | Комментарий |
---|---|
Зинкевич А. О. [видеозапись] : Лекция из курса // . — МГУ. | Лекция, ручное задание полей |
[видеозапись] // YouTube . — ВОЗ , 2022, 8 июля . — Дата обращения: 22 ноября 2022. | Видео на youtube, автоматическое получение данных по идентификаторам издателя и площадки |
Аудиоматериалы
Источник | Комментарий |
---|---|
Imagine : [ англ. ] // Imagine : studio album. — USA ; UK , 1971, 9 September . — WD . | Песня, автоматическое получение полей из Викиданных |
Разработка
План работ:
|
См. также
- WDFormat — модуль форматирования информации из Викиданных согласно задаваемым профилям.
- WDSource — подмодуль получения информации об источнике из соответствующего элемента Викиданных.
- Sources — выполняющий схожие c CiteGost функции модуль, на котором основан шаблон {{ source }} .
require('strict')
local p = {}
--: https://www.mediawiki.org/wiki/Extension_default_namespaces
local NS_MAIN = 0
local NS_PROJECT = 4
local NS_TEMPLATE = 10
local NS_MODULE = 828
local moduleNamespace = mw.site.namespaces[NS_MODULE].name
local source = require(moduleNamespace .. ':CiteGost/WDSource')
local formatter = require(moduleNamespace .. ':WDFormat')
local f = formatter.f
local wdLang = require(moduleNamespace .. ':WDLang')
local wikidata = require(moduleNamespace .. ':WDCommon')
local i18n = require(moduleNamespace .. ':I18n')
local l10n = i18n.load()
local currentLangObj = mw.getContentLanguage()
local currentLang = currentLangObj:getCode()
local stylesUsed = false
local function commonLangVisible(source, fieldName)
if not source[fieldName] then
return false
end
if table.getn(source[fieldName]) > 0 then
for _, lang in ipairs(source[fieldName]) do
if lang.components and currentLang == lang.components.langCode.value then
return false
end
end
else
if source[fieldName].components and currentLang == source[fieldName].components.langCode.value then
return false
end
end
return true
end
local function langVisible(source)
return commonLangVisible(source, 'lang')
end
local function mainAuthorVisible(source)
if not source.authors then
return false
end
if table.getn(source.authors) == 0 or table.getn(source.authors) > 3 then
return false
end
return true
end
local function langPropHintVisible(source)
if table.getn(source.lang) > 1 then
if source.lang == source.publishedInLang then
return true
end
end
return false
end
local function mainPublishedInAuthorVisible(source)
if not source.publishedInAuthors then
return false
end
if table.getn(source.publishedInAuthors) == 0 or table.getn(source.publishedInAuthors) > 3 then
return false
end
return true
end
local function authorsVisible(source)
if not source.authors then
return false
end
if table.getn(source.authors) == 1 then
return false
end
return true
end
local function originLangVisible(source)
if not source.originLang then
return false
end
if source.lang.entity == source.originLang.entity then
return false
end
return source.originLang.entity ~= nil
end
local function publishedInOriginLangVisible(source)
if not source.publishedInOriginLang then
return false
end
if source.lang.entity == source.publishedInOriginLang.entity then
return false
end
return source.publishedInOriginLang.entity ~= nil
end
local function publisherVisible(source)
if source.publishedInIsPeriodic and not source.workVersion then
if source.publisher.retrieved then
return false
end
end
return true
end
local function locationVisible(source)
if source.publishedInIsPeriodic and not source.workVersion then
if source.location.retrieved then
return false
end
end
return true
end
local function ruwikiAnchor(source)
if not source.ref then
return nil
end
local anchor = 'CITEREF' .. source.ref.value
local date = source.date
if date and date.value and date.value.year then
anchor = anchor .. date.value.year
end
return anchor
end
local function formatTitle(source, processedData, result)
if processedData.fieldTable.fromLabel then
if source.workVersion then
result.text = result.text .. '?'
result.wikitext = result.wikitext .. '<sup>[[d:Property:P1476|P1476?]]</sup>'
end
end
end
local function formatUrlStatus(source, processedData, result)
if not result.linked then
return
end
local fieldTable = processedData.fieldTable
if not fieldTable.components then
return
end
local statusTable = fieldTable.components.urlStatus
if not statusTable then
return
end
local classesMap = {
['Q1193907'] = 'cite-dead-url',
['Q910845'] = 'cite-paywall-url',
['Q232932'] = 'cite-open-access-url',
['Q24707952'] = 'cite-free-access-url',
['Q107459441'] = 'cite-reg-required-url',
}
local statusClass = classesMap[statusTable.entity]
if not statusClass then
mw.log('Unknown url status:')
mw.logObject(statusTable)
return
end
stylesUsed = true
local spanTitle
if statusTable.value then
spanTitle = mw.ustring.gsub(statusTable.value, '^%l', mw.ustring.upper)
else
spanTitle = ''
end
result.wikitext = '<span class="' .. statusClass .. '" title="' .. spanTitle .. '">' .. result.wikitext .. '</span>'
end
local function formatTitleUrlStatus(source, processedData, result)
if not result.linked then
return
end
formatUrlStatus(source, { fieldTable = source.url }, result)
end
local function formatPublishedInUrlStatus(source, processedData, result)
if not result.linked then
return
end
formatUrlStatus(source, { fieldTable = source.publishedInUrl }, result)
end
local function formatPublishedInTitle(source, processedData, result)
if processedData.fieldTable.fromLabel then
if source.publishedInVersion and not source.publishedInIsHosting then
result.text = result.text .. '?'
result.wikitext = result.wikitext .. '<sup>[[d:Property:P1476|P1476?]]</sup>'
end
end
end
local function formatArchiveUrl(source, processedData, result)
local t = processedData.fieldTable
local archiveUrl = t.components.archiveUrl
if type(archiveUrl) == 'table' then
archiveUrl = archiveUrl.value
end
local archiveDate = t.components.archiveDate
if type(archiveDate) == 'table' and archiveDate.value then
archiveDate = archiveDate.value
end
local langObj = mw.getLanguage(processedData.langCode)
local dateStr = langObj:formatDate('j xg Y', archiveDate.timestamp)
result.text = 'арх. ' .. dateStr
result.wikitext = '[' .. archiveUrl .. ' <abbr title="' .. l10n('messages', 'archive-date-hint') .. '">' .. l10n('messages', 'archive-abbreviated') .. '</abbr>] ' .. dateStr
end
local function formatDateMonth(source, processedData, result, state)
local langObj
if processedData.langCode then
langObj = mw.getLanguage(processedData.langCode)
else
langObj = currentLangObj
end
local dateStr
if source.date.value.day then
dateStr = langObj:formatDate('j xg', source.date.value.timestamp)
else
-- Without this hack formatDate() gives previous month for the 00 day
local timestamp = string.gsub(source.date.value.timestamp, '-00T00:00:00Z', '-01T00:00:00Z')
dateStr = langObj:formatDate('F', timestamp)
if (processedData.capitalize and state.groupEmpty) or processedData.forceCapitalize then
dateStr = mw.ustring.gsub(dateStr, '^%l', mw.ustring.upper)
end
end
result.text = dateStr
result.wikitext = '<span class="nowrap">' .. dateStr .. '</span>'
end
local function formatPartsCount(source, processedData, result, state)
local text
local prefixByLang = {
ru = 'в',
uk = 'у',
en = 'in',
be = 'у',
de = 'in',
fr = 'en',
el = 'σε',
es = 'en',
ar = 'في',
no = 'i',
}
local prefix = prefixByLang[processedData.langCode]
if not prefix then
prefix = ''
else
prefix = prefix .. ' '
end
text = prefix .. tostring(result.text)
if (processedData.capitalize and state.groupEmpty) or processedData.forceCapitalize then
text = mw.ustring.gsub(text, '^%l', mw.ustring.upper)
end
result.text = text
result.wikitext = text
end
local function formatMainAuthorInitialsToEnd(source, processedData, result)
local text = result.text
local initials, familyName = mw.ustring.match(text, '^(.+%.) ([^%. ]+)$')
if not initials or not familyName then
return false
end
text = familyName .. ' ' .. initials
result.text = text
result.wikitext = text
end
local function formatTranslatedFrom(source, processedData, result)
local abbrByLang = {
el = 'Μετάφρ. από τα',
ru = 'Пер. с',
uk = 'Пер. з',
en = 'Transl. from',
de = 'Übers. aus dem',
}
local supported = abbrByLang[processedData.langCode]
if supported then
result.text = supported
result.wikitext = result.text
else
result.text = result.text .. ':'
result.wikitext = result.text
end
end
local function formatEditorsLead(source, processedData, result, state)
local abbrByLang = {
el = 'επιμ.',
en = 'ed.',
es = 'ed.',
de = 'hrsg.',
uk = 'ред.',
no = 'hrsg.',
}
local text = abbrByLang[processedData.langCode]
if (text and state.groupEmpty and processedData.capitalize) or processedData.forceCapitalize then
text = mw.ustring.gsub(text, '^%l', mw.ustring.upper)
end
if text then
result.text = text
result.wikitext = text
end
end
local function formatEditorsInChiefLead(source, processedData, result, state)
local abbrByLang = {
el = 'αρχισυντ.',
en = 'ed. in ch.',
es = 'ed. jefe',
de = 'ch.-Red.',
uk = 'гол. ред.',
no = 'ch.-Red.',
}
local text = abbrByLang[processedData.langCode]
if (text and state.groupEmpty and processedData.capitalize) or processedData.forceCapitalize then
text = mw.ustring.gsub(text, '^%l', mw.ustring.upper)
end
if text then
result.text = text
result.wikitext = text
end
end
local function formatTranslatorsLead(source, processedData, result, state)
local abbrByLang = {
el = 'μεταφρ.',
en = 'transl.',
es = 'trad.',
de = 'übers.',
}
local text = abbrByLang[processedData.langCode]
if (text and state.groupEmpty and processedData.capitalize) or processedData.forceCapitalize then
text = mw.ustring.gsub(text, '^%l', mw.ustring.upper)
end
if text then
result.text = text
result.wikitext = text
end
end
local function formatIllustratorsLead(source, processedData, result, state)
local abbrByLang = {
el = 'εικον.',
en = 'illus.',
}
local text = abbrByLang[processedData.langCode]
if (text and state.groupEmpty and processedData.capitalize) or processedData.forceCapitalize then
text = mw.ustring.gsub(text, '^%l', mw.ustring.upper)
end
if text then
result.text = text
result.wikitext = text
end
end
local function formatPublishedInLink(source, processedData, result)
if result.linked then
return
end
if source.publishedInUrl and source.publishedInUrl.retrieved and mw.wikibase.getSitelink(processedData.fieldTable.entity) then
return
end
f.link(source, processedData, result)
end
local function formatNonNumber(source, processedData, result)
if string.match(result.text, '^[%d%-]+$') then
f.numericalRanges(source, processedData, result)
return
elseif string.match(result.text, '^%d[%.%-%s]') then
f.dash(source, processedData, result)
return
end
if processedData.langCode == 'ru' then
result.text = '«' .. result.text .. '»'
result.wikitext = result.text
end
end
local function replaceAuthors(source, processedData, others)
local othersText
local delimiter
if processedData.langCode == 'ru' then
othersText = '[и др.]'
delimiter = ' '
else
-- the delimiter would probably be language-dependent
othersText = '[' .. wikidata.abbr('Q311624', processedData.langCode) .. ']'
delimiter = ' '
end
others = string.gsub(others, '%[%[d:([^%]]+)|[^%]]+%]%]', '(%1)')
others = string.gsub(others, '<[^>]+>', '')
local othersWikitext = delimiter .. '<abbr title="' .. others .. '">' .. othersText .. '</abbr>'
return othersText, othersWikitext
end
local function replaceExceeded(source, processedData, others)
local othersWikitext = ' <abbr title="' .. others .. '">' .. l10n('messages', 'et-al') .. '</abbr>'
return l10n('messages', 'et-al'), othersWikitext
end
local function localTitleDelimiter(source)
if source.issue then
return ' : '
else
return ' '
end
end
local GostProfile = {
tag = {
name = 'span',
classes = { 'citation' },
attr = {
-- ref
id = ruwikiAnchor,
},
},
groups = {
{
{
field = { 'authors', 1 },
cond = mainAuthorVisible,
format = { formatMainAuthorInitialsToEnd, f.personReversedNoComma, f.wikilink, f.wikidata },
tag = {
name = 'i',
},
},
{
conflicts = { 'authors', 'publishedInIsHosting' },
field = { 'publishedInAuthors', 1 },
cond = mainPublishedInAuthorVisible,
format = { formatMainAuthorInitialsToEnd, f.personReversedNoComma, f.wikilink, f.wikidata },
tag = {
name = 'i',
},
},
{
delimiter = ' ',
ensureEnds = '.',
field = 'title',
urlField = 'url',
capitalize = true,
format = { f.dash, f.link, formatTitleUrlStatus, f.wikisource, f.wikiversity, f.wikibooks, f.resolveWikilink, formatTitle },
},
{
field = 'titleIsMissing',
delimiter = ' ',
ensureEnds = '.',
capitalize = true,
prefix='(',
tag = {
name = 'span',
classes = { 'error' },
},
suffix = ')',
},
{
delimiter = ' : ',
field = 'subtitle',
format = { f.dash },
},
{
tag = {
name = 'sup',
classes = { 'error' },
attr = {
title = l10n('errors', 'missing-lang-explanation'),
},
},
field = 'langIsMissing',
delimiter = '',
},
{
delimiter = ' ',
field = 'contentType',
format = { f.squareBrackets },
},
{
delimiter = ' = ',
cond = originLangVisible,
field = 'origin',
urlField = 'originUrl',
format = { f.dash, f.link, f.resolveWikilink },
},
{
delimiter = ' : ',
depends = 'origin',
cond = originLangVisible,
field = 'originSubtitle',
format = { f.dash },
},
},
{
childDelimiter = ' : ',
{
field = 'lang',
prefix = '[',
cond = langVisible,
forceLang = 'default',
capitalize = false,
limits = {
max = 2,
cutTo = 2,
replaceBy = replaceExceeded,
},
format = { f.abbrWithHint },
suffix = ']',
},
{
cond = langPropHintVisible,
delimiter = '',
value = '<sup>[[d:Property:P407|P407?]]</sup>',
},
{
depends = {
{ isPath=true, 'url', 'archiveUrl'},
{ isPath=true, 'url', 'archiveDate'},
},
field = 'url',
forceLang = 'default',
format = { formatArchiveUrl, f.squareBrackets },
},
{
delimiter = ' ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'wrongArchiveDateFormat',
itemsDelimiter = ' ',
suffix = ')'
},
{
conflicts = 'isVolume',
delimiter = ' : ',
field = 'partsCount',
capitalize = false,
format = { f.quantity, formatPartsCount },
},
},
{
{
depends = 'isVolume',
{
ensureEnds = '.',
delimiter = ' ',
field = 'partsCount',
format = { f.quantity, formatPartsCount },
},
{
ensureEnds = '.',
delimiter = ' ',
depends = 'volume',
entity = 'Q1238720',
capitalize = true,
format = { f.abbr },
},
{
delimiter = ' ',
field = 'volume',
format = { formatNonNumber },
},
{
delimiter = ' : ',
ensureEnds = '.',
delimiter = ' ',
depends = 'volume',
field = 'volumeTitle',
format = { f.dash },
},
{
ensureEnds = '.',
delimiter = ' ',
conflicts = 'volume',
depends = 'volumeTitle',
entity = 'Q1238720',
capitalize = true,
format = { f.abbr },
},
{
ensureEnds = '.',
delimiter = ' ',
conflicts = 'volume',
field = 'volumeTitle',
format = { formatNonNumber },
},
},
{
depends = 'isIssue',
{
ensureEnds = '.',
delimiter = ' ',
field = 'partsCount',
format = { f.quantity, formatPartsCount },
},
{
ensureEnds = '.',
delimiter = ' ',
depends = 'issue',
entity = 'Q28869365',
capitalize = true,
format = { f.abbr },
},
{
delimiter = ' ',
field = 'issue',
format = { formatNonNumber },
},
{
delimiter = ' : ',
ensureEnds = '.',
delimiter = ' ',
depends = 'issue',
field = 'issueTitle',
format = { f.dash },
},
{
ensureEnds = '.',
delimiter = ' ',
conflicts = 'issue',
depends = 'issueTitle',
entity = 'Q28869365',
capitalize = true,
format = { f.abbr },
},
{
ensureEnds = '.',
delimiter = ' ',
conflicts = 'issue',
field = 'issueTitle',
format = { formatNonNumber },
},
},
{
delimiter = ' : ',
field = 'workType',
capitalize = false,
},
{
delimiter = ' : ',
field = 'info',
format = { f.dash },
capitalize = false,
},
{
delimiter = ' : ',
prefix = '[',
field = 'detectedInfo',
forceLang = 'default',
format = { f.dash },
suffix = ']',
capitalize = false,
},
{
depends = 'originLang',
cond = originLangVisible,
delimiter = ' : ',
entity = 'Q7553',
format = { f.abbr, formatTranslatedFrom },
},
{
delimiter = ' ',
cond = originLangVisible,
field = 'originLang',
format = { f.abbrWithHint },
},
},
{
delimiter = ' / ',
{
field = 'authors',
cond = authorsVisible,
limits = {
max = 4,
cutTo = 3,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = 'illustrators',
delimiter = '; ',
entity = 'Q644687',
format = { f.abbr, formatIllustratorsLead },
},
{
delimiter = ': ',
field = 'illustrators',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = 'translators',
delimiter = '; ',
entity = 'Q333634',
format = { f.abbr, formatTranslatorsLead },
},
{
delimiter = ': ',
field = 'translators',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = 'editorInChief',
delimiter = '; ',
entity = 'Q589298',
format = { f.abbr, formatEditorsInChiefLead },
},
{
delimiter = ': ',
field = 'editorInChief',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = 'editors',
delimiter = '; ',
entity = 'Q1607826',
format = { f.abbr, formatEditorsLead },
},
{
delimiter = ': ',
field = 'editors',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
},
{
delimiter = ' // ',
conflicts = { 'isVolume', 'isIssue' },
{
field = 'publishedIn',
urlField = 'publishedInUrl',
capitalize = true,
format = { f.dash, formatPublishedInLink, formatPublishedInUrlStatus, f.wikisource, f.wikiversity, f.wikibooks, f.resolveWikilink, f.wikidata, formatPublishedInTitle },
},
{
field = 'publishedInTitleIsMissing',
delimiter = ' ',
ensureEnds = '.',
capitalize = true,
prefix='(',
tag = {
name = 'span',
classes = { 'error' },
},
suffix = ')',
},
{
delimiter = ' : ',
field = 'publishedInSubtitle',
format = { f.dash },
},
{
delimiter = ' = ',
cond = publishedInOriginLangVisible,
field = 'publishedInOrigin',
format = { f.dash, f.resolveWikilink },
},
{
depends = 'publishedInOriginLang',
cond = publishedInOriginLangVisible,
delimiter = ' : ',
entity = 'Q7553',
format = { f.abbr, formatTranslatedFrom },
},
{
delimiter = ' : ',
field = 'publishedInPartsCount',
capitalize = false,
format = { f.quantity, formatPartsCount },
},
{
delimiter = ' ',
cond = publishedInOriginLangVisible,
field = 'publishedInOriginLang',
format = { f.abbrWithHint },
},
{
delimiter = ' ',
depends = {
{ isPath=true, 'publishedInUrl', 'archiveUrl'},
{ isPath=true, 'publishedInUrl', 'archiveDate'},
},
field = 'publishedInUrl',
forceLang = 'default',
format = { formatArchiveUrl, f.squareBrackets },
},
{
delimiter = ' ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'wrongPublishedInArchiveDateFormat',
itemsDelimiter = ' ',
suffix = ')'
},
{
conflicts = 'isArticle',
delimiter = ' : ',
field = 'publishedInWorkType',
capitalize = false,
},
},
{
delimiter = ' / ',
{
conflicts = { 'isArticle', 'publishedInIsPeriodic' },
depends = 'publishedInEditionType',
field = 'publishedInAuthors',
limits = {
max = 4,
cutTo = 3,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = { 'publishedInIllustrators', 'publishedInIsPeriodic' },
delimiter = '; ',
entity = 'Q644687',
format = { f.abbr, formatIllustratorsLead },
},
{
delimiter = ': ',
field = { 'publishedInIllustrators', 'publishedInIsPeriodic' },
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = { 'publishedInTranslators', 'publishedInIsPeriodic' },
delimiter = '; ',
entity = 'Q333634',
format = { f.abbr, formatTranslatorsLead },
},
{
delimiter = ': ',
field = { 'publishedInTranslators', 'publishedInIsPeriodic' },
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
conflicts = { 'isArticle', 'publishedInIsPeriodic', 'publishedInIsHosting' },
{
depends = { 'publishedInEditorInChief' },
delimiter = '; ',
entity = 'Q589298',
format = { f.abbr, formatEditorsInChiefLead },
},
{
delimiter = ': ',
field = 'publishedInEditorInChief',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
{
depends = { 'publishedInEditors' },
delimiter = '; ',
entity = 'Q1607826',
format = { f.abbr, formatEditorsLead },
},
{
delimiter = ': ',
field = 'publishedInEditors',
limits = {
max = 2,
cutTo = 1,
replaceBy = replaceAuthors,
},
format = { f.person, f.wikilink, f.wikidata },
},
},
},
{
delimiter = ' — ',
ensureEnds = '.',
field = 'edition',
},
{
delimiter = ' — ',
ensureEnds = '.',
{
conflicts = 'isArticle',
cond = locationVisible,
field = 'location',
itemsDelimiter = '; ',
format = { f.abbr, f.wikilink, f.wikidata },
},
{
conflicts = 'isArticle',
cond = publisherVisible,
field = 'publisher',
delimiter = ' : ',
format = { f.short, f.wikilink, f.wikidata },
},
{
field = { 'date', sub='year' },
delimiter = ', ',
},
{
delimiter = ', ',
field = {'date', sub = 'month'},
format = { formatDateMonth },
},
{
field = { 'startDate', sub='year' },
delimiter = ', ',
},
{
delimiter = '—',
field = { 'endDate', sub='year' },
},
{
delimiter = ', ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'wrongDateFormat',
itemsDelimiter = ' ',
suffix = ')'
},
},
{
delimiter = ' — ',
ensureEnds = '.',
{
conflicts = 'isVolume',
{
depends = { {'volume', --[[ or --]] 'volumeTitle'} },
entity = 'Q1238720',
format = { f.abbr },
},
{
delimiter = ' ',
field = 'volume',
format = { f.numericalRanges },
},
{
delimiter = localTitleDelimiter,
field = 'volumeTitle',
},
},
{
conflicts = 'isIssue',
passthrough = true,
{
depends = { {'issue', --[[ or --]] 'issueTitle'} },
delimiter = ', ',
entity = 'Q28869365',
format = { f.abbr },
},
{
delimiter = ' ',
field = 'issue',
},
{
delimiter = localTitleDelimiter,
field = 'issueTitle',
},
},
},
{
delimiter = ' — ',
ensureEnds = '.',
childDelimiter = ' — ',
childEnsureEnds = '.',
{
depends = 'articleId',
entity = 'Q191067',
format = { f.abbr },
},
{
delimiter = ' ',
field = 'articleId',
},
{
depends = 'pages',
entity = 'Q1069725',
format = { f.unit },
},
{
delimiter = ' ',
field = 'pages',
format = { f.numericalRanges },
},
{
conflicts = 'pages',
field = 'pagesCount',
format = { f.quantity },
},
},
{
delimiter = ' — ',
ensureEnds = '.',
prefix = '(',
{
field = 'series',
},
{
ensureEnds = ';',
delimiter = ' ',
field = 'seriesIssue',
},
suffix = ')',
},
{
delimiter = ' — ',
ensureEnds = '.',
prefix = '(',
field = 'comment',
suffix = ')',
},
{
delimiter = ' — ',
ensureEnds = '.',
childDelimiter = ' — ',
childEnsureEnds = '.',
{
depends = 'dedicatedTo',
suffix = ':',
entity = 'P825',
},
{
delimiter = ' ',
field = 'dedicatedTo',
format = { f.person, f.wikilink },
},
{
depends = 'lastUpdate',
value = l10n('messages', 'last-update'),
},
{
delimiter = ': ',
field = 'lastUpdate',
forceLang = currentLang,
format = { f.date },
},
{
delimiter = ' ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'wrongLastUpdateFormat',
itemsDelimiter = ' ',
suffix = ')'
},
{
depends = 'accessDate',
value = l10n('messages', 'access-date'),
},
{
delimiter = ': ',
field = 'accessDate',
forceLang = currentLang,
format = { f.date },
},
{
delimiter = ' ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'wrongAccessDateFormat',
itemsDelimiter = ' ',
suffix = ')'
},
},
{
delimiter = ' — ',
ensureEnds = '.',
childDelimiter = ' — ',
childEnsureEnds = '.',
{
depends = 'issn',
entity = 'Q131276',
format = { f.abbr , f.wikilink },
},
{
delimiter = ' ',
field = 'issn',
urlMaskProp = 'P236',
format = { f.link },
},
{
depends = 'isbn',
entity = 'Q33057',
value = 'ISBN',
format = { f.wikilink },
},
{
delimiter = ' ',
field = 'isbn',
wikilinkMask = l10n('messages', 'wikilink-mask'),
format = { f.wikilink },
},
{
depends = 'doi',
entity = 'Q25670',
value = 'doi',
capitalize = false,
format = { f.wikilink },
},
{
delimiter = ':',
field = 'doi',
urlMaskProp = 'P356',
format = { f.lowercase, f.link, formatUrlStatus },
},
{
conflicts = { 'isbn', 'pmid' },
depends = 'oclc',
entity = 'Q190593',
value = 'OCLC',
format = { f.wikilink },
},
{
conflicts = { 'isbn', 'pmid' },
delimiter = ' ',
field = 'oclc',
urlMaskProp = 'P243',
format = { f.link },
},
{
depends = 'pmid',
entity = 'Q2082879',
value = 'PMID',
format = { f.wikilink },
},
{
delimiter = ' ',
field = 'pmid',
urlMaskProp = 'P698',
format = { f.link },
},
{
depends = 'pmc',
conflicts = 'workVersion',
entity = 'Q229883',
value = 'PMC',
format = { f.wikilink },
},
{
conflicts = 'workVersion',
delimiter = ' ',
field = 'pmc',
urlMaskProp = 'P932',
format = { f.link },
},
{
depends = 's2sic',
conflicts = 'workVersion',
entity = 'Q22908627',
value = 'S2SIC',
format = { f.wikilink },
},
{
conflicts = 'workVersion',
delimiter = ' ',
field = 's2sic',
urlMaskProp = 'P8299',
format = { f.link },
},
{
childDelimiter = ' — ',
childEnsureEnds = '.',
{
entity = 'Q2013',
value = 'WD',
isStatic = true,
format = { f.wikilink },
},
{
delimiter = ' ',
field = 'workVersion',
format = { f.entity, f.forceWikidataLink },
},
{
conflicts = { 'workVersion' },
delimiter = ' ',
field = 'issueVersion',
format = { f.entity, f.forceWikidataLink },
},
{
conflicts = { 'workVersion', 'issueVersion' },
delimiter = ' ',
field = 'volumeVersion',
format = { f.entity, f.forceWikidataLink },
},
{
conflicts = { 'workVersion', 'issueVersion', 'volumeVersion', 'isArticle', 'publishedInIsPeriodic', 'publishedInIsHosting', 'id' },
delimiter = ' ',
field = 'publishedInVersion',
format = { f.entity, f.forceWikidataLink },
},
},
},
{
ensureEnds = '.',
delimiter = ' — ',
depends = 'unknownFields',
tag = {
name = 'span',
classes = { 'error' },
},
prefix = '(',
{
value = l10n('errors', 'unknown-template-args')
},
{
delimiter = ' ',
field = 'unknownFields',
format = { f.nowiki },
},
suffix = ')'
},
{
ensureEnds = '.',
delimiter = ' — ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'urlIsArchive',
itemsDelimiter = ' ',
suffix = ')'
},
{
ensureEnds = '.',
delimiter = ' — ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'archiveUrlWithoutUrl',
itemsDelimiter = ' ',
suffix = ')'
},
{
ensureEnds = '.',
delimiter = ' — ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'archiveUrlWithoutArchiveDate',
itemsDelimiter = ' ',
suffix = ')'
},
{
ensureEnds = '.',
delimiter = ' — ',
prefix = '(',
tag = {
name = 'span',
classes = { 'error' },
},
field = 'idWithoutPublishedIn',
itemsDelimiter = ' ',
suffix = ')'
},
},
ensureEnds = '.',
}
local function argIsEmpty(s)
return (not s or s == '')
end
local function argIsSet(s)
return (s and s ~= '')
end
local function strToArray(str, t)
if type(str) == 'table' then
if next(str) == nil then
return t
end
return str
end
local array = t
for item in str:gmatch('[^,]+') do
item = item:gsub('^%s+', ''):gsub('%s+$', '')
table.insert(array, { value=item })
end
return array
end
local function strToDate(str, t)
local year, month, day = str:match('^(%d+)-(%d+)-(%d+)$')
if not year then
year, month = str:match('^(%d+)-(%d+)$')
if not year then
year = str:match('^(%d+)$')
end
end
if not year then
t.erroneous = true
return t
end
year = tonumber(year)
if month then
month = tonumber(month)
if month == 0 then
month = nil
end
end
if day then
day = tonumber(day)
if day == 0 then
day = nil
end
end
local timestamp
if day then
timestamp = string.format("%04d-%02d-%02d", year, month, day)
elseif month then
timestamp = string.format("%04d-%02d", year, month)
else
timestamp = string.format("%04d", year)
end
t.value = { year=year, month=month, day=day, timestamp=timestamp }
return t
end
local function strToDateToParentTable(value, parentTable, name)
if not parentTable.components then
parentTable.components = {}
end
parentTable.components[name] = strToDate(value, {})
return parentTable
end
local function waybackStampToArchiveUrl(stamp, url)
if argIsEmpty(stamp) then
return nil
end
return { value='https://web.archive.org/web/' .. stamp .. '/' .. url.value }
end
local function waybackStampToArchiveDate(stamp)
if argIsEmpty(stamp) then
return nil
end
local year, month, day = string.match(stamp, '(%d%d%d%d)(%d%d)(%d%d)')
local timestamp = string.format("%04d-%02d-%02d", year, month, day)
return { value={ year=year, month=month, day=day, timestamp=timestamp } }
end
local function volumesCountToPartsCount(volumesCount, t)
t.value = volumesCount
t.unitEntity = 'Q1238720'
return t
end
local function entityToTable(entity, t)
t.entity = entity
return t
end
local function valueToTable(value, t)
t.value = value
return t
end
local function valueToParentTable(value, parentTable, name)
if not parentTable.components then
parentTable.components = {}
end
local t = {
value = value,
}
parentTable.components[name] = t
return parentTable
end
local function urlStatusToTable(value, parentTable)
if not parentTable.components then
parentTable.components = {}
end
local status = l10n('args', 'reversed', 'urlStatus', value)
local entityMap = {
dead = 'Q1193907',
paywall = 'Q910845',
['open access'] = 'Q232932',
['free access'] = 'Q24707952',
['registration required'] = 'Q107459441',
}
local t = {
value = value,
lang = currentLang,
entity = entityMap[status],
}
parentTable.components.urlStatus = t
return parentTable
end
local function langCodeToTable(langCode, t)
t.entity = wdLang.langEntity(langCode)
t.components = {
langCode = { value = langCode },
}
return t
end
local function pagesToTable(pagesCount, t)
t.value = pagesCount
t.unitEntity = 'Q1069725'
return t
end
local function getTitles(frame)
if not frame then
frame = mw.getCurrentFrame()
end
local template
local parentFrame = frame:getParent()
local selfTitle = frame:getTitle()
if parentFrame then
template = parentFrame:getTitle()
else
template = selfTitle
end
return template, selfTitle
end
local function getTemplateNameFromTitle(template)
local templateNamespace = mw.site.namespaces[NS_TEMPLATE].name
return template:gsub('^' .. templateNamespace .. ':', '')
end
local function argsToSource(frame)
local s = {}
local argsMap = {
entity = { entityToTable, 'workVersion' },
origin = { valueToTable, 'origin' },
originEntity = { entityToTable, 'origin' },
originUrl = { valueToTable, 'originUrl' },
originLang = { langCodeToTable, 'originLang' },
contentTypeEntity = { entityToTable, 'contentType' },
contentType = { valueToTable, 'contentType' },
workTypeEntity = { entityToTable, 'workType' },
workType = { valueToTable, 'workType' },
authors = { strToArray, 'authors' },
illustrators = { strToArray, 'illustrators' },
editorInChief = { strToArray, 'editorInChief' },
editors = { strToArray, 'editors' },
translators = { strToArray, 'translators' },
title = { valueToTable, 'title' },
subtitle = { valueToTable, 'subtitle' },
info = { valueToTable, 'info' },
volumesCount = { volumesCountToPartsCount, 'partsCount' },
publishedInEntity = { entityToTable, 'publishedInVersion' },
publishedIn = { valueToTable, 'publishedIn' },
publishedInSubtitle = { valueToTable, 'publishedInSubtitle' },
publishedInOrigin = { valueToTable, 'publishedInOrigin' },
publishedInOriginLang = { langCodeToTable, 'publishedInOriginLang' },
publishedInLang = { langCodeToTable, 'publishedInLang' },
publishedInAuthors = { strToArray, 'publishedInAuthors' },
publishedInIllustrators = { strToArray, 'publishedInIllustrators' },
publishedInEditors = { strToArray, 'publishedInEditors' },
publishedInEditorInChief = { strToArray, 'publishedInEditorInChief' },
publishedInTranslators = { strToArray, 'publishedInTranslators' },
publishedInUrl = { valueToTable, 'publishedInUrl' },
publishedInUrlStatus = { urlStatusToTable, 'publishedInUrl' },
publishedInVolumes = { volumesCountToPartsCount, 'publishedInPartsCount' },
publishedInWorkType = { valueToTable, 'publishedInWorkType' },
comment = { valueToTable, 'comment' },
edition = { valueToTable, 'edition' },
location = { valueToTable, 'location' },
locationEntity = { entityToTable, 'location' },
publisher = { valueToTable, 'publisher' },
publisherEntity = { entityToTable, 'publisher' },
topic = { valueToTable, 'topic' },
topicEntity = { entityToTable, 'topic' },
id = { valueToTable, 'id' },
date = { strToDate, 'date' },
volume = { valueToTable, 'volume' },
volumeTitle = { valueToTable, 'volumeTitle' },
issue = { valueToTable, 'issue' },
issueTitle = { valueToTable, 'issueTitle' },
articleId = { valueToTable, 'articleId' },
pages = { valueToTable, 'pages' },
pagesCount = { pagesToTable, 'pagesCount' },
series = { valueToTable, 'series' },
seriesEntity = { entityToTable, 'series' },
seriesIssue = { valueToTable, 'seriesIssue' },
lastUpdate = { strToDate, 'lastUpdate' },
accessDate = { strToDate, 'accessDate' },
doi = { valueToTable, 'doi' },
pmid = { valueToTable, 'pmid' },
pmc = { valueToTable, 'pmc' },
s2sic = { valueToTable, 's2sic' },
oclc = { valueToTable, 'oclc' },
issn = { strToArray, 'issn' },
isbn = { strToArray, 'isbn' },
url = { valueToTable, 'url' },
urlStatus = { urlStatusToTable, 'url' },
waybackStamp = { valueToTable, 'waybackStamp' },
archiveUrl = { valueToParentTable, 'url', 'archiveUrl' },
archiveDate = { strToDateToParentTable, 'url', 'archiveDate' },
publishedInArchiveUrl = { valueToParentTable, 'publishedInUrl', 'archiveUrl' },
publishedInArchiveDate = { strToDateToParentTable, 'publishedInUrl', 'archiveDate' },
ref = { valueToTable, 'ref' },
lang = { langCodeToTable, 'lang' },
}
local serviceArgs = {
offline = true,
forceSubst = true,
pureWikitext = true,
}
local unknownFields = {}
local template, selfTitle = getTitles(frame)
local ok, templateInfo = pcall(mw.loadData, selfTitle .. '/args:' .. template)
if ok then
local parentFrame = frame:getParent()
for parentKey, value in pairs(parentFrame.args) do
local key = templateInfo.argsToModule[parentKey]
if key then
value = mw.text.trim(value)
if argIsSet(value) then
local argMap = argsMap[key]
if argMap then
local name = argMap[2]
local childName = argMap[3]
local fieldTable = s[name] or {}
s[name] = argMap[1](value, fieldTable, childName)
elseif not serviceArgs[key] then
error(string.format(l10n('errors', 'unknown-module-arg'), key))
end
end
else
table.insert(unknownFields, { value = parentKey })
end
end
else
for key, value in pairs(frame.args) do
if argIsSet(value) then
local argMap = argsMap[key]
if argMap then
local name = argMap[2]
local childName = argMap[3]
local fieldTable = s[name] or {}
s[name] = argMap[1](value, fieldTable, childName)
elseif not serviceArgs[key] then
error('Unknown module argument: ' .. key)
end
end
end
end
if next(unknownFields) ~= nil then
s.unknownFields = unknownFields
end
if s.publishedInVersion then
s.publishedIn = entityToTable(s.publishedInVersion.entity, s.publishedIn or {})
end
if s.publishedInEditors or s.publishedInEditorInChief then
s.isLikeBook = { entity = 'Q571' }
end
return s
end
local function urlIsArchive(urlTable)
local url = urlTable.value:gsub('^(https?://)www%.', '%1')
local isArchive = false
if url:match('^https?://web%.archive%.org/web/') or url:match('^https?://webcitation%.org/%w+') then
isArchive = true
end
if url:match('^https?://archive%.%a+/%w+') then
if url:match('^https?://archive%.today/') or
url:match('^https?://archive%.ph/') or
url:match('^https?://archive%.is/') or
url:match('^https?://archive%.li/') or
url:match('^https?://archive%.vn/') or
url:match('^https?://archive%.fo/') or
url:match('^https?://archive%.md/') then
isArchive = true
end
end
return isArchive
end
local function appendErrorField(s, fieldName, errorKey)
s[fieldName] = s[fieldName] or {}
table.insert(s[fieldName], {
value = l10n('errors', errorKey),
lang = currentLang,
})
end
local function checkFields(s)
local hasErrors = false
if not s.lang or (table.getn(s.lang) == 0 and s.lang.isDefault) then
appendErrorField(s, 'langIsMissing', 'missing-lang')
hasErrors = true
end
if s.url then
if s.url.value then
if urlIsArchive(s.url) then
appendErrorField(s, 'urlIsArchive', 'url-contains-archiveUrl')
hasErrors = true
end
elseif s.url.components then
if s.url.components.archiveUrl then
appendErrorField(s, 'archiveUrlWithoutUrl', 'archiveUrl-without-url')
hasErrors = true
end
if s.url.components.urlStatus then
appendErrorField(s, 'urlIsMissing', 'urlStatus-without-url')
hasErrors = true
end
end
if s.url.components then
if s.url.components.archiveDate then
if s.url.components.archiveDate.erroneous then
appendErrorField(s, 'wrongArchiveDateFormat', 'wrong-date-format')
hasErrors = true
end
elseif s.url.components.archiveUrl then
appendErrorField(s, 'archiveUrlWithoutArchiveDate', 'archiveUrl-without-archiveDate')
hasErrors = true
end
end
end
if s.publishedInUrl then
if s.publishedInUrl.value then
if urlIsArchive(s.publishedInUrl) then
appendErrorField(s, 'urlIsArchive', 'publishedIn-url-contains-archiveUrl')
hasErrors = true
end
elseif s.publishedInUrl.components then
if s.publishedInUrl.components.archiveUrl then
appendErrorField(s, 'archiveUrlWithoutUrl', 'publishedIn-archiveUrl-without-url')
hasErrors = true
end
if s.publishedInUrl.components.urlStatus then
appendErrorField(s, 'urlIsMissing', 'publishedIn-urlStatus-without-url')
hasErrors = true
end
end
if s.publishedInUrl.components then
if s.publishedInUrl.components.archiveDate then
if s.publishedInUrl.components.archiveDate.erroneous then
appendErrorField(s, 'wrongPublishedInArchiveDateFormat', 'wrong-date-format')
hasErrors = true
end
elseif s.publishedInUrl.components.archiveUrl then
appendErrorField(s, 'archiveUrlWithoutArchiveDate', 'publishedIn-archiveUrl-without-archiveDate')
hasErrors = true
end
end
end
if (not s.url or not s.url.value) and (not s.publishedInUrl or not s.publishedInUrl.value) then
if s.accessDate then
appendErrorField(s, 'urlIsMissing', 'accessDate-without-url')
hasErrors = true
end
end
if not s.title then
appendErrorField(s, 'titleIsMissing', 'missing-title')
hasErrors = true
end
if (s.publishedInUrl or s.publishedInSubtitle) and (not s.publishedIn or not s.publishedIn.value) then
appendErrorField(s, 'publishedInTitleIsMissing', 'missing-publishedIn')
hasErrors = true
end
if s.date and s.date.erroneous then
appendErrorField(s, 'wrongDateFormat', 'wrong-date-format')
hasErrors = true
end
if s.accessDate and s.accessDate.erroneous then
appendErrorField(s, 'wrongAccessDateFormat', 'wrong-date-format')
hasErrors = true
end
if s.lastUpdate and s.lastUpdate.erroneous then
appendErrorField(s, 'wrongLastUpdateFormat', 'wrong-date-format')
hasErrors = true
end
if s.id and not s.id.retrieved and not (s.publishedIn and s.publishedIn.entity) then
appendErrorField(s, 'idWithoutPublishedIn', 'id-without-publishedInEntity')
hasErrors = true
end
return hasErrors
end
local function categoriesAllowed()
if not mw.title.getCurrentTitle():inNamespaces(NS_MAIN, NS_TEMPLATE, NS_PROJECT) then
return false
end
return true
end
local function getErrorCategories(source, categories, templateName)
local categoriesStr = ''
for _, cat in ipairs(categories) do
local found = false
for _, fieldName in ipairs(cat) do
if source[fieldName] then
found = true
break
end
end
if found then
categoriesStr = categoriesStr .. '[[' .. mw.ustring.format(l10n('categories', cat.name), templateName) .. ']]'
end
end
return categoriesStr
end
function p.cite(frame)
local s = argsToSource(frame)
local langCode
if not s.offline or not s.offline.value then
s, langCode = source.fetch(s)
elseif s.lang then
if table.getn(s.lang) > 0 then
for _, lang in ipairs(s.lang) do
if lang.components and s.lang.components.langCode then
langCode = lang.components.langCode.value
break
end
end
else
if s.lang.components and s.lang.components.langCode then
langCode = s.lang.components.langCode.value
end
end
else
langCode = currentLangObj:getCode()
end
if s.url and s.url.value and s.waybackStamp then
if not s.url.components or (not s.url.components.archiveUrl or not s.url.components.archiveUrl.retrieved) then
if not s.url.components then
s.url.components = {}
end
s.url.components.archiveUrl = waybackStampToArchiveUrl(s.waybackStamp.value, s.url)
s.url.components.archiveDate = waybackStampToArchiveDate(s.waybackStamp.value)
end
end
local hasErrors = checkFields(s)
local args = frame.args
if (mw.isSubsting() or argIsSet(args.forceSubst)) and argIsEmpty(args.pureWikitext) then
local template, selfTitle = getTitles(frame)
local argsProfile = require(selfTitle .. '/Subst')
local langCode = s.lang and s.lang.components and s.lang.components.langCode
return '{{' .. getTemplateNameFromTitle(template) .. '|' .. formatter.format(argsProfile, s, langCode) .. '}}'
end
local formattedCitation = formatter.format(GostProfile, s, langCode)
local styles = ''
if stylesUsed then
styles = frame:extensionTag('templatestyles', '', { src = frame:getTitle() .. '/styles.css' })
end
local categoriesStr = ''
if not argIsSet(args.noCat) then
if hasErrors and categoriesAllowed() then
local template, selfTitle = getTitles(frame)
local templateName = getTemplateNameFromTitle(template)
local categories = {
{
'unknownFields',
name = 'Unknown parameters',
},
{
'archiveUrlWithoutUrl',
'archiveUrlWithoutArchiveDate',
'urlIsArchive',
name = 'Wrong archive url parameters',
},
{
name = 'Lang is not specified',
'langIsMissing',
},
{
'urlIsMissing',
name = 'URL is not specified',
},
{
'titleIsMissing',
name = 'Title is not specified',
},
{
'publishedInTitleIsMissing',
name = 'PublishedIn is not specified',
},
{
'wrongDateFormat',
'wrongAccessDateFormat',
'wrongLastUpdateFormat',
'wrongArchiveDate',
'wrongPublishedInArchiveDateFormat',
name = 'Wrong date format',
},
{
'idWithoutPublishedIn',
name = 'Id without publishedIn',
},
}
categoriesStr = getErrorCategories(s, categories, templateName)
end
end
return styles .. formattedCitation .. categoriesStr
end
return p
- 2021-05-15
- 1