<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://maruneko.autumns.page/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AInterlinear</id>
	<title>Module:Interlinear - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://maruneko.autumns.page/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AInterlinear"/>
	<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Interlinear&amp;action=history"/>
	<updated>2026-04-04T09:59:56Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://maruneko.autumns.page/mediawiki/index.php?title=Module:Interlinear&amp;diff=7889&amp;oldid=prev</id>
		<title>Rox: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Interlinear&amp;diff=7889&amp;oldid=prev"/>
		<updated>2025-11-09T07:53:48Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:53, 9 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key jth_wiki:diff:1.41:old-7888:rev-7889 --&gt;
&lt;/table&gt;</summary>
		<author><name>Rox</name></author>
	</entry>
	<entry>
		<id>https://maruneko.autumns.page/mediawiki/index.php?title=Module:Interlinear&amp;diff=7888&amp;oldid=prev</id>
		<title>Wikipedia&gt;Santiago Claudio: Replaced &quot;oldstyle&quot; with &quot;lining&quot;</title>
		<link rel="alternate" type="text/html" href="https://maruneko.autumns.page/mediawiki/index.php?title=Module:Interlinear&amp;diff=7888&amp;oldid=prev"/>
		<updated>2024-09-06T09:54:50Z</updated>

		<summary type="html">&lt;p&gt;Replaced &amp;quot;oldstyle&amp;quot; with &amp;quot;lining&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
local data = mw.loadData( 'Module:Interlinear/data' )&lt;br /&gt;
local gloss_override = {} -- for custom gloss abbreviations&lt;br /&gt;
local getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
local yesno = require('Module:Yesno')&lt;br /&gt;
local lang_data = mw.loadData( 'Module:Lang/data' )&lt;br /&gt;
&lt;br /&gt;
--------------------------&lt;br /&gt;
-- Almost-global variables&lt;br /&gt;
--------------------------&lt;br /&gt;
local glossing_type, displaying_messages, free_translation, msg, buffer&lt;br /&gt;
&lt;br /&gt;
-------------------&lt;br /&gt;
-- General settings&lt;br /&gt;
-------------------&lt;br /&gt;
local conf = { --settings&lt;br /&gt;
	WordSeparator = &amp;quot; \n\r\t&amp;quot;, -- Don't replace with %s as this would include non-breaking spaces&lt;br /&gt;
	GlossAbbrPattern = &amp;quot;^([Ø0-9A-Z]+)$&amp;quot;, -- this isn't a full regex, but a Lua pattern&lt;br /&gt;
	-- NOTE: The following characters must be formatted for use in a pattern set.&lt;br /&gt;
	GlossAbbrBoundary = &amp;quot;-.,;:&amp;lt;&amp;gt;‹›/\\~+=%?%s%[%]()%_\127'&amp;quot;,&lt;br /&gt;
	GlossExcludeTable = {I = true,}, --strings not be treated as glossing abbreviations&lt;br /&gt;
	GlossExcludePattern = '^[0-9][0-9]+$', -- excludes strings consisting entirely of digits&lt;br /&gt;
	GlossSmallCapsExclude = &amp;quot;^[AOPS]$&amp;quot;, -- glossing abbreviations matching this pattern will not be rendered in small caps&lt;br /&gt;
	GlossingType = &amp;quot;label&amp;quot;, -- if set to &amp;quot;label&amp;quot; gloss abbreviations are formatted as an &amp;lt;abbr&amp;gt; with the &amp;quot;label&amp;quot; appearing in a tooltip&lt;br /&gt;
						-- if set to &amp;quot;wikilink&amp;quot; the abbreviation is formatted as a wikilink to the relevant wikipedia article&lt;br /&gt;
						-- if set to &amp;quot;none&amp;quot; abbreviations aren't formatted at all&lt;br /&gt;
	ErrorCategory = &amp;quot;[[Category:Pages with errors in interlinear text]]&amp;quot;,&lt;br /&gt;
	AmbiguousGlossCategory = &amp;quot;[[Category:Articles with ambiguous glossing abbreviations]]&amp;quot;,&lt;br /&gt;
	MessageGlossingError = &amp;quot;Error(s) in interlinear glossing&amp;quot;,&lt;br /&gt;
	combining_gender_numbers = &amp;quot;[0-9][0-9]?$&amp;quot;, --e.g. G4 '4th gender' or CL7 'class 7'&lt;br /&gt;
	combining_gender_prefixes = {G = &amp;quot;gender&amp;quot;, CL = &amp;quot;class&amp;quot;},&lt;br /&gt;
	combining_person = {[&amp;quot;1&amp;quot;] = &amp;quot;first person&amp;quot;, [&amp;quot;2&amp;quot;] = &amp;quot;second person&amp;quot;, [&amp;quot;3&amp;quot;] = &amp;quot;third person&amp;quot;,},&lt;br /&gt;
	combining_number = {&lt;br /&gt;
		S = &amp;quot;singular&amp;quot;, SG = &amp;quot;singular&amp;quot;,&lt;br /&gt;
		P = &amp;quot;plural&amp;quot;, PL = &amp;quot;plural&amp;quot;,&lt;br /&gt;
		D = &amp;quot;dual&amp;quot;, DU = &amp;quot;dual&amp;quot;,&lt;br /&gt;
		TRI = &amp;quot;trial&amp;quot;, PAU = &amp;quot;paucal&amp;quot;, COL = &amp;quot;collective&amp;quot;,&lt;br /&gt;
		IN = &amp;quot;inclusive&amp;quot;, INC = &amp;quot;inclusive&amp;quot;, INCL = &amp;quot;inclusive&amp;quot;,&lt;br /&gt;
		EX = &amp;quot;exclusive&amp;quot;, EXC = &amp;quot;exclusive&amp;quot;, EXCL = &amp;quot;exclusive&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	combining_gender = {F = &amp;quot;feminine&amp;quot;, M = &amp;quot;masculine&amp;quot;, N = &amp;quot;neuter&amp;quot;},&lt;br /&gt;
	LowerCaseGlosses = {&lt;br /&gt;
		[&amp;quot;1sg&amp;quot;] = true, [&amp;quot;2sg&amp;quot;] = true, [&amp;quot;3sg&amp;quot;] = true,&lt;br /&gt;
		[&amp;quot;1du&amp;quot;] = true, [&amp;quot;2du&amp;quot;] = true, [&amp;quot;3du&amp;quot;] = true,&lt;br /&gt;
		[&amp;quot;1pl&amp;quot;] = true, [&amp;quot;2pl&amp;quot;] = true, [&amp;quot;3pl&amp;quot;] = true,&lt;br /&gt;
		[&amp;quot;Fsg&amp;quot;] = true, [&amp;quot;Fpl&amp;quot;] = true, [&amp;quot;Msg&amp;quot;] = true, [&amp;quot;Mpl&amp;quot;] = true,&lt;br /&gt;
	}, -- these are the non-all-upper-case strings that will be recognised as glossing abbreviations&lt;br /&gt;
	ErrorHelpLocation = &amp;quot;Template:Interlinear&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- CSS styles and classes&lt;br /&gt;
---------------------&lt;br /&gt;
conf.style = { --CSS styles&lt;br /&gt;
	WordDiv = &amp;quot;float: left; margin-bottom: 0.3em;&amp;quot;,&lt;br /&gt;
	WordMargin = &amp;quot;margin-right: 1em;&amp;quot;,&lt;br /&gt;
	WordP = &amp;quot;margin: 0px;&amp;quot;, -- the style for the word &amp;lt;p&amp;gt; elements&lt;br /&gt;
	GlossAbbr = &amp;quot;font-variant: small-caps; font-variant-numeric: lining-nums; text-transform: lowercase; &amp;quot;, -- won't be applied to gloss abbreviations containing lower-case characters&lt;br /&gt;
	HiddenText = &amp;quot;display: none;&amp;quot;,&lt;br /&gt;
	EndDiv = &amp;quot;clear: left; display: block;&amp;quot;, -- style of the &amp;lt;div&amp;gt; element at the end of the interlinear display&lt;br /&gt;
	ErrorMessage = &amp;quot;font-size: inherit&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
conf.class = { --CSS classes&lt;br /&gt;
	Interlinear = &amp;quot;interlinear&amp;quot;,&lt;br /&gt;
	GlossAbbr  = &amp;quot;gloss-abbr&amp;quot;,&lt;br /&gt;
	GlossAbbrAmb = &amp;quot;gloss-abbr-ambiguous&amp;quot;,&lt;br /&gt;
	GlossAbbrError = &amp;quot;gloss-abbr-error&amp;quot;,&lt;br /&gt;
	ErrorMessage = &amp;quot;error&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
---------------------&lt;br /&gt;
-- Section transclusion&lt;br /&gt;
---------------------&lt;br /&gt;
local page_content = nil -- lazy initilization&lt;br /&gt;
local function get_section(frame, section_name)&lt;br /&gt;
	if page_content == nil then&lt;br /&gt;
		local current_title = mw.title.getCurrentTitle()&lt;br /&gt;
		page_content = current_title:getContent()&lt;br /&gt;
	end&lt;br /&gt;
	if page_content then&lt;br /&gt;
		if mw.ustring.find(page_content, section_name, 1, true) then&lt;br /&gt;
			return frame:preprocess('{{#section:{{FULLPAGENAME}}|' .. section_name .. '}}')&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return ''&lt;br /&gt;
end&lt;br /&gt;
---------------------&lt;br /&gt;
-- Sundry small functions&lt;br /&gt;
---------------------&lt;br /&gt;
local function normalise(str)&lt;br /&gt;
	return mw.ustring.gsub(str,&amp;quot;[&amp;quot; .. conf.WordSeparator .. &amp;quot;]+&amp;quot;,&amp;quot; &amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyCss(str)&lt;br /&gt;
	str = mw.ustring.gsub(str, '^[\&amp;quot;\']*(.-)[\&amp;quot;\']*$', &amp;quot;%1&amp;quot;) -- trims quotation marks&lt;br /&gt;
	if mw.ustring.sub(str, -1) ~= &amp;quot;;&amp;quot; then str = str .. &amp;quot;;&amp;quot; end -- appends &amp;quot;;&amp;quot; if missing&lt;br /&gt;
	return str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function highlight(text)&lt;br /&gt;
	if text then&lt;br /&gt;
		return '&amp;lt;span style=&amp;quot;color:#C00;font-weight:bold;&amp;quot;&amp;gt;' .. text .. '&amp;lt;/span&amp;gt;'&lt;br /&gt;
	else return &amp;quot;&amp;quot; end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tone_sup(str)&lt;br /&gt;
	return mw.ustring.gsub(str, &amp;quot;([^%p%s0-9])([0-9]+)&amp;quot;, &amp;quot;%1&amp;lt;sup&amp;gt;%2&amp;lt;/sup&amp;gt;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function is_empty(str) -- returns &amp;quot;false&amp;quot; if its argument is a string containing chars other than spaces &amp;amp;c.&lt;br /&gt;
	if not str then return true end&lt;br /&gt;
	if mw.ustring.find(str, &amp;quot;[^&amp;quot; .. conf.WordSeparator .. &amp;quot;]&amp;quot;)&lt;br /&gt;
		then return false&lt;br /&gt;
	else return true end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function help_link (anchor)&lt;br /&gt;
	if anchor then&lt;br /&gt;
		return &amp;quot; ([[&amp;quot; .. conf.ErrorHelpLocation .. &amp;quot;#&amp;quot; .. anchor .. &amp;quot;|help]])&amp;quot;&lt;br /&gt;
	else return &amp;quot;&amp;quot; end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- the following is part of a trial implementation of automatic transliteration:&lt;br /&gt;
local function transliterate (str, lang_from, lang_to,  scheme)&lt;br /&gt;
	local lookup = {grc = {module = 'Module:Ancient Greek', funct = &amp;quot;transliterate&amp;quot;, } }&lt;br /&gt;
	if not lang_from then&lt;br /&gt;
		msg:add(&amp;quot;error&amp;quot;, &amp;quot;Source language for transliteration is not set&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		local t = lookup[lang_from]&lt;br /&gt;
		if t then&lt;br /&gt;
			local module = require(t.module)&lt;br /&gt;
			return module[t.funct](str)&lt;br /&gt;
		else msg:add(&amp;quot;error&amp;quot;, &amp;quot;Can't find transliterator for language '&amp;quot; .. lang_from .. &amp;quot;'&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return &amp;quot;&amp;quot;&lt;br /&gt;
end -- end of trial block&lt;br /&gt;
&lt;br /&gt;
--------------------&lt;br /&gt;
-- The following two functions update the glossing settings based on the received&lt;br /&gt;
-- template arguments. set_global_glossing_settings() updates the global settings&lt;br /&gt;
-- that are valid for all gloss abbreviations. set_glossing_type()&lt;br /&gt;
-- returns the glossing type, which can vary between the different lines.&lt;br /&gt;
--------------------&lt;br /&gt;
local function set_global_glossing_settings(a)&lt;br /&gt;
	local style = &amp;quot;&amp;quot;&lt;br /&gt;
	if a.style then style = tidyCss(a.style) end&lt;br /&gt;
	if a.underline == &amp;quot;no&amp;quot; then&lt;br /&gt;
		style = style .. &amp;quot;text-decoration: none;&amp;quot; end&lt;br /&gt;
	if a.small_caps == &amp;quot;no&amp;quot; then&lt;br /&gt;
		style = style .. &amp;quot;font-variant:normal; text-transform: none;&amp;quot; end&lt;br /&gt;
	if style ~= &amp;quot;&amp;quot; then conf.style.GlossAbbr = conf.style.GlossAbbr .. style end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function set_glossing_type(glossing)&lt;br /&gt;
	if glossing then&lt;br /&gt;
		local GlossingType&lt;br /&gt;
		glossing = mw.ustring.lower(mw.text.trim(glossing))&lt;br /&gt;
		if mw.ustring.find(glossing, 'link') then&lt;br /&gt;
			GlossingType = &amp;quot;wikilink&amp;quot;&lt;br /&gt;
		elseif mw.ustring.find(glossing, 'label')&lt;br /&gt;
			or  mw.ustring.find(glossing, 'no link') then&lt;br /&gt;
			GlossingType = 'label'&lt;br /&gt;
		elseif mw.ustring.find(glossing, 'no abbr') then&lt;br /&gt;
			GlossingType = &amp;quot;no abbr&amp;quot;&lt;br /&gt;
		elseif yesno(glossing) == false then&lt;br /&gt;
			GlossingType = nil&lt;br /&gt;
		elseif yesno(glossing) then&lt;br /&gt;
			GlossingType = conf.GlossingType&lt;br /&gt;
		else&lt;br /&gt;
			msg:add('error', 'Glossing type &amp;quot;' .. glossing .. '&amp;quot; not recognised') end&lt;br /&gt;
		return GlossingType&lt;br /&gt;
	else error(&amp;quot;set_glossing_type: 'glossing' is nil or false&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function set_custom_glosses(list)&lt;br /&gt;
	local abbs = mw.text.split(list, '[;\n\t]')&lt;br /&gt;
	for _,v in pairs(abbs) do&lt;br /&gt;
		local gloss = mw.text.split(v, ':')&lt;br /&gt;
		local a = mw.text.trim(gloss[1])&lt;br /&gt;
		if a and a ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			gloss_override[a] = {}&lt;br /&gt;
			gloss_override[a].expansion = gloss[2]&lt;br /&gt;
			gloss_override[a].wikipage = gloss[3]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- The UserMessages object contains and processes error messages and warnings&lt;br /&gt;
---------------------&lt;br /&gt;
local UserMessages = {errors = {}, warnings = {}, gloss_messages = {}}&lt;br /&gt;
function UserMessages:add(msgtype, text, gloss)&lt;br /&gt;
	if msgtype == &amp;quot;gloss_message&amp;quot; then&lt;br /&gt;
		self.gloss_messages[gloss] = text&lt;br /&gt;
	elseif msgtype == &amp;quot;warning&amp;quot; then&lt;br /&gt;
		table.insert(self.warnings, text)&lt;br /&gt;
	elseif msgtype == &amp;quot;non-repeating error&amp;quot; then&lt;br /&gt;
		self.errors.nre = text&lt;br /&gt;
	elseif msgtype == &amp;quot;ambiguous gloss&amp;quot; then&lt;br /&gt;
		self.if_ambiguous_glosses = true&lt;br /&gt;
	elseif msgtype == &amp;quot;error&amp;quot; then&lt;br /&gt;
		table.insert(self.errors, text)&lt;br /&gt;
	else return error(&amp;quot;UserMessages:add(): unknown message type&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
function UserMessages:print_errors()&lt;br /&gt;
	local out = &amp;quot;&amp;quot;&lt;br /&gt;
	local namespace = mw.title.getCurrentTitle().namespace&lt;br /&gt;
	if next(self.errors) or self.warnings[1] then&lt;br /&gt;
		local err_span = mw.html.create(&amp;quot;span&amp;quot;)&lt;br /&gt;
		err_span:attr(&amp;quot;style&amp;quot;, conf.style.ErrorMessage)&lt;br /&gt;
		err_span:addClass(conf.class.ErrorMessage)&lt;br /&gt;
		for _,v in pairs(self.errors) do&lt;br /&gt;
			err_span:wikitext(&amp;quot; &amp;quot; .. v .. &amp;quot;;&amp;quot;) end&lt;br /&gt;
		if namespace % 2 == 0 and namespace ~= 2 -- non-talk namespaces, excluding user pages; if modifying please update the description on the category page&lt;br /&gt;
			then err_span:wikitext(conf.ErrorCategory)&lt;br /&gt;
		end&lt;br /&gt;
		out = tostring(err_span)&lt;br /&gt;
		mw.addWarning(conf.MessageGlossingError)&lt;br /&gt;
	end&lt;br /&gt;
	if self.if_ambiguous_glosses then&lt;br /&gt;
		if namespace == 0 -- article namespace&lt;br /&gt;
			then out = out .. conf.AmbiguousGlossCategory -- this category will only track articles&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
function UserMessages:print_warnings()&lt;br /&gt;
	local out = &amp;quot;&amp;quot;&lt;br /&gt;
	-- Messages and warnings get displayed only if the page is being viewed in &amp;quot;preview&amp;quot; mode:&lt;br /&gt;
	if displaying_messages and (next(self.gloss_messages) or next(self.warnings)) then&lt;br /&gt;
		local div = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
		div:addClass(&amp;quot;interlinear-preview-warning&amp;quot;)&lt;br /&gt;
			:cssText('border: 1px solid #a2a9b1; background-color: #f8f9fa; width: 80%; padding: 0.2em;')&lt;br /&gt;
			:wikitext(&amp;quot;&amp;lt;i&amp;gt;This message box is shown only in preview:&amp;lt;/i&amp;gt;&amp;quot;)&lt;br /&gt;
			:newline()&lt;br /&gt;
		for _,v in ipairs(self.warnings) do&lt;br /&gt;
			local p = div:tag(&amp;quot;p&amp;quot;)&lt;br /&gt;
			p:addClass(conf.class.ErrorMessage)&lt;br /&gt;
			p:attr(&amp;quot;style&amp;quot;, conf.style.ErrorMessage)&lt;br /&gt;
			p:wikitext(v)&lt;br /&gt;
		end&lt;br /&gt;
		if self.gloss_messages then&lt;br /&gt;
			div:wikitext(&amp;quot;&amp;lt;p&amp;gt;  To change any of the following default expansions, see [[Template:Interlinear/doc#Custom abbreviations|the template's documentation]]:&amp;lt;/p&amp;gt;&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		for _,v in pairs(self.gloss_messages) do&lt;br /&gt;
			div:wikitext(&amp;quot;&amp;lt;p&amp;gt;&amp;quot; .. v .. &amp;quot;&amp;lt;/p&amp;gt;&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		out = out .. &amp;quot;\n\n&amp;quot; .. tostring(div)&lt;br /&gt;
	end&lt;br /&gt;
	return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- gloss_lookup() receives a gloss abbreviation and tries to uncover its meaning.&lt;br /&gt;
---------------------&lt;br /&gt;
local function gloss_lookup(a, label, wikilink)&lt;br /&gt;
	local _label, _wikilink, _lookup, source = nil, nil, nil, nil&lt;br /&gt;
	if gloss_override[a] then&lt;br /&gt;
		_lookup = gloss_override[a]&lt;br /&gt;
		source = &amp;quot;local&amp;quot;&lt;br /&gt;
	elseif data.abbreviations[a] then _lookup = data.abbreviations[a] end&lt;br /&gt;
	if _lookup and _lookup.expansion ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		_label, _wikilink = _lookup.expansion, _lookup.wikipage&lt;br /&gt;
	else&lt;br /&gt;
		local prefix = mw.ustring.sub(a,1,1)&lt;br /&gt;
		local suffix = mw.ustring.sub(a,2)&lt;br /&gt;
		if conf.combining_person[prefix] then -- is it of the form 1PL or 3FS?&lt;br /&gt;
			_label = conf.combining_person[prefix]&lt;br /&gt;
		local _suffix = conf.combining_number[suffix] or conf.combining_gender[suffix]&lt;br /&gt;
			if _suffix then&lt;br /&gt;
				_label = _label .. &amp;quot;, &amp;quot; .. _suffix&lt;br /&gt;
			else&lt;br /&gt;
				local suffix1 = mw.ustring.sub(suffix,1,1)&lt;br /&gt;
				local suffix2 = mw.ustring.sub(suffix,2)&lt;br /&gt;
					if conf.combining_gender[suffix1]&lt;br /&gt;
					and  conf.combining_number[suffix2] then&lt;br /&gt;
						_label = _label .. &amp;quot;, &amp;quot; .. conf.combining_gender[suffix1] .. &amp;quot;, &amp;quot; .. conf.combining_number[suffix2]&lt;br /&gt;
					else _label = nil end&lt;br /&gt;
			end&lt;br /&gt;
	elseif mw.ustring.match(suffix,conf.combining_gender_numbers) then -- cases like G4 = gender 4&lt;br /&gt;
		local _i,_j = mw.ustring.find(a, conf.combining_gender_numbers)&lt;br /&gt;
		local _pre = mw.ustring.sub(a, 1, _i - 1)&lt;br /&gt;
		local _suff = mw.ustring.sub(a, _i)&lt;br /&gt;
		if conf.combining_gender_prefixes[_pre] then&lt;br /&gt;
			_label = conf.combining_gender_prefixes[_pre] .. &amp;quot; &amp;quot; .. _suff&lt;br /&gt;
		end&lt;br /&gt;
	elseif prefix == &amp;quot;N&amp;quot; then -- dealing with cases like NPST = non-past&lt;br /&gt;
		local s = gloss_override[suffix] or data.abbreviations[suffix]&lt;br /&gt;
			if s ~= nil and not s.ExcludeNegation then&lt;br /&gt;
				_label = &amp;quot;non-&amp;quot; .. s.expansion&lt;br /&gt;
				_wikilink = s.wikipage&lt;br /&gt;
			end&lt;br /&gt;
			s = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if _label == &amp;quot;&amp;quot; then _label = nil end&lt;br /&gt;
	if _wikilink == &amp;quot;&amp;quot; then _wikilink = nil end&lt;br /&gt;
	if not label then label = _label end&lt;br /&gt;
	if not wikilink then wikilink = _wikilink end&lt;br /&gt;
	return label, wikilink, source&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- format_gloss() calls gloss_lookup() to find the meaning of a gloss&lt;br /&gt;
-- abbreviation, which it then proceeds to format&lt;br /&gt;
---------------------&lt;br /&gt;
local function format_gloss(gloss, label, wikilink)&lt;br /&gt;
	if string.sub(gloss,1,3) == &amp;quot;000&amp;quot; then -- checks for a common component of exposed strip markers (see [[:mw:Strip marker]])&lt;br /&gt;
		return gloss&lt;br /&gt;
	end&lt;br /&gt;
	local gloss2 = mw.ustring.gsub(gloss,&amp;quot;&amp;lt;.-&amp;gt;&amp;quot;,&amp;quot;&amp;quot;) -- remove any html fluff&lt;br /&gt;
	gloss2 = mw.ustring.gsub(gloss2, &amp;quot;%'%'+&amp;quot;, &amp;quot;&amp;quot;) -- remove wiki bold/italic formatting&lt;br /&gt;
	gloss2 = mw.text.trim(mw.ustring.upper(gloss2))&lt;br /&gt;
	if not (label or wikilink)&lt;br /&gt;
		or (not label and glossing_type == &amp;quot;label&amp;quot;)&lt;br /&gt;
		or (not wikilink  and glossing_type == &amp;quot;wikilink&amp;quot;)&lt;br /&gt;
		then&lt;br /&gt;
			if glossing_type ~= &amp;quot;no abbr&amp;quot;&lt;br /&gt;
				then label, wikilink, source = gloss_lookup(gloss2, label, wikilink)&lt;br /&gt;
			end&lt;br /&gt;
	end&lt;br /&gt;
	local gloss_node&lt;br /&gt;
	if glossing_type == &amp;quot;no abbr&amp;quot;&lt;br /&gt;
		then gloss_node = mw.html.create(&amp;quot;span&amp;quot;)&lt;br /&gt;
	else gloss_node = mw.html.create(&amp;quot;abbr&amp;quot;) end&lt;br /&gt;
	gloss_node:addClass(conf.class.GlossAbbr)&lt;br /&gt;
	if label or wikilink then&lt;br /&gt;
		if not mw.ustring.match(gloss, &amp;quot;%l&amp;quot;) -- excluding glosses that contain lower-case characters&lt;br /&gt;
			and not mw.ustring.match(gloss,conf.GlossSmallCapsExclude) -- and also excluding A, O etc. from rendering in small caps&lt;br /&gt;
			then gloss_node:attr(&amp;quot;style&amp;quot;, conf.style.GlossAbbr)&lt;br /&gt;
		end&lt;br /&gt;
		local abbr_label&lt;br /&gt;
		if label then abbr_label = label&lt;br /&gt;
			else abbr_label = wikilink end&lt;br /&gt;
		gloss_node:attr(&amp;quot;title&amp;quot;, abbr_label)&lt;br /&gt;
		if source ~= &amp;quot;local&amp;quot; and data.abbreviations[gloss2] then&lt;br /&gt;
			if data.abbreviations[gloss2].ambiguous then&lt;br /&gt;
				gloss_node:addClass(conf.class.GlossAbbrAmb)&lt;br /&gt;
					msg:add(&amp;quot;ambiguous gloss&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
		end&lt;br /&gt;
		if glossing_type == &amp;quot;wikilink&amp;quot; and wikilink&lt;br /&gt;
			then gloss_node:wikitext(&amp;quot;[[&amp;quot;, wikilink, &amp;quot;|&amp;quot; , gloss, &amp;quot;]]&amp;quot;)&lt;br /&gt;
			else gloss_node:wikitext(gloss) end&lt;br /&gt;
		if source ~= &amp;quot;local&amp;quot; and displaying_messages then -- logging gloss lookups:&lt;br /&gt;
			local message = &amp;quot;&amp;quot;&lt;br /&gt;
			if label then&lt;br /&gt;
				message = &amp;quot;assuming &amp;quot; .. gloss2 .. &amp;quot; means \&amp;quot;&amp;quot; .. abbr_label .. &amp;quot;\&amp;quot;;&amp;quot; end&lt;br /&gt;
			if glossing_type == &amp;quot;wikilink&amp;quot; and wikilink then&lt;br /&gt;
				message = message .. &amp;quot; linking to [[&amp;quot; .. wikilink .. &amp;quot;]];&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			msg:add(&amp;quot;gloss_message&amp;quot;, message, gloss)&lt;br /&gt;
		end&lt;br /&gt;
	elseif glossing_type == &amp;quot;no abbr&amp;quot;&lt;br /&gt;
		then gloss_node&lt;br /&gt;
				:attr(&amp;quot;style&amp;quot;, conf.style.GlossAbbr)&lt;br /&gt;
				:wikitext(gloss)&lt;br /&gt;
	else&lt;br /&gt;
		if displaying_messages then&lt;br /&gt;
			msg:add(&amp;quot;warning&amp;quot;, &amp;quot;Gloss abbreviation &amp;quot; .. highlight(gloss2) .. &amp;quot;  not recognised&amp;quot; .. help_link(&amp;quot;gloss abbr&amp;quot;))&lt;br /&gt;
		end&lt;br /&gt;
		msg:add(&amp;quot;non-repeating error&amp;quot;, &amp;quot;Unknown glossing abbreviation(s)&amp;quot; .. help_link(&amp;quot;gloss abbr&amp;quot;))&lt;br /&gt;
		gloss_node&lt;br /&gt;
			:addClass(conf.class.GlossAbbrError)&lt;br /&gt;
			:addClass(&amp;quot;error&amp;quot;)&lt;br /&gt;
			:css(&amp;quot;font-size&amp;quot;, &amp;quot;100%&amp;quot;)&lt;br /&gt;
			:attr(&amp;quot;title&amp;quot;, gloss2 .. &amp;quot;: glossing abbreviation not found&amp;quot;)&lt;br /&gt;
			:attr(&amp;quot;style&amp;quot;, conf.style.ErrorMessage)&lt;br /&gt;
			:wikitext(gloss)&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(gloss_node)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- find_gloss() parses a word into morphemes, and it calls format_gloss()&lt;br /&gt;
-- for anything that looks like a glossing abbreviation.&lt;br /&gt;
---------------------&lt;br /&gt;
local function find_gloss(word)&lt;br /&gt;
	local function scan_gloss(boundary, gloss_abbr) -- checks a morpheme if it is a gloss abbreviation&lt;br /&gt;
		if (mw.ustring.match(gloss_abbr, conf.GlossAbbrPattern)&lt;br /&gt;
			or conf.LowerCaseGlosses[gloss_abbr])&lt;br /&gt;
			and not (conf.GlossExcludeTable[gloss_abbr]&lt;br /&gt;
				or mw.ustring.match(gloss_abbr, conf.GlossExcludePattern))&lt;br /&gt;
			then gloss_abbr = format_gloss(gloss_abbr)&lt;br /&gt;
		end&lt;br /&gt;
		return boundary .. gloss_abbr&lt;br /&gt;
	end&lt;br /&gt;
	local word = mw.text.decode(word, true)&lt;br /&gt;
	if word == &amp;quot;I&amp;quot; -- for the case of the English word &amp;quot;I&amp;quot;, the 1SG pronoun&lt;br /&gt;
		then return word end&lt;br /&gt;
	local pattern = &amp;quot;([&amp;quot; .. conf.GlossAbbrBoundary .. &amp;quot;]?)([^&amp;quot; .. conf.GlossAbbrBoundary .. &amp;quot;]+)&amp;quot;&lt;br /&gt;
	word = mw.ustring.gsub(word, pattern, scan_gloss) -- splits into morphemes&lt;br /&gt;
	return word&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- The main purpose of the bletcherous parse() is to split a line into words and and then for each eligible word&lt;br /&gt;
-- to call find_gloss(). The parser outputs the individual words (with any gloss abbreviation formatting applied).&lt;br /&gt;
-- The simple job of splitting at whitespaces has been made complicated by a) the fact that the input can contain&lt;br /&gt;
-- whitespaces inside the various html elements that are the result of the application of various formatting templates;&lt;br /&gt;
-- and b) the need to be able to recognise the output of the template that formats custom gloss abbreviations&lt;br /&gt;
-- (and hence skip passing it on to find_gloss). See talk for a suggestion about its future.&lt;br /&gt;
---------------------&lt;br /&gt;
local function parse(cline, i, tags_found,ifglossing)&lt;br /&gt;
&lt;br /&gt;
	local function issue_error(message, culprit)&lt;br /&gt;
		UserMessages:add(&amp;quot;error&amp;quot;,  message .. &amp;quot;: ''&amp;quot; .. mw.ustring.sub(cline.whole, 1, i-1) .. &amp;quot;'''&amp;quot; .. culprit  .. &amp;quot;'''''&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if i &amp;gt; cline.length then return i end --this will only be triggered if the current line has less words than line 1&lt;br /&gt;
	local next_step, j, _, chunk&lt;br /&gt;
	local probe = mw.ustring.sub(cline.whole,i,i)&lt;br /&gt;
	if mw.ustring.match(probe,&amp;quot;[&amp;quot; .. conf.WordSeparator .. &amp;quot;]&amp;quot;) and tags_found == 0&lt;br /&gt;
		then next_step =  i-1&lt;br /&gt;
	elseif probe == &amp;quot;[&amp;quot; then --Wikilink?&lt;br /&gt;
		if mw.ustring.sub(cline.whole,i+1,i+1) == &amp;quot;[&amp;quot; then&lt;br /&gt;
			_,j,chunk = mw.ustring.find(cline.whole,&amp;quot;(%[%[.-%]%])&amp;quot;, i)&lt;br /&gt;
		else chunk = &amp;quot;[&amp;quot;; j = i end --not a wikilink then&lt;br /&gt;
		buffer = buffer .. chunk&lt;br /&gt;
		next_step =  parse(cline, j+1,tags_found,ifglossing)&lt;br /&gt;
	elseif probe == &amp;quot;{&amp;quot;  and tags_found == 0 then --curly brackets enclose a sequence of words to be treated as a single unit&lt;br /&gt;
		_,j,chunk = mw.ustring.find(cline.whole,&amp;quot;(.-)(})&amp;quot;, i+1)&lt;br /&gt;
		if not chunk then&lt;br /&gt;
			issue_error(&amp;quot;Unclosed curly bracket&amp;quot;, &amp;quot;{&amp;quot;)&lt;br /&gt;
			chunk = highlight(&amp;quot;{&amp;quot;); j = i&lt;br /&gt;
		elseif ifglossing==true then&lt;br /&gt;
			chunk = find_gloss(chunk)&lt;br /&gt;
		else&lt;br /&gt;
			if cline.tone_sup then chunk = tone_sup(chunk) end&lt;br /&gt;
		end&lt;br /&gt;
		buffer = buffer .. chunk&lt;br /&gt;
		next_step =  parse(cline, j+1,tags_found,ifglossing)&lt;br /&gt;
	elseif probe == &amp;quot;&amp;lt;&amp;quot; then -- We've encountered an HTML tag. What do we do now?&lt;br /&gt;
		local _,j,chunk = mw.ustring.find(cline.whole,&amp;quot;(&amp;lt;.-&amp;gt;)&amp;quot;,i)&lt;br /&gt;
		if not chunk then&lt;br /&gt;
			issue_error(&amp;quot;Unclosed angle bracket&amp;quot;, &amp;quot;&amp;lt;&amp;quot;)&lt;br /&gt;
			chunk = highlight(&amp;quot;&amp;lt;&amp;quot;); j = i&lt;br /&gt;
		elseif mw.ustring.sub(cline.whole,i,i+1) == &amp;quot;&amp;lt;/&amp;quot; then -- It's a CLOSING tag&lt;br /&gt;
			if cline.glossing&lt;br /&gt;
				and ifglossing==false&lt;br /&gt;
				and mw.ustring.match(chunk,&amp;quot;&amp;lt;/abbr&amp;gt;&amp;quot;)&lt;br /&gt;
				then ifglossing=true end&lt;br /&gt;
			tags_found = tags_found - 1&lt;br /&gt;
		elseif not mw.ustring.match(chunk, &amp;quot;/&amp;gt;$&amp;quot;) -- It's an OPENING tag, unless it opens a self-closing element (in which case the element is ignored)&lt;br /&gt;
			then if ifglossing == true -- the following checks for the output of {{ggl}}:&lt;br /&gt;
					and mw.ustring.find(chunk, conf.class.GlossAbbr, 1, true) -- it's important that the &amp;quot;find&amp;quot; function uses literal strings and not patterns&lt;br /&gt;
						then ifglossing = false end&lt;br /&gt;
			tags_found = tags_found + 1&lt;br /&gt;
		end&lt;br /&gt;
		buffer = buffer .. chunk&lt;br /&gt;
		next_step = parse(cline, j+1,tags_found,ifglossing)&lt;br /&gt;
	else -- No HTML tags, so we only need to find where the word ends&lt;br /&gt;
		local _,k,chunk = mw.ustring.find(cline.whole,&amp;quot;(..-)([ &amp;lt;[])&amp;quot;,i)&lt;br /&gt;
		if k then --ordinary text&lt;br /&gt;
			if ifglossing==true then&lt;br /&gt;
				buffer = buffer .. find_gloss(chunk)&lt;br /&gt;
			else&lt;br /&gt;
				if cline.tone_sup then chunk = tone_sup(chunk) end&lt;br /&gt;
				buffer = buffer .. chunk&lt;br /&gt;
			end&lt;br /&gt;
			next_step = parse(cline, k, tags_found, ifglossing)&lt;br /&gt;
		else -- reached end of string&lt;br /&gt;
			if ifglossing == true then&lt;br /&gt;
				chunk = find_gloss(mw.ustring.sub(cline.whole,i))&lt;br /&gt;
			else&lt;br /&gt;
				chunk = mw.ustring.sub(cline.whole,i)&lt;br /&gt;
				if cline.tone_sup then chunk = tone_sup(chunk) end&lt;br /&gt;
			end&lt;br /&gt;
			buffer = buffer .. chunk&lt;br /&gt;
			next_step = cline.length&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return next_step&lt;br /&gt;
end&lt;br /&gt;
--------------------&lt;br /&gt;
-- The following function is called by Template:gcl and is used for formatting an individual glossing abbreviation&lt;br /&gt;
--------------------&lt;br /&gt;
function p.gcl(frame)&lt;br /&gt;
	local args = getArgs(frame,{&lt;br /&gt;
		trim = true,&lt;br /&gt;
		removeBlanks = false,&lt;br /&gt;
		parentOnly = true,&lt;br /&gt;
		wrappers = {'Template:Grammatical category label'},&lt;br /&gt;
	})&lt;br /&gt;
	msg = UserMessages&lt;br /&gt;
	set_global_glossing_settings{style = args.style, underline = args.underline, small_caps = args['small-caps']}&lt;br /&gt;
	if not args.glossing then&lt;br /&gt;
		glossing_type = conf.GlossingType -- a global variable&lt;br /&gt;
	else glossing_type = set_glossing_type(args.glossing)&lt;br /&gt;
	end&lt;br /&gt;
	local gloss, label, wikilink = args[1], args[2], args[3]&lt;br /&gt;
	if not gloss then UserMessages:add(&amp;quot;error&amp;quot;, &amp;quot;No gloss supplied&amp;quot;)&lt;br /&gt;
		return UserMessages:print() end&lt;br /&gt;
	if wikilink and not args.glossing then -- if a wikilink is supplied and glossing isn't set to 'label'...&lt;br /&gt;
		glossing_type = 'wikilink' end --     .. then the wikilink will be formatted as such&lt;br /&gt;
	if label == &amp;quot;&amp;quot; then label = nil end&lt;br /&gt;
	if wikilink == &amp;quot;&amp;quot; then wikilink = nil end&lt;br /&gt;
	local result = format_gloss(gloss, label, wikilink)&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------&lt;br /&gt;
-- The following is the function called by Template:Interlinear.&lt;br /&gt;
-- It processes the template arguments, then calls parse() to split the input lines into words&lt;br /&gt;
-- and it then builds the output html.&lt;br /&gt;
--------------------&lt;br /&gt;
function p.interlinearise(frame)&lt;br /&gt;
---------------------&lt;br /&gt;
-- Prepare arguments&lt;br /&gt;
---------------------&lt;br /&gt;
	local if_auto_translit = false&lt;br /&gt;
	local args = getArgs(frame, { -- configuration for Module:Arguments&lt;br /&gt;
		trim = true,&lt;br /&gt;
		removeBlanks = false,&lt;br /&gt;
		parentFirst = true,&lt;br /&gt;
		wrappers = {'Template:Interlinear', 'Template:Fs interlinear'},&lt;br /&gt;
	})&lt;br /&gt;
	local template_name = frame:getParent():getTitle()&lt;br /&gt;
	if template_name == 'Template:Fs interlinear' then&lt;br /&gt;
		args.italics1 = args.italics1 or &amp;quot;no&amp;quot;&lt;br /&gt;
		args.italics2 = args.italics2 or &amp;quot;yes&amp;quot;&lt;br /&gt;
		args.glossing3 = args.glossing3 or &amp;quot;yes&amp;quot;&lt;br /&gt;
		if args.lang and not args.lang2 then args.lang2 = args.lang ..&amp;quot;-Latn&amp;quot; end&lt;br /&gt;
		if args.transl and not args.transl2 then args.transl2 = args.transl end&lt;br /&gt;
		if_auto_translit = true&lt;br /&gt;
&lt;br /&gt;
	end&lt;br /&gt;
	local revid = frame:preprocess( &amp;quot;{{REVISIONID}}&amp;quot; )&lt;br /&gt;
	if  revid == &amp;quot;&amp;quot; then&lt;br /&gt;
		if not args['display-messages'] or yesno(args['display-messages']) then&lt;br /&gt;
		displaying_messages = true end-- messages will be displayed only in preview mode&lt;br /&gt;
	end&lt;br /&gt;
	msg = UserMessages&lt;br /&gt;
	local line = {}&lt;br /&gt;
&lt;br /&gt;
	local function set_italics(n)&lt;br /&gt;
		line[n].attr.style = line[n].attr.style .. &amp;quot;font-style: italic;&amp;quot;&lt;br /&gt;
		line[n].tone_sup = true -- single digits are assumed to be tone markers and will hence be superscripted&lt;br /&gt;
		if args['tone-superscripting'] and not yesno(args['tone-superscripting'])&lt;br /&gt;
			then line[n].tone_sup = false end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args.glossing then -- the glossing= parameter sets the default glossing type&lt;br /&gt;
		local _gl = set_glossing_type(args.glossing)&lt;br /&gt;
		if _gl then conf.GlossingType = _gl end&lt;br /&gt;
	end&lt;br /&gt;
	--this looks for a list of glossing abbreviations on the page that transcludes the template:&lt;br /&gt;
	local _ablist_section = get_section(frame, 'list-of-glossing-abbreviations')&lt;br /&gt;
	if _ablist_section and _ablist_section ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		local _a = mw.ustring.gsub(_ablist_section, '&amp;lt;/?div [^\n]*&amp;gt;', '') -- strips off the div tags&lt;br /&gt;
		set_custom_glosses(_a)&lt;br /&gt;
	end&lt;br /&gt;
	--and this looks looks for a list of abbreviations set within the template:&lt;br /&gt;
	local _ablist = args.abbreviations&lt;br /&gt;
	if _ablist and _ablist ~= &amp;quot;&amp;quot;&lt;br /&gt;
		then set_custom_glosses(_ablist) end&lt;br /&gt;
	local _ablist = args.ablist&lt;br /&gt;
	if _ablist and _ablist ~= &amp;quot;&amp;quot;&lt;br /&gt;
		then set_custom_glosses(_ablist) end&lt;br /&gt;
&lt;br /&gt;
	local _spacing = tonumber(args.spacing)&lt;br /&gt;
	if _spacing and _spacing &amp;lt;= 20&lt;br /&gt;
		then conf.style.WordDiv = conf.style.WordDiv .. 'margin-right: ' .. _spacing .. 'em;'&lt;br /&gt;
	else conf.style.WordDiv = conf.style.WordDiv .. conf.style.WordMargin&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local offset, last_line = 0, 0&lt;br /&gt;
	for j,v in ipairs(args) do -- iterates over the unnamed parameters from the template&lt;br /&gt;
		last_line = last_line +1&lt;br /&gt;
		if is_empty(v)&lt;br /&gt;
			then offset = offset + 1&lt;br /&gt;
		else&lt;br /&gt;
		local i = j - offset&lt;br /&gt;
		line[i] = {}&lt;br /&gt;
		v = normalise(v)&lt;br /&gt;
&lt;br /&gt;
		-- the following is part of a trial implementation of automatic transliteration:&lt;br /&gt;
		if if_auto_translit and v == &amp;quot;auto&amp;quot; and i &amp;gt; 1 then&lt;br /&gt;
			local source_line = line[i-1]&lt;br /&gt;
			local src_lang = source_line.lang&lt;br /&gt;
			if not src_lang then src_lang = args.lang end&lt;br /&gt;
			if src_lang then&lt;br /&gt;
					v = transliterate(source_line.whole, src_lang)&lt;br /&gt;
			else v = &amp;quot;&amp;quot;; msg:add(&amp;quot;error&amp;quot;, &amp;quot;No language specified for automatic transliteration&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end  -- end of trial block&lt;br /&gt;
&lt;br /&gt;
		line[i].whole = v&lt;br /&gt;
		line[i].length = mw.ustring.len(v)&lt;br /&gt;
&lt;br /&gt;
		local _c = args[&amp;quot;c&amp;quot; .. i]&lt;br /&gt;
		if _c and _c ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			line.hasComments = true&lt;br /&gt;
			line[i].c = _c&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		---prepare style arguments----&lt;br /&gt;
		line[i].class = &amp;quot;&amp;quot;&lt;br /&gt;
		local _style = args[&amp;quot;style&amp;quot; .. i]&lt;br /&gt;
		if not _style then _style = &amp;quot;&amp;quot;&lt;br /&gt;
		else _style = tidyCss(_style) end&lt;br /&gt;
		--line[i].attr holds the attributes for the &amp;lt;p&amp;gt; elements that enclose the words in line i&lt;br /&gt;
		line[i].attr = {style = conf.style.WordP .. _style}&lt;br /&gt;
&lt;br /&gt;
		local _lang = args[&amp;quot;lang&amp;quot; .. i]&lt;br /&gt;
		if _lang and #_lang &amp;gt; 1 then&lt;br /&gt;
			line[i].lang = _lang&lt;br /&gt;
		else _lang = args.lang&lt;br /&gt;
			if _lang and #_lang &amp;gt; 1 and i == 1 then -- if a lang= parameter is supplied, it's assumed to apply to line 1&lt;br /&gt;
				line[i].lang = _lang&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		line[i].attr.lang = line[i].lang&lt;br /&gt;
		--the following emulates the behaviour of {{Bo-textonly}} (see Template talk:Fs interlinear#Tibetan):&lt;br /&gt;
		if template_name == 'Template:Fs interlinear' then&lt;br /&gt;
			if _lang == &amp;quot;bo&amp;quot; and i == 1 then&lt;br /&gt;
				line[1].class = line[1].class .. &amp;quot; uchen&amp;quot;&lt;br /&gt;
				line[1].attr.style = line[1].attr.style .. &amp;quot;font-size:1.25em; word-wrap:break-word;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--the following emulates the behaviour of {{Spell-nv}}:&lt;br /&gt;
		if template_name == 'Template:Interlinear' then&lt;br /&gt;
			if _lang == &amp;quot;nv&amp;quot; and i == 1 then&lt;br /&gt;
				line[1].attr.style = line[1].attr.style .. &amp;quot;font-family: Aboriginal Sans, DejaVu Sans, Calibri, Arial Unicode MS, sans-serif;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if yesno(args[&amp;quot;italics&amp;quot; .. i]) then&lt;br /&gt;
			set_italics(i)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local _transl = args[&amp;quot;transl&amp;quot; .. i]&lt;br /&gt;
		if _transl and #_transl &amp;gt; 1 then&lt;br /&gt;
			_transl = mw.ustring.lower(_transl)&lt;br /&gt;
			local _lookup = lang_data.translit_title_table[_transl]&lt;br /&gt;
			if _lookup then&lt;br /&gt;
				if _lang and  _lookup[_lang] then&lt;br /&gt;
					_transl = _lookup[_lang]&lt;br /&gt;
				else _transl = _lookup.default&lt;br /&gt;
				end&lt;br /&gt;
				if _transl then&lt;br /&gt;
					line[i].attr.title = _transl&lt;br /&gt;
				end&lt;br /&gt;
			else  msg:add(&amp;quot;error&amp;quot;, &amp;quot;Transliteration scheme '&amp;quot; .. _transl .. &amp;quot;' not recognised&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local _glossing = args[&amp;quot;glossing&amp;quot; .. i]&lt;br /&gt;
		if _glossing then&lt;br /&gt;
			line[i].glossing = set_glossing_type(_glossing)&lt;br /&gt;
			-- Do not treat default glossing settings as custom.&lt;br /&gt;
			if not ((i == 1 and not yesno(_glossing)) or (i == 2 and yesno(_glossing))) then&lt;br /&gt;
				line.HasCustomGlossing = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local _ipa = args['ipa' .. i]&lt;br /&gt;
		if yesno(_ipa) then&lt;br /&gt;
			line[i].class = &amp;quot;IPA&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local _class = args['class' .. i]&lt;br /&gt;
		if _class then&lt;br /&gt;
			line[i].class = line[i].class .. &amp;quot; &amp;quot; .. _class&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if line[i].class == &amp;quot;&amp;quot;&lt;br /&gt;
			then line[i].class = nil end&lt;br /&gt;
		end -- ends the first if-statement in the loop&lt;br /&gt;
	end -- ends the FOR cycle&lt;br /&gt;
&lt;br /&gt;
	local line_count = #line&lt;br /&gt;
	if line_count == 0 then&lt;br /&gt;
		msg:add(&amp;quot;error&amp;quot;, template_name .. &amp;quot;: no lines supplied.&amp;quot;)&lt;br /&gt;
		return msg:print_errors()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if line_count &amp;gt; 1 then&lt;br /&gt;
		local _italics = args.italics&lt;br /&gt;
		local n = tonumber(_italics)&lt;br /&gt;
		if n and n &amp;gt; 0 then&lt;br /&gt;
			set_italics(n)&lt;br /&gt;
		elseif not (_italics and not yesno(_italics)) and not (args[&amp;quot;italics1&amp;quot;] and not yesno(args[&amp;quot;italics1&amp;quot;])) then&lt;br /&gt;
			set_italics(1) -- by default, the first line will get italicised, unless italics=no or italics1=no&lt;br /&gt;
		end&lt;br /&gt;
		-- the last unnamed parameter is assumed to be the free translation:&lt;br /&gt;
		free_translation = args[last_line]&lt;br /&gt;
		if not is_empty(free_translation) then&lt;br /&gt;
			line [line_count] = nil   end  --... and is thus excluded from interlinearising&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
-- If glossing isn't specified for any line, then it's chosen by default to occur&lt;br /&gt;
-- in the second line, unless only a single line has been supplied, in which case&lt;br /&gt;
-- the assumption is that it is the one containing grammatical glosses&lt;br /&gt;
	if yesno(args.glossing) == false then&lt;br /&gt;
		line.HasCustomGlossing = true&lt;br /&gt;
	end&lt;br /&gt;
	if not line.HasCustomGlossing then&lt;br /&gt;
		if line_count == 1 then&lt;br /&gt;
			line[1].glossing = conf.GlossingType&lt;br /&gt;
		elseif line[2] then&lt;br /&gt;
			line[2].glossing = conf.GlossingType&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	set_global_glossing_settings{style = args['glossing-style'], underline = args.underline, small_caps = args['small-caps']}&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- Segment lines into words&lt;br /&gt;
---------------------&lt;br /&gt;
	for i,v in ipairs(line) do&lt;br /&gt;
		local ifglossing = false&lt;br /&gt;
		if line[i].glossing then&lt;br /&gt;
			ifglossing = true -- if true the parser will attempt to format gloss abbreviations in the current line&lt;br /&gt;
			glossing_type = line[i].glossing -- neccessarily a global variable&lt;br /&gt;
		end&lt;br /&gt;
		local wc, n = 1, 1&lt;br /&gt;
		line[i].words = {}&lt;br /&gt;
		while n &amp;lt;= line[i].length do&lt;br /&gt;
			buffer = &amp;quot;&amp;quot;&lt;br /&gt;
			n = parse(line[i], n, 0, ifglossing)+2&lt;br /&gt;
			line[i].words[wc] = buffer&lt;br /&gt;
			wc = wc + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	----Check for mismatches in number of words across lines----&lt;br /&gt;
	local number_of_words, mismatch_found = 0, false&lt;br /&gt;
	for i,v in ipairs(line) do -- find the maximum number of words in any line&lt;br /&gt;
		local wc = #line[i].words&lt;br /&gt;
		if wc ~= number_of_words then&lt;br /&gt;
			if i ~= 1 and wc ~= 0 then&lt;br /&gt;
				mismatch_found = true&lt;br /&gt;
			end&lt;br /&gt;
			if wc &amp;gt; number_of_words then&lt;br /&gt;
				number_of_words = wc&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	----Deal with mismatches---&lt;br /&gt;
	if mismatch_found then&lt;br /&gt;
		local error_text = &amp;quot;Mismatch in the number of words between lines: &amp;quot;&lt;br /&gt;
		for i,v in ipairs(line) do&lt;br /&gt;
			local wc = #line[i].words&lt;br /&gt;
			error_text = error_text .. wc .. &amp;quot; word(s) in line &amp;quot; .. i .. &amp;quot;, &amp;quot;&lt;br /&gt;
			if wc ~= number_of_words then&lt;br /&gt;
				for current_word = wc+1, number_of_words do&lt;br /&gt;
					line[i].words[current_word] = &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if string.sub(error_text, -2) == &amp;quot;, &amp;quot;&lt;br /&gt;
			then error_text = string.sub(error_text, 1, #error_text - 2) .. &amp;quot; &amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		error_text = error_text .. help_link(&amp;quot;mismatch&amp;quot;)&lt;br /&gt;
		UserMessages:add(&amp;quot;error&amp;quot;, error_text)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
---------------------&lt;br /&gt;
-- Build the HTML&lt;br /&gt;
---------------------&lt;br /&gt;
	---- If just a single line was supplied, format it as inline text&lt;br /&gt;
	if line_count == 1 then&lt;br /&gt;
		local span = mw.html.create('span')&lt;br /&gt;
		span:attr(line[1].attr)&lt;br /&gt;
		for wi = 1, number_of_words do&lt;br /&gt;
			local space&lt;br /&gt;
			if wi &amp;lt; number_of_words then space = &amp;quot; &amp;quot; else space = &amp;quot;&amp;quot; end&lt;br /&gt;
			span:wikitext(line[1].words[wi] .. space)&lt;br /&gt;
		end&lt;br /&gt;
		return tostring(span)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	---- More than one line supplied, so we'll produce interlinear display&lt;br /&gt;
	local div = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
	div:addClass(conf.class.Interlinear)&lt;br /&gt;
&lt;br /&gt;
	-- For stuff to be displayed in the left margin, like example numbering&lt;br /&gt;
	local number, indent = nil, nil&lt;br /&gt;
	if args.number and args.number ~= &amp;quot;&amp;quot;&lt;br /&gt;
		then number = args.number end&lt;br /&gt;
	if args.indent and args.indent ~=&amp;quot;&amp;quot;&lt;br /&gt;
		then indent = args.indent end&lt;br /&gt;
	if indent or number then&lt;br /&gt;
		if not indent then indent = &amp;quot;4&amp;quot; end --default value&lt;br /&gt;
		div:css(&amp;quot;margin-left&amp;quot;, indent .. 'em')&lt;br /&gt;
		if number then&lt;br /&gt;
			div:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
				:css(&amp;quot;position&amp;quot;, &amp;quot;absolute&amp;quot;)&lt;br /&gt;
				:css(&amp;quot;left&amp;quot;, &amp;quot;1em&amp;quot;)&lt;br /&gt;
				:wikitext(args.number)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args.box and args.box ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		div:css(&amp;quot;background-color&amp;quot;, &amp;quot;#f8f9fa&amp;quot;)&lt;br /&gt;
			:css(&amp;quot;border&amp;quot;, &amp;quot;1px solid #eaecf0&amp;quot;)&lt;br /&gt;
			:css(&amp;quot;padding&amp;quot;, &amp;quot;1em&amp;quot;) end&lt;br /&gt;
	if args.top and args.top ~= &amp;quot;&amp;quot; then --lines to display above the interlinear block&lt;br /&gt;
		div:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
			:wikitext(args.top)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Producing the interlinear block&lt;br /&gt;
	for wi = 1, number_of_words do&lt;br /&gt;
		local div2 = div:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
					:attr(&amp;quot;style&amp;quot;, conf.style.WordDiv)&lt;br /&gt;
		for i,_ in ipairs (line) do&lt;br /&gt;
			if line[i].whole ~= &amp;quot;&amp;quot; then -- skipping empty lines&lt;br /&gt;
				local p = div2:tag(&amp;quot;p&amp;quot;)&lt;br /&gt;
				p:attr(line[i].attr)&lt;br /&gt;
				if line[i].class then&lt;br /&gt;
					p:addClass(line[i].class)&lt;br /&gt;
				end&lt;br /&gt;
				local _text = line[i].words[wi]&lt;br /&gt;
				if _text == &amp;quot;&amp;quot; or _text == &amp;quot; &amp;quot;&lt;br /&gt;
					then _text = &amp;quot;&amp;amp;nbsp;&amp;quot; end -- &amp;lt;p&amp;gt; elements without content mess up the interlinear display&lt;br /&gt;
				p:wikitext(_text)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- If any &amp;quot;comments&amp;quot; have been specified, add them at the end of each line&lt;br /&gt;
	if line.hasComments then&lt;br /&gt;
		local divc = div:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
					:attr(&amp;quot;style&amp;quot;, conf.style.WordDiv)&lt;br /&gt;
		for i,_ in ipairs (line) do&lt;br /&gt;
			local p = divc:tag(&amp;quot;p&amp;quot;)&lt;br /&gt;
			p:attr(&amp;quot;style&amp;quot;, conf.style.WordP)&lt;br /&gt;
			if line[i].c then&lt;br /&gt;
				p:wikitext(line[i].c)&lt;br /&gt;
			else p:wikitext(&amp;quot;&amp;amp;nbsp;&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--Add hidden lines containing the content of each line of interlinear text: this is for accessibility&lt;br /&gt;
	for i,v in ipairs(line) do&lt;br /&gt;
		local hidden_line = div:tag(&amp;quot;p&amp;quot;)&lt;br /&gt;
		hidden_line:attr(&amp;quot;style&amp;quot;, conf.style.HiddenText)&lt;br /&gt;
					:wikitext(v.whole)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Format the free translation&lt;br /&gt;
	local ft_line = div:tag(&amp;quot;p&amp;quot;)&lt;br /&gt;
	if free_translation and free_translation ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		ft_line:attr(&amp;quot;style&amp;quot;, &amp;quot;clear: left;&amp;quot;)&lt;br /&gt;
		ft_line:wikitext(free_translation)&lt;br /&gt;
	end&lt;br /&gt;
	if args.bottom and args.bottom ~= &amp;quot;&amp;quot;&lt;br /&gt;
		then local bottom = div:tag('p')&lt;br /&gt;
		bottom:css('margin-top', '0')&lt;br /&gt;
		bottom:wikitext(args.bottom)&lt;br /&gt;
	end&lt;br /&gt;
	ft_line:node(msg:print_errors()) -- for error messages&lt;br /&gt;
&lt;br /&gt;
	local end_div = div:tag(&amp;quot;div&amp;quot;)&lt;br /&gt;
		end_div:attr(&amp;quot;style&amp;quot;, conf.style.EndDiv)&lt;br /&gt;
	div:newline()&lt;br /&gt;
	local temp_track = &amp;quot;&amp;quot;&lt;br /&gt;
	if last_line == 2&lt;br /&gt;
		then temp_track = &amp;quot;[[Category:Pages with interlinear glosses using two unnamed parameters]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if last_line &amp;gt; 3 and template_name ~= 'Template:Fs interlinear'&lt;br /&gt;
		then  temp_track = &amp;quot;[[Category:Pages with interlinear glosses using more than three unnamed parameters]]&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return tostring(div) .. temp_track .. msg:print_warnings()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wikipedia&gt;Santiago Claudio</name></author>
	</entry>
</feed>