Module:Quotations

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

This module is used by Template:Q.

Coding

The intent of this module was to make a quotations library which can be built and used asynchronously. An editor can reference a work or author which is not yet coded, and the display will still look fine, and if the information is later coded, the template will make use of it at that time.

Language modules

Each language needs its own data module, such as that found at Module:Quotations/grc/data, which is processed by the methods in the main module. Additional methods may be added for processing the data at, for example, Module:Quotations/grc, which is used as a starting point for building the language module. If this does not exist, the methods in the main module will still be available.

The data module should be a table, with entries for each author. Each author table should include information about the author, such as years active and the title of the Wikipedia article for the author, as well as tables for each of its works, with information such as the year the work was written, the title of its Wikipedia article, and the title of its Wiksource article. Alias tables can be used for convergence, such as when a work might have two common titles, as well as abbreviations.

Note that the module is designed to work with whatever data is available, and it should not be considered necessary to add all possible data; some is better than none.

Note: In order for a language module to be recognized, the corresponding language code must be added to the hasData table in this module.

One of the more complex aspects of coding the data set lies in the reference link, which is meant to be a fairly dynamic link which formats itself to account for information given. It is formatted in the author's data table as a table of strings and tables. Strings not prefixed by a period are inserted as is. Strings prefixed with a period indicate variable references. Tables which begin with a function run that function with the table's following elements as parameters. Tables not beginning with a function are nested variable addresses. Take the reference link format table data.Plato.rlFormat2, which is used solely by Plato's Republic:

{'s:el:', '.rlTitle', '/', {'.chapterSelect', {'authorData', 'republicChapters'}, '.ref1'}, '#p', '.ref1', {'.lower', '.ref2'} }

The first element, 's:el', is a simple string, and will be inserted as-is into the link target; it is the prefix for the Greek Wikisource, where a native language version of The Republic is found.

The second element, '.rlTitle', begins with a period, indicating that it should be replaced by the variable 'rlTitle', which is given in The Republic’s data table as 'Πολιτεία'.

The third element, '/', is a standard string, and will be inserted into the link as-is.

The fourth element is a function call, using the function chapterSelect, which is called with two parameters. The second parameter is the variable ref1, which is the chapter given by the user. The first parameter is formatted as a nested reference, it will be the variable republicChapters, which is found within data.Plato.

There is no getting around the fact that it is not the easiest format in the world, but it does make for a powerful and flexible engine to interpret data and create the proper link.

If the source is not wikilinkable, then you'll need an external reference link instead of a reference link. You can use the same method as reference links, except use '.xrlFormat' instead of '.rlFormat', and the URL to link to is the '.xurl' parameter for the work. For example:

data.xrlFormat1 = {'.xurl'}

data.works = {

		 = { = 'c. 334–337',  = 'https://archive.org/details/matheseoslibrivi02firmuoft',  = 1}

}

Language-specific submodules




-- Prevent substitution.
if mw.isSubsting() then
	return require("Module:unsubst")
end

local export = {}

local debug_track_module = "Module:debug/track"
local foreign_numerals_module = "Module:foreign numerals"
local functions_module = "Module:fun"
local languages_module = "Module:languages"
local links_module = "Module:links"
local load_module = "Module:load"
local quotations_date_validation_module = "Module:Quotations/date validation"
local script_utilities_module = "Module:script utilities"
local string_nowiki_module = "Module:string/nowiki"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local utilities_module = "Module:utilities"

local add_warning = mw.addWarning
local byte = string.byte
local concat = table.concat
local find = string.find
local floor = math.floor
local format = string.format
local insert = table.insert
local match = string.match
local rep = string.rep
local require = require
local sub = string.sub
local tonumber = tonumber
local tostring = tostring
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility

--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function date_validation(...)
	date_validation = require(quotations_date_validation_module).main
	return date_validation(...)
end

local function format_categories(...)
	format_categories = require(utilities_module).format_categories
	return format_categories(...)
end

local function get_lang(...)
	get_lang = require(languages_module).getByCode
	return get_lang(...)
end

local function is_callable(...)
	is_callable = require(functions_module).is_callable
	return is_callable(...)
end

local function is_Latin_script(...)
	is_Latin_script = require(script_utilities_module).is_Latin_script
	return is_Latin_script(...)
end

