Skip to content

Instantly share code, notes, and snippets.

@stevecheckoway
Last active October 24, 2018 21:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevecheckoway/aa110671b8af5a090a5f38d1af6fd0a2 to your computer and use it in GitHub Desktop.
Save stevecheckoway/aa110671b8af5a090a5f38d1af6fd0a2 to your computer and use it in GitHub Desktop.
Simple Jekyll plugin to 1. parse `$…$` or `\(…\)` as inline math; 2. parse `$$…$$` as display math both inside and outside paragraphs.
# This is a (more) sane math parsing scheme.
require 'kramdown/parser/kramdown'
require 'kramdown/parser/kramdown/block_boundary'
module Kramdown
module Parser
class Skramdown < Kramdown::Parser::GFM
def initialize(source, options)
super
idx = @span_parsers.index(:inline_math)
@span_parsers[idx] = :sane_inline_math
@span_parsers.insert(idx, :sane_display_math)
end
# (?<!\\|\$) Isn't preceded by a backslash or a dollar sign
# \$ Dollar sign
# (?!\$) Isn't followed by a dollar sign
# (.*?) Nongreedy match
# (?<!\\|\$) Isn't preceded by a backslash or a dollar sign
# \$ Dollar sign
# (?!\$) Isn't followed by a dollar sign
# | Or
# (?<!\\) Not a backslash
# \\\( Backslash, open parenthesis
# (.*?) Nongreedy match
# (?<!\\) Isn't preceded by a backslash
# \\\) Backslash, close parenthesis
SANE_INLINE_MATH_START = /(?<!\\|\$)\$(?!\$)(.*?)(?<!\\|\$)\$(?!\$)|(?<!\\)\\\((.*?)(?<!\\)\\\)/m
def parse_sane_inline_math
start_line_number = @src.current_line_number
@src.pos += @src.matched_size
data = (@src[1] || @src[2]).strip
@tree.children << Element.new(:math, data, nil, :category => :span, :location => start_line_number)
end
define_parser(:sane_inline_math, SANE_INLINE_MATH_START, '\\$|\\\\\\(')
SANE_DISPLAY_MATH_START = /(?<!\\)\$\$(.*?)\$\$/m
def parse_sane_display_math
start_line_number = @src.current_line_number
@src.pos += @src.matched_size
data = (@src[1] || @src[2]).strip
@tree.children << Element.new(:math, data, nil, :category => :block, :location => start_line_number)
end
define_parser(:sane_display_math, SANE_DISPLAY_MATH_START, '\\$\\$')
end
end
end
# vim: set sw=2 sts=2 ts=8 et:
@stevecheckoway
Copy link
Author

Files:

  • skramdown.rb goes in _plugins.
  • katex.min.js from KaTeX goes anywhere you want, I put it in a katex directory.

In my site's Gemfile, I have

gem 'sskatex'

In my site's _config.yml, I have

plugins:
  - 'sskatex'

exclude:
  - katex

markdown: kramdown

kramdown:
  math_engine: sskatex
  math_engine_opts:
    katex_js: 'katex/katex.min.js'
  input: Skramdown

In my _layouts/default.html, I have

  {% if page.katex %}
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css" integrity="sha384-TEMocfGvRuD1rIAacqrknm5BQZ7W7uWitoih+jMNFXQIbNl16bO8OZmylH/Vi/Ei" crossorigin="anonymous">
  {% endif %}

To include the KaTeX CSS file in a page, I set

katex: true

in the page's front matter.

After this is done, I noticed that the font size is too large and that display math inside paragraphs was respecting the paragraph's text-indent. These are easily fixed with the CSS (actually SASS)

/**
 * Math content
 */
.katex {
    font-size: $base-font-size !important;
}

.katex-display {
    text-indent: 0px;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment