summaryrefslogtreecommitdiffstats
path: root/lib/parse/lex.js
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@friendco.de>2014-04-06 14:02:49 -0700
committerAaron O'Mullan <aaron.omullan@friendco.de>2014-04-06 14:02:49 -0700
commitc98ba22b08759f054748050945a467819e7481a6 (patch)
treee485f0f3356cb9c0a3027d65c2bed67dce96bfaf /lib/parse/lex.js
parentef059c873753b3cdf42b102fc07b24767c5d0641 (diff)
downloadgitbook-c98ba22b08759f054748050945a467819e7481a6.zip
gitbook-c98ba22b08759f054748050945a467819e7481a6.tar.gz
gitbook-c98ba22b08759f054748050945a467819e7481a6.tar.bz2
Move page lexer to separate module
Allow lexer to be used independently of page parser/renderer
Diffstat (limited to 'lib/parse/lex.js')
-rw-r--r--lib/parse/lex.js63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/parse/lex.js b/lib/parse/lex.js
new file mode 100644
index 0000000..941e537
--- /dev/null
+++ b/lib/parse/lex.js
@@ -0,0 +1,63 @@
+var _ = require('lodash');
+var marked = require('marked');
+
+// Split a page up into sections (lesson, exercises, ...)
+function splitSections(nodes) {
+ var section = [];
+
+ return _.reduce(nodes, function(sections, el) {
+ if(el.type === 'hr') {
+ sections.push(section);
+ section = [];
+ } else {
+ section.push(el);
+ }
+
+ return sections;
+ }, []).concat([section]); // Add remaining nodes
+}
+
+// What is the type of this section
+function sectionType(nodes, idx) {
+ var codeNodes = _.filter(nodes, {
+ type: 'code'
+ }).length;
+
+ if(codeNodes === 3 && (idx % 2) == 1) {
+ return 'exercise';
+ }
+
+ return 'normal';
+}
+
+function lexPage(src) {
+ // Lex file
+ var nodes = marked.lexer(src);
+
+ return _.chain(splitSections(nodes))
+ .map(function(section, idx) {
+ // Detect section type
+ section.type = sectionType(section, idx);
+ return section;
+ })
+ .filter(function(section) {
+ return !_.isEmpty(section);
+ })
+ .reduce(function(sections, section) {
+ var last = _.last(sections);
+
+ // Merge normal sections together
+ if(last && last.type === section.type && last.type === 'normal') {
+ last.push.apply(last, [{'type': 'hr'}].concat(section));
+ } else {
+ // Add to list of sections
+ sections.push(section);
+ }
+
+ return sections;
+ }, [])
+ .value();
+}
+
+// Exports
+module.exports = lexPage;