local function keys_to_list(...)
	keys_to_list = require(table_module).keysToList
	return keys_to_list(...)
end

local function lang_err(...)
	lang_err = require(languages_module).err
	return lang_err(...)
end

local function language_link(...)
	language_link = require(links_module).language_link
	return language_link(...)
end

local function load_data(...)
	load_data = require(load_module).load_data
	return load_data(...)
end

local function nowiki(...)
	nowiki = require(string_nowiki_module)
	return nowiki(...)
end

local function remove_links(...)
	remove_links = require(links_module).remove_links
	return remove_links(...)
end

local function safe_require(...)
	safe_require = require(load_module).safe_require
	return safe_require(...)
end

local function split(...)
	split = require(string_utilities_module).split
	return split(...)
end

local function tag_text(...)
	tag_text = require(script_utilities_module).tag_text
	return tag_text(...)
end

local function tag_transcription(...)
	tag_transcription = require(script_utilities_module).tag_transcription
	return tag_transcription(...)
end

local function tag_translit(...)
	tag_translit = require(script_utilities_module).tag_translit
	return tag_translit(...)
end

local function to_Devanagari(...)
	to_Devanagari = require(foreign_numerals_module).to_Devanagari
	return to_Devanagari(...)
end

local function track(...)
	track = require(debug_track_module)
	return track(...)
end

local function ugsub(...)
	ugsub = require(string_utilities_module).gsub
	return ugsub(...)
end

local function ulower(...)
	ulower = require(string_utilities_module).lower
	return ulower(...)
end

local function uupper(...)
	uupper = require(string_utilities_module).upper
	return uupper(...)
end

local LanguageModule = {}
LanguageModule.__index = LanguageModule
LanguageModule.period = "."

local hasData = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}
export.hasData = hasData

function export.create(frame)
	return export.Create(frame:getParent().args, frame)
end

local function warn_about_unrecognized_args(unrecognized_args)
	track("Quotations/param error")
	add_warning('Unrecognized parameters in ' .. nowiki('{{Q}}: ' .. concat(keys_to_list(unrecognized_args), ', ')))
end

