উইকিঅভিধান 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.9 case-sensitive মিডিয়া বিশেষ আলাপ ব্যবহারকারী ব্যবহারকারী আলাপ উইকিঅভিধান উইকিঅভিধান আলোচনা চিত্র চিত্র আলোচনা মিডিয়াউইকি মিডিয়াউইকি আলোচনা টেমপ্লেট টেমপ্লেট আলোচনা সাহায্য সাহায্য আলোচনা বিষয়শ্রেণী বিষয়শ্রেণী আলোচনা পরিশিষ্ট পরিশিষ্ট আলোচনা ছন্দ ছন্দ আলোচনা থিসরাস থিসরাস আলোচনা উদ্ধৃতি উদ্ধৃতি আলোচনা TimedText TimedText talk মডিউল মডিউল আলাপ ইভেন্ট ইভেন্ট আলোচনা মডিউল:links 828 6287 512440 507788 2026-07-02T06:36:52Z Redmin 6857 512440 Scribunto text/plain local export = {} --[=[ [[Unsupported titles]], pages with high memory usage, extraction modules and part-of-speech names are listed at [[Module:links/data]]. Other modules used: [[Module:script utilities]] [[Module:scripts]] [[Module:languages]] and its submodules [[Module:gender and number]] [[Module:debug/track]] ]=] local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local form_of_module = "Module:form of" local gender_and_number_module = "Module:gender and number" local languages_module = "Module:languages" local load_module = "Module:load" local memoize_module = "Module:memoize" local pages_module = "Module:pages" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local script_utilities_module = "Module:script utilities" local string_encode_entities_module = "Module:string/encode entities" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local concat = table.concat local find = string.find local get_current_title = mw.title.getCurrentTitle local insert = table.insert local ipairs = ipairs local match = string.match local new_title = mw.title.new local pairs = pairs local remove = table.remove local sub = string.sub local toNFC = mw.ustring.toNFC local tostring = tostring local type = type local unstrip = mw.text.unstrip local NAMESPACE = get_current_title().nsText local function anchor_encode(...) anchor_encode = require(memoize_module)(mw.uri.anchorEncode, true) return anchor_encode(...) end local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function decode_uri(...) decode_uri = require(string_utilities_module).decode_uri return decode_uri(...) end -- Can't yet replace, as the [[Module:string utilities]] version no longer has automatic double-encoding prevention, which requires changes here to account for. local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_genders(...) format_genders = require(gender_and_number_module).format_genders return format_genders(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function get_current_L2(...) get_current_L2 = require(pages_module).get_current_L2 return get_current_L2(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function request_script(...) request_script = require(script_utilities_module).request_script return request_script(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function tag_translit(...) tag_translit = require(script_utilities_module).tag_translit return tag_translit(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local m_headword_data local function get_headword_data() m_headword_data = load_data("Module:headword/data") return m_headword_data end local function track(page, code) local tracking_page = "links/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function selective_trim(...) -- Unconditionally trimmed charset. local always_trim = "\194\128-\194\159" .. -- U+0080-009F (C1 control characters) "\194\173" .. -- U+00AD (soft hyphen) "\226\128\170-\226\128\174" .. -- U+202A-202E (directionality formatting characters) "\226\129\166-\226\129\169" -- U+2066-2069 (directionality formatting characters) -- Standard trimmed charset. local standard_trim = "%s" .. -- (default whitespace charset) "\226\128\139-\226\128\141" .. -- U+200B-200D (zero-width spaces) always_trim -- If there are non-whitespace characters, trim all characters in `standard_trim`. -- Otherwise, only trim the characters in `always_trim`. selective_trim = function(text) if text == "" then return text end local trimmed = trim(text, standard_trim) if trimmed ~= "" then return trimmed end return trim(text, always_trim) end return selective_trim(...) end local function escape(text, str) local rep repeat text, rep = text:gsub("\\\\(\\*" .. str .. ")", "\5%1") until rep == 0 return (text:gsub("\\" .. str, "\6")) end local function unescape(text, str) return (text :gsub("\5", "\\") :gsub("\6", str)) end -- Remove bold, italics, soft hyphens, strip markers and HTML tags. local function remove_formatting(str) str = str :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") return (unstrip(str) :gsub("<[^<>]+>", "")) end --[==[Takes an input and splits on a double slash (taking account of escaping backslashes).]==] function export.split_on_slashes(text) if text:find("\\", nil, true) then track("escaped", "split_on_slashes") end text = split(escape(text, "//"), "//", true) or {} for i, v in ipairs(text) do text[i] = unescape(v, "//") if v == "" then text[i] = false end end return text end --[==[Takes a wikilink and outputs the link target and display text. By default, the link target will be returned as a title object, but if `allow_bad_target` is set it will be returned as a string, and no check will be performed as to whether it is a valid link target.]==] function export.get_wikilink_parts(text, allow_bad_target) -- TODO: replace `allow_bad_target` with `allow_unsupported`, with support for links to unsupported titles, including escape sequences. if ( -- Filters out anything but "[[...]]" with no intermediate "[[" or "]]". not match(text, "^()%[%[") or -- Faster than sub(text, 1, 2) ~= "[[". find(text, "[[", 3, true) or find(text, "]]", 3, true) ~= #text - 1 ) then return nil, nil end local pipe, title, display = find(text, "|", 3, true) if pipe then title, display = sub(text, 3, pipe - 1), sub(text, pipe + 1, -3) else title = sub(text, 3, -3) display = title end if allow_bad_target then return title, display end title = new_title(title) -- No title object means the target is invalid. if title == nil then return nil, nil -- If the link target starts with "#" then mw.title.new returns a broken -- title object, so grab the current title and give it the correct fragment. elseif title.prefixedText == "" then local fragment = title.fragment if fragment == "" then -- [[#]] isn't valid return nil, nil end title = get_current_title() title.fragment = fragment end return title, display end -- Does the work of export.get_fragment, but can be called directly to avoid unnecessary checks for embedded links. local function get_fragment(text) text = escape(text, "#") -- Replace numeric character references with the corresponding character (&#39; → '), -- as they contain #, which causes the numeric character reference to be -- misparsed (wa'a → wa&#39;a → pagename wa&, fragment 39;a). text = decode_entities(text) local target, fragment = text:match("^(.-)#(.+)$") target = target or text target = unescape(target, "#") fragment = fragment and unescape(fragment, "#") return target, fragment end --[==[Takes a link target and outputs the actual target and the fragment (if any).]==] function export.get_fragment(text) if text:find("\\", nil, true) then track("escaped", "get_fragment") end -- If there are no embedded links, process input. local open = find(text, "[[", nil, true) if not open then return get_fragment(text) end local close = find(text, "]]", open + 2, true) if not close then return get_fragment(text) -- If there is one, but it's redundant (i.e. encloses everything with no pipe), remove and process. elseif open == 1 and close == #text - 1 and not find(text, "|", 3, true) then return get_fragment(sub(text, 3, -3)) end -- Otherwise, return the input. return text end --[==[ Given a link target as passed to `full_link()`, get the actual page that the target refers to. This removes bold, italics, strip markets and HTML; calls `makeEntryName()` for the language in question; converts targets beginning with `*` to the Reconstruction namespace; and converts appendix-constructed languages to the Appendix namespace. Returns up to three values: # the actual page to link to, or {nil} to not link to anything; # how the target should be displayed as, if the user didn't explicitly specify any display text; generally the same as the original target, but minus any anti-asterisk !!; # the value `true` if the target had a backslash-escaped * in it (FIXME: explain this more clearly). ]==] function export.get_link_page_with_auto_display(target, lang, sc, plain) local orig_target = target if not target then return nil elseif target:find("\\", nil, true) then track("escaped", "get_link_page") end target = remove_formatting(target) if target:sub(1, 1) == ":" then track("initial colon") -- FIXME, the auto_display (second return value) should probably remove the colon return target:sub(2), orig_target end local prefix = target:match("^(.-):") -- Convert any escaped colons target = target:gsub("\\:", ":") if prefix then -- If this is an a link to another namespace or an interwiki link, ensure there's an initial colon and then -- return what we have (so that it works as a conventional link, and doesn't do anything weird like add the term -- to a category.) prefix = ulower(trim(prefix)) if prefix ~= "" and ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then return target, orig_target end end -- Check if the term is reconstructed and remove any asterisk. Also check for anti-asterisk (!!). -- Otherwise, handle the escapes. local reconstructed, escaped, anti_asterisk if not plain then target, reconstructed = target:gsub("^%*(.)", "%1") if reconstructed == 0 then target, anti_asterisk = target:gsub("^!!(.)", "%1") if anti_asterisk == 1 then -- Remove !! from original. FIXME! We do it this way because the call to remove_formatting() above -- may cause non-initial !! to be interpreted as anti-asterisks. We should surely move the -- remove_formatting() call later. orig_target = orig_target:gsub("^!!", "") end end end target, escaped = target:gsub("^(\\-)\\%*", "%1*") if not (sc and sc:getCode() ~= "None") then sc = lang:findBestScript(target) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). if (not sc:hasCapitalization()) and sc:isTransliterated() and target:match("%^") then target = escape(target, "^") :gsub("%^", "") target = unescape(target, "^") end -- Get the entry name for the language. target = lang:makeEntryName(target, sc, reconstructed == 1 or lang:hasType("appendix-constructed")) -- If the link contains unexpanded template parameters, then don't create a link. if target:match("{{{.-}}}") then -- FIXME: Should we return the original target as the default display value (second return value)? return nil end -- Link to appendix for reconstructed terms and terms in appendix-only languages. Plain links interpret * -- literally, however. if reconstructed == 1 then if lang:getFullCode() == "und" then -- Return the original target as default display value. If we don't do this, we wrongly get -- [Term?] displayed instead. return nil, orig_target end target = "Reconstruction:" .. lang:getFullName() .. "/" .. target -- Reconstructed languages and substrates require an initial *. elseif anti_asterisk ~= 1 and (lang:hasType("reconstructed") or lang:getFamilyCode() == "qfa-sub") then --error(("The specified language %s is unattested, while the term '%s' does not begin with '*' to indicate that it is reconstructed.") -- : --format(lang:getCanonicalName(), orig_target)) elseif lang:hasType("appendix-constructed") then target = "Appendix:" .. lang:getFullName() .. "/" .. target else target = target end return target, orig_target, escaped > 0 end function export.get_link_page(target, lang, sc, plain) local target, auto_display, escaped = export.get_link_page_with_auto_display(target, lang, sc, plain) return target, escaped end -- Make a link from a given link's parts local function make_link(link, lang, sc, id, isolated, cats, no_alt_ast, plain) -- Convert percent encoding to plaintext. link.target = link.target and decode_uri(link.target, "PATH") link.fragment = link.fragment and decode_uri(link.fragment, "PATH") -- Find fragments (if one isn't already set). -- Prevents {{l|en|word#Etymology 2|word}} from linking to [[word#Etymology 2#English]]. -- # can be escaped as \#. if link.target and link.fragment == nil then link.target, link.fragment = get_fragment(link.target) end -- Process the target local auto_display, escaped link.target, auto_display, escaped = export.get_link_page_with_auto_display(link.target, lang, sc, plain) -- Create a default display form. -- If the target is "" then it's a link like [[#English]], which refers to the current page. if auto_display == "" then auto_display = (m_headword_data or get_headword_data()).pagename end -- If the display is the target and the reconstruction * has been escaped, remove the escaping backslash. if escaped then auto_display = auto_display:gsub("\\([^\\]*%*)", "%1", 1) end -- Process the display form. if link.display then local orig_display = link.display link.display = lang:makeDisplayText(link.display, sc, true) if cats then auto_display = lang:makeDisplayText(auto_display, sc) -- If the alt text is the same as what would have been automatically generated, then the alt parameter is redundant (e.g. {{l|en|foo|foo}}, {{l|en|w:foo|foo}}, but not {{l|en|w:foo|w:foo}}). -- If they're different, but the alt text could have been entered as the term parameter without it affecting the target page, then the target parameter is redundant (e.g. {{l|ru|фу|фу́}}). -- If `no_alt_ast` is true, use pcall to catch the error which will be thrown if this is a reconstructed lang and the alt text doesn't have *. if link.display == auto_display then insert(cats, lang:getFullName() .. " links with redundant alt parameters") else local ok, check if no_alt_ast then ok, check = pcall(export.get_link_page, orig_display, lang, sc, plain) else ok = true check = export.get_link_page(orig_display, lang, sc, plain) end if ok and link.target == check then insert(cats, lang:getFullName() .. " links with redundant target parameters") end end end else link.display = lang:makeDisplayText(auto_display, sc) end if not link.target then return link.display end -- If the target is the same as the current page, there is no sense id -- and either the language code is "und" or the current L2 is the current -- language then return a "self-link" like the software does. if link.target == get_current_title().prefixedText then local fragment, current_L2 = link.fragment, get_current_L2() if ( fragment and fragment == current_L2 or not (id or fragment) and (lang:getFullCode() == "und" or lang:getFullName() == current_L2) ) then return tostring(mw.html.create("strong") :addClass("selflink") :wikitext(link.display)) end end -- Add fragment. Do not add a section link to "Undetermined", as such sections do not exist and are invalid. -- TabbedLanguages handles links without a section by linking to the "last visited" section, but adding -- "Undetermined" would break that feature. For localized prefixes that make syntax error, please use the -- format: ["xyz"] = true. local prefix = link.target:match("^:*([^:]+):") prefix = prefix and ulower(prefix) if prefix ~= "category" and not (prefix and load_data("Module:data/interwikis")[prefix]) then if (link.fragment or link.target:sub(-1) == "#") and not plain then track("fragment", lang:getFullCode()) if cats then insert(cats, lang:getFullName() .. " links with manual fragments") end end if not link.fragment then if id then link.fragment = lang:getFullCode() == "und" and anchor_encode(id) or language_anchor(lang, id) elseif lang:getFullCode() ~= "und" and not (link.target:match("^Appendix:") or link.target:match("^Reconstruction:")) then link.fragment = anchor_encode(lang:getFullName()) end end end -- Put inward-facing square brackets around a link to isolated spacing character(s). if isolated and #link.display > 0 and not umatch(decode_entities(link.display), "%S") then link.display = "&#x5D;" .. link.display .. "&#x5B;" end link.target = link.target:gsub("^(:?)(.*)", function(m1, m2) return m1 .. encode_entities(m2, "#%&+/:<=>@[\\]_{|}") end) link.fragment = link.fragment and encode_entities(remove_formatting(link.fragment), "#%&+/:<=>@[\\]_{|}") return "[[" .. link.target:gsub("^[^:]", ":%0") .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]" end -- Split a link into its parts local function parse_link(linktext) local link = { target = linktext } local target = link.target link.target, link.display = target:match("^(..-)|(.+)$") if not link.target then link.target = target link.display = target end -- There's no point in processing these, as they aren't real links. local target_lower = link.target:lower() for _, false_positive in ipairs({ "category", "cat", "file", "image" }) do if target_lower:match("^" .. false_positive .. ":") then return nil end end link.display = decode_entities(link.display) link.target, link.fragment = get_fragment(link.target) -- So that make_link does not look for a fragment again. if not link.fragment then link.fragment = false end return link end local function check_params_ignored_when_embedded(alt, lang, id, cats) if alt then track("alt-ignored") if cats then insert(cats, lang:getFullName() .. " links with ignored alt parameters") end end if id then track("id-ignored") if cats then insert(cats, lang:getFullName() .. " links with ignored id parameters") end end end -- Find embedded links and ensure they link to the correct section. local function process_embedded_links(text, alt, lang, sc, id, cats, no_alt_ast, plain) -- Process the non-linked text. text = lang:makeDisplayText(text, sc, true) -- If the text begins with * and another character, then act as if each link begins with *. However, don't do this if the * is contained within a link at the start. E.g. `|*[[foo]]` would set all_reconstructed to true, while `|[[*foo]]` would not. local all_reconstructed = false if not plain then -- anchor_encode removes links etc. if anchor_encode(text):sub(1, 1) == "*" then all_reconstructed = true end -- Otherwise, handle any escapes. text = text:gsub("^(\\-)\\%*", "%1*") end check_params_ignored_when_embedded(alt, lang, id, cats) local function process_link(space1, linktext, space2) local capture = "[[" .. linktext .. "]]" local link = parse_link(linktext) -- Return unprocessed false positives untouched (e.g. categories). if not link then return capture end if all_reconstructed then if link.target:find("^!!") then -- Check for anti-asterisk !! at the beginning of a target, indicating that a reconstructed term -- wants a part of the term to link to a non-reconstructed term, e.g. Old English -- {{ang-noun|m|head=*[[!!Crist|Cristes]] [[!!mæsseǣfen]]}}. link.target = link.target:sub(3) -- Also remove !! from the display, which may have been copied from the target (as in mæsseǣfen in -- the example above). link.display = link.display:gsub("^!!", "") elseif not link.target:match("^%*") then link.target = "*" .. link.target end end linktext = make_link(link, lang, sc, id, false, nil, no_alt_ast, plain) :gsub("^%[%[", "\3") :gsub("%]%]$", "\4") return space1 .. linktext .. space2 end -- Use chars 1 and 2 as temporary substitutions, so that we can use charsets. These are converted to chars 3 and 4 by process_link, which means we can convert any remaining chars 1 and 2 back to square brackets (i.e. those not part of a link). text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- If the script uses ^ to capitalize transliterations, make sure that any carets preceding links are on the inside, so that they get processed with the following text. if ( text:find("^", nil, true) and not sc:hasCapitalization() and sc:isTransliterated() ) then text = escape(text, "^") :gsub("%^\1", "\1%^") text = unescape(text, "^") end text = text:gsub("\1(%s*)([^\1\2]-)(%s*)\2", process_link) -- Remove the extra * at the beginning of a language link if it's immediately followed by a link whose display begins with * too. if all_reconstructed then text = text:gsub("^%*\3([^|\1-\4]+)|%*", "\3%1|*") end return (text :gsub("[\1\3]", "[[") :gsub("[\2\4]", "]]") ) end local function simple_link(term, fragment, alt, lang, sc, id, cats, no_alt_ast, srwc) local plain if lang == nil then lang, plain = get_lang("und"), true end -- Get the link target and display text. If the term is the empty string, treat the input as a link to the current page. if term == "" then term = get_current_title().prefixedText elseif term then local new_term, new_alt = export.get_wikilink_parts(term, true) if new_term then check_params_ignored_when_embedded(alt, lang, id, cats) -- [[|foo]] links are treated as plaintext "[[|foo]]". -- FIXME: Pipes should be handled via a proper escape sequence, as they can occur in unsupported titles. if new_term == "" then term, alt = nil, term else local title = new_title(new_term) if title then local ns = title.namespace -- File: and Category: links should be returned as-is. if ns == 6 or ns == 14 then return term end end term, alt = new_term, new_alt if cats then if not (srwc and srwc(term, alt)) then insert(cats, lang:getFullName() .. " links with redundant wikilinks") end end end end end if alt then alt = selective_trim(alt) if alt == "" then alt = nil end end -- If there's nothing to process, return nil. if not (term or alt) then return nil end -- If there is no script, get one. if not sc then sc = lang:findBestScript(alt or term) end -- Embedded wikilinks need to be processed individually. if term then local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, alt, lang, sc, id, cats, no_alt_ast, plain) end term = selective_trim(term) end -- If not, make a link using the parameters. return make_link({ target = term, display = alt, fragment = fragment }, lang, sc, id, true, cats, no_alt_ast, plain) end --[==[Creates a basic link to the given term. It links to the language section (such as <code>==English==</code>), but it does not add language and script wrappers, so any code that uses this function should call the <code class="n">[[Module:script utilities#tag_text|tag_text]]</code> from [[Module:script utilities]] to add such wrappers itself at some point. The first argument, <code class="n">data</code>, may contain the following items, a subset of the items used in the <code class="n">data</code> argument of <code class="n">full_link</code>. If any other items are included, they are ignored. { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, id = sense_id, } } ; <code class="n">term</code> : Text to turn into a link. This is generally the name of a page. The text can contain wikilinks already embedded in it. These are processed individually just like a single link would be. The <code class="n">alt</code> argument is ignored in this case. ; <code class="n">alt</code> (''optional'') : The alternative display for the link, if different from the linked page. If this is {{code|lua|nil}}, the <code class="n">text</code> argument is used instead (much like regular wikilinks). If <code class="n">text</code> contains wikilinks in it, this argument is ignored and has no effect. (Links in which the alt is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/alt-ignored}}.) ; <code class="n">lang</code> : The [[Module:languages#Language objects|language object]] for the term being linked. If this argument is defined, the function will determine the language's canonical name (see [[Template:language data documentation]]), and point the link or links in the <code class="n">term</code> to the language's section of an entry, or to a language-specific senseid if the <code class="n">id</code> argument is defined. ; <code class="n">id</code> (''optional'') : Sense id string. If this argument is defined, the link will point to a language-specific sense id ({{ll|en|identifier|id=HTML}}) created by the template {{temp|senseid}}. A sense id consists of the language's canonical name, a hyphen (<code>-</code>), and the string that was supplied as the <code class="n">id</code> argument. This is useful when a term has more than one sense in a language. If the <code class="n">term</code> argument contains wikilinks, this argument is ignored. (Links in which the sense id is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/id-ignored}}.) The second argument is as follows: ; <code class="n">allow_self_link</code> : If {{code|lua|true}}, the function will also generate links to the current page. The default ({{code|lua|false}}) will not generate a link but generate a bolded "self link" instead. The following special options are processed for each link (both simple text and with embedded wikilinks): * The target page name will be processed to generate the correct entry name. This is done by the [[Module:languages#makeEntryName|makeEntryName]] function in [[Module:languages]], using the <code class="n">entry_name</code> replacements in the language's data file (see [[Template:language data documentation]] for more information). This function is generally used to automatically strip dictionary-only diacritics that are not part of the normal written form of a language. * If the text starts with <code class="n">*</code>, then the term is considered a reconstructed term, and a link to the Reconstruction: namespace will be created. If the text contains embedded wikilinks, then <code class="n">*</code> is automatically applied to each one individually, while preserving the displayed form of each link as it was given. This allows linking to phrases containing multiple reconstructed terms, while only showing the * once at the beginning. * If the text starts with <code class="n">:</code>, then the link is treated as "raw" and the above steps are skipped. This can be used in rare cases where the page name begins with <code class="n">*</code> or if diacritics should not be stripped. For example: ** {{temp|l|en|*nix}} links to the nonexistent page [[Reconstruction:English/nix]] (<code class="n">*</code> is interpreted as a reconstruction), but {{temp|l|en|:*nix}} links to [[*nix]]. ** {{temp|l|sl|Franche-Comté}} links to the nonexistent page [[Franche-Comte]] (<code>é</code> is converted to <code>e</code> by <code class="n">makeEntryName</code>), but {{temp|l|sl|:Franche-Comté}} links to [[Franche-Comté]].]==] function export.language_link(data) if type(data) ~= "table" then error( "The first argument to the function language_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "language_link") end -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Undetermined language links") end return simple_link( data.term, data.fragment, data.alt, lang, data.sc, data.id, cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end function export.plain_link(data) if type(data) ~= "table" then error( "The first argument to the function plain_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "plain_link") end return simple_link( data.term, data.fragment, data.alt, nil, data.sc, data.id, data.cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end --[==[Replace any links with links to the correct section, but don't link the whole text if no embedded links are found. Returns the display text form.]==] function export.embedded_language_links(data) if type(data) ~= "table" then error( "The first argument to the function embedded_language_links must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "embedded_language_links") end local term, lang, sc = data.term, data.lang, data.sc -- If we don't have a script, get one. if not sc then sc = lang:findBestScript(term) end -- Do we have embedded wikilinks? If so, they need to be processed individually. local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, data.alt, lang, sc, data.id, data.cats, data.no_alt_ast) end -- If not, return the display text. term = selective_trim(term) -- FIXME: Double-escape any percent-signs, because we don't want to treat non-linked text as having percent-encoded characters. This is a hack: percent-decoding should come out of [[Module:languages]] and only dealt with in this module, as it's specific to links. term = term:gsub("%%", "%%25") return lang:makeDisplayText(term, sc, true) end function export.mark(text, item_type, face, lang) local tag = { "", "" } if item_type == "gloss" then tag = { '<span class="mention-gloss-double-quote">“</span><span class="mention-gloss">', '</span><span class="mention-gloss-double-quote">”</span>' } if type(text) == "string" and text:match("^''[^'].*''$") then -- Temporary tracking for mention glosses that are entirely italicized or bolded, which is probably -- wrong. (Note that this will also find bolded mention glosses since they use triple apostrophes.) track("italicized-mention-gloss", lang and lang:getFullCode() or nil) end elseif item_type == "tr" then if face == "term" then tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr mention-tr Latn">', '</span>' } else tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr Latn">', '</span>' } end elseif item_type == "ts" then -- \226\129\160 = word joiner (zero-width non-breaking space) U+2060 tag = { '<span class="ts mention-ts Latn">/\226\129\160', '\226\129\160/</span>' } elseif item_type == "pos" then tag = { '<span class="ann-pos">', '</span>' } elseif item_type == "non-gloss" then tag = { '<span class="ann-non-gloss">', '</span>' } elseif item_type == "annotations" then tag = { '<span class="mention-gloss-paren annotation-paren">(</span>', '<span class="mention-gloss-paren annotation-paren">)</span>' } elseif item_type == "infl" then tag = { '<span class="ann-infl">', '</span>' } end if type(text) == "string" then return tag[1] .. text .. tag[2] else return "" end end local pos_tags --[==[Formats the annotations that are displayed with a link created by {{code|lua|full_link}}. Annotations are the extra bits of information that are displayed following the linked term, and include things such as gender, transliteration, gloss and so on. * The first argument is a table possessing some or all of the following keys: *:; <code class="n">genders</code> *:: Table containing a list of gender specifications in the style of [[Module:gender and number]]. *:; <code class="n">tr</code> *:: Transliteration. *:; <code class="n">gloss</code> *:: Gloss that translates the term in the link, or gives some other descriptive information. *:; <code class="n">pos</code> *:: Part of speech of the linked term. If the given argument matches one of the aliases in `pos_aliases` in [[Module:headword/data]], or consists of a part of speech or alias followed by `f` (for a non-lemma form), expand it appropriately. Otherwise, just show the given text as it is. *:; <code class="n">ng</code> *:: Arbitrary non-gloss descriptive text for the link. This should be used in preference to putting descriptive text in `gloss` or `pos`. *:; <code class="n">lit</code> *:: Literal meaning of the term, if the usual meaning is figurative or idiomatic. *:; <code class="n">infl</code> *:: Table containing a list of grammar tags in the style of [[Module:form of]] `tagged_inflections`. *:Any of the above values can be omitted from the <code class="n">info</code> argument. If a completely empty table is given (with no annotations at all), then an empty string is returned. * The second argument is a string. Valid values are listed in [[Module:script utilities/data]] "data.translit" table.]==] function export.format_link_annotations(data, face) local output = {} -- Interwiki link if data.interwiki then insert(output, data.interwiki) end -- Genders if type(data.genders) ~= "table" then data.genders = { data.genders } end if data.genders and #data.genders > 0 then local genders, gender_cats = format_genders(data.genders, data.lang) insert(output, "&nbsp;" .. genders) if gender_cats then local cats = data.cats if cats then extend(cats, gender_cats) end end end local annotations = {} -- Transliteration and transcription if data.tr and data.tr[1] or data.ts and data.ts[1] then local kind if face == "term" then kind = face else kind = "default" end if data.tr[1] and data.ts[1] then insert(annotations, tag_translit(data.tr[1], data.lang, kind) .. " " .. export.mark(data.ts[1], "ts")) elseif data.ts[1] then insert(annotations, export.mark(data.ts[1], "ts")) else insert(annotations, tag_translit(data.tr[1], data.lang, kind)) end end -- Gloss/translation if data.gloss then insert(annotations, export.mark(data.gloss, "gloss")) end -- Part of speech if data.pos then -- debug category for pos= containing transcriptions if data.pos:match("/[^><]-/") then data.pos = data.pos .. "[[Category:links likely containing transcriptions in pos]]" end -- Canonicalize part of speech aliases as well as non-lemma aliases like 'nf' or 'nounf' for "noun form". pos_tags = pos_tags or (m_headword_data or get_headword_data()).pos_aliases local pos = pos_tags[data.pos] if not pos and data.pos:find("f$") then local pos_form = data.pos:sub(1, -2) -- We only expand something ending in 'f' if the result is a recognized non-lemma POS. pos_form = (pos_tags[pos_form] or pos_form) .. " form" if (m_headword_data or get_headword_data()).nonlemmas[pos_form .. "s"] then pos = pos_form end end insert(annotations, export.mark(pos or data.pos, "pos")) end -- Inflection data if data.infl then local m_form_of = require(form_of_module) -- Split tag sets manually, since tagged_inflections creates a numbered list, and we do not want that. local infl_outputs = {} local tag_sets = m_form_of.split_tag_set(data.infl) for _, tag_set in ipairs(tag_sets) do table.insert(infl_outputs, m_form_of.tagged_inflections({ tags = tag_set, lang = data.lang, nocat = true, nolink = true, nowrap = true })) end insert(annotations, export.mark(table.concat(infl_outputs, "; "), "infl")) end -- Non-gloss text if data.ng then insert(annotations, export.mark(data.ng, "non-gloss")) end -- Literal/sum-of-parts meaning if data.lit then insert(annotations, "literally " .. export.mark(data.lit, "gloss")) end -- Provide a hook to insert additional annotations such as nested inflections. if data.postprocess_annotations then data.postprocess_annotations { data = data, annotations = annotations } end if #annotations > 0 then insert(output, " " .. export.mark(concat(annotations, ", "), "annotations")) end return concat(output) end -- Encode certain characters to avoid various delimiter-related issues at various stages. We need to encode < and > -- because they end up forming part of CSS class names inside of <span ...> and will interfere with finding the end -- of the HTML tag. I first tried converting them to URL encoding, i.e. %3C and %3E; they then appear in the URL as -- %253C and %253E, which get mapped back to %3C and %3E when passed to [[Module:accel]]. But mapping them to &lt; -- and &gt; somehow works magically without any further work; they appear in the URL as < and >, and get passed to -- [[Module:accel]] as < and >. I have no idea who along the chain of calls is doing the encoding and decoding. If -- someone knows, please modify this comment appropriately! local accel_char_map local function get_accel_char_map() accel_char_map = { ["%"] = ".", [" "] = "_", ["_"] = u(0xFFF0), ["<"] = "&lt;", [">"] = "&gt;", } return accel_char_map end local function encode_accel_param_chars(param) return (param:gsub("[% <>_]", accel_char_map or get_accel_char_map())) end local function encode_accel_param(prefix, param) if not param then return "" end if type(param) == "table" then local filled_params = {} -- There may be gaps in the sequence, especially for translit params. local maxindex = 0 for k in pairs(param) do if type(k) == "number" and k > maxindex then maxindex = k end end for i = 1, maxindex do filled_params[i] = param[i] or "" end -- [[Module:accel]] splits these up again. param = concat(filled_params, "*~!") end -- This is decoded again by [[WT:ACCEL]]. return prefix .. encode_accel_param_chars(param) end local function insert_if_not_blank(list, item) if item == "" then return end insert(list, item) end local function get_class(lang, tr, accel, nowrap) if not accel and not nowrap then return "" end local classes = {} if accel then insert(classes, "form-of lang-" .. lang:getFullCode()) local form = accel.form if form then insert(classes, encode_accel_param_chars(form) .. "-form-of") end insert_if_not_blank(classes, encode_accel_param("gender-", accel.gender)) insert_if_not_blank(classes, encode_accel_param("pos-", accel.pos)) insert_if_not_blank(classes, encode_accel_param("transliteration-", accel.translit or (tr ~= "-" and tr or nil))) insert_if_not_blank(classes, encode_accel_param("target-", accel.target)) insert_if_not_blank(classes, encode_accel_param("origin-", accel.lemma)) insert_if_not_blank(classes, encode_accel_param("origin_transliteration-", accel.lemma_translit)) if accel.no_store then insert(classes, "form-of-nostore") end end if nowrap then insert(classes, nowrap) end return concat(classes, " ") end -- Add any left or right regular or accent qualifiers, labels or references to a formatted term. `data` is the object -- specifying the term, which should optionally contain: -- * a language object in `lang`; required if any accent qualifiers or labels are given; -- * left regular qualifiers in `q` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * right regular qualifiers in `qq` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * left accent qualifiers in `a` (an array of strings); an empty array will be ignored; -- * right accent qualifiers in `aa` (an array of strings); an empty array will be ignored; -- * left labels in `l` (an array of strings); an empty array will be ignored; -- * right labels in `ll` (an array of strings); an empty array will be ignored; -- * references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text` -- (formatted reference text) and optionally `name` and/or `group`. -- `formatted` is the formatted version of the term itself. local function add_qualifiers_and_refs_to_term(data, formatted) local q = data.q if type(q) == "string" then q = { q } end local qq = data.qq if type(qq) == "string" then qq = { qq } end if q and q[1] or qq and qq[1] or data.a and data.a[1] or data.aa and data.aa[1] or data.l and data.l[1] or data.ll and data.ll[1] or data.refs and data.refs[1] then formatted = format_qualifiers { lang = data.lang, text = formatted, q = q, qq = qq, a = data.a, aa = data.aa, l = data.l, ll = data.ll, refs = data.refs, } end return formatted end --[==[ Creates a full link, with annotations (see `[[#format_link_annotations|format_link_annotations]]`), in the style of {{tl|l}} or {{tl|m}}. The first argument, `data`, must be a table. It contains the various elements that can be supplied as parameters to {{tl|l}} or {{tl|m}}: { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, sc = script_object, track_sc = boolean, no_nonstandard_sc_cat = boolean, fragment = link_fragment, id = sense_id, genders = { "gender1", "gender2", ... }, tr = transliteration, respect_link_tr = boolean, ts = transcription, gloss = gloss, pos = part_of_speech_tag, ng = non-gloss text, lit = literal_translation, infl = { "form_of_grammar_tag1", "form_of_grammar_tag2", ... }, no_alt_ast = boolean, accel = {accelerated_creation_tags}, interwiki = interwiki, pretext = "text_at_beginning" or nil, posttext = "text_at_end" or nil, q = { "left_qualifier1", "left_qualifier2", ...} or "left_qualifier", qq = { "right_qualifier1", "right_qualifier2", ...} or "right_qualifier", l = { "left_label1", "left_label2", ...}, ll = { "right_label1", "right_label2", ...}, a = { "left_accent_qualifier1", "left_accent_qualifier2", ...}, aa = { "right_accent_qualifier1", "right_accent_qualifier2", ...}, refs = { "formatted_ref1", "formatted_ref2", ...} or { {text = "text", name = "name", group = "group"}, ... }, show_qualifiers = boolean, } } Any one of the items in the `data` table may be {nil}, but an error will be shown if neither `term` nor `alt` nor `tr` is present. Thus, calling {full_link{ term = term, lang = lang, sc = sc }}, where `term` is the page to link to (which may have diacritics that will be stripped and/or embedded bracketed links) and `lang` is a [[Module:languages#Language objects|language object]] from [[Module:languages]], will give a plain link similar to the one produced by the template {{tl|l}}, and calling {full_link( { term = term, lang = lang, sc = sc }, "term" )} will give a link similar to the one produced by the template {{tl|m}}. The function will: * Try to determine the script, based on the characters found in the `term` or `alt` argument, if the script was not given. If a script is given and `track_sc` is {true}, it will check whether the input script is the same as the one which would have been automatically generated and add the category [[:Category:LANG terms with redundant script codes]] if yes, or [[:Category:LANG terms with non-redundant manual script codes]] if no. This should be used when the input script object is directly determined by a template's `sc` parameter. * Call `[[#language_link|language_link]]` on the `term` or `alt` forms, to remove diacritics in the page name, process any embedded wikilinks and create links to Reconstruction or Appendix pages when necessary. * Call `[[Module:script utilities#tag_text]]` to add the appropriate language and script tags to the term and italicize terms written in the Latin script if necessary. Accelerated creation tags, as used by [[WT:ACCEL]], are included. * Generate a transliteration, based on the `alt` or `term` arguments, if the script is not Latin, no transliteration was provided in `tr` and the combination of the term's language and script support automatic transliteration. The transliteration itself will be linked if both `.respect_link_tr` is specified and the language of the term has the `link_tr` property set for the script of the term; but not otherwise. * Add the annotations (transliteration, gender, gloss, etc.) after the link. * If `no_alt_ast` is specified, then the `alt` text does not need to contain an asterisk if the language is reconstructed. This should only be used by modules which really need to allow links to reconstructions that don't display asterisks (e.g. number boxes). * If `pretext` or `posttext` is specified, this is text to (respectively) prepend or append to the output, directly before processing qualifiers, labels and references. This can be used to add arbitrary extra text inside of the qualifiers, labels and references. * If `show_qualifiers` is specified or the `show_qualifiers` argument is given, then left and right qualifiers, accent qualifiers, labels and references will be displayed, otherwise they will be ignored. (This is because a fair amount of code stores qualifiers, labels and/or references in these fields and displays them itself, rather than expecting {full_link()} to display them.)]==] function export.full_link(data, face, allow_self_link, show_qualifiers) if type(data) ~= "table" then error("The first argument to the function full_link must be a table. " .. "See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "full_link") end -- Prevent data from being destructively modified. local data = shallow_copy(data) -- FIXME: this shouldn't be added to `data`, as that means the input table needs to be cloned. data.cats = {} -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Undetermined language links") end local terms = { true } -- Generate multiple forms if applicable. for _, param in ipairs { "term", "alt" } do if type(data[param]) == "string" and data[param]:find("//", nil, true) then data[param] = export.split_on_slashes(data[param]) elseif type(data[param]) == "string" and not (type(data.term) == "string" and data.term:find("//", nil, true)) then if not data.no_generate_forms then data[param] = lang:generateForms(data[param]) else data[param] = { data[param] } end else data[param] = {} end end for _, param in ipairs { "sc", "tr", "ts" } do data[param] = { data[param] } end for _, param in ipairs { "term", "alt", "sc", "tr", "ts" } do for i in pairs(data[param]) do terms[i] = true end end -- Create the link local output = {} local id, no_alt_ast, srwc, accel, nevercalltr = data.id, data.no_alt_ast, data.suppress_redundant_wikilink_cat, data.accel, data.never_call_transliteration_module local link_tr = data.respect_link_tr and lang:link_tr(data.sc[1]) for i in ipairs(terms) do local link -- Is there any text to show? if (data.term[i] or data.alt[i]) then -- Try to detect the script if it was not provided local display_term = data.alt[i] or data.term[i] local best = lang:findBestScript(display_term) -- no_nonstandard_sc_cat is intended for use in [[Module:interproject]] if ( not data.no_nonstandard_sc_cat and best:getCode() == "None" and find_best_script_without_lang(display_term):getCode() ~= "None" ) then insert(cats, lang:getFullName() .. " terms in nonstandard scripts") end if not data.sc[i] then data.sc[i] = best -- Track uses of sc parameter. elseif data.track_sc then if data.sc[i]:getCode() == best:getCode() then insert(cats, lang:getFullName() .. " terms with redundant script codes") else insert(cats, lang:getFullName() .. " terms with non-redundant manual script codes") end end -- If using a discouraged character sequence, add to maintenance category if data.sc[i]:hasNormalizationFixes() == true then if (data.term[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.term[i])) ~= toNFC(data.term[i])) or (data.alt[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.alt[i])) ~= toNFC(data.alt[i])) then insert(cats, "Pages using discouraged character sequences") end end link = simple_link( data.term[i], data.fragment, data.alt[i], lang, data.sc[i], id, cats, no_alt_ast, srwc ) end -- simple_link can return nil, so check if a link has been generated. if link then -- Add "nowrap" class to prefixes in order to prevent wrapping after the hyphen local nowrap local display_term = data.alt[i] or data.term[i] if display_term and (display_term:find("^%-") or display_term:find("^־")) then -- Hebrew maqqef -- FIXME, use hyphens from [[Module:affix]] nowrap = "nowrap" end link = tag_text(link, lang, data.sc[i], face, get_class(lang, data.tr[i], accel, nowrap)) else --[[ No term to show. Is there at least a transliteration we can work from? ]] link = request_script(lang, data.sc[i]) -- No link to show, and no transliteration either. Show a term request (unless it's a substrate, as they rarely take terms). if (link == "" or (not data.tr[i]) or data.tr[i] == "-") and lang:getFamilyCode() ~= "qfa-sub" then -- If there are multiple terms, break the loop instead. if i > 1 then remove(output) break elseif NAMESPACE ~= "Template" then insert(cats, lang:getFullName() .. " term requests") end link = "<small>[Term?]</small>" end end insert(output, link) if i < #terms then insert(output, "<span class=\"Zsym mention\" style=\"font-size:100%;\">&nbsp;/ </span>") end end -- When suppress_tr is true, do not show or generate any transliteration if data.suppress_tr then data.tr[1] = nil else -- TODO: Currently only handles the first transliteration, pending consensus on how to handle multiple translits for multiple forms, as this is not always desirable (e.g. traditional/simplified Chinese). if data.tr[1] == "" or data.tr[1] == "-" then data.tr[1] = nil else local phonetic_extraction = load_data("Module:links/data").phonetic_extraction phonetic_extraction = phonetic_extraction[lang:getCode()] or phonetic_extraction[lang:getFullCode()] if phonetic_extraction then data.tr[1] = data.tr[1] or require(phonetic_extraction).getTranslit(export.remove_links(data.alt[1] or data.term[1])) elseif (data.term[1] or data.alt[1]) and data.sc[1]:isTransliterated() then -- Track whenever there is manual translit. The categories below like 'terms with redundant transliterations' -- aren't sufficient because they only work with reference to automatic translit and won't operate at all in -- languages without any automatic translit, like Persian and Hebrew. if data.tr[1] then local full_code = lang:getFullCode() track("manual-tr", full_code) end if not nevercalltr then -- Try to generate a transliteration. local text = data.alt[1] or data.term[1] if not link_tr then text = export.remove_links(text, true) end local automated_tr = lang:transliterate(text, data.sc[1]) if automated_tr then local manual_tr = data.tr[1] if manual_tr then if export.remove_links(manual_tr) == export.remove_links(automated_tr) then insert(cats, lang:getFullName() .. " terms with redundant transliterations") else -- Prevents Arabic root categories from flooding the tracking categories. if NAMESPACE ~= "Category" then insert(cats, lang:getFullName() .. " terms with non-redundant manual transliterations") end end end if not manual_tr or lang:overrideManualTranslit(data.sc[1]) then data.tr[1] = automated_tr end end end end end end -- Link to the transliteration entry for languages that require this if data.tr[1] and link_tr and not data.tr[1]:match("%[%[(.-)%]%]") then data.tr[1] = simple_link( data.tr[1], nil, nil, lang, get_script("Latn"), nil, cats, no_alt_ast, srwc ) elseif data.tr[1] and not link_tr then -- Remove the pseudo-HTML tags added by remove_links. data.tr[1] = data.tr[1]:gsub("</?link>", "") end if data.tr[1] and not umatch(data.tr[1], "[^%s%p]") then data.tr[1] = nil end insert(output, export.format_link_annotations(data, face)) if data.pretext then insert(output, 1, data.pretext) end if data.posttext then insert(output, data.posttext) end local categories = cats[1] and format_categories(cats, lang, "-", nil, nil, data.sc) or "" output = concat(output) if show_qualifiers or data.show_qualifiers then output = add_qualifiers_and_refs_to_term(data, output) end return output .. categories end --[==[Replaces all wikilinks with their displayed text, and removes any categories. This function can be invoked either from a template or from another module. -- Strips links: deletes category links, the targets of piped links, and any double square brackets involved in links (other than file links, which are untouched). If `tag` is set, then any links removed will be given pseudo-HTML tags, which allow the substitution functions in [[Module:languages]] to properly subdivide the text in order to reduce the chance of substitution failures in modules which scrape pages like [[Module:zh-translit]]. -- FIXME: This is quite hacky. We probably want this to be integrated into [[Module:languages]], but we can't do that until we know that nothing is pushing pipe linked transliterations through it for languages which don't have link_tr set. * <code><nowiki>[[page|displayed text]]</nowiki></code> &rarr; <code><nowiki>displayed text</nowiki></code> * <code><nowiki>[[page and displayed text]]</nowiki></code> &rarr; <code><nowiki>page and displayed text</nowiki></code> * <code><nowiki>[[Category:English lemmas|WORD]]</nowiki></code> &rarr; ''(nothing)'']==] function export.remove_links(text, tag) if type(text) == "table" then text = text.args[1] end if not text or text == "" then return "" end text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Parse internal links for the display text. text = text:gsub("(\1)([^\1\2]-)(\2)", function(c1, c2, c3) -- Don't remove files. for _, false_positive in ipairs({ "file", "image" }) do if c2:lower():match("^" .. false_positive .. ":") then return c1 .. c2 .. c3 end end -- Remove categories completely. for _, false_positive in ipairs({ "category", "cat" }) do if c2:lower():match("^" .. false_positive .. ":") then return "" end end -- In piped links, remove all text before the pipe, unless it's the final character (i.e. the pipe trick), in which case just remove the pipe. c2 = c2:match("^[^|]*|(.+)") or c2:match("([^|]+)|$") or c2 if tag then return "<link>" .. c2 .. "</link>" else return c2 end end) text = text :gsub("\1", "[[") :gsub("\2", "]]") return text end function export.section_link(link) if type(link) ~= "string" then error("The first argument to section_link was a " .. type(link) .. ", but it should be a string.") elseif link:find("\\", nil, true) then track("escaped", "section_link") end local target, section = get_fragment((link:gsub("_", " "))) if not section then error("No \"#\" delineating a section name") end return simple_link( target, section, target .. " §&nbsp;" .. section ) end return export 44ts68ibk7xgxzqbwed8pc45072kqy8 ব্যবহারকারী আলাপ:Redmin 3 24780 512448 512359 2026-07-02T08:22:55Z MediaWiki message delivery 2534 /* Wikifunctions & Abstract Wikipedia Newsletter #255: Integration on test wiki and annual plan */ নতুন অনুচ্ছেদ 512448 wikitext text/x-wiki == I seen your RedminBot Tamil entries Creations == I seen your RedminBot Tamil entries Creations . That's was really nice. I hope you are interested in Tamil entries creations. Thanks for your continuous support! i created a spreadsheet file for Creating Tamil entries in bnwikt [https://docs.google.com/spreadsheets/d/1KDnIFSo8mCgN5Cb4GVxMv_gcgecZxjdFzQso9l-VhWg/edit#gid=0 See this]. This maybe useful for your bot Tamil entries. Thanks Again. [[ব্যবহারকারী:Sriveenkat|Sriveenkat]] ([[ব্যবহারকারী আলাপ:Sriveenkat|আলাপ]]) ০৭:৩৩, ৫ অক্টোবর ২০২৩ (ইউটিসি) :Thank you for this! I will make entries manually as this is too complex for the bot but this really helps. :D [[ব্যবহারকারী:Redmin|Redmin]] ([[ব্যবহারকারী আলাপ:Redmin#top|আলাপ]]) ০৯:৩৭, ৫ অক্টোবর ২০২৩ (ইউটিসি) ::Ok Redmin Thanks. We will do manually Thanks Again. [[ব্যবহারকারী:Sriveenkat|Sriveenkat]] ([[ব্যবহারকারী আলাপ:Sriveenkat|আলাপ]]) ০৯:৫৭, ৫ অক্টোবর ২০২৩ (ইউটিসি) == পর্যালোচনা == [[နာမ်]] এর বিশেষ্যের জন্য মডিউল তৈরি করেছি: [[মডিউল:my-headword]]। ইংরেজিতে [[https://en.m.wiktionary.org/wiki/Module:my-headword Module:my-headword]] কিন্তু কাজ হচ্ছে না কেন? [[ব্যবহারকারী:খালিদ জে. হোসেইন|哈立德]] ১৮:২৩, ২৮ ডিসেম্বর ২০২৩ (ইউটিসি) :@[[ব্যবহারকারী:খালিদ জে. হোসেইন|খালিদ জে. হোসেইন]], এখনও কি একই অবস্থা? [[ব্যবহারকারী:Redmin|Redmin]] ([[ব্যবহারকারী আলাপ:Redmin#top|আলাপ]]) ১৪:০৪, ৩ জানুয়ারি ২০২৪ (ইউটিসি) ::জ্বি, এখন ঠিক আছে। ধন্যবাদ। [[ব্যবহারকারী:খালিদ জে. হোসেইন|哈立德]] ০১:৩১, ৫ জানুয়ারি ২০২৪ (ইউটিসি) == <span lang="en" dir="ltr" class="mw-content-ltr">Reminder to vote now to select members of the first U4C</span> == <div lang="en" dir="ltr" class="mw-content-ltr"> <section begin="announcement-content" /> :''[[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – vote reminder|You can find this message translated into additional languages on Meta-wiki.]] [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-{{urlencode:Universal Code of Conduct/Coordinating Committee/Election/2024/Announcement – vote reminder}}&language=&action=page&filter= {{int:please-translate}}]'' Dear Wikimedian, You are receiving this message because you previously participated in the UCoC process. This is a reminder that the voting period for the Universal Code of Conduct Coordinating Committee (U4C) ends on May 9, 2024. Read the information on the [[m:Universal Code of Conduct/Coordinating Committee/Election/2024|voting page on Meta-wiki]] to learn more about voting and voter eligibility. The Universal Code of Conduct Coordinating Committee (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. Community members were invited to submit their applications for the U4C. For more information and the responsibilities of the U4C, please [[m:Universal Code of Conduct/Coordinating Committee/Charter|review the U4C Charter]]. Please share this message with members of your community so they can participate as well. On behalf of the UCoC project team,<section end="announcement-content" /> </div> [[m:User:RamzyM (WMF)|RamzyM (WMF)]] ২৩:১৬, ২ মে ২০২৪ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Universal_Code_of_Conduct/Coordinating_Committee/Election/2024/Previous_voters_list&oldid=26721206-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:RamzyM (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-09</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W09"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/09|Translations]] are available. '''Weekly highlight''' * [[mw:Special:MyLanguage/Edit check/Reference Check|Reference Check]] has been deployed to English Wikipedia, completing its rollout across all Wikipedias. The feature prompts newcomers to add a citation before publishing new content, helping reduce common citation-related reverts and improve verifiability. In A/B testing, the impact was substantial: newcomers shown Reference Check were approximately 2.2 times more likely to include a reference on desktop and about 17.5 times more likely on mobile web. [https://analytics.wikimedia.org/published/reports/editing/reference_check_ab_test_report_final_2025.html] '''Updates for editors''' * The [[mw:Special:MyLanguage/Extension:InterwikiSorting|InterwikiSorting extension]], which allowed for the [[m:Special:MyLanguage/Interwiki sorting order|sorting of interwiki links]], has been undeployed from Wikipedia. As a result, editors who had enabled interwiki link sorting in non-compact mode (full list format) will now see links reordered. The links moving forward will be listed in the alphabetical order of language code. [https://phabricator.wikimedia.org/T253764] * Later this week, people who are editing a page-section using the mobile visual editor, will notice a new "Edit full page" button. When tapped, you will be able to edit the entire article. This helps when the change you want to make is outside the section you initially opened. [https://phabricator.wikimedia.org/T387175][https://phabricator.wikimedia.org/T409112] * [[mw:Special:MyLanguage/Readers/Reader Experience|The Reader Experience team]] is inviting editors to assess whether dark mode should still be considered "beta" on their wiki, based on their experience of how well it functions on desktop and mobile. If the feature is deemed mature, editors can update the interface messages in <code dir=ltr>MediaWiki:skin-theme-description</code> and <code dir=ltr>MediaWiki:Vector-night-mode-beta-tag</code> to indicate that dark mode is ready and no longer considered beta. * The improved [[mw:Wikimedia_Apps/Team/iOS/Activity_Tab|Activity tab]] which displays user-insights is now available to all users of the Wikipedia iOS app (version 7.9.0 and later). Following earlier A/B testing that showed higher account creation among users with access to the feature, it has been rolled out to 100% of users along with some updates. The Activity tab now shows your edited articles in the timeline, offers editing impact insights like contribution counts and article view trends, and customization options to improve in-app experience for users. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:21}} community-submitted {{PLURAL:21|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, a bug that prevented [[mw:Special:MyLanguage/Extension:DiscussionTools|DiscussionTools]] from working on mobile has now been fixed, restoring full functionality. [https://phabricator.wikimedia.org/T415303] '''Updates for technical contributors''' * The [[m:Special:GlobalWatchlist|Global Watchlist]] lets you view your watchlists from multiple wikis on one page. The [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] that makes this possible continues to improve. The latest upgrade is the inclusion of a [[mw:Extension:GlobalWatchlist#hook|new hook]], <code dir=ltr>ext.globalwatchlist.rebuild</code>, which fires after each watchlist rebuild. This allows you to run gadgets and user scripts for the Special page. [https://phabricator.wikimedia.org/T275159] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.17|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/09|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W09"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৯:০৪, ২৩ ফেব্রুয়ারি ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30119102-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-10</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W10"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/10|Translations]] are available. '''Weekly highlight''' * Wikipedia 25 [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments|Birthday mode]] is now live on Betawi, Breton, Chinese, Czech, Dutch, English, French, Gorontalo, Indonesian, Italian, Luxembourgish, Madurese, Sicilian, Spanish, Thai, and Vietnamese Wikipedias! This limited-time campaign feature celebrates 25 years of Wikipedia with a birthday mascot, Baby Globe. When turned on, Baby Globe is shown on [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments/article configuration|~2,500 articles]], waiting to be discovered by readers. Communities can choose to turn Birthday mode on by getting consensus from their community and asking an admin to enable the feature and customize it via [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments#Community Configuration Demo|community configuration]] on the local wiki. '''Updates for editors''' * [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|Sub-referencing]], a new feature to re-use references with different details has been released to Swedish Wikipedia, Polish Wikipedia and [[:phab:T418209|a couple of other wikis]]. You can [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing#test|try the feature]] on these projects or on testwiki and [https://en.wikipedia.beta.wmcloud.org/wiki/Sub-referencing betawiki]. Learnings from the first pilot wiki German Wikipedia have been [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing/Learnings|published in a report]]. Reach out to the Wikimedia Deutschland team if you are [[:m:Talk:WMDE Technical Wishes/Sub-referencing#Pilot wikis|interested in becoming a pilot wiki]]. * [[mw:Special:MyLanguage/Help:Edit check#Paste check|Paste Check]] will become available at all Wikipedias this week. The feature prompts newcomers who are pasting text they are not likely to have written into VisualEditor to consider whether doing so risks a copyright violation. Paste Check [[mw:Special:MyLanguage/Edit check/Tags|tags]] all edits where it is shown for potential review. Local administrators can configure various aspects of the feature via [[{{#special:EditChecks}}]]. [[mw:Special:MyLanguage/Edit check/Paste Check#A/B Experiment|Research]] across 22 wikis found that Paste Check resulted in an 18% decrease in relative reverted-edits compared to the control group. Translators can [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-visualeditor-ve-mw-editcheck&filter=&optional=1&action=translate help to localize] this and related features. * The [[mw:Special:MyLanguage/Readers/Reader Experience|Reader Experience team]] will be standardizing the user menu in the top right for all mobile users so that it is closer to the desktop experience. Currently this user menu is only visible to users with Advanced Mobile Controls (AMC) turned on. The only change is that a couple buttons previously in the left-side menu will move to the top right for users who do not have AMC turned on. This change is expected to go out March 9 and seeks to improve the user interface. [https://phabricator.wikimedia.org/T413912] * Starting in the week of March 2, the emails sent out when an email address was added, removed, or changed for an account will switch to a substantially nicer and clearer HTML email from the prior plaintext one. [https://phabricator.wikimedia.org/T410807] * Notifications are currently limited to 2,000 historic entries per user, and extend back to 2013 when the feature was released. This is going to be changed to only store Notifications from the last 5 years, but up to 10,000 of them. This will help with long-term infrastructure health and help to prevent more recent notifications from disappearing too soon. [https://phabricator.wikimedia.org/T383948] * The [[m:Special:GlobalWatchlist|Global Watchlist]] which lets you view your watchlists from multiple wikis on a single page continues to see improvements. The latest update improves label usage experience. The [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] now allows activating the [[mw:Special:MyLanguage/Manual:Language#Fallback languages|language fallback system]] for Wikidata items without labels in the viewed language, and showing those labels in the user’s preferred Wikidata language if no <code dir=ltr>uselang=</code> URL parameter is provided. [https://phabricator.wikimedia.org/T373686][https://phabricator.wikimedia.org/T416111] * The Wikipedia Android team has started a beta test of [[mw:Special:MyLanguage/Readers/Information Retrieval/Phase 1|hybrid search]] on Greek Wikipedia. Hybrid search capabilities can handle both semantic and keyword queries enabling readers to find what they’re looking for directly on Wikipedia more easily. * For security reasons, members of certain user groups are [[m:Special:MyLanguage/Mandatory two-factor authentication for users with some extended rights|required to have two-factor authentication]] (2FA) enabled. Currently, 2FA is required to use the group, but not to be a member of it. Given that this model still has some vulnerabilities, the situation will [[phab:T418580|gradually change in March]]. Members of these groups will be unable to disable last 2FA method on their account, and it will be impossible to add users without 2FA to these groups. Users will still be able to add new authentication methods or remove them, as long as at least one method is continuously enabled. In the second half of March, users without 2FA will be removed from these groups. This applies to: CentralNotice administrators, checkusers, interface administrators, suppressors, Wikidata staff, Wikifunctions staff, WMF Office IT and WMF Trust & Safety. Nothing will change for other users. See the linked task for deployment schedule. [https://phabricator.wikimedia.org/T418580] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:27}} community-submitted {{PLURAL:27|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the issue preventing users from creating an instance in [https://www.wikibase.cloud/ Wikibase.cloud] has now been fixed. [https://phabricator.wikimedia.org/T416807] '''Updates for technical contributors''' * To help ensure [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]], over the next month the Wikimedia Foundation will implement global API rate limits across our APIs. In early March, stricter limits will be applied to unidentified requests from outside Toolforge/WMCS and API requests that are made from web browsers. In April, higher limits will be applied to identified traffic. These limits are intentionally set as high as possible to minimise impact on the community. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, see [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]]. * The Wikidata Query Service Linked Data Fragment (LDF) endpoint will be decommissioned in February. This endpoint served limited traffic, which was successfully migrated to other data access methods that were better suited to support existing use cases. The hardware used to support the LDF endpoint will be reallocated to support the ongoing backend migration efforts. [https://phabricator.wikimedia.org/T415696] * The new Parsoid parser [[mw:Special:MyLanguage/Parsoid/Parser Unification/Updates|continues to be deployed to additional wikis]], improving platform sustainability and making it easier to introduce new reading and editing features. Parsoid is now the default parser on 488 WMF wikis (268 Wikipedias), now covering more than 10% of all Wikipedia page views. * The process and criteria for [[Special:MyLanguage/Wikimedia Enterprise#Access|requesting exceptional access]] to the high volume feed of the ''Wikimedia Enterprise'' APIs (at no cost for mission-aligned usecases), [[m:Talk:Wikimedia Enterprise#Exceptional access criteria|have now been published]]. This is to provide more thorough and clearer documentation for users. * [https://techblog.wikimedia.org/ Tech Blog], the blog dedicated to the Wikimedia technical community [https://techblog.wikimedia.org/2026/02/24/a-tech-blog-diff/ will be migrating] to [[diffblog:|Diff]], the community news and event blog. The migration should be complete in April 2026, after which new posts will be accepted for publishing. Readers will be able to access posts – old and new – on the landing page at https://diff.wikimedia.org/techblog. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.18|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/10|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W10"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৭:৫২, ২ মার্চ ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30137798-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-11</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W11"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/11|Translations]] are available. '''Weekly highlight''' * [[m:Special:MyLanguage/Tech/Server switch|All wikis will be read-only]] for a few minutes on Wednesday, 25 March 2026 at [https://zonestamp.toolforge.org/1774450800 15:00 UTC]. This is for the datacenter server switchover backup tests, [[wikitech:Deployments/Yearly calendar|which happen twice a year]]. During the switchover, all Wikimedia website traffic is shifted from one primary data center to the backup data center to test availability and prevent service disruption even in emergencies. * Last week, all wikis had 2 hours of read-only time, and extended unavailability for user-scripts and gadgets. This was due to a security incident which has since been resolved. Work is ongoing to prevent re-occurrences. For current information please see the [[m:Steward's noticeboard#Statement on Meta about today's user script security incident|post on the Stewards' noticeboard]] ([[m:Special:MyLanguage/Wikimedia Foundation/Product and Technology/Product Safety and Integrity/March 2026 User Script Incident|translations]]). '''Updates for editors''' * Users facing multiple blocks on mobile will now see the reasons for each block separately, instead of a generic message. This helps them understand why they are blocked and what steps they can take to resolve the issue. For example, users affected for using common VPNs (such as [[Special:MyLanguage/Apple iCloud Private Relay|iCloud Private Relay]]) will receive clearer guidance on what they need to do to start editing again. [https://phabricator.wikimedia.org/T357118] * Later this week, [[mw:Special:MyLanguage/VisualEditor/Suggestion Mode|Suggestion Mode]] will become available as a beta feature within the visual editor at all Wikipedias. This feature proactively suggests various types of actions that people can consider taking to improve Wikipedia articles, and learn about related guidelines. The feature is locally configurable, and can also be locally expanded with custom Suggestions. Current settings can be seen at [[Special:EditChecks]] and there are [[mw:Special:MyLanguage/Help:Suggestion mode#For administrators %E2%80%93 local customization|instructions for how administrators can customize]] the links to point to local guidelines. The feature is connected to [[mw:Special:MyLanguage/Help:Edit check|Edit check]] which suggests improvements while someone is writing new content. In the future, the Editing team plans to evaluate the feature's impact with newcomers through a controlled experiment. [https://phabricator.wikimedia.org/T404600] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:23}} community-submitted {{PLURAL:23|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the issue where the cursor became misaligned during the use of CodeMirror’s syntax highlighting, which makes wikitext and code easier to read, has now been fixed. This problem specifically affected users who defined a font rule in a custom stylesheet while creating a new topic with DiscussionTools. [https://phabricator.wikimedia.org/T418793] '''Updates for technical contributors''' * API rate limiting update: To help ensure [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]], global API rate limits will be applied this week to requests without a compliant User-Agent that originate from outside Toolforge/WMCS and to unauthenticated requests made from web browsers. Higher limits will be applied to identified traffic in April. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, see [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]]. * The new GraphQL API has been released. The API was developed as a flexible alternative to select features of the Wikidata Query Service (WDQS), to improve developer experience and foster adaptability, and efficient data access. Try it out and [[d:Wikidata:Wikibase GraphQL#Feedback and development|give feedback]]. You can also [https://greatquestion.co/wikimediadeutschland/GraphQLAPI/apply sign up for usability tests]. * The [[m:Special:MyLanguage/Product and Technology Advisory Council/Unsupported Tools Working Group|PTAC Unsupported Tools Working Group]] continued improvements to [[commons:Special:MyLanguage/Commons:Video2commons#|Video2Commons]] in February, with fixes addressing authentication errors, large-file handling, task queue visibility, and clearer upload behavior. Work is still ongoing in some areas, including changes related to deprecated server-side uploads. Read [[m:Special:MyLanguage/Product and Technology Advisory Council/Unsupported Tools Working Group#February 2026|this update]] to learn more. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.19|MediaWiki]] '''In depth''' * The Article Guidance team invites experienced Wikipedia editors from selected [[mw:Special:MyLanguage/Article guidance/Pilot wikis and collaborators#Collaborators|pilot wikis]] and interested contributors from other Wikipedias to fill out this questionnaire which is available in [https://docs.google.com/forms/d/e/1FAIpQLSfmLeVWnxmsCbPoI_UF2jyRcn73WRGWCVPHzerXb4Cz97X_Ag/viewform English], [https://docs.google.com/forms/d/e/1FAIpQLSd6rzr4XXQw8r4024fE3geTPFe13M_6w7Mitj-YJi0sOlWTAw/viewform?usp=header Arabic], [https://docs.google.com/forms/d/e/1FAIpQLSdok3-RfB18lcugYTUMGkpwmqG_8p760Wv4dCXitOXOszjUDw/viewform?usp=header Bengali], [https://docs.google.com/forms/d/e/1FAIpQLSfjTfYp4jEo0akA4B1e-Nfg3QZPCudUjhJzHzzDi6AHyAaMGA/viewform?usp=header Japanese], [https://docs.google.com/forms/d/e/1FAIpQLScteVoI29Aue4xc72dekk-6RYtvmMgQxzMI900UOawrFrSTWg/viewform?usp=header Portuguese], [https://docs.google.com/forms/d/e/1FAIpQLSetdxnYwL3ub2vqA7awCg5hJZPMIYcDPaiTe12rY9h0GYnVlw/viewform?usp=header Persian], and [https://docs.google.com/forms/d/e/1FAIpQLScNvfJF-Ot-4pzA4qAN771_0QDJ4Li19YcUsaTgSKW8Nc7U_Q/viewform?usp=header Turkish]. Your answers will help the team customize guidance for less experienced editors and help them learn community policies and practices while creating an article. Learn more [[mw:Special:MyLanguage/Article guidance|on the project page]]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/11|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W11"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৮:৫৩, ৯ মার্চ ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30213008-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-12</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W12"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/12|Translations]] are available. '''Updates for editors''' * The [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature, also known as [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror 6]], has been used for wikitext syntax highlighting since November 2024. It will be promoted out of beta by May 2026 in order to bring improvements and new [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Features|features]] to all editors who use the standard syntax highlighter. If you have any questions or concerns about promoting the feature out of beta, [[mw:Special:MyLanguage/Help talk:Extension:CodeMirror|please share]]. [https://phabricator.wikimedia.org/T259059] * Some changes to local user groups are performed by stewards on Meta-Wiki and logged there only. Now, interwiki rights changes will be logged both on Meta-Wiki and the wiki of the target user to make it easier to access a full record of user's rights changes on a local wiki. Past log entries for such changes will be backfilled in the coming weeks. [https://phabricator.wikimedia.org/T6055] * On wikis using [[m:Special:MyLanguage/Flagged Revisions|Flagged Revisions]], the number of pending changes shown on [[{{#Special:PendingChanges}}]] previously counted pages which were no longer pending review, because they have been removed from the system without being reviewed, e.g. due to being deleted, moved to a different namespace, or due to wiki configuration changes. The count will be correct now. On some wikis the number shown will be much smaller than before. There should be no change to the list of pages itself. [https://phabricator.wikimedia.org/T413016] * Wikifunctions composition language has been rewritten, resulting in a new version of the language. This change aims to increase service stability by reducing the orchestrator's memory consumption. This rewrite also enables substantial latency reduction, code simplification, and better abstractions, which will open the door to later feature additions. Read more about [[f:Special:MyLanguage/Wikifunctions:Status updates/2026-03-11|the changes]]. * Users can now sort search results alphabetically by page title. The update gives an additional option to finding pages more easily and quickly. Previously, results could be sorted by Edit date, Creation date, or Relevance. To use the new option, open 'Advanced Search' on the search results page and select 'Alphabetically' under 'Sorting Order'. [https://phabricator.wikimedia.org/T403775] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:28}} community-submitted {{PLURAL:28|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the bug that prevented UploadWizard on Wikimedia Commons from importing files from Flickr has now been fixed. [https://phabricator.wikimedia.org/T419263] '''Updates for technical contributors''' * A new special page, [[{{#special:LintTemplateErrors}}]], has been created to list transcluded pages that are flagged as containing lint errors to help users discover them easily. The list is sorted by the number of transclusions with errors. For example: [[{{#special:LintTemplateErrors}}/night-mode-unaware-background-color]]. [https://phabricator.wikimedia.org/T170874] * Users of the [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature have been using [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] instead of [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] for syntax highlighting when editing JavaScript, CSS, JSON, Vue and Lua content pages, for some time now. Along with promoting CodeMirror 6 out of beta, the plan is to replace CodeEditor as the standard editor for these content models by May 2026. [[mw:Special:MyLanguage/Help talk:Extension:CodeMirror|Feedback or concerns are welcome]]. [https://phabricator.wikimedia.org/T419332] * The [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] JavaScript modules will soon be upgraded to CodeMirror 6. Leading up to the upgrade, loading the <code dir=ltr>ext.CodeMirror</code> or <code dir=ltr>ext.CodeMirror.lib</code> modules from gadgets and user scripts was deprecated in July 2025. The use of the <code dir=ltr>ext.CodeMirror.switch</code> hook was also deprecated in March 2025. Contributors can now make their scripts or gadgets compatible with CodeMirror 6. See the [[mw:Special:MyLanguage/Extension:CodeMirror#Gadgets and user scripts|migration guide]] for more information. [https://phabricator.wikimedia.org/T373720] * The MediaWiki Interfaces team is expanding coverage of REST API module definitions to include [[mw:Special:MyLanguage/API:REST API/Extensions|extension APIs]]. REST API modules are groups of related endpoints that can be independently managed and versioned. Modules now exist for [https://phabricator.wikimedia.org/T414470 GrowthExperiments] and [https://phabricator.wikimedia.org/T419053 Wikifunctions] APIs. As we migrate extension APIs to this structure, documentation will move out of the main MediaWiki OpenAPI spec and REST Sandbox view, and will instead be accessible via module-specific options in the dropdown on the [https://test.wikipedia.org/wiki/Special:RestSandbox REST Sandbox] (i.e., [[{{#Special:RestSandbox}}]], available on all wiki projects). * The [[mw:Special:MyLanguage/Extension:Scribunto|Scribunto]] extension provides different pieces of information about the wiki where the module is being used via the [[mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual|mw.site]] library. Starting last week, the library also provides a [[mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#mw.site.wikiId|way]] of accessing the [[mw:Special:MyLanguage/Manual:Wiki ID|wiki ID]] that can be used to facilitate cross-wiki module maintenance. [https://phabricator.wikimedia.org/T146616] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.20|MediaWiki]] '''In depth''' * The [[m:Special:MyLanguage/Coolest Tool Award|2026 Coolest Tool Award]] celebrating outstanding community tools, is now open for nominations! Nominate your favorite tool using the [https://wikimediafoundation.limesurvey.net/435684?lang=en nomination survey] form by 23 March 2026. For more information on privacy and data handling, please see the [[foundation:Special:MyLanguage/Legal:Coolest_Tool_Award_2026_Survey_Privacy_Statement|survey privacy statement]]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/12|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W12"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৯:৩৬, ১৬ মার্চ ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30260505-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-13</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W13"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/13|Translations]] are available. '''Weekly highlight''' * Wikimedia site users can now log in without a password using passkeys. This is a secure method supported by fingerprint, facial recognition, or PIN. With this change, all users who opt for passwordless login will find it easier, faster, and more secure to log in to their accounts using any device. The new passkey login option currently appears as an autofill suggestion in the username field. An additional [[phab:T417120|"Log in with passkey" button]] will soon be available for users who have already registered a passkey. This update will improve security and user experience. The [[c:File:Passwordless_login_screencast.webm|screen recording]] demonstrates the passwordless login process step by step. * [[m:Special:MyLanguage/Tech/Server switch|All wikis will be read-only]] for a few minutes on Wednesday, 25 March 2026 at [https://zonestamp.toolforge.org/1774450800 15:00 UTC]. This is for the datacenter server switchover backup tests, [[wikitech:Deployments/Yearly calendar|which happen twice a year]]. During the switchover, all Wikimedia website traffic is shifted from one primary data center to the backup data center to test availability and prevent service disruption even in emergencies. '''Updates for editors''' * Wikimedia site users can now export their notifications older than 5 years using a [[toolforge:echo-chamber|new Toolforge tool]]. This will ensure that users retain their important notifications and avoid them being lost based on the planned change to delete notifications older than 5 years, as previously announced. [https://phabricator.wikimedia.org/T383948] * Wikipedia editors in Indonesian, Thai, Turkish, and Simple English now have access to Special:PersonalDashboard. This is an [[mw:Special:MyLanguage/Moderator Tools/Dashboard|early version of an experience]] that introduces newer editors to patrolling workflows, making it easier for them to move from making edits to participating in more advanced moderation work on their project. [https://phabricator.wikimedia.org/T402647] * The [[Special:Block]] now has two minor interface changes. Administrators can now easily perform indefinite blocks through a dedicated radio button in the expiry section. Also, choosing an indefinite expiry provides a different set of common reasons to select from, which can be changed at: [[MediaWiki:Ipbreason-indef-dropdown]]. [https://phabricator.wikimedia.org/T401823] * Mobile editors [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#Logged-out|at several wikis]] can now see an improved logged-out edit warning, thanks to the recent updates from the Growth team. These changes released last week are part of ongoing efforts and tests to enhance [[mw:Special:MyLanguage/Contributors/Account Creation Experiments|account creation experience on mobile]] and then increase participation. [https://phabricator.wikimedia.org/T408484] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:36}} community-submitted {{PLURAL:36|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the bug that prevented mobile web users from seeing the block information when affected by multiple blocks has been fixed. They can now see messages of all the blocks currently affecting them when they access Wikipedia. '''Updates for technical contributors''' * Images built using Toolforge will soon get the upgraded buildpacks version, bringing support for newer language versions and other upstream improvements and fixes. If you use Toolforge Build Service, review the recent [https://lists.wikimedia.org/hyperkitty/list/cloud-announce@lists.wikimedia.org/thread/EMYTA32EV2V5SQ2JIEOD2CL66YFIZEKV/ cloud-announce email] and update your build configuration as necessary to ensure your tools are compatible. [https://wikitech.wikimedia.org/w/index.php?title=Help:Toolforge/Building_container_images&oldid=2392097#Buildpack_environment_upgrade_process][https://phabricator.wikimedia.org/T380127] * The [https://api.wikimedia.org/wiki/Main_Page API Portal] documentation wiki will shut down in June 2026. API keys created on the API Portal will continue to work normally. api.wikimedia.org endpoints will be deprecated gradually starting in July 2026. Documentation on the API Portal is moving to [[mw:Wikimedia APIs|mediawiki.org]]. Learn more on the [[wikitech:API Portal/Deprecation|project page]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.21|MediaWiki]] '''In depth''' * [[m:Special:MyLanguage/WMDE Technical Wishes|WMDE Technical Wishes]] is considering improvements to [[m:WMDE Technical Wishes/References/VisualEditor automatic reference names|automatically generated reference names in VisualEditor]]. Please check out the [[m:WMDE Technical Wishes/References/VisualEditor automatic reference names#Proposed solutions|proposed solutions]] and participate in the [[m:Talk:WMDE Technical Wishes/References/VisualEditor automatic reference names#Request for comment|request for comment]]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/13|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W13"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৬:৫১, ২৩ মার্চ ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30268305-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:UOzurumba (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-14</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W14"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/14|Translations]] are available. '''Weekly highlight''' * The Beta version of [[abstract:|Abstract Wikipedia]] a new Wikimedia project which is language-independent, was launched last week. The project allows communities to build Wikipedia articles in their native language, which can be readily accessed by other users in their own languages. The wiki is powered by instructions from Wikifunctions and also based on structured content from Wikidata. [[:f:Special:MyLanguage/Wikifunctions:Status updates/2026-03-26|Read more]]. '''Updates for editors''' * The Growth team is running an A/B test to evaluate a clearer, more user-friendly message that promotes account creation on wikis. Currently when logged-out mobile users begin editing, they see a jarring warning message that can feel abrupt and discouraging. This also presents temporary account editing as the default rather than encouraging account creation. The test is running on ten Wikipedias, including Arabic, French, Spanish and German. [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#2. Improve logged-out warning message (T415160)|Read more]]. * The Wikimedia Apps team is inviting feedback on [[mw:Special:MyLanguage/Wikimedia Apps/Team/Future of Editing on the Mobile Apps|how editing should work on the Wikipedia mobile apps]]. The discussion focuses on improving how users access editing tools when they tap "Edit". This is part of a broader effort to convert readers who develop an interest in editing, to access a more user-friendly pathway to start contributing. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:45}} community-submitted {{PLURAL:45|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where citation fetching from the large newspaper archive [https://www.newspapers.com Newspapers.com] was no longer working, due to a block in [[mw:Special:MyLanguage/Citoid|Citoid]] requests, has now been fixed. [https://phabricator.wikimedia.org/T419903] '''Updates for technical contributors''' * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.22|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/14|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W14"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৯:২৬, ৩০ মার্চ ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30329462-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-15</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W15"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/15|Translations]] are available. '''Updates for editors''' * The [[mw:Special:MyLanguage/Help:Extension:CampaignEvents|CampaignEvents extension]] now includes a new group goal-setting feature, enabling organizers to set and track event goals such as the number of articles created and participating contributors in real time. Similarly, participants can work toward shared targets and see their collective impact as the event unfolds. The feature is now available on all Wikimedia wikis. Learn more in [[mw:Special:MyLanguage/Help:Extension:CampaignEvents/Registration/Collaborative contributions#Goal setting|the documentation]]. * [[File:Maki-gift-15.svg|12px|link=|class=skin-invert|Wishlist item]] The new [[mw:Special:MyLanguage/Help:Watchlist labels|watchlist labels]] feature (announced in [[m:Special:MyLanguage/Tech/News/2026/07|Tech News 2026-07]]) is now available via VisualEditor, the source editor, and the 'watchstar' (or watch link, for skins that don't have a star icon). Previously it was only possible to assign labels via [[Special:EditWatchlist|EditWatchlist]]. In all three places it is a new field following the expiry field. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:23}} community-submitted {{PLURAL:23|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the issue where talk pages on mobile with Parsoid are unusable after empty section headers, has now been fixed. [https://phabricator.wikimedia.org/T419171] '''Updates for technical contributors''' * The [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|sub-referencing feature]], which lets editors add details to an existing reference without duplicating it, will be gradually rolled out to [[phab:T414094|more wikis]] later this year. Wikis using the [[mw:Special:MyLanguage/Reference Tooltips|Reference Tooltips]] gadget are encouraged to update their version (typically at [[m:MediaWiki:Gadget-ReferenceTooltips.js|MediaWiki:Gadget-ReferenceTooltips.js]] as shown [https://en.wikipedia.org/w/index.php?diff=1344408362 here]) to ensure compatibility. Other reference-related gadgets may also be affected. [https://phabricator.wikimedia.org/T416304] * All Wikinews editions will be closed and switched to read-only mode on 4 May 2026. Content will remain accessible, but no new edits or articles can be added. This closure was approved by the Board of Trustees of the Wikimedia Foundation following extended discussions. [[m:Wikimedia Foundation Board noticeboard#Board of Trustees Approves Closure of Wikinews|Read more]]. * The [[:mw:Special:MyLanguage/API:Action API|Action API]] has had several formats for requested output. One of them, <bdi lang="zxx" dir="ltr"><code><nowiki>format=php</nowiki></code></bdi>, is being removed soon. Please ensure your scripts or bots use the [[mw:Special:MyLanguage/API:Data formats#Output|JSON format]]. This removal should affect very few scripts and bots. [https://phabricator.wikimedia.org/T118538] * The [[Special:NamespaceInfo|Special:NamespaceInfo]] page now includes namespace aliases. For example "WP" for the "Project" ("Wikipedia") namespace on the German Wikipedia. [https://phabricator.wikimedia.org/T381455] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.23|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/15|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W15"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৬:১৯, ৬ এপ্রিল ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30362761-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-16</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W16"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/16|Translations]] are available. '''Weekly highlight''' * Experienced editors are invited to [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Main_Page test] the [[mw:Special:MyLanguage/Article guidance|Article guidance]] feature, designed to help less-experienced editors create well-structured, policy-compliant Wikipedia articles. Testing instructions are [[mw:Special:MyLanguage/Article guidance/Test feature guide|available]]. Also, after reviewing [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Category:Pages_using_article_guidance the outlines], please provide feedback on the [[mw:Talk:Article guidance|project talk page]]. Based on your input, the feature will be refined and transferred to the pilot Wikipedias to translate and adapt. Check out [[c:File:Article Guidance workflow demo - April 2026.webm|the video]] explaining the feature. '''Updates for editors''' * On most wikis, all autoconfirmed users can now use [[Special:ChangeContentModel|Special:ChangeContentModel]] page to [[mw:Special:MyLanguage/Help:ChangeContentModel|create new pages with custom content models]], such as mass message lists, making custom page formats more accessible. Check [[Special:ListGroupRights|Special:ListGroupRights]] for the status of your wiki. [https://phabricator.wikimedia.org/T248294] * The Growth team has launched an [[mw:Special:MyLanguage/Contributors/Account_Creation_Experiments|account creation experiment]] to evaluate whether adding an account creation button to the mobile web header increases new account registrations and encourages more mobile users to contribute to the wikis. The experiment is currently live on Hindi, Indonesian, Bengali, Thai, and Hebrew Wikipedia, and targets 10% of logged-out mobile web users. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:30}} community-submitted {{PLURAL:30|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where VisualEditor could get stuck loading on Windows devices with animations turned off, has now been fixed. [https://phabricator.wikimedia.org/T382856] '''Updates for technical contributors''' * Starting later this week, {{int:group-abusefilter}} who have the [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature enabled will have [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] instead of [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] as the editor at [[Special:AbuseFilter|Special:AbuseFilter]]. This is part of the broader effort to make the user experience more consistent across all editors. [https://phabricator.wikimedia.org/T399673][https://phabricator.wikimedia.org/T419332] * Tools and bots that access the [[mw:Special:MyLanguage/Notifications/API|Notifications API]] (<bdi lang="zxx" dir="ltr"><code><nowiki>action=query&meta=notifications</nowiki></code></bdi>) will need to update their OAuth or BotPassword grants to also include access to private notifications. [https://phabricator.wikimedia.org/T421991] * Due to a library upgrade, listings on category pages may be displayed out of order starting on Monday, 20th April. A migration script will be run to correct this, and will take hours to days depending on the size of the wiki (up to a week for English Wikipedia). [https://phabricator.wikimedia.org/T422544] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.24|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/16|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W16"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৫:১৯, ১৩ এপ্রিল ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30380527-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-17</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W17"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/17|Translations]] are available. '''Weekly highlight''' * After two years of development, [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]], also known as [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror 6]], is to be promoted out of beta on Tuesday, April 21. It brings better code and wikitext readability, reduction in typing errors, and other [[mw:Special:MyLanguage/Help:Extension:CodeMirror|benefits]] to all users of the standard syntax highlighter. A huge thank you to volunteer [https://phabricator.wikimedia.org/p/Bhsd/ Bhsd] who developed many of the new features, including [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Code folding|code folding]], [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Autocompletion|autocompletion]], and [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Linting|linting]]. [https://phabricator.wikimedia.org/T259059] * A major update to the Wikipedia app for iOS is now rolling out, redesigning the interface to align with Apple's latest "Liquid Glass" visual design. [https://apps.apple.com/us/app/wikipedia/id324715238 Download the latest version] and explore the update. '''Updates for editors''' * [[mw:Special:MyLanguage/Readers/Reader Experience/WE3.3.4 Reading lists|Reading lists]] is a feature which allows readers to save articles to a list for reading later. This feature is now in beta on Arabic, French, Indonesian, Vietnamese, and Chinese Wikipedias and by default for all new accounts on all Wikipedias. * An experiment which explores extending [[mw:Special:MyLanguage/Readers/Reader Growth/Mobile page previews|Page Previews to mobile web]] will be launched in the week of April 20 on Arabic, English, French, Italian, Polish, and Vietnamese Wikipedias. Page Previews are pop-ups that display a thumbnail, lead paragraph, and a link to open the full article of a blue link, thereby improving content discovery. The feature is already available on desktop and in the apps. [[m:Special:MyLanguage/List of experiments in Product and Technology#Template|Read more about this experiment and others]]. * On several wikis, logged-in editors who haven't [[mw:Special:MyLanguage/Help:Email confirmation|confirmed their email addresses]] can now see a banner encouraging them to do so. Having the email address confirmed allows a user to restore access to the account if they lose it. [[mw:Special:MyLanguage/Product Safety and Integrity/Account Security#Encouraging users to confirm their email addresses|Learn more]]. [https://phabricator.wikimedia.org/T421366] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:15}} community-submitted {{PLURAL:15|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where editing very large wiki pages in the 2017 wikitext editor caused slow loading, preview and scrolling lag, and performance issues when selecting, cutting, or pasting content, has now been fixed. [https://phabricator.wikimedia.org/T184857] '''Updates for technical contributors''' * As part of the promotion of [[mw:Special:MyLanguage/Help:Extension:CodeMirror|CodeMirror]] from a beta feature, all users will use [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] instead of [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] for syntax highlighting when editing JavaScript, CSS, JSON, Vue and Lua content pages. [https://phabricator.wikimedia.org/T419332] * The <code>mirrors.wikimedia.org</code> service for Debian and Ubuntu users will sunset and stop working on May 15. The resources for the service will be replaced with new and better options. Some users may need to switch to a different server which should take about a minute. [https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/LJYRIS4WB66HIRCAO4GIDTXCMDVZRBMA/ You can read more]. [https://phabricator.wikimedia.org/T416707] * The <bdi lang="zxx" dir="ltr"><code><nowiki>image</nowiki></code></bdi> and <bdi lang="zxx" dir="ltr"><code><nowiki>oldimage</nowiki></code></bdi> table will be removed from [[wikitech:Help:Wiki Replicas|wikireplicas]]. If your tools or queries access <bdi lang="zxx" dir="ltr"><code><nowiki>image</nowiki></code></bdi> or <bdi lang="zxx" dir="ltr"><code><nowiki>oldimage</nowiki></code></bdi> directly, please update them to use the <bdi lang="zxx" dir="ltr"><code><nowiki>file</nowiki></code></bdi> and <bdi lang="zxx" dir="ltr"><code><nowiki>filerevision</nowiki></code></bdi> table before 28 May. [https://phabricator.wikimedia.org/T28741] * Following the recent implementation of global API rate limits on unidentified traffic, the Wikimedia Foundation will continue efforts to ensure [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]] by applying global limits to identified API traffic beginning the last week of April. These limits are intentionally set as high as possible to minimise impact on the community. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, see [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]] and [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits/FAQ|Frequently Asked Questions]]. * The [[mw:Special:MyLanguage/Attribution API|Attribution API]] is now available as a [[mw:Special:MyLanguage/Wikimedia APIs/Stability policy|beta]]. The API fetches information for crediting Wikimedia articles and media files wherever they are used. Reference documentation is available through the REST Sandbox special page available on all Wikimedia wikis (such as the [https://en.wikipedia.org/w/index.php?api=attribution.v0-beta&title=Special%3ARestSandbox REST sandbox on English Wikipedia]). Share your feedback on the [[mw:Talk:Attribution API|project talk page]]. * There is no new MediaWiki version this week. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/17|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W17"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৫:০১, ২০ এপ্রিল ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30432763-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-18</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W18"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/18|Translations]] are available. '''Updates for editors''' * There is a change in how new users are autoconfirmed that will improve anti-vandalism protection. Currently, users who have had an account for a few days and made a few edits are automatically added to the [[{{int:grouppage-autoconfirmed/{{CONTENTLANGUAGE}}}}|{{int:group-autoconfirmed}}]] group. This configuration tends to be exploited by some vandals, who create accounts and start to use them only after some time. To mitigate this, the configuration will be updated next week so that – for the purpose of becoming autoconfirmed – the account age will be counted from their first edit, instead of registration date. The numeric value of the age threshold will remain the same. This change will be deployed only to wikis which require at least one edit as part of the autoconfirmation conditions. [https://phabricator.wikimedia.org/T418484] * All Wikipedia users with new accounts and those who activated the "automatically enable most beta features" option in their preference can now use the [[mw:Special:MyLanguage/Readers/Reader Experience/WE3.3.4 Reading lists|reading lists]] beta feature to save articles for later reading. This helps organize reading interests in one place for convenient access. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:30}} community-submitted {{PLURAL:30|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the issue where infobox images have huge padding in Firefox, has been fixed. [https://phabricator.wikimedia.org/T423676] '''Updates for technical contributors''' * As a reminder, the global API rate limits will be applied this week to identified API traffic. This is to help ensure [[mw:MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]]. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, including the actual rate limits, see [[mw:Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]] and [[mw:Wikimedia APIs/Rate limits/FAQ|Frequently Asked Questions]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.26|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/18|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W18"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৮:০৬, ২৭ এপ্রিল ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30458046-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:UOzurumba (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-19</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W19"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/19|Translations]] are available. '''Weekly highlight''' * The [[mw:Special:MyLanguage/Article guidance|Article guidance]] team invites experienced editors of [[mw:Special:MyLanguage/Article guidance/Pilot wikis and collaborators|pilot Wikipedias]]—Arabic, Bangla, Japanese, Portuguese, Persian, Turkish, Simple English, Spanish, and French—to help translate and adapt [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Category:Pages_using_article_guidance sample outlines]. These outlines will guide editors in creating clear, well-structured, and policy-compliant articles when using [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Special:NewArticle the feature] once it is launched in May 2026. [[mw:Special:MyLanguage/Article guidance#Adapting a sample outline in a Wikipedia|Simple instructions]] on how to translate and adapt the outlines are available. '''Updates for editors''' * The [[:m:Special:MyLanguage/Product and Technology Advisory Council|Product and Technology Advisory Council]] has published [[:m:Special:MyLanguage/Product and Technology Advisory Council/May 2026 draft PTAC recommendation for feedback|draft recommendations]] on a model that affiliates can follow when contributing to the technical space. Community members are invited to provide feedback on the recommendation until May 8th [[:m:Talk:Product and Technology Advisory Council/May 2026 draft PTAC recommendation for feedback|on the talk page]]. * The number of available thumbnail size preferences in MediaWiki is being reduced to three standardized options—Small (180px), Regular (250px), and Large (400px), as part of ongoing efforts to improve performance and reduce strain on thumbnail services. As a result, existing preferences will be mapped to the nearest new size (for example, smaller selections like 120px or 150px will render at 180px, while larger ones like 300px or 360px will render at 400px). The preferences interface will soon be updated to reflect these changes, and users who wish to opt out or provide feedback can do so. [https://phabricator.wikimedia.org/T424909] * From now on, even when a permission expires automatically, users will receive an Echo notification similar to the standard notification for permission changes. There is a difference between this and [[m:Special:MyLanguage/Global reminder bot|Global reminder bot]] in that the latter reminds users a week ''before'' the rights are due to expire, so that they can renew the rights. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:32}} community-submitted {{PLURAL:32|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the problem where the ULS language selector in [[m:Special:Translate|Special:Translate]] would scroll vertically when it shouldn't, has been resolved. Previously, when users opened the "Translate to English" dropdown and typed certain inputs, the dialog would scroll vertically by a few pixels even when there was enough space to display all results. The dropdown no longer shifts unnecessarily when filtering languages. [https://phabricator.wikimedia.org/T358864] * The [[m:Special:GlobalWatchlist|Global Watchlist]], which lets you view your watchlists from multiple wikis on a single page, continues to improve. For example, watchlists for Wikibase sites such as [[:d:|Wikidata]] now support [[mw:Special:MyLanguage/Extension:EntitySchema|EntitySchema]] elements for better tracking. The Live Updates mode now refreshes the special page every 60 seconds to comply with the updated [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|global API rate limits]] for improved real-time responsiveness. Additionally, a directionality bug that displayed links as "changes 3" instead of "3 changes" in mixed-direction lists has been fixed. [https://phabricator.wikimedia.org/T415450][https://phabricator.wikimedia.org/T424422][https://phabricator.wikimedia.org/T418091] '''Updates for technical contributors''' * The second phase of [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|global API rate limits]] has been rolled out to reduce the [[diffblog:2026/03/26/quo-vadis-crawlers-progress-and-whats-next-on-safeguarding-our-infrastructure/|impact of AI crawlers]] and ensure fair, sustainable access to Wikimedia resources, prioritising human and mission-aligned traffic. [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits#Limits|Limits]] have been shifted from per-hour to per-minute, producing smoother traffic patterns and more predictable API load. Community users are not expected to be affected, and no action is required. Early indications show some User-Agent-based requestors are adjusting behaviour, and around 64% of automated API traffic has been identified. Monitoring continues, and Wikimedia Enterprise remains available for commercial support. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.27|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/19|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W19"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ২০:৪৩, ৪ মে ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30498077-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-20</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W20"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/20|Translations]] are available. '''Weekly highlight''' * Community Tech has published [[m:Special:MyLanguage/Community Wishlist/How to write a good wish|new guidance]] explaining how wishes on Community Wishlist are triaged and prioritized. The documentation is intended to help contributors write stronger proposals by clarifying the factors that influence prioritization decisions. Beyond vote counts, the guidance highlights considerations such as potential impact on the community when determining which wishes move forward. '''Updates for editors''' * The Reader Growth team is launching an experiment to test a new [[mw:Special:MyLanguage/Readers/Reader_Growth/Share_Card|Share Card feature]] that allows readers to create visually engaging cards from Wikipedia articles or selected article sections and share them online, with each card linking back to the original article to help expand readership and article discovery. The mobile-only A/B test will be available to a portion of readers on Arabic, Chinese, French, Vietnamese, and English Wikipedia to better understand reading and sharing habits, and is scheduled to begin the week of May 18 and run for four weeks. * The Android and iOS Wikipedia apps recently released the [[mw:Special:MyLanguage/Wikimedia_Apps/Team/25th_Birthday_Reading_Challenge|25-day reading challenge]] into Beta, as part of efforts to drive reader engagement by encouraging users to complete reading milestones. To track their reading streak during the challenge, App users can add a widget featuring Baby Globe to their home screen. The challenge officially begins May 11. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:17}} community-submitted {{PLURAL:17|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where the global preference for enabling syntax highlighting in wikitext could unexpectedly disable itself after being turned on, has now been fixed. [https://phabricator.wikimedia.org/T425286] '''Updates for technical contributors''' * [[File:Octicons-tools.svg|12px|link=|alt=|Advanced item]] The ResourceLoader module <bdi lang="zxx" dir="ltr"><code><nowiki>mediawiki.ui.input</nowiki></code></bdi>, deprecated since [[m:Special:MyLanguage/Tech/News/2023/39|September 2023]], will be removed this week. There is a [[mw:Special:MyLanguage/Codex/Migrating_from_MediaWiki_UI|guide for migrating from MediaWiki UI to Codex]] for any tools that use it. [https://phabricator.wikimedia.org/T420125] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.2|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/20|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W20"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৯:২০, ১১ মে ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30524429-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-21</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W21"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/21|Translations]] are available. '''Weekly highlight''' * The Abstract Wikipedia team has identified five potential pilot wikis to assess their interest in adopting abstract articles on their wikis. The pilots are Malayalam, Bengali, Dagbani, Arabic, and Indonesian Wikipedia. The feedback period will be open until May 22. If your community is interested in becoming a pilot, [[m:Talk:Abstract Wikipedia|let us know on Meta]]. '''Updates for editors''' * An experiment to show [[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists|Reading Lists]] to logged-out readers on mobile web will launch on May 18 across German, Spanish, Italian, Portuguese, Polish, Dutch, Turkish, and Urdu Wikipedias, and will run for one month. The effort supports broader goals of helping readers save and organize articles for later reading, while encouraging habits that could lead to future Wikipedia contributions. * To support a bookmark button in the Reading List beta feature, the "Tools > Action" menu has been updated to display icons, including the watch star indicator that helps editors identify temporarily watched articles. The icons now also match those used on mobile, improving consistency across platforms. The change is currently limited to the actions menu and mainly affects editors with privileged user rights. [https://phabricator.wikimedia.org/T426008] * [[mw:Special:MyLanguage/VisualEditor/Suggestion Mode|Suggestion Mode]] was released as an [[w:en:A/B test|A/B test]] for newcomer editors on the mobile website at [[phab:T421189|~15 Wikipedias]]. The experiment will measure the impact that Suggestion Mode has on the proportion of newcomer mobile web edit sessions that result in constructive (un-reverted) article edits. The experiment will also evaluate the feature's impact on editor retention, and monitor changes in revert and block rates. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:27}} community-submitted {{PLURAL:27|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue in the Wikipedia Android app where images could sometimes fail to load after opening a recommended reading list notification, has now been fixed. [https://phabricator.wikimedia.org/T418231] '''Updates for technical contributors''' * The [[mw:Special:MyLanguage/Wikidata Platform|Wikidata Platform team]] has published its [[d:Special:MyLanguage/Wikidata:SPARQL query service/WDQS backend update/Backend Replacement|backend replacement recommendation]] and accompanying [[wikitech:Wikidata Query Service/WDQS Architecture re-design|technical architecture]] for the migration of the Wikidata Query Service (WDQS) away from Blazegraph. Feedback is invited until May 25th 2026, especially on potential gaps and impacts on advanced use cases. Wikidata community members and WDQS users are also encouraged to help identify high-impact tools and workflows that may need attention on [[d:Wikidata:SPARQL query service/WDQS backend update/High-Impact Use Cases|this page]]. Feedback can be shared on the [[d:Wikidata talk:SPARQL query service/WDQS backend update|Migration talk page]] or during the [[d:Special:MyLanguage/Wikidata:Blazegraph Migration Office Hours|next office hour]]. See the [[d:Special:MyLanguage/Wikidata:Wikidata Platform team/Newsletter|WDP team newsletter]] for more details. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.3|MediaWiki]] '''In depth''' * On English, French, Japanese, and a few other Wikipedias, there was a [[diffblog:2025/09/02/better-detecting-bots-and-replacing-our-captcha/|trial of hCaptcha]], a third-party bot detection service. The trial showed that hCaptcha effectively detects and deters some bad-faith automated activity, on its own and by giving [[w:en:Wikipedia:Village pump (technical)/Archive 225#Introducing SuggestedInvestigations|checkusers and stewards]] signals to look into. Because the results were positive, hCaptcha will be rolled out across all wikis over the next few weeks. [[mw:Special:MyLanguage/Product Safety and Integrity/Anti-abuse signals/hCaptcha|See the hCaptcha project page]] for technical information about the implementation and privacy protections. [[diffblog:2026/05/04/better-detecting-bots-and-replacing-our-captcha-part-2/|Learn more]]. * The latest Community Tech update is now available, with progress across several Community Wishlist initiatives, including Reading Lists expansion from the mobile app to the website, new language support for "Who Wrote That" and the Personal Dashboard, improvements to 3D rendering and Charts, and upcoming work on talk page sorting, audio playback, and editing workflows. The update also shares current priorities, wishlist status trends, and opportunities for community feedback on future focus areas and the Wikimedia Foundation’s 2026–2027 Annual Plan. [[m:Special:MyLanguage/Community Wishlist/Updates#May 13, 2026: Latest updates from the Community Tech team|Read the full newsletter for details]]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/21|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W21"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ২০:২২, ১৮ মে ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30539262-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-22</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W22"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/22|Translations]] are available. '''Weekly highlight''' * Following a [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#LOWM|successful account creation experiment]], an improved logged-out edit warning message will be deployed to all Wikimedia wikis in the first week of June. The change will only affect logged-out users on mobile web who open an editing session. The updated experience is designed to encourage account creation more clearly, while still allowing users to edit with temporary accounts. Results from the experiment showed a significant increase in account creation, with a 27% relative lift among users shown the updated message. As expected, as more people funnel into account creation, temporary accounts decreased by a relative 16%. The experiment did not show any significant changes in constructive edit rates or other monitored contributor metrics. [https://phabricator.wikimedia.org/T424595] '''Updates for editors''' * For security reasons, members of certain user groups are [[m:Special:MyLanguage/Mandatory two-factor authentication for users with some extended rights|required to have two-factor authentication]] (2FA) enabled. Members of these groups will be unable to disable the last 2FA method on their account, and it will be impossible to add users without 2FA to these groups. Users will still be able to add new authentication methods or remove them, as long as at least one method is continuously enabled. In the next few weeks, users without 2FA will be removed from these groups. Notably, this applies to bureaucrats. See the linked tasks for deployment schedules. [https://phabricator.wikimedia.org/T423119][https://phabricator.wikimedia.org/T423120] * [[m:Special:MyLanguage/WMDE Technical Wishes|WMDE Technical Wishes]] will run an [[w:en:A/B testing|A/B test]] on [[:phab:T415904|10 wikis]], testing [[m:WMDE Technical Wishes/References/Reference Previews|potential improvements for Reference Previews]]. The experiment will run for ~2 weeks at the end of May / beginning of June and will affect 10% of desktop readers on the participating wikis. * After two successful experiments, the Reader Growth team is rolling out an [[mw:Special:MyLanguage/Readers/Reader Growth/Image Browsing|Image Browsing]] beta feature for all Wikipedias on mobile on May 25. This means that anyone who has all beta features on by default will start to see this feature, and others can check the box to turn it on in their preferences. The beta feature will include a carousel of all an article's images at the top of the article, with controls for editors to [[mw:Readers/Reader_Growth/Image_Browsing#Phase_2.1_beta_feature|exclude images from the article's carousel or to exclude an article from the feature entirely]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:30}} community-submitted {{PLURAL:30|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, three dimensional STL files were being rendered incorrectly by the media viewer 3D extension which is now fixed. [https://phabricator.wikimedia.org/T416723] '''Updates for technical contributors''' * The legacy CSS classes <bdi lang="zxx" dir="ltr"><code><nowiki>tleft</nowiki></code></bdi> and <bdi lang="zxx" dir="ltr"><code><nowiki>tright</nowiki></code></bdi> have been replaced with <bdi lang="zxx" dir="ltr"><code><nowiki>floatleft</nowiki></code></bdi> and <bdi lang="zxx" dir="ltr"><code><nowiki>floatright</nowiki></code></bdi> as the former do not work consistently across all MediaWiki platforms, notably mobile web and mobile apps. Projects relying on these classes are encouraged to review related usage and plan for migration. Please note that <bdi lang="zxx" dir="ltr"><code><nowiki>floatleft</nowiki></code></bdi> and <bdi lang="zxx" dir="ltr"><code><nowiki>floatright</nowiki></code></bdi> may also be deprecated in future, although there are currently no plans to do so. [[phab:T426452|Read more]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.4|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/22|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W22"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ২১:৫২, ২৫ মে ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30584502-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Quiddity (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-23</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W23"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/23|Translations]] are available. '''Updates for editors''' * The [[mw:Special:MyLanguage/Readers/Reader Experience|Reader Experience team]] is conducting an experiment to show the [[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists|reading lists]] feature, which is still in development, to logged-out mobile readers to test whether it encourages account creation at a higher rate compared to the watchstar button. The [[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists#Experiment timeline|experiment]] was launched on May 18th on German, Spanish, Italian, Portuguese, Polish, Dutch, Turkish, and Urdu wikis, and it will run for a month. * The Wikimedia Apps team released [[mw:Special:MyLanguage/Wikimedia Apps/Team/Explore Feed Refresh/Phase 1|Phase 1]] of the redesigned Home Feed to the Android Beta app. The new Home Feed includes a refreshed "Community" tab and a personalized "For You" tab featuring daily updated reading recommendations. The redesign is part of a broader effort to improve content discovery and create more engaging learning experiences in the Wikipedia apps. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:18}} community-submitted {{PLURAL:18|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where images could fail to load for some suggested edits on [[w:Special:Homepage|Special:Homepage]], leaving the thumbnail stuck in a loading state, has now been fixed. [https://phabricator.wikimedia.org/T424048] '''Updates for technical contributors''' * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.5|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/23|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W23"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ২১:০৯, ১ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30613639-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr"> Wikidata Platform Newsletter - June 2026</span> == <div lang="en" dir="ltr"> <section begin="message"/> This is the 7th issue of our [[D:Wikidata:Wikidata_Platform_team/Newsletter|monthly newsletter]]! The next issue will be published in July 2026. * '''QLever as the New Backend System for WDQS:''' After reviewing feedback from the community on our architectural proposals shared last month (see [[D:Wikidata:SPARQL_query_service/WDQS_backend_update/Backend_Replacement|Backend Replacement]] and [[wikitech:Wikidata_Query_Service/WDQS_Architecture_re-design|WDQS Architecture Re-Design]]), we have decided to migrate to '''QLever''' as the new backend for the Wikidata Query Service. This decision has been aligned upon across partners in WMF, WMDE, and the QLever team. We are very excited about the improvements to performance and sustainability that this choice unlocks for WDQS users. We will continue to share details on the user-facing impacts of this decision, in future [[D:Wikidata:Wikidata_Platform_team/Newsletter|newsletters]] and on our [[D:Wikidata:SPARQL_query_service/WDQS_backend_update|migration project page]], as the work progresses. : We encourage all members of the community to continue helping us identify higher-risk areas by reporting use cases on our [[D:Wikidata:SPARQL_query_service/WDQS_backend_update/High-Impact_Use_Cases|high-impact use cases and tools page]]. This page is not intended to catalogue all WDQS usage, but to highlight complex or critical cases that may require additional attention. * '''Migration Timeline:''' Following the decision to use QLever, we would like to share some key milestones for our migration. More details will be shared as we approach full implementation. Please note that all dates are targets and may change in the event of unforeseen challenges. Refer to the [[D:Wikidata:SPARQL_query_service/WDQS_backend_update|migration project page]] for up to date information. *# '''Exploration:''' ('''COMPLETED''') From September through March, the team conducted traffic and benchmarking analyses to understand the needs of WDQS users and alternatives to our current system. This culminated in our final recommendations for a new backend and platform architecture, which have been reviewed and aligned upon across stakeholders. *# '''Installation:''' ('''IN-PROGRESS''') In April, the team began building. The development of new QLever endpoints (ie. WDQS v2) is underway, as is the refactoring of our platform architecture. This includes work on indexing, update pipelines, and rewriting observed production traffic into the SPARQL 1.1 standard. We are on track to complete our build of the new endpoints by '''July 1st''' and transition into initial implementation. The query service will continue to be available in its current state through implementation phases. *# '''Initial Implementation:''' ('''NOT STARTED''') WDQS v2, a new endpoint built on QLever, will be first available to a small number of pilot users. The team will work closely with this group to learn where improvements are needed and how we can best support users in independently migrating their use cases. A self-service hub will be published by '''October 1st'''. This will include learnings from our pilot group, guidance on how all users of WDQS can migrate their work flows, and documentation on best practices for adapting all Blazegraph dependencies to our new system or alternative endpoints where needed. *# '''Full Implementation:''' ('''NOT STARTED''') The new endpoints will be scaled to meet the needs of the broader community and will be generally accessible to all. The original Blazegraph endpoints will still be available, but may experience service degradation beginning in '''February, 2027''' as we reallocate resources to the new infrastructure and begin slowly winding down the legacy service. We aim to have all WDQS traffic migrated by '''June 30, 2027''', at which time the Blazegraph endpoint will be decommissioned. * '''Query Categorization and Testing:''' We have begun evaluating WDQS queries to identify Blazegraph-specific features and functionality. All bespoke query aspects need to be rewritten into the SPARQL 1.1 standard in order to work with the new QLever backend. We have documented our process for this work in two Wikitech publications on [[wikitech:SPARQL_Query_Characterization|SPARQL Query Characterization]] and [[Wikitech:Test_Architecture_for_QLever|Test Architecture for QLever]]. These documents provide more detail on methodology and testing used to validate the correctness and performance across the new and old backends. They are intended as supporting technical references for contributors interested in the migration validation and benchmarking approach. * '''2026-05-08 incident report:''' On May 7, 2026, aggressive web scrapers began overwhelming the Wikidata Query Service (WDQS), triggering a multi-day service degradation that impacted both availability and lag SLOs. The excessive load caused Blazegraph to timeout for over half of users at peak, while also throttling the streaming updater, which blocked index updates and cascaded into edit throttling on wikidata.org itself. Initial mitigation on May 7-8 included depooling the eqiad datacenter WDQS deployment and applying rate limits based on sampled request data, but the outage persisted through the weekend. Full resolution came on Monday, May 11, when deeper analysis of WDQS logs revealed a scraper that had evaded sampled webrequest data used for initial rate limiting. Once a targeted rate limiting rule was applied to the scraper's signatures, timeout rates returned to normal. ''[[wikitech:Incidents/2026-05-13_wdqs|See the full incident report]]'' * '''[[D:Event:Blazegraph_Migration_Office_Hours_-_June_2026|Blazegraph Migration Office Hour (June session)]]:''' Our next Blazegraph Migration Office Hour will take place on Tuesday, 9 June 2026 (Tomorrow) at {{zonestamp|2026-05-12 16:00|16:00 UTC}}. This session is focused on supporting the migration away from Blazegraph as the backend of WDQS. Whether you have questions, need clarification, or want to discuss how your use case may be affected. You can register for the session via [[D:Event:Blazegraph_Migration_Office_Hours_-_May_2026|the event page]]. : In preparation, we encourage you to add questions, feedback, or migration-related support needs to [https://etherpad.wikimedia.org/p/Blazegraph_Migration_Office_Hours this etherpad]. This helps us shape the agenda and focus on the most relevant topics during the session. <section end="message"/> </div> <bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|আলোচনা]]) ১১:১০, ৮ জুন ২০২৬ (ইউটিসি)</bdi> <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/WDP_team_updates&oldid=30635883-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Udehb-WMF@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-24</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W24"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/24|Translations]] are available. '''Weekly highlight''' * Wikimedia Enterprise has increased the free usage limits for its API offerings. The monthly request limit for the On-demand API has increased from 5,000 to 50,000 requests, while the Snapshot API limit has increased from 15 to 30 requests per month. In addition, Structured Contents snapshots are now available for free accounts. These changes expand access to Wikimedia Enterprise data for developers, researchers, and organizations using Wikimedia content. [https://enterprise.wikimedia.com/blog/enhanced-free-api] '''Updates for editors''' * The [[mw:Special:MyLanguage/Wikimedia_Apps/Team/Explore Feed Refresh/Phase 1|refreshed Explore Feed]], now called the Home Feed, is rolling out to 50% of users of the Wikipedia Android app. The Home Feed helps readers discover relevant content through two new tabs: ''Community'' and ''For You''. The Community tab provides a scrollable feed of curated content and updates from the broader Wikimedia community and movement, while the ''For You'' tab offers a full-screen, swipeable experience that shows content tailored to a user's interests. The redesign is part of a broader effort to improve discovery and enhance the learning experience in the Wikipedia app. * The [[mw:Special:MyLanguage/Wikimedia Apps/Team/iOS/"Which came first?" Game|Which came first?]] daily trivia game is now available in the beta version of the Wikipedia iOS app in English, German, French, Portuguese, Russian, Spanish, Arabic, Chinese, and Turkish. The game uses historical events from Wikipedia's "On This Day" content and challenges readers to guess which of two events happened first. The game was previously released on Android. Communities interested in making the game available in their languages can [[mw:Special:MyLanguage/Wikimedia_Apps/Team/Games#Game availability by language|read the instructions and requirements]]. * [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|Sub-referencing]], a new MediaWiki feature that allows editors to reuse references with different details, will begin rolling out to Wikimedia wikis following a successful pilot phase. Deployment will start on 8 June for most [[wikitech:Deployments/Train#Wednesday|Group 1 wikis]] and French Wikipedia, with additional Wikipedia language editions receiving the feature over the coming months. Communities are encouraged to prepare by checking for [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-cite&language=en&action_source=search&filter=%21translated&optional=1&action=translate untranslated Cite extension messages] in their language and reviewing any use of [[mw:Special:MyLanguage/Reference Tooltips|Reference Tooltips]], which may require [[:phab:T416304#11668731|updates]] to support the new functionality. Wikis using [[mw:Special:MyLanguage/Help:Reference Previews|Reference Previews]] do not need to take any action. Communities may also wish to create the ''cite-tracking-category-ref-details'' [[Special:TrackingCategories|tracking category]] as a hidden category using <code><nowiki>__HIDDENCAT__</nowiki></code> (or a dedicated template), and connect it to the corresponding Wikidata item [[d:Q129764848]]. [https://phabricator.wikimedia.org/T425662] * The [[mw:Special:MyLanguage/Readers/Reader Growth/Mobile page previews#Experimentation|Page Previews experiment]] on mobile web has concluded. The team decided not to roll out the feature after the results showed no statistically significant impact on reader retention, as the primary success metric was retention improvement. Page Previews, which are already available on desktop and in the apps, display a thumbnail, lead paragraph, and link to the full article when readers tap a blue link. The experiment tested this experience on mobile web across six Wikipedias. * The [[mw:Special:MyLanguage/Codex/Design/Icons|user interface icon library]] will be [[phab:T399175|updated later this week or next week]]. Most of the ~300 icons have been slightly refined and ~30 new icons have been added. These changes improve the icons to make them more consistent and comprehensible, and provide more visual balance when they are used in groups. * The [[mw:Special:MyLanguage/Universal Language Selector|Universal Language Selector]] (ULS) interface in MediaWiki, which helps users select content in other languages, has been updated. The new version improves speed and accessibility, and users of Wikimedia projects can now pin languages for quicker language switching. The deployment to Wikimedia sites will happen gradually in the coming weeks. You can test it now as a beta feature by selecting [[Special:Preferences#mw-prefsection-betafeatures|beta features]] in your profile preferences and share your feedback on [[mw:Special:MyLanguage/Universal Language Selector/New ULS|the project page]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:21}} community-submitted {{PLURAL:21|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where the Pageviews Analysis dashboard on pageviews.wmcloud.org stopped updating graph data in May 2026, affecting all users, has been fixed. [https://phabricator.wikimedia.org/T427171] '''Updates for technical contributors''' * The function signature for <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink()</nowiki></code></bdi> has been simplified. Developers can now pass a configuration object instead of a list of positional parameters when creating portlet links. The previous function signature remains supported for backwards compatibility. For example, instead of: <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink('p-cactions', '#', 'Stub', 'ca-stubtag', 'Add a stub tag to this page');</nowiki></code></bdi> use <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink('p-cactions', { href: '#', text: 'Stub', id: 'ca-stubtag', tooltip: 'Add a stub tag to this page' });</nowiki></code></bdi>. Script maintainers are encouraged to review existing uses of <bdi lang="zxx" dir="ltr"><code><nowiki>addPortletLink()</nowiki></code></bdi> and update them where appropriate. This change will be available on all wikis from 11 June. Thanks to community volunteer Gerges for contributing this improvement. [https://phabricator.wikimedia.org/T427945] * '''Community Wishlist discussion''': Product & Technology [[m:Special:MyLanguage/Community Wishlist/Updates#May 20, 2026: Community Tech becomes a program|introduced changes]] meant to increase the number and complexity of wishes fulfilled, including the disbanding of the Community Tech team. They are [[m:Special:MyLanguage/Community Wishlist/Updates|engaging in discussions]] about a [[m:Talk:Community Wishlist#Proposed direction for Wishlist|proposed direction for the wishlist]] from community members. Includes ways to structure annual voting, better tracking of wishes, removing focus areas, and [[m:Special:MyLanguage/Community Wishlist/Updates|staffing updates]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.6|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/24|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W24"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ২১:৩০, ৮ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30650573-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-25</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W25"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/25|Translations]] are available. '''Weekly highlight''' * The [[mw:Special:MyLanguage/Readers/Reader Growth|Reader Growth team]] has launched an [[mw:Special:MyLanguage/Readers/Reader Growth/Image Browsing|Image Browsing]] beta feature on the mobile web version of all Wikipedias. The feature shows an image carousel at the top of articles with 3 or more images. Editors can configure this feature with the following controls: to hide a specific image from a page, either use <code>class=notpageimage</code> excluding it from thumbnail previews, or <code>class=noviewer</code> excluding it from MediaViewer. The carousel can also be disabled from a page entirely, with the magic word <code><nowiki>__NOMEDIAVIEWERCAROUSEL__</nowiki></code>. To submit feedback or flag bugs, please visit the [[mw:Talk:Readers/Reader Growth/Image Browsing|project page]]. * [[mw:Special:MyLanguage/Help:Tables#class="wikitable"|Wikitables]] can now be [[mw:Special:MyLanguage/Help:Sortable tables#Forcing the initial sort direction|sorted in descending order]] on the first click by adding <code dir=ltr>data-sort-order="desc"</code> to the header cell. Previously, by default, clicking a column header for the first time sorts it in ascending order. This addition to a Wikitable gives it more control and flexibility, while the default behavior for subsequent clicks remains unchanged. [https://phabricator.wikimedia.org/T398416] '''Updates for editors''' * The [[mw:Special:MyLanguage/Article guidance|Article guidance]] feature is currently being tested with some editors creating new articles on the Simple English, French, and Turkish Wikipedias. The experiment will soon begin on the Arabic and Bangla Wikipedias as well. [[w:simple:Special:NewArticle|This feature]] gives editors community-curated guidance to help them create articles that follow community standards. Experienced editors can continue creating or adapting outlines for specific article types that are commonly created by less experienced contributors. The outlines guide less experienced editors in creating high-quality articles. A quick guide to markups used in outlines can be found on [[mw:Special:MyLanguage/Article guidance/Test feature guide#Markups in outlines|this page]]. [[w:simple:Wikipedia:Article Guidance|Example outlines]] that can be adapted and instructions for how to adapt them are on [[mw:Special:MyLanguage/Article guidance#Adapting a sample outline in a Wikipedia|this section]] of the project page. * Wikis that wish to replace the "indefinitely" button in Special:Block for temporary accounts (for example, wikis that block temporary users only until account expiration) will be able to do so by creating [[MediaWiki:ipb-indefinite-expiry-temporary-account]] with the block duration they want. [https://phabricator.wikimedia.org/T427125] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:41}} community-submitted {{PLURAL:41|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. '''Updates for technical contributors''' * By the end of June, a valid user-agent string will be required for automated dumps downloads from the dumps.wikimedia.org website. Automated requests that provide a generic or empty user-agent will be blocked. This [[phab:T400119|extends enforcement]] of the long standing [[foundation:Special:MyLanguage/Policy:Wikimedia Foundation User-Agent Policy|user-agent policy]]. Access to dumps through Wikimedia Cloud Services will not change. * The roll out of global [[mw:Wikimedia APIs/Rate limits|API rate limits]] is now complete, with limits enforced across all APIs and at the documented levels for all groups. Bots running in Toolforge/WMCS or with the bot user right on any wiki remain exempt. All bots should continue to follow the documented best practices to avoid being rate limited. * The [https://api.wikimedia.org/wiki/Main_Page API Portal wiki] will be read only starting this week (June 15-18). The following week (June 22-25), all API Portal wiki URLs will redirect to [[mw:Wikimedia APIs|Wikimedia APIs on mediawiki.org]]. Learn more on the [[wikitech:API Portal/Deprecation|project page]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.7|MediaWiki]] '''Meetings and events''' * On June 17th at 6pm UTC the WMF will be holding Discord call focused on a code review. We've heard through the [[mw:Special:MyLanguage/Developer Satisfaction Survey/2026|Developer Satisfaction Survey]] that volunteers are struggling with code review and we'd like to discuss these experiences with the goal of surfacing workable solutions. You can join the call [https://discord.gg/wikipedia?event=1514727511102062664 via the Wikimedia Community Discord server]. * The [[m:Special:MyLanguage/Conferencia Wikimedia de América Latina 2026|Latin American Wikimedia Conference]] will host a regional hackathon that will bring together the Wikimedia movement’s technical community including developers, system administrators, data scientists, and users with extended rights. Interested technical contributors can [https://docs.google.com/forms/d/e/1FAIpQLSf4osJzTHBJjQbYJk7TMVEJjTEQv7IgtsUDfP-o-qTgeRQQxw/viewform apply for a scholarship] to participate until June 21 at midnight (Bolivia time, UTC-4). * Sign up for Wikimania Team Challenges to join this special event. The Team challenges will take place online and in person from July 21 to 22, before Wikimania conference. Everyone is welcome, regardless of skills or Wikimania registration. Teams will work on 10 important challenges supporting the Wikimedia community. For details, visit [[wmania:Special:MyLanguage/2026:Team challenges|the Team Challenges page]] and [https://wikimedia.eventyay.com/wm/teamchallenges/ register there]. Registration closes on June 20th at 11pm UTC. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/25|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W25"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৬:৪৯, ১৫ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30689604-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:UOzurumba (WMF)@metawiki পাঠিয়েছেন --> == Wikifunctions & Abstract Wikipedia Newsletter #253 is out: The or not the, this is (the?) question == There is [[:f:Special:MyLanguage/Wikifunctions:Status updates/2026-06-19|a new update]] for Abstract Wikipedia and Wikifunctions. Please, come and read it! In this issue, we present you a delicate question regarding grammatical framework, we talk about our next events and about the results of our latest online meetings, we discuss news about Types, and we take a look at the latest software developments. Want to catch up with the previous updates? Check [[:f:Special:MyLanguage/Wikifunctions:Status updates|our archive]]! Enjoy the reading! -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) ১২:৩৪, ১৯ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikifunctions_%26_Abstract_Wikipedia&oldid=30701693-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Sannita (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-26</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W26"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/26|Translations]] are available. '''Weekly highlight''' * [[mw:Special:MyLanguage/Growth/Feature summary|Growth features]] are [[phab:T418115|now available at Wikidata]]. This update enables access to Mentorship ([[mw:Special:MyLanguage/Help:Growth/Mentorship|if configured]]), Impact module, the Help Panel, and a simplified Newcomer Homepage (without Suggested Edits). Wikidata administrators are still configuring the features through Community Configuration. '''Updates for editors''' * The special page [[{{#special:RangeCalculator}}]] has been created. It allows users to find an IP range without needing to rely on external tools. Until now, this tool was only available to CheckUsers. [https://phabricator.wikimedia.org/T268429] * [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|Sub-referencing]] is a new MediaWiki feature that allows editors to reuse references with different details. It will be deployed to most small and medium-sized Wikipedia language versions on June 23. The [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing#deployment|FAQ]] lists possible actions to take on your wiki to support the deployment. Check the [[:phab:T414094|rollout plan]] for the next deployment steps. [https://phabricator.wikimedia.org/T428902] * Starting next week, users will get a notification when they are blocked or unblocked from editing, or if this block changes. [https://phabricator.wikimedia.org/T100974] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:32}} community-submitted {{PLURAL:32|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. '''Updates for technical contributors''' * Starting next week, abuse filters that are set to "require CAPTCHA verification" will begin to also affect users with the <code>skipcaptcha</code> right, which includes most autoconfirmed users. Bots are exempted. This change only affects edits that trigger an abuse filter. The <code>skipcaptcha</code> right will continue to exempt users from having to solve CAPTCHAs in the ordinary course of using the wikis. [https://phabricator.wikimedia.org/T402595] * Reference documentation for the [[wikitech:Machine_Learning/LiftWing/API|Lift Wing API]] has moved from the API Portal to the interactive [https://wikitech.wikimedia.org/w/index.php?api=lift-wing&title=Special%3ARestSandbox REST Sandbox]. * The API Portal wiki is now closed. For API documentation, see [[mw:Special:MyLanguage/Wikimedia_APIs|Wikimedia APIs on mediawiki.org]]. All API Portal wiki URLs (https://api.wikimedia.org/wiki/) will redirect to the mediawiki.org page starting June 22. [https://phabricator.wikimedia.org/T427537] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.8|MediaWiki]] '''Meetings and events''' * Join an online call on 25 June at 2:30pm UTC to meet the current Wikimedia interns for [[mw:Google_Summer_of_Code/2026|Google Summer of Code]] and [[mw:Outreachy/Round_32|Outreachy]]. Interns will provide an overview of their projects and a brief demo of their work so far. Attendees are encouraged to [[mw:event:Google_Summer_of_Code/Summer_2026_June_Internship_open_session|share ideas and connections in their community]]. '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/26|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W26"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১৩:০৫, ২৩ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30722494-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Trizek (WMF)@metawiki পাঠিয়েছেন --> == Wikifunctions & Abstract Wikipedia Newsletter #254: Working on Functions, together == There is [[:f:Special:MyLanguage/Wikifunctions:Status updates/2026-06-26|a new update]] for Abstract Wikipedia and Wikifunctions. Please, come and read it! In this issue, we report on new collaborative patterns emerging in our community, we discuss news in Types, we share some events that relate to Wikifunctions and Abstract Wikipedia at Wikimania 2026, and we take a look at the latest software developments. Want to catch up with the previous updates? Check [[:f:Special:MyLanguage/Wikifunctions:Status updates|our archive]]! Also, we remind you that if you have questions or ideas to discuss, the next '''Volunteers' Corner''' will be held on '''[https://zonestamp.toolforge.org/1783359000 July 6, at 17:30 UTC]''' ([https://meet.google.com/xuy-njxh-rkw link to the meeting]). Enjoy the reading! -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) ০৯:৫৮, ২৭ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikifunctions_%26_Abstract_Wikipedia&oldid=30724999-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Sannita (WMF)@metawiki পাঠিয়েছেন --> == <span lang="en" dir="ltr">Tech News: 2026-27</span> == <div lang="en" dir="ltr"> <section begin="technews-2026-W27"/><div class="plainlinks"> Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/27|Translations]] are available. '''Updates for editors''' * As part of the [[mw:Special:MyLanguage/Contributors/Account Creation Experiments|Account Creation Experiments]], the Growth team tested adding a user account icon in the mobile web header for logged-out users, providing direct access to "Create account" and "Log in" actions. The experiment increased account creation by about 20% without negatively affecting edit quality or constructive edit rates. The feature will now be rolled out to all Wikimedia Foundation wikis on mobile web in the first week of July. [https://phabricator.wikimedia.org/T428220] * After a [[phab:T426248|successful experiment]], logged-in users who did not [[mw:Special:MyLanguage/Help:Email_confirmation|confirm their email address]] when their account was created see a new banner asking them to complete that process. This helps reduce the risk that users get locked out of their account, and makes account email addresses overall more reliable. This is part of the [[mw:Special:MyLanguage/Product Safety and Integrity/Account Security|Account Security]] project. [https://phabricator.wikimedia.org/T428292] * An update to [[Special:Search|Search]] is refining how the <bdi lang="zxx" dir="ltr"><code><nowiki>-prefix:</nowiki></code></bdi> behaves when used to exclude results. Previously, using <bdi lang="zxx" dir="ltr"><code><nowiki>-prefix:</nowiki></code></bdi> with negation could unintentionally broaden search results by adding the namespaces included in the search scope, leading to confusing behavior for users expecting a straightforward exclusion filter. With the update, <bdi lang="zxx" dir="ltr"><code><nowiki>-prefix:</nowiki></code></bdi> will now strictly exclude matching page titles as intended and may display a warning if the relevant namespace has not been explicitly selected. The behavior of <bdi lang="zxx" dir="ltr"><code><nowiki>prefix:</nowiki></code></bdi> without negation however remains unchanged. [https://phabricator.wikimedia.org/T427443] * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:33}} community-submitted {{PLURAL:33|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where reviewers using the Page Curation toolbar were not automatically subscribed to talk page discussions they started has now been fixed. Reviewers will now receive notifications when someone replies to those discussions. [https://phabricator.wikimedia.org/T329346] '''Updates for technical contributors''' * Starting June 29th, automated downloads from the dumps.wikimedia.org website will be subject to the [[Foundation:Special:MyLanguage/Policy:Wikimedia Foundation User-Agent Policy|user-agent policy]]. Automated requests that provide a generic or empty user-agent will be blocked. Access to dumps through Wikimedia Cloud Services remains unaffected. This is a follow up to the announcement made in the [[m:Special:MyLanguage/Tech/News/2026/25|2026/25 issue of Tech News]]. * [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.47/wmf.9|MediaWiki]] '''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]]&nbsp;• [[m:Special:MyLanguage/Tech/News#contribute|Contribute]]&nbsp;• [[m:Special:MyLanguage/Tech/News/2026/27|Translate]]&nbsp;• [[m:Tech|Get help]]&nbsp;• [[m:Talk:Tech/News|Give feedback]]&nbsp;• [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].'' </div><section end="technews-2026-W27"/> </div> <bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> ১১:৪৮, ২৯ জুন ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30744833-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:STei (WMF)@metawiki পাঠিয়েছেন --> == Wikifunctions & Abstract Wikipedia Newsletter #255: Integration on test wiki and annual plan == There is [[:f:Special:MyLanguage/Wikifunctions:Status updates/2026-07-01|a new update]] for Abstract Wikipedia and Wikifunctions. Please, come and read it! In this issue, we discuss integration of Abstract Wikipedia in Test Wiki and our objectives for the new Wikimedia Foundation Fiscal Year, we remind you of the Wikifunctions and Abstract Wikipedia events at Wikimania 2026, and we take a look at the latest software developments. Want to catch up with the previous updates? Check [[:f:Special:MyLanguage/Wikifunctions:Status updates|our archive]]! Also, we remind you that if you have questions or ideas to discuss, the next '''Volunteers' Corner''' will be held on '''[https://zonestamp.toolforge.org/1783359000 July 6, at 17:30 UTC]''' ([https://meet.google.com/xuy-njxh-rkw link to the meeting]). Enjoy the reading! -- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) ০৮:২২, ২ জুলাই ২০২৬ (ইউটিসি) <!-- https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Wikifunctions_%26_Abstract_Wikipedia&oldid=30755600-এর তালিকা ব্যবহার করে বার্তাটি ব্যবহারকারী:Sannita (WMF)@metawiki পাঠিয়েছেন --> ijddcoa8zn4nd1qvcxp6b1upd9x70we মডিউল:আভিধানিক উপাত্ত 828 50158 512422 512401 2026-07-02T05:30:37Z Redmin 6857 512422 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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 getItemForSense(sense) for k, stmt in pairs(sense:getAllStatements('P5137')) do -- যদি 'এই অর্থের জন্য আইটেম' মানের বাংলা লেবেল থাকে local qid = stmt.mainsnak.datavalue.value.id return qid, getLabel(qid) end end local function getTranslations(frame, senses) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item, label = getItemForSense(sense) end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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 stmt_value, item_label = getItemForSense(sense) if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology 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, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end if lang_code 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 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end 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 language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = getOneValueForProperty(current_lexeme, 'P5186') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) 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)) else 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' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif current_language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif current_language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q809' or current_language == 'Q9058' or current_language == 'Q6654' or current_language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and current_language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 2v8yxlxwsp2ixteeyohy3773xtj7vx1 512424 512422 2026-07-02T05:34:04Z Redmin 6857 512424 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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 getItemForSense(sense) for k, stmt in pairs(sense:getAllStatements('P5137')) do -- যদি 'এই অর্থের জন্য আইটেম' মানের বাংলা লেবেল থাকে local qid = stmt.mainsnak.datavalue.value.id return qid, getLabel(qid) end end local function getTranslations(frame, senses) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item, label = getItemForSense(sense) end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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 stmt_value, item_label = getItemForSense(sense) if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology 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, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end if lang_code 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 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end 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 language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186'), 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) 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)) else 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' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif current_language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif current_language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q809' or current_language == 'Q9058' or current_language == 'Q6654' or current_language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and current_language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 8u42c05y6di38wbhb0zh1cg8b5perob 512426 512424 2026-07-02T05:44:32Z Redmin 6857 512426 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology 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, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end if lang_code 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 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end 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 language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186'), 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) 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)) else 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' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif current_language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif current_language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif current_language == 'Q809' or current_language == 'Q9058' or current_language == 'Q6654' or current_language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and current_language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 no7g6tqoi9yne58y697g53ror9q8x6y 512427 512426 2026-07-02T05:50:48Z Redmin 6857 512427 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end if lang_code 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 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end 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 language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186'), 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 hkyojhtlxwtjamg3vdp4f1yx2ejtsjn 512429 512427 2026-07-02T06:06:12Z Redmin 6857 512429 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end if lang_code 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 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end 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 language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 qlw29s83v359veij4m5gv41yb2sjy0h 512435 512429 2026-07-02T06:20:57Z Redmin 6857 512435 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match end -- Returns the grammatical gender of a lexeme local function getGenderOfLexeme(lexeme) local gender local stmts = lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end local gender = getGenderOfLexeme(current_lexeme) if lang_code 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 -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 t0d69e0f71fk3dna8pnhldpo2ti8a5a 512437 512435 2026-07-02T06:33:49Z Redmin 6857 512437 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match end -- Returns the grammatical gender of a lexeme local function getGenderOfLexeme(lexeme) local gender local stmts = lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender end -- Returns the semantic gender for a sense -- @TODO: Complete this local function getGenderForSense(sense) local gender local stmts = sense:getAllStatements('P10339') -- semantic gender if #stmts ~= 0 and stmts[1].mainsnak.datavalue then if #stmts == 1 then local gender_qid = stmts[1].mainsnak.datavalue.value.id if gender_qid == 'Q6581097' then gender = 'm' elseif gender_qid == 'Q1775415' then gender = 'f' elseif gender_qid == 'Q1775461' then gender = 'n' elseif gender_qid == 'Q1305037' then gender = 'c' elseif gender_qid == 'Q70853302' then gender = 'mfbysense' end end else for i, stmt in pairs(stmts) do local qid = stmts[i].mainsnak.datavalue if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end local gender = getGenderOfLexeme(current_lexeme) if lang_code 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 -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getOneValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 jtrtdnl91gezail1j5z0tuw9g0p4ozl 512443 512437 2026-07-02T07:01:44Z Redmin 6857 512443 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 lang_id 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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 getLastValueForProperty(object, property) local val local stmts = object:getAllStatements(property) for i, j in ipairs(stmts) do count = i end val = stmts[count].mainsnak.datavalue.value return val end local function getTranslations(frame, senses) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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} }) iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') end local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match end -- Returns the grammatical gender of a lexeme local function getGenderOfLexeme(lexeme) local gender local stmts = lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender end -- Returns the semantic gender for a sense -- @TODO: Complete this local function getGenderForSense(sense) local gender local stmts = sense:getAllStatements('P10339') -- semantic gender if #stmts ~= 0 and stmts[1].mainsnak.datavalue then if #stmts == 1 then local gender_qid = stmts[1].mainsnak.datavalue.value.id if gender_qid == 'Q6581097' then gender = 'm' elseif gender_qid == 'Q1775415' then gender = 'f' elseif gender_qid == 'Q1775461' then gender = 'n' elseif gender_qid == 'Q1305037' then gender = 'c' elseif gender_qid == 'Q70853302' then gender = 'mfbysense' end end else for i, stmt in pairs(stmts) do local qid = stmts[i].mainsnak.datavalue if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end local gender = getGenderOfLexeme(current_lexeme) if lang_code 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 -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = wb.getLabelByLang(getLastValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') if conj_class then lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 75soa0n9havwo5lpnmje6r75eoy3cig 512445 512443 2026-07-02T07:26:58Z Redmin 6857 512445 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 lang_id 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 '[[' .. mw.text.nowiki(part) .. '#' .. i18n['content_lang_name'] .. '|' .. mw.text.nowiki(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 .. "\"[inserializable 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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 getLastValueForProperty(object, property) local val local stmts = object:getAllStatements(property) for i, j in ipairs(stmts) do count = i end val = stmts[count].mainsnak.datavalue.value return val end local function getTranslations(frame, senses) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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 iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match end -- Returns the grammatical gender of a lexeme local function getGenderOfLexeme(lexeme) local gender = '' local stmts = lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender end -- Returns the semantic gender for a sense -- @TODO: Complete this local function getGenderForSense(sense) local gender = '' local stmts = sense:getAllStatements('P10339') -- semantic gender if #stmts ~= 0 and stmts[1].mainsnak.datavalue then if #stmts == 1 then local gender_qid = stmts[1].mainsnak.datavalue.value.id if gender_qid == 'Q6581097' then gender = 'm' elseif gender_qid == 'Q1775415' then gender = 'f' elseif gender_qid == 'Q1775461' then gender = 'n' elseif gender_qid == 'Q1305037' then gender = 'c' elseif gender_qid == 'Q70853302' then gender = 'mfbysense' end end else for i, stmt in pairs(stmts) do local qid = stmts[i].mainsnak.datavalue if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end local gender = getGenderOfLexeme(current_lexeme) if lang_code 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 -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = getLastValueForProperty(current_lexeme, 'P5186') if conj_class then conj_class = wb.getLabelByLang(getLastValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 0gj7cbui0vgq64guifztglxx4rhzq75 512446 512445 2026-07-02T07:49:48Z Redmin 6857 512446 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 lang_id 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 '[[' .. mw.text.nowiki(part) .. '#' .. i18n['content_lang_name'] .. '|' .. mw.text.nowiki(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 .. "\"[inserializable 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 local function checkTitleCodePointInRange(title, start_point, end_point) return ustring.find( title, '[' ..ustring.char(start_point) .. '-' .. ustring.char(end_point) .. ']' ) end local function getLanguageForCategories( current_page_title ) -- বিশেষ ভাষার জন্য if lang_id == 'Q11051' then -- হিন্দি/উর্দু if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- উর্দু lang_id = 'Q11051ur' elseif checkTitleCodePointInRange(current_page_title, 0x0900, 0x097f) then -- হিন্দি lang_id = 'Q11051hi' end elseif lang_id == 'Q58635' then -- পাঞ্জাবি if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- শাহমুখী lang_id = 'Q58635pnb' elseif checkTitleCodePointInRange(current_page_title, 0x0a00, 0x0a7f) then -- গুরুমুখী lang_id = 'Q58635pa' end elseif lang_id == 'Q56356571' then -- নয়া ফার্সি ভাষা if checkTitleCodePointInRange(current_page_title, 0x0600, 0x06ff) then -- ফার্সি (ইরান/আফগানিস্তান) lang_id = 'Q56356571fa' elseif checkTitleCodePointInRange(current_page_title, 0x0400, 0x04ff) then -- তাজিক lang_id = 'Q56356571tg' end end return lang_id end local function getEntity( id ) if entity_cache[id] == nil then entity_cache[id] = wb.getEntity(id) or error('Invalid ID provided: ' .. id) end return entity_cache[id] ~= false and entity_cache[id] or nil 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 = 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 then if reference.snaks['P248'] 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'] then local snak = reference.snaks['P854'][1] if snak.datavalue then url_value = snak.datavalue.value end end end if url_value 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 -- Returns the Wiktionary language code for a lexeme entity or nil, in the latter case, getLemmas() can be relied on to fetch the language code by stripping extraneous bits from the 'language' string as necessary local function getLexemeLanguageCode(lexeme) local lang_item_id = lexeme:getLanguage() local lang_entity = getEntity(lang_item_id) for i, statement_property in ipairs({'P305','P424', 'P220'}) do -- আইইটিএফ ভাষা ট্যাগ, উইকিমিডিয়া ভাষা কোড, আইএসও ৬৩৯-৩ local statements = lang_entity:getBestStatements(statement_property) if statements[1] then local code = statements[1].mainsnak.datavalue.value if code == 'hr' then return 'sh' elseif code == 'pan' then return 'pa' else return code end end end 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 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) if lex then lex = getEntity(lex) n = n + 1 lemmas[n] = lex:getLemma(lang_code) end 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 then local property_source = wb.getBestStatements(property_id, 'P9073') local source_name if next(property_source) 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', 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 heading_level(text, level) return '<h' .. level .. '>' .. ' ' .. text .. ' ' .. '</h' .. level .. '>' end 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 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(lexeme, frame) local lemma_string = '' local lang for i, rep in pairs(lexeme:getLemmas()) do lang = getLexemeLanguageCode(lexeme) if lang == nil then lang = string.gsub(rep[2], '-%S+', '') end if lemma_string == '' then lemma_string = frame:expandTemplate{title='link', args={lang, rep[1]}} else lemma_string = lemma_string .. '/' .. frame:expandTemplate{title='link', args={lang, rep[1]}} 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 and stmt.qualifiers['P6072'] 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'] then table.insert(example_form_strs, stmt.qualifiers['P1810'][1].datavalue.value) elseif stmt.qualifiers['P5830'] 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 _, example_form_str in pairs(example_form_strs) do local 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 example_text = new_example_text end if example_str == nil then example_str = termSpan({example_text, example_lang}) end local reference_text = '' if stmt.references 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 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.qualifiers then example_form = getEntity(stmt.qualifiers['P5830'][1].datavalue.value.id) -- বিষয়ে লেক্সিমের রূপ if stmt.qualifiers['P1810'] then example_form_str = stmt.qualifiers['P1810'][1].datavalue.value end end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentation(i18n['content_lang_code']) end if example_form and example_form_str == nil then example_form_str = example_form:getRepresentations()[1][1] end if example_form_str 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 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 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 getOneValueForProperty(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 getLastValueForProperty(object, property) local val local stmts = object:getAllStatements(property) for i, j in ipairs(stmts) do count = i end val = stmts[count].mainsnak.datavalue.value return val end local function getTranslations(frame, senses) if #senses == 0 then return nil end local all_translations = {} local wmlang, item, label for _, sense in pairs(senses) do local translation_set = {} local gloss = sense:getGloss(i18n['content_lang_code']) if lex_cat ~= 'Q34698' then item = getOneValueForProperty(sense, 'P5137') if item then item = item.id label = getLabel(item) end end if item then wmlang = require("Module:wikimedia languages") end for _, stmt in pairs(sense:getAllStatements('P5972')) do local translation = stmt.mainsnak.datavalue.value.id local lexeme_id = wb.lexeme.splitLexemeId(translation) local trans_lexeme = getEntity(lexeme_id) local lang_name = getLabel(trans_lexeme:getLanguage()) local trans_code = getLexemeLanguageCode(trans_lexeme) if trans_code then table.insert(translation_set, lang_name .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={trans_code, getLinkedLemmata(trans_lexeme, frame) .. '<br/>'}}) else table.insert(translation_set, lang_name .. ': ' .. getLinkedLemmata(trans_lexeme, frame) .. '<br/>' .. i18n.trans_category(lang_name)) end end if item then for _, v in pairs(getEntity(item).labels) do if string.find(v.language, '-') == nil then -- @TODO: Implement deduplication of translation and get rid of this check local lang = wmlang.getByCode(v.language) local wikt = lang:getWiktionaryLanguage() if wikt:hasType('regular') then table.insert(translation_set, getLabel(wikt:getWikidataItem()) .. ': ' .. frame:expandTemplate{title=i18n['template_t'], args={wikt:getCode(), v.value .. '<br/>'}}) end end end end if #translation_set > 0 then local block = frame:expandTemplate{ title = i18n['template_trans-top'], args = { gloss or label } } 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 heading_level(i18n['heading_translation'], 4) .. ' \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 item_label_gloss_parts = {} 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 _, 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 then for j, reference in pairs(refs) do table.insert(references_seen, reference.hash) local got_reference = getReference(reference.hash, reference) reference_text = reference_text .. '\n\n' .. frame:extensionTag('ref', got_reference[2]) end end local val = getLabel(stmt_value) table.insert(specifiers, val .. reference_text) if property_id == 'P9488' and lang_code ~= nil then table.insert(item_label_gloss_parts, i18n.tocatlink(lang_code .. ':' .. val)) 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 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, other_gloss_lang, item_label local stmt_value = getOneValueForProperty(sense, 'P5137') if stmt_value then stmt_value = stmt_value.id item_label = getLabel(stmt_value) end if item_label then table.insert(item_label_gloss_parts, '[[:d:' .. stmt_value .. '|' .. item_label .. ']]') 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 _, fallback_lang in ipairs(mw_lang.getFallbacksFor( i18n['content_lang_code'] )) do if sense:getGloss( fallback_lang ) then other_gloss_text, other_gloss_lang = sense:getGloss( fallback_lang ) end end if other_gloss_lang == nil then local glosses = sense:getGlosses() for _, 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 _, stmt in pairs(sense:getAllStatements('P8394')) do -- টিপ্পনীর উদ্ধৃতি local gloss_quote = termSpan({stmt.mainsnak.datavalue.value.text, stmt.mainsnak.datavalue.value.language}) if stmt.references[1] 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 _, 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 } local qualifiers_order = stmt['qualifiers-order'] if qualifiers_order then for _, 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) 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] 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 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() local base_form = nil -- (!) অন্য ভাষার শব্দের যদি অন্য রকম মূল ফর্ম থাকে সেগুলো এখানে নতুন if বিবৃতি দিয়ে যোগ করা যায়। if lang_code == 'bn' 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 and stmt.qualifiers['P1545'] 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 then local part_lexeme_id = stmt.mainsnak.datavalue.value.id local part_lexeme = getEntity(part_lexeme_id) local current_substring = getLinkedLemmata(part_lexeme, frame) local part_etymology = getEtymology(part_lexeme, frame, 'partial') if part_etymology ~= '' and part_etymology then current_substring = current_substring .. ' (← ' .. part_etymology .. ')' end if combines == '' then combines = current_substring else -- @TODO: This should use the 'affix' and 'compound' templates instead. combines = combines .. ' + ' .. current_substring end end end end return combines end function getRoots( current_lexeme, frame ) 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, frame), 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, frame) if mode ~= 'partial' and root_str 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 then return current_roots .. '<br/>(' .. current_combines .. ')' elseif current_roots ~= '' then if lang_code == 'ar' and mode ~= 'partial' and root_str ~= matched_lemma 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 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, frame) .. ' (' .. sitelink .. ')' else origin_lexeme_string = getLinkedLemmata(origin_lexeme, frame) .. ' (' .. origin_lexeme_lang .. ')' end if stmt.qualifiers and stmt.qualifiers['P5886'] 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 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 and etymology then etymology = etymology .. ' ' .. origin_lexeme_string elseif origin_lexeme_string and etymology == nil then etymology = origin_lexeme_string end end if current_roots ~= '' and etymology and current_roots then etymology = etymology .. ' ' .. current_roots elseif current_roots ~= '' and etymology == nil then etymology = current_roots end if current_combines ~= '' and etymology 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) local pronunciations = {} local base_form = getPronunciationBaseForm() local iast, iso15919_transcription, itrans, xsampa if base_form 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 then for k, property_id in ipairs({'P5237'}) do -- উচ্চারণের ধরন local qual = stmt.qualifiers[property_id] if qual then for _, qual in pairs(qual) do local stmt_value = qual.datavalue.value.id table.insert(specifiers, getLabel(stmt_value)) end 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 iso15919_transcription = getOneValueForProperty(base_form, 'P5825') -- আইএসও ১৫৯১৯ প্রতিলিপিকরণ itrans = getOneValueForProperty(base_form, 'P8881') -- ITRANS iast = getOneValueForProperty(base_form, 'P7581') -- আইএএসটি প্রতিলিপিকরণ xsampa = getOneValueForProperty(base_form, 'P2859') local ipa_transcription = base_form:getAllStatements('P898') -- আধ্বব প্রতিলিপিকরণ -- @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 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_code == 'bn' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='bn-IPA', }) elseif lang_code == 'ar' then local lemma = current_lexeme:getLemma('ar') table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ar-IPA', args={lemma} }) elseif lang_code == 'en' then table.insert(pronunciations, '* ' .. i18n['text_syllable_count'] .. ' ' .. callWikifunctionsFunction('Z29940|' .. matched_lemma, frame)) elseif lang_code == 'pl' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='pl-IPA', }) elseif lang_code == 'ko' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ko-IPA', }) elseif lang_code == 'fi' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fi-IPA', }) elseif lang_code == 'ta' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='ta-IPA', }) elseif lang_code == 'fax' then table.insert(pronunciations, '* ' .. frame:expandTemplate{ title='fax-pron', }) end end -- {{আধ্বব|en|/ˈɪntəvjuː/}} if iso15919_transcription then table.insert(pronunciations, pronunciationBlock('iso15919', iso15919_transcription)) end if itrans then table.insert(pronunciations, pronunciationBlock('itrans', itrans)) end if iast then table.insert(pronunciations, pronunciationBlock('iast', iast)) end if xsampa then table.insert(pronunciations, pronunciationBlock('xsampa', xsampa)) end return table.concat(pronunciations, '\n') end local function getAlternativeSpellings( current_lexeme, frame ) local alt_spellings = {} for i, stmt in pairs(current_lexeme:getAllStatements('P11577')) do -- বিকল্প বানান if stmt.mainsnak.datavalue then table.insert(alt_spellings, '* ' .. frame:expandTemplate{title=i18n['template_alter'], args={lang_code, getLemmata(getEntity(stmt.mainsnak.datavalue.value.id), frame)}}) end end return table.concat(alt_spellings, '\n') end function get_any_notes(sections, args, keys) local notes = {} for i, v in ipairs(keys) do if args[v] 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, heading) for i, v in ipairs(keys) do if args[v] then if heading then table.insert(sections, heading) end table.insert(sections, args[v]) end end end local function getMatchingLemmaForPageTitle(lexeme, title) local lemmas = lexeme:getLemmas() local match for _, lemma_entry in ipairs(lemmas) do local lemma = lemma_entry[1] if lemma == title then match = lemma break end end if match == nil then if lang_code == 'ar' then match = lexeme:getLemma('ar') elseif lang_code == 'rhg' then match = lexeme:getLemma('rhg-arab') elseif lang_id == 'Q11051ur' then match = lexeme:getLemma('ur') elseif lang_code == 'arz' then match = lexeme:getLemma('arz') end end return match end -- Returns the grammatical gender of a lexeme local function getGenderOfLexeme(lexeme) local gender = '' local stmts = lexeme:getAllStatements('P5185') -- ব্যাকরণগত লিঙ্গ if #stmts ~= 0 and stmts[1].mainsnak.datavalue 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 if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender end -- Returns the semantic gender for a sense -- @TODO: Complete this local function getGenderForSense(sense) local gender = '' local stmts = sense:getAllStatements('P10339') -- semantic gender if #stmts ~= 0 and stmts[1].mainsnak.datavalue then if #stmts == 1 then local gender_qid = stmts[1].mainsnak.datavalue.value.id if gender_qid == 'Q6581097' then gender = 'm' elseif gender_qid == 'Q1775415' then gender = 'f' elseif gender_qid == 'Q1775461' then gender = 'n' elseif gender_qid == 'Q1305037' then gender = 'c' elseif gender_qid == 'Q70853302' then gender = 'mfbysense' end end else for i, stmt in pairs(stmts) do local qid = stmts[i].mainsnak.datavalue if qid then qid = qid.value.id end if qid == 'Q499327' then gender = gender .. 'm' elseif qid == 'Q1775415' then gender = gender .. 'f' end end end return gender 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) 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 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] 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 language = current_lexeme:getLanguage() lang_id = language local senses = current_lexeme:getSenses() local add_heading = true forms = current_lexeme:getForms() if args[2] 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(title, true) local lang_name = getLabel(lang_category) if add_heading == true then local lang_heading = heading_level(lang_name, 2) table.insert(sections, lang_heading) end lang_code = getLexemeLanguageCode(current_lexeme) matched_lemma = getMatchingLemmaForPageTitle(current_lexeme, title) lex_cat = current_lexeme:getLexicalCategory() local cat = i18n.lang_category(getLabel(lex_cat), lang_name) local lex_cat_template, ety_added, pron_added, alt_added if cat then table.insert(sections, heading_level(getLabel(lex_cat) .. cat .. frame:expandTemplate{ title = i18n['template_anchor'], args = { lexeme_id } }, 3)) 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 then table.insert(sections, heading_level(i18n['heading_etymology'], 4)) table.insert(sections, tostring(etymology)) ety_added = true end if ety_added then add_any_notes(sections, args, i18n['manual_etymology']) else add_any_notes(sections, args, i18n['manual_etymology'], heading_level(i18n['heading_etymology'], 4)) end local pronunciation = getPronunciation( frame, current_lexeme, lang_name) if pronunciation ~= '' then table.insert(sections, heading_level(i18n['heading_pronunciation'], 4)) table.insert(sections, tostring(pronunciation)) pron_added = true end if pron_added then add_any_notes(sections, args, i18n['manual_pronunciation']) else add_any_notes(sections, args, i18n['manual_pronunciation'], heading_level(i18n['heading_pronunciation'], 4)) end local alternative_spellings = getAlternativeSpellings(current_lexeme, frame) if alternative_spellings ~= '' then table.insert(sections, heading_level(i18n['heading_alternative_spellings'], 4)) table.insert(sections, alternative_spellings) alt_added = true end if alt_added then add_any_notes(sections, args, i18n['manual_alternative_spellings']) else add_any_notes(sections, args, i18n['manual_alternative_spellings'], heading_level( i18n['heading_alternative_spellings'], 4)) end local gender = getGenderOfLexeme(current_lexeme) if lang_code 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 -- The following checks are ordered based on which one is expected to be true in a higher number of cases. if language == 'Q13955' then if matched_lemma then lex_cat_template = safeExpand(frame, 'ar-noun', {matched_lemma,gender}) else lex_cat_template = frame:expandTemplate{title='ar-noun', args={nil,gender}} end elseif language == 'Q29919' then lex_cat_template = frame:expandTemplate{title='arz-noun', args={g=gender}} elseif language == 'Q397' then if matched_lemma then lex_cat_template = frame:expandTemplate{title='la-noun', args={matched_lemma,g=gender}} end elseif language == 'Q11059' then lex_cat_template = frame:expandTemplate{title='sa-noun', args={g=gender}} elseif 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 elseif lex_cat == 'Q24905' then -- ক্রিয়া if lang_code == 'ar' then local conj_class = getLastValueForProperty(current_lexeme, 'P5186') if conj_class then conj_class = wb.getLabelByLang(getLastValueForProperty(current_lexeme, 'P5186').id, 'en'):gsub('Form ', '') lex_cat_template = frame:expandTemplate{title='ar-verb', args={conj_class}} end else lex_cat_template = safeExpand(frame, lang_code .. '-verb') 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 then table.insert(sections, lex_cat_template) else if matched_lemma 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 == 'Q376431' then -- বর্ণের নাম table.insert(sections, i18n.tocatlink(lang_code .. ':রং')) else table.insert(sections, heading_level(i18n['heading_special_info'], 4) .. i18n['text_instance_of'] .. ' ' .. getLabel(instance_of_entity) .. i18n['text_sentence_terminator']) end end if lex_cat ~= 'Q9788' then local translations = getTranslations(frame, senses) if translations then table.insert(sections, translations) end end -- (!) বিশেষ ভাষার বিভক্তির সারণি যদি থাকে সেগুলো এখানে নতুন if বিবৃতি যোগ করা যায়। if next(forms) then if 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)) else if #forms > 1 then table.insert(sections, buildLanguageAgnosticInflectionTable()) end end --elseif language == 'Q13955' then -- আরবি -- if lex_cat == 'Q1084' then -- table.insert(sections, frame:expandTemplate{title='ar-decl-noun', args={lemma}}) -- end elseif language == 'Q188' and lex_cat == 'Q1084' then -- জার্মান table.insert(sections, callWikifunctionsFunction('Z28602|' .. lexeme_id .. '|', frame)) --elseif language == 'Q397' and lex_cat == 'Q1084' then -- লাতিন -- table.insert(sections, callWikifunctionsFunction('Z26333|' .. matched_lemma .. '|', frame)) elseif language == 'Q150' and lex_cat == 'Q34698' then -- ফরাসি table.insert(sections, callWikifunctionsFunction('Z36435|' .. lexeme_id .. '|', frame)) elseif language == 'Q652' and lex_cat == 'Q34698' then -- ইতালীয় table.insert(sections, callWikifunctionsFunction('Z36407|' .. lexeme_id .. '|', frame)) elseif language == 'Q809' or language == 'Q9058' or language == 'Q6654' or language == 'Q9056' then -- পোলীয়, স্লোভাক, ক্রোয়েশীয়, চেক table.insert(sections, callWikifunctionsFunction('Z36421|' .. lexeme_id .. '|', frame)) elseif #forms > 1 and language ~= 'Q150' then table.insert(sections, buildLanguageAgnosticInflectionTable()) 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 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 kv5gft7t0si2jioi06ghn5whf1nlyu6 মডিউল:আভিধানিক উপাত্ত/নথি 828 50210 512430 512271 2026-07-02T06:09:43Z Redmin 6857 /* ব্যবহার */ 512430 wikitext text/x-wiki এই মডিউলটি বর্তমানে পরীক্ষামূলক পর্যায়ে রয়েছে। ==ব্যবহার== <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all| লেক্সিম নং }}</nowiki></code> উদা: <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all|L301993}}</nowiki></code> ভাষার সেকশন হেডিং বাদ দিতে চাইলে টেম্পলেটটি এভাবে ব্যবহার করবেন: <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all|L301993|না}}</nowiki></code> এই মডিউলের কিছু ব্যবহার দেখতে এই পাতাগুলো দেখুন: '''[[হৃদয়]]''', '''[[knife]]''', '''[[س ك ن]]''', '''[[double]]''', '''[[mouse]]''', '''[[clinical psychology]]''', '''[[Aggression]]''', '''[[bygning]]''', '''[[ডাকঘর]]''', '''[[big]]''', '''[[চলা]]''', '''[[abdomen]]''', '''[[pizzabagare]]''', '''[[agricola]]''', '''[[blanc]]''', '''[[sekunda]]''', '''[[من]]''', '''[[علم]]'''। 2oa4yx328b6dejajfex8rszieasdkx5 512447 512430 2026-07-02T07:50:36Z Redmin 6857 /* ব্যবহার */ 512447 wikitext text/x-wiki এই মডিউলটি বর্তমানে পরীক্ষামূলক পর্যায়ে রয়েছে। ==ব্যবহার== <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all| লেক্সিম নং }}</nowiki></code> উদা: <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all|L301993}}</nowiki></code> ভাষার সেকশন হেডিং বাদ দিতে চাইলে টেম্পলেটটি এভাবে ব্যবহার করবেন: <code><nowiki>{{#invoke:আভিধানিক উপাত্ত|all|L301993|না}}</nowiki></code> এই মডিউলের কিছু ব্যবহার দেখতে এই পাতাগুলো দেখুন: '''[[হৃদয়]]''', '''[[knife]]''', '''[[س ك ن]]''', '''[[double]]''', '''[[mouse]]''', '''[[clinical psychology]]''', '''[[Aggression]]''', '''[[bygning]]''', '''[[ডাকঘর]]''', '''[[big]]''', '''[[চলা]]''', '''[[abdomen]]''', '''[[pizzabagare]]''', '''[[agricola]]''', '''[[blanc]]''', '''[[sekunda]]''', '''[[من]]''', '''[[নুক্তা]]''', '''[[علم]]'''। fiwwasn7fm45kim4k7p6uictwsxwgna teşekkürler 0 51130 512404 333482 2026-07-01T23:18:44Z Redmin 6857 /* ব্যুৎপত্তি */ 512404 wikitext text/x-wiki =={{ভাষা|tr}}== ===ব্যুৎপত্তি=== {{m|tr|teşekkür}} বিশেষ্যটির বহুবচন যা {{m|tr|teşekkür ederim}}-এও দেখা যায়, {{der|tr|ar|تَشَكُّر}} (tašakkur), {{ar-root|ش ك ر|nocat=1}} ত্রিকোণ মূল থেকে, যার অর্থ- ধন্যবাদ, কৃতজ্ঞ হওয়া। ===উচ্চারণ=== * {{আধ্বব|tr|/teʃecːyɾˈleɾ/}} * {{অডিও|tr|Teşekkürler.ogg|অডিও}} ===বিশেষ্য=== {{tr-বিশেষ্য-বহুবচন-form}} # {{inflection of|tr|teşekkür||def|p}} ===ইন্টারজেকশন=== {{head|tr|আবেগসূচক অব্যয়s}} # [[ধন্যবাদ]] ====আরও দেখুন==== * {{l|tr|mersi}} * {{l|tr|teşekkür ederim}} mah1y4kxr97s5yedq6alzajijwv2o8e جميلة 0 72271 512444 442668 2026-07-02T07:04:08Z Redmin 6857 /* {{ভাষা|ar}} */ 512444 wikitext text/x-wiki {{আরও দেখুন|جمیله|جمیلہ}} =={{ভাষা|ar}}== ===ব্যুৎপত্তি=== From the root {{ar-root|ج م ل}}. ===উচ্চারণ=== * {{ar-IPA|جَمِيلَة}} ===বিশেষণ=== {{ar-adj-fem|جَمِيلَة}} # {{feminine singular of|ar|جَمِيل}} ====উত্তরসূরি==== * {{উত্তরসূরী|ota|جمیله|tr=cemîle|bor=1}} ** {{উত্তরসূরী|tr|cemile}} ===নামবাচক বিশেষ্য=== {{ar-proper noun|جَمِيلَة|f}} # {{প্রদত্ত নাম|ar|নারী|xlit=Jamila|m=جَمِيل}} ====Declension==== {{ar-decl-noun|جَمِيلَة:di|state=ind-def}} ====উত্তরসূরি==== * {{উত্তরসূরী|az|Cəmilə|bor=1}} * {{উত্তরসূরী|ba|Йәмилә|bor=1}} * {{উত্তরসূরী|chg|جمیله|bor=1}} ** {{উত্তরসূরী|uz|Jamila}} * {{উত্তরসূরী|ota|جمیله|tr=Cemîle|bor=1}} ** {{উত্তরসূরী|tr|Cemile}} * {{উত্তরসূরী|fa|جمیله|tr=jamile|bor=1}} * {{উত্তরসূরী|ur|جمیلہ|tr=jamīla|bor=1}} dxjyrwxph59smgdajczs5675rj69tvl راجح 0 72300 512431 334660 2026-07-02T06:19:19Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1505478-এর সাথে সংযোগ তৈরি করছি 512431 wikitext text/x-wiki =={{langname|ar}}== ===ব্যুৎপত্তি=== From the root {{ar-root|ر|ج|ح}}. ===নামবাচক বিশেষ্য=== {{ar-proper noun|رَاجِح|m}} # {{প্রদত্ত নাম|ar|পুরুষ}} Rajih ====Declension==== {{ar-decl-noun|رَاجِح:tri|state=ind-def}} {{লে|L1505478|না}} ohjvepgsvzerluf81kt00usoxbnan24 512432 512431 2026-07-02T06:19:34Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1485310-এর সাথে সংযোগ তৈরি করছি 512432 wikitext text/x-wiki =={{langname|ar}}== ===ব্যুৎপত্তি=== From the root {{ar-root|ر|ج|ح}}. ===নামবাচক বিশেষ্য=== {{ar-proper noun|رَاجِح|m}} # {{প্রদত্ত নাম|ar|পুরুষ}} Rajih ====Declension==== {{ar-decl-noun|رَاجِح:tri|state=ind-def}} {{লে|L1505478|না}} {{লে|L1485310|না}} 4ato4s7o8bees55wmqlnz4i24ogqvqh 512433 512432 2026-07-02T06:19:46Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1098553-এর সাথে সংযোগ তৈরি করছি 512433 wikitext text/x-wiki =={{langname|ar}}== ===ব্যুৎপত্তি=== From the root {{ar-root|ر|ج|ح}}. ===নামবাচক বিশেষ্য=== {{ar-proper noun|رَاجِح|m}} # {{প্রদত্ত নাম|ar|পুরুষ}} Rajih ====Declension==== {{ar-decl-noun|رَاجِح:tri|state=ind-def}} {{লে|L1505478|না}} {{লে|L1485310|না}} {{লে|L1098553}} bzrjrdvtqv8odwjtorni2l3o7gnea6s 512434 512433 2026-07-02T06:20:14Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1513038-এর সাথে সংযোগ তৈরি করছি 512434 wikitext text/x-wiki =={{langname|ar}}== ===ব্যুৎপত্তি=== From the root {{ar-root|ر|ج|ح}}. ===নামবাচক বিশেষ্য=== {{ar-proper noun|رَاجِح|m}} # {{প্রদত্ত নাম|ar|পুরুষ}} Rajih ====Declension==== {{ar-decl-noun|رَاجِح:tri|state=ind-def}} {{লে|L1505478|না}} {{লে|L1485310|না}} {{লে|L1513038|না}} {{লে|L1098553}} 93wa6wiq700wup863mlh9gu1p2bpdn7 512436 512434 2026-07-02T06:24:18Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1571265-এর সাথে সংযোগ তৈরি করছি 512436 wikitext text/x-wiki {{লে|L1505478}} {{লে|L1485310|না}} {{লে|L1513038|না}} {{লে|L1571265|না}} {{লে|L1098553}} rae7mrvzvpsaftod24d44v3c4savq4b صادق 0 72362 512449 461242 2026-07-02T11:52:39Z Redmin 6857 /* ব্যুৎপত্তি 1 */ 512449 wikitext text/x-wiki =={{ভাষা|ar}}== ===ব্যুৎপত্তি 1=== {{ar-active participle}} of {{m|ar|صَدَقَ||to be [[sincere]], to be [[right]], [[come true]]}}, from the root {{ar-root|ص د ق}}। তুলনীয় {{সমোদ্ভব|he|צדיק|tr=tsadiq|t=honest, righteous}}. ====বিশেষণ==== {{ar-adj|صَادِق|f=صَادِقَة|pl=صَادِقُون|fpl=صَادِقَات|fpl2=صَوَادِقُ|el=أَصْدَق}} # telling the truth, [[truthful]], [[veracious]] #* {{RQ:Qur’an|2|111|passage=قُلْ هَاتُوا بُرْهَانَكُمْ إِنْ كُنْتُمْ {{quoted term|صَادِقِينَ}}|translation=Say, ‘Produce your evidence, if you are {{quoted term|telling the truth}}.’}} # [[true]] #* {{RQ:Qur’an|51|5|passage=إِنَّمَا تُوعَدُونَ لَصَادِقٌ}} # [[sincere]], [[candid]] # [[genuine]], [[faithful]], [[authentic]] =====Declension===== {{ar-decl-adj|صَادِق|pl=صَادِقُون|fpl=صَادِقَات|fpl2=صَوَادِقُ}} =====উত্তরসূরি===== * {{উত্তরসূরী|az|sadiq}} * {{desctree|ota|صادق}} * {{উত্তরসূরী|fa|صادق}} * {{উত্তরসূরী|uz|sodiq}} ===ব্যুৎপত্তি 2=== {{ar-form|III}} from the root {{ar-root|ص|د|ق}}. ====ক্রিয়া==== {{ar-verb|III}} [[befriend]] # to ratify, to certify, to substantiate {{+preo|ar|عَلَى}} =====ধাতুরূপ===== {{ar-conj|III}} ===ব্যুৎপত্তি 3=== এর উৎস {{m|ar|صَادِق}}, active participle of {{l|ar|صَدَقَ}}. ====নামবাচক বিশেষ্য==== {{ar-proper noun|صَادِق|m}} # {{প্রদত্ত নাম|ar|পুরুষ}}: [[Sadiq]], [[Sadeq]], Sadegh # {{lb|ar|defined}} [[w:Ja'far al-Sadiq|Ja'far al-Sadiq]] ==উসমানীয় তুর্কি== ===বিশেষণ=== {{ota-adj|tr=sadık}} # [[loyal]] ====উদ্ভূত শব্দ==== * {{l|ota|صادقلق}} ====উত্তরসূরি==== * {{উত্তরসূরী|tr|sadık}} ===তথ্যসূত্র=== * {{R:ota:Mallouf:1856|loyal|page=426}} =={{ভাষা|fa}}== {{উইকিপিডিয়া|lang=fa}} ===ব্যুৎপত্তি=== এর উৎস {{bor|fa|ar|صَادِق}}. ===উচ্চারণ=== {{fa-IPA|sādiq}} ===বিশেষণ=== {{fa-adj|tr=sâdeq|c=+}} # [[truthful]] # [[true]] # [[honest]] ====সম্পর্কিত পদ==== * {{l|fa|راستگو|tr=râstgu}} ===নামবাচক বিশেষ্য=== {{fa-proper noun|tr=sâdeq}} # {{প্রদত্ত নাম|fa|পুরুষ|xlit=Sadiq|xlit2=[[Sadegh]]|xlit3=[[Sadeq]]|from=আরবি}} #: {{উদা|fa|صادق خان|tr=sâdeq xân|Sadiq Khan|inline=1}} 8mjitoq516ub041e5p4tfi45sz8391n آهو 0 72551 512441 461198 2026-07-02T06:46:30Z Redmin 6857 512441 wikitext text/x-wiki ==Pashto== ===বিশেষ্য=== {{head|ps|noun|g=m|tr=āhu}} # [[antelope]] # [[wild goat]] # {{lb|ps|কাব্যিক}} [[gazelle]] =={{ভাষা|fa}}== {{উইকিপিডিয়া|lang=fa}} ===উচ্চারণ=== {{fa-IPA|āhū}} ===ব্যুৎপত্তি 1=== এর উৎস {{উত্তরাধিকারী|fa|pal||ts=āhūg}}, এর মূল উৎস {{der|fa|ine-pro|*h₂eḱ-|*h₂eḱus|sharp, swift}}। Cognates with {{সমোদ্ভব|kmr|ask}} এবং {{সমোদ্ভব|bal|آسک|tr=ásk}}. ====বিশেষ্য==== {{fa-regional|آهو|آهو|оҳу}} {{fa-noun|tr=âhu|pl=آهوان|pltr=âhovân|pl2=آهوها|pl2tr=âhuhâ}} # [[gazelle]] #: {{syn|fa|غزال|tr=ğazâl}} # {{lb|fa|কম প্রচলিত}} [[deer]] #: {{syn|fa|گوزن|tr=gavazn}} =====উদ্ভূত শব্দ===== * {{l|fa|آهوبره|tr=âhu-barre|gloss=fawn}}, {{l|fa|آهوانه|tr=âhuâne}} ====নামবাচক বিশেষ্য==== {{fa-proper noun|tr=âhu}} # {{প্রদত্ত নাম|fa|নারী|xlit=[[Ahu]]|from=Middle ফার্সি}} ===ব্যুৎপত্তি 2=== {{rfe|fa}} ====বিশেষ্য==== {{fa-noun|tr=âhu}} # {{lb|fa|archaic}} defect, imperfection #* '''10th Century CE''', [[w:Ferdowsi|Ferdowsi]], ''[[w:Shahnameh|Shahnameh]]'' #*: {{উদা|fa|دو گوش و دو پای من '''آهو گرفت''' / تهی‌دستی و سال نیرو گرفت|tr=do guš o do pâye man '''âhu gereft''' / tohidasti yo sâl niru gereft|t=My both ears and legs (my body) '''have grown faulty''' / and destitution and the old age emerged instead!}} =====উত্তরসূরি===== * {{উত্তরসূরী|glk|tr=åhú|bor=1}} * {{উত্তরসূরী|xme-ker|-|bor=1}} *: {{উত্তরসূরী|gzi|tr=åhū}} *: {{উত্তরসূরী|xme-kaf|tr=åvī́}} *: {{উত্তরসূরী|xme-kes|tr=ā̊hṻ}} *: {{উত্তরসূরী|ntz|tr=åvī́}} *: {{উত্তরসূরী|xme-qoh|tr=åhū́}} *: {{উত্তরসূরী|xme-von|tr=åhū́}} *: {{উত্তরসূরী|xme-sed|tr=åhū́}} *: {{উত্তরসূরী|xme-zef|tr=åhṻ}} * {{উত্তরসূরী|ur|آہو|tr=āhū|bor=1}} * {{উত্তরসূরী|lsa|tr=āhú|bor=1}} * {{উত্তরসূরী|oru|tr=āū|bor=1}} * {{উত্তরসূরী|prc|āhū́|bor=1}} * {{উত্তরসূরী|srh|tr=āhu|bor=1}} * {{উত্তরসূরী|smy|āhú|bor=1}} * {{উত্তরসূরী|srz|tr=ā̊hū̆|bor=1}} * {{উত্তরসূরী|siy|tr=āhū|bor=1}} * {{উত্তরসূরী|sqo|tr=ahü|bor=1}} * {{উত্তরসূরী|tr|Ahu|bor=1}} * {{উত্তরসূরী|en|ahu|bor=1}} ===তথ্যসূত্র=== * {{R:fa:Steingass}} * {{R:Dehkhoda|آهو}} * {{R:Mackenzie|page=7}} * {{R:fa:Horn|page=15}} [[Category:fa:Mammals]] sh9ae6jhgsvzl8d51mkfrrefc98mn8m علم 0 162491 512420 450223 2026-07-02T05:11:12Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1481818-এর সাথে সংযোগ তৈরি করছি 512420 wikitext text/x-wiki =={{langname|ar}}== ===ক্রিয়া ১=== ====উচ্চারণ==== * {{ar-IPA|عَلِمَ}} ====অর্থ==== {{ar-verb|I/i~a.vn:عِلْم.ap:+}} #জানা ===ক্রিয়া ২=== {{ar-verb|II}} #শেখানো ===বিশেষ্য=== ====উচ্চারণ==== * {{ar-IPA|عِلْم}} * {{audio|ar|Ar-علم.ogg|ʿilm}} {{ar-noun|عِلْم|m|pl=عُلُوم}} ====অর্থ==== # {{ar-verbal noun of|عَلِمَ|form=I}} #জ্ঞান {{লে|L1481818|না}} 8thr2w01zet3s6zsvsbo5xtqrklxjx5 512421 512420 2026-07-02T05:15:26Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1220891-এর সাথে সংযোগ তৈরি করছি 512421 wikitext text/x-wiki =={{langname|ar}}== ===ক্রিয়া ১=== ====উচ্চারণ==== * {{ar-IPA|عَلِمَ}} ====অর্থ==== {{ar-verb|I/i~a.vn:عِلْم.ap:+}} #জানা ===ক্রিয়া ২=== {{ar-verb|II}} #শেখানো {{লে|L1481818|না}} {{লে|L1220891|না|অর্থ=# {{ar-verbal noun of|عَلِمَ|form=I}}}} sufkffz3dmoqlfcmeay9xa6t0xds2ej 512423 512421 2026-07-02T05:31:07Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1371263-এর সাথে সংযোগ তৈরি করছি 512423 wikitext text/x-wiki =={{langname|ar}}== ===ক্রিয়া ১=== ====উচ্চারণ==== * {{ar-IPA|عَلِمَ}} ====অর্থ==== {{ar-verb|I/i~a.vn:عِلْم.ap:+}} #জানা {{লে|L1371263|না}} {{লে|L1481818|না}} {{লে|L1220891|না|অর্থ=# {{ar-verbal noun of|عَلِمَ|form=I}}}} 0isscxzwg4r6dvwfk7mb1r4xurn29gf 512428 512423 2026-07-02T05:51:16Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1377914-এর সাথে সংযোগ তৈরি করছি 512428 wikitext text/x-wiki {{লে|L1377914}} {{লে|L1371263|না}} {{লে|L1481818|না}} {{লে|L1220891|না|অর্থ=# {{ar-verbal noun of|عَلِمَ|form=I}}}} a5lqy90m5crof6xog1nnv8xx397ebs5 إن 0 165305 512417 504623 2026-07-02T05:08:59Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1549503-এর সাথে সংযোগ তৈরি করছি 512417 wikitext text/x-wiki {{লে|L1558955}} {{লে|L1549503|না}} isx8dqb4y9x9lt5i1505bkfaib7ltn4 512418 512417 2026-07-02T05:10:38Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1463230-এর সাথে সংযোগ তৈরি করছি 512418 wikitext text/x-wiki {{লে|L1558955}} {{লে|L1549503|না}} {{লে|L1463230|না}} mor6pex13uwebgp11jve0z72keh5ino Nazism 0 167048 512416 506805 2026-07-02T05:07:56Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L448623-এর সাথে সংযোগ তৈরি করছি 512416 wikitext text/x-wiki {{লে|L448623|উচ্চারণ= * {{IPA|en|/ˈnɑːts(i.)ɪzəm/}}}} [[File:Nazi Swastika.svg|thumb|'''নাৎসিবাদ''' এর প্রতীক — লাল পটভূমির ওপর সাদা বৃত্তের মাঝে একটি [[স্বস্তিকা]]]] === বিকল্প রূপ === * {{alter|en|Naziism|Naziïsm|q2=বিরল|nazism}} ==== উদ্ভূত শব্দ ==== {{col|en|Islamonazism|Zionazism}} ==== সংশ্লিষ্ট শব্দাবলী ==== {{col|en |grammar Nazism |Nazi |Nazification |Nazify |Nazist |neo-Nazism |Ukronazism }} === আরও দেখুন === {{col4|en |fascism |militarism }} === অ্যানাগ্রাম === * {{anagrams|en|a=aimnsz|Manzis|Mzansi|nizams}} {{C|en|নাৎসিবাদ}} 6u0m1vznzxm7prhiotfezkd7k9r6ynu أب 0 167205 512442 507589 2026-07-02T06:50:06Z Redmin 6857 /* ব্যুৎপত্তি ১ */ 512442 wikitext text/x-wiki {{also|اب|آب|ات|آپ|آت}} ==আরবি== ===ব্যুৎপত্তি ১=== {{etymon|ar|:inh|sem-pro:*ʔabw-<id:পিতা>|:root|ء ب ও<id:মূল শব্দ>|id=father}} সামীয় আদি-ভাষা (Proto-Semitic) {{inh|ar|sem-pro|*ʔabw-}} থেকে উত্তরাধিকারসূত্রে প্রাপ্ত, যা {{ar-root|ء ب و}} মূল থেকে আগত। হিব্রু {{cog|he|אָב|tr='áv}} এর সাথে সগোত্রীয়। ইতালীয় {{cog|it|babbo}} শব্দের সাথে তুলনা করা যেতে পারে। {{ar-rootbox|ء ب و}} ====উচ্চারণ==== {{ar-IPA|أَب}} ====বিশেষ্য==== {{ar-noun|أَب|m|cons=أَبُو|d=أَبَوَان|pl=آبَاء}} # [[পিতা]], [[বাবা]]। # [[পূর্বপুরুষ]], [[পিতামহ]]। =====ব্যবহারিক নোটসমূহ===== * এই শব্দটির অনিয়মিত সম্বোধন পদ (vocative) হলো {{m|ar|أَبَتَ}} এবং {{m|ar|أَبَتِ}}। =====শব্দরূপ===== {| class="wikitable" |+Declension of noun أَب (ʔab) ! rowspan="2" |singular ! colspan="3" |singular long construct |- !indefinite !definite !construct |- !informal |أَب ʔab |الْأَب al-ʔab |أَبُو ʔabū |- !nominative |أَبٌ ʔabun |الْأَبُ al-ʔabu |أَبُو ʔabū |- !accusative |أَبًا ʔaban |الْأَبَ al-ʔaba |أَبَا ʔabā |- !genitive |أَبٍ ʔabin |الْأَبِ al-ʔabi |أَبِي ʔabī |- !dual !indefinite !definite !construct |- !informal |أَبَوَيْن‎; أَبَيْن ʔabawayn‎; ʔabayn |الْأَبَوَيْن‎; الْأَبَيْن al-ʔabawayn‎; al-ʔabayn |أَبَوَيْ‎; أَبَيْ ʔabaway‎; ʔabay |- !nominative |أَبَوَانِ‎; أَبَانِ ʔabawāni‎; ʔabāni |الْأَبَوَانِ‎; الْأَبَانِ al-ʔabawāni‎; al-ʔabāni |أَبَوَا‎; أَبَا ʔabawā‎; ʔabā |- !accusative |أَبَوَيْنِ‎; أَبَيْنِ ʔabawayni‎; ʔabayni |الْأَبَوَيْنِ‎; الْأَبَيْنِ al-ʔabawayni‎; al-ʔabayni |أَبَوَيْ‎; أَبَيْ ʔabaway‎; ʔabay |- !genitive |أَبَوَيْنِ‎; أَبَيْنِ ʔabawayni‎; ʔabayni |الْأَبَوَيْنِ‎; الْأَبَيْنِ al-ʔabawayni‎; al-ʔabayni |أَبَوَيْ‎; أَبَيْ ʔabaway‎; ʔabay |- ! rowspan="2" |plural ! colspan="3" |basic broken plural triptote |- !indefinite !definite !construct |- !informal |آبَاء ʔābāʔ |الْآبَاء al-ʔābāʔ |آبَاء ʔābāʔ |- !nominative |آبَاءٌ ʔābāʔun |الْآبَاءُ al-ʔābāʔu |آبَاءُ ʔābāʔu |- !accusative |آبَاءً ʔābāʔan |الْآبَاءَ al-ʔābāʔa |آبَاءَ ʔābāʔa |- !genitive |آبَاءٍ ʔābāʔin |الْآبَاءِ al-ʔābāʔi |آبَاءِ ʔābāʔi |} =====সমার্থক শব্দ===== * {{l|ar|وَالِد}} (ওয়ালিদ - জন্মদাতা পিতা) =====সহ-সম্পর্কিত শব্দ===== * {{l|ar|أُمّ}} (উম্ম - মাতা) =====আগত শব্দসমূহ===== * Egyptian Arabic: أبّ (abb) * → Proto-Abkhaz-Abaza: *abá ** Abaza: [[аба]] (aba) ** Abkhaz: [[аб]] (ab) * → Assamese: [[আব্বা]] * → Bengali: [[আব্বা]] * → Urdu: [[ابو]] (abbū) * → Maltese: [[bu]] (“construct state, only used in some surnames and place names”) * → Rohingya: [[abba]] * → Swahili: [[bwana]], (abbreviation) Bw. ** → Chichewa: [[bwana]] ** → English: [[bwana]] * → Ottoman Turkish: [[اب]] (eb) * → Medieval Latin: [[borago]], [[borrago]] ** Italian: [[borragine]], [[borraggine]] ** Old French: [[borage]] *** French: [[bourrache]] *** → English: [[borage]] *** → Irish: [[borráiste]] ** Old Occitan: *** Catalan: [[borratja]] **** → Spanish: [[borraja]] ** Old Galician-Portuguese: *borragẽ *** Galician: [[borraxe]] *** Portuguese: [[borragem]] ** Sicilian: [[vurràjina]] ** → Bulgarian: [[пореч]] (poreč) ** → Middle Dutch: [[borage]] *** Dutch: [[bernagie]] ** → Greek: [[μποράγο]] (borágo) ** → Polish: [[burak]] *** → Belarusian: бура́к (burák) *** → Russian: буря́к (burják) *** → Ukrainian: буря́к (burják) *** → Yiddish: בוריק (burik) ** → Middle Low German: [[boragie]], [[borraghe]] ** → Middle High German: [[boretsch]], [[buretsch]] *** German: [[Borretsch]] ** → Slovak: [[borága]] * ⇒ Arabic: {{l|ar|أَبُو حِبَاب}} (ʔabū ḥibāb, “father of many seeds”) ** → Medieval Latin: [[bahobab]] *** → Armenian: [[բաոբաբ]] (baobab) *** → Danish: [[baobab]] *** → Dutch: [[baobab]] *** → English: [[baobab]] **** → Japanese: [[バオバブ]] (baobabu) **** → Korean: [[바오바브]] (baobabeu) *** → French: [[baobab]] **** Mauritian Creole: [[baobab]] **** → Vietnamese: bao báp *** → Italian: [[baobab]] *** → Polish: [[baobab]] *** → Portuguese: [[baobá]] *** → Russian: [[баобаб]] (baobab) *** → Spanish: [[baobab]] * ⇒ Arabic: {{l|ar|أَبُو المِسْك}} (ʔabū l-misk, “father of musk”) ** → Italian: [[abelmosch]] *** → New Latin: [[abelmoschus]] **** → Dutch: [[abelmos]] **** → English: [[abelmosk]] **** → Portuguese: abelmosco **** → Spanish: abelmosco ***** → Italian: [[abelmosco]] ***** → Norwegian Bokmål: [[abelmoskus]] * ⇒ Arabic: {{l|ar|أَبَوَيْن}} ** → Ottoman Turkish: [[ابوین]] *** Turkish: [[ebeveyn]] ===ব্যুৎপত্তি ২=== ====ক্রিয়া==== # '''{{l|ar|آبَ}}'''-এর [[মধ্যম পুরুষ]] [[পুংলিঙ্গ]] [[একবচন]] [[অনুজ্ঞাসূচক]] ===ব্যুৎপত্তি ৩=== {{ar-rootbox|ء ب ب}} ====ক্রিয়া==== # তলোয়ার বা কোনো কিছুর ওপর হাত রাখা। # [[নাড়া দেওয়া]], [[আলোড়িত করা]]। # স্বদেশের জন্য [[ব্যাকুল হওয়া]]। # ভ্রমণের জন্য [[প্রস্তুত হওয়া]]। # [[সংকল্প করা]]। # সোজা বা সৎ হওয়া। ====বিশেষ্য==== {{ar-noun|أَبّ|m|pl=أَؤُبّ}} # [[সংকল্প]] বা [[উদ্দেশ্য]]। # ভ্রমণের [[পরিকল্পনা]]। # [[চারাপুঞ্জ]], [[ঘাস]], [[তৃণভূমি]]। # চারণভূমির জন্য প্রস্তুত তৃণ। # [[শুকনো ফল]]। ==মিশরীয় আরবি== ===বিশেষ্য=== {{arz-noun|head=أبّ|tr=abb|g=m|cons=أبو|constr=abū|pl=أبّهات|pltr=abbahāt}} # {{altsp|arz|ابّ}} (পিতা/বাবা) ==উত্তর লেভান্তীয় আরবি== ===বিশেষ্য=== {{apc-noun|g=m|tr=ʔabb|cons=أبو|constr=ʔabu|pl=أبات|pltr=ʔabbāt|pl2=أبهات|pl2tr=ʔabbahāt}} # {{lb|apc|সিরিয়া}} [[বাবা]] বা [[পিতা]]। #: {{syn|apc|بي|tr=bayy}} (লেবানীয়) ==দক্ষিণ লেভান্তীয় আরবি== ===বিশেষ্য=== {{ajp-noun|head=أبّ|g=m|tr=ʔabb|cons=أبو|constr=ʔabu|pl=أبّهات|pltr=ʔabbahāt}} # {{alternative form of|ajp|أبو|tr=ʔabu|t=বাবা}} 1yt9r5vb88nsafmcbfrwl2lx2ai5gm1 أعلم 0 167859 512425 508714 2026-07-02T05:41:47Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1477948-এর সাথে সংযোগ তৈরি করছি 512425 wikitext text/x-wiki {{লে|L1477328}} {{লে|L1477948|না}} kposxiii1kjlpikj72rsijw2z6f4jkc fascism 0 170160 512405 2026-07-02T04:52:40Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L82651-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512405 wikitext text/x-wiki {{লে|L82651}} d6phbev56gwgy5lrsg04ztggyjb16gt fascismo 0 170161 512406 2026-07-02T04:53:00Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1157230-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512406 wikitext text/x-wiki {{লে|L1157230}} 2ot49kjqza895qorr9dibfnf652n5sg extremism 0 170162 512407 2026-07-02T04:53:10Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L320402-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512407 wikitext text/x-wiki {{লে|L320402}} lou8231fuk7bfofyh8xusrqchxrzr38 nazism 0 170163 512408 2026-07-02T04:55:03Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1123940-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512408 wikitext text/x-wiki {{লে|L1123940}} 38sh925t73bnstpto789gnqtsz967rl nazisme 0 170164 512409 2026-07-02T04:55:11Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1267024-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512409 wikitext text/x-wiki {{লে|L1267024}} ffb2opydnafix1e5vfjx6n35fa4my5a 512410 512409 2026-07-02T04:55:44Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L646527-এর সাথে সংযোগ তৈরি করছি 512410 wikitext text/x-wiki {{লে|L1267024}} {{লে|L646527}} h7pgqjlsca5px8m1kglkj318fxnb3cq 512413 512410 2026-07-02T04:57:27Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1462594-এর সাথে সংযোগ তৈরি করছি 512413 wikitext text/x-wiki {{লে|L1267024}} {{লে|L646527}} {{লে|L1462594}} gm5jbscvnlzv0fi29zqaxcbnlwb4kr0 nazismo 0 170165 512411 2026-07-02T04:56:22Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1167800-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512411 wikitext text/x-wiki {{লে|L1167800}} ggy0nqt86admkojiikwbmbd1sjz88oo 512412 512411 2026-07-02T04:56:57Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L658711-এর সাথে সংযোগ তৈরি করছি 512412 wikitext text/x-wiki {{লে|L1167800}} {{লে|L658711}} q9laf1i9q7y6ngvtve7muzz6vgk7t03 512414 512412 2026-07-02T05:00:30Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L234064-এর সাথে সংযোগ তৈরি করছি 512414 wikitext text/x-wiki {{লে|L1167800}} {{লে|L658711}} {{লে|L234064}} 6prexnykngv0qzxxqbw7cnq4jgbj8km 512415 512414 2026-07-02T05:00:51Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L989301-এর সাথে সংযোগ তৈরি করছি 512415 wikitext text/x-wiki {{লে|L1167800}} {{লে|L658711}} {{লে|L989301}} ifx45gvp5he4bpess0diqfoyvzvtynp ط غ ي 0 170166 512419 2026-07-02T05:10:55Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1468113-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512419 wikitext text/x-wiki {{লে|L1468113}} 5xtbvgx1odh07nz91zcvdbijiyi3yar аб 0 170167 512438 2026-07-02T06:34:48Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1010817-এর জন্য একটি নতুন ভুক্তি তৈরি করছি 512438 wikitext text/x-wiki {{লে|L1010817}} p153bov59slgvzw9dh62bvykersvb7y 512439 512438 2026-07-02T06:35:09Z Redmin 6857 লেক্সিম লিংকার এক্সটেনশনের সাহায্যে উইকিউপাত্ত লেক্সিম L1546932-এর সাথে সংযোগ তৈরি করছি 512439 wikitext text/x-wiki {{লে|L1010817}} {{লে|L1546932|না}} 6gyi11p1mtp9vvp8wl6h4gik4zdxjrl