How can I keep Jekyll from adding whitespace in highlight? - jekyll

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.

Related

Issue Creating Fenced Code Blocks in Jekyll using GFM

I am trying to create some fenced in code blocks on my gh-pages blog, but I am encountering some issues.
This is within my _config.yml
#Stuff I have added
highlight: rouge
markdown: kramdown
kramdown:
input: GFM
highlighter: rouge
Now I am attempting to run this code as follows,
~~~
Is this really how code should be represented?
Answer = NO!!!
~~~
but this is
Please help, I just want the nice fenced code structurem Thanks!
Try creating fenced code blocks with triple backticks ``` instead of triple-tilde ~~~
```
Is this really how code should be represented in GFM?
Answer = YEP!!!
```
It is not showing a fenced block for the source code because there is no source code.
If you don't specify anything then it will use:
<div class="highlighter-rouge"><pre class="highlight"><code>
Is this really how code should be represented?
Answer = NO!!!
</code></pre>
</div>
You always have the option to customize the output using the generated classes like highlighter-rouge.
On the other hand, if you specify a language:
~~~ html
<html>
<body>
<p>Is this really how code should be represented?</p>
<div>Answer = NO!!!</div>
</body>
</html>
~~~
then it will generated more spific styling:
<div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="nt"><html></span>
<span class="nt"><body></span>
<span class="nt"><p></span>Is this really how code should be represented?<span class="nt"></p></span>
<span class="nt"><div></span>Answer = NO!!!<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre>
</div>
If you still aren't able to see any default syntax highlighting, then the css containing those classes is missing, typipcally Jekyll comes with _syntax-highlighting.scss where it already contains them, but you can use the color scheme you want, for example the default theme uses this one: https://github.com/jekyll/minima/blob/master/_sass/minima/_syntax-highlighting.scss
Or you can install whatever Rouge theme you want: https://github.com/jneen/rouge/tree/master/lib/rouge/themes
$ rougify foo.rb
$ rougify style monokai.sublime > syntax.css

jekyll not linking to internal posts

Just started jekyll, and I want to display a link to one of my posts on the index.html page. I looked through the documentation and the following code appears to be what I'm suppose to do.
The following is in index.html
<p>......</p>
[Hello World]({% post_url 2015-01-19-soccer %})
<p>........ </p>
but it simply displays
.....
[Hello World]({% post_url 2015-01-19-soccer %})
.......
what am I doing wrong?
Since you used a mix of Markdown and HTML, which is causing the markdown processor to ignore anything in between the HTML blocks.
Markdown is also sometimes not processed when you have HTML right above the Markdown. (This is the case for you, since your example shows you have closed off the <p> tags)
There are a few ways around this.
Make sure there is a newline in between any HTML and Markdown, this will not show up as a <br> or a <p> in the final output, but rather ensures that the processor will convert the Markdown correctly.
So you should have something like this:
<p>......</p>
[Hello World]({% post_url 2015-01-19-soccer %})
<p>........ </p>
Notice the extra line there between the first <p></p> and the Markdown.
Use only HTML (this is as answered by user #topleft)
Use only Markdown, since <p> tags are supported.
Try the markdown=1 HTML attribute.
Markdown processors like Kramdown allow you to add an explicit tag to tell the processor to go through HTML blocks and process any Markdown there. I'm assuming you're using the default (which I believe is Redcarpet) and couldn't find the links on whether this is supported. But you can try this:
<div id="someDiv" markdown=1>
[This is a Markdown link that will be parsed](http://www.example.com)
</div>
You are using markdown language here, it won't work in html. You need to use that instead :
Hello World
site.baseurl default is empty
you can change it in _config.yml to suit your needs
for instance :
baseurl: "me/blog"

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 eliminate the empty line in code blocks rendered by jekyll?

GitHub Pages Jekyll use Pygments by default to render syntax highlighting for code blocks. But I prefer an easier alternative highlight.js to do the job because I only need to indent 4 spaces to mark code blocks in the markdown source files.
However, my R code are all mistakenly interpreted as php or perl or makefile or other type of code by highlight.js, and I want to manually mark the code block by
```r
(some r code)
```
instead. But when I use this, the first line of the code block always appears to be a blank line. I view the HTML source code produced by the 4-space mark, it is like
<pre><code>x <- rnorm(100)
y <- 2*x + rnorm(100)
lm(formula=y~x)
</code></pre>
which does not suffer from this problem.
How can I eliminate the blank line in the first line of the code block?
I face the same issue today when I change my highlighter to highlight.js.
With the help from others, I finally git rid of this blank line, and willing to share the solution. Basically, the whitespace inside <pre> is not trimmed, and be treated as a newline in the rendered page (you can use firebug extension of Firefox enabled with show whitespace to observe the extra line).
Then the solution is obvious.
put pre and code tags at the same line with your actual code. like this:
<pre><code class="css">#font-face {
font-family: Chunkfive; src: url('Chunkfive.otf');
}
or using solution provided by mhulse to make your raw post more readable
<pre><code
>line of code
Here and ...
Here
</code></pre>
Write your own js code to trim L/R whitespace(s) of your content before it be put in <pre>
For more details, check this page.

Jekyll automatic table of contents

I have built a website based on the Jekyll code for the website for Apache Buildr. The Buildr website automatically generates a table of contents for each page based on the headers in the textile format files.
For example, you write a page using textile marking out the headings like so . .
h2(#why). Why are we doing this?
BLah blah balh etc ..
h2(#something). Some other header
BLah blah balh etc ..
Then in the default HTML you have some code that pipes the content into something called toc and then you put the contents afterward. For example ...
<div id='content'>
<h1 id='{{ page.title | downcase | replace(' ', '_') }}'>{{ page.title }}</h1>
{{ content | toc }}
{{ content }}
</div>
On the Apache site they get the desired results (the toc is shown followed by the contents). However, on my site, the contents are rendered twice. No table of contents is generated.
Furthermore, if I clone the Apache Buildr project directly from github and run jekyll --server in the doc folder of that project, then no table of contents is generated either.
What am I missing?
I emailed the Buildr developer mailing list and someone told me to look here for inspiration. Turns out that the relevant code snippet is ...
module TocFilter
def toc(input)
output = "<ol class=\"toc\">"
input.scan(/<(h2)(?:>|\s+(.*?)>)([^<]*)<\/\1\s*>/mi).each do |entry|
id = (entry[1][/^id=(['"])(.*)\1$/, 2] rescue nil)
title = entry[2].gsub(/<(\w*).*?>(.*?)<\/\1\s*>/m, '\2').strip
if id
output << %{<li>#{title}</li>}
else
output << %{<li>#{title}</li>}
end
end
output << '</ol>'
output
end
end
Liquid::Template.register_filter(TocFilter)
Make a folder in the source folder of your site called _plugins and then paste this code into a file called TocFilter.rb within that folder.
It works!!
Where is toc defined? It isn't listed as one of the standard liquid filters or jekyll extensions, so likely you are missing a plugin.
I've used ghiculescu's JS TOC on my Jekyll powered Github blog. It works very well.
Example.
jekyll-toc plugin does this for you out of the box.
Add the following to your GemFile
gem 'jekyll-toc'
Add the following to your _config.yml
plugins:
- jekyll-toc
Add the following liquid tag where you want the TOC to be generated.
{{ content | toc_only }}
And finally set toc: true in your post's front-matter.
I added this value as a default in my _config.yml so that TOC is applied to all my posts by default.