function export.Create(args, frame)
	-- Set up our initial variables; set empty parameters to false
	local processed_args = {}
	local unrecognized_args = {}
	local params = {
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true,
		 = true, -- This is simply ignored if quote is in Latin script.
		 = true, -- This is simply ignored if quote is in Latin script.
		 = true, -- This is simply ignored if quote is in Latin script.
		 = true,
	}

	local max_numbered_param = 4
	for k, v in pairs(args) do
		if type(k) == 'number' then
			if k > max_numbered_param then
				max_numbered_param = k
			end
		elseif not params then
			unrecognized_args = v
		end
		
		if v == '' then
			if k == "lang" then
				processed_args = nil
			else
				processed_args = false
			end
		else
			processed_args = v
		end
	end
	
	if next(unrecognized_args) then
		warn_about_unrecognized_args(unrecognized_args)
	end
	
	-- Ensure that all numbered parameters up to the greatest numbered parameter
	-- are not nil.
	for i = 1, max_numbered_param do
		processed_args = processed_args or false
	end
	
	-- Apply aliases.
	-- This should be cleaned up when more robust parameter parsing is implemented.
	processed_args = processed_args or processed_args or processed_args
	
	args = processed_args -- Overwrite original args.
	
	local lang = args
	lang = get_lang(lang) or lang_err(lang, 1)
	
	local ante = {}
	
	if hasData then
		local m_langModule = LanguageModule.new(lang)
		ante = m_langModule:expand(args)
	else
		track("Quotations/no data")
		track("Quotations/no data/" .. lang:getCode())
	end
	
	if ante.author == nil then
		ante.author = args
	end
	if ante.work == nil then
		ante.work = args
	end
	if ante.ref == nil then
		local ref = {}
		for i = 4, 10 do
			if args then
				insert(ref, args)
			else
				break
			end
		end
		ante.ref = concat(ref, '.')
	end
	
	for k in pairs(args) do
		if type(k) ~= "number" then
			ante = args
		end
	end

	local penult = { = '',  = '',  = '',  = '',  = '',  = '',
		 = '',  = '',  = {},  = '',  = '',
		 = '',  = '',  = ''}
	local comma = false
	--Language specific modules are responsible for first line parameters.
	--Base formatting module will poll for other parameters,
	--pulling them only if the language module hasn't returned them.

	local otherOtherLineStuff = {'quote', 'transyear', 'transauthor', 'trans', 'termlang'}
	for _, item in ipairs(otherOtherLineStuff) do
		ante = ante or args
	end

	if not ante.code then
		penult.elAttr = ' class="wiktQuote" data-validation="white">'
	else
		penult.elAttr = ' class="wiktQuote" data-validation="' .. ante.code .. '">'
	end
	if ante.year then
		penult.year = "'''" .. date_validation(ante.year) .. "'''"
		comma = true
	end
	if ante.author then
		penult.s1 = (comma and ', ' or '')
		penult.author = ante.author
		comma = true
	end
	if ante.work then
		penult.s2 = (comma and ', ' or '')
		penult.work = ante.work
		comma = true
	end
	if ante.object then
		penult.s5 = (comma and ' ' or '')
		penult.object = '(' .. ante.object .. ')'
		comma = true
	end
	if ante.ref and ante.ref ~= '' then
		penult.s3 = (comma and ' ' or '')
		penult.ref = ante.ref
	end
	if ante.style == 'no' or penult.work == '' then
		-- Leave as-is
	elseif ante.style == 'q' then
		penult.work = '“' .. penult.work .. '”'
	else
		penult.work = "''" .. penult.work .. "''"
	end
	if ante.termlang then
		ante.termlang = get_lang(ante.termlang) or lang_err(ante.termlang, 1)
		penult.termlang = ' (in ' .. lang:getCanonicalName() .. ')'
	end
	
	local form = args or 'full'
	local ultimate
	if form == 'full' then
		local categories = {}

		if ante.notes then
			penult.s4 = (comma and ', ' or '')
			penult.notes = '(' .. ante.notes .. ')'
		end

		if ante.refn and frame then
			penult.refn = frame:preprocess(ante.refn)
		end
		
		if ante.t then
			ante.trans = ante.t
		end
		
		if ante.quote or (ante.trans and ante.trans ~= "-") then
			penult.refn = ":" .. penult.refn
			local translitwithtrans = false
			insert(penult.otherLines, "<dl><dd>")
			if ante.quote then
				local sc = lang:findBestScript(ante.quote)
				local quote = ante.quote
				-- fix up links with accents/macrons/etc.
				if find(quote, "[[", 1, true) then
					 quote = language_link{term = quote, lang = lang}
				end
				insert(penult.otherLines, tag_text(quote, lang, sc, nil, "e-quotation"))
				if args.nocat then
					track("Quotations/nocat")
				elseif ante.termlang then
					insert(categories, ante.termlang:getCanonicalName() .. " terms with quotations")
				else
					insert(categories, lang:getCanonicalName() .. " terms with quotations")
				end
				if not is_Latin_script(sc) or lang:getCode() == "egy" then
					-- Handle subst=		
					local subbed_quote = remove_links(quote)
					if args.subst then
						local substs = split(args.subst, ",")
						for _, subpair in ipairs(substs) do
							local subsplit = split(subpair, find(subpair, "//", 1, true) and "//" or "/")
							subbed_quote = ugsub(subbed_quote, subsplit, subsplit)
						end
					end

					local transliteration = args.tr or (lang:transliterate(subbed_quote, sc))
					if transliteration then
						transliteration = "<dd>" .. tag_translit(transliteration, lang, "usex") .. "</dd>"
					end
					local transcription = args.ts and "<dd>/" .. tag_transcription(args.ts, lang, "usex") .. "/</dd>"
					if transliteration or transcription then
						local translitend = "</dl>"
						if ante.trans and ante.trans ~= "-" and not ante.transyear and not ante.transauthor then
							translitwithtrans = true
							translitend = ""
						end
						insert(penult.otherLines, "<dl>" .. (transliteration or "") .. (transcription or "") .. translitend)
					end
				end
			end

			if ante.trans == "-" then
				ante.trans = nil
				insert(categories, "Omitted translation in the main namespace")
			elseif ante.trans then
				local litline = ""
				if ante.lit then
					litline = "<dd>(literally, “" .. ante.lit .. "”)</dd>"
				end
				if ante.transyear or ante.transauthor then
					insert(penult.otherLines, "<ul><li>")
					if ante.transyear then
						insert(penult.otherLines, "'''" .. ante.transyear .. "''' translation")
					else
						insert(penult.otherLines, "Translation")
					end
					if ante.transauthor then
						insert(penult.otherLines, " by " .. ante.transauthor)
					end
					insert(penult.otherLines, "<dl><dd>" .. ante.trans .. "</dd>" .. litline .. "</dl></li></ul>")
				else
					if not ante.quote then
						insert(penult.otherLines, ante.trans)
					else
						local transstart = "<dl><dd>"
						if translitwithtrans then
							transstart = "<dd>"
						end
						insert(penult.otherLines, transstart .. ante.trans .. "</dd>" .. litline .. "</dl>")
					end
				end
			elseif lang:getCode() ~= "en" and lang:getCode() ~= "und" then
				insert(penult.otherLines, "<dl><dd><small>(please ] of this quotation)</small>")
				-- add trreq category if translation is unspecified and language is not English or undetermined
				insert(categories, "Requests for translations of " .. lang:getCanonicalName() .. " quotations")
			end
			insert(penult.otherLines, "</dd></dl>")
		end
		penult.otherLines = concat(penult.otherLines)
		
		ultimate = '<div' .. penult.elAttr .. penult.year .. penult.s1 .. penult.author .. penult.s2 .. penult.work .. penult.termlang .. penult.s5 .. penult.object .. penult.s3 .. penult.ref .. penult.s4 .. penult.notes .. penult.refn .. penult.otherLines .. '</div>' .. format_categories(categories, lang)
	elseif form == 'inline' then
		ultimate = '<span' .. penult.elAttr .. penult.author .. penult.s2 .. penult.work .. penult.termlang .. penult.s5 .. penult.object .. penult.s3 .. penult.ref .. '</span>'
	elseif form == 'work' then
		ultimate = '<span' .. penult.elAttr .. penult.work .. penult.termlang .. penult.s5 .. penult.object .. penult.s3 .. penult.ref .. '</span>'
	elseif form == 'ref' then
		ultimate = '<span' .. penult.elAttr .. penult.ref .. '</span>'
	end
	return ultimate

