Dru Riley asked via a comment how I
achieved the CoffeeScript/JS highlighting switch on my blog which looks like
this:
.coffee .js <-- These buttons toggle CoffeeScript/JavaScript 1
2
3
4
CoffeeScript is 'awesome'
dance () if you . love CoffeeScript
i . love CoffeeScript
yay ()
The answer: a hack. I don’t code ruby, so I couldn’t figure out how to
do it neatly (or even if I could - feedback welcome!). The easiest way for me to do it was
just to modify plugins/backtick_code_block.rb
, then add the JS and CSS
to make it work.
If you want to see how I did it, or do it yourself, here are my diffs:
NOTE : These diffs should be ran against revision c069dc7 of Octopress,
which is already quite out of date…
Hack backtick plugin to highlight both JS and CS (plugins/backtick_code_block.rb.diff) download
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
diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb
index 40e7900..4450f12 100644
--- a/plugins/backtick_code_block.rb
+++ b/plugins/backtick_code_block.rb
@@ -14,12 +14,18 @@ module BacktickCodeBlock
@options = $1 || ''
str = $2
+ extra = ''
+ id = rand(999999999)
+ fig_id = "figure_#{id}"
+
if @options =~ AllOptions
@lang = $1
- @caption = "<figcaption><span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>"
+ extra = genExtra @lang, fig_id
+ @caption = "<figcaption>#{extra}<span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>"
elsif @options =~ LangCaption
@lang = $1
- @caption = "<figcaption><span>#{$2}</span></figcaption>"
+ extra = genExtra @lang, fig_id
+ @caption = "<figcaption>#{extra}<span>#{$2}</span></figcaption>"
end
if str.match(/\A( {4}|\t)/)
@@ -35,9 +41,40 @@ module BacktickCodeBlock
raw += "\n```\n"
else
code = highlight(str, @lang)
- "<figure class='code'>#{@caption}#{code}</figure>"
+ if extra == ''
+ "<figure class='code'>#{@caption}#{code}</figure>"
+ else
+ alt_lang = ''
+ str2 = ''
+ altcode = ''
+ if @lang == 'coffee-script'
+ lang_display = 'CoffeeScript'
+ alt_lang = 'javascript'
+ alt_lang_display = 'JavaScript'
+ stdin, stdout, stderr, wait_thr = Open3.popen3("coffee -s -b -c -p")
+ stdin.print(str)
+ stdin.close
+ str2 = stdout.readlines(nil)[0]
+ if !str2
+ str2 = stderr.readlines(nil)[0]
+ str2 = "Compilation failed: \n#{str2}"
+ end
+ stdout.close
+ stderr.close
+ exit_status = wait_thr.value
+ end
+ if alt_lang != ''
+ altcode = highlight(str2, alt_lang)
+ end
+ "<figure class='code'>#{@caption}<div clang='#{lang_display}' id=\"#{fig_id}\">#{code}</div><div clang='#{alt_lang_display}' id=\"#{fig_id}_alt\" style=\"display:none;\">#{altcode}</div></figure>"
+ end
end
end
end
end
+ def genExtra(lang,fig_id)
+ if @lang == "coffee-script"
+ return "<span class=\"switchLang\"><a class=\"switchLang selected\" onclick=\"switchLang(event,this,'#{fig_id}');\">.coffee</a><a class=\"switchLang\" onclick=\"switchLang(event,this,'#{fig_id}');\">.js</a></span>"
+ end
+ end
end
The JavaScript to allow the user to toggle (source/javascripts/switchlang.js) download
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
function switchLang ( e , me , id ) {
if ( me . className . match ( /selected/ )) {
return ;
}
if ( ! e ) e = window . event ;
if ( e . preventDefault ) {
e . preventDefault ();
}
if ( ! me . onmouseup ) {
me . onmouseup = function ( e ) {
if ( e && e . preventDefault ) {
e . preventDefault ();
}
}
}
var el1 = document . getElementById ( id );
var el2 = document . getElementById ( id + "_alt" );
if ( ! el1 || ! el2 ) {
return ;
}
if ( el1 . style . display == 'none' ) {
el2 . style . display = 'none' ;
el1 . style . display = 'block' ;
me . parentNode . childNodes [ 0 ]. className = "switchLang selected" ;
me . parentNode . childNodes [ 1 ]. className = "switchLang" ;
} else {
el1 . style . display = 'none' ;
el2 . style . display = 'block' ;
me . parentNode . childNodes [ 0 ]. className = "switchLang" ;
me . parentNode . childNodes [ 1 ]. className = "switchLang selected" ;
}
}
Require the JS (source/_includes/custom/head.html.diff) download
1
2
3
4
5
6
7
8
9
diff --git a/source/_includes/custom/head.html b/source/_includes/custom/head.html
index 85879f4..96009eb 100644
--- a/source/_includes/custom/head.html
+++ b/source/_includes/custom/head.html
@@ -1,3 +1,7 @@
<!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
+<script src="/javascripts/switchlang.js"></script>
Add some (terrible) styling (sass/custom/_styles.scss.diff) download
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
diff --git a/sass/custom/_styles.scss b/sass/custom/_styles.scss
index 680d07f..85db5e3 100644
--- a/sass/custom/_styles.scss
+++ b/sass/custom/_styles.scss
@@ -13,4 +13,102 @@ footer {
vertical-align:top;
}
}
-}
\ No newline at end of file
+}
+
+figure.code figcaption {
+ & a.switchLang {
+ color:white !important;
+ text-shadow: #333 0 1px 0;
+ }
+ span.switchLang {
+ position:absolute;
+ left: .8em;
+ right:auto;
+ padding-left:0;
+ padding-right:3em;
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ -webkit-transition: text-shadow, color 0.3s;
+ }
+ a.switchLang {
+ -webkit-user-select:none;
+ -moz-user-select:none;
+ user-select:none;
+ -webkit-transition: text-shadow, color 0.3s;
+ background-color: #888;
+ position:initial;
+ right:auto;
+ padding:0;
+ padding-left:.8em;
+ padding-right:.8em;
+ //border:1px solid black;
+ display: inline-block;
+ border-top-right-radius:6px;
+ border-bottom-right-radius:6px;
+ border-left:0;
+ height: 1.4em;
+ line-height: 1.4em;
+ }
+ a.switchLang:first-child {
+ //border-right:0;
+ //border-left:1px solid black;
+ border-radius:0;
+ border-top-left-radius:6px;
+ border-bottom-left-radius:6px;
+
+ }
+ a.switchLang.selected {
+ background-color:#666;
+ }
+}
Thanks for your question, Dru!