toloframework
Version:
Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.
134 lines (128 loc) • 4.52 kB
JavaScript
/**
* Component x-article
*/
var Path = require("path");
exports.tags = ["x-article"];
/**
* Compile a node of the HTML tree.
*/
exports.compile = function(root, libs) {
var N = libs.Tree,
result = [],
head = null,
title = libs.getVar("$title"),
app,
refs = {},
links = [],
pageIndex = 0;
N.forEachAttrib(root, function (attName, attValue) {
if (attName.toLowerCase() == 'title') {
title = attValue;
}
else if (attName.toLowerCase() == 'app' && attValue.length > 0) {
app = attValue;
}
});
N.forEachChild(root, function (child) {
if (child.type != N.TAG) return;
var name = child.name.toLowerCase();
if (name == 'head') {
head = child;
}
else if (name == 'page') {
var article = {
type: N.TAG,
name: "article",
attribs: {},
children: []
};
var section = {
type: N.TAG,
name: "section",
attribs: {"class": "x-article custom"},
children: []
};
var html = {
type: N.TAG,
name: "x-html",
attribs: {},
children: []
};
child.name = 'x-md';
if (typeof child.attribs.title === 'undefined') {
html.attribs.title = title;
section.children.push(
libs.parseHTML(
"<header><a class='back' href='"
+ libs.getBackToRoot(libs.getVar('$filename'))
+ "index.html'>◀</a>" + title + "</header>"
)
);
}
section.children.push(article);
if (typeof child.attribs.app === 'undefined') html.attribs.app = app;
if (head) {
html.children.push(head);
}
libs.compile(child);
// Looking for references over all pages.
N.walk(child, function(node) {
if (node.type == N.TAG && node.name.toLowerCase() == 'a') {
node.page = pageIndex;
if (node.attribs.name) {
refs[node.attribs.name] = pageIndex;
}
if (node.attribs.href && node.attribs.href.charAt(0) == '#') {
links.push(node);
}
}
});
article.children.push(child);
// Adding a tailing space. This is needed for aesthetic reasons.
article.children.push( N.div({style: 'height:1rem'}) );
html.children.push(section);
result.push(html);
pageIndex++;
}
});
links.forEach(function (link) {
var href = link.attribs.href.substr(1);
var ref = refs[href];
if (typeof ref === 'undefined') {
libs.fatal("Reference not found: \"" + href + "\"!\n" + N.toString(link));
}
if (link.page != ref) {
var filename = Path.basename(libs.getVar('$filename'));
if (ref > 0) {
filename = filename.substr(0, filename.length - 4) + ref + '.html';
}
link.attribs.href = filename + '#' + href;
}
});
// Add page navigation if more than one page.
if (result.length > 1) {
result.forEach(function (page, idx) {
var filename,
footer = "<footer><div>";
for (var idxPage = 0 ; idxPage < result.length ; idxPage++) {
filename = Path.basename(libs.getVar('$filename'));
if (idxPage > 0) {
filename = filename.substr(0, filename.length - 4) + idxPage + '.html';
}
footer += "<div>";
if (idx == idxPage) {
footer += "<div class='selected'>" + (1 + idx) + "</div>";
} else {
footer += "<a href='" + filename + "'>" + (idxPage + 1) + "</a>";
}
footer += "</div>";
}
footer += "</div></footer>";
page.children[page.children.length - 1].children.push(libs.parseHTML(footer));
});
}
root.type = N.PAGES;
delete root.name;
delete root.attribs;
root.children = result;
};