Module:bibliography/ref

Hello, you have come here looking for the meaning of the word Module:bibliography/ref. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:bibliography/ref, but we will also tell you about its etymology, its characteristics and you will know how to say Module:bibliography/ref in singular and plural. Everything you need to know about the word Module:bibliography/ref you have here. The definition of the word Module:bibliography/ref will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:bibliography/ref, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.


local export = {}

local tag_text = require("Module:script utilities").tag_text
local get_lang = require("Module:languages").getByCode
local utils = require("Module:bibliography/utils")

-- Understands if a number refers to one or multiple instances of something (e.g. pages, sections) and pluralises the label accordingly.
local function format_number_label(value, label)
	if type(label) == "table" then
		label = label
	end
	return label..value
end

-- Handles the set_page, set_id, etc. functions within page_url, entry_url, etc. nodes.
local function apply_param_setter(arg_name, setter, input_data)
	local input_value = input_data
	-- simple addition or subtraction
	if type(setter) == "number" and input_value then
		return input_value + setter
	-- operations as strings
	-- TODO: needs to be stricter with invalid inputs
	elseif type(setter) == "string" and input_value then
		-- separate the different actions within the setter string (operations, alterations)
		local operations = setter:match("^(*)")
		local esc_operations = "^"..operations:gsub("()", "%%%1")
		local alterations = setter:match(esc_operations.."(>+)")
		assert(alterations or not setter:match(esc_operations.."."), "Invalid string as set_page: "..setter)
		-- apply arithmetic operations
		local function calculate_operation(num, operations)
			assert(operations:gsub("() *(%d+)", function(operation, operation_num)
				num = ({
					 = function(a, b) return a + b end,
					 = function(a, b) return a - b end,
					 = function(a, b) return a * b end,
					 = function(a, b) return math.floor(a / b) end,
				})(num, tonumber(operation_num))
				return ""
			end):match("^ *$"), "Invalid operation in set_page: "..setter)
			return num
		end
		input_value = calculate_operation(input_value, operations)
		-- apply alterations (e.g. for missing or duplicate pages)
		if alterations then
			assert(alterations:gsub("> *(%d+) *(*)", function(alteration_from, alteration_operation)
				if input_data > tonumber(alteration_from) then
					input_value = calculate_operation(input_value, alteration_operation)
				end
				return ""
			end):match("^ *$"), "Invalid alteration in set_page: "..setter)
		end
		return input_value
	-- full function for complex operation
	elseif type(setter) == "function" then
		return setter(input_data)
	end
end

-- Handles page_url, entry_url, etc.
local function param_url(source, const_data, param_name)
	if not const_data then return nil end
	local input_data = {}
	for k, v in pairs(const_data) do
		if not source.unprocess_numbers and type(v) == "string"
			and v:match("^%d+") and (k == "page" or k == "volume") then
			-- TODO: understand if it is allowed to have non-standard parameters into the arguments
			-- table which is given to the module. we could set numerical = true inside that table
			v = tonumber(v:match("^%d+"))
		end
		input_data = v
	end
	local url_config, link_node
	if input_data.volume and source.volumes and source.volumes then
		local current_volume = source.volumes
		if current_volume then
			url_config = current_volume
			link_node = current_volume.link
		end
	end
	url_config = url_config or source
	if not url_config then return nil end
	if type(url_config) ~= "table" then
		url_config = { url = url_config }
	else
		-- applies setters
		for set_arg, set_value in pairs(url_config) do
			if set_arg:match("^set_")	then
				set_arg = set_arg:gsub("^set_", "")
				input_data = apply_param_setter(set_arg, set_value, input_data)
			end
		end
	end
	link_node = link_node or source.link
	-- percent encodes entry name
	if input_data.entry then
		input_data.entry = mw.uri.encode(input_data.entry)
	end
	-- formats the URL
	local function resolve_value(site_key)
		local value = url_config
		-- recycle data from stable links
		if value == true then
			value = link_node
		end
		if not value then error("Could not retrieve the "..site_key.." data for "..param_name) end
		-- if a function, runs it
		if type(value) == "string" then
			return value
		elseif type(value) == "function" then
			return value(input_data)
		end
		error("Could not define "..param_name.." URL from the site "..site_key)
	end
	if url_config.ia then
		return "https://archive.org/details/"..resolve_value("ia")
			.."/page/"..(url_config.pref or "n")
			..input_data.page.."/mode/1up?view=theater"
	elseif url_config.gb then
		return "https://books.google.com/?id="..resolve_value("gb").."&pg="..(url_config.pref or "PA")..input_data.page
	elseif url_config.url then
		local do_break = false
		local ret = resolve_value("url"):gsub("%$(*)%$", function (wanted_param_list)
			local param_ret
			for wanted_param in wanted_param_list:gmatch("*") do
				param_ret = input_data
				if param_ret then break end
			end
			if not param_ret then do_break = true end
			return param_ret
		end)
		if do_break then return end
		return ret
	end
	error("No URL could be made")
