Highlighting fenced code blocks in Jekyll using Pygments - jekyll

How to highlight fenced code block in Jekyll using Pygments?
```c
for(int i = 0; i < n; i++){
...
}
```
doesn't work. I have to write like this:
{% highlight c %}
for(int i = 0; i < n; i++){
...
}
{% endhighlight %}
I don't like to use Liquid tags and I am using Kramdown.
I am not ready to switch from Kramdown to Redcarpet.
Rouge works fine with fenced code block but I want to use Pygments because it supports more programming languages.
This problem is similar to mine except that it's too old.

Jekyll doesn't understand fenced code block out of the box. This can be easily resolved with the Github Flavored Markdown (aka GFM) parameter (see documentation).
In _config.yml, set :
kramdown:
input: GFM
But : Jekyll 3.x default highlighter is now rouge, that does code highlight for a lot of languages and doesn't need python install.

Related

white space control in jekyll - why does {%- ... -%} a la liquid not work?

The liquid documentation states that
By including hyphens in your assign tag, you can strip the generated whitespace from the rendered template ... if you don't want any of your tags to output whitespace, as a general rule you can add hyphens to both sides of all your tags ({%- and -%}):
When I try in jekyll
{%- case key -%}
I get the error
Error: Liquid syntax error (line 139): Tag '{%- case key -%}' was not
properly terminated with regexp: /\%\}/
There are many posts about excessive whitespace in the jekyll generated html, for example Compressing Liquid generated code.
They all complain about dilute HTML output and discuss plug-ins as solution.
My simple questions are:
Why does {%- ... -%} not work in jekyll ?
Why behaves jekyll differently than the liquid documentation suggests
Jekyll < v3.5.0 use liquid v3.0.6.
White space control is only available in liquid v4 and this version will soon land in Jekyll.
As of 18 June 2017, Jekyll v3.5.0 has upgraded to Liquid v4. {%- ... -%} now works.

Postprocessing HTML in jekyll

Is it possible to add a post-processing step (in ruby) to run in Jekyll after it converts markup to HTML?
I'd like to add some html content, and can't see a way to do that in Jekyll files in general (though certain dialects of markup might support it), so I think it would have to be done by operating on the HTML after Jekyll converts it and before it writes it into _site/.
EDIT: Clarified that I'm looking to do this in Ruby and in arbitrary dialects of markup.
It looks like I may be able to do this by providing a Liquid filter that postprocess the html content, and changing {{ content }} to {{ content | my_postprocess }} in _layouts/post.html and _layouts/page.html.
Indeed, kramdown will not parse markdown in html element by default.
But, there is some configuration parameters that can be set to force kramdown to parse markdown in span or block elements.
Kramdown parameters in Jekyll documentation (look under the kramdown: key) but more interesting things in the kramdown documentation particularly here and here
In configuration
If you want to globally parse markdown in html, in _config.yml, add :
kramdown:
parse_block_html: true
parse_span_html: true
Or, in your markdown itself
{::options parse_block_html="true" /}
{::options parse_span_html="true" /}
<div>
## Some markdown here
**bold** and `code`
<cite>a **span** level element</cite>
</div>
You can also use markdown includes like this :
{% capture md %}{% include markdown_file.md %}{% endcapture %}
{{ md | markdownify }}
This will render any markdown as if it was in the original post/page.
Newer versions of Jekyll let you use hooks to do post-processing (and many other things).
For example, you could put a file like this in the _plugins/ directory, and it will modify the contents of posts after they've been converted to HTML but before they've been embedded in a layout file or written to disk:
Jekyll::Hooks.register :posts, :post_convert do |post|
post.content = post.content.gsub('old', 'new')
end

How can I keep Jekyll from adding whitespace in highlight?

