Enabling drafting in Org Mode in Minimal Mistakes
From now on I will be able to write posts in Org Mode for this blog, besides the existing Markdown method. Here’s how I configure it. This article is written in an Org file and also serves as a demonstration of this new feature.
First, you can do everything in the original Markdown way, which is kept intact. Now you can write everything in Org Mode with the extra benefit of using front matter, Liquid syntax, figures, galleries, etc. exactly the same as in Markdown.
Here are the basic elements demonstrated:
Org Elements Examples
Tables
Here is the morphological breakdown:
| Component | Origin | Meaning |
|---|---|---|
| Erythro- | Greek (erythros) | Red |
| -xyl- | Greek (xylon) | Wood |
| -aceae | Latin (Suffix) | Belonging to the family of |
Lists
A multi-level list of mixed types:
- First item
- Second item
- Sub-item A (Indented 3 spaces)
Some text
- Sub-item A (Indented 3 spaces)
- Sub-item A (Indented 3 spaces)
- Sub-item A (Indented 3 spaces)
- Sub-item A (Indented 3 spaces)
- Sub-item A (Indented 3 spaces)
- Sub-item B
- Deeply nested bullet (Indented another 3 spaces)
- Deeply nested bullet (Indented another 3 spaces)
- Sub-item A (Indented 3 spaces)
- Third item
Images
A simple image:

A figure:

A gallery (with customization):
Code highlighting
Inline codes: print, hello
Using : to start a line of code:
descriptor + subject + taxonomic rank
Using structure template (code block):
def print_hi(name)
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.Configurations
Here’s how I did the configurations.
- Add
org-rubyto yourGemfile:group :jekyll_plugins do ... gem "org-ruby" end - Write a new plugin:
_plugins/org_converter.rbrequire 'nokogiri' require 'rouge' Jekyll::Hooks.register [:pages, :documents], :pre_render do |doc| # Enable Liquid syntax if doc.extname.downcase == '.org' # Enable {% raw %}...{% endraw %} doc.content = doc.content.gsub(/^[ \t]*(\{%[ \t]*raw[ \t]*%\})[ \t]*\n?/, '\1') doc.content = doc.content.gsub(/^[ \t]*(\{%[ \t]*endraw[ \t]*%\})[ \t]*\n?/, '\1') # Enable figures, galleries, and links to posts doc.content = doc.content.gsub(/^[ \t]*(\{%[ \t]*include[ \t]+(?:figure|gallery)(?:(?!%\}).|\{%.*?%\})*%\})[ \t]*$/m) do |match| "\n#+BEGIN_HTML\n#{$1}\n#+END_HTML\n" end block_regex = /(?mi:^[ \t]*#\+(?:begin_src|BEGIN_HTML).*?^[ \t]*#\+(?:end_src|END_HTML))/ inline_code = /[=~][^=~\n]+[=~]/ markdown_link = /(?<!\!)\[([^\]]+)\]\(([^)]+)\)/ doc.content = doc.content.gsub(/#{block_regex}|^[ \t]*:[^\n]*$|#{inline_code}|#{markdown_link}/) do |match| match.start_with?('[') && !match.start_with?('[[') ? "[[#{$2}][#{$1}]]" : match end end end module Jekyll class OrgConverter < Converter safe true priority :low def matches(ext) ext =~ /^\.org$/i end def output_ext(ext) ".html" end def convert(content) require 'org-ruby' html = Orgmode::Parser.new(content).to_html doc = Nokogiri::HTML.fragment(html) doc.css('h1, h2, h3, h4, h5, h6').each do |node| node['id'] = node.text.downcase.strip.gsub(/[^a-z0-9\s-]/, '').gsub(/\s+/, '-') end # Add <thead> to tables doc.css('table').each do |table| trs = table.xpath('./tr') next if trs.empty? if trs.first.at_xpath('./th') thead = Nokogiri::XML::Node.new('thead', doc) thead.add_child(trs.first) tbody = Nokogiri::XML::Node.new('tbody', doc) trs[1..-1].each { |tr| tbody.add_child(tr) } table.add_child(thead) table.add_child(tbody) else tbody = Nokogiri::XML::Node.new('tbody', doc) trs.each { |tr| tbody.add_child(tr) } table.add_child(tbody) end end # Process code blocks to enable code highlighting doc.css('pre.src[lang]').each do |pre| lang = pre['lang'] lexer = Rouge::Lexer.find_fancy(lang) || Rouge::Lexers::PlainText formatter = Rouge::Formatters::HTML.new # .sub(/\A[\r\n]+/, '') targets the absolute beginning of the string # (\A) and removes any leading line breaks or carriage returns. # .sub(/\s+\z/, '') targets the absolute end of the string (\z) and # removes any trailing whitespace, including empty lines and spaces. code_text = pre.text.sub(/\A[\r\n]+/, '').sub(/\s+\z/, '') highlighted = formatter.format(lexer.lex(code_text)) new_node = Nokogiri::HTML.fragment(%Q{ <div class="language-#{lang} highlighter-rouge"> <div class="highlight"><pre class="highlight"><code>#{highlighted}</code></pre></div> </div> }) pre.replace(new_node) end doc.to_html end end end - Install the gems with bundler and run:
bundle install bundle exec jekyll serve
Comments