├── .gitignore ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .travis.yml ├── Gemfile ├── History.markdown ├── LICENSE.txt ├── README.md ├── Rakefile ├── jekyll-gist.gemspec ├── lib ├── jekyll-gist.rb └── jekyll-gist │ ├── gist_tag.rb │ └── version.rb ├── script ├── bootstrap ├── cibuild ├── fmt └── release └── spec ├── fixtures ├── multiple-files.json └── single-file.json ├── gist_tag_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | *.bundle 19 | *.so 20 | *.o 21 | *.a 22 | mkmf.log 23 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format progress 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | 3 | require: rubocop-jekyll 4 | inherit_gem: 5 | rubocop-jekyll: .rubocop.yml 6 | 7 | AllCops: 8 | TargetRubyVersion: 2.3 9 | Exclude: 10 | - vendor/**/* 11 | - spec/*.rb 12 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2019-07-16 18:09:04 +0200 using RuboCop version 0.71.0. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 1 10 | Lint/ShadowedException: 11 | Exclude: 12 | - 'lib/jekyll-gist/gist_tag.rb' 13 | 14 | # Offense count: 1 15 | Metrics/AbcSize: 16 | Max: 24 17 | 18 | # Offense count: 1 19 | # Configuration parameters: CountComments, ExcludedMethods. 20 | Metrics/MethodLength: 21 | Max: 21 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | cache: bundler 3 | rvm: 4 | - &latest_ruby 2.7 5 | - 2.5 6 | 7 | script : script/cibuild 8 | 9 | branches: 10 | only: 11 | - master 12 | env: 13 | matrix: 14 | - JEKYLL_VERSION="~> 3.8" 15 | matrix: 16 | include: 17 | - # GitHub Pages 18 | rvm: 2.5.3 19 | env: JEKYLL_VERSION="~> 3.8.5" 20 | - rvm: *latest_ruby 21 | env: JEKYLL_VERSION="~> 4.0" 22 | 23 | notifications: 24 | email: false 25 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | gemspec 5 | 6 | gem "jekyll", ENV["JEKYLL_VERSION"] if ENV["JEKYLL_VERSION"] 7 | -------------------------------------------------------------------------------- /History.markdown: -------------------------------------------------------------------------------- 1 | ## HEAD 2 | 3 | ### Development Fixes 4 | 5 | * Test against Ruby 2.5 (#57) 6 | * Rely on rubocop-jekyll (#62) 7 | * chore(deps): rubocop-jekyll 0.3 (#64) 8 | * Refactor GistTag (#65) 9 | 10 | ### Major Enhancements 11 | 12 | * chore(deps): drop support for Liquid < 4.0 (#66) 13 | 14 | ### Bug Fixes 15 | 16 | * Re-introduce Ruby 2.3 support and test Jekyll 3.7+ (#72) 17 | * Use Liquid::Tag#raw to clarify error message (#73) 18 | 19 | ## 1.5.0 / 2017-12-03 20 | 21 | ### Documentation 22 | 23 | * replace 'plugins' key in config with 'gems' (#46) 24 | * Docs: Remove username in gist (#54) 25 | 26 | ### Development Fixes 27 | 28 | * Remove testing for Jekyll 2.x 29 | * Requires Ruby > 2.1 30 | * Add release script 31 | * Inherit Jekyll's rubocop config for consistency (#48) 32 | * define path with __dir__ (#47) 33 | 34 | ## 1.4.1 / 2017-06-21 35 | 36 | * Don't ask .empty? until it's a String. (#38) 37 | * rename Liquid 4 `has_key?` to `key?` to add compatibility for liquid 4 (#41) 38 | * Test against Ruby 2.1 to 2.4 (#45) 39 | 40 | ## 1.4.0 / 2015-12-01 41 | 42 | * Allow `noscript` fallback to be disabled (#29) 43 | * Use Octokit to fetch Gist content when passed `JEKYLL_GITHUB_TOKEN` in env(#28) 44 | 45 | ## 1.3.5 / 2015-10-23 46 | 47 | * Fix encoding error for `noscript` code (#23) 48 | * Test against Jekyll 3, 2, and the github-pages gem (#19) 49 | 50 | ## 1.3.4 / 2015-08-28 51 | 52 | * Catch `TimeoutError` to further support 1.9.3 (#16) 53 | 54 | ## 1.3.3 / 2015-08-20 55 | 56 | * Fix gemspec to allow Ruby 1.9.3 (relates to #14) 57 | 58 | ## 1.3.2 / 2016-08-19 59 | 60 | * Re-add support for Ruby 1.9.3. Fixes #11 for 1.9.3 (#14) 61 | * Replaced `OpenURI` with `Net::HTTP` and introduced timeout of 3 seconds (#11) 62 | 63 | ## 1.3.1 / 2015-08-16 64 | 65 | * Replaced `OpenURI` with `Net::HTTP` and introduced timeout of 3 seconds (#11) 66 | 67 | ## 1.3.0 / 2015-08-05 68 | 69 | * Added an `noscript` fallback for browsers without JavaScript enabled. (#7) 70 | 71 | ## 1.2.1 / 2015-03-22 72 | 73 | * Use `has_key?` (#6) 74 | 75 | ## 1.2.0 / 2015-03-21 76 | 77 | ### Minor Enhancements 78 | 79 | * Allow variables as parameters (#4) 80 | 81 | ### Development Fixes 82 | 83 | * Fix RSpec deprecation warning (#5) 84 | 85 | ## 1.1.0 / 2014-06-18 86 | 87 | ### Minor Enhancements 88 | 89 | * Update regex to allow for new sha-ish ids in Gist. (#1) 90 | 91 | ## 1.0.0 / 2014-06-01 92 | 93 | * Birthday! 94 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-present Parker Moore and jekyll-gist contributors 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::Gist 2 | 3 | Liquid tag for displaying GitHub Gists in Jekyll sites: `{% gist %}`. 4 | 5 | [![Build Status](https://travis-ci.org/jekyll/jekyll-gist.svg?branch=master)](https://travis-ci.org/jekyll/jekyll-gist) 6 | 7 | ## Installation 8 | 9 | Add this line to your application's Gemfile: 10 | 11 | $ gem 'jekyll-gist' 12 | 13 | And then execute: 14 | 15 | $ bundle 16 | 17 | Or install it yourself as: 18 | 19 | $ gem install jekyll-gist 20 | 21 | Then add the following to your site's `_config.yml`: 22 | 23 | ``` 24 | plugins: 25 | - jekyll-gist 26 | ``` 27 | 28 | 💡 If you are using a Jekyll version less than 3.5.0, use the `gems` key instead of `plugins`. 29 | 30 | ## Usage 31 | 32 | Use the tag as follows in your Jekyll pages, posts and collections: 33 | 34 | ```liquid 35 | {% gist c08ee0f2726fd0e3909d %} 36 | ``` 37 | 38 | This will create the associated script tag: 39 | 40 | ```html 41 | 42 | ``` 43 | 44 | You may optionally specify a `filename` after the `gist_id`: 45 | 46 | ```liquid 47 | {% gist c08ee0f2726fd0e3909d test.md %} 48 | ``` 49 | 50 | This will produce the correct URL to show just the specified file in your post rather than the entire Gist. 51 | 52 | **Pro-tip**: If you provide a personal access token with Gist scope, as the environmental variable `JEKYLL_GITHUB_TOKEN`, Jekyll Gist will use the Gist API to speed up site generation. 53 | 54 | ## Disabling `noscript` support 55 | 56 | By default, Jekyll Gist will make an HTTP call per Gist to retrieve the raw content of the Gist. This information is used to propagate `noscript` tags for search engines and browsers without JavaScript support. If you'd like to disable this feature, for example, to speed up builds locally, add the following to your site's `_config.yml`: 57 | 58 | ```yml 59 | gist: 60 | noscript: false 61 | ``` 62 | 63 | ## Contributing 64 | 65 | 1. Fork it ( https://github.com/jekyll/jekyll-gist/fork ) 66 | 2. Create your feature branch (`git checkout -b my-new-feature`) 67 | 3. Commit your changes (`git commit -am 'Add some feature'`) 68 | 4. Push to the branch (`git push origin my-new-feature`) 69 | 5. Create a new Pull Request 70 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | -------------------------------------------------------------------------------- /jekyll-gist.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/jekyll-gist/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "jekyll-gist" 7 | spec.version = Jekyll::Gist::VERSION 8 | spec.authors = ["Parker Moore"] 9 | spec.email = ["parkrmoore@gmail.com"] 10 | spec.summary = "Liquid tag for displaying GitHub Gists in Jekyll sites." 11 | spec.homepage = "https://github.com/jekyll/jekyll-gist" 12 | spec.license = "MIT" 13 | 14 | spec.files = `git ls-files -z`.split("\x0") 15 | spec.test_files = spec.files.grep(%r!^spec/!) 16 | spec.require_paths = ["lib"] 17 | 18 | spec.required_ruby_version = ">= 2.3.0" 19 | 20 | spec.add_runtime_dependency "jekyll", ">= 3.7", "< 5.0" 21 | spec.add_runtime_dependency "octokit", "~> 4.2" 22 | 23 | spec.add_development_dependency "bundler" 24 | spec.add_development_dependency "rake" 25 | spec.add_development_dependency "rspec" 26 | spec.add_development_dependency "rubocop-jekyll", "~> 0.4" 27 | spec.add_development_dependency "webmock" 28 | end 29 | -------------------------------------------------------------------------------- /lib/jekyll-gist.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "jekyll-gist/version" 4 | require "jekyll-gist/gist_tag" 5 | 6 | module Jekyll 7 | module Gist 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jekyll-gist/gist_tag.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cgi" 4 | require "net/http" 5 | require "octokit" 6 | 7 | Net::OpenTimeout = Class.new(RuntimeError) unless Net.const_defined?(:OpenTimeout) 8 | Net::ReadTimeout = Class.new(RuntimeError) unless Net.const_defined?(:ReadTimeout) 9 | 10 | module Jekyll 11 | module Gist 12 | class GistTag < Liquid::Tag 13 | def self.client 14 | @client ||= Octokit::Client.new :access_token => ENV["JEKYLL_GITHUB_TOKEN"] 15 | end 16 | 17 | def render(context) 18 | @encoding = context.registers[:site].config["encoding"] || "utf-8" 19 | @settings = context.registers[:site].config["gist"] 20 | if (tag_contents = determine_arguments(@markup.strip)) 21 | gist_id = tag_contents[0] 22 | filename = tag_contents[1] 23 | gist_id = context[gist_id] if context.key?(gist_id) 24 | filename = context[filename] if context.key?(filename) 25 | 26 | noscript_tag = gist_noscript_tag(gist_id, filename) 27 | script_tag = gist_script_tag(gist_id, filename) 28 | 29 | "#{noscript_tag}#{script_tag}" 30 | else 31 | raise ArgumentError, <<~ERROR 32 | Syntax error in tag 'gist' while parsing the following markup: 33 | 34 | '{% #{raw.strip} %}' 35 | 36 | Valid syntax: 37 | {% gist user/1234567 %} 38 | {% gist user/1234567 foo.js %} 39 | {% gist 28949e1d5ee2273f9fd3 %} 40 | {% gist 28949e1d5ee2273f9fd3 best.md %} 41 | 42 | ERROR 43 | end 44 | end 45 | 46 | private 47 | 48 | def determine_arguments(input) 49 | matched = input.match(%r!\A([\S]+|.*(?=\/).+)\s?(\S*)\Z!) 50 | [matched[1].strip, matched[2].strip] if matched && matched.length >= 3 51 | end 52 | 53 | def gist_script_tag(gist_id, filename = nil) 54 | url = "https://gist.github.com/#{gist_id}.js" 55 | url = "#{url}?file=#{filename}" unless filename.to_s.empty? 56 | 57 | "" 58 | end 59 | 60 | def gist_noscript_tag(gist_id, filename = nil) 61 | return if @settings && @settings["noscript"] == false 62 | 63 | code = fetch_raw_code(gist_id, filename) 64 | if code 65 | code = code.force_encoding(@encoding) 66 | code = CGI.escapeHTML(code).gsub("'", "'") 67 | 68 | "" 69 | else 70 | Jekyll.logger.warn "Warning:", "The