end

function LanguageModule.new(lang)
	local sema = safe_require("Module:Quotations/" .. lang:getCode()) or {}
	sema.library = load_data("Module:Quotations/" .. lang:getCode() .. "/data")
	return setmetatable(sema, LanguageModule)
end

function LanguageModule:changeCode(color)
	if color == 'orange' then
		self.code = 'orange'
	end
	if (color == 'yellow') and (self.code == 'green') then
		self.code = 'yellow'
	end
end

function LanguageModule:reroute(route)
	local temp = {}
	local data = self.library.data
	
	for k, v in pairs(route) do
		temp = self:interpret(v)
	end
	
	for k, v in pairs(temp) do
		self = v
	end
	
	if self.author ~= nil and data then
		self.aData = data
		if self.work ~= nil and self.aData.works then
			self.wData = self.aData.works
		end
	end
end

function LanguageModule:lower(input)
	return input ~= nil and ulower(input) or nil
end

function LanguageModule:upper(input)
	return input ~= nil and uupper(input) or nil
end

function LanguageModule:isLetter(input)
	return not tonumber(input)
end

function LanguageModule:digits(width, num)
	return format('%' .. width .. 'd', num)
end

function LanguageModule:numToDeva(input)
	return input ~= nil and to_Devanagari(input) or nil
end

function LanguageModule:separ(values, separator)
  return concat(values, separator)
end

function LanguageModule:roundDown(period, verse)
	if tonumber(verse) then
		return floor(verse / period) * period
	end
	self:changeCode('orange')
end

function LanguageModule:chapterSelect(rubric, verse)
	verse = tonumber(match(verse, "^%d+"))
	for k, v in pairs(rubric) do
		if v <= verse and verse <= v then
			return k
		end
	end
	self:changeCode('orange')
end

