Starting From Octopress

This blog is built on Octopress, which is built upon Jekyll.

Octopress is a blog system for coders, and Jekyll a cool static site generater.

Playing with Octopress is not so fun if you want to do some decent changes... And I hate the very nested liquid templates and the complex styles (I think it is over designed, not simple enough ...). But on the other side, I learned many interesting new things.

Compass

One benefit of Octopress over Jekyll is styling with SASS and Compass. There's a folder named "sass", containing a bunch of SCSS files(WTF?) ... I like sass more than scss, SASS is more syntactically concise. To convert SCSS to SASS:

1
sass-convert -f scss -t sass xxx.scss xxx.sass

Mysterious Liquid

Liquid is Jekyll's default and only template engine.

It has benefits like filters -- a pipe-like syntax, and monad-bind-like semantic.

But the endless {% endunless %} is nightmare. (To input Liquid tag is also very tricky ...)

Why not Slim for eyes' sake? Slim can also produce compact output which trims unnecessary spaces between html tags, but stupid Liquid won't.

But Mojombo seems unwillingly to fix it for Jekyll.

Ender's Game

Ender is an npm package, which acts as a browser-side js package manager.

Ender assumes lots of js libraries in different versions want to be loaded. It is reasonable when fanatics of Mootools and YUI are fighting in a room, but not really useful for a ... blog?

In addition, I don't use libraries like underscore because I have coffee-script. Language improvement is better than libraries.

To enable coffee-script, add coffee-script to Gemfile, and put this into plugins folder:

Then replace .js files in source folder with .coffee files. Every coffee file should start with an extra empty yaml leading:

1
2
---
---

For js compressing, Ender uses google closure compiler, which is large and slow. I prefer UglifyJS.

* You see coffee-script processing is a Jekyll plugin. There are many more useful plugins:

https://github.com/mojombo/jekyll/wiki/Plugins

Modernized

Modernizr is a js library for testing CSS3 and HTML5 features, but seems not very useful for a coder who doesn't want to give a shit on IE when not working...

And, jQuery supports some feature-detecting methods and Compass supports cross-browser CSS3. And there are many tools for unobtrusive HTML5 : PIE.htc, html5.js, IE7.js ...

Math Integration

Octopress uses Rdiscount instead of Maruku for Markdown engine. Maruku supports $\LaTeX$ math but Rdiscount doesn't. Octopress claims itself a blog for hackers, but what hacker doesn't use $\LaTeX$ math?

Since that rdiscount's backslash is breaking tex control instructions, I forked it for preserving formulas wrapped in '$' from markdown processing. To apply this change, modify Gemfile :

1
gem 'rdiscount', :git => "git://github.com/luikore/rdiscount"

And add an preserve_math option in _config.yml (the autolink option also saves some typing):

1
2
rdiscount:
extensions: [autolink, preserve_math]

In case you don't know what extension you can use, do take a look at rdiscount.rb.

Once well-defined $\LaTeX$ code is wrapped in '$'s, we can enable MathJax with the following code. Add them to default.html or somewhere else :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- mathjax config similar to math.stackexchange -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [ ['$', '$'] ],
displayMath: [ ['$$', '$$']],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
},
messageStyle: "none",
"HTML-CSS": { preferredFont: "TeX", availableFonts: ["STIX","TeX"] }
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" type="text/javascript"></script>

Note that displayMath may mess disqus comments, you can wrap the disqus footer with <div class="tex2jax_ignore">.

The remaining problem is when I right-click on a formula for MathJax context menu, the whole browser becomes white. It is an issue of both MathJax and Octopress, and it took me a whole night to find out why...

The fix is short, just look for this section in _theme.sass or _theme.scss and add #main:

1
2
3
4
5
6
7
8
body
- > div
+ > div#main
background: $sidebar-bg
border-bottom: 1px solid $page-border-bottom
> div
background: $main-bg
border-right: 1px solid $sidebar-border

Let's do some practice: Maxwell's Equations

$$ \begin{aligned} \nabla \cdot \mathbf{E} & = \frac{\rho}{\epsilon_0} \\ \nabla \cdot \mathbf{B} & = 0 \\ \nabla \times \mathbf{E} & = -\frac{\partial \mathbf{B}}{\partial t} \\ \nabla \times \mathbf{B} & = \mu_0\mathbf{J} + \mu_0\epsilon_0\frac{\partial\mathbf{E}}{\partial t} \end{aligned} $$

TextMate Editing

The markdown is quite different from the standard now. If you wish to make TextMate highlight this more precisely, you should take a look at the manual first.

For back tick code blocks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{ scopeName = 'text.html.markdown';
fileTypes = ( 'mdown', 'markdown', 'markdn', 'md' );
foldingStartMarker = '(?x)
(<(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)\b.*?>
|<!--(?!.*-->)
|\{\s*($|\?>\s*$|//|/\*(.*\*/\s*$|(?!.*?\*/)))
)';
foldingStopMarker = '(?x)
(</(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)>
|^\s*-->
|(^|\s)\}
)';
patterns = (
+ { name = 'markup.raw.block.markdown';
+ begin = '\`\`\`\s*\w+';
+ end = '\`\`\`';
+ },

For latex highlite, find the inline = part in repository, and add a regexp for '$' wrapped math:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+ math = {
+ name = 'entity';
+ match = '(?!\\)\$.+?\$';
+ },
inline = {
patterns = (
{ include = '#escape'; },
{ include = '#ampersand'; },
{ include = '#bracket'; },
{ include = '#raw'; },
+ { include = '#math'; },
{ include = '#bold'; },
{ include = '#italic'; },
{ include = '#line-break'; },
{ include = '#image-inline'; },
{ include = '#link-inline'; },
{ include = '#link-inet'; },
{ include = '#link-email'; },
{ include = '#image-ref'; },
{ include = '#link-ref-literal'; },
{ include = '#link-ref'; },
);
};

Tag Filter on Sidebar

Here's the simple implementation in coffee:

1
2
3
4
5
6
7
8
9
$('input.filter').keyup (e)->
val = $(@).val()
if (/^\s*$/.test(val) || e.keyCode == 27)
$('#tags li').show()
$(@).val('')
return
pattern = new RegExp(val, 'i')
$('#tags li').each ->
$(@)[if pattern.test($(@).find('a').text()) then 'show' else 'hide']()

Minor Issues

There are many more little problems, all easy to be dealt with:

  • Tab Order

    When pressing TAB on page, the I-beam gets into the Diquss textarea instead of the sidebar search. The fix is easy. Just add tabindex=1 and tabindex=2 on the sidebar inputs.

  • Smart Quotes

    Rubypants is the ruby version of smartypants. It converts all single-quotes and double-quotes to pair quotes.

    To disable it, just remove the smart_quote filter from default.html and make sure smart option disabled in rdiscount's extensions.

  • Double Height Diff Code Lines

    When the code block is diff, the '+' and '-' lines can become too high. Find these in _syntax.sass and remove them :

1
2
3
- div
- .gd, .gd .x, .gi, .gi .x
- display: block

Notes

  • Underscores in Markdown

    Use \_ when I don't mean to be italic.

  • Tex without Default Italic

1
$\rm \LaTeX$
  • Mathjax doesn't support non-italic lower-case greek letters, it uses italic for all cases.

Comments