Posts tagged ·



Jekyll: Include partial snippets of code

Comments Off

The Jekyll include tag is useful when including files or templates on a page. Combined with the highlight tag, it makes including code snippets easy. However, it will include the complete file, and often it is desirable to include only a few lines, or maybe a method. That could of course be done by simply copy/pasting the code in question into the article, but then the code gets out of sync if the example file is changed.

The basic usecase is something like this:

{% highlight java %}
    {% include src/ %}
{% endhighlight %}

Ruby based plugin

A Jekyll tag to include only a section of a file would be great. As far as I can tell, that does not exist yet, so I started writing one. Unfortunately, Github Pages does not allow custom plugin for security reasons. There are work-arounds for that, but it also makes the deployment more complex, and loses the convenience of being able to edit the articles and code directly on

Sans error handling or caching, a simple implementation could look like this. It works outside Github Pages, so it’s a start.

module Jekyll
  class IncludeLines < Liquid::Tag
     Syntax = /(#{Liquid::QuotedFragment}+)\s(\d+)\s(\d+)\s\z/o
     def initialize(tag_name, markup, options)
       if markup =~ Syntax
         @file = $1
         @startline = $2.to_i
         @endline = $3.to_i
         raise "Syntax error in includelines: " + markup
     def render(context)
       lines = IO.readlines(context.evaluate(@file))
       part = lines.drop(@startline)
       part.take(@endline - @startline)
 Liquid::Template.register_tag('includelines', Jekyll::IncludeLines)

Liquid slice and split

Using the Liquid capture block, it's possible to read a file and store it as a string variable. It can then be processed by Liquid instead of the plugin, and works fine with Github pages. The Liquid syntax is certainly verbose, but it gets the job done.

An initial implementation cutting the file content as a single string looked like this. However, it is far from ideal, since the character index and count will shift with any source code modifications on the included file.

{% capture filecontent %}
    {% include src/ %}
{% endcapture %}

{% highlight java %}
    {{ filecontent | slice: 132, 57 }}
{% endhighlight %}

A slightly better solution uses the same idea, but operates on line numbers instead. It is almost as fragile when it comes to changes, but at least usable.

{% capture filecontent %}
    {% include src/ %}
{% endcapture %}

{% assign lines = filecontent | newline_to_br | split: '<br />' %}
{% highlight java %}
    {% for line in lines offset:10 limit:5 %}{{ line }}{% endfor %}
{% endhighlight %}

A helper include file implementing this idea can be found here. It can be used like this:

{% include includelines filename='src/' start=10 count=5 %}

Include method

Ideally, it would be possible to mark the start of a line to include, and then indicate how much should be included. Improving on the line based iterator above, this helper file does that. Usage goes like this:

{% highlight java %}
    {% include includemethod filename='src/' method='test()' before=5  after=1 %}
{% endhighlight %}

It also adds options to include lines before and after the specified method, for example for comment blocks or further methods below the first. There are of course some extensions which could be made, e.g. to include multiple split sections; support other non-C like languages, etc. The linked code is under the GPL 3 license, so feel free to improve.

Comments Off

Getting started with GitHub Pages and Jekyll

Comments Off

In the beginning, there were static HTML pages, TABLE-tags, and FTP; later came dynamic sites, WordPress and other Content Management Systems; but now we are back to static pages again, albeit templated. So goes Quinn Supplee’s narrative of the move to Jekyll, Markdown and Liquid based static sites. Add in GitHub for free hosting, and it makes a very compelling offering for a small site run by tech savvy people. It’s not your web sites for dummies solution.

Enabling web page hosting from a Github repository is quick, as explained here. And setting a custom domain is a single setting on Github, and additional setting up your domain DNS. The Github Settings panel have a default example site template generator, so with that you’ll have some pages to look at in few clicks. Now you can download the generated files, modify and upload with standard git commands. (Replace username/repository with your own names).

git clone
git commit
git push

Github uses Jekell to statically generate the site, and this requires a special file and directory structure. It is of course possible to experiment with the files directly on Github, however it might be easier to edit and compile locally. For that, a local install of Jekyll and relevant dependencies and tools is required.

sudo apt-get install ruby ruby-dev rubygems-integration nodejs gcc make
sudo gem install jekyll jekyll-docs jekyll-feed jekyll-paginate bundler minima iconv

On older Debian (7 – Wheezy) or Ubuntu (14.04) distributions, the ruby packages where versioned incorrectly, so the 2.0 version is required for the ruby package and gem binary.

sudo apt-get install ruby2.0 ruby2.0-dev rubygems-integration nodejs ruby-mkrf gcc make
sudo gem2.0 install jekyll jekyll-docs jekyll-feed jekyll-paginate bundler minima iconv

With that in place, you can generate a new blank site, and make Jekyll serve it locally on . Of course, the final destination would be the Github repository.

jekyll new test --skip-bundle
cd test
jekyll serve

For more advanced options and functions, the Jekyll documentation is good. There are some Jekeyll based example sites here. In particular, Patrick Mckinley’s pagination example with source looks interesting.

Comments Off

Git branch in zsh prompt

Comments Off

When working in a git directory, I would like to see the current branch as part of the Zsh prompt. There are more advanced use cases out there, but I’ll stick with the branch name for now.

The following lines in ~/.zshrc takes care of the prompt. There are a few gotchas, though: The git command will fail if not in a git controlled directory, so we’ll have to hide that failure message. Then, for Zsh to execute the function, rather than printing its verbatim name, the prompt_subst option has to be set. Finally, it is important to use single quotes for the PROMPT line. If double quotes are used, the first output of the function is used, and never called again.

function get-git-branch {
  b="`git symbolic-ref --short HEAD 2> /dev/null`" && echo "($b)" || echo ""
setopt prompt_subst
PROMPT='%n@%2m %~ $(get-git-branch) %# '

Comments Off

Git server on Fedora

Comments Off

This covers setting up a SSH access controlled Git server from scratch. It’s assuming there is no other repository to import from. It is loosely based on the instructions from Chapter 4 of the Pro Git book.

Installing Git is simple. You might also want to grab gitk for visualizing your commits and branches, and kdiff3 for merging changes.

yum install git gitk kdiff3

Initial setup might include configuring your name, and editor. “—-global” means that the configuration will be stored under ~/.gitconfig.

git config --global "John Doe"
git config --global

git config --global core.editor emacs

git config --global merge.tool kdiff3

Create an empty repository, and clone it into a “bare” repository. Actually, I’m not sure if the first step is strictly necessary, since the “clone” is “init” + “fetch”.

You might also want to create a root level directory, or alternatively a symbolic link from root, e.g. /git. This will make it easy to reference when cloning and working from remote computers.

mkdir /tmp/git_empty
git init /tmp/git_empty

mkdir /git
cd /git
git clone --bare /tmp/git_empty test.git

Now you can clone (the still empty) repository by the following. Notice the optional port number, if you have SSH running on a different port than the default 22. Notice also, since the port argument is specified, ssh protocol has to be prefixed explicitly.

git clone ssh://

Finally, after adding, changing and committing to the new local clone, these changes can be “pushed” back to the server. Conversely, the updates on the server can be “pulled”.

git push origin master

git pull

Comments Off