text:
Module:User:Benwing2/quote

--[=[	This module contains functions to implement quote-* templates.

Author: Benwing2; conversion into Lua of template, written by Sgconlaw with some help from Erutuon and Benwing2.

The main interface is quote_t. Note that the source display is handled by source, which reads both the arguments passed to it *and* the arguments passed to the parent template, with the former overriding the latter. ]=]

local export = {}

-- Named constants for all modules used, to make it easier to swap out sandbox versions. local check_isxn_module = "Module:check isxn" local debug_track_module = "Module:debug/track" local italics_module = "Module:italics" local languages_module = "Module:languages" local links_module = "Module:links" local number_utilities_module = "Module:number-utilities" local parameters_module = "Module:parameters" local parse_utilities_module = "Module:User:Benwing2/parse utilities" local roman_numerals_module = "Module:roman numerals" local script_utilities_module = "Module:script utilities" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local usex_module = "Module:usex" local usex_templates_module = "Module:usex/templates" local utilities_module = "Module:utilities" local yesno_module = "Module:yesno"

local rsubn = mw.ustring.gsub local rmatch = mw.ustring.match local rfind = mw.ustring.find local rsplit = mw.text.split local rgsplit = mw.text.gsplit local ulen = mw.ustring.len local usub = mw.ustring.sub

-- Use HTML entities here to avoid parsing issues (esp. with brackets) local SEMICOLON_SPACE = "; " local SPACE_LBRAC = " [" local RBRAC = "]"

local function track(page) require(debug_track_module)("quote/" .. page) return true end

-- version of rsubn that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end

local function maintenance_line(text) return "(" .. text .. ") " end

local function isbn(text) return "→ISBN" .. require(check_isxn_module).check_isbn(text, " Invalid ISBN ") end

local function issn(text) return "[https://www.worldcat.org/issn/" .. text .. " →ISSN]" .. require(check_isxn_module).check_issn(text, " Invalid ISSN ") end

local function lccn(text) local origtext = text text = rsub(text, " ", "") if rfind(text, "%-") then -- old-style LCCN; reformat per request by User:The Editor's Apprentice local prefix, part1, part2 = rmatch(text, "^(.-)([0-9]+)%-([0-9]+)$") if prefix then if ulen(part2) < 6 then part2 = ("0"):rep(6 - ulen(part2)) .. part2 end text = prefix .. part1 .. part2 end end return "[https://lccn.loc.gov/" .. mw.uri.encode(text) .. " →LCCN]" end

local function format_date(text) return mw.getCurrentFrame:callParserFunction{name="#formatdate", args=text} end

local function tag_nowiki(text) return mw.getCurrentFrame:callParserFunction{name="#tag", args={"nowiki", text}} end

-- Convert a comma-separated list of language codes to a comma-separated list of language names. `paramname` is the -- name of the parameter from which the list of language codes was fetched. local function format_langs(langs, paramname) langs = rsplit(langs, ",") for i, langcode in ipairs(langs) do		local lang = require(languages_module).getByCode(langcode, paramname) langs[i] = lang:getCanonicalName end if #langs == 1 then return langs[1] else return require(table_module).serialCommaJoin(langs) end end

local param_mods = { t = { --  and  are aliases. item_dest = "gloss", },	gloss = {}, tr = {}, ts = {}, sc = { convert = function(arg, parse_err) return require(scripts_module).getByCode(arg, parse_err) end, } }

-- Parse a text property that may be in a foreign language or script. `val` is the value of the parameter and -- `paramname` is the name of the parameter from which the value was retrieved. `explicit_gloss`, if specified and -- non-nil, overrides any gloss specified using the  or  inline modifier. -- -- If `val` is nil, the return value of this function is nil. Otherwise it is parsed for a language prefix (e.g. -- 'ar:مُؤَلِّف') and inline modifiers (e.g. 'ar:مُؤَلِّف'), and the return value is an object with the following -- fields: --  `text`: The text after stripping off any language prefix and inline modifiers. --  `lang`: The language object corresponding to the language prefix, if specified, or nil if no language prefix is --           given. --  `sc`: The script object corresponding to the  modifier, if given; otherwise nil. --  `tr`: The transliteration corresponding to the  modifier, if given; otherwise nil. --  `ts`: The transcription corresponding to the  modifier, if given; otherwise nil. --  `gloss`: The gloss/translation corresponding to the `explicit_gloss` parameter (if given and non-nil), otherwise --           the  or  modifiers if given, otherwise nil. -- -- Note that as a special case, if `val` contains HTML tags at the top level (e.g. ' ... ', as -- might be generated by specifying مُؤَلِّف), no language prefix or inline modifiers are parsed, and the return -- value has the `noscript` field set to true, which tells format_text not to try to identify the script of the text -- and CSS-tag the text accordingly, but to leave the text untagged. -- -- This object can be passed to format_text to format a string displaying the text (appropriately script-tagged, -- unless `noscript` is set, as described above) and modifiers. local function parse_text_with_lang(val, paramname, explicit_gloss) if not val then return nil end -- Check for inline modifier, e.g. מרים. But exclude HTML entry with, , or -- similar in it, caused by wrapping an argument in, or similar. Basically, all tags of the -- sort we parse here should consist of a less-than sign, plus letters, plus a colon, e.g. , so if we see a	-- tag on the outer level that isn't in this format, we don't try to parse it. The restriction to the outer level is -- to allow generated HTML inside of e.g. qualifier modifiers, such as foo<q:similar to > (if we end up	-- supporting such modifiers). If we find a parameter value with top-level HTML in it, add 'noscript = true' to -- indicate that we should not try to do script inference and tagging. (Otherwise, e.g. if you specify	-- مُؤَلِّف as the author, you'll get an extra big font coming from the fact that wraps the	-- Arabic text in CSS that increases the size from the default, and then we do script detection and again wrap the	-- text in the same CSS, which increases the size even more.) --	-- Also exclude things that look like URL's from being parsed as having language code prefixes. if val:find("^[^<]*<[a-z]*[^a-z:]") or val:find("^[a-z]+://") then return {text = val, noscript = true} end

local function generate_obj(text, parse_err_or_paramname) local obj = {} if text:find(":[^ ]") then local actual_text, textlang = require(parse_utilities_module).parse_term_with_lang(text, parse_err_or_paramname) obj.text = actual_text obj.lang = textlang else obj.text = text end return obj end

local obj if val:find("<") then -- Check for inline modifier. obj = require(parse_utilities_module).parse_inline_modifiers(val, {			paramname = paramname,			param_mods = param_mods,			generate_obj = generate_obj,		}) else obj = generate_obj(val, paramname) end

if explicit_gloss then obj.gloss = explicit_gloss end

return obj end

-- Format a text property that may be in a foreign language or script, along with annotations. This is conceptually -- similar to the full_link function in Module:links, but displays the annotations in a different format that is -- more appropriate for bibliographic entries. The output looks like this: -- -- TEXT [TRANSLIT /TRANSCRIPTION/, GLOSS] -- -- `textobj` is as returned by `parse_text_with_lang`. `tag_text`, if supplied, is a function of one argument to further -- wrap the text after it has been processed and CSS-tagged appropriately, directly before insertion. `tag_gloss` is a -- similar function for the gloss. local function format_text(textobj, tag_text, tag_gloss) if not textobj then return nil end local text = textobj.text local tr, ts, gloss = textobj.tr, textobj.ts, textobj.gloss

-- See above for `noscript`, meaning HTML was found in the text value, probably generated using. -- already script-tags the text and processes embedded language links, so we don't want to do it again (in	-- fact, the code below within the if-clause is similar to what  does). In such a case, an explicit language -- won't be available and findBestScriptWithoutLang may not be accurate, so we can't do automatic transliteration. if not textobj.noscript then local lang = textobj.lang -- As an optimization, don't do script detection on an argument that contains only ASCII. local sc = textobj.sc or lang and lang:findBestScript(text) or not text:find("^[ -~]$") and require(scripts_module).findBestScriptWithoutLang(text) or nil -- As an optimization, don't do any of the following if there's no language, script, translit or transcription, -- as will be the case with simple ASCII values. if lang or sc or tr or ts then lang = lang or require(languages_module).getByCode("und", true)

if tr == "-" then tr = nil elseif not tr and sc and not sc:getCode:find("Latn") then -- Latn, Latnx or a lang-specific variant -- might return nil tr = (lang:transliterate(require(links_module).remove_links(text), sc)) end

text = require(links_module).embedded_language_links(				{					term = text,					lang = lang,					sc = sc				},				false			) if lang:getCode ~= "und" or sc:getCode ~= "Latn" then text = require(script_utilities_module).tag_text(text, lang, sc) end

if tr then -- Should we link to the transliteration of languages with lang:link_tr? Probably not because `text` is not -- likely to be a term that has an entry. tr = require(script_utilities_module).tag_translit(tr, lang, "usex") end if ts then ts = require(script_utilities_module).tag_transcription(ts, lang, "usex") end end end

text = require(italics_module).unitalicize_brackets(text) if tag_text then text = tag_text(text) end

local parts = {} local function ins(txt) table.insert(parts, txt) end

ins(text)

if tr or ts or gloss then ins(SPACE_LBRAC) if tr then ins(tr) end if ts then if tr then ins(" ") end ins("/" .. ts .. "/") end if gloss then if tr or ts then ins(", ") end gloss = ' ' .. gloss .. " "			gloss = require(italics_module).unitalicize_brackets(gloss) if tag_gloss then gloss = tag_gloss(gloss) end ins(gloss) end ins(RBRAC) end

return table.concat(parts) end

-- Fancy version of ine (if-not-empty). Converts empty string to nil, but also strips leading/trailing space. local function ine(arg) if not arg then return nil end arg = mw.text.trim(arg) if arg == "" then return nil end return arg end

-- Clone and combine frame's and parent's args while also assigning nil to empty strings. Handle aliases and ignores. local function clone_args(direct_args, parent_args) local args = {}

-- Processing parent args must come first so that direct args override parent args. Note that if a direct arg is -- specified but is blank, it will still override the parent arg (with nil). for pname, param in pairs(parent_args) do		-- Special:WhatLinksHere/Wiktionary:Tracking/quote/param/PARAM track("param/" .. pname) args[pname] = ine(param) end

-- Process ignores. The value of `ignore` is a comma-separated list of parameter names to ignore (erase). We need to	-- do this before aliases due to, which sets chapter= to the value of title= in the direct params and -- sets title= to the value of album= using an alias. If we do the ignores after aliases, we get an error during alias -- processing, saying that title= and its alias album= are both present. local ignores = ine(direct_args.ignore) if ignores then for ignore in rgsplit(ignores, "%s*,%s*") do			args[ignore] = nil end end

-- Process aliases. The value of `alias` is a list of semicolon-separated specs, each of which is of the form -- DEST:SOURCE,SOURCE,... where DEST is the canonical name of a parameter and SOURCE refers to an alias. Whitespace -- is allowed between all delimiters. The order of aliases may be important. Ffor example, for , -- title= contains the article name and is an alias of underlying chapter=, while journal= or work= contains the -- journal name and is an alias of underlying title=. As a result, the title -> chapter alias must be specified -- before the journal/work -> title alias. --	-- Whenever we copy a value from argument SOURCE to argument DEST, we record an entry for the pair in alias_map, so -- that when we would display an error message about DEST, we display SOURCE instead. --	-- Do alias processing (and ignore and error_if processing) before processing direct_args so that e.g. we can set up -- an alias of title -> chapter and then set title= to something else in the direct args ( does this). local aliases = ine(direct_args.alias) local alias_map = {} if aliases then -- Allow and discard a trailing semicolon, to make managing multiple aliases easier. aliases = rsub(aliases, "%s*;$", "") for alias_spec in rgsplit(aliases, "%s*;%s*") do			local alias_spec_parts = rsplit(alias_spec, "%s*:%s*") if #alias_spec_parts ~= 2 then error(("Alias spec '%s' should have one colon in it"):format(alias_spec)) end local dest, sources = unpack(alias_spec_parts) sources = rsplit(sources, "%s*,%s*") saw_source = nil for _, source in ipairs(sources) do				if args[source] then if saw_source == nil then saw_source = source else error(("|%s= and |%s= are aliases; cannot specify a value for both"):format(saw_source, source)) end end end if saw_source then if args[dest] then error(("|%s= is an alias of |%s=; cannot specify a value for both"):format(saw_source, dest)) end args[dest] = args[saw_source] -- Wipe out the original after copying. This important in case of a param that has general significance -- but has been redefined (e.g. redefines number= for the episode number, and				--  redefines title= for the chapter= (article). It's also important once we implement				-- unhandled parameter checking.				args[saw_source] = nil				alias_map[dest] = saw_source			end		end	end

-- Process error_if. The value of `error_if` is a comma-separated list of parameter names to throw an error if seen -- in parent_args (they are params we overwrite in the direct args). local error_ifs = ine(direct_args.error_if) if error_ifs then for error_if in rgsplit(error_ifs, "%s*,%s*") do			if ine(parent_args[error_if]) then error(("Cannot specify a value |%s=%s as it would be overwritten or ignored"):format(error_if, ine(parent_args[error_if]))) end end end

for pname, param in pairs(direct_args) do		args[pname] = ine(param) end

return args, alias_map end

local function format_date_with_code(code, timestamp) local language = mw.getContentLanguage local ok, date = pcall(language.formatDate, language, code, timestamp) if ok then return date else -- All the formats used in format_date_args are fine, so the timestamp must be at fault. error("Timestamp '" .. tostring(timestamp) .. "' could not be parsed; "			.. "see the documentation for the #time parser function).")	end end

-- Try to figure out if the given timestamp has the day of the month explicitly given. We use the following algorithm: -- 1. Format as year-month-day; if the day is not 1, the day was explicitly given, since if only the year/month are --   given, the day shows up as 1. -- 2. If the day shows up as 1 and there isn't a 1 or 01 in the timestamp, the day wasn't explicitly given. -- 3. Otherwise, if there are three separate numbers (e.g. 2022-07-01), or two separate numbers plus a capitalized --   letter (taken as an English month, e.g. 2022 July 1), the day was explicitly given, otherwise not. local function date_has_day_specified(timestamp) local day = format_date_with_code("j", timestamp) if day ~= "1" then return true end local english_month = timestamp:find("[A-Z]") local canon_timestamp = mw.text.trim((timestamp:gsub("[^0-9]+", " "))) local seen_nums = rsplit(canon_timestamp, " ") local saw_one = false for _, num in ipairs(seen_nums) do		if num == "1" or num == "01" then saw_one = true break end end if not saw_one then return false end return #seen_nums >= 3 or english_month and #seen_nums >= 2 end

local abbrs = { ["a."] = { anchor = "a.", full = "ante", }, ["c."] = { anchor = "c.", full = "circa", }, ["p."] = { anchor = "p.", full = "post", }, }

local function process_ante_circa_post(date) local prefix = usub(date, 1, 2) local abbr = abbrs[prefix] local abbr_prefix = ""

if abbr then abbr_prefix = "<abbr title="' .. abbr.full .. '">' ..			abbr.anchor .. "  " -- Remove lowercase letter, period, and space from beginning of date parameter. date = rsub(date, "^%l%.%s*", "") end

return abbr_prefix, date end

-- Format the arguments that specify the date of the quotation. These include the following: -- |date=: The date. If |start_date= is given, this is the end date. -- |year=, |month=: Year and month of quotation date or end of range, if |date= isn't given. -- |start_date=: The start date, to specify a range. -- |start_year=, |start_month=: Year and month of start of range, if |start_date= isn't given. -- |accessdate=: Date a website was accessed; processed if no other date was given. -- |nodate=: Indicate that no date is present; otherwise a maintenance line will be displayed if there is no date. -- -- If `parampref` and/or `paramsuf` are given, this modifies all the date arguments accordingly. For example, if -- `parampref` == "orig" and `paramsuf` is omitted, the date is specified using |origdate= or |origyear=/|origmonth=, -- and the start of the range is |origstart_date=, etc. Similarly, if `parampref` is omitted and `paramsuf` is -- "_published", the date is specified using |date_published= or |year_published=/|month_published=, and the start of -- the range is |start_date_published=, etc. -- -- `a` and `get_full_paramname` are functions with the same interpretation as the local functions of the same name in -- source. These are used to fetch parameters and get their full names. Note that this may cause all arguments to -- have an index added to them (|date2=, |year2=, |month2=, etc.). -- -- `alias_map` is as in source and is used to map canonical arguments to their aliases when aliases were used. -- -- If `bold_year` is given, displayed years are boldfaced unless boldface is present in the parameter value. -- -- If `maintenance_line_no_date` is specified, it should be a string that will be returned if no date is found (i.e. -- neither |date= nor |year=, or their appropriate equivalents per `parampref` and `paramsuf`, are specified, and -- neither |nodate= is given to indicate that there is no date, or |accessdate= is given). -- -- Returns two values: the formatted date and a boolean indicating whether to add a maintenance category -- Category:Requests for date in LANG entries. The return value can be nil if `maintenance_line_no_date` is not -- given (in which case the scond return value will always be nil). local function format_date_args(a, get_full_paramname, alias_map, parampref, paramsuf, bold_year,	maintenance_line_no_date) local output = {}

parampref = parampref or "" paramsuf = paramsuf or "" local function getp(param) return a(parampref .. param .. paramsuf) end local function pname(param) local fullname = get_full_paramname(parampref .. param .. paramsuf) return alias_map[fullname] or fullname end

local function ins(text) table.insert(output, text) end

local function format_bold_date(date, explicit_day) local month_day_code = explicit_day and "F j" or "F" if bold_year then -- This formats like "2023 August 3" (or "2023 August" if day not explicitly given). return format_date_with_code("Y " .. month_day_code, date) else -- This formats like "2023 August 3" (or "2023 August" if day not explicitly given). return format_date_with_code("Y " .. month_day_code, date) end end

local function boldface_if_not_already(year) if not bold_year or year:find("'''") then return year else return "'''" .. year .. "'''"		end end

-- The formatDate method of the mw.language object behaves like the parser function, which doesn't	-- accept the formats "monthday monthname, year" or "year monthname monthday", but outputs garbage when it receives -- them, behavior inherited from PHP. magic word is more forgiving. Fix dates so that, for -- instance, the |date= parameter of (which uses this code) and the |accessdate= parameter (which	-- uses ) accept similar date formats. See: -- * mw:Extension:Scribunto/Lua_reference_manual -- * mw:Help:Extension:ParserFunctions -- * mw:Help:Magic_words local function fix_date(date) if tonumber(date) ~= nil then error(("|%s= should contain a full date (year, month, day of month); use |%s= for year"):				format(pname("date"), pname("year"))) elseif date and date:find "%s*%a+,%s*%d+%s*$" then error(("|%s= should contain a full date (year, month, day of month); use |%s=, |%s= for month and year"):				format(pname("date"), pname("month"), pname("year"))) end if date then date = rsub(date, "(%d+ %a+),", "%1") date = rsub(date, "^(%d%d%d%d) (%a+ %d%d?)$", "%2 %1") return date end end

local start_date, date = fix_date(getp("start_date")), fix_date(getp("date")) local year = getp("year") local month = getp("month") local start_year = getp("start_year") local start_month = getp("start_month")

if date and year then error(("Only one of |%s= or |%s= should be specified"):format(pname("date"), pname("year"))) end if date and month then error(("|%s= should only be specified in conjunction with |%s=, not with |%s="):			format(pname("month"), pname("year"), pname("date"))) end if start_date and start_year then error(("Only one of |%s= or |%s= should be specified"):format(pname("start_date"), pname("start_year"))) end if start_date and start_month then error(("|%s= should only be specified in conjunction with |%s=, not with |%="):			format(pname("start_month"), pname("start_year"), pname("start_date"))) end if (start_date or start_year) and not (date or year) then error(("|%s= or |%s=/|%s= cannot be specified without specifying |%s= or |%s=/|%s="):			format(pname("start_date"), pname("start_year"), pname("start_month"), pname("date"), pname("year"), pname("month"))) end

local dash = " – "

local day_explicitly_given = date and date_has_day_specified(date) local start_day_explicitly_given = start_date and date_has_day_specified(start_date)

local function format_date_or_year_month(date, year, month, explicit_day) if date then return format_bold_date(date, explicit_day) else return boldface_if_not_already(year) .. (month and " " .. month or "") end end

if year then local abbr_prefix abbr_prefix, year = process_ante_circa_post(year) ins(abbr_prefix) end

if start_date or start_year then ins(format_date_or_year_month(start_date, start_year, start_month, start_day_explicitly_given)) local cur_year = year or format_date_with_code("Y", date) local cur_month = month or date and format_date_with_code("F", date) or nil local cur_day = date and day_explicitly_given and format_date_with_code("j", date) or nil local beg_year = start_year or format_date_with_code("Y", start_date) local beg_month = start_month or start_date and format_date_with_code("F", start_date) or nil local beg_day = start_date and start_day_explicitly_given and format_date_with_code("j", start_date) or nil

if cur_year ~= beg_year then -- Different years; insert current date in full. ins(dash) ins(format_date_or_year_month(date, year, month)) elseif cur_month and cur_month ~= beg_month then -- Same year but different months; insert current month and (if available) current day. ins(dash) ins(cur_month) if cur_day then ins(" " .. cur_day) end elseif cur_day and cur_day ~= beg_day then -- Same year and month but different days; insert current day. ins(dash) ins(" " .. cur_day) else -- Same year, month and day; or same year and month, and day not available; or same year, and month and -- day not available. Do nothing. FIXME: Should we throw an error? end elseif date or year then ins(format_date_or_year_month(date, year, month, day_explicitly_given)) elseif not maintenance_line_no_date then -- Not main quote date. Return nil, caller will handle. return nil, nil elseif not getp("nodate") then local accessdate = getp("accessdate") if accessdate then local explicit_day = date_has_day_specified(accessdate) ins(format_bold_date(accessdate, explicit_day) .. " (last accessed)") else if mw.title.getCurrentTitle.nsText ~= "Template" then return maintenance_line(maintenance_line_no_date), true else return "", nil end end end

return table.concat(output), nil end

local function tag_with_cite(txt) return " " .. txt .. " " end

local function pluralize(txt) -- Try to shortcut loading Module:string utilities. if txt:find("[sxzhy%]]$") then return require(string_utilities_module).pluralize(txt) else return txt .. "s" end end

-- Display the source line of the quote, above the actual quote text. This contains the majority of the logic of this -- module (formerly contained in ). function export.source(args, alias_map) local tracking_categories = {}

local argslang = args.lang or args[1] if not argslang then -- For the moment, only trigger an error on mainspace pages and -- other pages that are not user pages or pages containing discussions. -- These are the same pages that appear in the appropriate tracking -- categories. User and discussion pages have not generally been -- fixed up to include a language code and so it's more helpful -- to use a maintenance line than signal an error. local FULLPAGENAME = mw.title.getCurrentTitle.fullText local NAMESPACE = mw.title.getCurrentTitle.nsText

if NAMESPACE ~= "Template" and not require(usex_templates_module).page_should_be_ignored(FULLPAGENAME) then require(languages_module).err(nil, 1) end end

-- Given a canonical param, convert it to the original parameter specified by the user (which may have been an	-- alias). local function alias(param) return alias_map[param] or param end

local output = {} -- Add text to the output. The text goes into a list, and we concatenate -- all the list components together at the end. local function add(text) table.insert(output, text) end if args.brackets then add("[") end

-- Return a function that generates the actual parameter name associated with a base param (e.g. "author", "last"). -- The actual parameter name may have an index added (an empty string for the first set of params, e.g. author=,	-- last=, or a numeric index for further sets of params, e.g. author2=, last2=, etc.). local function make_get_full_paramname(ind) return function(param) return param .. ind end end -- Function to fetch the actual parameter name associated with a base param (see make_get_full_paramname above). -- Assigned at various times below by calling make_get_full_paramname. We do it this way so that we can have -- wrapper functions that access params and define them only oncec. local get_full_paramname -- Return two values: the value of a parameter given the base param name (which may have a numeric index added), -- and the parameter name from which the value was fetched (which may be an alias, i.e. you can't necessarily fetch	-- the parameter value from args[] given this name). The base parameter can be a list of such base params, which -- are checked in turn. local function a_with_name(param) if type(param) == "table" then for _, par in ipairs(param) do				local val, name = a_with_name(par) if val then return val, name end end return nil end local fullname = get_full_paramname(param) return args[fullname], alias(fullname) end -- Fetch the value of a parameter given the base param name (which may have a numeric index added). The base -- parameter can be a list of such base params, which are checked in turn. local function a(param) return (a_with_name(param)) end

-- Identical to a_with_name(param) except that it verifies that no space is present. Should be used for URL's.	local function aurl_with_name(param) local value, fullname = a_with_name(param) if value and value:find(" ") and not value:find("%[") then error(("URL not allowed to contain a space, but saw |%s=%s"):format(fullname, value)) end return value, fullname end -- Identical to a(param) except that it verifies that no space is present. Should be used for URL's.	local function aurl(param) return (aurl_with_name(param)) end

-- Convenience function to fetch a parameter that may be in a foreign language or text (and may consequently have	-- a language prefix and/or inline modifiers), parse the modifiers and convert the result into a formatted string. -- This is the same as parse_and_format_text below but also returns the param name as the second return value -- and the raw param value (as directly specified by the user, after stripping off inline modifiers and language	-- prefix) as the third return value. local function parse_and_format_text_with_name(param, tag_text, tag_gloss) local paramval, paramname = a_with_name(param) local obj = parse_text_with_lang(paramval, paramname) return format_text(obj, tag_text, tag_gloss), paramname, obj and obj.text or nil end

-- Convenience function to fetch a parameter that may be in a foreign language or text (and may consequently have	-- a language prefix and/or inline modifiers), parse the modifiers and convert the result into a formatted string. -- This is a wrapper around parse_text_with_lang and format_text. `param` is the base parameter name (see	-- a_with_name), `tag_text` is an optional function to tag the parameter text after all other processing (e.g.	-- wrap in ... tags), and `tag_gloss` is a similar function for the parameter translation/gloss. local function parse_and_format_text(param, tag_text, tag_gloss) return (parse_and_format_text_with_name(param, tag_text, tag_gloss)) end

-- Set this now so a works just below. get_full_paramname = make_get_full_paramname("")

local formatted_date, need_date = format_date_args(a, get_full_paramname, alias_map, nil, nil, "bold year",		"Can we date this quote?") add(formatted_date)

-- Fetch origdate=/origyear=/origmonth= and format appropriately. local formatted_origdate = format_date_args(a, get_full_paramname, alias_map, "orig") if formatted_origdate then add(SPACE_LBRAC .. formatted_origdate .. RBRAC) end

if args.author or args.last or args.quotee then -- Find maximum indexed author or last name. local maxind = 0 for arg, _ in pairs(args) do			local argbase, argind = rmatch(arg, "^([a-z]+)([0-9]*)$") if argbase == "author" or argbase == "last" then argind = argind == "" and 1 or tonumber(argind) if argind > maxind then maxind = argind end end end

for i = 1, maxind do			local ind = i == 1 and "" or i			get_full_paramname = make_get_full_paramname(ind) local author, author_param = a_with_name("author") local last = a("last") local first = a("first") if author or last then -- If first author, output a comma unless used. if i == 1 and not args.nodate then add(", ") end -- If not first author, output a semicolon to separate from preceding authors. add(i == 1 and " " or SEMICOLON_SPACE) local function make_author_with_url(txt, authorlink) if authorlink then return "" .. txt .. "" else return txt end end local authorlink = a("authorlink") local authorlink_gloss = a("trans-authorlink") if author then local authorobj = parse_text_with_lang(author, author_param, a("trans-author")) authorobj.text = make_author_with_url(authorobj.text, authorlink) if authorobj.gloss and authorlink_gloss then authorobj.gloss = make_author_with_url(authorobj.gloss, authorlink_gloss) end add(format_text(authorobj)) else -- Author separated into first name + last name. We don't currently support non-Latin-script -- authors separated this way and probably never will. local first = a("first") if first then author = first .. " " .. last else author = last end author = make_author_with_url(author, authorlink) local last_gloss = a("trans-last") local author_gloss if last_gloss then local first_gloss = a("trans-first") if first_gloss then author_gloss = first_gloss .. " " .. last_gloss else author_gloss = last_gloss end author_gloss = make_author_with_url(author_gloss, authorlink_gloss) end add(author) if author_gloss then add(SPACE_LBRAC) add(author_gloss) add(RBRAC) end end end end if args.coauthors or args.quotee then -- Need to set this. It's accessed (indirectly) by parse_and_format_text, and will have the wrong value -- as a result of the 1, maxind loop above. get_full_paramname = make_get_full_paramname("") if args.coauthors then add(SEMICOLON_SPACE .. parse_and_format_text("coauthors")) end if args.quotee then add(", quoting " .. parse_and_format_text("quotee")) end end add(",") elseif args.year or args.date or args.start_year or args.start_date then --If no author stated but date provided, add a comma. add(",") end add(" ")

local function has_new_title_or_ancillary_author return args.chapter2 or args.title2 or			args.tlr2 or args.translator2 or args.translators2 or			args.mainauthor2 or args.editor2 or args.editors2 end

local function has_new_title_or_author return args["2ndauthor"] or args["2ndlast"] or has_new_title_or_ancillary_author end

local function has_newversion return args.newversion or args.location2 or has_new_title_or_author end

-- Handle chapter=, section=, etc. `param` is the base name of the parameter in question, e.g. "chapter" or -- "section". If numeric (either Arabic or Roman), add `numeric_prefix`; otherwise, parse as textual (allowing for	-- language prefixes, inline modifiers, etc.), prefix with `textual_prefix` (if given) and suffix with -- `textual_suffix` (if given). Also checks for and handles the following (assuming param == "chapter"): -- * chapterurl=: URL of the chapter. -- * trans-chapter=: Chapter translation (can be given using an inline modifier <t:...>). -- * chapter_number=: Chapter number, when chapter= is also given (otherwise put the chapter number in chapter=). -- * chapter_plain=: Plain version of the chapter number; the "chapter " prefix isn't added. -- * chapter_series=: Series that the chapter is within (used e.g. for journal articles part of a series). -- * chapter_seriesvolume=: Volume of the series (compare seriesvolume=). --	-- Returns nil if no value specified for the main parameter, otherwise the formatted value. local function format_chapterlike(param, numeric_prefix, textual_prefix, textual_suffix) local chap, chap_param = a_with_name(param) local chap_num, chap_num_param = a_with_name(param .. "_number") local chap_plain, chap_plain_param = parse_and_format_text_with_name(param .. "_plain") if chap_num and chap_plain then error(("Specify only one of |%s= or %s="):format(chap_num_param, chap_plain_param)) end local chap_series, chap_series_param = parse_and_format_text_with_name(param .. "_series", tag_with_cite, tag_with_cite) local chap_seriesvolume, chap_seriesvolume_param = parse_and_format_text_with_name(param .. "_seriesvolume") if chap_series then chap_series = ", " .. chap_series end if chap_seriesvolume then if not chap_series then error(("Cannot specify |%s= without %s="):format(chap_series_param, chap_seriesvolume_param)) end chap_series = chap_series .. " (" .. chap_seriesvolume .. ")" end

if not chap then if chap_num then error(("Cannot specify |%s= without |%s=; put the numeric value in |%s= directly"):					format(chap_num_param, chap_param, chap_param)) end if chap_plain then return chap_plain .. (chap_series or "") end return nil end

local cleaned_chap = chap:gsub("[^<>]*", ""):gsub("[*+#]", "") local chapterurl = aurl(param .. "url") local function make_chapter_with_url(chap) if chapterurl then return "[" .. chapterurl .. " " .. chap .. "]"			else return chap end end

local formatted

if require(number_utilities_module).get_number(cleaned_chap) then -- Arabic chapter number formatted = numeric_prefix .. make_chapter_with_url(chap) elseif rfind(cleaned_chap, "^[mdclxviMDCLXVI]+$") and require(roman_numerals_module).roman_to_arabic(cleaned_chap, true) then -- Roman chapter number formatted = numeric_prefix .. make_chapter_with_url(mw.ustring.upper(chap)) else -- Must be a chapter name local chapterobj = parse_text_with_lang(chap, chap_param, a("trans-" .. param)) chapterobj.text = make_chapter_with_url(chapterobj.text) formatted = (textual_prefix or "") .. format_text(chapterobj) .. (textual_suffix or "") end

if chap_num or chap_plain then -- NOTE: Up above we throw an error if both chap_num and chap_plain are specified. formatted = formatted .. " (" .. (chap_plain or numeric_prefix .. chap_num) .. ")" end if chap_series then formatted = formatted .. chap_series end

return formatted end

-- This handles everything after displaying the author, starting with the chapter and ending with page, column and -- then other=. It is currently called twice: Once to handle the main portion of the citation, and once to handle a	-- "newversion" citation. `ind` is either "" for the main portion or a number (currently only 2) for a "newversion" -- citation. In a few places we conditionalize on `ind` to take actions depending on its value. `sep` is the -- separator to display before the first item we add; see add_with_sep below. local function postauthor(ind, sep) get_full_paramname = make_get_full_paramname(ind)

local chapter_tlr = parse_and_format_text("chapter_tlr") if chapter_tlr then add(chapter_tlr .. ", transl., ") end

local formatted_chapter = format_chapterlike("chapter", "chapter ", "“", "”") if formatted_chapter then add(" ") add(formatted_chapter) if not a("notitle") then add(", in ") end end

local tlr = parse_and_format_text({"tlr", "translator", "translators"}) local editor, editor_param = parse_and_format_text_with_name("editor") local editors, editors_param = parse_and_format_text_with_name("editors") if editor and editors then error(("Can't specify both |%s= and |%s="):format(editor_param, editors_param)) end if a("mainauthor") then add(parse_and_format_text("mainauthor") .. ((tlr or editor or editors) and SEMICOLON_SPACE or ",")) end

if tlr then add(tlr .. ", transl." .. ((editor or editors) and SEMICOLON_SPACE or ",")) end

if editor then add(editor .. ", editor,") elseif editors then add(editors .. ", editors,") end

-- If we're in the "newversion" code (ind ~= ""), and there's no title and no URL, then the first time we add -- anything after the title, we don't want to add a separating comma because the preceding text will say -- "republished " or "republished as " or "translated as " or similar. In all other cases, we do want to add a -- separating comma. We handle this using a `sep` variable whose value will generally either be "" or ", ". The -- add_with_sep(text) function adds the `sep` variable and then `text`, and then resets `sep` to ", " so the -- next time around we do add a comma to separate `text` from the preceding piece of text. local function add_with_sep(text) add(sep .. text) sep = ", " end local title, title_param = a_with_name("title") if title then local titleobj = parse_text_with_lang(title, title_param, a("trans-title")) add(" ") add(format_text(titleobj, tag_with_cite, tag_with_cite)) local series = parse_and_format_text("series") if series then add(" (" .. series)				local seriesvolume = parse_and_format_text("seriesvolume")				if seriesvolume then					add(SEMICOLON_SPACE .. seriesvolume)				end				add(")") end sep = ", " elseif ind == "" then sep = ", " if not a("notitle") then add(maintenance_line("Please provide the book title or journal name")) end end

local url = aurl("archiveurl") or aurl("url") if url then add("[" .. url .. "]") sep = ", " end

local urls = aurl("urls") if urls then add("" .. urls .. "") sep = ", " end

local edition = parse_and_format_text("edition") if edition then add_with_sep(edition .. " edition") end

local edition_plain = parse_and_format_text("edition_plain") if edition_plain then add_with_sep(" " .. edition_plain) end

-- Display a numeric param such as page=, volume=, column=. For each `paramname`, four params are actually -- recognized, e.g. for paramname == "page", the params page=, pages=, page_plain= and pageurl= are recognized -- and checked (or the same with an index, e.g. page2=, pages2=, page_plain2= and pageurl2= respectively if		-- ind == "2"). Only one of the first three can be specified; an error results if more than one are given. -- If none are given, the return value is nil; otherwise it is a string. The numeric spec is taken directly -- from e.g. page_plain= if given; otherwise if e.g. pages= is given, or if page= is given and looks like a -- combination of numbers (i.e. it has a hyphen or dash in it, a comma, or the word " and "), it is prefixed -- by `singular_desc` + "s" (e.g. "pages "), otherwise it is prefixed by just `singular_desc` (e.g. "page "). -- (As a special case, if either e.g. page=unnumbered or pages=unnumbered is given, the numeric spec is		-- "unnumbered page".) The resulting spec is returned directly unless e.g. pageurl= is given, in which case -- it is linked to the specified URL. Note that any of the specs can be foreign text, e.g. foreign numbers -- (including with optional inline modifiers), and such text is handled appropriately. local function format_numeric_param(paramname, singular_desc) local sgval, sg_param = a_with_name(paramname) local sgobj = parse_text_with_lang(sgval, paramname) local plparamname = paramname .. "s" local plval, pl_param = a_with_name(plparamname) local plobj = parse_text_with_lang(plval, plparamname) local plainval, plain_param = parse_and_format_text_with_name(paramname .. "_plain") local howmany = (sgval and 1 or 0) + (plval and 1 or 0) + (plainval and 1 or 0) if howmany > 1 then local params_specified = {} local function insparam(param) if param then table.insert(params_specified, ("|%s="):format(param)) end end insparam(sg_param) insparam(pl_param) insparam(plain_param) error(("Can't specify more than one of %s"):format( require(table_module).serialCommaJoin(params_specified, {dontTag = true}))) end if howmany == 0 then return nil end -- Merge page= and pages= and treat alike because people often mix them up in both directions. local numspec if plainval then numspec = plainval else local val = sgobj and sgobj.text or plobj.text if val == "unnumbered" then numspec = "unnumbered " .. singular_desc else local function get_plural_desc -- Only call when needed to potentially avoid a module load. return pluralize(singular_desc) end local desc if val:find("^!") then val = val:gsub("^!", "") desc = sgval and singular_desc or get_plural_desc else local check_val = val if check_val:find("%[") then check_val = require(links_module).remove_links(check_val) -- convert URL's of the form [URL DISPLAY] to the displayed value check_val = check_val:gsub("%^ %[%* ([^%[%]]*)%]", "%1") end -- in case of negative page numbers (do they exist?), don't treat as multiple pages check_val = check_val:gsub("^%-", "") -- replace HTML entity en-dashes and em-dashes with their literal codes check_val = check_val:gsub("–", "–") check_val = check_val:gsub("–", "–") check_val = check_val:gsub("—", "—") check_val = check_val:gsub("—", "—") -- Check for en-dash or em-dash, or two numbers (possibly with stuff after like 12a-15b) -- separated by a hyphen or by comma a followed by a space (to avoid firing on thousands separators). if rfind(check_val, "[–—]") or check_val:find(" and ") or rfind(check_val, "[0-9]+[^ ]* *%- *[0-9]+") or rfind(check_val, "[0-9]+[^ ]* *, +[0-9]+") then desc = get_plural_desc else desc = singular_desc end end local obj = sgobj or plobj obj.text = val val = format_text(obj) numspec = desc .. " " .. val end end local url = a(paramname .. "url") if url then return "[" .. url .. " " .. numspec .. "]"			else return numspec end end

local volume = format_numeric_param("volume", a("volume_prefix") or "volume") if volume then add_with_sep(volume) end

local issue = format_numeric_param("issue", a("issue_prefix") or "number") if issue then add_with_sep(issue) end

-- number= is an alias for issue= (except in, where it is the episode number) local number = format_numeric_param("number", a("number_prefix") or "number") if number then add_with_sep(number) end

-- This function handles the display of annotations like "(in French)" or "(in German; quote in Nauruan)". It -- takes two params PRETEXT and POSTTEXT to display before and after the annotation, respectively. These are -- used to insert the surrounding parens, commas, etc. They are necessary because we don't always display the -- annotation (in fact it's usually not displayed), and when there's no annotation, no pre-text or post-text is -- displayed. local function langhandler(pretext, posttext) local argslang, argslang_param if ind == "" then argslang = args.lang or args[1] argslang_param = 1 else argslang, argslang_param = a_with_name("lang") end local worklang, worklang_param = a_with_name("worklang") if worklang then return pretext .. "in " .. format_langs(worklang, worklang_param) .. posttext elseif argslang and a("termlang") and argslang ~= a("termlang") then return pretext .. "in " .. format_langs(argslang, argslang_param) .. posttext elseif not argslang and ind == "" then return pretext .. maintenance_line("Please specify the language of the quote") .. posttext end return "" end

if a("genre") then add(" (" .. a("genre") .. (a("format") and ", " .. a("format") or "") .. langhandler(", ", "") .. ")")			sep = ", " elseif a("format") then add(" (" .. a("format") .. langhandler(", ", "") .. ")")			sep = ", " else local to_insert = langhandler(" (", ")") if to_insert ~= "" then sep = ", " add(to_insert) end end

if a("others") then add_with_sep(parse_and_format_text("others")) end local quoted_in = parse_and_format_text("quoted_in", tag_with_cite, tag_with_cite) if quoted_in then add_with_sep("quoted in " .. quoted_in) table.insert(tracking_categories, "Quotations using quoted-in parameter") end

local location = parse_and_format_text("location") if a("publisher") then if location then add_with_sep(location .. ":") -- colon sep = " " end add_with_sep(parse_and_format_text("publisher")) elseif location then add_with_sep(location) end

if a("source") then add_with_sep("sourced from " .. parse_and_format_text("source")) end

local original = parse_and_format_text("original", tag_with_cite, tag_with_cite) local by = parse_and_format_text("by") if original or by then add_with_sep((a("type") or "translation") .. " of " .. (original or "original") .. (by and " by " .. by or "")) end

-- Fetch date_published=/year_published=/month_published= and format appropriately. local formatted_date_published = format_date_args(a, get_full_paramname, alias_map, "", "_published") local platform = parse_and_format_text("platform") if formatted_date_published then add_with_sep("published " .. formatted_date_published .. (platform and " via " .. platform or "")) elseif platform then add_with_sep("via " .. platform) end

if ind ~= "" and has_newversion then local formatted_new_date, this_need_date = format_date_args(a, get_full_paramname, alias_map, "", "", nil, 				"Please provide a date or year") need_date = need_date or this_need_date add_with_sep(formatted_new_date) end

-- From here on out, there should always be a preceding item, so we -- can dispense with add_with_sep and always insert the comma.

local function small(txt) add(", ") add(txt) add(" ") end

-- Add an identifier to a book or article database such as DOI, ISBN, JSTOR, etc. `param_or_params` -- is a string identifying the base param, or a list of such strings to check in turn. If found, the value -- of the parameter is processed using `process` (a function of one argument, defaulting to mw.uri.encode), -- and then the actual URL to insert is generated by preceding with `pretext`, following with `posttext`, -- and running the resulting string through small, which first adds a comma and then the URL in small font. local function add_identifier(param_or_params, pretext, posttext, process) local val = a(param_or_params) if val then val = (process or mw.uri.encode)(val) small(pretext .. val .. posttext) end end

add_identifier("bibcode", "" →Bibcode") add_identifier({"DOI", "doi"}, "<span class=\"neverexpand\">" →DOI ") add_identifier({"ISBN", "isbn"}, "", "", isbn) add_identifier({"ISSN", "issn"}, "", "", issn) add_identifier({"JSTOR", "jstor"}, "" →JSTOR") add_identifier({"LCCN", "lccn"}, "", "", lccn) add_identifier({"OCLC", "oclc"}, "" →OCLC") add_identifier({"OL", "ol"}, ""/ →OL") add_identifier({"PMID", "pmid"}, "" →PMID") add_identifier({"PMCID", "pmcid"}, ""/ →PMCID") add_identifier({"SSRN", "ssrn"}, "" →SSRN") local id = a("id") if id then small(id) end

local archiveurl, archiveurl_param = aurl_with_name("archiveurl") if archiveurl then add(", archived from ") local url, url_param = aurl_with_name("url") if not url then -- attempt to infer original URL from archive URL; this works at				-- least for Wayback Machine (web.archive.org) URL's				url = rmatch(archiveurl, "/(https?:.*)$") if not url then error(("When |%s= is specified, |%s= must also be included"):format(archiveurl_param, url_param)) end end add("[" .. url .. " the original] on ") local archivedate, archivedate_param = a_with_name("archivedate") if archivedate then add(format_date(archivedate)) elseif (string.sub(archiveurl, 1, 28) == "https://web.archive.org/web/") then -- If the archive is from the Wayback Machine, then it already contains the date -- Get the date and format into ISO 8601 local wayback_date = string.sub(archiveurl, 29, 29+7) wayback_date = string.sub(wayback_date, 1, 4) .. "-" .. string.sub(wayback_date, 5, 6) .. "-" ..					string.sub(wayback_date, 7, 8) add(format_date(wayback_date)) else error(("When |%s= is specified, |%s= must also be included"):format( archiveurl_param, archivedate_param)) end end if a("accessdate") then --Otherwise do not display here, as already used as a fallback for missing date= or year= earlier. if (a("date") or a("nodate") or a("year")) and not a("archivedate") then add(", retrieved " .. format_date(a("accessdate"))) end end

local formatted_section = format_chapterlike("section", "section ") if formatted_section then add(", ") add(formatted_section) end

local note = parse_and_format_text("note") if note then add(", " .. note) end

local note_plain = parse_and_format_text("note_plain") if note_plain then add(" " .. note_plain) end

-- Wrapper around format_numeric_param that inserts the formatted text with optional preceding text. local function handle_numeric_param(paramname, singular_desc, pretext) local numspec = format_numeric_param(paramname, singular_desc) if numspec then add((pretext or "") .. numspec) end end

handle_numeric_param("line", a("line_prefix") or "line", ", ") handle_numeric_param("page", a("page_prefix") or "page", ", ") handle_numeric_param("column", a("column_prefix") or "column", ", ") -- FIXME: Does this make sense? What is other=? local other = parse_and_format_text("other") if other then add(", " .. other) end end

-- Display all the text that comes after the author, for the main portion. postauthor("", "")

local sep

-- If there's a "newversion" section, add the new-version text. if has_newversion then --Test for new version of work. add(SEMICOLON_SPACE) if args.newversion then -- newversion= is intended for English text, e.g. "quoted in" or "republished as". add(args.newversion) elseif not args.edition2 then if has_new_title_or_author then add("republished as") else add("republished") end end add(" ") sep = "" else sep = ", " end

-- Add the author(s). if args["2ndauthor"] or args["2ndlast"] then add(" ") local authorlink = args["2ndauthorlink"] local function make_author_with_url(txt) if authorlink then return "" .. txt .. "" else return txt end end local author = args["2ndauthor"] if author then local authorobj = parse_text_with_lang(author, "2ndauthor") authorobj.text = make_author_with_url(authorobj.text) add(format_text(authorobj)) else local last = args["2ndlast"] local first = args["2ndfirst"] -- Author separated into first name + last name. We don't currently support non-Latin-script -- authors separated this way and probably never will. if first then author = first .. " " .. last else author = last end author = make_author_with_url(author) add(author) end

-- FIXME, we should use sep = ", " here too and fix up the handling -- of chapter/mainauthor/etc. in postauthor to use add_with_sep. if has_new_title_or_ancillary_author then add(", ") sep = "" else sep = ", " end end

-- Display all the text that comes after the author, for the "newversion" section. postauthor(2, sep)

add(":")

-- Concatenate output portions to form output text. local output_text = table.concat(output)

-- Remainder of code handles adding categories. We add one or more of the following categories: --	-- 1., based on the first language code in termlang= or 1=. Not added to --   non-main-namespace pages except for Reconstruction: and Appendix:. Not added if 1= is missing or nocat= is --   given. -- 2., based on the first language code in 1=. Added under the same --   circumstances as above. -- 3., if nocat= is given. Added to mainspace, Reconstruction: and --   Appendix: pages.

local categories = {}

local langcode = args.termlang or argslang or "und" langcode = rsplit(langcode, ",")[1] local lang = require(languages_module).getByCode(langcode, true)

if args.nocat then table.insert(tracking_categories, "Quotations using nocat parameter") elseif argslang then if lang then table.insert(categories, lang:getCanonicalName .. " terms with quotations") end if need_date then local argslangcode = rsplit(argslang, ",")[1] local argslangobj = require(languages_module).getByCode(argslangcode, 1) table.insert(categories, "Requests for date in " .. argslangobj:getCanonicalName .. " entries") end else -- Only allowable on non-mainspace pages, where we don't add categories. end

local FULLPAGENAME = mw.title.getCurrentTitle.fullText return output_text .. (not lang and "" or		(#categories > 0 and require(utilities_module).format_categories(categories, lang) or "") ..		(#tracking_categories > 0 and require(utilities_module).format_categories(tracking_categories, lang, nil, nil,			not require(usex_templates_module).page_should_be_ignored(FULLPAGENAME)) or "")) end

-- External interface, meant to be called from a template. -- FIXME: Remove this in favor of using quote_t. function export.source_t(frame) local parent_args = frame:getParent.args local args, alias_map = clone_args(frame.args, parent_args) return export.source(args, alias_map) end

-- External interface, meant to be called from a template. Replaces and meant to be the primary -- interface for templates. function export.quote_t(frame) local parent_args = frame:getParent.args local args, alias_map = clone_args(frame.args, parent_args) local deprecated = args.lang

local function yesno(val) if not val then return false end return require(yesno_module)(val) end

args.nocat = yesno(args.nocat) args.brackets = yesno(args.brackets)

local text = args.text or args.passage local gloss = args.t or args.gloss or args.translation

local parts = {} local function ins(text) table.insert(parts, text) end

ins(' ') ins(export.source(args, alias_map)) ins(" <dl><dd>") -- If any quote-related args are present, display the actual quote; otherwise, display nothing. local tr = args.tr or args.transliteration local ts = args.ts or args.transcription local norm = args.norm or args.normalization local sc = args.sc and require(scripts_module).getByCode(args.sc, "sc") or nil local normsc = args.normsc == "auto" and args.normsc or args.normsc and require(scripts_module).getByCode(args.normsc, "normsc") or nil if text or gloss or tr or ts or norm then local langcodes = args[1] or args.lang local langcode = langcodes and rsplit(langcodes, ",")[1] or nil

local usex_data = { -- Pass "und" here rather than cause an error; there will be an error on mainspace, Citations, etc. pages -- in any case in source if the language is omitted. lang = require(languages_module).getByCode(langcode or "und", 1), usex = text, sc = sc, translation = gloss, normalization = norm, normsc = normsc, transliteration = tr, transcription = ts, brackets = args.brackets, substs = args.subst, lit = args.lit, footer = args.footer, -- pass true here because source already adds 'LANG terms with quotations' nocat = true, quote = "quote-meta", }		ins(require(usex_module).format_usex(usex_data)) end ins("</dd></dl> ") local retval = table.concat(parts) return deprecated and frame:expandTemplate{title = "check deprecated lang param usage", args = {retval, lang = args.lang}} or retval end

-- External interface, meant to be called from a template. function export.call_quote_template(frame) local iparams = { ["template"] = {}, ["textparam"] = {}, ["pageparam"] = {}, ["allowparams"] = {list = true}, ["propagateparams"] = {list = true}, }	local iargs, other_direct_args = require(parameters_module).process(frame.args, iparams, "return unknown", "quote", "call_quote_template") local direct_args = {} for pname, param in pairs(other_direct_args) do		direct_args[pname] = ine(param) end

local function process_paramref(paramref) if not paramref then return {} end local params = rsplit(paramref, "%s*,%s*") for i, param in ipairs(params) do			if rfind(param, "^[0-9]+$") then param = tonumber(param) end params[i] = param end return params end

local function fetch_param(source, params) for _, param in ipairs(params) do			if source[param] then return source[param] end end return nil end

local params = { ["text"] = {}, ["passage"] = {}, ["footer"] = {}, ["brackets"] = {}, }	local textparams = process_paramref(iargs.textparam) for _, param in ipairs(textparams) do		params[param] = {} end local pageparams = process_paramref(iargs.pageparam) if #pageparams > 0 then params["page"] = {} params["pages"] = {} for _, param in ipairs(pageparams) do			params[param] = {} end end

local parent_args = frame:getParent.args local allow_all = false for _, allowspec in ipairs(iargs.allowparams) do		for _, allow in ipairs(rsplit(allowspec, "%s*,%s*")) do			local param = rmatch(allow, "^(.*):list$") if param then if rfind(param, "^[0-9]+$") then param = tonumber(param) end params[param] = {list = true} elseif allow == "*" then allow_all = true else if rfind(allow, "^[0-9]+$") then allow = tonumber(allow) end params[allow] = {} end end end

local params_to_propagate = {} for _, propagate_spec in ipairs(iargs.propagateparams) do		for _, param in ipairs(process_paramref(propagate_spec)) do			table.insert(params_to_propagate, param) params[param] = {} end end

local args = require(parameters_module).process(parent_args, params, allow_all, "quote", "call_quote_template") parent_args = require(table_module).shallowcopy(parent_args)

if textparams[1] ~= "-" then other_direct_args.passage = args.text or args.passage or fetch_param(args, textparams) end if #pageparams > 0 and pageparams[1] ~= "-" then other_direct_args.page = fetch_param(args, pageparams) or args.page or nil other_direct_args.pages = args.pages end if args.footer then other_direct_args.footer = frame:expandTemplate { title = "small", args = {args.footer} } end other_direct_args.brackets = args.brackets if not other_direct_args.authorlink and not other_direct_args.author:find("[%[<]") then other_direct_args.authorlink = other_direct_args.author end for _, param in ipairs(params_to_propagate) do		if args[param] then other_direct_args[param] = args[param] end end

return frame:expandTemplate { title = iargs.template or "quote-book", args = other_direct_args } end

local paramdoc_param_replacements = { passage = { param_with_synonym = '< >, text, or passage', param_no_synonym = 'text or passage', text = [=[ },	page = { param_with_synonym = '< > or page, or pages', param_no_synonym = 'page or pages', text = [=[
 * < > – the passage to be quoted.]=],
 * < > – mandatory in some cases: the page number(s) quoted from. When quoting a range of pages, note the following:
 * Separate the first and last pages of the range with an en dash, like this: 10–11.
 * You must also use pageref to indicate the page to be linked to (usually the page on which the Wiktionary entry appears).
 * This parameter must be specified to have the template link to the online version of the work.]=]

},	page_with_roman_preface = { param_with_synonym = {"inherit", "page"}, param_no_synonym = {"inherit", "page"}, text = [=[
 * < > – mandatory in some cases: the page number(s) quoted from. If quoting from the preface, specify the page number(s) in lowercase Roman numerals. When quoting a range of pages, note the following:
 * Separate the first and last page number of the range with an en dash, like this: 10–11 or iii–iv.
 * You must also use pageref to indicate the page to be linked to (usually the page on which the Wiktionary entry appears).
 * This parameter must be specified to have the template link to the online version of the work.]=]

},	chapter = { param_with_synonym = '< > or chapter', param_no_synonym = 'chapter', text = [=[ },	roman_chapter = { param_with_synonym = {"inherit", "chapter"}, param_no_synonym = {"inherit", "chapter"}, text = [=[ },	arabic_chapter = { param_with_synonym = {"inherit", "chapter"}, param_no_synonym = {"inherit", "chapter"}, text = [=[ },	trailing_params = { text = [=[ } }
 * < > – the name of the chapter quoted from.]=],
 * < > – the chapter number quoted from in uppercase Roman numerals.]=],
 * < > – the chapter number quoted from in Arabic numerals.]=],
 * footer – a comment on the passage quoted.
 * brackets – use on to surround a quotation with brackets. This indicates that the quotation either contains a mere mention of a term (for example, “some people find the word manoeuvre hard to spell”) rather than an actual use of it (for example, “we need to manoeuvre carefully to avoid causing upset”), or does not provide an actual instance of a term but provides information about related terms.]=],

function export.paramdoc(frame) local params = { [1] = {},	}

local parargs = frame:getParent.args local args = require(parameters_module).process(parargs, params, nil, "quote", "paramdoc")

local text = args[1]

local function do_param_with_optional_synonym(param, text_to_sub, paramtext_synonym, paramtext_no_synonym) local function sub_param(synonym) local subbed_paramtext if synonym then subbed_paramtext = rsub(paramtext_synonym, "< >", "" .. synonym .. "") else subbed_paramtext = paramtext_no_synonym end return frame:preprocess(rsub(text_to_sub, "< >", subbed_paramtext)) end text = rsub(text, "<<" .. param .. ">>", function return sub_param end) text = rsub(text, "<<" .. param .. ":(.-)>>", sub_param) end

local function fetch_text(param_to_replace, key) local spec = paramdoc_param_replacements[param_to_replace] local val = spec[key] if type(val) == "string" then return val end if type(val) == "table" and val[1] == "inherit" then return fetch_text(val[2], key) end error("Internal error: Unrecognized value for param '" .. param_to_replace .. "', key '" .. key .. "': "			.. mw.dumpObject(val)) end

for param_to_replace, spec in pairs(paramdoc_param_replacements) do		local function fetch(key) return fetch_text(param_to_replace, key) end

if not spec.param_no_synonym then -- Text to substitute directly. text = rsub(text, "<<" .. param_to_replace .. ">>", function return frame:preprocess(fetch("text")) end) else do_param_with_optional_synonym(param_to_replace, fetch("text"), fetch("param_with_synonym"),				fetch("param_no_synonym")) end end

-- Remove final newline so template code can add a newline after invocation text = text:gsub("\n$", "") return text end

return export

title: Module:User:Benwing2/quote


text:
trakooma

Etymology
(see 🇨🇬), ultimately from.

Noun

 * 1) trachoma

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: trakooma


text:
jacarando

Adjective

 * 1)  jácara
 * 2) handsome; good-looking

title: jacarando


text:
tromboosi

Etymology
.

Noun

 * 1)  thrombosis