function LanguageModule:interpret(item)
	local output
	if type(item) == 'string' then
		if #item > 1 and byte(item) == 0x2E then
			local address = sub(item, 2)
			local returnable = self or self.library.data.Sundry and self.library.data.Sundry
			output = returnable
		else
			output = item
		end
	elseif type(item) == 'table' then
	--If it's a table, it's either a function call or a nested address.
		local presumedFunction = self:interpret(item)
		if is_callable(presumedFunction) then
			local parameters = {}
			for i = 2, 30 do
				if item ~= nil then
					insert(parameters, self:interpret(item))
				else
					break
				end
			end
			output = presumedFunction(self, unpack(parameters))
		else
			local nested = self
			for i = 1, 30 do
				local address = item
				if address and nested then
					nested = nested
				else
					break
				end
			end
			output = nested
		end
	else
		output = item
	end
	return output
end

function LanguageModule:convert(scheme, initiate)
	if is_callable(scheme) then
		local initiate = tonumber(initiate) or initiate
		local converted = scheme(self, initiate)
		if converted == nil then
			self:changeCode('orange')
		end
		return converted
	elseif type(scheme) == "table" then
		local initiate = tonumber(initiate) or initiate
		local converted = scheme
		if converted == nil then
			self:changeCode('orange')
		end
		return converted
	end
	self:changeCode('orange')
end

function LanguageModule:numToRoman(item)
	local j = tonumber(item)
	if (j == nil) then
		return item
	end
	if (j <= 0) then
		return item
	end

	local ints = {1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,   5,  4,   1}
	local nums = {'M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I'}

	local result = ""
	for k = 1, #ints do
		local count = floor(j / ints)
		result = result .. rep(nums, count)
		j = j - ints * count
	end
	return result
end

-- Iterate through "array" and its sublevels. Find indices in "array" that
-- contain a string matching "valToFind". Return last index where that string
-- (minus its first letter) is the key for a field in "self", as well as last
-- index where that string was found.
-- Used to locate the place where the "rlformat" should be skipped out of,
-- because there's no ".ref" value supplied for what comes next.
-- For instance, if book but not line number has been supplied.
local function findLastValidRefIndex(self, array, valToFind)
	local lastValidIndex, lastIndex
	for i, val in ipairs(array) do
		if type(val) == 'table' then
			local res1, res2 = findLastValidRefIndex(self, val, valToFind)
			if res1 then
				lastValidIndex = i
			end
			if res2 then
				lastIndex = i
			end
		elseif type(val) == "string" and match(val, valToFind) then
			lastIndex = i
			if self then
				lastValidIndex = i
			end
		end
	end
	return lastValidIndex, lastIndex
end

