উইকিঅভিধান bnwiktionary https://bn.wiktionary.org/wiki/%E0%A6%AA%E0%A7%8D%E0%A6%B0%E0%A6%A7%E0%A6%BE%E0%A6%A8_%E0%A6%AA%E0%A6%BE%E0%A6%A4%E0%A6%BE MediaWiki 1.47.0-wmf.4 case-sensitive মিডিয়া বিশেষ আলাপ ব্যবহারকারী ব্যবহারকারী আলাপ উইকিঅভিধান উইকিঅভিধান আলোচনা চিত্র চিত্র আলোচনা মিডিয়াউইকি মিডিয়াউইকি আলোচনা টেমপ্লেট টেমপ্লেট আলোচনা সাহায্য সাহায্য আলোচনা বিষয়শ্রেণী বিষয়শ্রেণী আলোচনা পরিশিষ্ট পরিশিষ্ট আলোচনা ছন্দ ছন্দ আলোচনা থিসরাস থিসরাস আলোচনা উদ্ধৃতি উদ্ধৃতি আলোচনা TimedText TimedText talk মডিউল মডিউল আলাপ ইভেন্ট ইভেন্ট আলোচনা মোড়ল 0 2611 509328 447379 2026-05-29T08:54:08Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L644120-এর সাথে সংযোগ তৈরি করছি 509328 wikitext text/x-wiki =={{langname|bn}}== === উচ্চারণ === * {{bn-IPA}} ===বিশেষ্য=== {{বিশেষ্য|bn}} # [[গ্রাম|গ্রামের]] [[প্রধান]] [[ব্যক্তি]] # [[গ্রামনী]] # [[দল|দলের]] [[প্রধান]] # [[প্রধান]] # [[সর্দার]] ==অনুবাদ== {{trans-top}} # [[head]] # [[chief]] # [[superior]] # [[supervisor]] # [[lead]] # [[director]] # [[adviser]] {{trans-bottom}} c34k6ekmkzkc89t7bff4dvawetilqgn 509329 509328 2026-05-29T08:55:06Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L644120-এর সাথে সংযোগ তৈরি করছি 509329 wikitext text/x-wiki {{লে|L644120|meaning= # [[গ্রামনী]] # [[দল|দলের]] [[প্রধান]] # [[প্রধান]] # [[সর্দার]]}} ==অনুবাদ== {{trans-top}} # [[head]] # [[chief]] # [[superior]] # [[supervisor]] # [[lead]] # [[director]] # [[adviser]] {{trans-bottom}} ruckh3p2wt30t6c7cuglj3y1ybvwcag টেমপ্লেট:maintenance box 10 6810 509311 503539 2026-05-29T01:13:01Z Hiyuune 11971 509311 wikitext text/x-wiki <templatestyles src="Module:message box/styles.css" /><div class="noprint maintenance-box maintenance-box-{{{1|blue}}}"> {| | rowspan="2" class="maintenance-box-image-cell" | {{{image|[[File:Codex icon Notice blue.svg|40px|alt=Notice]]}}} ! style="text-align: left;" | {{{title|}}} |- | {{{text|}}} |}</div><noinclude>{{documentation}}</noinclude> pn4fc374opf897cbzurxrblzw75otms ব্যবহারকারী আলাপ:Mahir256 3 21832 509310 62163 2026-05-28T19:42:00Z Leaderbot 11919 /* Notice of expiration of your sysop right */ নতুন অনুচ্ছেদ 509310 wikitext text/x-wiki == বাংলা উইকিঅভিধানে স্বাগতম == {| class="plainlinks" style="width: 100%; padding: 10px; border: 2px solid #909999; background: #F6FFFF; margin-bottom: 3px; color: #000; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow: 0 0 0.25em #829595; -moz-box-shadow: 0 0 0.25em #829595; -webkit-box-shadow: 0 0 0.25em #829595;" |- | সুপ্রিয় Mahir256! <br /> উইকিঅভিধানে, বাংলা ভাষায় এই মুক্ত অভিধান গড়ার এই প্রকল্পে [[বিশেষ:অবদান/Mahir256|আপনার প্রচেষ্টাকে]]&nbsp;স্বাগত জানাচ্ছি। আশা করছি এই প্রচেষ্টাকে সফল করতে আপনার সাহায্য অব্যাহত থাকবে, এবং এই সম্প্রদায়ে আপনার অবস্থান আনন্দপূর্ণ হবে। যেকোনো প্রকার প্রশ্নে নিঃসঙ্কোচে [[ব্যবহারকারী আলাপ:ZI Jony|আমার আলাপ পাতায়]]&nbsp;বার্তা রাখার অনুরোধ করছি। উইকিঅভিধানে লেখার ক্ষেত্রে কিছু বিষয় মনে রাখা উত্তম: * [[উইকিঅভিধান:নীতিমালা ও নির্দেশাবলী|নীতিমালা ও নির্দেশাবলী]] &mdash; উইকিঅভিধানের মূল নীতিমালাগুলোতে একবার চোখ বুলিয়ে নিন, ও মেনে চলার চেষ্টা করুন। * [[উইকিঅভিধান:ভুক্তির কাঠামো ব্যাখ্যা|ভুক্তির কাঠামো ব্যাখ্যা]] &mdash; অর্থাৎ একটি ভুক্তিতে যে বিষয়গুলো যোগ করার মাধ্যমে আপনি ভুক্তিটির উন্নয়ন ঘটাতে পারেন। * [[উইকিঅভিধান:কপিরাইট|কপিরাইট নীতিমালা]] &mdash; উইকিঅভিধান আইনের প্রতি শ্রদ্ধাশীল। তাই কপিরাইটের মূল বিষয়গুলো অনুগ্রহপূর্বক দেখে নিন। * [[উইকিঅভিধান:নতুন শব্দ যোগ|নতুন শব্দ যোগ]] &mdash; বাংলা ও ইংরেজীতে নতুন শব্দ যোগ করতে অনুগ্রহপূর্বক [[উইকিঅভিধান:নতুন শব্দ যোগ]] পাতার প্রণালীটি অনুসরণ করুন। নিজের সম্পর্কে তথ্য আপনি আপনার [[ব্যবহারকারী:Mahir256|ব্যবহারকারী পাতায়]] রাখতে পারেন। এর মাধ্যমে অন্যরা আপনার সম্পর্কে জানতে পারবে। সাহায্য চাইতে এবং মতামত রাখতে অনুগ্রহপূর্বক সম্পর্কিত পাতার আলাপ পাতা ব্যবহার করুন। <br /><br /> অনুগ্রহপূর্বক আলাপের পাতায় বার্তা রাখার পর সম্পাদনা সরঞ্জামদণ্ডের [[চিত্র:OOjs UI icon signature-ltr.svg|22px|link=|alt=স্বাক্ষর আইকন]] চিহ্নে ক্লিক করার মাধ্যমে অথবা চারটি টিল্ডা (<code><nowiki>~~~~</nowiki></code>) চিহ্ন দিয়ে নাম স্বাক্ষর করুন। এটি স্বয়ংক্রিয় ভাবে আপনার নাম এবং তারিখ যোগ করবে। <br /> আশা করি আপনি বাংলা উইকিঅভিধান সম্প্রদায়ের একজন হয়ে সম্পাদনা করে আনন্দ পাবেন! আবারও স্বাগতম এবং শুভেচ্ছা! [[উইকিঅভিধান:অভ্যর্থনা কমিটি|উইকিঅভিধান অভ্যর্থনা কমিটি]], [[ব্যবহারকারী:ZI Jony|<span style="color:#8B0000">'''''জনি'''''</span>]] [[ব্যবহারকারী আলাপ:ZI Jony|<sup><span style="color:Green"><i>(আলাপ)</i></span></sup>]] ১৮:১৭, ১২ ডিসেম্বর ২০১৮ (ইউটিসি) |} == Notice of expiration of your sysop right == <div dir="ltr">Hi, as part of [[:m:Special:MyLanguage/Global reminder bot|Global reminder bot]], this is an automated reminder to let you know that your permission "sysop" (প্রশাসক) will expire on 2026-06-03 21:53:52. Please renew this right if you would like to continue using it. <i>In other languages: [[:m:Special:MyLanguage/Global reminder bot/Messages/default|click here]]</i> [[ব্যবহারকারী:Leaderbot|Leaderbot]] ([[ব্যবহারকারী আলাপ:Leaderbot|আলাপ]]) ১৯:৪২, ২৮ মে ২০২৬ (ইউটিসি)</div> dirx387sv0yrrch9x7qdtx8kji3abz6 মডিউল:আভিধানিক উপাত্ত 828 50158 509309 509305 2026-05-28T16:36:03Z Redmin 6857 509309 Scribunto text/plain local p = {} local i18n = require('মডিউল:আভিধানিক উপাত্ত/i18n') local references = require('মডিউল:উইকিউপাত্ত তথ্যসূত্র বিন্যাসকরণ').format local getArgs = require('Module:Arguments').getArgs local wb = mw.wikibase local ustring = mw.ustring local html = mw.html local mw_lang = mw.language local entity_cache = {} local reference_cache = {} local forms local lang_code local lex_cat local matched_lemma local function wrapStringInWikilinks(str) local exceptions = i18n.nolinks local result = str:gsub('(%S+)', function(token) local word, trailing_char = token:match('^(.-)([;,]*)$') local wrapped = word:gsub('[^(-/]+', function(part) if exceptions[part] then return part else return '[[' .. part .. '#' .. i18n['content_lang_name'] .. '|' .. part .. ']]' end end) return wrapped .. trailing_char end) return result end local function serializeTable(val, name, skipnewlines, depth) -- https://stackoverflow.com/a/6081639 skipnewlines = skipnewlines or false depth = depth or 0 local tmp = string.rep(" ", depth) if name then tmp = tmp .. name .. " = " end if type(val) == "table" then tmp = tmp .. "{" .. (not skipnewlines and "\n" or "") for k, v in pairs(val) do tmp = tmp .. serializeTable(v, k, skipnewlines, depth + 1) .. "," .. (not skipnewlines and "\n" or "") end tmp = tmp .. string.rep(" ", depth) .. "}" elseif type(val) == "number" then tmp = tmp .. tostring(val) elseif type(val) == "string" then tmp = tmp .. string.format("%q", val) elseif type(val) == "boolean" then tmp = tmp .. (val and "true" or "false") else tmp = tmp .. "\"[inserializeable datatype:" .. type(val) .. "]\"" end return tmp end -- Use this to safely expand templates when you are not sure that they exist. local function safeExpand(frame, title, args) local _, result = pcall(function() return frame:expandTemplate{ title = title, args = args } end) if result:find('does not exist') then -- expandTemplate{} doesn't seem to throw any error that can be handled with pcall() so string search is the only viable option. return nil end return result end -- Use this function to get the label of an item even if that item does not have any label in the wiki's content language or English. local function getLabel(id) if id == 'Q11051hi' then return 'হিন্দি' elseif id == 'Q11051ur' then return 'উর্দু' elseif id == 'Q56356571fa' then return 'নয়া ফার্সি' elseif id == 'Q56356571tg' then return 'তাজিক' elseif id == 'Q58635pa' or id == 'Q58635pnb' then return 'পাঞ্জাবি' end local label = wb.getLabel(id) if label then return label end local labels = wb.getEntity(id).labels if not labels then return id end for _, v in pairs(labels) do if v and v.value then return v.value end end end local function getReference( id, reference ) local out_id = nil local url_value if reference_cache[id] == nil then local ref_text = references(reference, wb, mw_lang, i18n['content_lang_code'], i18n['wikipedia']) if reference.snaks ~= nil then if reference.snaks['P248'] ~= nil then for _, snak in pairs(reference.snaks['P248']) do if snak.datavalue and snak.datavalue.value.id == 'Q428' then -- কুরআন ref_text = ustring.gsub(ref_text, 'নামক অনুচ্ছেদ', 'নং আয়াত') break end end end if reference.snaks['P854'] ~= nil then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value ~= nil then ref_text = ref_text .. ', [' .. url_value .. ' সংযোগ]' end reference_cache[id] = ref_text else out_id = id end return {out_id, reference_cache[id]} end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) end return entity_cache[id] ~= false and entity_cache[id] or nil end local function getLexemeLanguageCode(current_lexeme) local lang_item_id = current_lexeme:getLanguage() if lang_item_id == nil then return nil end local lang_entity = getEntity(lang_item_id) if lang_entity == nil then return nil end for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] ~= nil then return statements[1].mainsnak.datavalue.value end end return nil end -- Return the first form of the lexeme which has exactly the given grammatical feature. local function formWithSingleGrammaticalFeature( item_id ) for i = 1, #forms do local grammaticalFeatures = forms[i]:getGrammaticalFeatures() if #grammaticalFeatures == 1 and grammaticalFeatures[1] == item_id then return forms[i] end end return nil end local function getArticleLinkTemplate(frame, stmt_value) local template = '' local sitelink = getEntity(stmt_value):getSitelink(i18n['wikipedia']) if sitelink ~= nil then template = frame:expandTemplate{ title=i18n['template_wikipedia'], args={sitelink} } end return template end local function getArticleLinks (frame, sense ) local article_links = '' for i, stmt in pairs(sense:getAllStatements('P5137')) do -- এই অর্থের জন্য আইটেম article_links = article_links .. getArticleLinkTemplate(frame, stmt.mainsnak.datavalue.value.id) end for i, stmt in pairs(sense:getAllStatements('P9970')) do -- এই অর্থের জন্য বিধেয় article_links = article_links .. getArticleLinkTemplate(frame, stmt.mainsnak.datavalue.value.id) end return article_links end -- @TODO: Generalise local function expandTemplateForProperty(frame, object, property, template) local lemmas = {} local n = 0 for _, stmt in pairs(object:getAllStatements(property)) do local lex = wb.lexeme.splitLexemeId(stmt.mainsnak.datavalue.value.id) lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end if not lang_code or n == 0 then return '' end -- Build args: first lang_code, then lemmas local args = {lang_code} for i = 1, n do args[#args + 1] = lemmas[i] end return frame:expandTemplate{ title = template, args = args } end local function getExternalLinks( entity ) -- T418639 local external_links = {} if entity.claims == nil then return external_links end local formatter_urls = require('মডিউল:আভিধানিক উপাত্ত/urls').formatter_urls for property_id, statements in pairs(entity.claims) do local formatter_url = formatter_urls[property_id] if formatter_url ~= nil then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) ~= nil then source_name = getLabel(property_source[1].mainsnak.datavalue.value.id) or property_source[1].mainsnak.datavalue.value.id else source_name = getLabel(property_id) or property_id end for i = 1, #statements do local stmt = statements[i] if stmt.mainsnak.datavalue then local formatted_link = ustring.gsub( ustring.gsub(formatter_url, '$1', ustring.gsub(stmt.mainsnak.datavalue.value, '%%', '%%%%')), ' ', '+' ) table.insert(external_links, '[' .. formatted_link .. ' ' .. source_name .. ']') end end end end return external_links end p.getExternalLinks = getExternalLinks -- রেখে দিন যাতে ডিবাগিং সম্ভব হয় local function termSpan( term ) local text = term[1] local lang = term[2] local dir = mw_lang.new( lang ):getDir() local span = html.create( 'span' ) span:attr( 'lang', lang ) :attr( 'dir', dir ) :wikitext( text ) return tostring( span ) end local function termLink( term, lang_qid ) local text = term[1] local lang = term[2] local dir = mw_lang.new( lang ):getDir() local span = html.create( 'span' ) span:attr( 'lang', lang ) :attr( 'dir', dir ) :wikitext( '[[' .. text .. '#' .. getLabel(lang_qid) .. '|' .. text .. ']]' ) return tostring( span ) end local function getLemmata( current_lexeme ) local lemma_string = '' for i, rep in pairs(current_lexeme:getLemmas()) do if lemma_string == '' then lemma_string = termSpan(rep) else lemma_string = lemma_string .. '/' .. termSpan(rep) end end return lemma_string end local function getLinkedLemmata( current_lexeme ) local lemma_string = '' for i, rep in pairs(current_lexeme:getLemmas()) do if lemma_string == '' then lemma_string = termLink(rep, current_lexeme:getLanguage()) else lemma_string = lemma_string .. '/' .. termLink(rep, current_lexeme:getLanguage()) end end return lemma_string end local function getExamples( current_lexeme, sense_id, references_seen ) local examples = html.create('dl') local example_text, example_lang, example_form, example_str for i, stmt in pairs(current_lexeme:getAllStatements('P5831')) do -- ব্যবহারের উদাহরণ if stmt.qualifiers ~= nil and stmt.qualifiers['P6072'] ~= nil and stmt.qualifiers['P6072'][1].datavalue.value.id == sense_id then -- বিষয়ে লেক্সিমের অর্থ example_text = ustring.gsub(stmt.mainsnak.datavalue.value.text, ' / ','<br/>') example_lang = stmt.mainsnak.datavalue.value.language local example_form_strs = {} if stmt.qualifiers['P1810'] ~= nil then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] ~= nil then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ for _, rep in pairs(example_form:getRepresentations()) do table.insert(example_form_strs, rep[1]) end end for i, example_form_str in pairs(example_form_strs) do new_example_text = ustring.gsub(example_text, example_form_str, "'''" .. example_form_str .. "'''") if new_example_text ~= example_text then example_str = termSpan({new_example_text, example_lang}) break end new_example_text = example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references ~= nil then for j, reference in pairs(stmt.references) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. got_reference[2] end end if example_str ~= nil then examples:tag('dd'):wikitext("''" .. example_str .. "''") if reference_text ~= '' then examples:done():tag('dd'):css('text-indent', '2em'):wikitext(reference_text) end end end end for i, stmt in pairs(wb.getAllStatements(sense_id, 'P5831')) do -- ব্যবহারের উদাহরণ example_text = ustring.gsub(stmt.mainsnak.datavalue.value.text, ' / ','<br/>') example_lang = stmt.mainsnak.datavalue.value.language local example_form_str = nil if stmt.qualifers ~= nil then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] ~= nil then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form ~= nil and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form ~= nil and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str ~= nil then example_text = ustring.gsub(example_text, example_form_str, "'''" .. example_form_str .. "'''") end example_str = termSpan({example_text, example_lang}) local reference_text = '' if stmt.references ~= nil then for j, reference in pairs(stmt.references) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. got_reference[2] end end if example_str ~= nil then examples:tag('dd'):wikitext("''" .. example_str .. "''") if reference_text ~= '' then examples:done():tag('dd'):css('text-indent', '2em'):wikitext(reference_text) end end end return { tostring(examples) , references_seen } end -- This calls frame:preprocess() instead of :callParserFunction() because the latter does not work for Wikifunctions function calls yet (see https://www.wikifunctions.org/wiki/Wikifunctions:Embedded_function_calls). local function callWikifunctionsFunction(args, frame) return frame:preprocess('{{#function:' .. args .. '}}') end local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( lang_id, current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) ~= nil then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) ~= nil then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) ~= nil then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) ~= nil then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) ~= nil then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) ~= nil then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getOneStringForProperty(object, property) local val local stmts = object:getAllStatements(property) if #stmts ~= 0 then val = stmts[1].mainsnak.datavalue.value end return val end local function getTranslations(frame, senses) -- TODO: woefully incomplete until T185313 and T199887 are resolved if #senses == 0 then return nil end local all_translations = {} for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss('bn') for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local language = getLabel(getEntity(lexeme_id):getLanguage()) table.insert(translation_set, language .. ': ' .. getLinkedLemmata(getEntity(lexeme_id)) .. '<br/>') end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss } } block = block .. table.concat(translation_set, '\n') .. frame:expandTemplate{ title = i18n['template_trans-bottom'] } table.insert(all_translations, block) end end if #all_translations == 0 then return nil end return '====' .. i18n['heading_translation'] .. '==== \n' .. table.concat(all_translations, '\n') end local createicon = function(langcode, entityID, propertyID) langcode = langcode or "" propertyID = propertyID or "" local icon = "&nbsp;<span class='penicon autoconfirmed-show'>[[" -- "&nbsp;<span data-bridge-edit-flow='overwrite' class='penicon'>[[" -> enable Wikidata Bridge .. "File:OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt=" .. i18n['edit_wikidata'] .. "|link=https://www.wikidata.org/entity/" .. entityID if langcode ~= "" then icon = icon .. "?uselang=" .. langcode end if propertyID ~= "" then icon = icon .. "#" .. propertyID end icon = icon .. "|" .. i18n['edit_wikidata'] .. "]]</span>" return icon end local function getMeanings( frame, args, current_lexeme, senses, references_seen, language_name) if #senses == 0 then return {createicon(i18n['content_lang_code'], current_lexeme:getId()) .. "''" .. i18n['text_category_rfdef'] .. "''" .. i18n.tocatlink(i18n['category_rfdef']), references_seen} end local meanings = html.create( 'ol' ) local idlinkset = {} for i, sense in pairs(senses) do local gloss_text_parts = {} local main_gloss_text = frame:expandTemplate{ title=i18n['template_anchor'], args={sense:getId()} } local specifiers = {} for k, property_id in ipairs({'P6084', 'P6191', 'P9488'}) do -- অবস্থান যেখানে শব্দার্থ ব্যবহৃত, যে রীতিতে শব্দার্থ ব্যবহৃত হয়, যে ক্ষেত্রে ব্যবহৃত for i, stmt in pairs(sense:getAllStatements(property_id)) do local stmt_value = stmt.mainsnak.datavalue.value.id local reference_text = '' local refs = stmt.references if refs ~= nil then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' then table.insert(specifiers, i18n.tocatlink(lang_code .. val)) end end end end if #specifiers > 0 then main_gloss_text = main_gloss_text .. "(''" .. table.concat(specifiers, "'', ''") .. "'') " end local gloss = sense:getGloss( i18n['content_lang_code'] ) if gloss ~= nil then main_gloss_text = main_gloss_text .. wrapStringInWikilinks(gloss) if gloss:match('^প্রদত্ত%s*(%S-)%s*নাম$') then -- given names main_gloss_text = main_gloss_text .. i18n.tocatlink(language_name .. ' ' .. i18n['category_given_names']) end else local other_gloss_text = nil local other_gloss_lang = nil local item_label_gloss_parts = {} for k, stmt in pairs(sense:getAllStatements('P5137')) do -- যদি 'এই অর্থের জন্য আইটেম' মানের বাংলা লেবেল থাকে local stmt_value = stmt.mainsnak.datavalue.value.id local stmt_label = getLabel(stmt_value) if stmt_label ~= nil then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. stmt_label .. ']]') end end if #item_label_gloss_parts > 0 then other_gloss_text = table.concat(item_label_gloss_parts, '; ') end if other_gloss_text == nil then for i, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) ~= nil then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for j, gloss in pairs(glosses) do other_gloss_text = gloss[1] other_gloss_lang = gloss[2] break end end main_gloss_text = main_gloss_text .. other_gloss_text .. "<sup><em>" .. mw_lang.fetchLanguageName(other_gloss_lang, i18n['content_lang_code']) .. "</em></sup>" else main_gloss_text = main_gloss_text .. "''" .. other_gloss_text .. "''" end main_gloss_text = main_gloss_text .. i18n.tocatlink(i18n['category_rfdef_equivalent']) end local synonym = expandTemplateForProperty(frame, sense, 'P5973', i18n['template_synonym']) if synonym ~= '' then main_gloss_text = main_gloss_text .. ' <br/> ' .. synonym end local antonym = expandTemplateForProperty(frame, sense, 'P5974', i18n['template_antonym']) if antonym ~= '' then main_gloss_text = main_gloss_text .. ' <br/> ' .. antonym end local hypernym = expandTemplateForProperty(frame, sense, 'P6593', i18n['template_hypernym']) if hypernym ~= '' then main_gloss_text = main_gloss_text .. ' <br/> ' .. hypernym end if lex_cat == 'Q1084' or lex_cat == 'Q147276' then -- noun or proper noun local demonym = expandTemplateForProperty(frame, sense, 'P6271', i18n['template_demonym-noun']) main_gloss_text = main_gloss_text .. ' <br/> ' .. demonym elseif lex_cat == 'Q34698' then local demonym = expandTemplateForProperty(frame, sense, 'P6271', i18n['template_demonym-adj']) main_gloss_text = main_gloss_text .. ' <br/> ' .. demonym end table.insert(gloss_text_parts, main_gloss_text .. createicon(i18n['content_lang_code'], sense:getId())) for i, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] ~= nil then local got_reference = getReference ( stmt.references[1].hash, stmt.references[1] ) gloss_quote = '"' .. gloss_quote .. '" ' .. got_reference[2] end table.insert(references_seen, stmt.references[1].hash) table.insert(gloss_text_parts, frame:extensionTag('ref', gloss_quote)) end for i, stmt in pairs(sense:getAllStatements('P1343')) do -- বর্ণিত উৎস -- TODO: do away with making fake reference objects local fake_reference = { ['snaks'] = {} } fake_reference.snaks['P248'] = { [1] = stmt.mainsnak } qualifiers_order = stmt['qualifiers-order'] if qualifiers_order ~= nil then for i, k in ipairs(qualifiers_order) do fake_reference.snaks[k] = stmt.qualifiers[k] end end fake_reference.hash = mw.hash.hashValue('sha3-512', serializeTable(fake_reference)) table.insert(references_seen, fake_reference.hash) local got_reference = getReference(fake_reference.hash, fake_reference) if got_reference[1] == nil then table.insert(gloss_text_parts, frame:extensionTag('ref', got_reference[2], {name = fake_reference.hash})) else table.insert(gloss_text_parts, frame:extensionTag{name = 'ref', content='', args = {name = got_reference[1]}}) end end local first_sense_image = '' local sense_images = sense:getAllStatements('P18') if next(sense_images) ~= nil then first_sense_image = sense_images[1].mainsnak.datavalue.value end if first_sense_image ~= '' then table.insert(gloss_text_parts, '[[চিত্র:' .. first_sense_image .. "|thumb|'''" .. getLemmata(current_lexeme) .. "'''—" .. main_gloss_text .. ']]') end local idlinks = getExternalLinks(sense) if #idlinks > 0 then local idlinktext = '<small>(' for _, idlink in pairs(idlinks) do idlinktext = idlinktext .. idlink .. '\n' end idlinktext = idlinktext .. ')</small>' table.insert(gloss_text_parts, idlinktext) table.insert(idlinkset, idlinks) end local externallinks = getArticleLinks(frame, sense) if externallinks ~= '' then table.insert(gloss_text_parts, externallinks) end local new_notes = {} local sense_keys = { sense:getId(), string.sub(sense:getId(), string.find(sense:getId(), '-')+1) } for _, v in ipairs(sense_keys) do if args[v] ~= nil then table.insert(new_notes, args[v]) end end if #new_notes > 0 then for _, v in ipairs(new_notes) do if i == 1 then table.insert(gloss_text_parts, '<br/>' .. v) else table.insert(gloss_text_parts, v) end end end local examples, references_seen = unpack(getExamples( current_lexeme, sense:getId(), references_seen )) local gloss_text = table.concat(gloss_text_parts, '\n') meanings:tag('li'):wikitext(gloss_text):wikitext(examples) end return {meanings, references_seen, idlinkset} end local function getPronunciationBaseForm( lang_name, lex_cat) local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_name == 'বাংলা' then if lex_cat == 'Q1084' then -- বিশেষ্য base_form = formWithSingleGrammaticalFeature( 'Q131105' ) -- কর্তৃকারক elseif lex_cat == 'Q24905' then -- ক্রিয়া base_form = formWithSingleGrammaticalFeature( 'Q1350145' ) -- ক্রিয়া বিশেষ্য end end if base_form == nil then for i, form in pairs(forms) do base_form = form break end end return base_form end local function getCombines( current_lexeme, frame ) local combines = '' local index_mappings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P5238')) do if stmt.qualifiers ~= nil and stmt.qualifiers['P1545'] ~= nil then -- ক্রম local current_index = tonumber(stmt.qualifiers['P1545'][1].datavalue.value) index_mappings[current_index] = stmt end end if #index_mappings ~= 0 then for i, stmt in ipairs(index_mappings) do if stmt.mainsnak.datavalue ~= nil then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology ~= nil then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This shoukd use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme ) local stmts = current_lexeme:getAllStatements('P5920') if #stmts == 0 then return '' end local root_lexeme = getEntity(stmts[1].mainsnak.datavalue.value.id) return getLexemeLanguageCode(root_lexeme), '√' .. getLinkedLemmata(root_lexeme), root_lexeme:getLemma('ar') end function getEtymology( current_lexeme, frame, mode ) -- @TODO: Fix the etymology chains that are not possible to render local etymology = '' local current_combines = getCombines(current_lexeme, frame) local root_lang, current_roots, root_str = getRoots(current_lexeme) if mode ~= 'partial' and root_str ~= nil then frame:expandTemplate{title=i18n['template_root'], args={lang_code, root_lang, root_str}} end local stmts = current_lexeme:getAllStatements('P5191') local new_etymology_string if #stmts == 0 then if current_roots ~= '' and current_combines ~= '' and current_roots ~= nil then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' then return frame:expandTemplate{title=i18n['template_ar-rootbox'], args={root_str}} else return current_roots end else return current_combines end end local origin_lexeme_string for i, stmt in pairs(stmts) do local origin_lexeme_dv = stmt.mainsnak.datavalue -- If this is nil, the origin lexeme is not known. if origin_lexeme_dv ~= nil then local origin_lexeme = getEntity(origin_lexeme_dv.value.id) local origin_lexeme_lang = getLabel(origin_lexeme:getLanguage()) local sitelink = i18n.wplink(origin_lexeme:getLanguage(), origin_lexeme_lang, wb) if sitelink ~= '' then origin_lexeme_string = getLinkedLemmata(origin_lexeme) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers ~= nil and stmt.qualifiers['P5886'] ~= nil then local mode_of_derivation = stmt.qualifiers['P5886'][1].datavalue.value.id if mode_of_derivation == 'Q1345001' then -- @TODO: Add support for showing gender origin_lexeme_string = frame:expandTemplate{title=i18n['template_borrowed'], args={lang_code, getLexemeLanguageCode(origin_lexeme), getLemmata(origin_lexeme), pos=getLabel(lex_cat)}} .. ' ' .. i18n['etymology_borrowing'] elseif mode_of_derivation == 'Q845079' then origin_lexeme_string = ustring.gsub(i18n['etymology_learned_borrowing'], '$1', origin_lexeme_string) elseif mode_of_derivation == 'Q56611986' then origin_lexeme_string = frame:expandTemplate{title=i18n['template_inherited'], args={lang_code, getLexemeLanguageCode(origin_lexeme), getLemmata(origin_lexeme), pos=getLabel(lex_cat)}} .. ' ' .. i18n['etymology_inheritance'] elseif mode_of_derivation == 'Q189743' then origin_lexeme_string = frame:expandTemplate{title=i18n['template_ellipsis'], args={lang_code, getLemmata(origin_lexeme)}} .. ' ' .. i18n['etymology_ellipsis'] end end local origin_origin = getEtymology(origin_lexeme, frame) if origin_origin ~= '' and origin_origin ~= nil then new_etymology_string = origin_lexeme_string .. ' ← ' .. origin_origin else new_etymology_string = origin_lexeme_string end end if etymology == '' then etymology = new_etymology_string elseif origin_lexeme_string ~= nil and etymology ~= nil then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string ~= nil and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology ~= nil and current_roots ~= nil then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology ~= nil then etymology = etymology .. '<br/>(' .. current_combines .. ')' end return etymology end local function pronunciationBlock(block, value) return '* ' .. i18n['text_' .. block] .. ' ' .. value end local function getPronunciation( frame, current_lexeme, lang_name, lex_cat ) local pronunciations = {} local base_form = getPronunciationBaseForm(lang_name, lex_cat ) if base_form ~= nil then for i, stmt in pairs(base_form:getAllStatements('P443')) do -- উচ্চারণের অডিও local pronunciation_file = stmt.mainsnak.datavalue.value local specifier_text = '' local specifiers = {} if stmt.qualifiers ~= nil then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন for l, qual in pairs(stmt.qualifiers[property_id]) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end end end if #specifiers > 0 then specifier_text = table.concat(specifiers, "'', ''") end local audio_text if specifier_text ~= '' then audio_text = i18n['text_audio'] .. ' (' .. specifier_text .. ')' else audio_text = i18n['text_audio'] end table.insert(pronunciations, '* ' .. frame:expandTemplate{ title= i18n['template_audio'], args = {lang_name, pronunciation_file, audio_text} }) end local ipa_transcription = base_form:getAllStatements('P898') -- - আধ্বব প্রতিলিপিকরণ local iso15919_transcription = getOneStringForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ local itrans = getOneStringForProperty(base_form, 'P8881') -- ITRANS local iast = getOneStringForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ local xsampa = getOneStringForProperty(base_form, 'P2859') -- @TODO: অডিও ও প্রতিলিপিকরণ দুটোই থাকলে সেই ক্ষেত্রে একটার ঠিক পরেই আরেকটা দেখানো উচিত if #ipa_transcription ~= 0 then for i, stmt in pairs(ipa_transcription) do local ipa_text = stmt.mainsnak.datavalue.value local specifier_text = '' local specifiers = {} if stmt.qualifiers ~= nil then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন for l, qual in ipairs(stmt.qualifiers[property_id]) do table.insert(specifiers, getLabel( qual.datavalue.value.id )) end end end if #specifiers > 0 then specifier_text = "(''" .. table.concat(specifiers, "'', ''") .. "'') " end local syllable_count if lang_code == 'tr' then syllable_count = i18n['text_syllable_count'] .. callWikifunctionsFunction('Z10029|' .. ipa_text, frame) else syllable_count = i18n['text_syllable_count'] .. callWikifunctionsFunction('Z30837|' .. ipa_text, frame) end table.insert(pronunciations, '* ' .. specifier_text .. frame:expandTemplate{ title= i18n['template_ipa'], args = {lang_name, ipa_text} } .. '\n* ' .. syllable_count) end -- The following checks are ordered based on which one is expected to be true in a higher number of cases. elseif lang_name == 'বাংলা' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_name == 'আরবি' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_name == 'ফালা' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) end if iso15919_transcription ~= nil then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans ~= nil then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast ~= nil then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa ~= nil then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue ~= nil then table.insert(alt_spellings, '* ' .. getLinkedLemmata(getEntity(stmt.mainsnak.datavalue.value.id))) end end return table.concat(alt_spellings, '\n') end local function heading_level(text, level) local heading_delimiter = string.rep('=', level) return heading_delimiter .. ' ' .. text .. ' ' .. heading_delimiter end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] ~= nil then table.insert(notes, args[v]) end end return notes end function add_specific_notes(sections, notes) for i, v in ipairs(notes) do table.insert(sections, v) end end local function add_any_notes(sections, args, keys) for i, v in ipairs(keys) do if args[v] ~= nil then table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local matched_lemma for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then matched_lemma = lemma break end end if matched_lemma == nil and lang_code == 'ar' then -- Arabic lemmas do not match the title of the entry because those are written with different characters stripped out on Wiktionary matched_lemma = lexeme:getLemma('ar') end return matched_lemma end local function buildLanguageAgnosticInflectionTable() local has_image = false local form_images = {} for i, form in ipairs(forms) do local form_image = form:getAllStatements('P7407') if next(form_image) ~= nil then form_images[i] = form_image[1].mainsnak.datavalue.value has_image = true end end local table_class = "wikitable mw-collapsible sortable" if not has_image then table_class = table_class .. " mw-collapsed" end local text = "{| class='" .. table_class .. "' style='border:solid 1px rgb(80%,80%,100%); text-align:center;'\n" text = text .. "|+ " .. i18n['heading_inflection_table'] .. "\n" text = text .. "|- \n" text = text .. "! " .. i18n['heading_form'] .. " !! " .. i18n['heading_grammatical_features'] if has_image then text = text .. " !! " .. (i18n['heading_image']) end text = text .. " \n" for i, form in ipairs(forms) do local rep = form:getRepresentations() local feat = form:getGrammaticalFeatures() local rep_text = "" for j, r in pairs(rep) do if rep_text == "" then rep_text = r[1] else rep_text = rep_text .. " / " .. r[1] end end local feat_text = "" if feat ~= nil then for j, f in ipairs(feat) do local label = getLabel(f) or f if feat_text == "" then feat_text = label else feat_text = feat_text .. ", " .. label end end end text = text .. "|-\n" text = text .. "| " .. (rep_text ~= "" and rep_text or "—") text = text .. " || " .. (feat_text ~= "" and feat_text or "—") if has_image then local image_cell = "—" if form_images[i] ~= nil then image_cell = "[[চিত্র:" .. form_images[i] .. "|50px]]" end text = text .. " || " .. image_cell end text = text .. "\n" end text = text .. "|}" return text end function p.all( frame ) local args = getArgs(frame) local lexeme_id = args[1] local current_lexeme = getEntity(lexeme_id) local current_language = current_lexeme:getLanguage() local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] ~= nil then local val = mw.text.trim(tostring(args[2])) if val == "false" or val == "0" or val == "না" then add_heading = false end end local references_seen = {} local sections = {} local title = mw.title.getCurrentTitle().text local lang_category = getLanguageForCategories(current_language, title) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = "== " .. lang_name .. " ==" table.insert(sections, lang_heading) end matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() lang_code = getLexemeLanguageCode(current_lexeme) local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template if cat ~= nil then table.insert(sections, '===' .. getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } } .. '===') table.insert(sections, frame:expandTemplate{ title= i18n['template_lexeme'], args = {lexeme_id} }) add_any_notes(sections, args, i18n['manual_category']) local etymology = getEtymology( current_lexeme, frame ) if etymology ~= '' and etymology ~= nil then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) end add_any_notes(sections, args, i18n['manual_etymology']) local pronunciation = getPronunciation( frame, current_lexeme, lang_name, lex_cat ) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) end add_any_notes(sections, args, i18n['manual_pronunciation']) local alternative_spellings = getAlternativeSpellings( current_lexeme ) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) end if lang_code ~= nil and lang_code ~= 'ksy' and lang_code ~= 'rkt' then -- Skip for Kharia Thar, Rangpuri if lex_cat == 'Q34698' then -- বিশেষণ if lang_code == 'en' or lang_code == 'bn' then if #forms <= 1 then lex_cat_template = frame:expandTemplate{title= lang_code .. '-বিশেষণ'} end else lex_cat_template = safeExpand(frame, lang_code .. '-adj') if not lex_cat_template then lex_cat_template = safeExpand(frame, lang_code .. '-বিশেষণ') end end elseif lex_cat == 'Q1084' then -- @TODO: Also check for plural forms local gender local stmts = current_lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 then if #stmts == 1 then local gender_qid = stmts[1].mainsnak.datavalue.value.id if gender_qid == 'Q499327' then gender = 'm' elseif gender_qid == 'Q1775415' then gender = 'f' elseif gender_qid == 'Q1775461' then gender = 'n' elseif gender_qid == 'Q1305037' then gender = 'c' end end else for i, stmt in pairs(stmts) do local qid = stmts[i].mainsnak.datavalue.value.id if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if current_language == 'Q13955' then if matched_lemma ~= nil then lex_cat_template = safeExpand(frame, {title='ar-noun', args={matched_lemma,gender}}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif current_language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif current_language == 'Q397' then if matched_lemma ~= nil then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif current_language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif current_language ~= 'Q1860' then -- These templates require the gender to be passed as the 1st argument. lex_cat_template = safeExpand(frame, lang_code .. i18n['noun_template_suffix'], {gender}) if not lex_cat_template then lex_cat_template = safeExpand(frame, lang_code .. i18n['noun_template_suffix_fallback'], {gender}) end end end end -- elseif lex_cat == 'Q147276' then -- lex_cat_template = safeExpand(frame, lang_code .. '-proper noun', {gender}) -- if not lex_cat_template then -- lex_cat_template = safeExpand(frame, lang_code .. '-নামবাচক বিশেষ্য', {gender}) -- end end if lex_cat_template ~= nil then table.insert(sections, lex_cat_template) else if matched_lemma ~= nil then table.insert(sections, heading_level(matched_lemma, 4)) else table.insert(sections, i18n.tocatlink(i18n['category_no_matching_lemma'])) end end local meanings, references_seen, sense_extlinks = unpack(getMeanings( frame, args, current_lexeme, senses, references_seen, lang_name)) table.insert(sections, tostring(meanings)) add_any_notes(sections, args, i18n['manual_meaning']) local instance_of = current_lexeme:getAllStatements('P31') -- সত্ত্বার ধরন if #instance_of ~= 0 then local instance_of_entity = instance_of[1].mainsnak.datavalue.value.id if instance_of_entity == 'Q40437546' or instance_of_entity == 'Q120831827' or instance_of_entity == 'Q120717979' or instance_of_entity == 'Q124476844' then -- @TODO: generalise this so all types of roots are shown table.insert(sections, i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity)) elseif instance_of_entity == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) end end local translations = getTranslations(frame, senses) if translations ~= nil then table.insert(sections, translations) end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) ~= nil then if current_language == 'Q9610' then -- বাংলা if lex_cat == 'Q24905' then local conjTable = require('মডিউল:আভিধানিক উপাত্ত/Q9610').getConjTable(frame, forms) table.insert(sections, conjTable) elseif lex_cat == 'Q1084' then --table.insert(sections, callWikifunctionsFunction('Z33243|' .. lexeme_id .. '|', frame)) table.insert(sections, buildLanguageAgnosticInflectionTable()) elseif lex_cat == 'Q34698' then if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif current_language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif current_language == 'Q188' then -- জার্মান if lex_cat == 'Q1084' then table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) end else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end end if lex_cat == 'Q134830' then table.insert(sections, frame:expandTemplate{title='prefixsee', args={lang_code}}) elseif lex_cat == 'Q102047' then table.insert(sections, frame:expandTemplate{title='suffixsee', args={lang_code}}) -- elseif lex_cat == 'Q111029' then -- table.insert(sections, frame:expandTemplate{title='rootsee', args={'+', lang_code, matched_lemma}}) end local reference_notes = get_any_notes(sections, args, i18n['manual_reference']) if #references_seen > 0 or #reference_notes > 0 then table.insert(sections, heading_level(i18n['heading_references'], 4)) table.insert(sections, frame:extensionTag('references')) add_specific_notes(sections, reference_notes) end local external_link_table = getExternalLinks ( current_lexeme ) if #external_link_table > 0 then local external_links = '* ' .. table.concat(external_link_table, '\n* ') table.insert(sections, heading_level(i18n['heading_external_links'], 4)) table.insert(sections, external_links) end add_any_notes(sections, args, i18n['manual_external_link']) if #references_seen == 0 and #reference_notes == 0 and sense_extlinks ~= nil and #sense_extlinks == 0 and #external_link_table == 0 and #get_any_notes(sections, args, i18n['manual_external_link']) == 0 then table.insert(sections, i18n.rfref_category(lang_name)) end return table.concat(sections,"\n\n") end return p se7njm2volxptk8iwn6z0i7805dajw4 মডিউল:names 828 58828 509312 507793 2026-05-29T06:16:31Z Redmin 6857 'Temporary' stop-gap measure to 'fix' thousands of errors so 'স্ক্রিপ্ট ত্রুটিসহ পাতা' is actually maintainable 509312 Scribunto text/plain local export = {} local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local pron_qualifier_module = "Module:pron qualifier" local enlang = m_languages.getByCode("en") local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local u = m_str_utils.char local function rsub(str, from, to) return (rsubn(str, from, to)) end local TEMP_LESS_THAN = u(0xFFF2) local force_cat = false -- for testing --[=[ FIXME: 1. from=the Bible (DONE) 2. origin=18th century [DONE] 3. popular= (DONE) 4. varoftype= (DONE) 5. eqtype= [DONE] 6. dimoftype= [DONE] 7. from=de:Elisabeth (same language) (DONE) 8. blendof=, blendof2= [DONE] 9. varform, dimform [DONE] 10. from=English < Latin [DONE] 11. usage=rare -> categorize as rare? 12. dimeq= (also vareq=?) [DONE] 13. fromtype= [DONE] 14. <tr:...> and similar params [DONE] ]=] -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "surnames" -- of "male surnames", but not "male surnames" of "female surnames" because "male" only matches a part of the word -- "female") should follow the longer name. export.personal_name_types = { "male surnames", "female surnames", "common-gender surnames", "surnames", "patronymics", "matronymics", } export.personal_name_type_set = m_table.listToSet(export.personal_name_types) export.given_name_genders = { male = {type = "human"}, female = {type = "human"}, unisex = {type = "human", cat = {"male given names", "female given names", "unisex given names"}, article = "a"}, ["unknown-gender"] = {type = "human", cat = {}, track = true}, animal = {type = "animal", track = true}, cat = {type = "animal"}, cow = {type = "animal"}, dog = {type = "animal"}, horse = {type = "animal"}, pig = {type = "animal"}, } local function get_given_name_cats(gender, props) --local cats = props.cat if not cats then if props.type == "animal" then cats = {gender .. " names"} else cats = {gender .. " given names"} end end return cats end do local function do_cat(cat) if not export.personal_name_type_set[cat] then export.personal_name_type_set[cat] = true table.insert(export.personal_name_types, cat) end end for gender, props in pairs(export.given_name_genders) do local cats = get_given_name_cats(gender, props) for _, cat in ipairs(cats) do do_cat("diminutives of " .. cat) do_cat("augmentatives of " .. cat) do_cat(cat) end end do_cat("given names") end local translit_name_type_list = { "surname", "male given name", "female given name", "unisex given name", "patronymic" } local function track(page) require("Module:debug").track("names/" .. page) end -- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also -- remove parens that may surround qualifier or label text preceding a term. local function get_rawtext(text) text = m_utilities.get_plaintext(text) text = text:gsub("[()%[%]]", "") return text end --[=[ Parse a term and associated properties. This works with parameters of the form 'Karlheinz' or 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, and the return value is a list of objects of the form described just above. ]=] local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"link", "l", "q", "ref"}}, {param = "eq", convert = function(eqval, parse_err) return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") end}, } local function generate_obj(term, parse_err) local termlang if allow_explicit_lang then local actual_term actual_term, termlang = require(parse_interface_module).parse_term_with_lang { term = term, --parse_err = parse_err, paramname = paramname, } term = actual_term or term end return { term = term, lang = termlang or deflang, } end return require(parse_interface_module).parse_inline_modifiers(term, { param_mods = param_mods, paramname = paramname, generate_obj = generate_obj, splitchar = allow_multiple_terms and "," or nil, }) end --[=[ Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). ]=] local function link_one_term(termobj, do_language_link) local link if do_language_link and termobj.lang:getCode() == "en" then link = m_links.language_link(termobj) else link = m_links.full_link(termobj) end if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then link = require(pron_qualifier_module).format_qualifiers { lang = termobj.lang, text = link, q = termobj.q, qq = termobj.qq, l = termobj.l, ll = termobj.ll, refs = termobj.refs, } end if termobj.eq then local eqtext = {} for _, eqobj in ipairs(termobj.eq) do table.insert(eqtext, link_one_term(eqobj, true)) end link = link .. " [=" .. m_table.serialCommaJoin(eqtext, {conj = "or"}) .. "]" end return link end --[=[ Link the terms in `terms`, and join them using the conjunction in `conj` (defaulting to "or"). Joining is done using serialCommaJoin() in [[Module:table]], so that e.g. two terms are joined as "TERM or TERM" while three terms are joined as "TERM, TERM or TERM" with special CSS spans before the final "or" to allow an "Oxford comma" to appear if configured appropriately. (However, if `conj` is the special value ", ", joining is done directly using that value.) If `include_langname` is given, the language of the first term will be prepended to the joined terms. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by parse_term_with_annotations(). ]=] local function join_terms(terms, include_langname, do_language_link, conj) local links = {} local langnametext for _, termobj in ipairs(terms) do if include_langname and not langnametext then langnametext = termobj.lang:getCanonicalName() .. " " end table.insert(links, link_one_term(termobj, do_language_link)) end local joined_terms if conj == ", " then joined_terms = table.concat(links, conj) else joined_terms = m_table.serialCommaJoin(links, {conj = conj or "or"}) end return (langnametext or "") .. joined_terms end --[=[ Gather the parameters for multiple names and link each name using full_link() (for foreign names) or language_link() (for English names), joining the names using serialCommaJoin() in [[Module:table]] with the conjunction `conj` (defaulting to "or"). (However, if `conj` is the special value ", ", joining is done directly using that value.) This can be used, for example, to fetch and join all the masculine equivalent names for a feminine given name. Each name is specified using parameters beginning with `pname` in `args`, e.g. "m", "m2", "m3", etc. `lang` is a language object specifying the language of the names (defaulting to English), for use in linking them. If `allow_explicit_lang` is given, the language of the terms can be specified explicitly by prefixing a term with a language code, e.g. 'sv:Björn' or 'la:[[Nicolaus|Nīcolāī]]'. This function assumes that the parameters have already been parsed by [[Module:parameters]] and gathered into lists, so that e.g. all "mN" parameters are in a list in args["m"]. ]=] local function join_names(lang, args, pname, conj, allow_explicit_lang) local termobjs = {} local do_language_link = false if not lang then lang = enlang do_language_link = true end local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, allow_explicit_lang, "allow multiple terms")) do table.insert(termobjs, termobj) end end if not args[pname] then return "", 0 elseif type(args[pname]) == "table" then for i, term in ipairs(args[pname]) do process_one_term(term, i) end else process_one_term(args[pname], 1) end return join_terms(termobjs, nil, do_language_link, conj), #termobjs end local function get_eqtext(args) local eqsegs = {} local lastlang = nil local last_eqseg = {} local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, "allow explicit lang", "allow multiple terms")) do local termlang = termobj.lang:getCode() if lastlang and lastlang ~= termlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = termlang table.insert(last_eqseg, termobj) end end if type(args.eq) == "table" then for i, term in ipairs(args.eq) do process_one_term(term, i) end elseif type(args.eq) == "string" then process_one_term(args.eq, 1) end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs, {conj = "or"}) end local function get_fromtext(lang, args) local catparts = {} local fromsegs = {} local i = 1 local function parse_from(from) local unrecognized = false local prefix, suffix if from == "surnames" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then prefix = "transferred from the " suffix = from:gsub("s$", "") table.insert(catparts, from) elseif from == "patronymics" or from == "matronymics" or from == "coinages" then prefix = "originating " suffix = "as a " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "occupations" or from == "ethnonyms" then prefix = "originating " suffix = "as an " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "the Bible" then prefix = "originating " suffix = "from the Bible" table.insert(catparts, from) else prefix = "from " if from:find(":") then local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") local fromlangname = "" if termobj.lang:getCode() ~= lang:getCode() then -- If name is derived from another name in the same language, don't include lang name after text -- "from " or create a category like "German male given names derived from German". local canonical_name = termobj.lang:getCanonicalName() fromlangname = canonical_name .. " " table.insert(catparts, canonical_name) end suffix = fromlangname .. link_one_term(termobj) else local family = from:match("^(.+) languages$") or from:match("^.+ Languages$") or from:match("^.+ [Ll]ects$") if family then if require("Module:families").getByCanonicalName(family) then table.insert(catparts, from) else unrecognized = true end suffix = "the " .. from else if m_languages.getByCanonicalName(from, nil, "allow etym") then table.insert(catparts, from) else unrecognized = true end suffix = from end end end if unrecognized then track("unrecognized from") track("unrecognized from/" .. from) end return prefix, suffix end local last_fromseg = nil local put = require(parse_utilities_module) local from_args = args.from or {} if type(from_args) == "string" then from_args = {from_args} end while from_args[i] do -- We may have multiple comma-separated items, each of which may have multiple items separated by a -- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle -- this correctly, first replace space-delimited < signs with a special character, then split on balanced -- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on -- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) local comma_separated_groups = put.split_alternating_runs_on_comma(segments) for j, comma_separated_group in ipairs(comma_separated_groups) do comma_separated_groups[j] = table.concat(comma_separated_group) end for _, rawfrom in ipairs(comma_separated_groups) do local froms = rsplit(rawfrom, TEMP_LESS_THAN) if #froms == 1 then local prefix, suffix = parse_from(froms[1]) if last_fromseg and (last_fromseg.has_multiple_froms or last_fromseg.prefix ~= prefix) then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) else if last_fromseg then table.insert(fromsegs, last_fromseg) last_fromseg = nil end local first_suffixpart = "" local rest_suffixparts = {} for j, from in ipairs(froms) do local prefix, suffix = parse_from(from) if j == 1 then first_suffixpart = prefix .. suffix else table.insert(rest_suffixparts, prefix .. suffix) end end local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} end end i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts end local function parse_given_name_genders(genderspec) if export.given_name_genders[genderspec] then -- optimization return {{ type = genderspec, props = export.given_name_genders[genderspec], }}, export.given_name_genders[genderspec].type == "animal" end local genders = {} local is_animal = nil local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"l", "q", "ref"}}, {param = {"text", "article"}}, } local function generate_obj(term, parse_err) if not export.given_name_genders[term] then local valid_genders = {} for k, _ in pairs(export.given_name_genders) do table.insert(valid_genders, k) end table.sort(valid_genders) --parse_err(("Unrecognized gender '%s': valid genders are %s"):format( -- term, table.concat(valid_genders, ", "))) end return { type = term, props = export.given_name_genders[term], } end local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { param_mods = param_mods, paramname = "2", generate_obj = generate_obj, splitchar = ",", }) for _, spec in ipairs(retval) do --local this_is_animal = spec.props.type == "animal" if is_animal == nil then is_animal = this_is_animal elseif is_animal ~= this_is_animal then error("Can't mix animal and human genders") end end return retval, is_animal end local function generate_given_name_genders(lang, genders) local parts = {} for _, spec in ipairs(genders) do local text if spec.text then -- NOTE: This assumes no % sign in the gender type, which seems safe. text = spec.text:gsub("%+", spec.type) else -- if spec.props.type == "animal" then -- text = "[[" .. spec.type .. "]]" -- else -- text = spec.type -- end end if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or spec.refs and spec.refs[1] then text = require(pron_qualifier_module).format_qualifiers { lang = lang, text = text, q = spec.q, qq = spec.qq, l = spec.l, ll = spec.ll, refs = spec.refs, raw = true, } end table.insert(parts, text) end local retval = m_table.serialCommaJoin(parts, {conj = "or"}) local article = genders[1].article --if not article and not genders[1].text and not genders[1].q and not genders[1].l then -- article = genders[1].props.article --end if not article then article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) end return retval, article end -- The entry point for {{given name}}. function export.given_name(frame) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 local lang_index = compat and "lang" or 1 local list = {list = true} local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", default = "und"}, ["gender"] = {default = "unknown-gender"}, [1 + offset] = {alias_of = "gender"}, ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["addl"] = true, -- initial article: A or An ["A"] = true, ["sort"] = true, ["from"] = true, [2 + offset] = {alias_of = "from"}, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["dimof"] = true, ["dimoftype"] = true, ["dim"] = {alias_of = "dimof"}, ["dimtype"] = {alias_of = "dimoftype"}, ["dimform"] = true, ["dimformtype"] = true, ["augof"] = true, ["augoftype"] = true, ["aug"] = {alias_of = "augof"}, ["augtype"] = {alias_of = "augoftype"}, ["augform"] = true, ["augformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local genders, is_animal = parse_given_name_genders(args.gender) local dimoftext, numdimofs = join_names(lang, args, "dimof") local augoftext, numaugofs = join_names(lang, args, "augof") local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") local augformtext, numaugforms = join_names(lang, args, "augform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end local dimoftype = args.dimoftype local augoftype = args.augoftype added_text = nil if numdimofs > 0 then added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " elseif numaugofs > 0 then added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " end force_plural = false if added_text ~= nil then if args.dimof == "-" then dimoftext = "" force_plural = true else added_text = added_text .. "the " end ins(added_text) end local article = args.A if not article and textsegs[1] then article = require(en_utilities_module).get_indefinite_article(textsegs[1]) end if not is_animal then local gendertext, gender_article = generate_given_name_genders(lang, genders) article = article or gender_article ins(gendertext) ins(" ") end ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") article = article or "a" -- if no article set yet, it's "a" based on "given name" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end local need_comma = false if numdimofs > 0 then ins(" " .. dimoftext) need_comma = not is_animal elseif numaugofs > 0 then ins(" " .. augoftext) need_comma = not is_animal elseif xlittext ~= "" then ins(", " .. xlittext) need_comma = true end if is_animal then if need_comma then ins(",") end need_comma = true ins(" for ") local gendertext, gender_article = generate_given_name_genders(lang, genders) ins(gender_article) ins(" ") ins(gendertext) end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end if dimformtext ~= "" then ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. dimformtext) end if augformtext ~= "" then ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. augformtext) end textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(dimaugof) -- if dimaugof == "" and genders[1].props.type == "human" then -- No category such as "English diminutives of given names" -- table.insert(categories, langname .. "given names") --end local function insert_cat(cat) table.insert(categories, langname .. dimaugof .. cat) for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) end end for _, spec in ipairs(genders) do local typ = spec.type --if spec.props.track then -- track(typ) --end local cats = get_given_name_cats(spec.type, spec.props) for _, cat in ipairs(cats) do insert_cat(cat) end end end insert_cats("") if numdimofs > 0 then insert_cats("diminutives of ") elseif numaugofs > 0 then insert_cats("augmentatives of ") end return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{surname}}, {{patronymic}} and {{matronymic}}. function export.surname(frame) local iargs = require("Module:parameters").process(frame.args, { ["type"] = {required = true, set = {"surname", "patronymic", "matronymic"}}, }) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 if parent_args.dot or parent_args.nodot then error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. "period is no longer added by default; if you want it, add it explicitly after the template") end local lang_index = compat and "lang" or 1 local list = {list = true} local gender_arg = iargs.type == "surname" and "g" or 1 + offset local adj_arg = iargs.type == "surname" and 1 + offset or 2 + offset local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", template_default = "und"}, [gender_arg] = iargs.type == "surname" and true or {required = true, template_default = "unknown"}, -- gender(s) [adj_arg] = true, -- adjective/qualifier ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["parent"] = true, ["addl"] = true, -- initial article: by default A or An (English), a or an (otherwise) ["A"] = true, ["sort"] = true, ["from"] = true, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, ["nocat"] = {type = "boolean"}, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local saw_male = false local saw_female = false local genders = {} if args[gender_arg] then for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then g = "unknown-gender" track("unknown gender") elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then g = "common-gender" saw_male = true saw_female = true elseif g == "m" or g == "male" then g = "male" saw_male = true elseif g == "f" or g == "female" then g = "female" saw_female = true else error("Unrecognized gender: " .. g) end table.insert(genders, g) end end local adj = args[adj_arg] local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end if parenttext ~= "" then local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or "son/daughter" table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") -- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is -- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender -- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" -- because the word "surname", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. local article if args.A then article = args.A else article = #genders > 0 and genders[1] == "unknown-gender" and "an" or #genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or "a" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end end ins(article .. " ") if #genders > 0 then ins(table.concat(genders, " or ") .. " ") end if adj then ins(adj .. " ") end ins("[[" .. iargs.type .. "]]") local need_comma = false if xlittext ~= "" then ins(", " .. xlittext) need_comma = true end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end ins("</span>") local text = table.concat(textsegs, "") if args.nocat then return text end local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(g) g = g and g .. " " or "" table.insert(categories, langname .. g .. iargs.type .. "s") for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) end end insert_cats(nil) local function insert_cats_gender(g) if g == "unknown-gender" then return end if g == "common-gender" then insert_cats_gender("male") insert_cats_gender("female") end insert_cats(g) end for _, g in ipairs(genders) do insert_cats_gender(g) end return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. function export.name_translit(frame) local boolean = {type = "boolean"} local iargs = require("Module:parameters").process(frame.args, { ["desctext"] = {required = true}, ["obor"] = boolean, ["foreign_name"] = boolean, }) local parent_args = frame:getParent().args local params = { [1] = {required = true, type = "language", template_default = "en"}, [2] = {required = true, type = "language", sublist = true, template_default = "ru"}, [3] = {list = true, allow_holes = true}, ["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, ["dim"] = boolean, ["aug"] = boolean, ["nocap"] = boolean, ["addl"] = true, ["sort"] = true, ["pagename"] = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = {"xlit", "eq"}}, } local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 3, track_module = "names/name translit", disallow_custom_separators = true, -- Use the first source language as the language of the specified names. lang = function(args) return args[2][1] end, sc = "sc.default", } local lang = args[1] local langcode = lang:getCode() local sources = args[2] local pagename = args.pagename or mw.loadData("Module:headword/data").pagename local textsegs = {} local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") local desctext = iargs.desctext if langcode == "en" and not args.nocap then desctext = mw.getContentLanguage():ucfirst(desctext) end ins(desctext .. " ") if not iargs.foreign_name then ins("of ") end local langsegs = {} for i, source in ipairs(sources) do local sourcename = source:getCanonicalName() local function get_source_link() local term_to_link = names[1] and names[1].term or pagename -- We link the language name to either the first specified name or the pagename, in the following -- circumstances: -- (1) More than one language was given along with at least one name; or -- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. -- The reason for (1) is that if more than one language was given, we want a link to the name -- in each language, as the name that's displayed is linked only to the first specified language. -- However, if only one language was given, linking the language to the name is redundant. -- The reason for (2) is that {{foreign name}} is often used when the name in the destination language -- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), -- and in that case no name will be explicitly specified but we still want a link to the name in the -- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to -- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be -- used for names spelled differently in the destination language (either transliterated or respelled), so -- assuming the pagename is the name in the source language is wrong. if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then return m_links.language_link{ lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" } else return sourcename end end if i == 1 and not iargs.foreign_name then -- If at least one name is given, we say "A transliteration of the LANG surname FOO", linking LANG to FOO. -- Otherwise we say "A transliteration of a LANG surname". if names[1] then table.insert(langsegs, "the " .. get_source_link()) else table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) end else table.insert(langsegs, get_source_link()) end end local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) local augdim_text if args.dim then augdim_text = " [[diminutive]]" elseif args.aug then augdim_text = " [[augmentative]]" else augdim_text = "" end local nametype_linked = {} for _, nametype in ipairs(args["type"]) do if nametype == "surname" or nametype == "patronymic" then table.insert(nametype_linked, "[[" .. nametype .. "]]") elseif nametype == "male given name" then table.insert(nametype_linked, "male [[given name]]") elseif nametype == "female given name" then table.insert(nametype_linked, "female [[given name]]") elseif nametype == "unisex given name" then table.insert(nametype_linked, "unisex [[given name]]") else table.insert(nametype_linked, nametype) end end local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text if not iargs.foreign_name then ins(langseg_text .. " ") ins(nametype_text) if names[1] then ins(" ") end else ins(nametype_text) ins(" in " .. langseg_text) if names[1] then ins(", ") end end local linked_names = {} local embedded_comma = false for _, name in ipairs(names) do local linked_name = m_links.full_link(name, "term") if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or name.refs and name.refs[1] then linked_name = require(pron_qualifier_module).format_qualifiers { lang = name.lang, text = linked_name, q = name.q, qq = name.qq, l = name.l, ll = name.ll, refs = name.refs, raw = true, } end if name.xlit then embedded_comma = true linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } end if name.eq then embedded_comma = true linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } end table.insert(linked_names, linked_name) end if embedded_comma then ins(table.concat(linked_names, "; or of ")) else ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end ins("</span>") local categories = {} local function inscat(cat) table.insert(categories, lang:getFullName() .. " " .. cat) end for _, nametype in ipairs(args.type) do local function insert_cats(dimaugof) local function insert_cats_type(ty) if ty == "unisex given name" then insert_cats_type("male given name") insert_cats_type("female given name") end for _, source in ipairs(sources) do inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") inscat("terms derived from " .. source:getCanonicalName()) inscat("terms borrowed from " .. source:getCanonicalName()) if iargs.obor then inscat("orthographic borrowings from " .. source:getCanonicalName()) end if source:getCode() ~= source:getFullCode() then -- etymology language inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") end end end insert_cats_type(nametype) end insert_cats("") if args.dim then insert_cats("diminutives of ") end if args.aug then insert_cats("augmentatives of ") end end return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end return export d3iugldnp4xg7pcbn4tfu7y6q3077fm 509317 509312 2026-05-29T07:01:54Z Redmin 6857 509317 Scribunto text/plain local export = {} local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local pron_qualifier_module = "Module:pron qualifier" local enlang = m_languages.getByCode("en") local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local u = m_str_utils.char local function rsub(str, from, to) return (rsubn(str, from, to)) end local TEMP_LESS_THAN = u(0xFFF2) local force_cat = false -- for testing --[=[ FIXME: 1. from=the Bible (DONE) 2. origin=18th century [DONE] 3. popular= (DONE) 4. varoftype= (DONE) 5. eqtype= [DONE] 6. dimoftype= [DONE] 7. from=de:Elisabeth (same language) (DONE) 8. blendof=, blendof2= [DONE] 9. varform, dimform [DONE] 10. from=English < Latin [DONE] 11. usage=rare -> categorize as rare? 12. dimeq= (also vareq=?) [DONE] 13. fromtype= [DONE] 14. <tr:...> and similar params [DONE] ]=] -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "পদবি" -- of "male পদবি", but not "male পদবি" of "female পদবি" because "male" only matches a part of the word -- "female") should follow the longer name. export.personal_name_types = { "male পদবি", "female পদবি", "common-gender পদবি", "পদবি", "patronymics", "matronymics", } export.personal_name_type_set = m_table.listToSet(export.personal_name_types) export.given_name_genders = { male = {type = "human"}, female = {type = "human"}, unisex = {type = "human", cat = {"male given names", "female given names", "unisex given names"}, article = "a"}, ["unknown-gender"] = {type = "human", cat = {}, track = true}, animal = {type = "animal", track = true}, cat = {type = "animal"}, cow = {type = "animal"}, dog = {type = "animal"}, horse = {type = "animal"}, pig = {type = "animal"}, } local function get_given_name_cats(gender, props) --local cats = props.cat if not cats then if props.type == "animal" then cats = {gender .. " names"} else cats = {gender .. " given names"} end end return cats end do local function do_cat(cat) if not export.personal_name_type_set[cat] then export.personal_name_type_set[cat] = true table.insert(export.personal_name_types, cat) end end for gender, props in pairs(export.given_name_genders) do local cats = get_given_name_cats(gender, props) for _, cat in ipairs(cats) do do_cat("diminutives of " .. cat) do_cat("augmentatives of " .. cat) do_cat(cat) end end do_cat("given names") end local translit_name_type_list = { "পদবি", "male given name", "female given name", "unisex given name", "patronymic" } local function track(page) require("Module:debug").track("names/" .. page) end -- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also -- remove parens that may surround qualifier or label text preceding a term. local function get_rawtext(text) text = m_utilities.get_plaintext(text) text = text:gsub("[()%[%]]", "") return text end --[=[ Parse a term and associated properties. This works with parameters of the form 'Karlheinz' or 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, and the return value is a list of objects of the form described just above. ]=] local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"link", "l", "q", "ref"}}, {param = "eq", convert = function(eqval, parse_err) return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") end}, } local function generate_obj(term, parse_err) local termlang if allow_explicit_lang then local actual_term actual_term, termlang = require(parse_interface_module).parse_term_with_lang { term = term, --parse_err = parse_err, paramname = paramname, } term = actual_term or term end return { term = term, lang = termlang or deflang, } end return require(parse_interface_module).parse_inline_modifiers(term, { param_mods = param_mods, paramname = paramname, generate_obj = generate_obj, splitchar = allow_multiple_terms and "," or nil, }) end --[=[ Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). ]=] local function link_one_term(termobj, do_language_link) local link if do_language_link and termobj.lang:getCode() == "en" then link = m_links.language_link(termobj) else link = m_links.full_link(termobj) end if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then link = require(pron_qualifier_module).format_qualifiers { lang = termobj.lang, text = link, q = termobj.q, qq = termobj.qq, l = termobj.l, ll = termobj.ll, refs = termobj.refs, } end if termobj.eq then local eqtext = {} for _, eqobj in ipairs(termobj.eq) do table.insert(eqtext, link_one_term(eqobj, true)) end link = link .. " [=" .. m_table.serialCommaJoin(eqtext, {conj = "or"}) .. "]" end return link end --[=[ Link the terms in `terms`, and join them using the conjunction in `conj` (defaulting to "or"). Joining is done using serialCommaJoin() in [[Module:table]], so that e.g. two terms are joined as "TERM or TERM" while three terms are joined as "TERM, TERM or TERM" with special CSS spans before the final "or" to allow an "Oxford comma" to appear if configured appropriately. (However, if `conj` is the special value ", ", joining is done directly using that value.) If `include_langname` is given, the language of the first term will be prepended to the joined terms. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by parse_term_with_annotations(). ]=] local function join_terms(terms, include_langname, do_language_link, conj) local links = {} local langnametext for _, termobj in ipairs(terms) do if include_langname and not langnametext then langnametext = termobj.lang:getCanonicalName() .. " " end table.insert(links, link_one_term(termobj, do_language_link)) end local joined_terms if conj == ", " then joined_terms = table.concat(links, conj) else joined_terms = m_table.serialCommaJoin(links, {conj = conj or "or"}) end return (langnametext or "") .. joined_terms end --[=[ Gather the parameters for multiple names and link each name using full_link() (for foreign names) or language_link() (for English names), joining the names using serialCommaJoin() in [[Module:table]] with the conjunction `conj` (defaulting to "or"). (However, if `conj` is the special value ", ", joining is done directly using that value.) This can be used, for example, to fetch and join all the masculine equivalent names for a feminine given name. Each name is specified using parameters beginning with `pname` in `args`, e.g. "m", "m2", "m3", etc. `lang` is a language object specifying the language of the names (defaulting to English), for use in linking them. If `allow_explicit_lang` is given, the language of the terms can be specified explicitly by prefixing a term with a language code, e.g. 'sv:Björn' or 'la:[[Nicolaus|Nīcolāī]]'. This function assumes that the parameters have already been parsed by [[Module:parameters]] and gathered into lists, so that e.g. all "mN" parameters are in a list in args["m"]. ]=] local function join_names(lang, args, pname, conj, allow_explicit_lang) local termobjs = {} local do_language_link = false if not lang then lang = enlang do_language_link = true end local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, allow_explicit_lang, "allow multiple terms")) do table.insert(termobjs, termobj) end end if not args[pname] then return "", 0 elseif type(args[pname]) == "table" then for i, term in ipairs(args[pname]) do process_one_term(term, i) end else process_one_term(args[pname], 1) end return join_terms(termobjs, nil, do_language_link, conj), #termobjs end local function get_eqtext(args) local eqsegs = {} local lastlang = nil local last_eqseg = {} local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, "allow explicit lang", "allow multiple terms")) do local termlang = termobj.lang:getCode() if lastlang and lastlang ~= termlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = termlang table.insert(last_eqseg, termobj) end end if type(args.eq) == "table" then for i, term in ipairs(args.eq) do process_one_term(term, i) end elseif type(args.eq) == "string" then process_one_term(args.eq, 1) end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs, {conj = "or"}) end local function get_fromtext(lang, args) local catparts = {} local fromsegs = {} local i = 1 local function parse_from(from) local unrecognized = false local prefix, suffix if from == "পদবি" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then prefix = "transferred from the " suffix = from:gsub("s$", "") table.insert(catparts, from) elseif from == "patronymics" or from == "matronymics" or from == "coinages" then prefix = "originating " suffix = "as a " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "occupations" or from == "ethnonyms" then prefix = "originating " suffix = "as an " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "the Bible" then prefix = "originating " suffix = "from the Bible" table.insert(catparts, from) else prefix = "from " if from:find(":") then local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") local fromlangname = "" if termobj.lang:getCode() ~= lang:getCode() then -- If name is derived from another name in the same language, don't include lang name after text -- "from " or create a category like "German male given names derived from German". local canonical_name = termobj.lang:getCanonicalName() fromlangname = canonical_name .. " " table.insert(catparts, canonical_name) end suffix = fromlangname .. link_one_term(termobj) else local family = from:match("^(.+) languages$") or from:match("^.+ Languages$") or from:match("^.+ [Ll]ects$") if family then if require("Module:families").getByCanonicalName(family) then table.insert(catparts, from) else unrecognized = true end suffix = "the " .. from else if m_languages.getByCanonicalName(from, nil, "allow etym") then table.insert(catparts, from) else unrecognized = true end suffix = from end end end if unrecognized then track("unrecognized from") track("unrecognized from/" .. from) end return prefix, suffix end local last_fromseg = nil local put = require(parse_utilities_module) local from_args = args.from or {} if type(from_args) == "string" then from_args = {from_args} end while from_args[i] do -- We may have multiple comma-separated items, each of which may have multiple items separated by a -- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle -- this correctly, first replace space-delimited < signs with a special character, then split on balanced -- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on -- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) local comma_separated_groups = put.split_alternating_runs_on_comma(segments) for j, comma_separated_group in ipairs(comma_separated_groups) do comma_separated_groups[j] = table.concat(comma_separated_group) end for _, rawfrom in ipairs(comma_separated_groups) do local froms = rsplit(rawfrom, TEMP_LESS_THAN) if #froms == 1 then local prefix, suffix = parse_from(froms[1]) if last_fromseg and (last_fromseg.has_multiple_froms or last_fromseg.prefix ~= prefix) then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) else if last_fromseg then table.insert(fromsegs, last_fromseg) last_fromseg = nil end local first_suffixpart = "" local rest_suffixparts = {} for j, from in ipairs(froms) do local prefix, suffix = parse_from(from) if j == 1 then first_suffixpart = prefix .. suffix else table.insert(rest_suffixparts, prefix .. suffix) end end local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} end end i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts end local function parse_given_name_genders(genderspec) if export.given_name_genders[genderspec] then -- optimization return {{ type = genderspec, props = export.given_name_genders[genderspec], }}, export.given_name_genders[genderspec].type == "animal" end local genders = {} local is_animal = nil local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"l", "q", "ref"}}, {param = {"text", "article"}}, } local function generate_obj(term, parse_err) if not export.given_name_genders[term] then local valid_genders = {} for k, _ in pairs(export.given_name_genders) do table.insert(valid_genders, k) end table.sort(valid_genders) --parse_err(("Unrecognized gender '%s': valid genders are %s"):format( -- term, table.concat(valid_genders, ", "))) end return { type = term, props = export.given_name_genders[term], } end local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { param_mods = param_mods, paramname = "2", generate_obj = generate_obj, splitchar = ",", }) for _, spec in ipairs(retval) do --local this_is_animal = spec.props.type == "animal" if is_animal == nil then is_animal = this_is_animal elseif is_animal ~= this_is_animal then error("Can't mix animal and human genders") end end return retval, is_animal end local function generate_given_name_genders(lang, genders) local parts = {} for _, spec in ipairs(genders) do local text if spec.text then -- NOTE: This assumes no % sign in the gender type, which seems safe. text = spec.text:gsub("%+", spec.type) else -- if spec.props.type == "animal" then -- text = "[[" .. spec.type .. "]]" -- else -- text = spec.type -- end end if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or spec.refs and spec.refs[1] then text = require(pron_qualifier_module).format_qualifiers { lang = lang, text = text, q = spec.q, qq = spec.qq, l = spec.l, ll = spec.ll, refs = spec.refs, raw = true, } end table.insert(parts, text) end local retval = m_table.serialCommaJoin(parts, {conj = "or"}) local article = genders[1].article --if not article and not genders[1].text and not genders[1].q and not genders[1].l then -- article = genders[1].props.article --end if not article then article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) end return retval, article end -- The entry point for {{given name}}. function export.given_name(frame) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 local lang_index = compat and "lang" or 1 local list = {list = true} local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", default = "und"}, ["gender"] = {default = "unknown-gender"}, [1 + offset] = {alias_of = "gender"}, ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["addl"] = true, -- initial article: A or An ["A"] = true, ["sort"] = true, ["from"] = true, [2 + offset] = {alias_of = "from"}, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["dimof"] = true, ["dimoftype"] = true, ["dim"] = {alias_of = "dimof"}, ["dimtype"] = {alias_of = "dimoftype"}, ["dimform"] = true, ["dimformtype"] = true, ["augof"] = true, ["augoftype"] = true, ["aug"] = {alias_of = "augof"}, ["augtype"] = {alias_of = "augoftype"}, ["augform"] = true, ["augformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local genders, is_animal = parse_given_name_genders(args.gender) local dimoftext, numdimofs = join_names(lang, args, "dimof") local augoftext, numaugofs = join_names(lang, args, "augof") local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") local augformtext, numaugforms = join_names(lang, args, "augform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end local dimoftype = args.dimoftype local augoftype = args.augoftype added_text = nil if numdimofs > 0 then added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " elseif numaugofs > 0 then added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " end force_plural = false if added_text ~= nil then if args.dimof == "-" then dimoftext = "" force_plural = true else added_text = added_text .. "the " end ins(added_text) end local article = args.A if not article and textsegs[1] then article = require(en_utilities_module).get_indefinite_article(textsegs[1]) end if not is_animal then local gendertext, gender_article = generate_given_name_genders(lang, genders) article = article or gender_article ins(gendertext) ins(" ") end ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") article = article or "a" -- if no article set yet, it's "a" based on "given name" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end local need_comma = false if numdimofs > 0 then ins(" " .. dimoftext) need_comma = not is_animal elseif numaugofs > 0 then ins(" " .. augoftext) need_comma = not is_animal elseif xlittext ~= "" then ins(", " .. xlittext) need_comma = true end if is_animal then if need_comma then ins(",") end need_comma = true ins(" for ") local gendertext, gender_article = generate_given_name_genders(lang, genders) ins(gender_article) ins(" ") ins(gendertext) end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end if dimformtext ~= "" then ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. dimformtext) end if augformtext ~= "" then ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. augformtext) end textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(dimaugof) -- if dimaugof == "" and genders[1].props.type == "human" then -- No category such as "English diminutives of given names" -- table.insert(categories, langname .. "given names") --end local function insert_cat(cat) table.insert(categories, langname .. dimaugof .. cat) for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) end end for _, spec in ipairs(genders) do local typ = spec.type --if spec.props.track then -- track(typ) --end local cats = get_given_name_cats(spec.type, spec.props) for _, cat in ipairs(cats) do insert_cat(cat) end end end insert_cats("") if numdimofs > 0 then insert_cats("diminutives of ") elseif numaugofs > 0 then insert_cats("augmentatives of ") end return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{পদবি}}, {{patronymic}} and {{matronymic}}. function export.surname(frame) local iargs = require("Module:parameters").process(frame.args, { ["type"] = {required = true, set = {"পদবি", "patronymic", "matronymic"}}, }) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 if parent_args.dot or parent_args.nodot then error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. "period is no longer added by default; if you want it, add it explicitly after the template") end local lang_index = compat and "lang" or 1 local list = {list = true} local gender_arg = iargs.type == "পদবি" and "g" or 1 + offset local adj_arg = iargs.type == "পদবি" and 1 + offset or 2 + offset local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", template_default = "und"}, [gender_arg] = iargs.type == "পদবি" and true or {required = true, template_default = "unknown"}, -- gender(s) [adj_arg] = true, -- adjective/qualifier ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["parent"] = true, ["addl"] = true, -- initial article: by default A or An (English), a or an (otherwise) ["A"] = true, ["sort"] = true, ["from"] = true, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, ["nocat"] = {type = "boolean"}, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local saw_male = false local saw_female = false local genders = {} if args[gender_arg] then for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then g = "unknown-gender" track("unknown gender") elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then g = "common-gender" saw_male = true saw_female = true elseif g == "m" or g == "male" then g = "male" saw_male = true elseif g == "f" or g == "female" then g = "female" saw_female = true else error("Unrecognized gender: " .. g) end table.insert(genders, g) end end local adj = args[adj_arg] local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end if parenttext ~= "" then local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or "son/daughter" table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") -- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is -- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender -- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" -- because the word "পদবি", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. local article if args.A then article = args.A else article = #genders > 0 and genders[1] == "unknown-gender" and "an" or #genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or "a" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end end ins(article .. " ") if #genders > 0 then ins(table.concat(genders, " or ") .. " ") end if adj then ins(adj .. " ") end ins("[[" .. iargs.type .. "]]") local need_comma = false if xlittext ~= "" then ins(", " .. xlittext) need_comma = true end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end ins("</span>") local text = table.concat(textsegs, "") if args.nocat then return text end local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(g) g = g and g .. " " or "" table.insert(categories, langname .. g .. iargs.type .. "s") for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) end end insert_cats(nil) local function insert_cats_gender(g) if g == "unknown-gender" then return end if g == "common-gender" then insert_cats_gender("male") insert_cats_gender("female") end insert_cats(g) end for _, g in ipairs(genders) do insert_cats_gender(g) end return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. function export.name_translit(frame) local boolean = {type = "boolean"} local iargs = require("Module:parameters").process(frame.args, { ["desctext"] = {required = true}, ["obor"] = boolean, ["foreign_name"] = boolean, }) local parent_args = frame:getParent().args local params = { [1] = {required = true, type = "language", template_default = "en"}, [2] = {required = true, type = "language", sublist = true, template_default = "ru"}, [3] = {list = true, allow_holes = true}, ["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, ["dim"] = boolean, ["aug"] = boolean, ["nocap"] = boolean, ["addl"] = true, ["sort"] = true, ["pagename"] = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = {"xlit", "eq"}}, } local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 3, track_module = "names/name translit", disallow_custom_separators = true, -- Use the first source language as the language of the specified names. lang = function(args) return args[2][1] end, sc = "sc.default", } local lang = args[1] local langcode = lang:getCode() local sources = args[2] local pagename = args.pagename or mw.loadData("Module:headword/data").pagename local textsegs = {} local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") local desctext = iargs.desctext if langcode == "en" and not args.nocap then desctext = mw.getContentLanguage():ucfirst(desctext) end ins(desctext .. " ") if not iargs.foreign_name then ins("of ") end local langsegs = {} for i, source in ipairs(sources) do local sourcename = source:getCanonicalName() local function get_source_link() local term_to_link = names[1] and names[1].term or pagename -- We link the language name to either the first specified name or the pagename, in the following -- circumstances: -- (1) More than one language was given along with at least one name; or -- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. -- The reason for (1) is that if more than one language was given, we want a link to the name -- in each language, as the name that's displayed is linked only to the first specified language. -- However, if only one language was given, linking the language to the name is redundant. -- The reason for (2) is that {{foreign name}} is often used when the name in the destination language -- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), -- and in that case no name will be explicitly specified but we still want a link to the name in the -- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to -- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be -- used for names spelled differently in the destination language (either transliterated or respelled), so -- assuming the pagename is the name in the source language is wrong. if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then return m_links.language_link{ lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" } else return sourcename end end if i == 1 and not iargs.foreign_name then -- If at least one name is given, we say "A transliteration of the LANG পদবি FOO", linking LANG to FOO. -- Otherwise we say "A transliteration of a LANG পদবি". if names[1] then table.insert(langsegs, "the " .. get_source_link()) else table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) end else table.insert(langsegs, get_source_link()) end end local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) local augdim_text if args.dim then augdim_text = " [[diminutive]]" elseif args.aug then augdim_text = " [[augmentative]]" else augdim_text = "" end local nametype_linked = {} for _, nametype in ipairs(args["type"]) do if nametype == "পদবি" or nametype == "patronymic" then table.insert(nametype_linked, "[[" .. nametype .. "]]") elseif nametype == "male given name" then table.insert(nametype_linked, "male [[given name]]") elseif nametype == "female given name" then table.insert(nametype_linked, "female [[given name]]") elseif nametype == "unisex given name" then table.insert(nametype_linked, "unisex [[given name]]") else table.insert(nametype_linked, nametype) end end local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text if not iargs.foreign_name then ins(langseg_text .. " ") ins(nametype_text) if names[1] then ins(" ") end else ins(nametype_text) ins(" in " .. langseg_text) if names[1] then ins(", ") end end local linked_names = {} local embedded_comma = false for _, name in ipairs(names) do local linked_name = m_links.full_link(name, "term") if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or name.refs and name.refs[1] then linked_name = require(pron_qualifier_module).format_qualifiers { lang = name.lang, text = linked_name, q = name.q, qq = name.qq, l = name.l, ll = name.ll, refs = name.refs, raw = true, } end if name.xlit then embedded_comma = true linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } end if name.eq then embedded_comma = true linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } end table.insert(linked_names, linked_name) end if embedded_comma then ins(table.concat(linked_names, "; or of ")) else ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end ins("</span>") local categories = {} local function inscat(cat) table.insert(categories, lang:getFullName() .. " " .. cat) end for _, nametype in ipairs(args.type) do local function insert_cats(dimaugof) local function insert_cats_type(ty) if ty == "unisex given name" then insert_cats_type("male given name") insert_cats_type("female given name") end for _, source in ipairs(sources) do inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") inscat("terms derived from " .. source:getCanonicalName()) inscat("terms borrowed from " .. source:getCanonicalName()) if iargs.obor then inscat("orthographic borrowings from " .. source:getCanonicalName()) end if source:getCode() ~= source:getFullCode() then -- etymology language inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") end end end insert_cats_type(nametype) end insert_cats("") if args.dim then insert_cats("diminutives of ") end if args.aug then insert_cats("augmentatives of ") end end return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end return export qdfi8ttpmp2q1hre80nh35kferzn3pq 509323 509317 2026-05-29T08:34:15Z Redmin 6857 509323 Scribunto text/plain local export = {} local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local pron_qualifier_module = "Module:pron qualifier" local enlang = m_languages.getByCode("en") local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local u = m_str_utils.char local function rsub(str, from, to) return (rsubn(str, from, to)) end local TEMP_LESS_THAN = u(0xFFF2) local force_cat = false -- for testing --[=[ FIXME: 1. from=the Bible (DONE) 2. origin=18th century [DONE] 3. popular= (DONE) 4. varoftype= (DONE) 5. eqtype= [DONE] 6. dimoftype= [DONE] 7. from=de:Elisabeth (same language) (DONE) 8. blendof=, blendof2= [DONE] 9. varform, dimform [DONE] 10. from=English < Latin [DONE] 11. usage=rare -> categorize as rare? 12. dimeq= (also vareq=?) [DONE] 13. fromtype= [DONE] 14. <tr:...> and similar params [DONE] ]=] -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "পদবি" -- of "male পদবি", but not "male পদবি" of "female পদবি" because "male" only matches a part of the word -- "female") should follow the longer name. export.personal_name_types = { "male পদবি", "female পদবি", "common-gender পদবি", "পদবি", "patronymics", "matronymics", } export.personal_name_type_set = m_table.listToSet(export.personal_name_types) export.given_name_genders = { male = {type = "human"}, female = {type = "human"}, unisex = {type = "human", cat = {"male given names", "পুরুষবাচক মূল নাম", "female given names", "unisex given names"}, article = "a"}, ["unknown-gender"] = {type = "human", cat = {}, track = true}, animal = {type = "animal", track = true}, cat = {type = "animal"}, cow = {type = "animal"}, dog = {type = "animal"}, horse = {type = "animal"}, pig = {type = "animal"}, } local function get_given_name_cats(gender, props) --local cats = props.cat if not cats then if props.type == "animal" then cats = {gender .. " names"} else cats = {gender .. " given names"} end end return cats end do local function do_cat(cat) if not export.personal_name_type_set[cat] then export.personal_name_type_set[cat] = true table.insert(export.personal_name_types, cat) end end for gender, props in pairs(export.given_name_genders) do local cats = get_given_name_cats(gender, props) for _, cat in ipairs(cats) do do_cat("diminutives of " .. cat) do_cat("augmentatives of " .. cat) do_cat(cat) end end do_cat("given names") end local translit_name_type_list = { "পদবি", "male given name", "female given name", "unisex given name", "patronymic" } local function track(page) require("Module:debug").track("names/" .. page) end -- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also -- remove parens that may surround qualifier or label text preceding a term. local function get_rawtext(text) text = m_utilities.get_plaintext(text) text = text:gsub("[()%[%]]", "") return text end --[=[ Parse a term and associated properties. This works with parameters of the form 'Karlheinz' or 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, and the return value is a list of objects of the form described just above. ]=] local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"link", "l", "q", "ref"}}, {param = "eq", convert = function(eqval, parse_err) return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") end}, } local function generate_obj(term, parse_err) local termlang if allow_explicit_lang then local actual_term actual_term, termlang = require(parse_interface_module).parse_term_with_lang { term = term, --parse_err = parse_err, paramname = paramname, } term = actual_term or term end return { term = term, lang = termlang or deflang, } end return require(parse_interface_module).parse_inline_modifiers(term, { param_mods = param_mods, paramname = paramname, generate_obj = generate_obj, splitchar = allow_multiple_terms and "," or nil, }) end --[=[ Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). ]=] local function link_one_term(termobj, do_language_link) local link if do_language_link and termobj.lang:getCode() == "en" then link = m_links.language_link(termobj) else link = m_links.full_link(termobj) end if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then link = require(pron_qualifier_module).format_qualifiers { lang = termobj.lang, text = link, q = termobj.q, qq = termobj.qq, l = termobj.l, ll = termobj.ll, refs = termobj.refs, } end if termobj.eq then local eqtext = {} for _, eqobj in ipairs(termobj.eq) do table.insert(eqtext, link_one_term(eqobj, true)) end link = link .. " [=" .. m_table.serialCommaJoin(eqtext, {conj = "or"}) .. "]" end return link end --[=[ Link the terms in `terms`, and join them using the conjunction in `conj` (defaulting to "or"). Joining is done using serialCommaJoin() in [[Module:table]], so that e.g. two terms are joined as "TERM or TERM" while three terms are joined as "TERM, TERM or TERM" with special CSS spans before the final "or" to allow an "Oxford comma" to appear if configured appropriately. (However, if `conj` is the special value ", ", joining is done directly using that value.) If `include_langname` is given, the language of the first term will be prepended to the joined terms. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by parse_term_with_annotations(). ]=] local function join_terms(terms, include_langname, do_language_link, conj) local links = {} local langnametext for _, termobj in ipairs(terms) do if include_langname and not langnametext then langnametext = termobj.lang:getCanonicalName() .. " " end table.insert(links, link_one_term(termobj, do_language_link)) end local joined_terms if conj == ", " then joined_terms = table.concat(links, conj) else joined_terms = m_table.serialCommaJoin(links, {conj = conj or "or"}) end return (langnametext or "") .. joined_terms end --[=[ Gather the parameters for multiple names and link each name using full_link() (for foreign names) or language_link() (for English names), joining the names using serialCommaJoin() in [[Module:table]] with the conjunction `conj` (defaulting to "or"). (However, if `conj` is the special value ", ", joining is done directly using that value.) This can be used, for example, to fetch and join all the masculine equivalent names for a feminine given name. Each name is specified using parameters beginning with `pname` in `args`, e.g. "m", "m2", "m3", etc. `lang` is a language object specifying the language of the names (defaulting to English), for use in linking them. If `allow_explicit_lang` is given, the language of the terms can be specified explicitly by prefixing a term with a language code, e.g. 'sv:Björn' or 'la:[[Nicolaus|Nīcolāī]]'. This function assumes that the parameters have already been parsed by [[Module:parameters]] and gathered into lists, so that e.g. all "mN" parameters are in a list in args["m"]. ]=] local function join_names(lang, args, pname, conj, allow_explicit_lang) local termobjs = {} local do_language_link = false if not lang then lang = enlang do_language_link = true end local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, allow_explicit_lang, "allow multiple terms")) do table.insert(termobjs, termobj) end end if not args[pname] then return "", 0 elseif type(args[pname]) == "table" then for i, term in ipairs(args[pname]) do process_one_term(term, i) end else process_one_term(args[pname], 1) end return join_terms(termobjs, nil, do_language_link, conj), #termobjs end local function get_eqtext(args) local eqsegs = {} local lastlang = nil local last_eqseg = {} local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, "allow explicit lang", "allow multiple terms")) do local termlang = termobj.lang:getCode() if lastlang and lastlang ~= termlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = termlang table.insert(last_eqseg, termobj) end end if type(args.eq) == "table" then for i, term in ipairs(args.eq) do process_one_term(term, i) end elseif type(args.eq) == "string" then process_one_term(args.eq, 1) end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs, {conj = "or"}) end local function get_fromtext(lang, args) local catparts = {} local fromsegs = {} local i = 1 local function parse_from(from) local unrecognized = false local prefix, suffix if from == "পদবি" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then prefix = "transferred from the " suffix = from:gsub("s$", "") table.insert(catparts, from) elseif from == "patronymics" or from == "matronymics" or from == "coinages" then prefix = "originating " suffix = "as a " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "occupations" or from == "ethnonyms" then prefix = "originating " suffix = "as an " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "the Bible" then prefix = "originating " suffix = "from the Bible" table.insert(catparts, from) else prefix = "from " if from:find(":") then local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") local fromlangname = "" if termobj.lang:getCode() ~= lang:getCode() then -- If name is derived from another name in the same language, don't include lang name after text -- "from " or create a category like "German male given names derived from German". local canonical_name = termobj.lang:getCanonicalName() fromlangname = canonical_name .. " " table.insert(catparts, canonical_name) end suffix = fromlangname .. link_one_term(termobj) else local family = from:match("^(.+) languages$") or from:match("^.+ Languages$") or from:match("^.+ [Ll]ects$") if family then if require("Module:families").getByCanonicalName(family) then table.insert(catparts, from) else unrecognized = true end suffix = "the " .. from else if m_languages.getByCanonicalName(from, nil, "allow etym") then table.insert(catparts, from) else unrecognized = true end suffix = from end end end if unrecognized then track("unrecognized from") track("unrecognized from/" .. from) end return prefix, suffix end local last_fromseg = nil local put = require(parse_utilities_module) local from_args = args.from or {} if type(from_args) == "string" then from_args = {from_args} end while from_args[i] do -- We may have multiple comma-separated items, each of which may have multiple items separated by a -- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle -- this correctly, first replace space-delimited < signs with a special character, then split on balanced -- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on -- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) local comma_separated_groups = put.split_alternating_runs_on_comma(segments) for j, comma_separated_group in ipairs(comma_separated_groups) do comma_separated_groups[j] = table.concat(comma_separated_group) end for _, rawfrom in ipairs(comma_separated_groups) do local froms = rsplit(rawfrom, TEMP_LESS_THAN) if #froms == 1 then local prefix, suffix = parse_from(froms[1]) if last_fromseg and (last_fromseg.has_multiple_froms or last_fromseg.prefix ~= prefix) then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) else if last_fromseg then table.insert(fromsegs, last_fromseg) last_fromseg = nil end local first_suffixpart = "" local rest_suffixparts = {} for j, from in ipairs(froms) do local prefix, suffix = parse_from(from) if j == 1 then first_suffixpart = prefix .. suffix else table.insert(rest_suffixparts, prefix .. suffix) end end local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} end end i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts end local function parse_given_name_genders(genderspec) if export.given_name_genders[genderspec] then -- optimization return {{ type = genderspec, props = export.given_name_genders[genderspec], }}, export.given_name_genders[genderspec].type == "animal" end local genders = {} local is_animal = nil local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"l", "q", "ref"}}, {param = {"text", "article"}}, } local function generate_obj(term, parse_err) if not export.given_name_genders[term] then local valid_genders = {} for k, _ in pairs(export.given_name_genders) do table.insert(valid_genders, k) end table.sort(valid_genders) --parse_err(("Unrecognized gender '%s': valid genders are %s"):format( -- term, table.concat(valid_genders, ", "))) end return { type = term, props = export.given_name_genders[term], } end local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { param_mods = param_mods, paramname = "2", generate_obj = generate_obj, splitchar = ",", }) for _, spec in ipairs(retval) do --local this_is_animal = spec.props.type == "animal" if is_animal == nil then is_animal = this_is_animal elseif is_animal ~= this_is_animal then error("Can't mix animal and human genders") end end return retval, is_animal end local function generate_given_name_genders(lang, genders) local parts = {} for _, spec in ipairs(genders) do local text if spec.text then -- NOTE: This assumes no % sign in the gender type, which seems safe. text = spec.text:gsub("%+", spec.type) else -- if spec.props.type == "animal" then -- text = "[[" .. spec.type .. "]]" -- else -- text = spec.type -- end end if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or spec.refs and spec.refs[1] then text = require(pron_qualifier_module).format_qualifiers { lang = lang, text = text, q = spec.q, qq = spec.qq, l = spec.l, ll = spec.ll, refs = spec.refs, raw = true, } end table.insert(parts, text) end local retval = m_table.serialCommaJoin(parts, {conj = "or"}) local article = genders[1].article --if not article and not genders[1].text and not genders[1].q and not genders[1].l then -- article = genders[1].props.article --end if not article then article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) end return retval, article end -- The entry point for {{given name}}. function export.given_name(frame) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 local lang_index = compat and "lang" or 1 local list = {list = true} local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", default = "und"}, ["gender"] = {default = "unknown-gender"}, [1 + offset] = {alias_of = "gender"}, ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["addl"] = true, -- initial article: A or An ["A"] = true, ["sort"] = true, ["from"] = true, [2 + offset] = {alias_of = "from"}, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["dimof"] = true, ["dimoftype"] = true, ["dim"] = {alias_of = "dimof"}, ["dimtype"] = {alias_of = "dimoftype"}, ["dimform"] = true, ["dimformtype"] = true, ["augof"] = true, ["augoftype"] = true, ["aug"] = {alias_of = "augof"}, ["augtype"] = {alias_of = "augoftype"}, ["augform"] = true, ["augformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local genders, is_animal = parse_given_name_genders(args.gender) local dimoftext, numdimofs = join_names(lang, args, "dimof") local augoftext, numaugofs = join_names(lang, args, "augof") local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") local augformtext, numaugforms = join_names(lang, args, "augform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end local dimoftype = args.dimoftype local augoftype = args.augoftype added_text = nil if numdimofs > 0 then added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " elseif numaugofs > 0 then added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " end force_plural = false if added_text ~= nil then if args.dimof == "-" then dimoftext = "" force_plural = true else added_text = added_text .. "the " end ins(added_text) end local article = args.A if not article and textsegs[1] then article = require(en_utilities_module).get_indefinite_article(textsegs[1]) end if not is_animal then local gendertext, gender_article = generate_given_name_genders(lang, genders) article = article or gender_article ins(gendertext) ins(" ") end ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") article = article or "a" -- if no article set yet, it's "a" based on "given name" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end local need_comma = false if numdimofs > 0 then ins(" " .. dimoftext) need_comma = not is_animal elseif numaugofs > 0 then ins(" " .. augoftext) need_comma = not is_animal elseif xlittext ~= "" then ins(", " .. xlittext) need_comma = true end if is_animal then if need_comma then ins(",") end need_comma = true ins(" for ") local gendertext, gender_article = generate_given_name_genders(lang, genders) ins(gender_article) ins(" ") ins(gendertext) end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end if dimformtext ~= "" then ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. dimformtext) end if augformtext ~= "" then ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. augformtext) end textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(dimaugof) -- if dimaugof == "" and genders[1].props.type == "human" then -- No category such as "English diminutives of given names" -- table.insert(categories, langname .. "given names") --end local function insert_cat(cat) table.insert(categories, langname .. dimaugof .. cat) for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) end end for _, spec in ipairs(genders) do local typ = spec.type --if spec.props.track then -- track(typ) --end local cats = get_given_name_cats(spec.type, spec.props) for _, cat in ipairs(cats) do insert_cat(cat) end end end insert_cats("") if numdimofs > 0 then insert_cats("diminutives of ") elseif numaugofs > 0 then insert_cats("augmentatives of ") end return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{পদবি}}, {{patronymic}} and {{matronymic}}. function export.surname(frame) local iargs = require("Module:parameters").process(frame.args, { ["type"] = {required = true, set = {"পদবি", "patronymic", "matronymic"}}, }) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 if parent_args.dot or parent_args.nodot then error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. "period is no longer added by default; if you want it, add it explicitly after the template") end local lang_index = compat and "lang" or 1 local list = {list = true} local gender_arg = iargs.type == "পদবি" and "g" or 1 + offset local adj_arg = iargs.type == "পদবি" and 1 + offset or 2 + offset local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", template_default = "und"}, [gender_arg] = iargs.type == "পদবি" and true or {required = true, template_default = "unknown"}, -- gender(s) [adj_arg] = true, -- adjective/qualifier ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["parent"] = true, ["addl"] = true, -- initial article: by default A or An (English), a or an (otherwise) ["A"] = true, ["sort"] = true, ["from"] = true, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, ["nocat"] = {type = "boolean"}, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local saw_male = false local saw_female = false local genders = {} if args[gender_arg] then for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then g = "unknown-gender" track("unknown gender") elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then g = "common-gender" saw_male = true saw_female = true elseif g == "m" or g == "male" then g = "male" saw_male = true elseif g == "f" or g == "female" then g = "female" saw_female = true else error("Unrecognized gender: " .. g) end table.insert(genders, g) end end local adj = args[adj_arg] local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end if parenttext ~= "" then local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or "son/daughter" table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") -- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is -- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender -- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" -- because the word "পদবি", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. local article if args.A then article = args.A else article = #genders > 0 and genders[1] == "unknown-gender" and "an" or #genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or "a" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end end ins(article .. " ") if #genders > 0 then ins(table.concat(genders, " or ") .. " ") end if adj then ins(adj .. " ") end ins("[[" .. iargs.type .. "]]") local need_comma = false if xlittext ~= "" then ins(", " .. xlittext) need_comma = true end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end ins("</span>") local text = table.concat(textsegs, "") if args.nocat then return text end local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(g) g = g and g .. " " or "" table.insert(categories, langname .. g .. iargs.type .. "s") for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) end end insert_cats(nil) local function insert_cats_gender(g) if g == "unknown-gender" then return end if g == "common-gender" then insert_cats_gender("male") insert_cats_gender("female") end insert_cats(g) end for _, g in ipairs(genders) do insert_cats_gender(g) end return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. function export.name_translit(frame) local boolean = {type = "boolean"} local iargs = require("Module:parameters").process(frame.args, { ["desctext"] = {required = true}, ["obor"] = boolean, ["foreign_name"] = boolean, }) local parent_args = frame:getParent().args local params = { [1] = {required = true, type = "language", template_default = "en"}, [2] = {required = true, type = "language", sublist = true, template_default = "ru"}, [3] = {list = true, allow_holes = true}, ["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, ["dim"] = boolean, ["aug"] = boolean, ["nocap"] = boolean, ["addl"] = true, ["sort"] = true, ["pagename"] = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = {"xlit", "eq"}}, } local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 3, track_module = "names/name translit", disallow_custom_separators = true, -- Use the first source language as the language of the specified names. lang = function(args) return args[2][1] end, sc = "sc.default", } local lang = args[1] local langcode = lang:getCode() local sources = args[2] local pagename = args.pagename or mw.loadData("Module:headword/data").pagename local textsegs = {} local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") local desctext = iargs.desctext if langcode == "en" and not args.nocap then desctext = mw.getContentLanguage():ucfirst(desctext) end ins(desctext .. " ") if not iargs.foreign_name then ins("of ") end local langsegs = {} for i, source in ipairs(sources) do local sourcename = source:getCanonicalName() local function get_source_link() local term_to_link = names[1] and names[1].term or pagename -- We link the language name to either the first specified name or the pagename, in the following -- circumstances: -- (1) More than one language was given along with at least one name; or -- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. -- The reason for (1) is that if more than one language was given, we want a link to the name -- in each language, as the name that's displayed is linked only to the first specified language. -- However, if only one language was given, linking the language to the name is redundant. -- The reason for (2) is that {{foreign name}} is often used when the name in the destination language -- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), -- and in that case no name will be explicitly specified but we still want a link to the name in the -- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to -- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be -- used for names spelled differently in the destination language (either transliterated or respelled), so -- assuming the pagename is the name in the source language is wrong. if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then return m_links.language_link{ lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" } else return sourcename end end if i == 1 and not iargs.foreign_name then -- If at least one name is given, we say "A transliteration of the LANG পদবি FOO", linking LANG to FOO. -- Otherwise we say "A transliteration of a LANG পদবি". if names[1] then table.insert(langsegs, "the " .. get_source_link()) else table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) end else table.insert(langsegs, get_source_link()) end end local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) local augdim_text if args.dim then augdim_text = " [[diminutive]]" elseif args.aug then augdim_text = " [[augmentative]]" else augdim_text = "" end local nametype_linked = {} for _, nametype in ipairs(args["type"]) do if nametype == "পদবি" or nametype == "patronymic" then table.insert(nametype_linked, "[[" .. nametype .. "]]") elseif nametype == "male given name" then table.insert(nametype_linked, "male [[given name]]") elseif nametype == "female given name" then table.insert(nametype_linked, "female [[given name]]") elseif nametype == "unisex given name" then table.insert(nametype_linked, "unisex [[given name]]") else table.insert(nametype_linked, nametype) end end local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text if not iargs.foreign_name then ins(langseg_text .. " ") ins(nametype_text) if names[1] then ins(" ") end else ins(nametype_text) ins(" in " .. langseg_text) if names[1] then ins(", ") end end local linked_names = {} local embedded_comma = false for _, name in ipairs(names) do local linked_name = m_links.full_link(name, "term") if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or name.refs and name.refs[1] then linked_name = require(pron_qualifier_module).format_qualifiers { lang = name.lang, text = linked_name, q = name.q, qq = name.qq, l = name.l, ll = name.ll, refs = name.refs, raw = true, } end if name.xlit then embedded_comma = true linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } end if name.eq then embedded_comma = true linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } end table.insert(linked_names, linked_name) end if embedded_comma then ins(table.concat(linked_names, "; or of ")) else ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end ins("</span>") local categories = {} local function inscat(cat) table.insert(categories, lang:getFullName() .. " " .. cat) end for _, nametype in ipairs(args.type) do local function insert_cats(dimaugof) local function insert_cats_type(ty) if ty == "unisex given name" then insert_cats_type("male given name") insert_cats_type("female given name") end for _, source in ipairs(sources) do inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") inscat("terms derived from " .. source:getCanonicalName()) inscat("terms borrowed from " .. source:getCanonicalName()) if iargs.obor then inscat("orthographic borrowings from " .. source:getCanonicalName()) end if source:getCode() ~= source:getFullCode() then -- etymology language inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") end end end insert_cats_type(nametype) end insert_cats("") if args.dim then insert_cats("diminutives of ") end if args.aug then insert_cats("augmentatives of ") end end return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end return export nijzl74g72s67ut19d2o8f8cg3lykmi 509324 509323 2026-05-29T08:35:45Z Redmin 6857 509324 Scribunto text/plain local export = {} local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local pron_qualifier_module = "Module:pron qualifier" local enlang = m_languages.getByCode("en") local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local u = m_str_utils.char local function rsub(str, from, to) return (rsubn(str, from, to)) end local TEMP_LESS_THAN = u(0xFFF2) local force_cat = false -- for testing --[=[ FIXME: 1. from=the Bible (DONE) 2. origin=18th century [DONE] 3. popular= (DONE) 4. varoftype= (DONE) 5. eqtype= [DONE] 6. dimoftype= [DONE] 7. from=de:Elisabeth (same language) (DONE) 8. blendof=, blendof2= [DONE] 9. varform, dimform [DONE] 10. from=English < Latin [DONE] 11. usage=rare -> categorize as rare? 12. dimeq= (also vareq=?) [DONE] 13. fromtype= [DONE] 14. <tr:...> and similar params [DONE] ]=] -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "পদবি" -- of "male পদবি", but not "male পদবি" of "female পদবি" because "male" only matches a part of the word -- "female") should follow the longer name. export.personal_name_types = { "পুরুষবাচক পদবি", "surnames", "male surnames", "female পদবি", "common-gender পদবি", "পদবি", "patronymics", "matronymics", } export.personal_name_type_set = m_table.listToSet(export.personal_name_types) export.given_name_genders = { male = {type = "human"}, female = {type = "human"}, unisex = {type = "human", cat = {"male given names", "পুরুষবাচক মূল নাম", "female given names", "unisex given names"}, article = "a"}, ["unknown-gender"] = {type = "human", cat = {}, track = true}, animal = {type = "animal", track = true}, cat = {type = "animal"}, cow = {type = "animal"}, dog = {type = "animal"}, horse = {type = "animal"}, pig = {type = "animal"}, } local function get_given_name_cats(gender, props) --local cats = props.cat if not cats then if props.type == "animal" then cats = {gender .. " names"} else cats = {gender .. " given names"} end end return cats end do local function do_cat(cat) if not export.personal_name_type_set[cat] then export.personal_name_type_set[cat] = true table.insert(export.personal_name_types, cat) end end for gender, props in pairs(export.given_name_genders) do local cats = get_given_name_cats(gender, props) for _, cat in ipairs(cats) do do_cat("diminutives of " .. cat) do_cat("augmentatives of " .. cat) do_cat(cat) end end do_cat("given names") end local translit_name_type_list = { "পদবি", "male given name", "female given name", "unisex given name", "patronymic" } local function track(page) require("Module:debug").track("names/" .. page) end -- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also -- remove parens that may surround qualifier or label text preceding a term. local function get_rawtext(text) text = m_utilities.get_plaintext(text) text = text:gsub("[()%[%]]", "") return text end --[=[ Parse a term and associated properties. This works with parameters of the form 'Karlheinz' or 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, and the return value is a list of objects of the form described just above. ]=] local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"link", "l", "q", "ref"}}, {param = "eq", convert = function(eqval, parse_err) return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") end}, } local function generate_obj(term, parse_err) local termlang if allow_explicit_lang then local actual_term actual_term, termlang = require(parse_interface_module).parse_term_with_lang { term = term, --parse_err = parse_err, paramname = paramname, } term = actual_term or term end return { term = term, lang = termlang or deflang, } end return require(parse_interface_module).parse_inline_modifiers(term, { param_mods = param_mods, paramname = paramname, generate_obj = generate_obj, splitchar = allow_multiple_terms and "," or nil, }) end --[=[ Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). ]=] local function link_one_term(termobj, do_language_link) local link if do_language_link and termobj.lang:getCode() == "en" then link = m_links.language_link(termobj) else link = m_links.full_link(termobj) end if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then link = require(pron_qualifier_module).format_qualifiers { lang = termobj.lang, text = link, q = termobj.q, qq = termobj.qq, l = termobj.l, ll = termobj.ll, refs = termobj.refs, } end if termobj.eq then local eqtext = {} for _, eqobj in ipairs(termobj.eq) do table.insert(eqtext, link_one_term(eqobj, true)) end link = link .. " [=" .. m_table.serialCommaJoin(eqtext, {conj = "or"}) .. "]" end return link end --[=[ Link the terms in `terms`, and join them using the conjunction in `conj` (defaulting to "or"). Joining is done using serialCommaJoin() in [[Module:table]], so that e.g. two terms are joined as "TERM or TERM" while three terms are joined as "TERM, TERM or TERM" with special CSS spans before the final "or" to allow an "Oxford comma" to appear if configured appropriately. (However, if `conj` is the special value ", ", joining is done directly using that value.) If `include_langname` is given, the language of the first term will be prepended to the joined terms. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by parse_term_with_annotations(). ]=] local function join_terms(terms, include_langname, do_language_link, conj) local links = {} local langnametext for _, termobj in ipairs(terms) do if include_langname and not langnametext then langnametext = termobj.lang:getCanonicalName() .. " " end table.insert(links, link_one_term(termobj, do_language_link)) end local joined_terms if conj == ", " then joined_terms = table.concat(links, conj) else joined_terms = m_table.serialCommaJoin(links, {conj = conj or "or"}) end return (langnametext or "") .. joined_terms end --[=[ Gather the parameters for multiple names and link each name using full_link() (for foreign names) or language_link() (for English names), joining the names using serialCommaJoin() in [[Module:table]] with the conjunction `conj` (defaulting to "or"). (However, if `conj` is the special value ", ", joining is done directly using that value.) This can be used, for example, to fetch and join all the masculine equivalent names for a feminine given name. Each name is specified using parameters beginning with `pname` in `args`, e.g. "m", "m2", "m3", etc. `lang` is a language object specifying the language of the names (defaulting to English), for use in linking them. If `allow_explicit_lang` is given, the language of the terms can be specified explicitly by prefixing a term with a language code, e.g. 'sv:Björn' or 'la:[[Nicolaus|Nīcolāī]]'. This function assumes that the parameters have already been parsed by [[Module:parameters]] and gathered into lists, so that e.g. all "mN" parameters are in a list in args["m"]. ]=] local function join_names(lang, args, pname, conj, allow_explicit_lang) local termobjs = {} local do_language_link = false if not lang then lang = enlang do_language_link = true end local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, allow_explicit_lang, "allow multiple terms")) do table.insert(termobjs, termobj) end end if not args[pname] then return "", 0 elseif type(args[pname]) == "table" then for i, term in ipairs(args[pname]) do process_one_term(term, i) end else process_one_term(args[pname], 1) end return join_terms(termobjs, nil, do_language_link, conj), #termobjs end local function get_eqtext(args) local eqsegs = {} local lastlang = nil local last_eqseg = {} local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, "allow explicit lang", "allow multiple terms")) do local termlang = termobj.lang:getCode() if lastlang and lastlang ~= termlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = termlang table.insert(last_eqseg, termobj) end end if type(args.eq) == "table" then for i, term in ipairs(args.eq) do process_one_term(term, i) end elseif type(args.eq) == "string" then process_one_term(args.eq, 1) end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs, {conj = "or"}) end local function get_fromtext(lang, args) local catparts = {} local fromsegs = {} local i = 1 local function parse_from(from) local unrecognized = false local prefix, suffix if from == "পদবি" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then prefix = "transferred from the " suffix = from:gsub("s$", "") table.insert(catparts, from) elseif from == "patronymics" or from == "matronymics" or from == "coinages" then prefix = "originating " suffix = "as a " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "occupations" or from == "ethnonyms" then prefix = "originating " suffix = "as an " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "the Bible" then prefix = "originating " suffix = "from the Bible" table.insert(catparts, from) else prefix = "from " if from:find(":") then local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") local fromlangname = "" if termobj.lang:getCode() ~= lang:getCode() then -- If name is derived from another name in the same language, don't include lang name after text -- "from " or create a category like "German male given names derived from German". local canonical_name = termobj.lang:getCanonicalName() fromlangname = canonical_name .. " " table.insert(catparts, canonical_name) end suffix = fromlangname .. link_one_term(termobj) else local family = from:match("^(.+) languages$") or from:match("^.+ Languages$") or from:match("^.+ [Ll]ects$") if family then if require("Module:families").getByCanonicalName(family) then table.insert(catparts, from) else unrecognized = true end suffix = "the " .. from else if m_languages.getByCanonicalName(from, nil, "allow etym") then table.insert(catparts, from) else unrecognized = true end suffix = from end end end if unrecognized then track("unrecognized from") track("unrecognized from/" .. from) end return prefix, suffix end local last_fromseg = nil local put = require(parse_utilities_module) local from_args = args.from or {} if type(from_args) == "string" then from_args = {from_args} end while from_args[i] do -- We may have multiple comma-separated items, each of which may have multiple items separated by a -- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle -- this correctly, first replace space-delimited < signs with a special character, then split on balanced -- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on -- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) local comma_separated_groups = put.split_alternating_runs_on_comma(segments) for j, comma_separated_group in ipairs(comma_separated_groups) do comma_separated_groups[j] = table.concat(comma_separated_group) end for _, rawfrom in ipairs(comma_separated_groups) do local froms = rsplit(rawfrom, TEMP_LESS_THAN) if #froms == 1 then local prefix, suffix = parse_from(froms[1]) if last_fromseg and (last_fromseg.has_multiple_froms or last_fromseg.prefix ~= prefix) then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) else if last_fromseg then table.insert(fromsegs, last_fromseg) last_fromseg = nil end local first_suffixpart = "" local rest_suffixparts = {} for j, from in ipairs(froms) do local prefix, suffix = parse_from(from) if j == 1 then first_suffixpart = prefix .. suffix else table.insert(rest_suffixparts, prefix .. suffix) end end local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} end end i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts end local function parse_given_name_genders(genderspec) if export.given_name_genders[genderspec] then -- optimization return {{ type = genderspec, props = export.given_name_genders[genderspec], }}, export.given_name_genders[genderspec].type == "animal" end local genders = {} local is_animal = nil local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"l", "q", "ref"}}, {param = {"text", "article"}}, } local function generate_obj(term, parse_err) if not export.given_name_genders[term] then local valid_genders = {} for k, _ in pairs(export.given_name_genders) do table.insert(valid_genders, k) end table.sort(valid_genders) --parse_err(("Unrecognized gender '%s': valid genders are %s"):format( -- term, table.concat(valid_genders, ", "))) end return { type = term, props = export.given_name_genders[term], } end local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { param_mods = param_mods, paramname = "2", generate_obj = generate_obj, splitchar = ",", }) for _, spec in ipairs(retval) do --local this_is_animal = spec.props.type == "animal" if is_animal == nil then is_animal = this_is_animal elseif is_animal ~= this_is_animal then error("Can't mix animal and human genders") end end return retval, is_animal end local function generate_given_name_genders(lang, genders) local parts = {} for _, spec in ipairs(genders) do local text if spec.text then -- NOTE: This assumes no % sign in the gender type, which seems safe. text = spec.text:gsub("%+", spec.type) else -- if spec.props.type == "animal" then -- text = "[[" .. spec.type .. "]]" -- else -- text = spec.type -- end end if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or spec.refs and spec.refs[1] then text = require(pron_qualifier_module).format_qualifiers { lang = lang, text = text, q = spec.q, qq = spec.qq, l = spec.l, ll = spec.ll, refs = spec.refs, raw = true, } end table.insert(parts, text) end local retval = m_table.serialCommaJoin(parts, {conj = "or"}) local article = genders[1].article --if not article and not genders[1].text and not genders[1].q and not genders[1].l then -- article = genders[1].props.article --end if not article then article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) end return retval, article end -- The entry point for {{given name}}. function export.given_name(frame) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 local lang_index = compat and "lang" or 1 local list = {list = true} local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", default = "und"}, ["gender"] = {default = "unknown-gender"}, [1 + offset] = {alias_of = "gender"}, ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["addl"] = true, -- initial article: A or An ["A"] = true, ["sort"] = true, ["from"] = true, [2 + offset] = {alias_of = "from"}, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["dimof"] = true, ["dimoftype"] = true, ["dim"] = {alias_of = "dimof"}, ["dimtype"] = {alias_of = "dimoftype"}, ["dimform"] = true, ["dimformtype"] = true, ["augof"] = true, ["augoftype"] = true, ["aug"] = {alias_of = "augof"}, ["augtype"] = {alias_of = "augoftype"}, ["augform"] = true, ["augformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local genders, is_animal = parse_given_name_genders(args.gender) local dimoftext, numdimofs = join_names(lang, args, "dimof") local augoftext, numaugofs = join_names(lang, args, "augof") local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") local augformtext, numaugforms = join_names(lang, args, "augform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end local dimoftype = args.dimoftype local augoftype = args.augoftype added_text = nil if numdimofs > 0 then added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " elseif numaugofs > 0 then added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " end force_plural = false if added_text ~= nil then if args.dimof == "-" then dimoftext = "" force_plural = true else added_text = added_text .. "the " end ins(added_text) end local article = args.A if not article and textsegs[1] then article = require(en_utilities_module).get_indefinite_article(textsegs[1]) end if not is_animal then local gendertext, gender_article = generate_given_name_genders(lang, genders) article = article or gender_article ins(gendertext) ins(" ") end ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") article = article or "a" -- if no article set yet, it's "a" based on "given name" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end local need_comma = false if numdimofs > 0 then ins(" " .. dimoftext) need_comma = not is_animal elseif numaugofs > 0 then ins(" " .. augoftext) need_comma = not is_animal elseif xlittext ~= "" then ins(", " .. xlittext) need_comma = true end if is_animal then if need_comma then ins(",") end need_comma = true ins(" for ") local gendertext, gender_article = generate_given_name_genders(lang, genders) ins(gender_article) ins(" ") ins(gendertext) end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end if dimformtext ~= "" then ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. dimformtext) end if augformtext ~= "" then ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. augformtext) end textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(dimaugof) -- if dimaugof == "" and genders[1].props.type == "human" then -- No category such as "English diminutives of given names" -- table.insert(categories, langname .. "given names") --end local function insert_cat(cat) table.insert(categories, langname .. dimaugof .. cat) for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) end end for _, spec in ipairs(genders) do local typ = spec.type --if spec.props.track then -- track(typ) --end local cats = get_given_name_cats(spec.type, spec.props) for _, cat in ipairs(cats) do insert_cat(cat) end end end insert_cats("") if numdimofs > 0 then insert_cats("diminutives of ") elseif numaugofs > 0 then insert_cats("augmentatives of ") end return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{পদবি}}, {{patronymic}} and {{matronymic}}. function export.surname(frame) local iargs = require("Module:parameters").process(frame.args, { ["type"] = {required = true, set = {"পদবি", "patronymic", "matronymic"}}, }) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 if parent_args.dot or parent_args.nodot then error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. "period is no longer added by default; if you want it, add it explicitly after the template") end local lang_index = compat and "lang" or 1 local list = {list = true} local gender_arg = iargs.type == "পদবি" and "g" or 1 + offset local adj_arg = iargs.type == "পদবি" and 1 + offset or 2 + offset local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", template_default = "und"}, [gender_arg] = iargs.type == "পদবি" and true or {required = true, template_default = "unknown"}, -- gender(s) [adj_arg] = true, -- adjective/qualifier ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["parent"] = true, ["addl"] = true, -- initial article: by default A or An (English), a or an (otherwise) ["A"] = true, ["sort"] = true, ["from"] = true, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, ["nocat"] = {type = "boolean"}, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local saw_male = false local saw_female = false local genders = {} if args[gender_arg] then for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then g = "unknown-gender" track("unknown gender") elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then g = "common-gender" saw_male = true saw_female = true elseif g == "m" or g == "male" then g = "male" saw_male = true elseif g == "f" or g == "female" then g = "female" saw_female = true else error("Unrecognized gender: " .. g) end table.insert(genders, g) end end local adj = args[adj_arg] local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end if parenttext ~= "" then local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or "son/daughter" table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") -- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is -- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender -- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" -- because the word "পদবি", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. local article if args.A then article = args.A else article = #genders > 0 and genders[1] == "unknown-gender" and "an" or #genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or "a" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end end ins(article .. " ") if #genders > 0 then ins(table.concat(genders, " or ") .. " ") end if adj then ins(adj .. " ") end ins("[[" .. iargs.type .. "]]") local need_comma = false if xlittext ~= "" then ins(", " .. xlittext) need_comma = true end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end ins("</span>") local text = table.concat(textsegs, "") if args.nocat then return text end local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(g) g = g and g .. " " or "" table.insert(categories, langname .. g .. iargs.type .. "s") for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) end end insert_cats(nil) local function insert_cats_gender(g) if g == "unknown-gender" then return end if g == "common-gender" then insert_cats_gender("male") insert_cats_gender("female") end insert_cats(g) end for _, g in ipairs(genders) do insert_cats_gender(g) end return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. function export.name_translit(frame) local boolean = {type = "boolean"} local iargs = require("Module:parameters").process(frame.args, { ["desctext"] = {required = true}, ["obor"] = boolean, ["foreign_name"] = boolean, }) local parent_args = frame:getParent().args local params = { [1] = {required = true, type = "language", template_default = "en"}, [2] = {required = true, type = "language", sublist = true, template_default = "ru"}, [3] = {list = true, allow_holes = true}, ["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, ["dim"] = boolean, ["aug"] = boolean, ["nocap"] = boolean, ["addl"] = true, ["sort"] = true, ["pagename"] = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = {"xlit", "eq"}}, } local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 3, track_module = "names/name translit", disallow_custom_separators = true, -- Use the first source language as the language of the specified names. lang = function(args) return args[2][1] end, sc = "sc.default", } local lang = args[1] local langcode = lang:getCode() local sources = args[2] local pagename = args.pagename or mw.loadData("Module:headword/data").pagename local textsegs = {} local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") local desctext = iargs.desctext if langcode == "en" and not args.nocap then desctext = mw.getContentLanguage():ucfirst(desctext) end ins(desctext .. " ") if not iargs.foreign_name then ins("of ") end local langsegs = {} for i, source in ipairs(sources) do local sourcename = source:getCanonicalName() local function get_source_link() local term_to_link = names[1] and names[1].term or pagename -- We link the language name to either the first specified name or the pagename, in the following -- circumstances: -- (1) More than one language was given along with at least one name; or -- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. -- The reason for (1) is that if more than one language was given, we want a link to the name -- in each language, as the name that's displayed is linked only to the first specified language. -- However, if only one language was given, linking the language to the name is redundant. -- The reason for (2) is that {{foreign name}} is often used when the name in the destination language -- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), -- and in that case no name will be explicitly specified but we still want a link to the name in the -- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to -- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be -- used for names spelled differently in the destination language (either transliterated or respelled), so -- assuming the pagename is the name in the source language is wrong. if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then return m_links.language_link{ lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" } else return sourcename end end if i == 1 and not iargs.foreign_name then -- If at least one name is given, we say "A transliteration of the LANG পদবি FOO", linking LANG to FOO. -- Otherwise we say "A transliteration of a LANG পদবি". if names[1] then table.insert(langsegs, "the " .. get_source_link()) else table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) end else table.insert(langsegs, get_source_link()) end end local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) local augdim_text if args.dim then augdim_text = " [[diminutive]]" elseif args.aug then augdim_text = " [[augmentative]]" else augdim_text = "" end local nametype_linked = {} for _, nametype in ipairs(args["type"]) do if nametype == "পদবি" or nametype == "patronymic" then table.insert(nametype_linked, "[[" .. nametype .. "]]") elseif nametype == "male given name" then table.insert(nametype_linked, "male [[given name]]") elseif nametype == "female given name" then table.insert(nametype_linked, "female [[given name]]") elseif nametype == "unisex given name" then table.insert(nametype_linked, "unisex [[given name]]") else table.insert(nametype_linked, nametype) end end local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text if not iargs.foreign_name then ins(langseg_text .. " ") ins(nametype_text) if names[1] then ins(" ") end else ins(nametype_text) ins(" in " .. langseg_text) if names[1] then ins(", ") end end local linked_names = {} local embedded_comma = false for _, name in ipairs(names) do local linked_name = m_links.full_link(name, "term") if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or name.refs and name.refs[1] then linked_name = require(pron_qualifier_module).format_qualifiers { lang = name.lang, text = linked_name, q = name.q, qq = name.qq, l = name.l, ll = name.ll, refs = name.refs, raw = true, } end if name.xlit then embedded_comma = true linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } end if name.eq then embedded_comma = true linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } end table.insert(linked_names, linked_name) end if embedded_comma then ins(table.concat(linked_names, "; or of ")) else ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end ins("</span>") local categories = {} local function inscat(cat) table.insert(categories, lang:getFullName() .. " " .. cat) end for _, nametype in ipairs(args.type) do local function insert_cats(dimaugof) local function insert_cats_type(ty) if ty == "unisex given name" then insert_cats_type("male given name") insert_cats_type("female given name") end for _, source in ipairs(sources) do inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") inscat("terms derived from " .. source:getCanonicalName()) inscat("terms borrowed from " .. source:getCanonicalName()) if iargs.obor then inscat("orthographic borrowings from " .. source:getCanonicalName()) end if source:getCode() ~= source:getFullCode() then -- etymology language inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") end end end insert_cats_type(nametype) end insert_cats("") if args.dim then insert_cats("diminutives of ") end if args.aug then insert_cats("augmentatives of ") end end return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end return export 52nwfzt7ojq5t38e7av7n4as1miiz2r 509325 509324 2026-05-29T08:37:06Z Redmin 6857 509325 Scribunto text/plain local export = {} local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local pron_qualifier_module = "Module:pron qualifier" local enlang = m_languages.getByCode("en") local rsubn = m_str_utils.gsub local rsplit = m_str_utils.split local u = m_str_utils.char local function rsub(str, from, to) return (rsubn(str, from, to)) end local TEMP_LESS_THAN = u(0xFFF2) local force_cat = false -- for testing --[=[ FIXME: 1. from=the Bible (DONE) 2. origin=18th century [DONE] 3. popular= (DONE) 4. varoftype= (DONE) 5. eqtype= [DONE] 6. dimoftype= [DONE] 7. from=de:Elisabeth (same language) (DONE) 8. blendof=, blendof2= [DONE] 9. varform, dimform [DONE] 10. from=English < Latin [DONE] 11. usage=rare -> categorize as rare? 12. dimeq= (also vareq=?) [DONE] 13. fromtype= [DONE] 14. <tr:...> and similar params [DONE] ]=] -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "পদবি" -- of "male পদবি", but not "male পদবি" of "female পদবি" because "male" only matches a part of the word -- "female") should follow the longer name. export.personal_name_types = { "পুরুষবাচক পদবি", "surnames", "male surnames", "female পদবি", "common-gender পদবি", "পদবি", "patronymics", "matronymics", } export.personal_name_type_set = m_table.listToSet(export.personal_name_types) export.given_name_genders = { male = {type = "human"}, female = {type = "human"}, unisex = {type = "human", cat = {"male given names", "পুরুষবাচক মূল নাম", "female given names", "unisex given names"}, article = "a"}, ["unknown-gender"] = {type = "human", cat = {}, track = true}, animal = {type = "animal", track = true}, cat = {type = "animal"}, cow = {type = "animal"}, dog = {type = "animal"}, horse = {type = "animal"}, pig = {type = "animal"}, } local function get_given_name_cats(gender, props) --local cats = props.cat if not cats then if props.type == "animal" then cats = {gender .. " names"} else cats = {gender .. " given names"} end end return cats end do local function do_cat(cat) if not export.personal_name_type_set[cat] then export.personal_name_type_set[cat] = true table.insert(export.personal_name_types, cat) end end for gender, props in pairs(export.given_name_genders) do local cats = get_given_name_cats(gender, props) for _, cat in ipairs(cats) do do_cat("diminutives of " .. cat) do_cat("augmentatives of " .. cat) do_cat(cat) end end do_cat("given names") end local translit_name_type_list = { "পদবি", "male given name", "পুরুষবাচক মূল নাম", "female given name", "unisex given name", "patronymic" } local function track(page) require("Module:debug").track("names/" .. page) end -- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also -- remove parens that may surround qualifier or label text preceding a term. local function get_rawtext(text) text = m_utilities.get_plaintext(text) text = text:gsub("[()%[%]]", "") return text end --[=[ Parse a term and associated properties. This works with parameters of the form 'Karlheinz' or 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, and the return value is a list of objects of the form described just above. ]=] local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"link", "l", "q", "ref"}}, {param = "eq", convert = function(eqval, parse_err) return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") end}, } local function generate_obj(term, parse_err) local termlang if allow_explicit_lang then local actual_term actual_term, termlang = require(parse_interface_module).parse_term_with_lang { term = term, --parse_err = parse_err, paramname = paramname, } term = actual_term or term end return { term = term, lang = termlang or deflang, } end return require(parse_interface_module).parse_inline_modifiers(term, { param_mods = param_mods, paramname = paramname, generate_obj = generate_obj, splitchar = allow_multiple_terms and "," or nil, }) end --[=[ Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). ]=] local function link_one_term(termobj, do_language_link) local link if do_language_link and termobj.lang:getCode() == "en" then link = m_links.language_link(termobj) else link = m_links.full_link(termobj) end if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then link = require(pron_qualifier_module).format_qualifiers { lang = termobj.lang, text = link, q = termobj.q, qq = termobj.qq, l = termobj.l, ll = termobj.ll, refs = termobj.refs, } end if termobj.eq then local eqtext = {} for _, eqobj in ipairs(termobj.eq) do table.insert(eqtext, link_one_term(eqobj, true)) end link = link .. " [=" .. m_table.serialCommaJoin(eqtext, {conj = "or"}) .. "]" end return link end --[=[ Link the terms in `terms`, and join them using the conjunction in `conj` (defaulting to "or"). Joining is done using serialCommaJoin() in [[Module:table]], so that e.g. two terms are joined as "TERM or TERM" while three terms are joined as "TERM, TERM or TERM" with special CSS spans before the final "or" to allow an "Oxford comma" to appear if configured appropriately. (However, if `conj` is the special value ", ", joining is done directly using that value.) If `include_langname` is given, the language of the first term will be prepended to the joined terms. If `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by parse_term_with_annotations(). ]=] local function join_terms(terms, include_langname, do_language_link, conj) local links = {} local langnametext for _, termobj in ipairs(terms) do if include_langname and not langnametext then langnametext = termobj.lang:getCanonicalName() .. " " end table.insert(links, link_one_term(termobj, do_language_link)) end local joined_terms if conj == ", " then joined_terms = table.concat(links, conj) else joined_terms = m_table.serialCommaJoin(links, {conj = conj or "or"}) end return (langnametext or "") .. joined_terms end --[=[ Gather the parameters for multiple names and link each name using full_link() (for foreign names) or language_link() (for English names), joining the names using serialCommaJoin() in [[Module:table]] with the conjunction `conj` (defaulting to "or"). (However, if `conj` is the special value ", ", joining is done directly using that value.) This can be used, for example, to fetch and join all the masculine equivalent names for a feminine given name. Each name is specified using parameters beginning with `pname` in `args`, e.g. "m", "m2", "m3", etc. `lang` is a language object specifying the language of the names (defaulting to English), for use in linking them. If `allow_explicit_lang` is given, the language of the terms can be specified explicitly by prefixing a term with a language code, e.g. 'sv:Björn' or 'la:[[Nicolaus|Nīcolāī]]'. This function assumes that the parameters have already been parsed by [[Module:parameters]] and gathered into lists, so that e.g. all "mN" parameters are in a list in args["m"]. ]=] local function join_names(lang, args, pname, conj, allow_explicit_lang) local termobjs = {} local do_language_link = false if not lang then lang = enlang do_language_link = true end local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, allow_explicit_lang, "allow multiple terms")) do table.insert(termobjs, termobj) end end if not args[pname] then return "", 0 elseif type(args[pname]) == "table" then for i, term in ipairs(args[pname]) do process_one_term(term, i) end else process_one_term(args[pname], 1) end return join_terms(termobjs, nil, do_language_link, conj), #termobjs end local function get_eqtext(args) local eqsegs = {} local lastlang = nil local last_eqseg = {} local function process_one_term(term, i) for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, "allow explicit lang", "allow multiple terms")) do local termlang = termobj.lang:getCode() if lastlang and lastlang ~= termlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = termlang table.insert(last_eqseg, termobj) end end if type(args.eq) == "table" then for i, term in ipairs(args.eq) do process_one_term(term, i) end elseif type(args.eq) == "string" then process_one_term(args.eq, 1) end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs, {conj = "or"}) end local function get_fromtext(lang, args) local catparts = {} local fromsegs = {} local i = 1 local function parse_from(from) local unrecognized = false local prefix, suffix if from == "পদবি" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then prefix = "transferred from the " suffix = from:gsub("s$", "") table.insert(catparts, from) elseif from == "patronymics" or from == "matronymics" or from == "coinages" then prefix = "originating " suffix = "as a " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "occupations" or from == "ethnonyms" then prefix = "originating " suffix = "as an " .. from:gsub("s$", "") table.insert(catparts, from) elseif from == "the Bible" then prefix = "originating " suffix = "from the Bible" table.insert(catparts, from) else prefix = "from " if from:find(":") then local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") local fromlangname = "" if termobj.lang:getCode() ~= lang:getCode() then -- If name is derived from another name in the same language, don't include lang name after text -- "from " or create a category like "German male given names derived from German". local canonical_name = termobj.lang:getCanonicalName() fromlangname = canonical_name .. " " table.insert(catparts, canonical_name) end suffix = fromlangname .. link_one_term(termobj) else local family = from:match("^(.+) languages$") or from:match("^.+ Languages$") or from:match("^.+ [Ll]ects$") if family then if require("Module:families").getByCanonicalName(family) then table.insert(catparts, from) else unrecognized = true end suffix = "the " .. from else if m_languages.getByCanonicalName(from, nil, "allow etym") then table.insert(catparts, from) else unrecognized = true end suffix = from end end end if unrecognized then track("unrecognized from") track("unrecognized from/" .. from) end return prefix, suffix end local last_fromseg = nil local put = require(parse_utilities_module) local from_args = args.from or {} if type(from_args) == "string" then from_args = {from_args} end while from_args[i] do -- We may have multiple comma-separated items, each of which may have multiple items separated by a -- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle -- this correctly, first replace space-delimited < signs with a special character, then split on balanced -- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on -- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) local comma_separated_groups = put.split_alternating_runs_on_comma(segments) for j, comma_separated_group in ipairs(comma_separated_groups) do comma_separated_groups[j] = table.concat(comma_separated_group) end for _, rawfrom in ipairs(comma_separated_groups) do local froms = rsplit(rawfrom, TEMP_LESS_THAN) if #froms == 1 then local prefix, suffix = parse_from(froms[1]) if last_fromseg and (last_fromseg.has_multiple_froms or last_fromseg.prefix ~= prefix) then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) else if last_fromseg then table.insert(fromsegs, last_fromseg) last_fromseg = nil end local first_suffixpart = "" local rest_suffixparts = {} for j, from in ipairs(froms) do local prefix, suffix = parse_from(from) if j == 1 then first_suffixpart = prefix .. suffix else table.insert(rest_suffixparts, prefix .. suffix) end end local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} end end i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts end local function parse_given_name_genders(genderspec) if export.given_name_genders[genderspec] then -- optimization return {{ type = genderspec, props = export.given_name_genders[genderspec], }}, export.given_name_genders[genderspec].type == "animal" end local genders = {} local is_animal = nil local param_mods = require(parameter_utilities_module).construct_param_mods { {group = {"l", "q", "ref"}}, {param = {"text", "article"}}, } local function generate_obj(term, parse_err) if not export.given_name_genders[term] then local valid_genders = {} for k, _ in pairs(export.given_name_genders) do table.insert(valid_genders, k) end table.sort(valid_genders) --parse_err(("Unrecognized gender '%s': valid genders are %s"):format( -- term, table.concat(valid_genders, ", "))) end return { type = term, props = export.given_name_genders[term], } end local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { param_mods = param_mods, paramname = "2", generate_obj = generate_obj, splitchar = ",", }) for _, spec in ipairs(retval) do --local this_is_animal = spec.props.type == "animal" if is_animal == nil then is_animal = this_is_animal elseif is_animal ~= this_is_animal then error("Can't mix animal and human genders") end end return retval, is_animal end local function generate_given_name_genders(lang, genders) local parts = {} for _, spec in ipairs(genders) do local text if spec.text then -- NOTE: This assumes no % sign in the gender type, which seems safe. text = spec.text:gsub("%+", spec.type) else -- if spec.props.type == "animal" then -- text = "[[" .. spec.type .. "]]" -- else -- text = spec.type -- end end if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or spec.refs and spec.refs[1] then text = require(pron_qualifier_module).format_qualifiers { lang = lang, text = text, q = spec.q, qq = spec.qq, l = spec.l, ll = spec.ll, refs = spec.refs, raw = true, } end table.insert(parts, text) end local retval = m_table.serialCommaJoin(parts, {conj = "or"}) local article = genders[1].article --if not article and not genders[1].text and not genders[1].q and not genders[1].l then -- article = genders[1].props.article --end if not article then article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) end return retval, article end -- The entry point for {{given name}}. function export.given_name(frame) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 local lang_index = compat and "lang" or 1 local list = {list = true} local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", default = "und"}, ["gender"] = {default = "unknown-gender"}, [1 + offset] = {alias_of = "gender"}, ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["addl"] = true, -- initial article: A or An ["A"] = true, ["sort"] = true, ["from"] = true, [2 + offset] = {alias_of = "from"}, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["dimof"] = true, ["dimoftype"] = true, ["dim"] = {alias_of = "dimof"}, ["dimtype"] = {alias_of = "dimoftype"}, ["dimform"] = true, ["dimformtype"] = true, ["augof"] = true, ["augoftype"] = true, ["aug"] = {alias_of = "augof"}, ["augtype"] = {alias_of = "augoftype"}, ["augform"] = true, ["augformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local genders, is_animal = parse_given_name_genders(args.gender) local dimoftext, numdimofs = join_names(lang, args, "dimof") local augoftext, numaugofs = join_names(lang, args, "augof") local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") local augformtext, numaugforms = join_names(lang, args, "augform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end local dimoftype = args.dimoftype local augoftype = args.augoftype added_text = nil if numdimofs > 0 then added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " elseif numaugofs > 0 then added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. (xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " end force_plural = false if added_text ~= nil then if args.dimof == "-" then dimoftext = "" force_plural = true else added_text = added_text .. "the " end ins(added_text) end local article = args.A if not article and textsegs[1] then article = require(en_utilities_module).get_indefinite_article(textsegs[1]) end if not is_animal then local gendertext, gender_article = generate_given_name_genders(lang, genders) article = article or gender_article ins(gendertext) ins(" ") end ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") article = article or "a" -- if no article set yet, it's "a" based on "given name" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end local need_comma = false if numdimofs > 0 then ins(" " .. dimoftext) need_comma = not is_animal elseif numaugofs > 0 then ins(" " .. augoftext) need_comma = not is_animal elseif xlittext ~= "" then ins(", " .. xlittext) need_comma = true end if is_animal then if need_comma then ins(",") end need_comma = true ins(" for ") local gendertext, gender_article = generate_given_name_genders(lang, genders) ins(gender_article) ins(" ") ins(gendertext) end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end if dimformtext ~= "" then ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. dimformtext) end if augformtext ~= "" then ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. augformtext) end textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(dimaugof) -- if dimaugof == "" and genders[1].props.type == "human" then -- No category such as "English diminutives of given names" -- table.insert(categories, langname .. "given names") --end local function insert_cat(cat) table.insert(categories, langname .. dimaugof .. cat) for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) end end for _, spec in ipairs(genders) do local typ = spec.type --if spec.props.track then -- track(typ) --end local cats = get_given_name_cats(spec.type, spec.props) for _, cat in ipairs(cats) do insert_cat(cat) end end end insert_cats("") if numdimofs > 0 then insert_cats("diminutives of ") elseif numaugofs > 0 then insert_cats("augmentatives of ") end return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{পদবি}}, {{patronymic}} and {{matronymic}}. function export.surname(frame) local iargs = require("Module:parameters").process(frame.args, { ["type"] = {required = true, set = {"পদবি", "patronymic", "matronymic"}}, }) local parent_args = frame:getParent().args local compat = parent_args.lang local offset = compat and 0 or 1 if parent_args.dot or parent_args.nodot then error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. "period is no longer added by default; if you want it, add it explicitly after the template") end local lang_index = compat and "lang" or 1 local list = {list = true} local gender_arg = iargs.type == "পদবি" and "g" or 1 + offset local adj_arg = iargs.type == "পদবি" and 1 + offset or 2 + offset local args = require("Module:parameters").process(parent_args, { [lang_index] = {required = true, type = "language", template_default = "und"}, [gender_arg] = iargs.type == "পদবি" and true or {required = true, template_default = "unknown"}, -- gender(s) [adj_arg] = true, -- adjective/qualifier ["usage"] = true, ["origin"] = true, ["popular"] = true, ["populartype"] = true, ["meaning"] = list, ["meaningtype"] = true, ["parent"] = true, ["addl"] = true, -- initial article: by default A or An (English), a or an (otherwise) ["A"] = true, ["sort"] = true, ["from"] = true, ["fromtype"] = true, ["xlit"] = true, ["eq"] = true, ["eqtype"] = true, ["varof"] = true, ["varoftype"] = true, ["var"] = {alias_of = "varof"}, ["vartype"] = {alias_of = "varoftype"}, ["varform"] = true, ["varformtype"] = true, ["clipof"] = true, ["clipoftype"] = true, ["blend"] = true, ["blendtype"] = true, ["m"] = true, ["mtype"] = true, ["f"] = true, ["ftype"] = true, ["nocat"] = {type = "boolean"}, }) local textsegs = {} local lang = args[lang_index] local langcode = lang:getCode() local function fetch_typetext(param) return args[param] and args[param] .. " " or "" end local saw_male = false local saw_female = false local genders = {} if args[gender_arg] then for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then g = "unknown-gender" track("unknown gender") elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then g = "common-gender" saw_male = true saw_female = true elseif g == "m" or g == "male" then g = "male" saw_male = true elseif g == "f" or g == "female" then g = "female" saw_female = true else error("Unrecognized gender: " .. g) end table.insert(genders, g) end end local adj = args[adj_arg] local xlittext = join_names(nil, args, "xlit") local blendtext = join_names(lang, args, "blend", "and") local varoftext = join_names(lang, args, "varof") local clipoftext = join_names(lang, args, "clipof") local mtext = join_names(lang, args, "m") local ftext = join_names(lang, args, "f") local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") local varformtext, numvarforms = join_names(lang, args, "varform", ", ") local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '“' .. meaning .. '”') end if parenttext ~= "" then local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or "son/daughter" table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) local eqtext = get_eqtext(args) local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") -- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is -- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender -- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" -- because the word "পদবি", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. local article if args.A then article = args.A else article = #genders > 0 and genders[1] == "unknown-gender" and "an" or #genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or "a" if langcode == "en" then article = mw.getContentLanguage():ucfirst(article) end end ins(article .. " ") if #genders > 0 then ins(table.concat(genders, " or ") .. " ") end if adj then ins(adj .. " ") end ins("[[" .. iargs.type .. "]]") local need_comma = false if xlittext ~= "" then ins(", " .. xlittext) need_comma = true end local from_catparts = {} if args.from then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("fromtype")) local textseg, this_catparts = get_fromtext(lang, args) for _, catpart in ipairs(this_catparts) do m_table.insertIfNot(from_catparts, catpart) end ins(textseg) end if meaningtext ~= "" then if need_comma then ins(",") end need_comma = true ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) end if args.origin then if need_comma then ins(",") end need_comma = true ins(" of " .. args.origin .. " origin") end if args.usage then if need_comma then ins(",") end need_comma = true ins(" of " .. args.usage .. " usage") end if varoftext ~= "" then ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) end if clipoftext ~= "" then ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) end if blendtext ~= "" then ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) end if args.popular then ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) end if mtext ~= "" then ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) end if ftext ~= "" then ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) end if eqtext ~= "" then ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end if varformtext ~= "" then ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. varformtext) end ins("</span>") local text = table.concat(textsegs, "") if args.nocat then return text end local categories = {} local langname = lang:getCanonicalName() .. " " local function insert_cats(g) g = g and g .. " " or "" table.insert(categories, langname .. g .. iargs.type .. "s") for _, catpart in ipairs(from_catparts) do table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) end end insert_cats(nil) local function insert_cats_gender(g) if g == "unknown-gender" then return end if g == "common-gender" then insert_cats_gender("male") insert_cats_gender("female") end insert_cats(g) end for _, g in ipairs(genders) do insert_cats_gender(g) end return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end -- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. function export.name_translit(frame) local boolean = {type = "boolean"} local iargs = require("Module:parameters").process(frame.args, { ["desctext"] = {required = true}, ["obor"] = boolean, ["foreign_name"] = boolean, }) local parent_args = frame:getParent().args local params = { [1] = {required = true, type = "language", template_default = "en"}, [2] = {required = true, type = "language", sublist = true, template_default = "ru"}, [3] = {list = true, allow_holes = true}, ["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, ["dim"] = boolean, ["aug"] = boolean, ["nocap"] = boolean, ["addl"] = true, ["sort"] = true, ["pagename"] = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = {"xlit", "eq"}}, } local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 3, track_module = "names/name translit", disallow_custom_separators = true, -- Use the first source language as the language of the specified names. lang = function(args) return args[2][1] end, sc = "sc.default", } local lang = args[1] local langcode = lang:getCode() local sources = args[2] local pagename = args.pagename or mw.loadData("Module:headword/data").pagename local textsegs = {} local function ins(txt) table.insert(textsegs, txt) end ins("<span class='use-with-mention'>") local desctext = iargs.desctext if langcode == "en" and not args.nocap then desctext = mw.getContentLanguage():ucfirst(desctext) end ins(desctext .. " ") if not iargs.foreign_name then ins("of ") end local langsegs = {} for i, source in ipairs(sources) do local sourcename = source:getCanonicalName() local function get_source_link() local term_to_link = names[1] and names[1].term or pagename -- We link the language name to either the first specified name or the pagename, in the following -- circumstances: -- (1) More than one language was given along with at least one name; or -- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. -- The reason for (1) is that if more than one language was given, we want a link to the name -- in each language, as the name that's displayed is linked only to the first specified language. -- However, if only one language was given, linking the language to the name is redundant. -- The reason for (2) is that {{foreign name}} is often used when the name in the destination language -- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), -- and in that case no name will be explicitly specified but we still want a link to the name in the -- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to -- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be -- used for names spelled differently in the destination language (either transliterated or respelled), so -- assuming the pagename is the name in the source language is wrong. if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then return m_links.language_link{ lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" } else return sourcename end end if i == 1 and not iargs.foreign_name then -- If at least one name is given, we say "A transliteration of the LANG পদবি FOO", linking LANG to FOO. -- Otherwise we say "A transliteration of a LANG পদবি". if names[1] then table.insert(langsegs, "the " .. get_source_link()) else table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) end else table.insert(langsegs, get_source_link()) end end local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) local augdim_text if args.dim then augdim_text = " [[diminutive]]" elseif args.aug then augdim_text = " [[augmentative]]" else augdim_text = "" end local nametype_linked = {} for _, nametype in ipairs(args["type"]) do if nametype == "পদবি" or nametype == "patronymic" then table.insert(nametype_linked, "[[" .. nametype .. "]]") elseif nametype == "male given name" then table.insert(nametype_linked, "male [[given name]]") elseif nametype == "female given name" then table.insert(nametype_linked, "female [[given name]]") elseif nametype == "unisex given name" then table.insert(nametype_linked, "unisex [[given name]]") else table.insert(nametype_linked, nametype) end end local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text if not iargs.foreign_name then ins(langseg_text .. " ") ins(nametype_text) if names[1] then ins(" ") end else ins(nametype_text) ins(" in " .. langseg_text) if names[1] then ins(", ") end end local linked_names = {} local embedded_comma = false for _, name in ipairs(names) do local linked_name = m_links.full_link(name, "term") if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or name.refs and name.refs[1] then linked_name = require(pron_qualifier_module).format_qualifiers { lang = name.lang, text = linked_name, q = name.q, qq = name.qq, l = name.l, ll = name.ll, refs = name.refs, raw = true, } end if name.xlit then embedded_comma = true linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } end if name.eq then embedded_comma = true linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } end table.insert(linked_names, linked_name) end if embedded_comma then ins(table.concat(linked_names, "; or of ")) else ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) end if args.addl then if args.addl:find("^;") then ins(args.addl) elseif args.addl:find("^_") then ins(" " .. args.addl:sub(2)) else ins(", " .. args.addl) end end ins("</span>") local categories = {} local function inscat(cat) table.insert(categories, lang:getFullName() .. " " .. cat) end for _, nametype in ipairs(args.type) do local function insert_cats(dimaugof) local function insert_cats_type(ty) if ty == "unisex given name" then insert_cats_type("male given name") insert_cats_type("female given name") end for _, source in ipairs(sources) do inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") inscat("terms derived from " .. source:getCanonicalName()) inscat("terms borrowed from " .. source:getCanonicalName()) if iargs.obor then inscat("orthographic borrowings from " .. source:getCanonicalName()) end if source:getCode() ~= source:getFullCode() then -- etymology language inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") end end end insert_cats_type(nametype) end insert_cats("") if args.dim then insert_cats("diminutives of ") end if args.aug then insert_cats("augmentatives of ") end end return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) end return export cahzx5oldqo14gw4ytxleeflag0tf49 হিম 0 60828 509318 455894 2026-05-29T07:04:58Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L308242-এর সাথে সংযোগ তৈরি করছি 509318 wikitext text/x-wiki ==অসমীয়া== ===ব্যুৎপত্তি=== {{root|as|ine-pro|*ǵʰey-}} {{lbor|as|sa|हिम}}। ===উচ্চারণ=== * {{as-IPA}} ===বিশেষ্য=== {{head|as|noun}} # {{c|as|তুষার}} [[frost]], [[dew]], [[snow]] ===তথ্যসূত্র=== * {{R:as:CA|912}} * {{R:as:xobdo.org}} {{লে|L308242|ব্যুৎপত্তি={{root|bn|ine-pro|*ǵʰey-}} {{lbor|bn|sa|हिम}}।|উচ্চারণ=* {{IPA|bn|/ɦim/|[ɦiːm]}} }} ====সম্পর্কিত শব্দ==== * {{l|bn|হিমবাহ}} * {{l|bn|হিমশীতল}} * {{l|bn|হিমশৈল}} * {{l|bn|হিমসাগর}} * {{l|bn|হিমাগম}} * {{l|bn|হিমাগার}} * {{l|bn|হিমাঙ্গ}} * {{l|bn|হিমাচল}} * {{l|bn|হিমাদ্রি}} * {{l|bn|হিমালয়}} * {{l|bn|হিমায়িত}} * {{l|bn|হিমাংশু}} * {{l|bn|হিমেল}} * {{l|bn|হৈম}} ===বিশেষণ=== {{bn-বিশেষণ}} {{tlb|bn|সাহিত্যিক}} # [[cool]], [[cold]] ===তথ্যসূত্র=== * {{R:bn:Dasa|2158}} * {{R:bn:Bhattacharya|408}} * {{R:bn:Biswas|1058}} {{c|bn|Seasons|Temperature|তুষার}} joubnj8mhm7ya4df08g3hihd0xbb31y 509319 509318 2026-05-29T07:07:25Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L302123-এর সাথে সংযোগ তৈরি করছি 509319 wikitext text/x-wiki ==অসমীয়া== ===ব্যুৎপত্তি=== {{root|as|ine-pro|*ǵʰey-}} {{lbor|as|sa|हिम}}। ===উচ্চারণ=== * {{as-IPA}} ===বিশেষ্য=== {{head|as|noun}} # {{c|as|তুষার}} [[frost]], [[dew]], [[snow]] ===তথ্যসূত্র=== * {{R:as:CA|912}} * {{R:as:xobdo.org}} {{লে|L302123|ব্যুৎপত্তি={{root|bn|ine-pro|*ǵʰey-}} {{lbor|bn|sa|हिम}}।|উচ্চারণ=* {{IPA|bn|/ɦim/|[ɦiːm]}} ====সম্পর্কিত শব্দ==== * {{l|bn|হিমবাহ}} * {{l|bn|হিমশীতল}} * {{l|bn|হিমশৈল}} * {{l|bn|হিমসাগর}} * {{l|bn|হিমাগম}} * {{l|bn|হিমাগার}} * {{l|bn|হিমাঙ্গ}} * {{l|bn|হিমাচল}} * {{l|bn|হিমাদ্রি}} * {{l|bn|হিমালয়}} * {{l|bn|হিমায়িত}} * {{l|bn|হিমাংশু}} * {{l|bn|হিমেল}} * {{l|bn|হৈম}} ===বিশেষণ=== {{bn-বিশেষণ}} {{tlb|bn|সাহিত্যিক}} # [[cool]], [[cold]] ===তথ্যসূত্র=== * {{R:bn:Dasa|2158}} * {{R:bn:Bhattacharya|408}} * {{R:bn:Biswas|1058}} {{c|bn|Seasons|Temperature|তুষার}} 8ye19kziux82kipjk689aub3nm0mtut 509320 509319 2026-05-29T07:07:50Z Redmin 6857 509320 wikitext text/x-wiki ==অসমীয়া== ===ব্যুৎপত্তি=== {{root|as|ine-pro|*ǵʰey-}} {{lbor|as|sa|हिम}}। ===উচ্চারণ=== * {{as-IPA}} ===বিশেষ্য=== {{head|as|noun}} # {{c|as|তুষার}} [[frost]], [[dew]], [[snow]] ===তথ্যসূত্র=== * {{R:as:CA|912}} * {{R:as:xobdo.org}} {{লে|L302123|ব্যুৎপত্তি={{root|bn|ine-pro|*ǵʰey-}} {{lbor|bn|sa|हिम}}।|উচ্চারণ=* {{IPA|bn|/ɦim/|[ɦiːm]}}}} ====সম্পর্কিত শব্দ==== * {{l|bn|হিমবাহ}} * {{l|bn|হিমশীতল}} * {{l|bn|হিমশৈল}} * {{l|bn|হিমসাগর}} * {{l|bn|হিমাগম}} * {{l|bn|হিমাগার}} * {{l|bn|হিমাঙ্গ}} * {{l|bn|হিমাচল}} * {{l|bn|হিমাদ্রি}} * {{l|bn|হিমালয়}} * {{l|bn|হিমায়িত}} * {{l|bn|হিমাংশু}} * {{l|bn|হিমেল}} * {{l|bn|হৈম}} ===বিশেষণ=== {{bn-বিশেষণ}} {{tlb|bn|সাহিত্যিক}} # [[cool]], [[cold]] ===তথ্যসূত্র=== * {{R:bn:Dasa|2158}} * {{R:bn:Bhattacharya|408}} * {{R:bn:Biswas|1058}} {{c|bn|Seasons|Temperature|তুষার}} klvbqzwl4lt6dlxauissn7d56j2sq1s Alastar 0 73462 509321 452315 2026-05-29T08:08:40Z Redmin 6857 509321 wikitext text/x-wiki =={{ভাষা|ga}}== ===ব্যুৎপত্তি=== এর উৎস {{উত্তরাধিকারী|ga|sga|Alaxander}}, borrowed from {{bor|ga|la|Alexander}}; এর উৎস {{der|ga|grc|Ἀλέξανδρος}}; এর উৎস {{m|grc|ἀλέξω|t=I defend}} + {{m|grc|ἀνδρός}}, genitive of {{m|grc|ἀνήρ|t=man}}. ===উচ্চারণ=== * {{আধ্বব|ga|/ˈal̪ˠəsˠt̪ˠəɾˠ/}} ===নামবাচক বিশেষ্য=== {{ga-proper noun|m|Alastair}} # {{প্রদত্ত নাম|ga|পুরুষ|eq=Alexander,Alec}} ====জাত শব্দ==== * {{l|ga|Alastar Mór|g=m|t=Alexander the Great}} ===Mutation=== {{ga-mut|msn}} ===আরো পড়ুন=== * {{R:ga:Ó Dónaill}} * {{R:ga:EID}} * {{R:ga:NEID}} a01kpe8jbj62czpc2yt95k44hq90g1q ছিলা 0 125292 509316 268155 2026-05-29T06:44:11Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L408640-এর সাথে সংযোগ তৈরি করছি 509316 wikitext text/x-wiki {{লে|L408640|etymology=* সংস্কৃত: ছল্লি>|meaning=# [[আঁচল]] বা চাদরের প্রান্তভাগে বেরিয়ে থাকা ঝালর।}} ===ব্যুৎপত্তি ২=== * প্রাকৃত: ছোল্ল> === ক্রিয়া বিশেষ্য === {{বিশেষ্য|bn}} # খোসা ছাড়ানো। 8vyhfz8p2f8c455v3lugxciy9slpirg মডিউল:আভিধানিক উপাত্ত/i18n 828 148710 509308 509306 2026-05-28T16:33:25Z Redmin 6857 509308 Scribunto text/plain local p = {} p['wikipedia'] = 'bnwiki' p['fallback_wikipedia'] = 'enwiki' p['content_lang_name'] = 'বাংলা' p['content_lang_code'] = 'bn' p['heading_etymology'] = 'ব্যুৎপত্তি' p['heading_pronunciation'] = 'উচ্চারণ' p['heading_translation'] = 'অনুবাদ' p['heading_references'] = 'তথ্যসূত্র' p['heading_external_links'] = 'বহিঃসংযোগ' p['heading_alternative_spellings'] = 'বিকল্প বানান' p['heading_inflection_table'] = 'বিভক্তির সারণী' p['heading_form'] = 'রূপ' p['heading_grammatical_features'] = 'ব্যাকরণিক বৈশিষ্ট্য' p['heading_image'] = 'চিত্র' p['heading_alternative_script'] = 'বিকল্প রূপ' p['text_instance_of'] = 'একটি' p['text_audio'] = 'অডিও' p['text_iso15919'] = '[[w:আইএসও ১৫৯১৯|আইএসও ১৫৯১৯]]:' p['text_iast'] = '[[w:সংস্কৃত লিপ্যন্তরের আন্তর্জাতিক বর্ণমালা|সলিআব]]:' p['text_itrans'] = '[[w:en:ITRANS|ITRANS]]:' p['text_xsampa'] = '[[w:এক্স-সাম্পা|এক্স-সাম্পা]]:' p['text_syllable_count'] = '[[w:অক্ষর (সিলেবল)|অক্ষর]] সংখ্যা:' p['template_lexeme'] = 'উইকিউপাত্ত লেক্সিম' -- Q81739987 p['template_wikipedia'] = 'উইকিপিডিয়া' -- Q6275256 p['template_audio'] = 'অডিও ভাষার নাম' -- Q138620346 p['template_anchor'] = 'anchor' -- Q5412976 p['template_rfdef'] = 'rfdef' -- Q30733154 p['template_ipa'] = 'আধ্বব ভাষার নাম' -- Q138608718 p['template_trans-top'] = 'অনুবাদ-শীর্ষ' -- Q30528422 p['template_trans-bottom'] = 'অনুবাদ-নিচ' -- Q30528419 p['template_antonym'] = 'বিপরীতার্থক' -- Q35305357 p['template_synonym'] = 'synonyms' -- Q32751230 p['template_hypernym'] = 'hypernyms' -- Q35305454 p['template_demonym-noun'] = 'demonym-noun' -- Q130360250 p['template_demonym-adj'] = 'demonym-adj' -- Q135184225 p['template_homophones'] = 'সমোচ্চারিত' -- Q30557565 p['template_borrowed'] = 'ধারকৃত শব্দ' -- Q30872304 p['template_inherited'] = 'inherited' -- Q30864051 p['template_ar-rootbox'] = 'ar-rootbox' -- Q115627074 p['template_root'] = 'root' -- Q104521645 p['template_ellipsis'] = 'ellipsis' -- Q107037827 p['template_prefixsee'] = 'prefixsee' -- Q47517865 p['template_rootsee'] = 'rootsee' -- Q105987491 p['template_suffixsee'] = 'suffixsee' -- Q47517855 p['noun_template_suffix'] = '-noun' p['noun_template_suffix_fallback'] = '-বিশেষ্য' p['proper noun_template_suffix'] = '-proper noun' p['proper noun_template_suffix_fallback'] = '-নামবাচক বিশেষ্য' p['verb_template_suffix'] = '-verb' p['verb_template_suffix_fallback'] = '-ক্রিয়া' p['manual_category'] = {'বিষয়শ্রেণী', 'category'} p['manual_etymology'] = {'ব্যুৎপত্তি', 'etymology'} p['manual_pronunciation'] = {'উচ্চারণ', 'pronunciation'} p['manual_meaning'] = {'অর্থ', 'meaning'} p['manual_reference'] = {'তথ্যসূত্র', 'reference'} p['manual_external_link'] = {'বহিঃসংযোগ', 'external_link'} p['etymology_borrowing'] = 'থেকে [[w:ঋণশব্দ|ঋণকৃত]]' p['etymology_learned_borrowing'] = '$1 থেকে [[d:Q845079|শিক্ষিতভাবে ঋণকৃত]]' p['etymology_inheritance'] = 'থেকে [[উত্তরলব্ধ]]' p['etymology_ellipsis'] = '[[w:en:Ellipsis (linguistics)|সংক্ষিপ্ত হয়ে]] উপলব্ধ' -- অংশচ্ছেদ (ভাষাবিজ্ঞান) p['edit_wikidata'] = 'উইকিউপাত্তে সম্পাদনা করুন' -- বিষয়শ্রেণী যেগুলো অন্য উইকিঅভিধানে আছে p['category_rfdef'] = 'ভাষা অনুযায়ী সংজ্ঞার জন্য অনুরোধ' -- Q33129136 p['category_rfdef_equivalent'] = 'শব্দার্থের বাংলা মানের অনুরোধ' -- [[:wikt:en:Category:Requests for English equivalent term by language]]-এর কাছাকাছি p['category_no_matching_lemma'] = 'যেসব ভুক্তিতে লেমার হেডিং দেখানো অসম্ভব' -- Entries will be put in this category whenever a lemma heading cannot be rendered because no lemma of the linked lexeme matched the page title. p['category_given_names'] = 'প্রদত্ত নাম' -- Q8492384 -- বিষয়শ্রেণী যেগুলো অন্য উইকিঅভিধানে নেই p['text_category_rfdef'] = 'এই শব্দের লেক্সিমে অর্থ প্রয়োজন। দয়া করে লেক্সিম পাতায় গিয়ে একটি অর্থ যোগ করুন, যাতে অন্য পাঠকরা জানতে পারবে এটা মানে কি।' function p.tocatlink(str) return '[[বিষয়শ্রেণী:' .. str .. ']]' end function p.lang_category(lex_cat, language) local cat_text = p.tocatlink(language .. ' লেমা') cat_text = cat_text .. p.tocatlink(language .. ' ' .. lex_cat) return cat_text end function p.wplink(qid, display_text, wb) local link = wb.getSitelink(qid, p['wikipedia']) if link == nil then link = wb.getSitelink(qid, p['fallback_wikipedia']) if link ~= nil then return '[[w:en:' .. link .. '|' .. display_text .. ']]' end else return '[[w:' .. link .. '|' .. display_text .. ']]' end return '' end function p.rfref_category(language) local cat_text = p.tocatlink('তথ্যসূত্রহীন ' .. language .. ' শব্দ',language) return cat_text end p.nolinks = { -- These are words that are so commonly used that links to entries about them are unnecessary. ['করা'] = true, ['হওয়া'] = true, ['যাওয়া'] = true, ['যে'] = true, ['ও'] = true, ['তার'] = true, ['এবং'] = true, ['যার'] = true, ['যায়'] = true, } return p 742215a86unkq7buuphlm48c9lam1xi Obergefell 0 155204 509322 508781 2026-05-29T08:23:15Z Redmin 6857 /* নামবাচক বিশেষ্য */ 509322 wikitext text/x-wiki =={{ভাষা|en}}== ===উৎপত্তি=== ===উচ্চারণ=== * {{IPA|en|/ˈoʊbərɡəˌfɛl/}} * {{hyph|en|OH-bər-gə-fel}} ===নামবাচক বিশেষ্য=== {{en-proper-noun}} # {{lb|en|গণনাযোগ্য}} {{surname|en}}; ওবেরগেফেল — একটি পদবি। # {{lb|en|মার্কিন যুক্তরাষ্ট্র|আইন|লিঙ্গতা|মার্কিন রাজনীতি|অনানুষ্ঠানিক|অগণনীয়}} {{ellipsis of|en|[[Obergefell]] [[v.]] [[Hodges]]|addl=২০১৫ সালের একটি মার্কিন সুপ্রিম কোর্টের রায়, যা সমলিঙ্গ বিবাহকে বৈধতা দেয়; এবং চতুর্দশ সংশোধনী অনুসারে [[due process]]-এর মাধ্যমে [[গোপনীয়তার অধিকার]] পুনরায় নিশ্চিত করে।}} #: {{cot|en|Lawrence|Loving|substantive due process}} {{cln|en|eponyms}} clpupe7fxhkxg73a52qxzfstmy33rgt ট্রাম্প 0 155827 509326 338176 2026-05-29T08:38:40Z Redmin 6857 /* Proper noun */ 509326 wikitext text/x-wiki =={{ভাষা|bn}}== ===ব্যুৎপত্তি=== {{bor+|bn|en|Trump}}. ===উচ্চারণ=== * {{bn-IPA|ট্রাম্প্}} ===Proper noun=== {{bn-proper noun|tr={{xlit|bn|ট্রাম্প্}}}} # {{name translit|bn|en|Trump|type=পদবি}} ## {{w|Donald Trump}} (b. 1946), a businessman, television personality, and current president of the United States of America (2017-2021, 2025-present). {{c|bn|Individuals}} t0lreqjr3pzgjeta2dxc1t63s821t3u nonfootwear 0 159463 509327 441966 2026-05-29T08:42:29Z Redmin 6857 509327 wikitext text/x-wiki =={{ভাষা|en}}== ===ব্যুৎপত্তি=== {{উপসর্গ|en|non|footwear}} থেকে। ===বিশেষণ=== {{en-adj}} # [[পা]]য়ে পরিধেয় কিছুর (যেমন: [[জুতা]]) সাথে সম্পর্কিত নয় অথবা এর অন্তর্গত নয়। h5144ts1ou7gngoqzdsc6p0oa53ts9f আলাং 0 164839 509331 502800 2026-05-29T08:59:15Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L993155-এর সাথে সংযোগ তৈরি করছি 509331 wikitext text/x-wiki {{লে|L1348558}} {{লে|L993155}} te9jc98aunqgxnaziv9ak58sodbo81y الشكور 0 168091 509313 2026-05-29T06:42:13Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1566777-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 509313 wikitext text/x-wiki {{লে|L1566777}} ab6cluce69x066kln5mmwp26rtd2pz6 شكور 0 168092 509314 2026-05-29T06:42:37Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1513083-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 509314 wikitext text/x-wiki {{লে|L1513083}} 16wy8t7l60ambqk5p1dmtqam4cfcu90 509315 509314 2026-05-29T06:42:50Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1510005-এর সাথে সংযোগ তৈরি করছি 509315 wikitext text/x-wiki {{লে|L1513083}} {{লে|L1510005|না}} 4kz3nju31l93bd7bypgfle5ewzfglkc sew 0 168093 509330 2026-05-29T08:58:32Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L997416-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 509330 wikitext text/x-wiki {{লে|L997416}} 27671dn4d05f3zsf90735w9jlev5hep