-
Notifications
You must be signed in to change notification settings - Fork 56
/
snippets.rb
66 lines (60 loc) · 1.86 KB
/
snippets.rb
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
module Jekyll
class SnippetsTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
@text = text.strip
end
def render(context)
page = context['page']
types = page['snippets_types']
out = '<div class="tabs">'
basename = File.join('snippets', @text)
glob_snippets(basename, types).each_with_index { |row, index|
out << render_tab(row['label'], row['filename'], row['syntax'], index == 0)
}
out << '</div>'
end
private
def render_tab(label, filename, syntax, focused)
name = "snippet-#{@text}"
id = "snippet-#{@text}-#{label.downcase.gsub(/\s+/, '-')}"
code = File.read(filename)
highlighted = highlight(syntax, code)
checked = focused ? 'checked="checked"' : ''
<<-HTML
<input name="#{name}" type="radio" id="#{id}" #{checked}/>
<label for="#{id}">#{label}</label>
<div class="tab">
<figure class="highlight">
<pre><code class="language-#{syntax.tr('+', '-')}" data-lang="#{syntax}">#{highlighted}</code></pre>
</figure>
</div>
HTML
end
def glob_snippets(basename, types)
types.map { |ext, params|
filename = "#{basename}.#{ext}"
if File.exist? filename
data = params.clone
data['filename'] = filename
data
else
nil
end
}.compact
end
def highlight(lang, code)
require "rouge"
formatter = ::Rouge::Formatters::HTMLLegacy.new(
:line_numbers => false,
:wrap => false,
:css_class => "highlight",
:gutter_class => "gutter",
:code_class => "code"
)
lexer = ::Rouge::Lexer.find_fancy(lang, code) || Rouge::Lexers::PlainText
formatter.format(lexer.lex(code))
end
end
end
Liquid::Template.register_tag('snippets', Jekyll::SnippetsTag)