I'm currently experimenting with Jekyll. Most things look fine, but the way Jekyll processes code highlighting seems to be buggy.
I use pygments.
Then Jekyll seems to use pieces like:
{% highlight python %}
#!/usr/bin/env python
def wer(r, h):
"""
{% endhighlight %}
to generate code like
<div class="highlight">
<pre>
<code class="python"><span class="c">#!/usr/bin/env python</span>
<span class="k">def</span> <span class="nf">wer</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> Calculation of WER with Levenshtein distance.</span>
<span class="sd"> Works only for iterables up to 254 elements (uint8).</span>
<span class="sd"> O(nm) time ans space complexity.</span>
[...]
<span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">()</span>
</code>
</pre>
</div>
which looks like
The problem is whitespace between code and pre:
How can I tell Jekyll not to put whitespace between those tags?
repository with my blog
a rendered example page (with this source page).
Bug hunting
My Jekyll version is jekyll 1.3.1.
With gem environment I found that my gems are at /var/lib/gems/1.9.1.
With grep -rn "highlight" --exclude-dir=site --exclude-dir=test * I found that the highlight tag gets parsed in /var/lib/gems/1.9.1/gems/jekyll-1.3.1/lib/jekyll/tags/highlight.rb
As this might be a Jekyll bug, I've added issue 1801
Now comes the strange part: highlight.rb seems not to add any whitespace between <pre> and <code>.
This problem is caused by Liquid, the templating engine of Jekyll (see Issue 216 of Liquid and Issue 1806 of Jekyll).
The current (12.12.2013) answer to this question is: You cannot keep Jekyll from adding those whitespaces.
But a fix to the underlying problem is to remove the whitespaces after all pages have been compiled. I've written the following Python script to do so:
#!/usr/bin/env python
import re, fnmatch, os
def removeWhitespace(file_path):
#read file content
with open(file_path) as f:
content = f.read()
#replace whitespace
openingTag = re.compile('<pre>\s*<code', re.DOTALL)
closingTag = re.compile('</code>\s*</pre>', re.DOTALL)
if re.findall(openingTag, content):
content = re.sub(openingTag, '<pre><code', content)
content = re.sub(closingTag, '</code></pre>', content)
#write without whitespace
with open(file_path,'w') as f:
f.write(content)
# Get all HTML files
files = []
for root, dirnames, filenames in os.walk('.'):
for filename in fnmatch.filter(filenames, '*.html'):
files.append(os.path.join(root, filename))
for filename in files:
removeWhitespace(filename)
This is stylesheet related.
I was able to build your sample page on my test environment using the default without any problem*.
Try adding the following to style.css
/* standard */
.post pre {
border: 1px solid #ddd;
background-color: #eef;
padding: 0 .4em;
}
* Only problem I had was it complained about the following line
Jekyll is a static blog generator.
Which I resolved by wrapping the line in a paragraph tag.

rdiscount enable parsing markdown within block html?

Is there any global option for rdiscount to enable parsing markdown in block html tags? And any way to use that option within Octopress/Jekyll? This is the option that Kramdown supports:
parse_block_html Process kramdown syntax in block HTML tags If this
option is true, the kramdown parser processes the content of block
HTML tags as text containing block-level elements. Since this is not
wanted normally, the default is false. It is normally better to
selectively enable kramdown processing via the markdown attribute.
Default: false
Unfortunately, Jekyll does not pass this kramdown flag to kramdown. I opened an issue on that: https://github.com/mojombo/jekyll/issues/1095
No. There is no RDiscount option for this. All options are listed in the API docs here:
http://rdoc.info/github/davidfstr/rdiscount/RDiscount
Here is a workaround for Jekyll/Octopress. Consider the following example:
<div>
I want this to be in *Markdown*!
</div>
You can use the markdownify tag in Jekyll to manually force a section to be in Markdown:
<div>
{% capture m %}I want this to be in *Markdown*!{% endcapture %}
{{ m | markdownify }}
</div>

How to configure Pygments' HTML formatter in Jekyll

I want to use Jekyll for Github pages and I'm struggling a bit with pygments. Jekyll does not seem to let me configure anything pygments related.
There are two things I want (need) to change:
Use linenos=table so code can be copied easily. {% highlight c linenos=table %} does not work. In addition, it would be more convenient to define this globally and not in every {% highlight ...
When I use {% highlight c %} (notice the C lexer) pygments generates something like: <div class="highlight"><code class="c">...</code></div>. As a result the class c in <code> conflicts with the class c used for <span>s for comments in the highlighted source code. How do I tell pygments to use classprefix?
Both are options documented here: http://pygments.org/docs/formatters.