title: tromboosi


text: epäjumalan

title: epäjumalan


text:
giây phút

Etymology
.

Noun

 * 1)  seconds and minutes
 * 2)  a moment; a time

title: giây phút


text: vastamelukuulokkeet

title: vastamelukuulokkeet


text:
trombosytopenia

Etymology
(see 🇨🇬).

Noun

 * 1) thrombocytopenia

title: trombosytopenia


text:
valkuaisvirtsaisuus

Noun

 * 1)  proteinuria

title: valkuaisvirtsaisuus


text:
vesirakkula

Noun

 * 1) vesicle

title: vesirakkula


text: jumalankieltäminen

title: jumalankieltäminen


text:
perder un tornillo

Etymology
lit. 'lose a screw'.

Verb

 * 1)  to lose one's mind

title: perder un tornillo


text:
faltarle un tornillo

Etymology
lit. 'be missing a screw'.

Verb

 * 1)  to have a screw loose

title: faltarle un tornillo


text:
User:Benwing2/dorf

Etymology 1
In some cases from and in others from the cognate.

Noun

 * 1) A village in a Germanic-speaking area.
 * 2) * 1845, Jeptha Root Simms, History of Schoharie County and Border Wars of New York: , Albany, Munsell & Tanner, printers, page 48:
 * This dorf contained some forty dwellings.
 * 1) * 1853, Thomas Carlyle, Fraser's Magazine, page 280:
 * So, all things considered, we were not very cheerful at first; but when the mist got higher and the day got brighter, and particularly after we left the first little dorf.

