Module:Mooc/IndexParser
This module is part of the MOOC interface.
The index parser is a central script of the MOOC module. It parses the MOOC index and creates a Lua object holding the single MOOC items along with their meta data stored in the index.
Instance functions
[edit source]parseIndexOverview(indexPlain, rootPath)
[edit source]Parses the MOOC index and extracts the MOOC root item in order to display an overview page.
Parameters:
String
indexPlain: MOOC index contentString
rootPath: title of the MOOC index page
Returns:
Table
table t withMooc/Data/Item
t.item: MOOC root item
parseIndex(indexPlain, itemPath, rootPath)
[edit source]Parses the MOOC index and extracts the MOOC item you are searching for (aka. target item).
Parameters:
String
indexPlain: MOOC index contentString
itemPath: path of the target itemString
rootPath: title of the MOOC index page
Returns:
Table
table t withMooc/Data/Item
t.navigation: MOOC root itemMooc/Data/Item
t.item: target item itself (may benil
if the item was not found)Mooc/Data/Item
t.parent: direct parent of the target itemMooc/Data/Item
t.previous: item preceding the target item (may benil
if first item in its context)Mooc/Data/Item
t.next: item following the target item (may benil
if last item in its context)
Local functions
[edit source]splitLines(text)
[edit source]Splits a text into its single lines.
Parameters:
String
stringValue: String that will be splitted up into single lines
Returns:
Table<String>
table containing the single lines
splitPath(itemPath)
[edit source]Splits an item path into its single parts.
Parameters:
String
itemPath: item path with its single parts separated by/
Returns:
String
item name (last part of the path)Table<String>
table containing the single parts
getLevel(itemHeaderLine)
[edit source]Calculates the level of an item according to the number of heading symbols =
in it's header line.
Q: This is a copy of Mooc/Data/Item.getLevel
, why don't we use it?
Parameters:
String
itemHeaderLine: header line of the item
Returns:
int
item's level if the line is an item headerint
zero otherwise
isItem(header, itemName, itemType)
[edit source]Checks if a header represents a certain item you search for.
Parameters:
Mooc/Data/Item.Header
header: header of an itemString
itemName: name of the item searched forString
itemType: type of the item searched for
Returns:
true
if the header is the item searched forfalse
otherwise
loadParam(textLines, iParamStart)
[edit source]Loads a parameter (aka. meta data entry) from the index.
Parameters:
Table<String>
textLines: MOOC index linesint
iParamStart: index of the (first) line the parameter declaration occupies
Returns:
Table
table t withString
t.name: parameter keyString
t.value: parameter valueint
t.iEnd: last line the parameter declaration occupies
nil
if the line did not contain a parameter (or is malformed)
loadParams(textLines, iItemStart)
[edit source]Loads all parameters of an item.
Parameters:
Table<String>
textLines: MOOC index linesint
iItemStart: index of the (first) line the item occupies
Returns:
Table<String, String>
table containing the parameter values loaded from the index, accessible using the parameter keyint
index of the last line the item occupies
extractItem(textLines, iItemStart, parent, maxLevel, section)
[edit source]Extracts a MOOC item from the index including its meta data and all children up to the maximum level defined.
Parameters:
Table<String>
textLines: MOOC index linesint
iItemStart: index of the (first) line the item occupiesMooc/Data/Item
parent: parental MOOC itemint
maxLevel: maximum item level that will be extracted, children at deeper level will be ignoredint
section: section number of the previous item
Returns:
Mooc/Data/Item
item object extracted from the indexint
index of the last line the item occupiesint
highest section number in use
extractIndex(baseItem, searchPath, searchLevel)
[edit source]Extract the item objects related to a certain MOOC item you are searching for (aka. target item).
Parameters:
Mooc/Data/Item
baseItem: any parental item of the target itemString
searchPath: path of the target itemint
searchLevel: current item level searching at
Returns:
Table
table t withMooc/Data/Item
t.item: target item itself (may benil
if the item was not found)Mooc/Data/Item
t.parent: direct parent of the target itemMooc/Data/Item
t.previous: item preceding the target item (may benil
if first item in its context)Mooc/Data/Item
t.next: item following the target item (may benil
if last item in its context)
local Item = require("Module:Mooc/Data/Item");
local moocIndex = {}
local function splitLines(stringValue)
local lines = {}
for s in stringValue:gmatch("[^\r?\n]+") do
table.insert(lines, s);
end
return lines;
end
local function splitPath(path)
local name;
local pathParts = {}
for s in path:gmatch("[^/]+") do
table.insert(pathParts, s);
end
if #pathParts > 1 then
-- name is last path part
name = pathParts[#pathParts];
else
-- name is full path for root item
name = path;
end
return name, pathParts;
end
local function getLevel(itemHeader)
local leading = string.len(string.match(itemHeader, "^=*"));
local trailing = string.len(string.match(itemHeader, "=*$"));
return math.min(leading, trailing);
end
local function isItem(header, itemName, itemType)
if header:getName() == itemName then
if itemType == nil or itemType:isType(header:getTypeIdentifier()) then
return true;
end
end
return false;
end
local function loadParam(textLines, iParamStart)
local line = textLines[iParamStart];
if line ~= nil and string.sub(line, 1, 1) == "*" then
local iSeparator = string.find(line, "=", 2, true);
if iSeparator ~= nil then
local paramLines = nil;
local paramName = string.sub(line, 2, iSeparator - 1);
local i = iParamStart;
local paramValue = string.sub(line, iSeparator + 1);
local numLines = #textLines;
repeat
if i > iParamStart then
if paramLines == nil then
paramLines = {}
if string.len(paramValue) > 0 then
table.insert(paramLines, paramValue);
end
end
table.insert(paramLines, line);
end
i = i + 1;
line = textLines[i];
until i > numLines or string.sub(line, 1, 1) == "*" or getLevel(line) > 0;
if paramLines ~= nil then
paramValue = table.concat(paramLines, '\n');
end
return {
name = paramName,
value = paramValue,
iEnd = i
}
end
else
return nil;
end
end
local function loadParams(textLines, iItemStart)
local params = {}
local iParamStart = iItemStart + 1;
local numLines = #textLines;
local param;
repeat
param = loadParam(textLines, iParamStart);
if param ~= nil then
params[param.name] = param.value;
iParamStart = param.iEnd;
end
until param == nil or iParamStart > numLines;
return params, iParamStart;
end
local function extractItem(textLines, iItemStart, parent, maxLevel, section)
local section = section + 1;
local header = Item.parseHeader(textLines[iItemStart], parent);
header:setSection(section);
local item = Item(header);
local params;
local nextMaxLevel = 0;
if maxLevel > 0 then
nextMaxLevel = math.max(1, maxLevel - 1);
end
-- load parameters
local i;
params, i = loadParams(textLines, iItemStart);
item:setParams(params);
local itemLevel = item:getLevel();
local child;
local numLines = #textLines;
if maxLevel == 0 or maxLevel > 1 then
-- extract direct children
while i <= numLines do
local level = getLevel(textLines[i]);
if level > itemLevel then
-- add child
child, i, section = extractItem(textLines, i, item, nextMaxLevel, section);
item:addChild(child);
else
-- no child
break;
end
end
else
-- skip all children
while i <= numLines do
local level = getLevel(textLines[i]);
if level > 0 then
if level <= itemLevel then
break;
end
section = section + 1;
end
i = i + 1;
end
end
return item, i, section;
end
local function extractIndex(baseItem, searchPath, searchLevel)
local targetLevel = #searchPath;
local index = nil;
if searchLevel == targetLevel then
-- current item is target item
local index = {}
index["item"] = baseItem;
return index;
end
if baseItem:getChildren() ~= nil then
-- search at next level
local previous = nil;
for _,child in ipairs(baseItem:getChildren()) do
if isItem(child, searchPath[searchLevel + 1]) then
-- child is part of search path
index = extractIndex(child, searchPath, searchLevel + 1);
elseif searchLevel == targetLevel - 1 then
-- child may be next or previous item
if index == nil then
-- child may be previous item
previous = child;
else
-- child is next item
index["next"] = child;
break;
end
end
end
if searchLevel == targetLevel - 1 and index ~= nil and searchLevel > 0 then
-- current item is parental item
index["parent"] = baseItem;
index["previous"] = previous;
end
end
return index;
end
function moocIndex.parseIndexOverview(indexPlain, rootPath)
local textLines = splitLines(indexPlain);
local rootItem = Item(Item.Header("MOOC", 'mooc', nil, rootPath, 0));
rootItem:setParams({});
-- extract all index item down to target level
local i = 1;
local section = 0;
local item;
local numLines = #textLines;
while i <= numLines do
local level = getLevel(textLines[i]);
if level > 0 then
item, i, section = extractItem(textLines, i, rootItem, 2, section);
rootItem:addChild(item);
else
-- skip initial lines
i = i + 1;
end
end
local index = {}
index['item'] = rootItem;
return index;
end
function moocIndex.parseIndex(indexPlain, itemPath, rootPath)
local textLines = splitLines(indexPlain);
local itemName, itemPath = splitPath(itemPath);
local targetLevel = #itemPath;
local rootItem = Item(Item.Header("MOOC", 'mooc', nil, rootPath, 0));
-- extract all index item down to target level
local i = 1;
local section = 0;
local item;
local numLines = #textLines;
while i <= numLines do
local level = getLevel(textLines[i]);
if level > 0 then
item, i, section = extractItem(textLines, i, rootItem, targetLevel + 1, section);
rootItem:addChild(item);
else
-- skip initial lines
i = i + 1;
end
end
-- find target item
local index = extractIndex(rootItem, itemPath, 0);
if index ~= nil then
index["navigation"] = rootItem;
end
return index;
end
return moocIndex;