Module:FishRef/utilities

Documentation for this module may be created at Module:FishRef/utilities/doc

local p = {}

p.format_species_list = function(frame, taxa)

  local list = frame.args[1] or frame:getParent().args[1] or taxa
  local expand = frame.args['expand'] or frame:getParent().args['expand'] -- want to subst template code
  local compare = frame.args['compare'] or frame:getParent().args['compare'] 
  local mode = frame.args['mode'] or frame:getParent().args['mode'] 
  local nolink =  frame.args['nolink'] or frame:getParent().args['nolink'] 
  
  list = mw.text.trim( list )
  
	local names = mw.text.split( list, "\n" )   -- could use plain option
	--local genus, species, authority
	local output = { }            -- table of species names for output

	local i = 1
	while names[i] do
		
		local name, match, skip
		local sep = " "                                               -- space between genus and species
		local infrasep = ""  
		local italics = "''"
		local genus, species, subspecies, authority
        --local subspecies = ""
        
        if compare and not names[i]:find("^" .. compare) then skip = true end -- only consider lines beginning with compare text (=genus)                                                          
                                                                              -- TODO try "(%S+)([%s×]+)(%S+) (.*)" 
        if mode == "genus" or mode == "taxon" then               -- assume form taxon authority
 				for g, a in string.gmatch(names[i], "(%S+) (.*)" )  do -- match: genus × species authority
					genus = g
					species = ""
				    sep = ""
					if a ~= "" then authority = a end                          -- no authority after space
					match = true                                               -- we have a match 
					if mode == "taxon" then italics = "" end
				end
      	
        else                                  -- match species list (various forms w/wo authority, hybrid)

	        if not match then 
				for g, s, f, ss, a in string.gmatch(names[i], "(%S+) (%S+)( subsp%. )(%S+) (.*)" ) do -- match: genus species subsp. subspecies authority
					genus = g
					species = s 
					subspecies = ss
					infrasep = f --" subsp. "
					sep = " "
					if a ~= "" then authority = a end                          -- no authority after space
					match = true                                               -- we have a match 
				end
			end
			if not match then 
				for g, s, f, ss in string.gmatch(names[i], "(%S+) (%S+)( subsp%. )(%S+)" ) do -- match: genus species subsp. subspecies
					genus = g
					species = s 
					subspecies = ss
					infrasep = f -- " subsp. "
					sep = " "
					--if a ~= "" then authority = a end                          -- no authority after space
					match = true                                               -- we have a match 
				end
			end
	        if not match then 
				for g, s, a in string.gmatch(names[i], "(%S+) × (%S+) (.*)" ) do -- match: genus × species authority
					genus = g
					species = s 
					sep = " × "
					if a ~= "" then authority = a end                          -- no authority after space
					match = true                                               -- we have a match 
				end
			end
	
			if not match then 
				for g, s in string.gmatch(names[i], "(%S+) × (%S+).*" ) do   --  match:  genus × species
					genus = g
					species = s
					sep = " × "
					if a ~= "" then authority = a end
					match = true
				end
			end
	        if not match then 
				for g, s, a in string.gmatch(names[i], "(%S+) (%S+) (.*)" ) do -- match: genus species authority
					genus = g
					species = s 
					if a ~= "" then authority = a end                          -- no authority after space
					match = true                                               -- we have a match for genus, species, authority
				end
			end
			if not match then 
				for g, s in string.gmatch(names[i], "(%S+) (%S+).*" ) do       -- match: genus species
					genus = g
					species = s 
					match = true
				end
			end
		end

		if match and not skip then
			local species_name = genus .. sep .. species  
			if subspecies then
				name = "''" .. species_name .. "''" .. infrasep .. "''"  .. subspecies .."''"          
				if not nolink then 
					name =  "[[" .. species_name .. infrasep .. subspecies   .. "|" .. name .. "]]"    -- wikilinked name with redirect
			    end
			else
				name = species_name
				if not nolink then name = "[[" .. name .. "]]" end       -- add wikilink
				name = italics .. name .. italics                        -- add italics 
			end
 
 
			if authority  and expand then
			   name = name.. " " .. frame:expandTemplate{ title = 'small', args = { authority } }  --expand template
			elseif authority then
			   name = name .. " {{small|" .. authority .."}}"                                 -- don't expand template
			end

		end
	   	if name  then 
	  		table.insert ( output , name )
	  	elseif not skip then 
	  		table.insert ( output ,'<span class="error">unsupported format: expects "genus species authority"</span>' )
	  	end
	   
  	 
		i=i+1
	end
  
	return "*" .. table.concat(output, "\n*")
	
end

p.format_taxon_list = function(frame)

  local list = frame.args[1] or frame:getParent().args[1] 
  local expand = frame.args['expand'] or frame:getParent().args['expand'] -- want to subst template code
  
  list = mw.text.trim( list )
  
	local names = mw.text.split( list, "\n", plain )
	--local genus, species, authority
	local output = { }            -- table of species names for output
    local patterns = { "(%S+)( × )(%S+) (.*)",           --     genus × species authority
    	              "(%S+)( × )(%S+).*",              --     genus × species
    	               "(%S+)( )(%S+) (.*)",            --     genus species authority
    	               "(%S+)( )(%S+).*",               --     genus species 
    	                                                -- taxon or genus authority
    }
	local i = 1
	while names[i] do
		local name, match
		--local sep = " "                                               -- space between genus and species
		local genus, separator, species, authority
                                                                     -- TODO try "(%S+)([%s×]+)(%S+) (.*)" 
       for k, v in pairs (patterns) do 
			for g, sep, s, a in string.gmatch(names[i], v ) do -- match: genus × species authority
				genus = g
				species = s 
				separator = sep
				if a and a ~= "" then authority = a end                          -- no authority after space
				match = true                                               -- we have a match 
			end
			if match then break end
		end

		if match then
			name = "''[[" .. genus .. separator .. species .. "]]''"  
			if authority  and expand then
			   name = name .. frame:expandTemplate{ title = 'small', args = { authority } }  --expand template
			elseif authority then
			   name = name .. "{{small|" .. authority .."}}"                                 -- don't expand template
			end

		end
	   	if name  then 
	  		table.insert ( output , name )
	  	else
	  		table.insert ( output ,'<span class="error">unsupported format: expects "genus species authority"</span>' )
	  	end
	   
  	 
		i=i+1
	end
  
	return "*" .. table.concat(output, "\n*")
	
end
return p