Etymology 2
Changed from.

Noun

 * 1) ; freak.

title: User:Benwing2/dorf


text:
tener flojos los tornillos

Etymology
lit. 'have screws loose'.

Verb

 * 1)  to have a screw loose

title: tener flojos los tornillos


text:
jumalanluoma

Noun

 * 1) creature something created by God; derogatory if said of a human

title: jumalanluoma


text:
schlecht gelaunt

Adjective

 * 1) sullen, sulky having ill temper

title: schlecht gelaunt


text: chalenges

title: chalenges


text: chaleng

title: chaleng


text: chalaunge

title: chalaunge


text:
jumalanäiti

Noun

 * 1)  Mother of God Virgin Mary

title: jumalanäiti


text: kalange

title: kalange


text: kalleng

title: kalleng


text: chalence

title: chalence


text:
vastahypoteesi

Noun

 * 1)  alternative hypothesis

title: vastahypoteesi


text:
回娘家

Verb

 * 1)  to return to her parents' home for a visit
 * 2)  to return to one's old place, former job, etc.

title: 回娘家


text: Category:vi:Capitalism

title: Category:vi:Capitalism


text:
chimuelo

Adjective

 * 1)  missing at least one tooth

title: chimuelo


text:
Module talk:R:Duden

The module is broken for compound terms. See Matthias Buchmeier (talk) 09:01, 28 February 2019 (UTC)
 * Fixed, at least when incorrect manual input has not been supplied. — Eru·tuon 09:47, 28 February 2019 (UTC)
 * OK, thanks Matthias Buchmeier (talk) 11:39, 28 February 2019 (UTC)

