├── .clash.yml ├── .gitignore ├── .travis.yml ├── Gemfile ├── History.markdown ├── LICENSE.txt ├── README.md ├── Rakefile ├── jekyll-latex.gemspec ├── lib ├── jekyll-latex.rb ├── jekyll-latex │ ├── filters.rb │ └── version.rb └── jekyll │ └── converters │ └── latex.rb ├── script ├── bootstrap ├── cibuild ├── clash └── test └── spec ├── latex_converter_spec.rb ├── latexify_filter_spec.rb ├── source ├── _config.yml ├── _expected │ ├── 2015 │ │ └── 01 │ │ │ └── 17 │ │ │ └── my-textile-post.html │ └── index.html ├── _posts │ └── 2015-01-17-my-textile-post.textile └── index.html └── spec_helper.rb /.clash.yml: -------------------------------------------------------------------------------- 1 | - 2 | title: Simple build 3 | build: true 4 | - 5 | title: Compare build 6 | compare: _expected _site 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.bundle 11 | *.so 12 | *.o 13 | *.a 14 | mkmf.log 15 | spec/source/_site 16 | log/ 17 | .highlight_cache 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.0 4 | - 2.1 5 | - 2.2 6 | sudo: false 7 | cache: bundler 8 | before_script: bundle update 9 | script: script/cibuild 10 | notifications: 11 | email: false 12 | env: 13 | - JEKYLL_VERSION=tip 14 | - JEKYLL_VERSION=3.0 15 | - JEKYLL_VERSION=2.0 16 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in jekyll-latex.gemspec 4 | gemspec 5 | gem "jekyll", "~> 4" 6 | -------------------------------------------------------------------------------- /History.markdown: -------------------------------------------------------------------------------- 1 | ## 0.1.0 / 2014-01-17 2 | 3 | * First working iteration. 4 | 5 | ## 0.0.1 / 2014-01-17 6 | 7 | * Birthday! 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Parker Moore, 2017 Michael Hartl 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jekyll::Latex 2 | 3 | Use LaTeX with Jekyll. 4 | 5 | Supports all LaTeX syntax supported by [PolyTeXnic](https://github.com/softcover/polytexnic). For Jekyll 3.0 and up. 6 | 7 | ## Installation 8 | 9 | Add this line to your application's Gemfile: 10 | 11 | ```ruby 12 | gem 'jekyll-latex' 13 | ``` 14 | 15 | And then execute: 16 | 17 | ``` 18 | $ bundle 19 | ``` 20 | 21 | Or install it yourself as: 22 | 23 | ``` 24 | $ gem install jekyll-latex 25 | ``` 26 | 27 | Lastly, add it to the plugins section of the `_config.yml` file: 28 | 29 | ``` 30 | plugins: 31 | - jekyll-latex 32 | ``` 33 | 34 | ## Usage 35 | 36 | Create files with the `.tex` extension in the `_posts` directory, as in 37 | 38 | `_posts/2017-07-12-test-post.tex`: 39 | 40 | ``` 41 | --- 42 | layout: post 43 | title: "Welcome to Jekyll 3" 44 | categories: jekyll update 45 | published: true 46 | --- 47 | 48 | This is a \LaTeX\ file. 49 | 50 | \emph{This} is a \LaTeX\ file. 51 | 52 | This \emph{is} a \LaTeX\ file. 53 | ``` 54 | 55 | ### Mathematics 56 | 57 | To get mathematics to render, you should include [MathJax](https://www.mathjax.org) on your site. The simplest configuration looks like this and should be put in the `head` of your page: 58 | 59 | ```html 60 | 61 | 62 | . 63 | . 64 | . 65 | 66 | . 67 | . 68 | . 69 | 72 | 73 | 74 | . 75 | . 76 | . 77 | 78 | 79 | ``` 80 | 81 | MathJax includes many options; here’s one configuration that I like that hides the “processing” message and supports dollar-sign-style math input like `$x$` (note that this means you will have to escape out literal dollar signs with a leading backslash, as in `This costs \$20`): 82 | 83 | ```html 84 | 104 | ``` -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | -------------------------------------------------------------------------------- /jekyll-latex.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'jekyll-latex/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "jekyll-latex" 8 | spec.version = Jekyll::Latex::VERSION 9 | spec.authors = ["Michael Hartl"] 10 | spec.email = ["michael@michaelhartl.com"] 11 | spec.summary = %q{Latex converter for Jekyll.} 12 | spec.homepage = "https://github.com/mhartl/jekyll-latex" 13 | spec.license = "MIT" 14 | 15 | spec.files = `git ls-files -z`.split("\x0") 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.add_runtime_dependency "polytexnic", "~> 1.10" 21 | 22 | spec.add_development_dependency "bundler", "~> 2" 23 | spec.add_development_dependency "rake", "~> 10.0" 24 | spec.add_development_dependency "rspec", "~> 3.0" 25 | spec.add_development_dependency "bigdecimal", "~> 3.2" 26 | spec.add_development_dependency "logger", "~> 1.7" 27 | end 28 | -------------------------------------------------------------------------------- /lib/jekyll-latex.rb: -------------------------------------------------------------------------------- 1 | require 'jekyll' 2 | 3 | root = File.expand_path('jekyll-latex', File.dirname(__FILE__)) 4 | require "#{root}/filters" 5 | require "#{root}/version" 6 | 7 | require File.expand_path('jekyll/converters/latex', File.dirname(__FILE__)) 8 | 9 | module Jekyll 10 | module LatexConverter 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jekyll-latex/filters.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module Filters 3 | # Convert a Latex string into HTML output. 4 | # 5 | # input - The Latex String to convert. 6 | # 7 | # Returns the HTML formatted String. 8 | def latexify(input) 9 | site = @context.registers[:site] 10 | converter = if site.respond_to?(:find_converter_instance) 11 | site.find_converter_instance(Jekyll::Converters::Latex) 12 | else 13 | site.getConverterImpl(Jekyll::Converters::Latex) 14 | end 15 | converter.convert(input) 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/jekyll-latex/version.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module Latex 3 | VERSION = "1.3.1" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/jekyll/converters/latex.rb: -------------------------------------------------------------------------------- 1 | module Jekyll 2 | module Converters 3 | class Latex < Converter 4 | safe true 5 | 6 | DEFAULT_CONFIGURATION = { 7 | 'latex_ext' => 'tex', 8 | } 9 | 10 | def initialize(config = {}) 11 | @config = Jekyll::Utils.deep_merge_hashes(DEFAULT_CONFIGURATION, config) 12 | @setup = false 13 | end 14 | 15 | def setup 16 | return if @setup 17 | require 'polytexnic' 18 | @setup = true 19 | rescue LoadError 20 | STDERR.puts 'You are missing a library required for Latex. Please run:' 21 | STDERR.puts ' $ [sudo] gem install polytexnic' 22 | raise Errors::FatalException.new("Missing dependency: polytexnic") 23 | end 24 | 25 | def extname_list 26 | @extname_list ||= @config['latex_ext'].split(',').map { |e| ".#{e}" } 27 | end 28 | 29 | def matches(ext) 30 | extname_list.include? ext.downcase 31 | end 32 | 33 | def output_ext(ext) 34 | ".html" 35 | end 36 | 37 | def convert(content) 38 | setup 39 | return Polytexnic::Pipeline.new(content, article: true).to_html 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | bundle install -j8 $@ 3 | -------------------------------------------------------------------------------- /script/cibuild: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | script/test $@ && script/clash 3 | -------------------------------------------------------------------------------- /script/clash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | bundle exec clash spec/source 3 | -------------------------------------------------------------------------------- /script/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | bundle exec rspec --color --require spec_helper $@ 3 | -------------------------------------------------------------------------------- /spec/latex_converter_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper' 2 | 3 | RSpec.describe(Jekyll::Converters::Latex) do 4 | let(:converter) { described_class.new } 5 | 6 | context "minimal example" do 7 | it "converts LaTeX to HTML" do 8 | expect(converter.convert("\\emph{yo}").strip).to eq("

