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
editparseIndexOverview(indexPlain, rootPath)
editParses 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)
editParses 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
editsplitLines(text)
editSplits 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)
editSplits 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)
editCalculates 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)
editChecks 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)
editLoads 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)
editLoads 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)
editExtracts 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)
editExtract 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;