title: Module talk:R:Duden


text:
vogelwichelarij

Etymology
Compound of or from.

Noun

 * 1)  augury, bird divination

title: vogelwichelarij


text:
borlote

Noun

 * 1)  fuss; uproar

title: borlote


text:
chalengeable

Etymology
From.

Adjective

 * 1) Challengeable; able to be called out, disagreed with, or argued with.

title: chalengeable


text:
vogelwichelaar

Etymology
Compound of.

Noun

 * 1)  augur, bird diviner

title: vogelwichelaar


text: vogelwichelaars

title: vogelwichelaars


text: laicizarse

title: laicizarse


text: chalangeable

title: chalangeable


text:
autogordel

Etymology
Compound of.

Noun

 * 1) seat belt in a car

title: autogordel


text: autogordels

title: autogordels


text:
כספת

Etymology
From.

Noun

 * 1) safe

title: כספת


text:
underhook

Etymology
en

Noun

 * 1)  A clinch hold performed by putting an arm under the opponent's arm, and holding the opponent's midsection or upper body.

Verb

 * 1)  To use such a hold upon.

title: underhook


text: gordels

title: gordels


text: chalengeres

title: chalengeres


text:
chalengere

Etymology
From ; some forms are influenced by.

Noun

 * 1) A slanderer or liar; one who defames.
 * 2)  A claimant; one who claims something.
 * 3)  An objector; one who challenges something.

title: chalengere


text:
ekosysteemipalvelu

Noun

 * 1) ecosystem service

title: ekosysteemipalvelu


text:
elinkaariarviointi

Noun

 * 1) life cycle assessment

title: elinkaariarviointi


text: chalangeour

title: chalangeour


text: chalongour

title: chalongour


text:
energia-avustus

Noun

 * 1) energy assistance

title: energia-avustus


text: chalanger

title: chalanger


text:
energiahyötykäyttö

Noun

 * 1) use of recycled materials for energy

title: energiahyötykäyttö


text:
energiajäte

Noun

 * 1) energy waste waste that can be easily converted into energy

title: energiajäte


text:
energiakäyttö

Noun

 * 1) energy recovery

title: energiakäyttö


text:
energiamerkki

Noun

 * 1) energy label

title: energiamerkki


text:
energiatehokkuus

Noun

 * 1) energy efficiency

title: energiatehokkuus


text: clústeres

title: clústeres


text:
energiavero

Noun

 * 1) energy tax

title: energiavero


text: clústers

title: clústers


text:
fluorikaasu

Noun

 * 1) fluorine gas

title: fluorikaasu


text:
fuusiovoima

Noun

 * 1) fusion power

title: fuusiovoima


text:
happipoltto

Noun

 * 1) oxyfuel combustion

title: happipoltto


text:
hiilensidonta

Noun

 * 1) carbon sequestration

title: hiilensidonta


text:
hiilidioksidiekvivalentti

Noun

 * 1) carbon dioxide equivalent

title: hiilidioksidiekvivalentti


text:
hiilidioksidinielu

Noun

 * 1) carbon dioxide sink

title: hiilidioksidinielu


text:
hiili-intensiteetti

Noun

 * 1) carbon intensity

title: hiili-intensiteetti


text:
álabe

Etymology
. Perhaps or. Compare 🇨🇬.

Noun

 * 1) olive branch bent down and reaching the ground
 * 2) any of the force-transmitting elements of a propelling wheel in a water-mill, flier, vane
 * 3) turbine blade
 * 4) tappet on a fulling wheel
 * 5) a barrier such as a mat on the side of a carriage so he who drives it does not fall out
 * 6) sides of a target or shield
 * 1) sides of a target or shield

title: álabe


text:
parnaso

Etymology
From.

Noun

 * 1)  poetry

Etymology
.

Noun

 * 1) group of poets (of a certain era, style, location)
 * 2) collection of poems

title: parnaso


text:
бағыныңқылық

Noun

 * 1) dependence, subordination

title: бағыныңқылық


text:
infraorden

Noun

 * 1) infraorder

title: infraorden


text:
sotuer

Noun

 * 1)  saltire

title: sotuer


text:
volksaltaar

Etymology
Compound of.

Noun

 * 1)  people's altar

title: volksaltaar


text:
сыңар

Noun

 * 1) component

Pronoun

 * 1) one

Etymology
From. Compare to 🇨🇬, 🇨🇬, etc.

Noun

 * 1) single, one of a pair

title: сыңар


text:
jumaluusopillinen

Adjective

 * 1) theological, theologic

title: jumaluusopillinen


text:
diaconía

Noun

 * 1) deaconry
 * 2) the house of a deacon

title: diaconía


text:
vigorosidad

Etymology
From.

Noun

 * 1) vigorousness

title: vigorosidad


text: jumaluusoppinut

title: jumaluusoppinut


text: pellonvarauksen

title: pellonvarauksen


text:
arco formero

Noun

 * 1)  side arch

title: arco formero


text: hematíes

title: hematíes


text:
Olm

Etymology
From, from. Further etymology unknown. Cognate with 🇨🇬.

Noun

 * 1) olm cave-dwelling salamander

title: Olm


text: vesirakennustyön

title: vesirakennustyön


text:
de trecho en trecho

Adverb

 * 1)  from time to time; occasionally

title: de trecho en trecho


text: vierastyövoiman

title: vierastyövoiman


text:
currícula

Noun

 * 1) curriculum, CV

Usage notes

 * The RAE advises against the use of.

title: currícula


text:
мекендеу

Verb

 * 1) to reside

title: мекендеу


text:
mosfet

Noun

 * 1) MOSFET

title: mosfet


text:
chalengen

Etymology
,, , from ; equivalent to.

