var _ = require('lodash');
var marked = require('marked');

var renderer = require('./renderer');

// Synchronous highlighting with highlight.js
marked.setOptions({
    highlight: function (code) {
        return require('highlight.js').highlightAuto(code).value;
    }
});


// 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';
}

// Render a section using our custom renderer
function render(section) {
    // marked's Render expects this, we don't use it yet
    section.links = {};

    // Build options using defaults and our custom renderer
    var options = _.extend({}, marked.defaults, {
        renderer: renderer()
    });

    return marked.parser(section, options);
}

function parsePage(src) {
    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);
    })
    .map(function(section) {
        // Generate a uniqueId to identify this section in our code
        var id = _.uniqueId('gitbook_');

        // Transform given type
        if(section.type === 'exercise') {
            var nonCodeNodes = _.reject(section, {
                'type': 'code'
            });

            var codeNodes = _.filter(section, {
                'type': 'code'
            });

            return {
                id: id,
                type: section.type,
                content: render(nonCodeNodes),
                code: {
                    base: codeNodes[0].text,
                    solution: codeNodes[1].text,
                    validation: codeNodes[2].text,
                }
            };
        }

        // Render normal pages
        return {
            id: id,
            type: section.type,
            content: render(section)
        };
    })
    .value();
}

// Exports
module.exports = parsePage;

@@ -51,16 +51,52 @@
 arked');
+%0Avar hljs = require('highlight.js');
 %0A%0Avar re
@@ -223,16 +223,22 @@
 on (code
+, lang
 ) %7B%0A    
@@ -245,38 +245,111 @@
     
-return require('highlight.js')
+try %7B%0A            return hljs.highlight(lang, code).value;%0A        %7D catch(e) %7B%0A            return hljs
 .hig
@@ -368,24 +368,34 @@
 ode).value;%0A
+        %7D%0A
     %7D%0A%7D);%0A%0A%0A

Fix usage of highlight.js