Module:ListSearch

From Lotro-Wiki.com
Jump to navigation Jump to search

This module is used to search a bulleted/numbered list for a given item, and return the next or previous item. If you pass it a page that contains multiple lists, it will consider them all one list. For example, Template:Index of Patches uses this module to search the List of Patches page and find the next/previous patches in the list.

The main functions provided by this module are:

  • get_next_item -- returns the next item in the list after the specified item
{{#invoke: ListSearch | get_next_item | <wikitext> | <search_item> }}
  • get_previous_item -- returns the previous item in the list before the specified item
{{#invoke: ListSearch | get_previous_item | <wikitext> | <search_item> }}
  • get_first_item -- returns the first item in the list
{{#invoke: ListSearch | get_first_item | <wikitext> }}
  • get_last_item - returns the last item in the list
{{#invoke: ListSearch | get_last_item | <wikitext> }}

The arguments are:

<wikitext> -- some wikitext (e.g. a transcluded page) containing one or more bulleted or numbered list items
<search_item> -- the list item to search for
mode=<mode> -- optional argument; default is "exact"
mode=exact -- the list will be searched for a list item that exactly matches <search_item>
mode=substr -- the list will be searched for a list item that contains <search_item> as a substring
mode=regexp -- not implemented (yet)
error=<text> -- optional argument; default is "(error)"
If the <search_item> is not found in the list, this <text> is returned.
none=<text> -- optional argument; default is "(none)"
If the <search_item> is found at the end of the list and get_next_item() was called, this <text> is returned.
If the <search_item> is found at the beginning of the list and get_previous_item() was called, this <text> is returned.

(This header can be edited at Module:ListSearch/doc.)


-- Extracts all of the bulleted/numbered list items from the supplied wikitext
local function get_list_items(wikitext)
    local items = {};
    for item in wikitext:gmatch('\n[#*:%s]*[#*]%s*([^\n]+)') do
        table.insert(items, item:match('^(.-)%s*$'));
    end
    return items;
end

local p = {}

-- Searches the bulleted/numbered list(s) in the supplied 'wikitext' for the specified 'search_item', then returns the next item in the list.
--  If 'search_item' is the last list item in the 'wikitext', the 'none=' parameter is returned, if any (or "(none)" by default).
--  If 'search_item' is not found in the 'wikitext', the 'error=' parameter is returned, if any (or "(error)" by default).
--  The optional parameter 'mode=' can be 'exact' (default) or 'substr'; if the latter is specified, the 'search_item' will be considered a substring rather than an exact match.
--   Usage:   {{#invoke: ListSearch | get_next_item | <wikitext> | <search_item> }}
--   Usage:   {{#invoke: ListSearch | get_next_item | <wikitext> | <search_item> | mode=<mode> }}
function p.get_next_item(frame)
    local items = get_list_items(frame.args[1]);
    local search_item = frame.args[2]:match('^%s*(.-)%s*$');
    local mode = (frame.args["mode"] or "exact"):match('^%s*(.-)%s*$');
    for n, item in ipairs(items) do
        if (((mode == "exact") and (item == search_item)) or ((mode == "substr") and item:find(search_item, 1, true)))  then
            if (n < #items) then
                return items[n + 1];
            else
                return frame.args["none"] or "(none)";
            end
        end
    end
    return frame.args["error"] or "(error)";
end

-- Identical to get_next_item(), but returns the previous item instead.
--   Usage:   {{#invoke: ListSearch | get_previous_item | wikitext | search_item }}
function p.get_previous_item(frame)
    local items = get_list_items(frame.args[1]);
    local search_item = frame.args[2]:match('^%s*(.-)%s*$');
    local mode = (frame.args["mode"] or "exact"):match('^%s*(.-)%s*$');
    for n, item in ipairs(items) do
        if (((mode == "exact") and (item == search_item)) or ((mode == "substr") and item:find(search_item, 1, true)))  then
            if (n > 1) then
                return items[n - 1];
            else
                return frame.args["none"] or "(none)";
            end
        end
    end
    return frame.args["error"] or "(error)";
end

-- Returns the first item from the bulleted/numbered list(s) in the supplied 'wikitext'
--   Usage:   {{#invoke: ListSearch | get_first_item | <wikitext> }}
function p.get_first_item(frame)
    local items = get_list_items(frame.args[1]);
    return items[1];
end

-- Identical to get_first_item(), but returns the last item instead.
--   Usage:   {{#invoke: ListSearch | get_last_item | <wikitext> }}
function p.get_last_item(frame)
    local items = get_list_items(frame.args[1]);
    return items[#items];
end

return p;