Бикитиэкэ sahwikisource https://sah.wikisource.org/wiki/%D0%A1%D2%AF%D1%80%D2%AF%D0%BD_%D1%81%D0%B8%D1%80%D1%8D%D0%B9 MediaWiki 1.47.0-wmf.8 first-letter Миэдьийэ Аналлаах Ырытыы Кыттааччы Кыттааччы ырытыыта Бикитиэкэ Бикитиэкэ Ырытыы Билэ Билэ ырытыыта MediaWiki MediaWiki-ни ырытыы Халыып Халыыбы ырытыы Көмө Көмөнү ырытыы Категория Категорияны ырытыы Ааптар Ааптар ырытыыта Page Page talk Index Index talk TimedText TimedText talk Модуль Обсуждение модуля Event Event talk Халыып:Сүрүн сирэй/Бастыҥ тиэкис 10 1907 9635 9346 2026-06-25T02:40:34Z Sauit 2200 9635 wikitext text/x-wiki <center><div style="font-size:125%">'''[[Болот Боотур]]''' — «[[Саллааттар этибит (Болот Боотур)|Саллааттар этибит]]»</div></center><br> <poem> {{poem-on|САЛЛААТТАР ЭТИБИТ}} ''(Публицистическэй бэйиэмэ)'' Урукку бэлэмҥэ Олорбот аналлаах, Түбүктээх бу кэмҥэ Төрөөбүт «буруйдаах» Биһиги көлүөнэ Биир тэгил кэккэтэ Капитал өһүөнэ Хайдаҕын билбитэ. Умнуллуо суох өтөр Ол сэрии күннэрэ, Утуйар уу көтөр Түн түлэй түүннэрэ. Оҕону, аҕаны Фроҥҥа сүтэрбит Соһумар даҕаны Сураҕы истэрбит. Фашизмы самнара Барыбыт турбуппут. Хахайдыы утарсан Хааммытын тохпуппут. Кыайтарар, чугуйар Кыһыытын билбиппит, Өрөгөйдүүр, кыайар Үөрүүгэ тиийбиппит. </poem> {{poem-off}} <div align="right"> [[Саллааттар этибит (Болот Боотур)|Салгыы…]] | [[Бикитиэкэ:Бастыҥ тиэкистэр|Атын бастыҥ тиэкистэр]] </div> <noinclude>[[Категория:Халыыптар:Сүрүн сирэй халыыптара]]</noinclude> bb56lugk4xx4yydyxd7m6fn7bsynw01 9636 9635 2026-06-25T02:43:25Z Sauit 2200 9636 wikitext text/x-wiki <center><div style="font-size:125%">'''[[Болот Боотур]]''' — «[[Саллааттар этибит (Болот Боотур)|Саллааттар этибит]]»</div></center><br> {{poemx|САЛЛААТТАР ЭТИБИТ| ''(Публицистическэй бэйиэмэ)'' Урукку бэлэмҥэ Олорбот аналлаах, Түбүктээх бу кэмҥэ Төрөөбүт «буруйдаах» Биһиги көлүөнэ Биир тэгил кэккэтэ Капитал өһүөнэ Хайдаҕын билбитэ. Умнуллуо суох өтөр Ол сэрии күннэрэ, Утуйар уу көтөр Түн түлэй түүннэрэ. Оҕону, аҕаны Фроҥҥа сүтэрбит Соһумар даҕаны Сураҕы истэрбит. Фашизмы самнара Барыбыт турбуппут. Хахайдыы утарсан Хааммытын тохпуппут. Кыайтарар, чугуйар Кыһыытын билбиппит, Өрөгөйдүүр, кыайар Үөрүүгэ тиийбиппит.}} <div align="right"> [[Саллааттар этибит (Болот Боотур)|Салгыы…]] | [[Бикитиэкэ:Бастыҥ тиэкистэр|Атын бастыҥ тиэкистэр]] </div> <noinclude>[[Категория:Халыыптар:Сүрүн сирэй халыыптара]]</noinclude> 6vu9wqse0u0cymmpsuw463zugie9958 Халыып:Ааптар 10 1985 9637 8773 2026-06-25T02:50:51Z Sauit 2200 9637 wikitext text/x-wiki {{#invoke:Author|author}} <noinclude> {{documentation}} [[Категория:Халыыптар:Сирэйдэр халыыптара|{{PAGENAME}}]] </noinclude> liop0fd7d6moux78iozvu108mt9n0gn Модуль:Author 828 2493 9638 2026-06-25T02:51:43Z Sauit 2200 "require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args..." саҥа сирэй оҥоһулунна 9638 Scribunto text/plain require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args) return mw.getCurrentFrame():preprocess(args) end local wd_properties = { birth = 'P569', death = 'P570', workperiodstart = 'P2031', workperiodend = 'P2032', floruit = 'P1317', familyname = 'P734', gender = 'P21', instanceof = 'P31', medialegend = 'P2096', image = 'P18', flag_image = 'P41', logo_image = 'P154', nationalities = 'P27', occupations = 'P106', religions = 'P140', movements = 'P135', ideologies = 'P1142', employer = 'P108', positionheld = 'P39', awardreceived = 'P166', memberof = 'P463', canonizationstatus = 'P411', contributedto = 'P3919', socialclassification = 'P3716', instrument = 'P1303', describedby = 'P1343', mannerofdeath = 'P1196' } -------------------------------------------------------------------------------- -- Add a category to the current list of categories. Do not include the Category prefix. local function addCategory(category) table.insert(categories, category) end -------------------------------------------------------------------------------- -- Remove a category. Do not include the Category prefix. local function removeCategory(category) for catPos, cat in pairs(categories) do if cat == category then table.remove(categories, catPos) end end end -------------------------------------------------------------------------------- -- Get wikitext for all categories added using addCategory. local function getCategories() categories = TableTools.removeDuplicates(categories) table.sort(categories) local out = '' for _, cat in pairs(categories) do out = out .. '[[Category:' .. cat .. ']]' end return out end local function normalize_args(args) -- aliases local dup_cat = '' local oldKeys = {} local newArgs = {} for k, v in pairs(args) do local newkey = string.lower(string.gsub(string.gsub(tostring(k), '-', '_'), ' ', '_')) if newkey ~= tostring(k) then if args[newkey] then addCategory('Pages using duplicate arguments in template calls') end newArgs[newkey] = newArgs[newkey] or v table.insert(oldKeys, tostring(k)) end end for k, v in pairs(newArgs) do args[k] = v end for k, v in pairs(oldKeys) do args[v] = nil end args.wikidata = args.wikidata or args.wikidata_id args.wikidata_id = nil -- Fetch entity object for Wikidata item connected to the current page -- Let manually-specified Wikidata ID override if given and valid if args.wikidata and mw.wikibase.isValidEntityId(args.wikidata) then args.wd_entity = mw.wikibase.getEntity(args.wikidata) else args.wd_entity = mw.wikibase.getEntity() end args.use_initials = yesno(args.use_initials) ~= false and args.last_initial ~= '!NO_INITIALS' args.nocat = yesno(args.nocat) or false return args end -------------------------------------------------------------------------------- -- Get the actual parentheses-enclosed HTML string that shows the dates. local function getFormattedDates(birthyear, deathyear, workPeriodYears) if not birthyear and not deathyear and not workPeriodYears then return nil end local dates = '<br />(' local birthNotFloruit = birthyear and not birthyear:match("^fl%.") local deathNotFloruit = deathyear and not deathyear:match("^fl%.") if (birthNotFloruit and birthyear ~= '?') or (deathNotFloruit and deathyear ~= '?') or not workPeriodYears then removeCategory('Authors with approximate workperiodend dates') removeCategory('Authors with approximate workperiodstart dates') if birthyear then if birthNotFloruit and deathyear and not deathNotFloruit then dates = dates .. "b. " end dates = dates .. birthyear end if (birthyear or deathyear) and birthyear ~= deathyear then -- Add spaces if there are spaces in either of the dates. local spaces = '' if string.match((birthyear or '') .. (deathyear or ''), ' ') then spaces = ' ' end dates = dates .. spaces .. '–' .. spaces end if deathyear and birthyear ~= deathyear then if deathNotFloruit and birthyear and not birthNotFloruit then dates = dates .. "d. " end dates = dates .. deathyear end else dates = dates .. workPeriodYears addCategory('Authors with floruit dates') end if birthyear or deathyear or workPeriodYears then dates = dates .. ')' end return dates end -------------------------------------------------------------------------------- -- Take a statement of a given property and make a human-readable year string -- out of it, adding the relevant categories as we go. -- @param table statement The statement. -- @param string type One of 'birth' or 'death'. local function getYearStringFromSingleStatement(statement, year_type) local snak = statement.mainsnak -- We're not using mw.wikibase.formatValue because we only want years. -- No value. This is invalid for birth dates (should be 'somevalue' -- instead), and indicates 'still alive' for death dates. if snak.snaktype == 'novalue' and year_type == 'birth' then addCategory('Authors with missing birth dates') return nil end if snak.snaktype == 'novalue' and year_type == 'death' then addCategory('Living authors') return nil end -- Unknown value. if snak.snaktype == 'somevalue' then addCategory('Authors with unknown ' .. year_type .. ' dates') return '?' end -- Extract year from the time value. local _, _, extractedYear = string.find(snak.datavalue.value.time, '([%+%-]%d%d%d+)%-') local year = math.abs(tonumber(extractedYear)) addCategory(dateModule.era(extractedYear) .. ' authors') -- Century & millennium precision. if snak.datavalue.value.precision == 6 or snak.datavalue.value.precision == 7 then local ceilfactor = 100 local precisionName = 'century' if snak.datavalue.value.precision == 6 then ceilfactor = 1000 precisionName = 'millennium' end local cent = math.max(math.ceil(year/ceilfactor), 1) local suffixed_cent = ordinal(cent, false, false) year = suffixed_cent .. ' ' .. precisionName addCategory('Authors with approximate ' .. year_type .. ' dates') elseif snak.datavalue.value.precision == 8 then -- decade precision year = math.floor(tonumber(year)/10) * 10 .. 's' addCategory('Authors with approximate ' .. year_type .. ' dates') end if tonumber(extractedYear) < 0 then year = year .. ' BCE' end -- Remove from 'Living authors' if that's not possible. if tonumber(extractedYear) < tonumber(os.date('%Y') - 110) then removeCategory('Living authors') end -- Add to e.g. 'YYYY births' category (before we add 'c.' or 'fl.' prefixes). if year_type == 'birth' or year_type == 'death' then -- mw.logObject('Wikidata cat') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end -- Extract circa (P1480 = sourcing circumstances, Q5727902 = circa) if statement.qualifiers and statement.qualifiers.P1480 then for _,qualifier in pairs(statement.qualifiers.P1480) do if qualifier.datavalue and qualifier.datavalue.value.id == 'Q5727902' then addCategory('Authors with approximate ' .. year_type .. ' dates') year = 'c. ' .. year end end end -- Add floruit abbreviation. if year_type == 'floruit' then year = 'fl. ' .. year end return year end -------------------------------------------------------------------------------- -- Get a given or family name property. -- This concatenates (with spaces) all statements of the given property in order of the series ordinal (P1545) qualifier. -- @TODO fix this. local function getNameFromWikidata(item, property) local statements = item:getBestStatements(property) local out = {} if statements[1] and statements[1].mainsnak.datavalue then local itemId = statements[1].mainsnak.datavalue.value.id table.insert(out, mw.wikibase.label(itemId) or '') end return table.concat(out, ' ') end -------------------------------------------------------------------------------- local function getPropertyValue(item, property) local statements = item:getBestStatements(property) if statements[1] and statements[1].mainsnak.datavalue then return statements[1].mainsnak.datavalue.value end end -------------------------------------------------------------------------------- -- The 'Wikisource' format for a birth or death year is as follows: -- "?" or empty for unknown (or still alive) -- Use BCE for years before year 1 -- Approximate dates: -- Decades or centuries: "1930s" or "20th century" -- Circa: "c/1930" or "c. 1930" or "ca 1930" or "circa 1930" -- Tenuous year: "1932/?" -- Choice of two or more years: "1932/1933" -- This is a slightly overly-complicated function, but one day will be able to be deleted. -- @param string type Either 'birth' or 'death' -- @return string The year to display local function formatWikisourceYear(year, year_type) if not year then return nil end -- mw.logObject('formatWikisourceYear') local yearParts = mw.text.split(year, '/', true) -- mw.logObject('yearParts') -- mw.logObject(yearParts) -- Ends in a question mark. if yearParts[2] == '?' then addCategory('Authors with unknown ' .. year_type .. ' dates') if tonumber(yearParts[1]) then -- mw.logObject('unknown') -- mw.logObject(yearParts[1] .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearParts[1]) .. ' authors') addCategory(yearParts[1] .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return yearParts[1] .. '?' end -- Starts with one of the 'circa' abbreviations local circaNames = {'ca.', 'c.', 'ca', 'c', 'circa'} for _, circaName in pairs(circaNames) do local yearNumber local isCirca = false if yearParts[1] == circaName then yearNumber = mw.text.trim(yearParts[2]) isCirca = true elseif string.match(yearParts[1], '^' .. circaName) then yearNumber = string.gsub(yearParts[1], '^' .. circaName, '') isCirca = (tonumber(yearNumber) ~= nil) end if isCirca then addCategory('Authors with approximate ' .. year_type .. ' dates') if tonumber(yearNumber) then yearNumber = tonumber(yearNumber) -- mw.logObject(yearNumber) addCategory(dateModule.era(tostring(yearNumber)) .. ' authors') addCategory(yearNumber .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return 'c. ' .. yearNumber end end -- If there is more than one year part, and they're all numbers, add categories. local allPartsAreNumeric = true if #yearParts > 1 then for _, yearPart in pairs(yearParts) do if tonumber(yearPart) then -- mw.logObject('numeric') -- mw.logObject(yearPart .. ' ' .. year_type .. 's') addCategory(yearPart .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearPart) .. ' authors') else allPartsAreNumeric = false end end if allPartsAreNumeric then addCategory('Authors with approximate birth dates') end elseif #yearParts == 1 and not tonumber(year) then allPartsAreNumeric = false end -- Otherwise, just use whatever's been given if not allPartsAreNumeric then addCategory('Authors with non-numeric ' .. year_type .. ' dates') end if #yearParts == 1 or allPartsAreNumeric == false then -- mw.logObject('not numeric') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end return year end --[=[ Get a formatted year of the given property and add to the relevant categories ]=] local function formatWikidataYear(item, year_type) -- Check sanity of inputs if not item or not year_type or not wd_properties[year_type] then return nil end local property = wd_properties[year_type] -- Get this property's statements. local statements = item:getBestStatements(property) if #statements == 0 then -- If there are no statements of this type, add to 'missing' category. if year_type == 'birth' or year_type == 'death' then addCategory('Authors with missing ' .. year_type .. ' dates') end local isHuman = item:formatPropertyValues(wd_properties['instanceof']).value == 'human' if year_type == 'death' and isHuman then -- If no statements about death, assume to be alive. addCategory('Living authors') end end -- Compile a list of years, one from each statement. local years = {} for _, statement in pairs(statements) do local year = getYearStringFromSingleStatement(statement, year_type) if year then table.insert(years, year) end end years = TableTools.removeDuplicates(years) -- If no year found yet, try for a floruit date. Make an exception for workperiod if (#years == 0 or table.concat(years, '/') == '?') and year_type ~= "workperiodstart" and year_type ~= "workperiodend" then local floruitStatements = item:getBestStatements(wd_properties["floruit"]) for _, statement in pairs(floruitStatements) do -- If all we've got so far is 'unknown', replace it. if table.concat(years, '/') == '?' then years = {} end addCategory('Authors with floruit dates') local year = getYearStringFromSingleStatement(statement, 'floruit') if year then table.insert(years, year) end end end years = TableTools.removeDuplicates(years) if #years == 0 then return nil end return table.concat(years, '/') end -------------------------------------------------------------------------------- -- Get a single formatted date, with no categories. -- args.year, args.year_type, args.wd_entity local function date(args) if args.year then return formatWikisourceYear(args.year, args.year_type) else return formatWikidataYear(args.wd_entity, args.year_type) end end -------------------------------------------------------------------------------- -- Get a formatted string of the years that this author lived, -- and categorise in the appropriate categories. -- The returned string starts with a line break (<br />). local function dates(args) local outHtml = mw.html.create() -------------------------------------------------------------------------------- -- Check a given title as having the appropriate dates as a disambiguating suffix. local function checkTitleDatesAgainstWikidata(title, wikidata) -- All disambiguated author pages have parentheses in their titles. local titleHasParentheses = string.find(tostring(title), '%d%)') if not titleHasParentheses then return end -- The title should end with years in the same format as is used in the page header -- but with a normal hyphen instead of an en-dash. local dates = '(' .. (date({year_type = 'birth', wd_entity = args.wd_entity}) or '') .. '-' .. (date({year_type = 'death', wd_entity = args.wd_entity}) or '') .. ')' if string.sub(tostring(title), -string.len(dates)) ~= dates then addCategory('Authors with title-date mismatches') end end -- Check disambiguated page titles for accuracy. checkTitleDatesAgainstWikidata(args.pagetitle or mw.title.getCurrentTitle(), args.wikidata) -- Get the dates (do death first, so birth can override categories if required): -- Death local deathyear local wikidataDeathyear = formatWikidataYear(args.wd_entity, 'death') local wikisourceDeathyear = formatWikisourceYear(args.deathyear, 'death') if args.deathyear then -- For Wikisource-supplied death dates. deathyear = wikisourceDeathyear addCategory('Authors with override death dates') if args.wd_entity and wikisourceDeathyear ~= wikidataDeathyear then addCategory('Authors with death dates differing from Wikidata') end if tonumber(deathyear) then addCategory(dateModule.era(deathyear) .. ' authors') end else deathyear = wikidataDeathyear end if not deathyear then addCategory('Authors with missing death dates') end -- Birth local birthyear local wikidataBirthyear = formatWikidataYear(args.wd_entity, 'birth') local wikisourceBirthyear = formatWikisourceYear(args.birthyear, 'birth') if args.birthyear then -- For Wikisource-supplied birth dates. birthyear = wikisourceBirthyear addCategory('Authors with override birth dates') if args.wd_entity and wikisourceBirthyear ~= wikidataBirthyear then addCategory('Authors with birth dates differing from Wikidata') end if tonumber(birthyear) then addCategory(dateModule.era(birthyear) .. ' authors') end else birthyear = wikidataBirthyear end if not birthyear then addCategory('Authors with missing birth dates') end -- Work period local startYear = formatWikidataYear(args.wd_entity, "workperiodstart") local endYear = formatWikidataYear(args.wd_entity, "workperiodend") local workPeriodYears if startYear or endYear then if not startYear then startYear = '?' end if not endYear then endYear = '?' end workPeriodYears = "fl. " .. startYear .. "–" .. endYear else workPeriodYears = nil end -- Put all the output together, including manual override of the dates. local dates = '' if args.dates then -- The parentheses are repeated here and in getFormattedDates() addCategory('Authors with override dates') dates = '<br />(' .. args.dates .. ')' else dates = getFormattedDates(birthyear, deathyear, workPeriodYears) end if dates then outHtml:wikitext(dates) return tostring(outHtml) end return nil end --[=[ Match claims to configured categories. Utility function for constructCategories. Modifies the provided table to add categories configured in /data. ]=] local function addCategoriesFromClaims(entity, pId, knownCategories) -- Abort if the provided category mappings are missing or undefined if not knownCategories then error('Category mappings are not defined. Check [[Module:Author/data]].') end -- Get statements for the property provided (ignore deprecated statements) local statements = entity:getBestStatements(pId) -- Get the category for each statement's value if a mapping exists for _, v in pairs(statements) do -- Sometimes the property exists on the item but has no value, -- or it has an unknown value, -- so in the output from mw.wikibase.getEntity() -- .mainsnak's .datavalue will be nil. if v.mainsnak.snaktype == 'value' then local valueId = v.mainsnak.datavalue.value.id -- Add the category if we have a mapping for this statement local knownCat = knownCategories[valueId] if knownCat then addCategory(knownCat) end end end end --[=[ Get categories for nationality, occupations, etc. Returns categories as a string of wikicode ]=] local function constructCategories(entity) if not entity then return nil end -- Load the property to category mappings local DATA = mw.loadData('Module:Author/data') -- Add categories from properties for which we have a configured mapping addCategoriesFromClaims(entity, wd_properties['nationalities'], DATA.categories.nationalities) addCategoriesFromClaims(entity, wd_properties['occupations'], DATA.categories.occupations) addCategoriesFromClaims(entity, wd_properties['religions'], DATA.categories.religions) addCategoriesFromClaims(entity, wd_properties['movements'], DATA.categories.movements) addCategoriesFromClaims(entity, wd_properties['ideologies'], DATA.categories.ideologies) addCategoriesFromClaims(entity, wd_properties['employer'], DATA.categories.employer) addCategoriesFromClaims(entity, wd_properties['positionheld'], DATA.categories.positionheld) addCategoriesFromClaims(entity, wd_properties['awardreceived'], DATA.categories.awardreceived) addCategoriesFromClaims(entity, wd_properties['memberof'], DATA.categories.memberof) addCategoriesFromClaims(entity, wd_properties['canonizationstatus'], DATA.categories.canonizationstatus) addCategoriesFromClaims(entity, wd_properties['contributedto'], DATA.categories.contributedto) addCategoriesFromClaims(entity, wd_properties['socialclassification'], DATA.categories.socialclassification) addCategoriesFromClaims(entity, wd_properties['instrument'], DATA.categories.instrument) addCategoriesFromClaims(entity, wd_properties['describedby'], DATA.categories.describedby) addCategoriesFromClaims(entity, wd_properties['mannerofdeath'], DATA.categories.mannerofdeath) end -------------------------------------------------------------------------------- -- Output link and category for initial letters of family name. -- local function lastInitial(args) -- Handle special override if not args.use_initials then return nil end -- Allow manual override of initials. local initials = args.last_initial -- If a lastname is provided, get the initials from that. if not initials and args.lastname then initials = mw.ustring.sub(args.lastname, 1, 2) end -- Fetch from Wikidata. if not initials then local item = args.wd_entity if item then -- Get the first family name statement. local familyNames = item:getBestStatements(wd_properties['familyname']) if #familyNames > 0 then local familyNameId = familyNames[1].mainsnak.datavalue.value.id local familyName = mw.wikibase.getEntity(familyNameId) if familyName.labels and familyName.labels.en then -- Take the first two characters of the English label -- (this avoids issues with 'native label P1705' and is fine for English Wikisource). initials = mw.ustring.sub(familyName.labels.en.value, 1, 2) end end end end -- Put it all together and output local out if initials then out = '[[Wikisource:Authors-' .. initials .. '|Author Index: ' .. initials .. ']]' local authorCategory = mw.title.new('Authors-' .. initials, 'Category') addCategory(authorCategory.text) if authorCategory.exists ~= true then addCategory('Author pages with missing initials category') end else addCategory('Authors without initials') out = '[[:Category:Authors without initials|Authors without initials]]' end return out end -------------------------------------------------------------------------------- -- Header assembly local function ucfirst(s) return string.sub(s, 1, 1) .. string.sub(s, 2) end local function gender_from_wd(wd_entity) if not wd_entity then return nil end local statements = wd_entity:getBestStatements(wd_properties['gender']) if #statements == 0 then return nil end local genders = {} for _, statement in pairs(statements) do local snak = statement.mainsnak if snak.snaktype ~= 'value' or not snak or snak.datatype ~= 'wikibase-item' or not snak.datavalue or not snak.datavalue.value or not snak.datavalue.value.id then break end local gender_item = mw.wikibase.getEntity(snak.datavalue.value.id) if not gender_item or not gender_item.labels or not gender_item.labels.en or not gender_item.labels.en.value then break end table.insert(genders, gender_item.labels.en.value) end return genders[1] end local function image_from_wd(wd_entity, prefer_logo) if not wd_entity then return {} end local ordered_properties = {wd_properties['image'], wd_properties['flag_image'], wd_properties['logo_image']} if prefer_logo then ordered_properties = {wd_properties['flag_image'], wd_properties['logo_image'], wd_properties['image']} end local statements = {} for i, prop in ipairs(ordered_properties) do if #statements == 0 then statements = wd_entity:getBestStatements(prop) end end if #statements == 0 then return {} end local images = {} --[=[ local langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) langcode = (mw.language.isKnownLanguageTag(langcode) and langcode) or mw.language.getContentLanguage().code local base_langcode = mw.text.split(langcode, '-', true)[1] local langcode_fallbacks_ordered = {base_langcode} for i, lang in ipairs(mw.language.getFallbacksFor(base_langcode)) do table.insert(langcode_fallbacks_ordered, lang) end if base_langcode ~= langcode then table.insert(langcode_fallbacks_ordered, 2, langcode) for i, lang in ipairs(mw.language.getFallbacksFor(langcode)) do table.insert(langcode_fallbacks_ordered, lang) end end local langcode_fallbacks = {} for i, v in ipairs(langcode_fallbacks_ordered) do langcode_fallbacks[v] = i end ]=] local langcode_fallbacks = {[mw.language.getContentLanguage().code] = 1} for _, statement in pairs(statements) do local image = statement.mainsnak.datatype == 'commonsMedia' and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value local captions = {} local legends = statement['qualifiers'] and statement['qualifiers'][wd_properties['medialegend']] if legends then for i, legend in ipairs(legends) do if legend.datatype == 'monolingualtext' and legend.datavalue and legend.datavalue.value and legend.datavalue.value.text and legend.datavalue.value.language then local legend_langcode = legend.datavalue.value.language local legend_base_langcode = mw.text.split(legend_langcode, '-', true)[1] local legend_text = legend.datavalue.value.text if langcode_fallbacks[legend_langcode] then captions[langcode_fallbacks[legend_langcode]] = legend_text elseif langcode_fallbacks[legend_base_langcode] then captions[langcode_fallbacks[legend_base_langcode]] = captions[langcode_fallbacks[legend_base_langcode]] or legend_text end end end captions = TableTools.compressSparseArray(captions) end if image then table.insert(images, {image = image, image_caption = captions[1]}) end end return images[1] or {} end function p.image_from_wd(wd_entity, prefer_logo) return image_from_wd(wd_entity, prefer_logo) end local function get_image(args) local image = args.image local wd_image_info = image_from_wd(args.wd_entity, args.prefer_logo) local template_ns = args.template_ns or 'Author' if image then addCategory(template_ns .. ' pages with image') else image = wd_image_info.image if image then addCategory(template_ns .. ' pages with Wikidata image') else addCategory(template_ns .. ' pages without image') end end local image_display = '' if image then local upright = (yesno(args.upright) and '|upright=0.6') or '' args.image_caption = args.image_caption or wd_image_info.image_caption or args.name_text local caption_div = (args.image_caption and tostring(mw.html.create('div'):css({['text-align'] = 'center'}):wikitext(args.image_caption))) or '' image_display = '[[File:' .. image .. '|thumb' .. upright .. '|' .. caption_div .. '|alt=' .. (args.image_alt or '') .. ']]' end return image_display end local function construct_defaultsort(args) local defaultsort = args.defaultsort if not defaultsort then if args.firstname and args.lastname then defaultsort = ucfirst(args.lastname .. ', ' .. args.firstname) elseif args.firstname or args.lastname then defaultsort = ucfirst((args.lastname or '') .. (args.firstname or '')) end end if defaultsort then return mw.getCurrentFrame():callParserFunction('DEFAULTSORT', {defaultsort}) end return '' end local function author(args) args = normalize_args(args) -- Always tell Header structure that we're {{author}} -- TODO: Is there a use case for letting our clients set this? args.template = 'author' local current_title = mw.title.getCurrentTitle() local firstname = args.firstname local lastname = args.lastname local last_initial = args.last_initial if firstname then firstname = preprocess(firstname) end if lastname then lastname = preprocess(lastname) end if last_initial then last_initial = preprocess(last_initial) end args.header_class = 'wst-author ws-header' -- main block args.main_class = 'authortemplate' args.previous = lastInitial(args) if firstname and lastname then if yesno(args.invert_names) then args.name_text = lastname .. ' ' .. firstname else args.name_text = firstname .. ' ' .. lastname end else args.name_text = firstname or lastname end local name_text_span = '' if args.name_text then name_text_span = tostring(mw.html.create('span'):css({['font-weight'] = 'bold'}):wikitext(args.name_text)) end local dates_text = '' if not yesno(args.disambiguation) then dates_text = dates(args) or '' end args.main_title = name_text_span .. dates_text -- notes block args.notes_class = 'author_notes' args.commonscat = args.commonscat or ( args.wd_entity and args.wd_entity.claims and args.wd_entity.claims.P373 and args.wd_entity.claims.P373[1] and args.wd_entity.claims.P373[1].mainsnak and args.wd_entity.claims.P373[1].mainsnak.datatype == 'string' and args.wd_entity.claims.P373[1].mainsnak.datavalue and args.wd_entity.claims.P373[1].mainsnak.datavalue.value ) args.notes = args.description -- image local image_display = get_image(args) -- defaultsort args.defaultsort = args.defaultsort or args.sortkey local defaultsort_magicword = construct_defaultsort(args) -- categories if not args.categories then -- Author index category if last_initial then addCategory('Authors-' .. last_initial) elseif not last_initial then addCategory('Authors without initials') end -- Categorisation of author pages by gender, based on Wikidata sex or gender Property (P21) -- The main are: male (Q6581097), female (Q6581072), transgender female (Q1052281), transgender male (Q2449503) if args.wd_entity then local gender = gender_from_wd(args.wd_entity) if gender == 'transgender female' or gender == 'female' then addCategory('Women authors') addCategory('Author pages with gender in Wikidata') elseif gender == 'transgender male' or gender == 'male' then addCategory('Male authors') addCategory('Author pages with gender in Wikidata') elseif gender then addCategory('Author pages with unknown gender in Wikidata') else addCategory('Author pages with no gender in Wikidata') end if gender == 'transgender female' or gender == 'transgender male' then addCategory('Transgender and transsexual authors') end else addCategory('Author pages with gender manually categorised') end constructCategories(args.wd_entity) -- Categorisation of author pages with interwiki links (used for maintenance view only, links come from WD) if args.wikipedia then addCategory('Author pages linking to Wikipedia') end if args.wikiquote then addCategory('Author pages linking to Wikiquote') end if args.commons then addCategory('Author pages linking to Wikimedia Commons') end if args.commonscat then addCategory('Author pages linking to Wikimedia Commons categories') end -- Whether page is connected to Wikidata if (args.namespace or current_title.nsText) == 'Author' then if args.wd_entity then addCategory('Author pages connected to Wikidata') else addCategory('Author pages not connected to Wikidata') end end end -- microformat local microformat = mw.html.create('div') :attr('id', 'ws-data') :addClass('vcard ws-noexport') :css({['display'] = 'none', ['speak'] = 'none'}) local microformat_wikitext = { tostring(mw.html.create('span'):attr('id', 'ws-article-id'):wikitext(current_title.id)) } if args.wd_entity then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'wd-article-id') :wikitext(args.wd_entity.id) ) ) end if args.name_text then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-name') :addClass('fn') :wikitext(args.name_text) ) ) table.insert( microformat_wikitext, tostring(mw.html.create('span') :addClass('n') :wikitext(table.concat({ tostring(mw.html.create('span'):addClass('given-name'):wikitext(firstname or '')), tostring(mw.html.create('span'):addClass('family-name'):wikitext(lastname or '')) })) ) ) end if args.defaultsort then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-key'):wikitext(args.defaultsort))) end if args.image then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-image'):wikitext(args.image))) end if args.birthyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-birthdate') :addClass('bday') :wikitext(date({['year_type'] = 'birth', ['year'] = args.birthyear})) ) ) end if args.deathyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-deathdate') :addClass('dday') :wikitext(date({['year_type'] = 'death', ['year'] = args.deathyear})) ) ) end if args.wikipedia then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikipedia'):wikitext(args.wikipedia))) end if args.wikiquote then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikiquote'):wikitext(args.wikiquote))) end if args.commonscat then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext(args.commonscat))) elseif args.commons then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext('Category' .. args.commons))) end if args.description then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-description'):addClass('note'):wikitext(args.description))) end microformat:wikitext(table.concat(microformat_wikitext)) -- assemble local cats = '' if not args.nocat then cats = (args.categories or '') .. getCategories() end args.post_notes = image_display .. defaultsort_magicword .. cats .. tostring(microformat) args.wikidataswitch = true return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Template:Author/styles.css'}) .. construct_header(args) end -- for testing function p._getCategories(args) args = normalize_args(args) p._author(args) return getCategories() end function p.getCategories(frame) return p._getCategories(getArgs(frame)) end function p._date(args) args = normalize_args(args) args.year_type = args.year_type or args['type'] or 'birth' return date(args) end function p.date(frame) return p._date(getArgs(frame)) end function p._lastInitial(args) args = normalize_args(args) return lastInitial(args) end function p.lastInitial(frame) return p._lastInitial(getArgs(frame)) end -- Debugging 1: mw.log(p._lastInitial({last_initial = 'Qx'})) -- Debugging 2: mw.log(p._lastInitial({wikidata = 'Q1107985'})) -- Debugging 1: mw.log(p._lastInitial({lastname = 'Qqxxx'})) -- Debugging 3: mw.log(p._lastInitial({last_initial = 'Qx', wikidata_id='Q1107985'})) -- used by [[Module:Person]] function p._dates(args) args = normalize_args(args) return dates(args) end function p.dates(frame) return p._dates(getArgs(frame)) end function p._get_image(args) args = normalize_args(args) if args.nocat then return get_image(args) else return get_image(args) .. getCategories() end end function p.get_image(frame) return p._get_image(getArgs(frame)) end function p._construct_defaultsort(args) args = normalize_args(args) return construct_defaultsort(args) end function p.construct_defaultsort(frame) return p._construct_defaultsort(getArgs(frame)) end -- Used by [[Module:Disambiguation]] and [[Template:Author]] function p._author(args) return author(args) end function p.author(frame) return p._author(getArgs(frame)) end return p 345ekbjn0qby75uhcq83aue5p236iho 9647 9638 2026-06-25T03:04:29Z Sauit 2200 9647 Scribunto text/plain require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args) return mw.getCurrentFrame():preprocess(args) end local wd_properties = { birth = 'P569', death = 'P570', workperiodstart = 'P2031', workperiodend = 'P2032', floruit = 'P1317', familyname = 'P734', gender = 'P21', instanceof = 'P31', medialegend = 'P2096', image = 'P18', flag_image = 'P41', logo_image = 'P154', nationalities = 'P27', occupations = 'P106', religions = 'P140', movements = 'P135', ideologies = 'P1142', employer = 'P108', positionheld = 'P39', awardreceived = 'P166', memberof = 'P463', canonizationstatus = 'P411', contributedto = 'P3919', socialclassification = 'P3716', instrument = 'P1303', describedby = 'P1343', mannerofdeath = 'P1196' } -------------------------------------------------------------------------------- -- Add a category to the current list of categories. Do not include the Category prefix. local function addCategory(category) table.insert(categories, category) end -------------------------------------------------------------------------------- -- Remove a category. Do not include the Category prefix. local function removeCategory(category) for catPos, cat in pairs(categories) do if cat == category then table.remove(categories, catPos) end end end -------------------------------------------------------------------------------- -- Get wikitext for all categories added using addCategory. local function getCategories() categories = TableTools.removeDuplicates(categories) table.sort(categories) local out = '' for _, cat in pairs(categories) do out = out .. '[[Category:' .. cat .. ']]' end return out end local function normalize_args(args) -- aliases local dup_cat = '' local oldKeys = {} local newArgs = {} for k, v in pairs(args) do local newkey = string.lower(string.gsub(string.gsub(tostring(k), '-', '_'), ' ', '_')) if newkey ~= tostring(k) then if args[newkey] then addCategory('Pages using duplicate arguments in template calls') end newArgs[newkey] = newArgs[newkey] or v table.insert(oldKeys, tostring(k)) end end for k, v in pairs(newArgs) do args[k] = v end for k, v in pairs(oldKeys) do args[v] = nil end args.wikidata = args.wikidata or args.wikidata_id args.wikidata_id = nil -- Fetch entity object for Wikidata item connected to the current page -- Let manually-specified Wikidata ID override if given and valid if args.wikidata and mw.wikibase.isValidEntityId(args.wikidata) then args.wd_entity = mw.wikibase.getEntity(args.wikidata) else args.wd_entity = mw.wikibase.getEntity() end args.use_initials = yesno(args.use_initials) ~= false and args.last_initial ~= '!NO_INITIALS' args.nocat = yesno(args.nocat) or false return args end -------------------------------------------------------------------------------- -- Get the actual parentheses-enclosed HTML string that shows the dates. local function getFormattedDates(birthyear, deathyear, workPeriodYears) if not birthyear and not deathyear and not workPeriodYears then return nil end local dates = '<br />(' local birthNotFloruit = birthyear and not birthyear:match("^fl%.") local deathNotFloruit = deathyear and not deathyear:match("^fl%.") if (birthNotFloruit and birthyear ~= '?') or (deathNotFloruit and deathyear ~= '?') or not workPeriodYears then removeCategory('Authors with approximate workperiodend dates') removeCategory('Authors with approximate workperiodstart dates') if birthyear then if birthNotFloruit and deathyear and not deathNotFloruit then dates = dates .. "b. " end dates = dates .. birthyear end if (birthyear or deathyear) and birthyear ~= deathyear then -- Add spaces if there are spaces in either of the dates. local spaces = '' if string.match((birthyear or '') .. (deathyear or ''), ' ') then spaces = ' ' end dates = dates .. spaces .. '–' .. spaces end if deathyear and birthyear ~= deathyear then if deathNotFloruit and birthyear and not birthNotFloruit then dates = dates .. "d. " end dates = dates .. deathyear end else dates = dates .. workPeriodYears addCategory('Authors with floruit dates') end if birthyear or deathyear or workPeriodYears then dates = dates .. ')' end return dates end -------------------------------------------------------------------------------- -- Take a statement of a given property and make a human-readable year string -- out of it, adding the relevant categories as we go. -- @param table statement The statement. -- @param string type One of 'birth' or 'death'. local function getYearStringFromSingleStatement(statement, year_type) local snak = statement.mainsnak -- We're not using mw.wikibase.formatValue because we only want years. -- No value. This is invalid for birth dates (should be 'somevalue' -- instead), and indicates 'still alive' for death dates. if snak.snaktype == 'novalue' and year_type == 'birth' then addCategory('Authors with missing birth dates') return nil end if snak.snaktype == 'novalue' and year_type == 'death' then addCategory('Living authors') return nil end -- Unknown value. if snak.snaktype == 'somevalue' then addCategory('Authors with unknown ' .. year_type .. ' dates') return '?' end -- Extract year from the time value. local _, _, extractedYear = string.find(snak.datavalue.value.time, '([%+%-]%d%d%d+)%-') local year = math.abs(tonumber(extractedYear)) addCategory(dateModule.era(extractedYear) .. ' authors') -- Century & millennium precision. if snak.datavalue.value.precision == 6 or snak.datavalue.value.precision == 7 then local ceilfactor = 100 local precisionName = 'century' if snak.datavalue.value.precision == 6 then ceilfactor = 1000 precisionName = 'millennium' end local cent = math.max(math.ceil(year/ceilfactor), 1) local suffixed_cent = ordinal(cent, false, false) year = suffixed_cent .. ' ' .. precisionName addCategory('Authors with approximate ' .. year_type .. ' dates') elseif snak.datavalue.value.precision == 8 then -- decade precision year = math.floor(tonumber(year)/10) * 10 .. 's' addCategory('Authors with approximate ' .. year_type .. ' dates') end if tonumber(extractedYear) < 0 then year = year .. ' BCE' end -- Remove from 'Living authors' if that's not possible. if tonumber(extractedYear) < tonumber(os.date('%Y') - 110) then removeCategory('Living authors') end -- Add to e.g. 'YYYY births' category (before we add 'c.' or 'fl.' prefixes). if year_type == 'birth' or year_type == 'death' then -- mw.logObject('Wikidata cat') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end -- Extract circa (P1480 = sourcing circumstances, Q5727902 = circa) if statement.qualifiers and statement.qualifiers.P1480 then for _,qualifier in pairs(statement.qualifiers.P1480) do if qualifier.datavalue and qualifier.datavalue.value.id == 'Q5727902' then addCategory('Authors with approximate ' .. year_type .. ' dates') year = 'c. ' .. year end end end -- Add floruit abbreviation. if year_type == 'floruit' then year = 'fl. ' .. year end return year end -------------------------------------------------------------------------------- -- Get a given or family name property. -- This concatenates (with spaces) all statements of the given property in order of the series ordinal (P1545) qualifier. -- @TODO fix this. local function getNameFromWikidata(item, property) local statements = item:getBestStatements(property) local out = {} if statements[1] and statements[1].mainsnak.datavalue then local itemId = statements[1].mainsnak.datavalue.value.id table.insert(out, mw.wikibase.label(itemId) or '') end return table.concat(out, ' ') end -------------------------------------------------------------------------------- local function getPropertyValue(item, property) local statements = item:getBestStatements(property) if statements[1] and statements[1].mainsnak.datavalue then return statements[1].mainsnak.datavalue.value end end -------------------------------------------------------------------------------- -- The 'Wikisource' format for a birth or death year is as follows: -- "?" or empty for unknown (or still alive) -- Use BCE for years before year 1 -- Approximate dates: -- Decades or centuries: "1930s" or "20th century" -- Circa: "c/1930" or "c. 1930" or "ca 1930" or "circa 1930" -- Tenuous year: "1932/?" -- Choice of two or more years: "1932/1933" -- This is a slightly overly-complicated function, but one day will be able to be deleted. -- @param string type Either 'birth' or 'death' -- @return string The year to display local function formatWikisourceYear(year, year_type) if not year then return nil end -- mw.logObject('formatWikisourceYear') local yearParts = mw.text.split(year, '/', true) -- mw.logObject('yearParts') -- mw.logObject(yearParts) -- Ends in a question mark. if yearParts[2] == '?' then addCategory('Authors with unknown ' .. year_type .. ' dates') if tonumber(yearParts[1]) then -- mw.logObject('unknown') -- mw.logObject(yearParts[1] .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearParts[1]) .. ' authors') addCategory(yearParts[1] .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return yearParts[1] .. '?' end -- Starts with one of the 'circa' abbreviations local circaNames = {'ca.', 'c.', 'ca', 'c', 'circa'} for _, circaName in pairs(circaNames) do local yearNumber local isCirca = false if yearParts[1] == circaName then yearNumber = mw.text.trim(yearParts[2]) isCirca = true elseif string.match(yearParts[1], '^' .. circaName) then yearNumber = string.gsub(yearParts[1], '^' .. circaName, '') isCirca = (tonumber(yearNumber) ~= nil) end if isCirca then addCategory('Authors with approximate ' .. year_type .. ' dates') if tonumber(yearNumber) then yearNumber = tonumber(yearNumber) -- mw.logObject(yearNumber) addCategory(dateModule.era(tostring(yearNumber)) .. ' authors') addCategory(yearNumber .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return 'c. ' .. yearNumber end end -- If there is more than one year part, and they're all numbers, add categories. local allPartsAreNumeric = true if #yearParts > 1 then for _, yearPart in pairs(yearParts) do if tonumber(yearPart) then -- mw.logObject('numeric') -- mw.logObject(yearPart .. ' ' .. year_type .. 's') addCategory(yearPart .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearPart) .. ' authors') else allPartsAreNumeric = false end end if allPartsAreNumeric then addCategory('Authors with approximate birth dates') end elseif #yearParts == 1 and not tonumber(year) then allPartsAreNumeric = false end -- Otherwise, just use whatever's been given if not allPartsAreNumeric then addCategory('Authors with non-numeric ' .. year_type .. ' dates') end if #yearParts == 1 or allPartsAreNumeric == false then -- mw.logObject('not numeric') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end return year end --[=[ Get a formatted year of the given property and add to the relevant categories ]=] local function formatWikidataYear(item, year_type) -- Check sanity of inputs if not item or not year_type or not wd_properties[year_type] then return nil end local property = wd_properties[year_type] -- Get this property's statements. local statements = item:getBestStatements(property) if #statements == 0 then -- If there are no statements of this type, add to 'missing' category. if year_type == 'birth' or year_type == 'death' then addCategory('Authors with missing ' .. year_type .. ' dates') end local isHuman = item:formatPropertyValues(wd_properties['instanceof']).value == 'human' if year_type == 'death' and isHuman then -- If no statements about death, assume to be alive. addCategory('Living authors') end end -- Compile a list of years, one from each statement. local years = {} for _, statement in pairs(statements) do local year = getYearStringFromSingleStatement(statement, year_type) if year then table.insert(years, year) end end years = TableTools.removeDuplicates(years) -- If no year found yet, try for a floruit date. Make an exception for workperiod if (#years == 0 or table.concat(years, '/') == '?') and year_type ~= "workperiodstart" and year_type ~= "workperiodend" then local floruitStatements = item:getBestStatements(wd_properties["floruit"]) for _, statement in pairs(floruitStatements) do -- If all we've got so far is 'unknown', replace it. if table.concat(years, '/') == '?' then years = {} end addCategory('Authors with floruit dates') local year = getYearStringFromSingleStatement(statement, 'floruit') if year then table.insert(years, year) end end end years = TableTools.removeDuplicates(years) if #years == 0 then return nil end return table.concat(years, '/') end -------------------------------------------------------------------------------- -- Get a single formatted date, with no categories. -- args.year, args.year_type, args.wd_entity local function date(args) if args.year then return formatWikisourceYear(args.year, args.year_type) else return formatWikidataYear(args.wd_entity, args.year_type) end end -------------------------------------------------------------------------------- -- Get a formatted string of the years that this author lived, -- and categorise in the appropriate categories. -- The returned string starts with a line break (<br />). local function dates(args) local outHtml = mw.html.create() -------------------------------------------------------------------------------- -- Check a given title as having the appropriate dates as a disambiguating suffix. local function checkTitleDatesAgainstWikidata(title, wikidata) -- All disambiguated author pages have parentheses in their titles. local titleHasParentheses = string.find(tostring(title), '%d%)') if not titleHasParentheses then return end -- The title should end with years in the same format as is used in the page header -- but with a normal hyphen instead of an en-dash. local dates = '(' .. (date({year_type = 'birth', wd_entity = args.wd_entity}) or '') .. '-' .. (date({year_type = 'death', wd_entity = args.wd_entity}) or '') .. ')' if string.sub(tostring(title), -string.len(dates)) ~= dates then addCategory('Authors with title-date mismatches') end end -- Check disambiguated page titles for accuracy. checkTitleDatesAgainstWikidata(args.pagetitle or mw.title.getCurrentTitle(), args.wikidata) -- Get the dates (do death first, so birth can override categories if required): -- Death local deathyear local wikidataDeathyear = formatWikidataYear(args.wd_entity, 'death') local wikisourceDeathyear = formatWikisourceYear(args.deathyear, 'death') if args.deathyear then -- For Wikisource-supplied death dates. deathyear = wikisourceDeathyear addCategory('Authors with override death dates') if args.wd_entity and wikisourceDeathyear ~= wikidataDeathyear then addCategory('Authors with death dates differing from Wikidata') end if tonumber(deathyear) then addCategory(dateModule.era(deathyear) .. ' authors') end else deathyear = wikidataDeathyear end if not deathyear then addCategory('Authors with missing death dates') end -- Birth local birthyear local wikidataBirthyear = formatWikidataYear(args.wd_entity, 'birth') local wikisourceBirthyear = formatWikisourceYear(args.birthyear, 'birth') if args.birthyear then -- For Wikisource-supplied birth dates. birthyear = wikisourceBirthyear addCategory('Authors with override birth dates') if args.wd_entity and wikisourceBirthyear ~= wikidataBirthyear then addCategory('Authors with birth dates differing from Wikidata') end if tonumber(birthyear) then addCategory(dateModule.era(birthyear) .. ' authors') end else birthyear = wikidataBirthyear end if not birthyear then addCategory('Authors with missing birth dates') end -- Work period local startYear = formatWikidataYear(args.wd_entity, "workperiodstart") local endYear = formatWikidataYear(args.wd_entity, "workperiodend") local workPeriodYears if startYear or endYear then if not startYear then startYear = '?' end if not endYear then endYear = '?' end workPeriodYears = "fl. " .. startYear .. "–" .. endYear else workPeriodYears = nil end -- Put all the output together, including manual override of the dates. local dates = '' if args.dates then -- The parentheses are repeated here and in getFormattedDates() addCategory('Authors with override dates') dates = '<br />(' .. args.dates .. ')' else dates = getFormattedDates(birthyear, deathyear, workPeriodYears) end if dates then outHtml:wikitext(dates) return tostring(outHtml) end return nil end --[=[ Match claims to configured categories. Utility function for constructCategories. Modifies the provided table to add categories configured in /data. ]=] local function addCategoriesFromClaims(entity, pId, knownCategories) -- Abort if the provided category mappings are missing or undefined if not knownCategories then error('Category mappings are not defined. Check [[Module:Author/data]].') end -- Get statements for the property provided (ignore deprecated statements) local statements = entity:getBestStatements(pId) -- Get the category for each statement's value if a mapping exists for _, v in pairs(statements) do -- Sometimes the property exists on the item but has no value, -- or it has an unknown value, -- so in the output from mw.wikibase.getEntity() -- .mainsnak's .datavalue will be nil. if v.mainsnak.snaktype == 'value' then local valueId = v.mainsnak.datavalue.value.id -- Add the category if we have a mapping for this statement local knownCat = knownCategories[valueId] if knownCat then addCategory(knownCat) end end end end --[=[ Get categories for nationality, occupations, etc. Returns categories as a string of wikicode ]=] local function constructCategories(entity) if not entity then return nil end -- Load the property to category mappings local DATA = mw.loadData('Module:Author/data') -- Add categories from properties for which we have a configured mapping addCategoriesFromClaims(entity, wd_properties['nationalities'], DATA.categories.nationalities) end -------------------------------------------------------------------------------- -- Output link and category for initial letters of family name. -- local function lastInitial(args) -- Handle special override if not args.use_initials then return nil end -- Allow manual override of initials. local initials = args.last_initial -- If a lastname is provided, get the initials from that. if not initials and args.lastname then initials = mw.ustring.sub(args.lastname, 1, 2) end -- Fetch from Wikidata. if not initials then local item = args.wd_entity if item then -- Get the first family name statement. local familyNames = item:getBestStatements(wd_properties['familyname']) if #familyNames > 0 then local familyNameId = familyNames[1].mainsnak.datavalue.value.id local familyName = mw.wikibase.getEntity(familyNameId) if familyName.labels and familyName.labels.en then -- Take the first two characters of the English label -- (this avoids issues with 'native label P1705' and is fine for English Wikisource). initials = mw.ustring.sub(familyName.labels.en.value, 1, 2) end end end end -- Put it all together and output local out if initials then out = '[[Wikisource:Authors-' .. initials .. '|Author Index: ' .. initials .. ']]' local authorCategory = mw.title.new('Authors-' .. initials, 'Category') addCategory(authorCategory.text) if authorCategory.exists ~= true then addCategory('Author pages with missing initials category') end else addCategory('Authors without initials') out = '[[:Category:Authors without initials|Authors without initials]]' end return out end -------------------------------------------------------------------------------- -- Header assembly local function ucfirst(s) return string.sub(s, 1, 1) .. string.sub(s, 2) end local function gender_from_wd(wd_entity) if not wd_entity then return nil end local statements = wd_entity:getBestStatements(wd_properties['gender']) if #statements == 0 then return nil end local genders = {} for _, statement in pairs(statements) do local snak = statement.mainsnak if snak.snaktype ~= 'value' or not snak or snak.datatype ~= 'wikibase-item' or not snak.datavalue or not snak.datavalue.value or not snak.datavalue.value.id then break end local gender_item = mw.wikibase.getEntity(snak.datavalue.value.id) if not gender_item or not gender_item.labels or not gender_item.labels.en or not gender_item.labels.en.value then break end table.insert(genders, gender_item.labels.en.value) end return genders[1] end local function image_from_wd(wd_entity, prefer_logo) if not wd_entity then return {} end local ordered_properties = {wd_properties['image'], wd_properties['flag_image'], wd_properties['logo_image']} if prefer_logo then ordered_properties = {wd_properties['flag_image'], wd_properties['logo_image'], wd_properties['image']} end local statements = {} for i, prop in ipairs(ordered_properties) do if #statements == 0 then statements = wd_entity:getBestStatements(prop) end end if #statements == 0 then return {} end local images = {} --[=[ local langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) langcode = (mw.language.isKnownLanguageTag(langcode) and langcode) or mw.language.getContentLanguage().code local base_langcode = mw.text.split(langcode, '-', true)[1] local langcode_fallbacks_ordered = {base_langcode} for i, lang in ipairs(mw.language.getFallbacksFor(base_langcode)) do table.insert(langcode_fallbacks_ordered, lang) end if base_langcode ~= langcode then table.insert(langcode_fallbacks_ordered, 2, langcode) for i, lang in ipairs(mw.language.getFallbacksFor(langcode)) do table.insert(langcode_fallbacks_ordered, lang) end end local langcode_fallbacks = {} for i, v in ipairs(langcode_fallbacks_ordered) do langcode_fallbacks[v] = i end ]=] local langcode_fallbacks = {[mw.language.getContentLanguage().code] = 1} for _, statement in pairs(statements) do local image = statement.mainsnak.datatype == 'commonsMedia' and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value local captions = {} local legends = statement['qualifiers'] and statement['qualifiers'][wd_properties['medialegend']] if legends then for i, legend in ipairs(legends) do if legend.datatype == 'monolingualtext' and legend.datavalue and legend.datavalue.value and legend.datavalue.value.text and legend.datavalue.value.language then local legend_langcode = legend.datavalue.value.language local legend_base_langcode = mw.text.split(legend_langcode, '-', true)[1] local legend_text = legend.datavalue.value.text if langcode_fallbacks[legend_langcode] then captions[langcode_fallbacks[legend_langcode]] = legend_text elseif langcode_fallbacks[legend_base_langcode] then captions[langcode_fallbacks[legend_base_langcode]] = captions[langcode_fallbacks[legend_base_langcode]] or legend_text end end end captions = TableTools.compressSparseArray(captions) end if image then table.insert(images, {image = image, image_caption = captions[1]}) end end return images[1] or {} end function p.image_from_wd(wd_entity, prefer_logo) return image_from_wd(wd_entity, prefer_logo) end local function get_image(args) local image = args.image local wd_image_info = image_from_wd(args.wd_entity, args.prefer_logo) local template_ns = args.template_ns or 'Author' if image then addCategory(template_ns .. ' pages with image') else image = wd_image_info.image if image then addCategory(template_ns .. ' pages with Wikidata image') else addCategory(template_ns .. ' pages without image') end end local image_display = '' if image then local upright = (yesno(args.upright) and '|upright=0.6') or '' args.image_caption = args.image_caption or wd_image_info.image_caption or args.name_text local caption_div = (args.image_caption and tostring(mw.html.create('div'):css({['text-align'] = 'center'}):wikitext(args.image_caption))) or '' image_display = '[[File:' .. image .. '|thumb' .. upright .. '|' .. caption_div .. '|alt=' .. (args.image_alt or '') .. ']]' end return image_display end local function construct_defaultsort(args) local defaultsort = args.defaultsort if not defaultsort then if args.firstname and args.lastname then defaultsort = ucfirst(args.lastname .. ', ' .. args.firstname) elseif args.firstname or args.lastname then defaultsort = ucfirst((args.lastname or '') .. (args.firstname or '')) end end if defaultsort then return mw.getCurrentFrame():callParserFunction('DEFAULTSORT', {defaultsort}) end return '' end local function author(args) args = normalize_args(args) -- Always tell Header structure that we're {{author}} -- TODO: Is there a use case for letting our clients set this? args.template = 'author' local current_title = mw.title.getCurrentTitle() local firstname = args.firstname local lastname = args.lastname local last_initial = args.last_initial if firstname then firstname = preprocess(firstname) end if lastname then lastname = preprocess(lastname) end if last_initial then last_initial = preprocess(last_initial) end args.header_class = 'wst-author ws-header' -- main block args.main_class = 'authortemplate' args.previous = lastInitial(args) if firstname and lastname then if yesno(args.invert_names) then args.name_text = lastname .. ' ' .. firstname else args.name_text = firstname .. ' ' .. lastname end else args.name_text = firstname or lastname end local name_text_span = '' if args.name_text then name_text_span = tostring(mw.html.create('span'):css({['font-weight'] = 'bold'}):wikitext(args.name_text)) end local dates_text = '' if not yesno(args.disambiguation) then dates_text = dates(args) or '' end args.main_title = name_text_span .. dates_text -- notes block args.notes_class = 'author_notes' args.commonscat = args.commonscat or ( args.wd_entity and args.wd_entity.claims and args.wd_entity.claims.P373 and args.wd_entity.claims.P373[1] and args.wd_entity.claims.P373[1].mainsnak and args.wd_entity.claims.P373[1].mainsnak.datatype == 'string' and args.wd_entity.claims.P373[1].mainsnak.datavalue and args.wd_entity.claims.P373[1].mainsnak.datavalue.value ) args.notes = args.description -- image local image_display = get_image(args) -- defaultsort args.defaultsort = args.defaultsort or args.sortkey local defaultsort_magicword = construct_defaultsort(args) -- categories if not args.categories then -- Author index category if last_initial then addCategory('Authors-' .. last_initial) elseif not last_initial then addCategory('Authors without initials') end -- Categorisation of author pages by gender, based on Wikidata sex or gender Property (P21) -- The main are: male (Q6581097), female (Q6581072), transgender female (Q1052281), transgender male (Q2449503) if args.wd_entity then local gender = gender_from_wd(args.wd_entity) if gender == 'transgender female' or gender == 'female' then addCategory('Women authors') addCategory('Author pages with gender in Wikidata') elseif gender == 'transgender male' or gender == 'male' then addCategory('Male authors') addCategory('Author pages with gender in Wikidata') elseif gender then addCategory('Author pages with unknown gender in Wikidata') else addCategory('Author pages with no gender in Wikidata') end if gender == 'transgender female' or gender == 'transgender male' then addCategory('Transgender and transsexual authors') end else addCategory('Author pages with gender manually categorised') end constructCategories(args.wd_entity) -- Categorisation of author pages with interwiki links (used for maintenance view only, links come from WD) if args.wikipedia then addCategory('Author pages linking to Wikipedia') end if args.wikiquote then addCategory('Author pages linking to Wikiquote') end if args.commons then addCategory('Author pages linking to Wikimedia Commons') end if args.commonscat then addCategory('Author pages linking to Wikimedia Commons categories') end -- Whether page is connected to Wikidata if (args.namespace or current_title.nsText) == 'Author' then if args.wd_entity then addCategory('Author pages connected to Wikidata') else addCategory('Author pages not connected to Wikidata') end end end -- microformat local microformat = mw.html.create('div') :attr('id', 'ws-data') :addClass('vcard ws-noexport') :css({['display'] = 'none', ['speak'] = 'none'}) local microformat_wikitext = { tostring(mw.html.create('span'):attr('id', 'ws-article-id'):wikitext(current_title.id)) } if args.wd_entity then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'wd-article-id') :wikitext(args.wd_entity.id) ) ) end if args.name_text then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-name') :addClass('fn') :wikitext(args.name_text) ) ) table.insert( microformat_wikitext, tostring(mw.html.create('span') :addClass('n') :wikitext(table.concat({ tostring(mw.html.create('span'):addClass('given-name'):wikitext(firstname or '')), tostring(mw.html.create('span'):addClass('family-name'):wikitext(lastname or '')) })) ) ) end if args.defaultsort then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-key'):wikitext(args.defaultsort))) end if args.image then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-image'):wikitext(args.image))) end if args.birthyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-birthdate') :addClass('bday') :wikitext(date({['year_type'] = 'birth', ['year'] = args.birthyear})) ) ) end if args.deathyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-deathdate') :addClass('dday') :wikitext(date({['year_type'] = 'death', ['year'] = args.deathyear})) ) ) end if args.wikipedia then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikipedia'):wikitext(args.wikipedia))) end if args.wikiquote then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikiquote'):wikitext(args.wikiquote))) end if args.commonscat then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext(args.commonscat))) elseif args.commons then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext('Category' .. args.commons))) end if args.description then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-description'):addClass('note'):wikitext(args.description))) end microformat:wikitext(table.concat(microformat_wikitext)) -- assemble local cats = '' if not args.nocat then cats = (args.categories or '') .. getCategories() end args.post_notes = image_display .. defaultsort_magicword .. cats .. tostring(microformat) args.wikidataswitch = true return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Template:Author/styles.css'}) .. construct_header(args) end -- for testing function p._getCategories(args) args = normalize_args(args) p._author(args) return getCategories() end function p.getCategories(frame) return p._getCategories(getArgs(frame)) end function p._date(args) args = normalize_args(args) args.year_type = args.year_type or args['type'] or 'birth' return date(args) end function p.date(frame) return p._date(getArgs(frame)) end function p._lastInitial(args) args = normalize_args(args) return lastInitial(args) end function p.lastInitial(frame) return p._lastInitial(getArgs(frame)) end -- Debugging 1: mw.log(p._lastInitial({last_initial = 'Qx'})) -- Debugging 2: mw.log(p._lastInitial({wikidata = 'Q1107985'})) -- Debugging 1: mw.log(p._lastInitial({lastname = 'Qqxxx'})) -- Debugging 3: mw.log(p._lastInitial({last_initial = 'Qx', wikidata_id='Q1107985'})) -- used by [[Module:Person]] function p._dates(args) args = normalize_args(args) return dates(args) end function p.dates(frame) return p._dates(getArgs(frame)) end function p._get_image(args) args = normalize_args(args) if args.nocat then return get_image(args) else return get_image(args) .. getCategories() end end function p.get_image(frame) return p._get_image(getArgs(frame)) end function p._construct_defaultsort(args) args = normalize_args(args) return construct_defaultsort(args) end function p.construct_defaultsort(frame) return p._construct_defaultsort(getArgs(frame)) end -- Used by [[Module:Disambiguation]] and [[Template:Author]] function p._author(args) return author(args) end function p.author(frame) return p._author(getArgs(frame)) end return p 9ym8wgisfi9x462xnmll6zjsjr9354k Модуль:Author/doc 828 2494 9639 2026-06-25T02:51:59Z Sauit 2200 "[[Категория:Бикитиэкэ:Модульдар]]" саҥа сирэй оҥоһулунна 9639 wikitext text/x-wiki [[Категория:Бикитиэкэ:Модульдар]] 92yd9acwb4a8fbbxpieefto3kn28ys4 9640 9639 2026-06-25T02:52:43Z Sauit 2200 9640 wikitext text/x-wiki [[Категория:Бикитиэкэ:Модульдар]] Бу [[Халыып:Ааптар|ааптар халыыпка]] аналлаах модуль документацията jllat9nw3hp01ef6a1kct3m3dm8hm6l Модуль:Era 828 2495 9641 2026-06-25T02:54:37Z Sauit 2200 "--[[ Get the name of an era, based on Wikisource's definition. This implements the logic of Template:What era is --]] require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame, { wrappers = { 'Template:What era is', } }) return p.era(args[1]) end function p.era(year) -- Nil years need to trigger bailout before we do anything else. if year == nil then ret..." саҥа сирэй оҥоһулунна 9641 Scribunto text/plain --[[ Get the name of an era, based on Wikisource's definition. This implements the logic of Template:What era is --]] require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame, { wrappers = { 'Template:What era is', } }) return p.era(args[1]) end function p.era(year) -- Nil years need to trigger bailout before we do anything else. if year == nil then return 'Unknown era' end --[[ The template (What era is) treated every year that failed to parse as "Ancient", and years given as "BCE" fell into this category. With the module logic this no loonger works, so we need to treat BCE years as negative instead, so the numeric logic can deal wiith them. --]] if mw.ustring.match(year, ' BCE$') ~= nil then year = mw.ustring.gsub(year, ' BCE$', '') -- Strip the "BCE" year = '-' .. year -- And prepend a minus (we tonumber() it later) end -- Unknown value. if tonumber(year) == nil or mw.ustring.lower(year) == 'unknown' or year == '?' then return 'Unknown era' end -- Handle numeric years. year = tonumber(year) local today = tonumber(os.date('%Y')) if year <= 600 then return 'Античность' elseif year <= 1420 then return 'Орто үйэлэр' elseif year <= 1630 then return 'Ренессанс' elseif year <= 1900 then return 'Саҥа кэм' elseif year <= today then return 'Аныгы' else return 'Кэлэр кэм' end end return rnq2tv85bkaanyuiamc9zv5r6ozdeym 9642 9641 2026-06-25T02:54:57Z Sauit 2200 9642 Scribunto text/plain --[[ Get the name of an era, based on Wikisource's definition. This implements the logic of Template:What era is --]] require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame, { wrappers = { 'Template:What era is', } }) return p.era(args[1]) end function p.era(year) -- Nil years need to trigger bailout before we do anything else. if year == nil then return 'Биллибэт' end --[[ The template (What era is) treated every year that failed to parse as "Ancient", and years given as "BCE" fell into this category. With the module logic this no loonger works, so we need to treat BCE years as negative instead, so the numeric logic can deal wiith them. --]] if mw.ustring.match(year, ' BCE$') ~= nil then year = mw.ustring.gsub(year, ' BCE$', '') -- Strip the "BCE" year = '-' .. year -- And prepend a minus (we tonumber() it later) end -- Unknown value. if tonumber(year) == nil or mw.ustring.lower(year) == 'unknown' or year == '?' then return 'Unknown era' end -- Handle numeric years. year = tonumber(year) local today = tonumber(os.date('%Y')) if year <= 600 then return 'Античность' elseif year <= 1420 then return 'Орто үйэлэр' elseif year <= 1630 then return 'Ренессанс' elseif year <= 1900 then return 'Саҥа кэм' elseif year <= today then return 'Аныгы' else return 'Кэлэр кэм' end end return hk6pov931e0gv7yv8zxqfa0m6p2cbf4 Халыып:What era is 10 2496 9643 2026-06-25T02:55:54Z Sauit 2200 "{{#invoke:Era|main}}<noinclude> {{documentation}}[[Категория:Халыыптар:Кэм]] </noinclude>" саҥа сирэй оҥоһулунна 9643 wikitext text/x-wiki {{#invoke:Era|main}}<noinclude> {{documentation}}[[Категория:Халыыптар:Кэм]] </noinclude> kiux3quz8j7r5hrli5nojfpxyogkorv Модуль:Ordinal 828 2497 9644 2026-06-25T02:59:15Z Sauit 2200 "--[[ This template will add the appropriate ordinal suffix to a given integer. Please do not modify this code without applying the changes first at Module:Ordinal/sandbox and testing. ]] local p = {} local yesno = require('Module:Yesno') -- boolean value interpretation --[[ This function converts an integer value into a numeral followed by ordinal indicator. The output string might contain HTML tags. Usage: {{#invoke:Ordinal|ordina..." саҥа сирэй оҥоһулунна 9644 Scribunto text/plain --[[ This template will add the appropriate ordinal suffix to a given integer. Please do not modify this code without applying the changes first at Module:Ordinal/sandbox and testing. ]] local p = {} local yesno = require('Module:Yesno') -- boolean value interpretation --[[ This function converts an integer value into a numeral followed by ordinal indicator. The output string might contain HTML tags. Usage: {{#invoke:Ordinal|ordinal|1=|2=|sup=}} {{#invoke:Ordinal|ordinal}} - uses the caller's parameters Parameters 1: Any number or string. 2: Set to "d" if the module should display "d" instead of "nd" and "rd". sup: Set to yes/no to toggle superscript ordinal suffix. ]] function p.ordinal(frame) local args = frame.args if args[1] == nil then args = frame:getParent().args end if args[1] == nil then args[1] = "{{{1}}}" end return p._ordinal(args[1], (args[2] == 'd'), yesno(args.sup)) end function p._ordinal(n, d, sup) local x = tonumber(mw.ustring.match(n, "(%d*)%W*$")) local suffix = "-с" -- If tonumber(n) worked: if sup then suffix = "<sup>" .. suffix .. "</sup>" end return n .. suffix end return p l8alx4rj1ukyqb70z9ggw0oxshwd7ny Модуль:Author/data 828 2498 9645 2026-06-25T03:01:16Z Sauit 2200 "return { }" саҥа сирэй оҥоһулунна 9645 Scribunto text/plain return { } 902rac2jbx6q4ghmlz4kd8f4aoo7nh4 9646 9645 2026-06-25T03:02:32Z Sauit 2200 9646 Scribunto text/plain return { categories = 'Бары ааптардар' } 6rdt34qnz9ytpix0q44tus5tl6jqmka 9648 9646 2026-06-25T03:05:22Z Sauit 2200 9648 Scribunto text/plain return { categories = { nationalities = { 'Бары ааптардар', } } } 69m5qj2ok3kidtrl9z4vcmyvbyxl154 Халыып:Author/styles.css 10 2499 9649 2026-06-25T03:06:12Z Sauit 2200 ".wst-author-mainblock { border: 1px solid #BEA2A2; background-color: #E4D8D8; } .wst-author-notes { border-bottom: 1px solid #A88; background-color: var(--background-color-neutral, #FFFBFC); color: inherit; } .wst-author-seealso { border: 1px solid #CCC; } @media screen { html.skin-theme-clientpref-night .wst-author-mainblock { background-color: #4B3434; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os..." саҥа сирэй оҥоһулунна 9649 sanitized-css text/css .wst-author-mainblock { border: 1px solid #BEA2A2; background-color: #E4D8D8; } .wst-author-notes { border-bottom: 1px solid #A88; background-color: var(--background-color-neutral, #FFFBFC); color: inherit; } .wst-author-seealso { border: 1px solid #CCC; } @media screen { html.skin-theme-clientpref-night .wst-author-mainblock { background-color: #4B3434; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wst-author-mainblock { background-color: #4B3434; } } /* [[Категория:Халыыптар:CSS]] */ tv4cex0irsincehm4i3359bg829b53g