make a smarter Enlighter Syntax Highlighter  [ 1097 views ]

Goal: to add some usefull functionality to the Enlighter plugin

In my blog I use the Enlighter plugin to colorize my code sections. The plugin is great, but have some defect.
My extender/customzier is the following:

1. the code block height maximized to 140px and added to div style

.enlighterEnlighterJS {
  max-height: 140px;
  box-shadow: 0px 0px 8px rgba(187, 187, 187, 0.5);  
}
.eshcbebs_wrapper{
  position:relative;
  top: 2px;
}
.eshcbebs_cont{
  position: absolute;
  color: #7d97bd;
  top: -15px;
  right: 4px;
}
.handy{
  cursor: pointer; cursor: hand;
}

2. I’ve added 2 controller to the code block (top right corner)

  • plain text / row numbers switcher
    …be careful you can copy the plain code all time. Even if the row numbers are visible because of the technical solution you never will copy those to the clipboard!
  • expand this / be smaller switcher (visible only when the block is too long)

Check the code provides these functions.

/*
Enlighter Syntax Highlighter Code Block Extender by SilverTerra 
date: 2014.06.02.
version: 1.0.0
*/

var codeBlock = function(block){
  this.build(block);
  return this;
};

(function($){

  codeBlock.prototype = {
    blocks: null,
    build: function(block){
      this.blocks = block || $('ul.EnlighterJS');
      this.blocks.each(function(){
        var h1 = $(this)[0].scrollHeight,
            h2 = $(this).height();  
        
        { // 0. inline blokk - don't touch
        if(h1 == 0){ return false; }    
        }
        
        { // 1. wrap the code view into a div
        $(this).wrap('<div class="eshcbebs_wrapper">');
        }
        
        { // 2. add the extenders
        var rn = '', codeState = 0;
        var myCodeBlock = $(this).parent();
        
        if(myCodeBlock.html().substr(0,3) == '<ol'){
          rn = 'plain text';
          codeState = 1;
        }
        else{
          rn = 'row numbers';
          codeState = 0;
        }
        
        var n = '<div><span class="codeBlockStyle handy">' + rn + '</span>';
        
        // if the overflow is not too big, just increase the height of the block
        if(h1 > 0 && h2 - h1 > -60){
          $(this).css('max-height',h1);
        }
        else if(h1 > h2){
          n += ' | <span class="codeBlockExpander handy">expand this</span>';
        }

          var sw = $(n).addClass('eshcbebs_cont').insertBefore($(this));
        
          // code view height style changer
          sw.find('.codeBlockExpander').on('click',  function(e){
            
              var next = $(this).parent().next(),
                  h1 = next[0].scrollHeight,
                  h2 = next.height();
              
              if($(this).data('opened') == 1){
                next.css('max-height','');
                $(this).removeData('opened');
                $(this).html('expand this');          
                return false;
              }          
              
              if(h1 > h2){ // scrolled
                $(this).data('opened',1);
                $(this).html('be smaller');
                next.css('max-height',h1);
              }
            });        
          
          // code view style changer
          sw.find('.codeBlockStyle').on('click', function(){
            var t = $(this).parent().next()[0].outerHTML;
            if(codeState == 1){ // plain -> row numbered
              codeState = 0;
              $(this).html('row numbers');
              t = t.replace('<ol', '<ul').replace('</ol>','</ul>');
            }
            else{                // row numbered -> plain
              codeState = 1;
              $(this).html('plain text');
              t = t.replace('<ul', '<ol').replace('</ul>','</ol>');
            }
            $(this).parent().next()[0].outerHTML = t;
          });
    
        }
        
      });      
    }
  
  };

}(jQuery));

// link to the syntax highlighter
EnlighterJS.prototype.enlight_old = EnlighterJS.prototype.enlight
EnlighterJS.prototype.enlight = function(x){
  // call the original code
  EnlighterJS.prototype.enlight_old.call(this,x);
  // call my extender
  if(this.isRendered){
    var cd = new codeBlock(jQuery(this.container));
  }
}

how it’s working
After the page load the Enlighter processing the code blocks with EnlighterJS.prototype.enlight(); function one by one.
I want to catch the point where one code block processing is done. Here is. Just override this function mentioned. Inside call the old one and after I can do my job.

...
EnlighterJS.prototype.enlight_old = EnlighterJS.prototype.enlight // the old function
EnlighterJS.prototype.enlight = function(x){ // override
  EnlighterJS.prototype.enlight_old.call(this,x); // first call the original code
  if(this.isRendered){
    var cd = new codeBlock(jQuery(this.container)); // after call my extender
  }
}
...

The extender mechanism is in the code. Wrap the code block and insert the controllers before of the block.

to use this extension you need to do the followings:

  • Enable jquery in your blog (check this: enable jquery in wordpress)
  • put the styles into your stylesheet file
  • put the js code into your js code file or somewhere you want

…and be happy today…

see also: Enlighter – Customizable Syntax Highlighter

#sidebar a { color:#fff; } #sidebar ul ul li { color: #DEF585; } #sidebar h2 { color: #fff; } #sidebar ul p, #sidebar ul select { color: #BEDDBE; } #backfly { background: url(images/golfBallWallPaper.jpg) left bottom fixed repeat-x #65a51d; }