'use strict';

var path = require('path');
var marked = require('marked');
var cheerio = require('cheerio');
var deepExtend = require('deep-extend');
var translit = require(path.join(global.pathToApp,'core/lib/translit'));

var renderer = new marked.Renderer();

// Module configuration
var globalConfig = global.opts.core && global.opts.core.processMd ? global.opts.core.processMd : {};
var config = {
    espaceCodeHTML: true,

    marked: {
        renderer: renderer
    }
};
// Overwriting base options
deepExtend(config, globalConfig);

marked.setOptions(config.marked);

// Processing with native markdown renderer
renderer.code = function (code, language) {
    if (language === 'example') {
        return '<div class="source_example">' + code + '</div>';
    } else {
        if (config.espaceCodeHTML) code = code.replace(/</g, "&lt;").replace(/>/g, "&gt;");

        if (language && language !== '') {
            return '<code class="src-' + language + ' source_visible">' + code + '</code>';
        } else {
            return '<pre><code class="lang-source_wide-code">' + code + '</code></pre>';
        }
    }
};

renderer.heading = function (text, level) {
    var escapedText = translit(text);

    return '<h' + level + ' id="' + escapedText + '">' + text + '</h' + level + '>';
};

module.exports = function (markdown) {
    var input = markdown;

    var $ = cheerio.load('<div id="content">' + marked(input) + '</div>');

    // Spec description
    var $H1 = $('#content > h1');
    var $afterH1 = $H1.nextUntil('h2');
    $afterH1.remove();
    $H1.after('<div class="source_info">' + $afterH1 + '</div>');

    // Spec sections
    $('#content > h2').each(function () {
        var $this = $(this);
        var $filteredElems = $('');

        var $sectionElems = $this.nextUntil('h2');
        var id = $this.attr('id');
        $this.removeAttr('id');

        // Adding additional check, since cheerio .nextUntil is not stable
        $sectionElems.each(function () {
            if (this.tagName === 'h2') return false;

            $filteredElems = $filteredElems.add(this);
        });

        $filteredElems.remove();

        $(this).replaceWith([
            '<div class="source_section" id="' + id + '">',
            $this + $filteredElems,
            '</div>'
        ].join(''));
    });

    return $('#content').html();
};
@@ -426,54 +426,204 @@
 ue,%0A
-%0A
     
-marked: %7B%0A        renderer: renderer%0A    
+languageRenderers: %7B%0A        example: function (code) %7B%0A            return '%3Cdiv class=%22source_example%22%3E' + code + '%3C/div%3E';%0A        %7D%0A    %7D,%0A%0A    // Define marked module options%0A    marked: %7B
 %7D%0A%7D;
@@ -690,43 +690,8 @@
 );%0A%0A
-marked.setOptions(config.marked);%0A%0A
 // P
@@ -782,24 +782,31 @@
     if (
+config.
 language
  === 'ex
@@ -801,89 +801,101 @@
 uage
- === 'example') %7B%0A        return '%3Cdiv class=%22source_example%22%3E' + code + '%3C/div%3E'
+Renderers.hasOwnProperty(language)) %7B%0A        return config.languageRenderers%5Blanguage%5D(code)
 ;%0A  
@@ -1431,16 +1431,153 @@
 %3E';%0A%7D;%0A%0A
+// Extend re-defined renderer%0Aconfig.marked.renderer = deepExtend(renderer, config.marked.renderer);%0A%0Amarked.setOptions(config.marked);%0A%0A
 module.e

allow configuration of MD lang-renderers, add extend for re-defined MD renderer (for #155)