end

-- load sources data from submodule
local function get_submodule_data(input_lang, input_sid)
	local submodule_data = require("Module:bibliography/data/"..input_lang)
	-- find the source in among data
	local source, sid = (function ()
		local sources = submodule_data.sources
		-- simply return the source if easily accessible
		if sources then
			return sources, input_sid
		end
		for iter_sid, iter_source in pairs(sources) do
			-- maybe if stripped it is the same
			if utils.is_abbrev(iter_sid) then
				if utils.strip_markup(iter_sid) == input_sid then
					return iter_source, iter_sid
				end
			end
			-- try with the aliases
			local alias = iter_source.alias
			if alias then
				if type(alias) == "string" then
					if alias == input_sid then
						return iter_source, iter_sid
					end
				elseif type(alias) == "table" then
					for _, v in ipairs(alias) do
						if v == input_sid then
							return iter_source, iter_sid
						end
					end
				end
			end
		end
		error("could not find the source with the ID "..input_sid.." in the database ]")
	end)()
	-- handle importing
	if source.import_from then source, sid, input_lang = get_submodule_data(source.import_from, sid) end
	-- deduce the bib_page
	local bib_page = submodule_data.bib_page
	if not bib_page then
		bib_page = get_lang(input_lang, "could not deduce the page to link to from invalid language code", true, true):getCanonicalName()
	end
	return source, sid, input_lang, "Appendix:Bibliography/"..bib_page
end

function export.show(frame)
	-- universal parameters
	local list_allow_holes = { list = true, allow_holes = true }
	local list_entry_alias = { list = true, alias_of = "entry" }
	local list_page_alias = { list = true, alias_of = "page" }
	local list_section_alias = { list = true, alias_of = "section" }
	local volume_alias = { list = true, alias_of = "volume" }
	local params = {
		-- language
		 = true,
		-- source id
		 = true,
		-- headword
		 = list_allow_holes,
		 = list_entry_alias,
		 = list_entry_alias,
		 = list_entry_alias,
		 = list_entry_alias,
		-- page
		 = list_allow_holes,
		 = list_page_alias,
		 = list_page_alias,
		-- section
		 = list_allow_holes,
		 = list_section_alias,
		 = list_section_alias,
		-- volume
		 = list_allow_holes,
		 = volume_alias,
		 = volume_alias,
		-- sub entries
		 = list_allow_holes,
		-- entry ID
		 = list_allow_holes,
	}
	local args = frame:getParent().args
	local source, sid, tracking_lang, bib_page = get_submodule_data(args, args)
	-- source-specific parameters and displays
	local own_display = {}
	if source.own_args then
		for arg_name, arg_data in pairs(source.own_args) do
			if arg_data.list and arg_data.allow_holes == nil then
				-- lists will be automatically assumed to 
				arg_data.allow_holes = true
			end
			if arg_data.display then
				local display_after = arg_data.display.after or "entry"
				arg_data.display.after = nil
				arg_data.display.name = arg_name
				if not own_display then own_display = {} end
				table.insert(own_display, arg_data.display)
			end
			params = arg_data
		end
	end
	args = require("Module:parameters").process(frame:getParent().args, params)
	args, args = nil, nil
	args.pagename = mw.title.getCurrentTitle().text
	-- display the source, and handle arguments if different
	args.sid_display = utils.format(sid)
	args.sid = utils.strip_markup(sid)
	if source.default_pagename then
		if #args.entry == 0 then
			args.entry = args.pagename
			args.entry.maxindex = 1
		elseif #args.entry == 1 and args.entry == "-" then
			args.entry = nil
			args.entry.maxindex = 0
		end
	end
	-- apply the set_args parameter
	if source.set_args then
		local function apply_general_setter(setter)
			if type(setter) == "function" then
				setter(args)
			elseif type(setter) == "string" then
				require("Module:bibliography/presets")(args)
			elseif type(setter) == "table" then
				if #setter > 0 then
					for _, setter_child in ipairs(setter) do
						apply_general_setter(setter_child)
					end
				-- TODO: understand whether this is really needed or just complicates syntax
				elseif setter.from and setter.to and setter.setter then
					for index, from in ipairs(args) do
						if not args then
							args = setter.setter(from)
						elseif args == "-" then
							args = nil
						end
					end
				end
			end
		end
		apply_general_setter(source.set_args)
	end
	local ret = "]"
	-- tracks the source being cited
	require("Module:debug/track")(utils.tracking_path(tracking_lang, args.sid))
	-- handle parameters
	local i = 0
	local current_volume
	while true do i = i + 1
		local cit_data = {}
		local is_data_over = true
		for arg_name, arg in pairs(args) do
			if type(arg) == "table" then
				if arg then
					is_data_over = false
					cit_data = arg
				end
			else
				cit_data = arg
			end
		end
		if is_data_over then break end
		local is_separator_needed = false
		local function format_display_table(arg_data)
			local arg_name = arg_data.name
			local value = cit_data
			if not value then return end
			if arg_data.label then
				value = format_number_label(value, arg_data.label)
			end
			if arg_data.url then
				local value_url = param_url(source, cit_data, arg_name)
				if value_url then value = "" end
			end
			if arg_data.formatter then
				value = arg_data.formatter(value, cit_data, source) or value
			end
			if is_separator_needed and arg_data.separator then
				value = arg_data.separator..value
			end
			ret = ret..value
			is_separator_needed = true
		end
		local function format_own_display_table_list(own_display_table_list)
			if own_display_table_list then
				for _, own_display_table in ipairs(own_display_table_list) do
					format_display_table(own_display_table)
				end
			end
		end
		ret =  ret..((cit_data.volume and i > 1) and "; " or ", ")
		-- VOLUME
		if cit_data.volume then
			format_display_table { name = "volume", label = "vol. " }
			current_volume = cit_data.volume
			ret = ret..", "
		elseif current_volume then
			cit_data.volume = current_volume
		end
		format_own_display_table_list(own_display.volume)
		-- SECTION
		format_display_table {
			name = "section",
			label = {"§", "§§"},
			url = true,
		}
		format_own_display_table_list(own_display.section)
		-- PAGE
		format_display_table {
			name = "page",
			separator = " ",
			label = {"page ", "pages "},
			url = true,
		}
		format_own_display_table_list(own_display.page)
		-- ENTRY
		format_display_table {
			name = "entry",
			separator = ": ",
			url = true,
			formatter = function(entry, cit_data, source)
				local sub = cit_data.sub
				if source.entry_lang then
					entry = tag_text(entry, get_lang(source.entry_lang))
					if sub then sub = tag_text(sub, get_lang(source.entry_lang)) end
				end
				if sub then entry = entry.."” → “"..sub end
				entry = entry:gsub("()%^(%d+)", "%1<sup>%2</sup>")
				return "“"..entry.."”"
			end
		}
		format_own_display_table_list(own_display.entry)
	end
	return ret
end

return export