yo\n

") 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/latexify_filter_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper' 2 | 3 | RSpec.describe(Jekyll::Filters) do 4 | class JekyllFilter 5 | include Jekyll::Filters 6 | attr_accessor :site, :context 7 | 8 | def initialize(opts = {}) 9 | @site = Jekyll::Site.new(Jekyll::Configuration::DEFAULTS) 10 | @context = Liquid::Context.new({}, {}, { :site => @site }) 11 | end 12 | end 13 | 14 | let(:filter) { JekyllFilter.new } 15 | let(:latex) { "something \\textbf{really} simple" } 16 | let(:html) { "

something really simple\n

" } 17 | 18 | it "should convert latex" do 19 | expect(filter.latexify(latex)).to eq(html) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/source/_config.yml: -------------------------------------------------------------------------------- 1 | gems: 2 | - jekyll-latex 3 | -------------------------------------------------------------------------------- /spec/source/_expected/2015/01/17/my-textile-post.html: -------------------------------------------------------------------------------- 1 |

a post about latex

2 |

line 1
3 | line 2

-------------------------------------------------------------------------------- /spec/source/_expected/index.html: -------------------------------------------------------------------------------- 1 |

Testing the textilize filter

2 | 3 |

this is a paragraph

4 | -------------------------------------------------------------------------------- /spec/source/_posts/2015-01-17-my-textile-post.textile: -------------------------------------------------------------------------------- 1 | --- 2 | title: My latex post 3 | --- 4 | 5 | h2. a post about latex 6 | 7 | p. line 1 8 | line 2 9 | -------------------------------------------------------------------------------- /spec/source/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 |

Testing the textilize filter

5 | 6 | {{ "p. this is a paragraph" | latexify }} 7 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'jekyll' 2 | require File.expand_path('../../lib/jekyll-latex', __FILE__) 3 | 4 | RSpec.configure do |config| 5 | config.expect_with :rspec do |expectations| 6 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 7 | end 8 | 9 | config.mock_with :rspec do |mocks| 10 | mocks.verify_partial_doubles = true 11 | end 12 | 13 | config.filter_run :focus 14 | config.run_all_when_everything_filtered = true 15 | config.disable_monkey_patching! 16 | 17 | config.warnings = false 18 | if config.files_to_run.one? 19 | config.default_formatter = 'doc' 20 | end 21 | 22 | config.profile_examples = 2 23 | config.order = :random 24 | Kernel.srand config.seed 25 | end 26 | --------------------------------------------------------------------------------