Skip to content

Instantly share code, notes, and snippets.

@LouisBarranqueiro
Last active August 2, 2016 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LouisBarranqueiro/c1ba29e7d008d81164ab6173d9850d8b to your computer and use it in GitHub Desktop.
Save LouisBarranqueiro/c1ba29e7d008d81164ab6173d9850d8b to your computer and use it in GitHub Desktop.
Hexo tag + Client JS code to create and animate a tabbed code block. https://jsfiddle.net/LouisBarranqueiro/77qyxx6c/
'use strict';
(function($) {
/**
* Animate tabs of tabbed code blocks
* @returns {void}
*/
function animateTabbedCodeBlocks() {
var $codeBlocks = $('.codeblock-tabbed');
$codeBlocks.find('.tab').click(function() {
var $codeblock = $(this).parent().parent().parent();
var $tabsContent = $codeblock.find('.tabs-content').children('pre, .highlight');
// remove `active` css class on all tabs
$(this).siblings().removeClass('active');
// add `active` css class on the clicked tab
$(this).addClass('active');
// hide all tab contents
$tabsContent.hide();
// show only the right one
$tabsContent.eq($(this).index()).show();
});
}
$(document).ready(function() {
animateTabbedCodeBlocks();
});
})(jQuery);
'use strict';
var util = require('hexo-util');
var highlight = util.highlight;
var stripIndent = require('strip-indent');
var jsDom = require('jsdom');
// create a window with a document to use jQuery library
jsDom.env('', function(err, window) {
if (err) {
console.error(err);
}
var $ = require('jquery')(window);
/**
* Tabbed code block
* @param {Array} args
* @param {String} content
* @returns {string}
*/
function tabbedCodeblock(args, content) {
var rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i;
var rCaption = /(\S[\S\s]*)/;
var rTab = /<!--\s*tab (\w*)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
var arg = args.join(' ');
var config = hexo.config.highlight || {};
var html;
var matches = [];
var match;
var caption = '';
var codes = '';
// extract languages and source codes
while ((match = rTab.exec(content))) {
matches.push(match[1]);
matches.push(match[2]);
}
// create tabs and tabs content
for (var i = 0; i < matches.length; i += 2) {
var lang = matches[i];
var code = matches[i + 1];
var $code;
// trim code
code = stripIndent(code).trim();
if (config.enable) {
// highlight code
code = highlight(code, {
lang: lang,
gutter: config.line_number,
tab: config.tab_replace,
autoDetect: config.auto_detect
});
}
else {
code = code.replace(/</g, '&lt;').replace(/>/g, '&gt;');
code = '<pre><code>' + code + '</code></pre>';
}
// used to parse HTML code and ease DOM manipulation
$code = $('<div>').append(code).find('>:first-child');
// add tab
// active the first tab
// display the first code block
if (i === 0) {
caption += '<li class="tab active" data-lang="' + lang + '">' + lang + '</li>';
$code.css('display', 'block');
}
else {
$code.css('display', 'none');
caption += '<li class="tab" data-lang="' + lang + '">' + lang + '</li>';
}
codes += $code.prop('outerHTML');
}
// build caption
caption = '<ul class="tabs">' + caption + '</ul>';
// add caption title
if (rCaptionUrl.test(arg)) {
match = arg.match(rCaptionUrl);
caption = '<a href="' + match[2] + match[3] + '">' + match[1] + '</a>' + caption;
}
else if (rCaption.test(arg)) {
match = arg.match(rCaption);
caption = '<span>' + match[1] + '</span>' + caption;
}
codes = '<div class="tabs-content">' + codes + '</div>';
// wrap caption
caption = '<figcaption>' + caption + '</figcaption>';
html = '<figure class="codeblock codeblock-tabbed">' + caption + codes + '</figure>';
return html;
}
// Register tabbed code block tag
hexo.extend.tag.register('tabbed_codeblock', tabbedCodeblock, {ends: true});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment