Web Notes
2016.08.20
Using Liquid in Jekyll - Live with Demos
Liquid is a simple template language that Jekyll uses to process pages for your site. With Liquid you can output complex contents without additional plugins.
While using Markdown in Jekyll, it’s easy to insert any code blocks into blog posts. But we need a step further to make them fancy.
By default, Jekyll was integrated with Rouge - a pure Ruby syntax highlighter which supports over 100 languages. Since Rouge themes are compatible with Pygments’s stylesheets, it’s nice for us to choose a favourable style from availabe Pygments themes.1
Once you have installed Jekyll, Rouge is already included as dependencies.
If you’re still using Jekyll 2, it’s also quick and painless to install Rouge. Just open your favourite command line tool and enter the following command:
gem install rouge
Then, in your _config.yml
, set Rouge as your syntax highlighter:
highlighter: rouge
Rouge will help to render the code snippets in your Markdown posts into pre
and code
tags in the generated HTML pages. The further step is style these HTML elements using CSS.
In Jekyll’s official document: stylesheets for syntax highlighting, there is an example stylesheet (syntax.css) you can use.
Besides that, Rouge is 100% compatible with Pygments’s stylesheets, you can choose one of those Pygments themes and use it on your site.
You can preview the Pygments predefined styles at http://pygments.org/demo/. Input some sample codes, and choose the correct language.
Adjust the Style to preview the rendered HTML snippet. Once you found your favourite style, download the demo file. The CSS styles in the downloaded file are we needed.
Since Pygments stylesheet uses .demo-highlight
as the class name in the demo file, and Rouge uses .highlight
instead. You need to replace all the .demo-highlight
with .highlight
and put those CSS styles into your stylesheet file.
Highlight code blocks in Jekyll posts is very easy, just wrap the code snippets in Markdown files like this:
{% highlight ruby linenos %}
...
...
{% endhighlight %}
In this way of using Liquid tag highlight
, you can add language identifier (here is ruby
) or its supported aliases (rb
for Ruby). All supported language by Rouge can be found at List of supported languages and lexers - Rouge Wiki. Also, the always-up-to-date list of supporting language can be found by running the command: bundle exec rougify list
.2
If you don’t need the line numbers, you can simply use fenced_code_blocks
style in Markdown files just with triple backticks like this:
For example, this snippet of Ruby code:
def show
puts "Outputting a very lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong line"
@widget = Widget(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @widget }
end
end
Just using the following markups in the Markdown file:
To display the line numbers, like:
1
2
3
4
5
6
7
8
def show
puts "Outputting a very lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong line"
@widget = Widget(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @widget }
end
end
You need to use the highlight
liquid tag with linenos
explicitly in the Markdown files:
{% highlight ruby linenos %}
def show
puts "Outputting a very lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong lo-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-ong line"
@widget = Widget(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @widget }
end
end
{% endhighlight %}
The fenced_code_blocks
(triple backticks style) is the most simple and recommended way for code highlights. But it defaults without line numbers. Here we can configure kramdown
to show line number for the triple backticks code block. In the Jekyll’s _config.yml
, config like this:
markdown: kramdown
highlighter: rouge
kramdown:
input: GFM
syntax_highlighter_opts:
default_lang: html
css_class: 'highlight'
span:
line_numbers: false
block:
line_numbers: true
start_line: 1
Now, all your code blocks will have line numbers if you use fenced_code_blocks
styled markups. For those code blocks that you don’t want to show the line numbers, just switch to Liquid highlight
tags.
Like dark themes? Have a look at the Pygments Syntax Highlighting themes page. Preview a list of dark Pygments themes and download one from https://github.com/StylishThemes/Syntax-Themes/tree/master/pygments/css-github.
Aside from the Pygments’ styles, Sunil Sarolkar has created a series of pre-defined Rouge themes. Here is a Rouge Theme Preview Page that allows you to have a feel on these themes. Then, download your favourable one from https://github.com/spsarolkar/rouge-theme-preview/tree/gh-pages/css.
Or, if you like my code highlight style just shown in this post, you can get the SCSS from the gist: https://gist.github.com/flinhong/f37f0271bcada97b383bf9f81d8942e7. Don’t forget to include the converted css on required pages…
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// define variables
$code-bg: #2e3e4e;
$tea: #ecebe7;
$gray-200: #e9ecef;
$gray-500: #adb5bd;
$gray-800: #343a40;
$font-family-monospace: 'Ubuntu Mono', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', 'Noto Serif SC', 'STSong', monospace;
figure.highlight,
pre.highlight {
padding: 1rem 1.5rem;
margin: 1.5rem 0;
overflow: auto;
line-height: 1.4rem;
position: relative;
}
.highlighter-rouge {
font-weight: 300;
position: relative;
}
p code.highlighter-rouge,
p kbd {
color: #cc6666;
font-size: 1rem;
background-color: lighten($tea, 5%);
padding: 2px 4px;
border-radius: 2px;
word-break: break-word;
}
kbd {
border: 1px solid $gray-800;
border-radius: 4px;
}
/* "data-lang" should be injected by JavaScript */
/*
figure.highlight::before,
div.highlighter-rouge::before {
font-family: $font-family-monospace;
content: attr(data-lang);
font-size: .9rem;
color: $gray-200;
position: absolute;
display: block;
height: 1rem;
right: .5rem;
z-index: 5;
}
figure.highlight::before {
margin-top: -1rem;
}
*/
.rouge-table .code pre {
overflow: hidden;
}
.rouge-table .code pre {
overflow: hidden;
}
table.rouge-table,
table.rouge-table tr,
table.rouge-table td,
table.rouge-table pre {
border: 0;
padding: 0;
margin: 0;
}
table.rouge-table td.gutter {
padding-right: .5rem;
border-right: 1px solid $gray-500;
}
table.rouge-table td.code {
padding-left: .5rem;
}
figure pre {
margin-bottom: 0;
}
.lineno {
text-align: right;
}
/* Base16 Tomorrow Dark by Chris Kempson; https://github.com/idleberg */
.highlight,
.highlight pre,
.highlight table {
background: $code-bg;
color: $gray-200;
border-radius: 4px;
font-size: 1rem;
}
.highlight .hll { background-color: #373b41 }
.highlight .c { color: #969896 } /* Comment */
.highlight .err { color: #cc6666 } /* Error */
.highlight .k { color: #b294bb } /* Keyword */
.highlight .l { color: #de935f } /* Literal */
.highlight .n, .highlight .h { color: #ffffff } /* Name */
.highlight .o { color: #8abeb7 } /* Operator */
.highlight .p { color: #ffffff } /* Punctuation */
.highlight .cm { color: #969896 } /* Comment.Multiline */
.highlight .cp { color: #969896 } /* Comment.Preproc */
.highlight .c1 { color: #969896 } /* Comment.Single */
.highlight .cs { color: #969896 } /* Comment.Special */
.highlight .gd { color: #cc6666 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #b5bd68 } /* Generic.Inserted */
.highlight .gp { color: #969896; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #8abeb7; font-weight: bold } /* Generic.Subheading */
.highlight .kc { color: #b294bb } /* Keyword.Constant */
.highlight .kd { color: #b294bb } /* Keyword.Declaration */
.highlight .kn { color: #8abeb7 } /* Keyword.Namespace */
.highlight .kp { color: #b294bb } /* Keyword.Pseudo */
.highlight .kr { color: #b294bb } /* Keyword.Reserved */
.highlight .kt { color: #f0c674 } /* Keyword.Type */
.highlight .ld { color: #b5bd68 } /* Literal.Date */
.highlight .m { color: #de935f } /* Literal.Number */
.highlight .s { color: #b5bd68 } /* Literal.String */
.highlight .na { color: #81a2be } /* Name.Attribute */
.highlight .nb { color: #ffffff } /* Name.Builtin */
.highlight .nc { color: #f0c674 } /* Name.Class */
.highlight .no { color: #cc6666 } /* Name.Constant */
.highlight .nd { color: #8abeb7 } /* Name.Decorator */
.highlight .ni { color: #ffffff } /* Name.Entity */
.highlight .ne { color: #cc6666 } /* Name.Exception */
.highlight .nf { color: #81a2be } /* Name.Function */
.highlight .nl { color: #ffffff } /* Name.Label */
.highlight .nn { color: #f0c674 } /* Name.Namespace */
.highlight .nx { color: #81a2be } /* Name.Other */
.highlight .py { color: #ffffff } /* Name.Property */
.highlight .nt { color: #8abeb7 } /* Name.Tag */
.highlight .nv { color: #cc6666 } /* Name.Variable */
.highlight .ow { color: #8abeb7 } /* Operator.Word */
.highlight .w { color: #ffffff } /* Text.Whitespace */
.highlight .mf { color: #de935f } /* Literal.Number.Float */
.highlight .mh { color: #de935f } /* Literal.Number.Hex */
.highlight .mi { color: #de935f } /* Literal.Number.Integer */
.highlight .mo { color: #de935f } /* Literal.Number.Oct */
.highlight .sb { color: #b5bd68 } /* Literal.String.Backtick */
.highlight .sc { color: #ffffff } /* Literal.String.Char */
.highlight .sd { color: #969896 } /* Literal.String.Doc */
.highlight .s2 { color: #b5bd68 } /* Literal.String.Double */
.highlight .se { color: #de935f } /* Literal.String.Escape */
.highlight .sh { color: #b5bd68 } /* Literal.String.Heredoc */
.highlight .si { color: #de935f } /* Literal.String.Interpol */
.highlight .sx { color: #b5bd68 } /* Literal.String.Other */
.highlight .sr { color: #b5bd68 } /* Literal.String.Regex */
.highlight .s1 { color: #b5bd68 } /* Literal.String.Single */
.highlight .ss { color: #b5bd68 } /* Literal.String.Symbol */
.highlight .bp { color: #ffffff } /* Name.Builtin.Pseudo */
.highlight .vc { color: #cc6666 } /* Name.Variable.Class */
.highlight .vg { color: #cc6666 } /* Name.Variable.Global */
.highlight .vi { color: #cc6666 } /* Name.Variable.Instance */
.highlight .il { color: #de935f } /* Literal.Number.Integer.Long */
Thanks to @undavide for the feedbacks on the variable definitions.
The font-face in use in this post is actually the
IBM Plex Mono
, from Google Fonts.
Both configurations and stylings are covered in this post. I think it’s clean now for highlight code blocks using build-in Rouge in Jekyll. If you have any further issues with code highlight in Jekyll, welcome to leave your comment for discussion.
Frank Lin
Web Notes
2016.08.20
Liquid is a simple template language that Jekyll uses to process pages for your site. With Liquid you can output complex contents without additional plugins.
Tutorials
2020.01.09
IKEv2, or Internet Key Exchange v2, is a protocol that allows for direct IPSec tunnelling between networks. It is developed by Microsoft and Cisco (primarily) for mobile users, and introduced as an updated version of IKEv1 in 2005. The IKEv2 MOBIKE (Mobility and Multihoming) protocol allows the client to main secure connection despite network switches, such as when leaving a WiFi area for a mobile data area. IKEv2 works on most platforms, and natively supported on some platforms (OS X 10.11+, iOS 9.1+, and Windows 10) with no additional applications necessary.
Tools
2020.10.20
IBM Cloud CLI allows complete management of the Cloud Functions system. You can use the Cloud Functions CLI plugin-in to manage your code snippets in actions, create triggers, and rules to enable your actions to respond to events, and bundle actions into packages.