Tuesday, September 6, 2016

Simple and functional code syntax highlighter gadget for the Blogger, part 2

In my previous blog post I was evaluating a number of free code syntax highlighters that could be used in my blog. I have also developed a simple and usable gadget that extends the formatted content produced by the the Syntax Highlighter with convenient buttons that allow selecting the complete code blocks. This eliminates annoying  process of selection with a mouse throughout multiple screens.

I have also mentioned about a true lightweight and usable alternative tool, hilite.me. It impressed me with "no code" approach, rich formatting options, and complete absence of usually annoying tiny bugs. In other words, you can just quickly format your source code on the site and directly insert it into your blog post. I mean you do not need to bother of embedding any kind of custom JS-libraries to support the formatting of your code in the post.

A gadget

Traditionally, I have developed a second gadget for my blog. It extends the formatted code, produced by "hilite,me" and inserted into a blog post, with convenient buttons that can select the complete code blocks. It also adds a green line separator between row numbers and lines of code to unify the "look-and-feel" with the highlighting functionality of GitHub Gist and the Syntax Highlighter,

How to use this gadget to highlight your code

1. Copy the source code you plan to add to your blog post into he clipboard from the code block shown below.

2. Open the hilite.me, paste your source code into the left text area, select a desired Language below it, change CSS option in the text box below Language to "padding:0px 0px;", select Style (I use vs), toggle the checkbox Line numbers, and click the button "Highlight!".

3. Copy the produced formatted output from the right text area into the clipboard.

4. Paste the content into your blog post and save it. It should already look good.

5. Open your blog settings, change to Layout, add an "HTML/JavaScript gadget" into a section "footer-<n>" of your blog's layout, copy-paste the complete source code of the gadget shown above, and save changes.

  • Use the button "Select the code", copy-paste and save changes.

After that, your inserted source code should look like on the screen below.

Complete code of the gadget

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<!-- 
The gadget that refines the formatted output from http://hilite.me. 
Author: Paul Borisov, http://paulborisov.blogspot.fi/2016/09/simple-and-functional-source-code.html
-->
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js" type="text/javascript"></script-->
<script type="text/javascript">  
  jQuery(document).ready(function() {
    jQuery.fn.selTextHlm = function() {
      if( this.length === 0 ) return;
      var doc = document
        , text = this[0]
        , range, selection
      ;    
      if (doc.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
      } else if (window.getSelection) {
        selection = window.getSelection();        
        range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    }

    jQuery("tr > td:nth-child(2) > pre").each(function() {
      var uniqueId = Math.random().toString(16).slice(2);
      var idTop = "btnSelectCode" + uniqueId + "top";
      var idBottom = "btnSelectCode" + uniqueId + "bottom";
      if( !jQuery(this).parent().hasClass("code-block-container-hlm") ) {
        var htmlButton = '<div class="code-selection-container-hlm"><div id="{0}">Select the code</div></div>';
        jQuery(this).wrap('<div class="code-block-container-hlm"></div>');
        if( !jQuery(this).hasClass("hide-top-button") ) {
          var buttonTop = htmlButton.replace("{0}", idTop);
          var codeTopDiv = jQuery(this).closest("table").parent();
          codeTopDiv.before(buttonTop);
          if( !codeTopDiv.hasClass("code-top-container-hlm") ) {
            codeTopDiv.addClass("code-top-container-hlm");
          }
        }
        if( !jQuery(this).hasClass("hide-bottom-button") ) {
          var buttonBottom = htmlButton.replace("{0}", idBottom);
          var codeTopDiv = jQuery(this).closest("table").parent();
          codeTopDiv.after(buttonBottom);
          if( !codeTopDiv.hasClass("code-top-container-hlm") ) {
            codeTopDiv.addClass("code-top-container-hlm");
          }
        }

        function SelectTextInCodeContainerHlm(codeContainer) {
          var codeTopContainer = codeContainer.closest(".code-top-container-hlm");
          // Get and keep scroll positions
          var scrollLeft = codeTopContainer.scrollLeft();
          var scrollTop = jQuery(document).scrollTop();
          codeContainer.selTextHlm();
          // Next line eliminates unpleasant bug with changed scroll positions in IE.
          codeTopContainer.scrollLeft(0);
          jQuery(document).scrollTop(scrollTop);       
        }
        jQuery("#" + idTop).click(function() {
          var codeContainer = 
            jQuery(this).closest(".code-selection-container-hlm")
              .next().find(".code-block-container-hlm pre");
          SelectTextInCodeContainerHlm(codeContainer);
        });
        jQuery("#" + idBottom).click(function() {
          var codeContainer = 
            jQuery(this).closest(".code-selection-container-hlm")
              .prev().find(".code-block-container-hlm pre");
          SelectTextInCodeContainerHlm(codeContainer);
        });
      }
      
      var re1 = /<span\s+?style="border\:\s+?1px\s+?solid\s+?#FF0000;">/gi;
      var re2 = /<span\s+?style="border\:\s+?1px\s+?solid\s+?rgb\(255,\s+?0,\s+?0\);\s+?border-image\:\s+?none;">/gi;
      var replacement = '<span style="color:#00f;">';
      var html = jQuery(this).html();
      if( html.match(re1) ) {
        jQuery(this).html(html.replace(re1,replacement));
        html = jQuery(this).html();
      }
      if( html.match(re2) ) {
        jQuery(this).html(html.replace(re2, replacement));
        //html = jQuery(this).html();
      }
    });
  });
</script>
<style type="text/css">
  .code-selection-container-hlm {text-align: left;}
  .code-selection-container-hlm > div {cursor:pointer; border:1px #ccc solid;padding:2px 2px 2px 8px; width: 100px; display:inline-block; border-radius: 7px 7px;}
  .code-top-container-hlm {margin-top:15px;margin-bottom:15px;width:875px !important;overflow:hidden;}
  .code-top-container-hlm tr td:nth-of-type(1) {border-right:3px solid #6ce26c !important;color:#afafaf !important;padding-right:5px;}
  .code-top-container-hlm tr td:nth-of-type(2) {padding-left:5px;}
  .code-block-container-hlm {}
</style>



No comments:

Post a Comment