Verb

 * 1) To counter, oppose, argue, or be against something or someone:
 * 2) To insult, criticise, or reprehend something or someone.
 * 3) To make a malicious and wrongful accusation or allegation.
 * 4)  To act with undeserved malice towards someone.
 * 5)  To punish or penalise someone for their behaviour
 * 6) To claim a possession, right, or privilege:
 * 7) To appropriate or expropriate; to take wrongfully or forcibly.
 * 8)  To forcibly request or order; to make a demand.
 * 9) To search or look for something; to seek out.
 * 10) To summon to a battle or duel.
 * 11)  To win a conflict or engagement; to defeat one's enemies.
 * 12)  To supply a reason for entering into a duel.

title: chalengen


text: chalengyn

title: chalengyn


text: challengen

title: challengen


text: calangy

title: calangy


text: calengen

title: calengen


text: calange

title: calange


text:
kenozooid

Noun

 * 1)  A small bryozoan heterozooid

title: kenozooid


text:
match safe

Noun

 * 1)  A small container for matches.

title: match safe


text: match safes

title: match safes


text:
castellanía

Noun

 * 1)  During feudalism in the  or, an independent region

title: castellanía


text:
heterozooid

Noun

 * 1)  A specialized non-feeding bryozoan zooid

title: heterozooid


text: kenozooids

title: kenozooids


text: heterozooids

title: heterozooids


text:
เสียอาการ

Etymology
From 🇰🇲.

Verb

 * 1)  to lose control of oneself, lose one's mind, or go crazy because of shyness, excitement, surprise, etc.

title: เสียอาการ


text:
前記

Noun

 * 1) preface; foreword; introductory remarks; preamble; prelude
 * 2) earlier remarks

Noun

 * 1) preface, the opening section of a book or text
 * 2) the aforementioned, something written in an earlier section of a text
 * 3) documents from a previous generation, an old chronicle or record
 * 1) documents from a previous generation, an old chronicle or record
 * 1) documents from a previous generation, an old chronicle or record

Adnominal

 * 1) aforementioned, noted earlier

title: 前記


text:
ínfero

Adjective

 * 1)  inferior (said of an ovary)

title: ínfero


text: 前记

title: 前记


text: qiánjì

title: qiánjì


text: fākāncí

title: fākāncí


text: fākān

title: fākān


text:
kirromycin

Noun

 * 1) An antibiotic that inhibits protein biosynthesis

title: kirromycin


text:
aerostaat

Etymology
Borrowed from.

Noun

 * 1) aerostat

title: aerostaat


text: aerostaten

title: aerostaten


text:
adpreso

Adjective

 * 1)  appressed

title: adpreso


text: kānfā

title: kānfā


text:
jumalansana

Noun

 * 1)  Word word of God; Bible

title: jumalansana


text: yǐnlùn

title: yǐnlùn


text: dǎolùn

title: dǎolùn


text: liàngzǐ lìxué

title: liàngzǐ lìxué


text:
малодушный

Adjective

 * 1) faint-hearted, cowardly, craven

Noun

 * 1) faint-hearted person, coward

title: малодушный


text: xùbá

title: xùbá


text: chalengyng

title: chalengyng


text:
vaído

Adjective

 * 1)  pendentive

title: vaído


text: User:Sobreira/Books/English Idioms

title: User:Sobreira/Books/English Idioms


text: biànyán

title: biànyán


text:
labiomesial

Adjective

 * 1)  labial and mesial

title: labiomesial


text: chalangyng

title: chalangyng


text: chalenging

title: chalenging


text:
игеру

Noun

 * 1) mastery

Verb

 * 1) to master
 * 2) to take use of

title: игеру


text: chalyngynge

title: chalyngynge


text:
chalengynge

Etymology
From.

Noun

 * 1) Slander, defamation; the propagation of untrue and unflattering claims.
 * 2) The challenging or countering of a claim, allegation, or belief.
 * 3) A claim; the assertion of a privilege or right.

title: chalengynge


text:
labiomesially

Adverb

 * 1) In a labiomesial manner or direction

title: labiomesially


text: chalenginge

title: chalenginge


text: baído

title: baído


text:
automejora

Etymology 1
From.

Noun

 * 1) self-enhancement

title: automejora


text:
labiosternal

Adjective

 * 1) labial and sternal

title: labiosternal


text:
automejorarse

Etymology
From.

Verb

 * 1)  to enhance or better oneself

title: automejorarse


text:
exhacienda

Noun

 * 1) a former treasury

title: exhacienda


text: Thesaurus:序文

title: Thesaurus:序文


text: lamniforms

title: lamniforms


text: Category:ja:Aesthetics

title: Category:ja:Aesthetics


text:
lankanectid

Noun

 * 1) Any frog of the genus,.

title: lankanectid


text: lankanectids

title: lankanectids


text:
User:Sobreira/Books/English Idioms and other figures of speech 1