function LanguageModule:expand(args)
	--Instantiate our variables.
	local results = {}
	self.code = 'green'
	local data = self.library.data

	self.author = args or args
	self.work = args or args
	
	for i = 1, 5 do
		local refName = 'ref' .. i
		local paramNumber = i + 3
		self = args or args
	end

	--Check if we've been given an author alias.
	if data.authorAliases then
		self.author = data.authorAliases
	end

	if not data then
		self:changeCode('yellow')
	else
		self.aData = data
		if self.aData.reroute then
			self:reroute(self.aData.reroute)
		else
			if self.aData.aliases and self.aData.aliases then
				self.work = self.aData.aliases
			end
			if not (self.aData.works and self.aData.works) then
				self:changeCode('yellow')
			else
				self.wData = self.aData.works
				if self.wData.reroute then
					self:reroute(self.wData.reroute)
				end
			end
		end
	end

	--Load all author-level data.
	if self.aData and self.aData.aLink then
		results.author = ']'
	else
		results.author = self.author
	end
	if self.aData and self.aData.year then
		results.year = self.aData.year
	end

	--If the database has a link for the work, incorporate it.
	if not self.wData or not self.wData then
		results.work = self.work
	else
		results.work = ' .. '|' .. self.work .. ']]'
	end
	
	--Some works have info which overrides the author-level info or fills other parameters.
	if self.wData then
		if self.wData then
			results.year = self.wData.year
		end
		if self.wData ~= nil then
			results.author = self.wData.author
		end
		if self.wData then
			results.object = self.wData.object
		end
		if self.wData then
			results.style = self.wData.style
		end
		if self.wData then
			results.refn = self.wData.refn
		end
	end
	
	self.thru = args or args
	--Custom formatter for displayed reference
	if self.aData and self.aData.rdFormat and self.aData.rdFormat.custom then
		local formatted = {}
		for _, current in ipairs(self.aData.rdFormat.custom) do
			insert(formatted, self:interpret(current))
		end
		self.refDisplay = concat(formatted)
	else
		--The displayed reference usually consists of all the ref argument(s) joined with a period.
		self.refDisplay = self.ref1 and '' or (self.wData and self.wData or false)
		local separator_num = 1
		for i = 1, 5 do
			local whichRef = 'ref' .. tostring(i)
			if self then
				local ref = self
				
				local separator
				-- no separator before a letter
				if umatch(ref, "^%a$") then
					separator = ""
				-- to allow colon between biblical chapter and verse
				elseif self.aData and self.aData.rdFormat and self.aData.rdFormat.separator then
					separator = self.aData.rdFormat.separator
				elseif self.aData and self.aData.rdFormat and self.aData.rdFormat.separators then
					separator = self.aData.rdFormat.separators
				else
					separator = "."
				end
				
				if i > 1 then
					self.refDisplay = self.refDisplay .. separator
					separator_num = separator_num + 1
				end
				self.refDisplay = self.refDisplay .. self
			else
				break
			end
		end
		if self.thru then
			self.refDisplay = self.refDisplay .. '–' .. self.thru
		end
	end
	
	-- Apply custom work formatting, if specified
	if self.wData and self.wData then
		self.workFormat = self.aData
	elseif self.aData and self.aData then
		self.workFormat = self.aData
	end
	if self.workFormat then
		results.style = 'no' -- Ignore/override style parameter
		local formatted = {}
		for _, current in ipairs(self.workFormat) do
			insert(formatted, self:interpret(current))
		end
		results.work = concat(formatted)
	end
	
	
	
	--[[	If the work is not in the database,
			or we don't have a source text link,
			the ref is simply the display.
			Otherwise, we have to create a reference link,
			easily the most challenging function of this script. ]]
	if self.wData and self.wData then
		self.rlFormat = self.aData
	elseif self.aData and self.aData then
		self.rlFormat = self.aData
	end
	if self.wData and self.rlFormat then
		self.rlTitle = self.wData
		
		-- Go through indices in "self.rlFormat" that contain a string
		-- beginning in ".ref" (either in the first level of "self.rlFormat"
		-- or a sublevel). Return the index of the string that has a
		-- corresponding field in "self", as well as the index of the last
		-- such string.
		local lastValidIndex, lastIndex = findLastValidRefIndex(self, self.rlFormat, '^%.ref(%d+)$')
		-- If there isn't another ".ref" string after the last valid index,
		-- then there is no need to cut short the rlFormat.
		self.refLink = {}
		if lastIndex and lastValidIndex and lastIndex > lastValidIndex then
			for i, current in ipairs(self.rlFormat) do
				if i > lastValidIndex then
					break
				end
				insert(self.refLink, self:interpret(current))
			end
		else
			for _, current in ipairs(self.rlFormat) do
				insert(self.refLink, self:interpret(current))
			end
		end
		self.refLink = concat(self.refLink)
	end
	if self.wData and self.wData then
		self.xrlFormat = self.aData
	elseif self.aData and self.aData then
		self.xrlFormat = self.aData
	end
	if self.xrlFormat then
		self.xurl = self.wData
		-- Go through indices in "self.xrlFormat" that contain a string
		-- beginning in ".ref" (either in the first level of "self.xrlFormat"
		-- or a sublevel). Return the index of the string that has a
		-- corresponding field in "self", as well as the index of the last
		-- such string.
		local lastValidIndex, lastIndex = findLastValidRefIndex(self, self.xrlFormat, '^%.ref(%d+)$')
		-- If there isn't another ".ref" string after the last valid index,
		-- then there is no need to cut short the rlFormat.
		self.xrefLink = {}
		if lastIndex and lastValidIndex and lastIndex > lastValidIndex then
			for i, current in ipairs(self.xrlFormat) do
				if i > lastValidIndex then
					break
				end
				insert(self.xrefLink, self:interpret(current))
			end
		else
			for _, current in ipairs(self.xrlFormat) do
				insert(self.xrefLink, self:interpret(current))
			end
		end
		self.xrefLink = concat(self.xrefLink)
	end
 	if self.refLink and self.refDisplay then
		results.ref = ']'
	elseif self.xrefLink and self.refDisplay then
		results.ref = ''
	else
		results.ref = self.refDisplay or ''
	end
	if args then
		results.notes = args.notes
	end
	results.code = self.code
	
	return results

end

return export