Aph, Cph, Pvb, SPh (as of 20190228)

 * Aphorisms
 * a chain is only as strong as its weakest link
 * all cats are gray at night
 * all cats are gray in the dark
 * all cats are grey at night
 * all cats are grey by night
 * all cats are grey in the dark
 * any press is good press
 * better late than never
 * clothes don't make the man
 * heaven helps those who help themselves
 * hindsight is 20/20
 * if it ain't broke, don't fix it
 * ignorance is bliss
 * leave well enough alone
 * live life to the fullest
 * never change a running system
 * size matters
 * something is rotten in the state of Denmark
 * twenty-twenty hindsight

 * Catch phrases
 * accidentally on purpose
 * act one's age
 * age before beauty
 * all your base are belong to us
 * different strokes
 * get off of someone's cloud
 * I see, said the blind man
 * take the flak

 * Proverbs
 * Appendix:English proverbs
 * a bad penny always comes back
 * a bad penny always turns up
 * a bad tree does not yield good apples
 * a bad workman always blames his tools
 * a bird in the hand is worth two in the bush
 * a buck is a buck
 * a buck is a buck is a buck
 * a buck's a buck
 * a buck's a buck's a buck
 * a burnt child dreads the fire
 * a camel is a horse designed by a committee
 * a camel is a horse made by a committee
 * a cat can look at a king
 * a cat in gloves catches no mice
 * a cat may look at a king
 * a change is as good as a rest
 * a closed mouth catches no flies
 * a closed mouth gathers no feet
 * a contented mind is a perpetual feast
 * a creaking door hangs long on its hinges
 * a creaking door hangs longest
 * a danger foreseen is half avoided
 * a drowning man will clutch at a straw
 * a dumb priest never got a parish
 * a fault confessed is half redressed
 * a fool and his money are soon parted
 * a foolish consistency is the hobgoblin of little minds
 * a friend in need is a friend indeed
 * a golden key can open any door
 * a good beginning makes a good ending
 * a good deed is its own reward
 * a hit dog will holler
 * a house divided against itself cannot stand
 * a house is not a home
 * a journey of a thousand miles begins with a single step
 * a leopard cannot change its spots
 * a lie has no legs
 * a little knowledge is a dangerous thing
 * a man is known by the company he keeps
 * a man's home is his castle
 * a mind is a terrible thing to waste
 * a miss is as good as a mile
 * a new broom sweeps clean
 * a new broom sweeps clean, but an old broom knows the corners
 * a nod is as good as a wink
 * a penny saved is a penny earned
 * a penny saved is a penny gained
 * a picture is worth a thousand words
 * a picture paints a thousand words
 * a poison tree bears poison fruit
 * a problem shared is a problem halved
 * a promise is a promise
 * a promise made is a promise kept
 * a quick drop and a sudden stop
 * a revolution is not a dinner party
 * a rising tide lifts all boats
 * a rolling stone gathers no moss
 * a smooth sea never made a skilled sailor
 * a spoonful of sugar helps the medicine go down
 * a spoonful of sugar makes the medicine go down
 * a stick in a bundle cannot be broken
 * a stick in a bundle can't be broken
 * a stick in a bundle is unbreakable
 * a stitch in time saves nine
 * a stopped clock is right twice a day
 * a twig in a bundle cannot be broken
 * a twig in a bundle can't be broken
 * a twig in a bundle is unbreakable
 * a watched kettle never boils
 * a watched pot never boils
 * a wild goose never laid a tame egg
 * absence makes the heart grow fonder
 * accidents will happen
 * accidents will happen in the best regulated families
 * actions speak louder than words
 * all good things come to an end
 * all or none
 * all politics are local
 * all politics is local
 * all roads lead to Mecca
 * all roads lead to Rome
 * all that glisters is not gold
 * all that glitters is not gold
 * all the world's a stage
 * all things come to those who wait
 * all work and no play makes Jack a dull boy
 * all's fair in love and war
 * all's well that ends well
 * almost doesn't count
 * an apple a day keeps the doctor away
 * an army marches on its stomach
 * an Englishman's home is his castle
 * an eye for an eye makes the whole world blind
 * an ounce of prevention is better than a pound of cure
 * an ounce of prevention is better than an ounce of cure
 * an ounce of prevention is worth a pound of cure
 * Annuit cœptis
 * another day, another dollar
 * any port in a storm
 * appearances are deceptive
 * April showers bring May flowers
 * art is long, life is short
 * as a dog returns to his vomit, so a fool repeats his folly
 * as one door closes, another opens
 * as you make your bed, so you must lie in it
 * as you sow, so shall you reap
 * attack is the best form of defence
 * bad money drives out good
 * bad news travels fast
 * bad things come in threes
 * barking dogs never bite
 * barking dogs seldom bite
 * beauty is in the eye of the beholder
 * beauty is only skin deep
 * beggars can't be choosers
 * better an egg today than a hen tomorrow
 * better dead than red
 * better dead than Red
 * better Dead than Red
 * better safe than sorry
 * better the devil you know
 * better the devil you know than the devil you don't
 * better the devil you know than the devil you don't know
 * better the devil you know than the one you don't
 * better the devil you know than the one you don't know
 * better to light a candle than to curse the darkness
 * better to light a single candle than to curse the darkness
 * better to light one candle than to curse the darkness
 * beware of Greeks bearing gifts
 * bi now, gay later
 * big things come in small packages
 * bird in the hand
 * birds of a feather flock together
 * birds of the feather flock together
 * blood is thicker than water
 * boys will be boys
 * brevity is the soul of wit
 * bros before hoes
 * bros before hos
 * business before pleasure
 * buy cheap, buy twice
 * buy low, sell high
 * buy when it snows and sell when it goes
 * buy when it snows, sell when it goes
 * Caesar's wife must be above suspicion
 * cannot live with them, cannot live without them
 * can't live with 'em, can't live without 'em
 * can't live with them and can't live without them
 * can't live with them, can't live without them
 * care killed the cat
 * carpe diem
 * carpe diem cras
 * caveat lector
 * charity begins at home
 * cheaters never prosper
 * cheats never prosper
 * chicks before dicks
 * children should be seen and not heard
 * Christmas comes but once a year
 * claret would be port if it could
 * claw me, claw thee
 * clogs to clogs in three generations
 * close only counts in horseshoes
 * close only counts in horseshoes and hand grenades
 * cold hands, warm heart
 * cool heads must prevail
 * cool heads prevail
 * cool heads will prevail
 * cooler heads must prevail
 * cooler heads prevail
 * cooler heads will prevail
 * crime doesn't pay
 * cross my heart and hope to die, stick a needle in my eye
 * curiosity killed the cat
 * curses, like chickens, come home to roost
 * dance with the one that brought ya
 * dance with the one that brought you
 * dance with the one that brung ya
 * dance with the one that brung you
 * dance with the one what brought ya
 * dance with the one what brought you
 * dance with the one what brung ya
 * dance with the one what brung you
 * dance with the one who brought ya
 * dance with the one who brought you
 * dance with the one who brung ya
 * dance with the one who brung you
 * dead men can tell no tales
 * dead men tell no tales
 * desperate times call for desperate measures
 * desperate times require desperate measures
 * devil is in the details
 * devil lies in the details
 * diamonds are a girl's best friend
 * different strokes for different folks
 * discretion is the better part of valor
 * discretion is the better part of valour
 * do as I say, not as I do
 * do unto others as you would have them do unto you
 * doctors make the worst patients
 * does Macy's tell Gimbel's
 * don't change a winning team
 * don't count your chickens before the eggs have hatched
 * don't count your chickens before they're hatched
 * don't cry over spilled milk
 * don't dip your pen in company ink
 * don't drive faster than your guardian angel can fly
 * don't drop the soap
 * don't get your meat where you get your bread
 * don't hate the player, hate the game
 * don't judge a book by its cover
 * don't keep a dog and bark yourself
 * don't look a gift horse in the mouth
 * don't put all your eggs in one basket
 * don't shit in your own nest
 * don't shit where you eat
 * don't shoot the messenger
 * don't sweat the small stuff
 * don't take any wooden nickels
 * don't try to teach grandma how to suck eggs
 * e pluribus unum
 * each to his own
 * early bird catches the worm
 * early to bed, early to rise, makes a man healthy, wealthy and wise
 * easy come, easy go
 * eat to live, not live to eat
 * eat, drink and be merry
 * eat, drink and be merry for tomorrow we die
 * eaten bread is soon forgotten
 * empty vessels make the most sound
 * enough is as good as a feast
 * even a blind pig can find an acorn
 * even a blind pig can find an acorn once in a while
 * even Homer nods
 * even Jove nods
 * every cloud has a silver lining
 * every dark cloud has a silver lining
 * every day is a school day
 * every dog has his day
 * every dog has its day
 * every dog must have his day
 * every dog must have its day
 * every Jack has his Jill
 * every king needs a queen
 * every law has its loophole
 * every little bit helps
 * every little helps
 * every man has a price
 * every man is the architect of his own fortune
 * every rose has a thorn
 * every rose has its thorn
 * every rule has an exception
 * every shut eye isn't asleep
 * every silver lining has a cloud
 * experience is the best teacher
 * eye for an eye, a tooth for a tooth
 * fair exchange is no robbery
 * faith will move mountains
 * familiarity breeds contempt
 * feed a cold, starve a fever
 * finders, keepers
 * finders, keepers; losers, weepers
 * fine feathers make fine birds
 * fine words butter no parsnips
 * first catch your hare
 * first come, first served
 * fish and company stink after three days
 * fool me once, shame on you; fool me twice, shame on me
 * fools rush in where angels fear to tread
 * forbidden fruit is the sweetest
 * forewarned is forearmed
 * forewarned, forearmed
 * fortune favors the bold
 * fortune favors the brave
 * fortune favours the bold
 * fortune favours the brave
 * garbage in, garbage out
 * genius is one percent inspiration, ninety-nine percent perspiration
 * give a man a fish
 * give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime
 * give him enough rope and he'll hang himself
 * give someone an inch and they'll take a mile
 * give them an inch and they'll take a mile
 * give them an inch and they'll take an ell
 * given enough eyeballs, all bugs are shallow
 * go hard or go home
 * God helps them that help themselves
 * God helps them who help themselves
 * God helps those who help themselves
 * God is in the detail
 * God works in mysterious ways
 * good fences make good neighbors
 * good fences make good neighbours
 * good things come to those who wait
 * good wine needs no bush
 * grasp all, lose all
 * great haste makes great waste
 * great minds
 * great minds think alike
 * great oaks from little acorns grow
 * half a loaf is better than no bread
 * half a loaf is better than no loaf
 * half a loaf is better than none
 * handsome is as handsome does
 * handsome is that handsome does
 * haste makes waste
 * haters gonna hate
 * he that mischief hatches, mischief catches
 * he who can, does, he who cannot, teaches
 * he who digs a pit for others, falls in himself
 * he who laughs last laughs best
 * he who laughs last laughs hardest
 * he who pays the piper calls the tune
 * he who smelt it dealt it
 * he who sups with the devil should have a long spoon
 * heaven helps those that help themselves
 * hell hath no fury like a woman scorned
 * here today, gone tomorrow
 * hic Rhodus, hic salta
 * history repeats itself
 * home is where the heart is
 * home is where you hang your hat
 * honesty is the best policy
 * honey catches more flies than vinegar
 * hope springs eternal
 * hope springs eternal in the human breast
 * hunger is a good sauce
 * hunger is the best sauce
 * hunger is the best spice
 * hunt where the ducks are
 * hydrate or diedrate
 * IAR
 * idle hands are the devil's playthings
 * idle hands are the Devil's playthings
 * idle hands are the devil's tools
 * idle hands are the Devil's tools
 * idle hands are the devil's workshop
 * idle hands are the Devil's workshop
 * if all you have is a hammer, everything looks like a nail
 * if at first you don't succeed
 * if at first you don't succeed, try try again
 * if it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck
 * if my aunt had balls, she'd be my uncle
 * if my grandmother had balls, she'd be my granddad
 * if my sister had balls, she'd be my brother
 * if my uncle had tits, he'd be my aunt
 * if pigs had wings they would fly
 * if the mountain won't come to Muhammad
 * if the mountain won't come to Muhammad, then Muhammad must go to the mountain
 * if there's grass on the field, play ball
 * if there's grass on the pitch, play ball
 * if we had ham we could have ham and eggs, if we had eggs
 * if we had some ham we could have some ham and eggs, if we had some eggs
 * if wishes were horses, beggars would ride
 * if you can't beat them, join them
 * if you can't do the time, don't do the crime
 * if you can't stand the heat, get out of the kitchen
 * if you find yourself in a hole, the first thing to do is stop digging
 * if you fly with the crows, you get shot with the crows
 * if you lie down with dogs, you get up with fleas
 * if you lie with dogs you will get fleas
 * if you mess with the bull, you get the horns
 * if you pay bananas, you get monkeys
 * if you pay peanuts, you get monkeys
 * if you torture the data long enough, it will confess to anything
 * if you want a thing done well, do it yourself
 * ignore all rules
 * ill news spreads apace
 * in for a dime, in for a dollar
 * in for a penny, in for a pound
 * in for an inch, in for a mile
 * in the country of the blind, the one-eyed man is king
 * in the land of the blind, the one-eyed man is king
 * in the valley of the blind, the one-eyed man is king
 * in unity, there is strength
 * in vino veritas
 * in wine, there is truth
 * it ain't over 'til the fat lady sings
 * it ain't over till the fat lady sings
 * it ain't the meat, it's the motion
 * it ain't the whistle that pulls the train
 * it is a wise child that knows his own father
 * it is all fun and games until someone loses an eye
 * it is always darkest before the dawn
 * it is always darkest just before the dawn
 * it is darkest before the dawn
 * it is darkest just before the dawn
 * it is easier for a camel to go through the eye of a needle than for a rich man to enter into the kingdom of God
 * it is easy to find a stick to beat a dog
 * it is not the whistle that pulls the train
 * it is what it is
 * it isn't the whistle that pulls the train
 * it never rains but it pours
 * it never rains but that it pours
 * it pays to advertise
 * it takes a heap o' livin' to make a house a home
 * it takes a heap of living to make a house a home
 * it takes a lot of living to make a house a home
 * it takes all kinds
 * it takes all kinds to make a world
 * it takes all sorts
 * it takes all sorts to make a world
 * it takes one to know one
 * it takes two to make a quarrel
 * it takes two to quarrel
 * it takes two to tango
 * it took Nixon to go to China
 * it's a long road that has no turning
 * it's an ill bird that fouls its own nest
 * it's an ill wind
 * it's an ill wind that blows no good
 * it's an ill wind that blows no one any good
 * it's an ill wind that blows nobody any good
 * it's better to ask forgiveness than permission
 * it's never too late to mend
 * it's not the meat, it's the motion
 * it's not the whistle that pulls the train
 * it's not what you know but who you know
 * it's the hit dog that howls
 * it's the thought that counts
 * judge not, that ye be not judged
 * judge not, that you be not judged
 * justice delayed is justice denied
 * justice is blind
 * keep your friends close, and your enemies closer
 * kids will be kids
 * know thyself
 * knowing is half the battle
 * knowledge is power
 * ladies first
 * laughter is the best medicine
 * least said, soonest mended
 * leave with the one that brought ya
 * leave with the one that brung ya
 * leave with the one that brung you
 * leave with the one what brought ya
 * leave with the one what brought you
 * leave with the one what brung ya
 * leave with the one what brung you
 * leave with the one who brought ya
 * leave with the one who brought you
 * leave with the one who brung ya
 * leave with the one who brung you
 * leaves of three, let it be
 * less is more
 * let a thousand flowers bloom
 * lex dubia non obligat
 * life is like a box of chocolates
 * life is not all beer and skittles
 * life is short
 * life's a bitch and then you die
 * lightning never strikes twice in the same place
 * like father like son
 * like father, like son
 * like mother, like daughter
 * little pitchers have big ears
 * little pitchers have long ears
 * little strokes fell great oaks
 * live and let live
 * live by the sword, die by the sword

 * Set phrases
 * all in all
 * all of a sudden
 * all of the sudden
 * one day
 * sooner or later


text:
магниттік

Etymology
. From.

Adjective

 * 1) magnetic

title: магниттік


text:
miembra

Usage notes

 * The Real Academia Española advises against the use of miembra

title: miembra


text: niángjiā

title: niángjiā


text:
lapillopsid

Noun

 * 1) Any extinct temnospondyl amphibian of the family †

title: lapillopsid


text: lapillopsids

title: lapillopsids


text: terrazado

title: terrazado


text:
jumalatodistus

Noun

 * 1)  argument for the existence of God

title: jumalatodistus


text: bananenschillen

title: bananenschillen


text:
laterocone

Noun

 * 1) A small pointed cusp on the lateral side of the incisors of some plesiadapiforms

title: laterocone


text: laterocones

title: laterocones


text:
тағатсыздану

Noun

 * 1) impatience
 * 2) anxiety

Verb

 * 1) to be impatient
 * 2) to be anxious
 * 3) to worry

title: тағатсыздану


text: bandbreedtes

title: bandbreedtes


text:
leptothecate

Noun

 * 1) Any hydrozoan of the order

title: leptothecate


text: leptothecates

title: leptothecates


text:
sesquizygotic

Etymology
From.

Adjective

 * 1) Describing twins which are semi-identical, formed from one egg that is fertilized by two separate sperm.

title: sesquizygotic


text: Thesaurus:規則

title: Thesaurus:規則


text:
бұқарашылдық

Etymology
.

Noun

 * 1) democratism

title: бұқарашылдық


text:
lignitize

Verb

 * 1) To convert to lignite

title: lignitize