mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fe3a5d59b | ||
|
|
331361aee6 | ||
|
|
8681d67d76 | ||
|
|
917c7b13ad | ||
|
|
a6e21936a5 | ||
|
|
f98b2492fc | ||
|
|
071913e350 | ||
|
|
82fc6ba01c | ||
|
|
0ac94d7766 | ||
|
|
5a2f8d7279 | ||
|
|
382002ae42 | ||
|
|
5b90cecbc9 | ||
|
|
9bfd37570b | ||
|
|
cbde121dc4 | ||
|
|
5db0b067be | ||
|
|
ae1d7c5aa2 | ||
|
|
687785a00d | ||
|
|
ac7b264112 | ||
|
|
7683292976 | ||
|
|
24515914b4 | ||
|
|
d276dc2698 | ||
|
|
262d950b27 | ||
|
|
2ca200bc2d | ||
|
|
56862cac6c | ||
|
|
82128692f5 | ||
|
|
fbc79f6605 | ||
|
|
e894f830fa | ||
|
|
51a65754bf | ||
|
|
ce68268aaa | ||
|
|
9e4b4f2bd1 | ||
|
|
7ff9a885b8 | ||
|
|
5c4e125dad | ||
|
|
cc5c850a03 | ||
|
|
72d853779f | ||
|
|
c945c48b79 | ||
|
|
27e1433ee0 | ||
|
|
9c574f779f | ||
|
|
47b67f1222 | ||
|
|
b8d5a04b57 | ||
|
|
8701fdbc29 | ||
|
|
f29c72e0b9 | ||
|
|
fbeadab63f | ||
|
|
3c06609406 | ||
|
|
f3b6877a39 | ||
|
|
c2dff2cd15 | ||
|
|
cb11099394 | ||
|
|
17efa2a485 | ||
|
|
02133f4e1f | ||
|
|
77208fac2c | ||
|
|
f157093ab3 | ||
|
|
a395dfe27c | ||
|
|
889af57f03 | ||
|
|
b5772dc787 | ||
|
|
21d8def9ed | ||
|
|
f15804423e | ||
|
|
511ea72d05 | ||
|
|
41c82448ae | ||
|
|
ee35322193 | ||
|
|
a7e8f08bea | ||
|
|
a4171db345 | ||
|
|
aedb403afd | ||
|
|
924ca62bd2 | ||
|
|
cc52cac81a | ||
|
|
91abe9f741 | ||
|
|
d9a2758ff6 |
@@ -53,6 +53,8 @@ Layout/EmptyComment:
|
||||
Enabled: false
|
||||
Layout/EndAlignment:
|
||||
Severity: error
|
||||
Lint/SplatKeywordArguments:
|
||||
Enabled: false
|
||||
Lint/UnreachableCode:
|
||||
Severity: error
|
||||
Lint/UselessAccessModifier:
|
||||
|
||||
21
.travis.yml
21
.travis.yml
@@ -1,15 +1,13 @@
|
||||
bundler_args: --without benchmark:site:development
|
||||
bundler_args: --without benchmark:development
|
||||
script: script/cibuild
|
||||
cache: bundler
|
||||
language: ruby
|
||||
sudo: false
|
||||
|
||||
rvm:
|
||||
- &ruby1 2.5.1
|
||||
- &ruby2 2.4.4
|
||||
- &ruby3 2.3.7
|
||||
- &ruby4 2.2.10
|
||||
- &jruby jruby-9.1.16.0
|
||||
- &ruby1 2.7.1
|
||||
- &ruby2 2.6.6
|
||||
- &ruby3 2.5.8
|
||||
- &jruby jruby-9.2.11.1
|
||||
|
||||
matrix:
|
||||
include:
|
||||
@@ -17,8 +15,12 @@ matrix:
|
||||
env: TEST_SUITE=fmt
|
||||
- rvm: *ruby1
|
||||
env: TEST_SUITE=default-site
|
||||
- rvm: *ruby1
|
||||
env: TEST_SUITE=profile-docs
|
||||
- rvm: *ruby1
|
||||
env: ROUGE_VERSION=1.11.1 # runs everything with this version
|
||||
- rvm: *ruby1
|
||||
env: KRAMDOWN_VERSION=1.17.0 # runs everything with this version
|
||||
exclude:
|
||||
- rvm: *jruby
|
||||
env: TEST_SUITE=cucumber
|
||||
@@ -31,7 +33,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- themes
|
||||
- /*-stable/
|
||||
- /.*-stable/
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
@@ -54,5 +56,4 @@ after_success:
|
||||
- bundle exec codeclimate-test-reporter
|
||||
|
||||
before_install:
|
||||
- gem update --system
|
||||
- gem install bundler
|
||||
- gem update --system || true
|
||||
|
||||
17
Gemfile
17
Gemfile
@@ -27,15 +27,17 @@ group :test do
|
||||
gem "httpclient"
|
||||
gem "jekyll_test_plugin"
|
||||
gem "jekyll_test_plugin_malicious"
|
||||
# nokogiri v1.8 does not work with ruby 2.1 and below
|
||||
gem "nokogiri", RUBY_VERSION >= "2.2" ? "~> 1.7" : "~> 1.7.0"
|
||||
# nokogiri v1.10 does not work with ruby 2.2 and below
|
||||
gem "nokogiri", RUBY_VERSION >= "2.3" ? "~> 1.9" : "~> 1.9.0"
|
||||
gem "rspec"
|
||||
gem "rspec-mocks"
|
||||
gem "rubocop", "~> 0.56.0"
|
||||
gem "test-dependency-theme", :path => File.expand_path("test/fixtures/test-dependency-theme", __dir__)
|
||||
gem "test-theme", :path => File.expand_path("test/fixtures/test-theme", __dir__)
|
||||
gem "test-theme-skinny", :path => File.expand_path("test/fixtures/test-theme-skinny", __dir__)
|
||||
gem "test-theme-symlink", :path => File.expand_path("test/fixtures/test-theme-symlink", __dir__)
|
||||
|
||||
gem "jruby-openssl" if RUBY_ENGINE == "jruby"
|
||||
gem "jruby-openssl", "0.10.1" if RUBY_ENGINE == "jruby"
|
||||
end
|
||||
|
||||
#
|
||||
@@ -66,18 +68,23 @@ end
|
||||
#
|
||||
|
||||
group :jekyll_optional_dependencies do
|
||||
gem "coderay", "~> 1.1.0"
|
||||
gem "jekyll-coffeescript"
|
||||
gem "jekyll-docs", :path => "../docs" if Dir.exist?("../docs") && ENV["JEKYLL_VERSION"]
|
||||
gem "jekyll-feed", "~> 0.9"
|
||||
gem "jekyll-gist"
|
||||
gem "jekyll-paginate"
|
||||
gem "jekyll-redirect-from"
|
||||
gem "kramdown", "~> 1.14"
|
||||
gem "mime-types", "~> 3.0"
|
||||
gem "rdoc", RUBY_VERSION >= "2.2.2" ? "~> 6.0" : "~> 5.1"
|
||||
gem "tomlrb", "~> 1.2"
|
||||
|
||||
if ENV["KRAMDOWN_VERSION"].nil? || ENV["KRAMDOWN_VERSION"].to_i >= 2
|
||||
gem "kramdown-syntax-coderay"
|
||||
gem "kramdown-parser-gfm"
|
||||
else
|
||||
gem "coderay", "~> 1.0"
|
||||
end
|
||||
|
||||
platform :ruby, :mswin, :mingw, :x64_mingw do
|
||||
gem "classifier-reborn", "~> 2.2.0"
|
||||
gem "liquid-c", "~> 3.0"
|
||||
|
||||
@@ -1,3 +1,44 @@
|
||||
### HEAD
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Allow use of kramdown v2 (#8322)
|
||||
* Add default language for kramdown syntax highlighting (#8325)
|
||||
|
||||
## 3.8.7 / 2020-05-08
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Prevent console warnings with Ruby 2.7 (#8125)
|
||||
|
||||
## 3.8.6 / 2019-07-02
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update log output for an invalid theme directory (#7734)
|
||||
* Memoize `SiteDrop#documents` to reduce allocations (#7722)
|
||||
* Excerpt handling of custom and intermediate tags (#7467)
|
||||
* Escape valid special chars in a site's path name (#7573)
|
||||
* Revert memoizing `Site#docs_to_write` and refactor `#documents` (#7689)
|
||||
* Fix broken `include_relative` usage in excerpt (#7690)
|
||||
* Install platform-specific gems as required (3c06609406)
|
||||
|
||||
### Security Fixes
|
||||
|
||||
* Theme gems: ensure directories aren't symlinks (#7424)
|
||||
|
||||
## 3.8.5 / 2018-11-04
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Re-implement handling Liquid blocks in excerpts (#7250)
|
||||
|
||||
## 3.8.4 / 2018-09-18
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* security: fix `include` bypass of `EntryFilter#filter` symlink check (#7228)
|
||||
|
||||
## 3.8.3 / 2018-06-05
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
19
appveyor.yml
19
appveyor.yml
@@ -6,30 +6,31 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- themes
|
||||
- /.*-stable/
|
||||
|
||||
build: off
|
||||
|
||||
install:
|
||||
- SET PATH=C:\Ruby%RUBY_FOLDER_VER%\bin;%PATH%
|
||||
- SET PATH=C:\Ruby%RUBY_FOLDER_VER%-x64\bin;%PATH%
|
||||
- bundle install --retry 5 --jobs=%NUMBER_OF_PROCESSORS% --clean --path vendor\bundle
|
||||
|
||||
environment:
|
||||
BUNDLE_WITHOUT: "benchmark:site:development"
|
||||
BUNDLE_WITHOUT: "benchmark:development"
|
||||
matrix:
|
||||
- RUBY_FOLDER_VER: "25"
|
||||
- RUBY_FOLDER_VER: "26"
|
||||
TEST_SUITE: "test"
|
||||
- RUBY_FOLDER_VER: "25"
|
||||
TEST_SUITE: "cucumber"
|
||||
- RUBY_FOLDER_VER: "25"
|
||||
TEST_SUITE: "default-site"
|
||||
- RUBY_FOLDER_VER: "25-x64"
|
||||
TEST_SUITE: "test"
|
||||
- RUBY_FOLDER_VER: "24"
|
||||
TEST_SUITE: "test"
|
||||
- RUBY_FOLDER_VER: "23"
|
||||
TEST_SUITE: "test"
|
||||
- RUBY_FOLDER_VER: "22"
|
||||
TEST_SUITE: "test"
|
||||
- RUBY_FOLDER_VER: "26"
|
||||
TEST_SUITE: "default-site"
|
||||
- RUBY_FOLDER_VER: "26"
|
||||
TEST_SUITE: "profile-docs"
|
||||
- RUBY_FOLDER_VER: "26"
|
||||
TEST_SUITE: "cucumber"
|
||||
|
||||
test_script:
|
||||
- ruby --version
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
version: 3.8.3
|
||||
version: 3.9.0
|
||||
name: Jekyll • Simple, blog-aware, static sites
|
||||
description: Transform your plain text into static websites and blogs
|
||||
url: https://jekyllrb.com
|
||||
|
||||
@@ -4,6 +4,53 @@ permalink: "/docs/history/"
|
||||
note: This file is autogenerated. Edit /History.markdown instead.
|
||||
---
|
||||
|
||||
## 3.8.7 / 2020-05-08
|
||||
{: #v3-8-7}
|
||||
|
||||
### Bug Fixes
|
||||
{: #bug-fixes-v3-8-7}
|
||||
|
||||
- Prevent console warnings with Ruby 2.7 ([#8125]({{ site.repository }}/issues/8125))
|
||||
|
||||
|
||||
## 3.8.6 / 2019-07-02
|
||||
{: #v3-8-6}
|
||||
|
||||
### Bug Fixes
|
||||
{: #bug-fixes-v3-8-6}
|
||||
|
||||
- Update log output for an invalid theme directory ([#7734]({{ site.repository }}/issues/7734))
|
||||
- Memoize `SiteDrop#documents` to reduce allocations ([#7722]({{ site.repository }}/issues/7722))
|
||||
- Excerpt handling of custom and intermediate tags ([#7467]({{ site.repository }}/issues/7467))
|
||||
- Escape valid special chars in a site's path name ([#7573]({{ site.repository }}/issues/7573))
|
||||
- Revert memoizing `Site#docs_to_write` and refactor `#documents` ([#7689]({{ site.repository }}/issues/7689))
|
||||
- Fix broken `include_relative` usage in excerpt ([#7690]({{ site.repository }}/issues/7690))
|
||||
- Install platform-specific gems as required (3c06609406)
|
||||
|
||||
### Security Fixes
|
||||
{: #security-fixes-v3-8-6}
|
||||
|
||||
- Theme gems: ensure directories aren't symlinks ([#7424]({{ site.repository }}/issues/7424))
|
||||
|
||||
|
||||
## 3.8.5 / 2018-11-04
|
||||
{: #v3-8-5}
|
||||
|
||||
### Bug Fixes
|
||||
{: #bug-fixes-v3-8-5}
|
||||
|
||||
- Re-implement handling Liquid blocks in excerpts ([#7250]({{ site.repository }}/issues/7250))
|
||||
|
||||
|
||||
## 3.8.4 / 2018-09-18
|
||||
{: #v3-8-4}
|
||||
|
||||
### Bug Fixes
|
||||
{: #bug-fixes-v3-8-4}
|
||||
|
||||
- security: fix `include` bypass of `EntryFilter#filter` symlink check ([#7228]({{ site.repository }}/issues/7228))
|
||||
|
||||
|
||||
## 3.8.3 / 2018-06-05
|
||||
{: #v3-8-3}
|
||||
|
||||
|
||||
19
docs/_posts/2019-07-02-jekyll-3-8-6-released.markdown
Normal file
19
docs/_posts/2019-07-02-jekyll-3-8-6-released.markdown
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: 'Jekyll 3.8.6 Released'
|
||||
date: 2019-07-02 11:21:02 -0400
|
||||
author: parkr
|
||||
version: 3.8.6
|
||||
categories: [release]
|
||||
---
|
||||
|
||||
We have another patch release in the 3.8 series! This time, we have one security patch
|
||||
and a handful of bug patches, including:
|
||||
|
||||
- Filter symlinks from theme gems
|
||||
- Fix excerpt handling of some Liquid tags
|
||||
- Handle case where a theme directory doesn't exist
|
||||
- A few internal optimizations to reduce memory overhead
|
||||
|
||||
... and a few more! You can check out the patches and see all the details in [the release notes](/docs/history/#v3-8-6)
|
||||
|
||||
Happy Jekylling!
|
||||
28
docs/_posts/2020-08-06-jekyll-3-9-0-released.markdown
Normal file
28
docs/_posts/2020-08-06-jekyll-3-9-0-released.markdown
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: 'Jekyll 3.9.0 Released'
|
||||
author: parkr
|
||||
version: 3.9.0
|
||||
categories: [release]
|
||||
---
|
||||
|
||||
Jekyll 3.9.0 allows use of kramdown v2, the latest series of kramdown.
|
||||
|
||||
If you choose to upgrade, please note that the GitHub-Flavored Markdown
|
||||
parser and other features of kramdown v1 are now distributed via
|
||||
separate gems. If you would like to continue using these features, you will
|
||||
need to add the gems to your `Gemfile`. They are as follows:
|
||||
|
||||
- GFM parser – `kramdown-parser-gfm`
|
||||
- coderay syntax highlighter – `kramdown-syntax-coderay`
|
||||
- mathjaxnode math engine – `kramdown-math-mathjaxnode`
|
||||
- sskatex math engine – `kramdown-math-sskatex`
|
||||
- katex math engine – `kramdown-math-katex`
|
||||
- ritex math engine – `kramdown-math-ritex`
|
||||
- itex2mml math engine – `kramdown-math-itex2mml`
|
||||
|
||||
Jekyll will require the given gem when the configuration requires it, and
|
||||
will show a helpful message when a dependency is missing.
|
||||
|
||||
You can check out the patches and see all the details in [the release notes](/docs/history/#v3-9-0)
|
||||
|
||||
Happy Jekylling!
|
||||
@@ -1 +1 @@
|
||||
3.8.3
|
||||
3.9.0
|
||||
|
||||
@@ -386,7 +386,23 @@ Feature: Collections
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "Second document's output: <p>Use <code class=\"highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
And I should see "Second document's output: <p>Use <code class=\"language-plaintext highlighter-rouge\">Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Documents have an output attribute, which is the converted HTML based on site.config
|
||||
Given I have an "index.html" page that contains "Second document's output: {{ site.documents[2].output }}"
|
||||
And I have fixture collections
|
||||
And I have a "_config.yml" file with content:
|
||||
"""
|
||||
kramdown:
|
||||
guess_lang: false
|
||||
collections:
|
||||
- methods
|
||||
"""
|
||||
And I'm using kramdown v2
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
Then the _site directory should exist
|
||||
And I should see "Second document's output: <p>Use <code>Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Filter documents by where
|
||||
Given I have an "index.html" page that contains "{% assign items = site.methods | where: 'whatever','foo.bar' %}Item count: {{ items.size }}"
|
||||
|
||||
60
features/include_relative_tag.feature
Normal file
60
features/include_relative_tag.feature
Normal file
@@ -0,0 +1,60 @@
|
||||
Feature: include_relative Tag
|
||||
In order to share content across several closely related pages
|
||||
As a hacker who likes to blog
|
||||
I want to be able to include snippets in my site's pages and documents relative to current file
|
||||
|
||||
Scenario: Include a file relative to a post
|
||||
Given I have a _posts directory
|
||||
And I have a _posts/snippets directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| Star Wars | 2018-09-02 | {% include_relative snippets/welcome_para.md %} |
|
||||
And I have an "_posts/snippets/welcome_para.md" file that contains "Welcome back Dear Reader!"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
|
||||
|
||||
Scenario: Include a nested file relative to a post
|
||||
Given I have a _posts directory
|
||||
And I have a _posts/snippets directory
|
||||
And I have a _posts/snippets/welcome_para directory
|
||||
And I have the following post:
|
||||
| title | date | content |
|
||||
| Star Wars | 2018-09-02 | {% include_relative snippets/welcome_para.md %} |
|
||||
And I have an "_posts/snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
|
||||
And I have an "_posts/snippets/welcome_para/greeting.md" file that contains "Welcome back"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
|
||||
|
||||
Scenario: Include a nested file relative to a post as an excerpt
|
||||
Given I have a _posts directory
|
||||
And I have a _posts/snippets directory
|
||||
And I have a _posts/snippets/welcome_para directory
|
||||
And I have a "_posts/2018-09-02-star-wars.md" file with content:
|
||||
"""
|
||||
{% include_relative snippets/welcome_para.md %}
|
||||
|
||||
Hello World
|
||||
"""
|
||||
And I have an "_posts/snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
|
||||
And I have an "_posts/snippets/welcome_para/greeting.md" file that contains "Welcome back"
|
||||
And I have an "index.md" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
|
||||
And I should see "Welcome back Dear Reader!" in "_site/index.html"
|
||||
|
||||
Scenario: Include a nested file relative to a page at root
|
||||
Given I have a snippets directory
|
||||
And I have a snippets/welcome_para directory
|
||||
And I have a "index.md" page that contains "{% include_relative snippets/welcome_para.md %}"
|
||||
And I have a "snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
|
||||
And I have a "snippets/welcome_para/greeting.md" file that contains "Welcome back"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Welcome back Dear Reader!" in "_site/index.html"
|
||||
@@ -5,6 +5,19 @@ Feature: Rendering
|
||||
But I want to make it as simply as possible
|
||||
So render with Liquid and place in Layouts
|
||||
|
||||
Scenario: Rendering a site with parentheses in its path name
|
||||
Given I have a blank site in "omega(beta)"
|
||||
And I have an "omega(beta)/test.md" page with layout "simple" that contains "Hello World"
|
||||
And I have an omega(beta)/_includes directory
|
||||
And I have an "omega(beta)/_includes/head.html" file that contains "Snippet"
|
||||
And I have a configuration file with "source" set to "omega(beta)"
|
||||
And I have an omega(beta)/_layouts directory
|
||||
And I have an "omega(beta)/_layouts/simple.html" file that contains "{% include head.html %}: {{ content }}"
|
||||
When I run jekyll build --profile
|
||||
Then I should get a zero exit status
|
||||
And I should see "Snippet: <p>Hello World</p>" in "_site/test.html"
|
||||
And I should see "_layouts/simple.html" in the build output
|
||||
|
||||
Scenario: When receiving bad Liquid
|
||||
Given I have a "index.html" page with layout "simple" that contains "{% include invalid.html %}"
|
||||
And I have a simple layout that contains "{{ content }}"
|
||||
|
||||
@@ -185,6 +185,12 @@ end
|
||||
|
||||
#
|
||||
|
||||
Given("I'm using kramdown v{int}") do |int|
|
||||
skip_this_scenario unless Kramdown::VERSION.to_i == int.to_i
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
Given(%r!^I wait (\d+) second(s?)$!) do |time, _|
|
||||
sleep(time.to_f)
|
||||
end
|
||||
|
||||
@@ -57,6 +57,17 @@ Feature: Writing themes
|
||||
And I should see "From your site." in "_site/assets/application.coffee"
|
||||
And I should see "From your site." in "_site/assets/base.js"
|
||||
|
||||
Scenario: A theme with *just* layouts
|
||||
Given I have a configuration file with "theme" set to "test-theme-skinny"
|
||||
And I have an "index.html" page with layout "home" that contains "The quick brown fox."
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "Message: The quick brown fox." in "_site/index.html"
|
||||
But I should not see "_includes" in the build output
|
||||
And I should not see "_sass" in the build output
|
||||
And I should not see "assets" in the build output
|
||||
|
||||
Scenario: Requiring dependencies of a theme
|
||||
Given I have a configuration file with "theme" set to "test-dependency-theme"
|
||||
When I run jekyll build
|
||||
|
||||
@@ -36,11 +36,15 @@ Gem::Specification.new do |s|
|
||||
s.add_runtime_dependency("i18n", "~> 0.7")
|
||||
s.add_runtime_dependency("jekyll-sass-converter", "~> 1.0")
|
||||
s.add_runtime_dependency("jekyll-watch", "~> 2.0")
|
||||
s.add_runtime_dependency("kramdown", "~> 1.14")
|
||||
s.add_runtime_dependency("liquid", "~> 4.0")
|
||||
s.add_runtime_dependency("mercenary", "~> 0.3.3")
|
||||
s.add_runtime_dependency("pathutil", "~> 0.9")
|
||||
rouge_versions = ENV["ROUGE_VERSION"] ? ["~> #{ENV["ROUGE_VERSION"]}"] : [">= 1.7", "< 4"]
|
||||
s.add_runtime_dependency("rouge", *rouge_versions)
|
||||
s.add_runtime_dependency("safe_yaml", "~> 1.0")
|
||||
|
||||
# Depend on kramdown. For kramdown v2, extra gems are required.
|
||||
# https://kramdown.gettalong.org/news.html#kramdown-200-released
|
||||
kramdown_versions = ENV["KRAMDOWN_VERSION"] ? ["~> #{ENV["KRAMDOWN_VERSION"]}"] : [">= 1.17", "< 3"]
|
||||
s.add_runtime_dependency("kramdown", *kramdown_versions)
|
||||
end
|
||||
|
||||
@@ -88,10 +88,18 @@ group :jekyll_plugins do
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||
# and associated library.
|
||||
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.0" if Gem.win_platform?
|
||||
gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
|
||||
|
||||
# kramdown v2 ships without the gfm parser by default. If you're using
|
||||
# kramdown v1, comment out this line.
|
||||
gem "kramdown-parser-gfm"
|
||||
|
||||
RUBY
|
||||
end
|
||||
|
||||
@@ -81,6 +81,7 @@ module Jekyll
|
||||
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
||||
"input" => "GFM",
|
||||
"hard_wrap" => false,
|
||||
"guess_lang" => true,
|
||||
"footnote_nr" => 1,
|
||||
"show_warnings" => false,
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ module Jekyll
|
||||
@config = config["kramdown"] || {}
|
||||
@highlighter = nil
|
||||
setup
|
||||
load_dependencies
|
||||
end
|
||||
|
||||
# Setup and normalize the configuration:
|
||||
@@ -30,6 +31,8 @@ module Jekyll
|
||||
def setup
|
||||
@config["syntax_highlighter"] ||= highlighter
|
||||
@config["syntax_highlighter_opts"] ||= {}
|
||||
@config["syntax_highlighter_opts"]["default_lang"] ||= "plaintext"
|
||||
@config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
|
||||
@config["coderay"] ||= {} # XXX: Legacy.
|
||||
modernize_coderay_config
|
||||
make_accessible
|
||||
@@ -47,6 +50,24 @@ module Jekyll
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_dependencies
|
||||
return if Kramdown::VERSION.to_i < 2
|
||||
if @config["input"] == "GFM"
|
||||
Jekyll::External.require_with_graceful_fail("kramdown-parser-gfm")
|
||||
end
|
||||
|
||||
if highlighter == "coderay"
|
||||
Jekyll::External.require_with_graceful_fail("kramdown-syntax-coderay")
|
||||
end
|
||||
|
||||
# `mathjax` emgine is bundled within kramdown-2.x and will be handled by
|
||||
# kramdown itself.
|
||||
if (math_engine = @config["math_engine"]) && math_engine != "mathjax"
|
||||
Jekyll::External.require_with_graceful_fail("kramdown-math-#{math_engine}")
|
||||
end
|
||||
end
|
||||
|
||||
def make_accessible(hash = @config)
|
||||
hash.keys.each do |key|
|
||||
hash[key.to_sym] = hash[key]
|
||||
|
||||
@@ -39,7 +39,7 @@ module Jekyll
|
||||
|
||||
begin
|
||||
self.content = File.read(@path || site.in_source_dir(base, name),
|
||||
Utils.merged_file_read_opts(site, opts))
|
||||
**Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ Document::YAML_FRONT_MATTER_REGEXP
|
||||
self.content = $POSTMATCH
|
||||
self.data = SafeYAML.load(Regexp.last_match(1))
|
||||
|
||||
@@ -266,7 +266,7 @@ module Jekyll
|
||||
else
|
||||
begin
|
||||
merge_defaults
|
||||
read_content(opts)
|
||||
read_content(**opts)
|
||||
read_post_data
|
||||
rescue StandardError => e
|
||||
handle_read_error(e)
|
||||
@@ -445,8 +445,8 @@ module Jekyll
|
||||
end
|
||||
|
||||
private
|
||||
def read_content(opts)
|
||||
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
||||
def read_content(**opts)
|
||||
self.content = File.read(path, **Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ YAML_FRONT_MATTER_REGEXP
|
||||
self.content = $POSTMATCH
|
||||
data_file = SafeYAML.load(Regexp.last_match(1))
|
||||
|
||||
@@ -8,8 +8,7 @@ module Jekyll
|
||||
mutable false
|
||||
|
||||
def_delegator :@obj, :site_data, :data
|
||||
def_delegators :@obj, :time, :pages, :static_files, :documents,
|
||||
:tags, :categories
|
||||
def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
|
||||
|
||||
private def_delegator :@obj, :config, :fallback_data
|
||||
|
||||
@@ -39,6 +38,16 @@ module Jekyll
|
||||
@site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
|
||||
end
|
||||
|
||||
# `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
|
||||
# latest state of the attribute.
|
||||
#
|
||||
# Since this method will be called after `Site#pre_render` hook,
|
||||
# the `Site#documents` array shouldn't thereafter change and can therefore be
|
||||
# safely memoized to prevent additional computation of `Site#documents`.
|
||||
def documents
|
||||
@documents ||= @obj.documents
|
||||
end
|
||||
|
||||
# `{{ site.related_posts }}` is how posts can get posts related to
|
||||
# them, either through LSI if it's enabled, or through the most
|
||||
# recent posts.
|
||||
|
||||
@@ -31,9 +31,12 @@ module Jekyll
|
||||
|
||||
def filter(entries)
|
||||
entries.reject do |e|
|
||||
unless included?(e)
|
||||
special?(e) || backup?(e) || excluded?(e) || symlink?(e)
|
||||
end
|
||||
# Reject this entry if it is a symlink.
|
||||
next true if symlink?(e)
|
||||
# Do not reject this entry if it is included.
|
||||
next false if included?(e)
|
||||
# Reject this entry if it is special, a backup file, or excluded.
|
||||
special?(e) || backup?(e) || excluded?(e)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -128,36 +128,47 @@ module Jekyll
|
||||
#
|
||||
# Returns excerpt String
|
||||
|
||||
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+).+\s*-?%}!m
|
||||
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m
|
||||
MKDWN_LINK_REF_REGEX = %r!^ {0,3}\[[^\]]+\]:.+$!
|
||||
|
||||
def extract_excerpt(doc_content)
|
||||
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
||||
|
||||
# append appropriate closing tag (to a Liquid block), to the "head" if the
|
||||
# partitioning resulted in leaving the closing tag somewhere in the "tail"
|
||||
# partition.
|
||||
if head.include?("{%")
|
||||
head =~ LIQUID_TAG_REGEX
|
||||
tag_name = Regexp.last_match(1)
|
||||
# append appropriate closing tag(s) (for each Liquid block), to the `head`
|
||||
# if the partitioning resulted in leaving the closing tag somewhere
|
||||
# in the `tail` partition.
|
||||
|
||||
if liquid_block?(tag_name) && head.match(%r!{%-?\s*end#{tag_name}\s*-?%}!).nil?
|
||||
print_build_warning
|
||||
if head.include?("{%")
|
||||
modified = false
|
||||
tag_names = head.scan(LIQUID_TAG_REGEX)
|
||||
tag_names.flatten!
|
||||
tag_names.reverse_each do |tag_name|
|
||||
next unless liquid_block?(tag_name)
|
||||
next if head =~ endtag_regex_stash(tag_name)
|
||||
|
||||
modified = true
|
||||
head << "\n{% end#{tag_name} %}"
|
||||
end
|
||||
print_build_warning if modified
|
||||
end
|
||||
|
||||
if tail.empty?
|
||||
head
|
||||
else
|
||||
head.to_s.dup << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
|
||||
end
|
||||
return head if tail.empty?
|
||||
|
||||
head << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def endtag_regex_stash(tag_name)
|
||||
@endtag_regex_stash ||= {}
|
||||
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
|
||||
end
|
||||
|
||||
def liquid_block?(tag_name)
|
||||
Liquid::Template.tags[tag_name].superclass == Liquid::Block
|
||||
return false unless tag_name.is_a?(String)
|
||||
return false unless Liquid::Template.tags[tag_name]
|
||||
|
||||
Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
|
||||
rescue NoMethodError
|
||||
Jekyll.logger.error "Error:",
|
||||
"A Liquid tag in the excerpt of #{doc.relative_path} couldn't be " \
|
||||
@@ -167,12 +178,13 @@ module Jekyll
|
||||
|
||||
def print_build_warning
|
||||
Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
|
||||
Jekyll.logger.warn "",
|
||||
"Found a Liquid block containing separator '#{doc.excerpt_separator}' and has " \
|
||||
"been modified with the appropriate closing tag."
|
||||
Jekyll.logger.warn "",
|
||||
"Feel free to define a custom excerpt or excerpt_separator in the document's " \
|
||||
"Front Matter if the generated excerpt is unsatisfactory."
|
||||
Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
|
||||
" #{doc.excerpt_separator.inspect}. "
|
||||
Jekyll.logger.warn "", "The block has been modified with the appropriate" \
|
||||
" closing tag."
|
||||
Jekyll.logger.warn "", "Feel free to define a custom excerpt or" \
|
||||
" excerpt_separator in the document's front matter" \
|
||||
" if the generated excerpt is unsatisfactory."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,7 +53,9 @@ module Jekyll
|
||||
private
|
||||
|
||||
def filename_regex
|
||||
@filename_regex ||= %r!\A(#{source_dir}/|#{theme_dir}/|\W*)(.*)!i
|
||||
@filename_regex ||= begin
|
||||
%r!\A(#{Regexp.escape(source_dir)}/|#{Regexp.escape(theme_dir.to_s)}/|/*)(.*)!i
|
||||
end
|
||||
end
|
||||
|
||||
def new_profile_hash
|
||||
|
||||
@@ -314,15 +314,15 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of Documents which should be written
|
||||
def docs_to_write
|
||||
@docs_to_write ||= documents.select(&:write?)
|
||||
documents.select(&:write?)
|
||||
end
|
||||
|
||||
# Get all the documents
|
||||
#
|
||||
# Returns an Array of all Documents
|
||||
def documents
|
||||
collections.reduce(Set.new) do |docs, (_, collection)|
|
||||
docs + collection.docs + collection.files
|
||||
collections.each_with_object(Set.new) do |(_, collection), set|
|
||||
set.merge(collection.docs).merge(collection.files)
|
||||
end.to_a
|
||||
end
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ MSG
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def read_file(file, context)
|
||||
File.read(file, file_read_opts(context))
|
||||
File.read(file, **file_read_opts(context))
|
||||
end
|
||||
|
||||
private
|
||||
@@ -224,6 +224,7 @@ MSG
|
||||
else
|
||||
File.join(site.config["collections_dir"], page_payload["path"])
|
||||
end
|
||||
resource_path.sub!(%r!/#excerpt\z!, "")
|
||||
site.in_source_dir File.dirname(resource_path)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,12 +56,28 @@ module Jekyll
|
||||
end
|
||||
|
||||
def realpath_for(folder)
|
||||
File.realpath(Jekyll.sanitized_path(root, folder.to_s))
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
|
||||
Jekyll.logger.warn "Invalid theme folder:", folder
|
||||
# This resolves all symlinks for the theme subfolder and then ensures
|
||||
# that the directory remains inside the theme root. This prevents the
|
||||
# use of symlinks for theme subfolders to escape the theme root.
|
||||
# However, symlinks are allowed to point to other directories within the theme.
|
||||
Jekyll.sanitized_path(root, File.realpath(Jekyll.sanitized_path(root, folder.to_s)))
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP => e
|
||||
log_realpath_exception(e, folder)
|
||||
nil
|
||||
end
|
||||
|
||||
def log_realpath_exception(err, folder)
|
||||
return if err.is_a?(Errno::ENOENT)
|
||||
|
||||
case err
|
||||
when Errno::EACCES
|
||||
Jekyll.logger.error "Theme error:", "Directory '#{folder}' is not accessible."
|
||||
when Errno::ELOOP
|
||||
Jekyll.logger.error "Theme error:",
|
||||
"Directory '#{folder}' includes a symbolic link loop."
|
||||
end
|
||||
end
|
||||
|
||||
def gemspec
|
||||
@gemspec ||= Gem::Specification.find_by_name(name)
|
||||
rescue Gem::LoadError
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
VERSION = "3.8.3".freeze
|
||||
VERSION = "3.9.0".freeze
|
||||
end
|
||||
|
||||
@@ -13,6 +13,15 @@ pushd tmp/default-site
|
||||
|
||||
echo "$0: respecifying the jekyll install location"
|
||||
ruby -e "contents = File.read('Gemfile'); File.write('Gemfile', contents.sub(/gem \"jekyll\".*\\n/, 'gem \"jekyll\", path: \"../../\"'))"
|
||||
if [ -n "$KRAMDOWN_VERSION" ]; then
|
||||
echo "$0: respecifying the kramdown version"
|
||||
ruby -e "contents = File.read('Gemfile'); File.write('Gemfile', contents.sub(/gem \"kramdown-parser-gfm\".*\\n/, ''))"
|
||||
echo "gem 'kramdown', '~> $KRAMDOWN_VERSION'" >> Gemfile
|
||||
fi
|
||||
if [ -n "$ROUGE_VERSION" ]; then
|
||||
echo "$0: respecifying the rouge version"
|
||||
echo "gem 'rouge', '~> $ROUGE_VERSION'" >> Gemfile
|
||||
fi
|
||||
echo "$0: installing default site dependencies"
|
||||
BUNDLE_GEMFILE=Gemfile bundle install
|
||||
echo "$0: building the default site"
|
||||
|
||||
10
script/profile-docs
Executable file
10
script/profile-docs
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build Jekyll's Documentation site in 'debug' mode and outputs the site's profile stats.
|
||||
# Helps detecting *hard* breaking-changes (`jekyll build` aborts) and optimizations
|
||||
# in the `build` process.
|
||||
#
|
||||
# Usage: bash script/profile-docs
|
||||
|
||||
SOURCE_DIR=$PWD/docs
|
||||
bundle exec jekyll build -s $SOURCE_DIR -d $SOURCE_DIR/_site --profile --trace --verbose
|
||||
11
test/fixtures/test-theme-skinny/_layouts/default.html
vendored
Normal file
11
test/fixtures/test-theme-skinny/_layouts/default.html
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Skinny</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
{{ content }}
|
||||
</body>
|
||||
</html>
|
||||
5
test/fixtures/test-theme-skinny/_layouts/home.html
vendored
Normal file
5
test/fixtures/test-theme-skinny/_layouts/home.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
Message: {{ content }}
|
||||
11
test/fixtures/test-theme-skinny/test-theme-skinny.gemspec
vendored
Normal file
11
test/fixtures/test-theme-skinny/test-theme-skinny.gemspec
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "test-theme-skinny"
|
||||
s.version = "0.1.0"
|
||||
s.licenses = ["MIT"]
|
||||
s.summary = "This is a theme with just layouts used to test Jekyll"
|
||||
s.authors = ["Jekyll"]
|
||||
s.files = ["lib/example.rb"]
|
||||
s.homepage = "https://github.com/jekyll/jekyll"
|
||||
end
|
||||
11
test/fixtures/test-theme-symlink/test-theme-symlink.gemspec
vendored
Normal file
11
test/fixtures/test-theme-symlink/test-theme-symlink.gemspec
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "test-theme-symlink"
|
||||
s.version = "0.1.0"
|
||||
s.licenses = ["MIT"]
|
||||
s.summary = "This is a theme with a symlink used to test Jekyll"
|
||||
s.authors = ["Jekyll"]
|
||||
s.files = ["lib/example.rb"]
|
||||
s.homepage = "https://github.com/jekyll/jekyll"
|
||||
end
|
||||
@@ -195,6 +195,15 @@ class JekyllUnitTest < Minitest::Test
|
||||
skip msg.to_s.magenta
|
||||
end
|
||||
end
|
||||
|
||||
def symlink_if_allowed(target, sym_file)
|
||||
FileUtils.ln_sf(target, sym_file)
|
||||
rescue Errno::EACCES
|
||||
skip "Permission denied for creating a symlink to #{target.inspect} " \
|
||||
"on this machine".magenta
|
||||
rescue NotImplementedError => error
|
||||
skip error.to_s.magenta
|
||||
end
|
||||
end
|
||||
|
||||
class FakeLogger
|
||||
|
||||
14
test/source/_plugins/custom_block.rb
Normal file
14
test/source/_plugins/custom_block.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# For testing excerpt handling of custom tags
|
||||
|
||||
module Jekyll
|
||||
class DoNothingBlock < Liquid::Block
|
||||
end
|
||||
|
||||
class DoNothingOther < Liquid::Tag
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("do_nothing", Jekyll::DoNothingBlock)
|
||||
Liquid::Template.register_tag("do_nothing_other", Jekyll::DoNothingOther)
|
||||
@@ -2,10 +2,23 @@
|
||||
layout: post
|
||||
---
|
||||
|
||||
{% if
|
||||
page.layout == "post" %}
|
||||
You’ll find this post in your `_posts` directory.
|
||||
To add new posts, simply add a file in the `_posts` directory.
|
||||
{% endif %}
|
||||
{%
|
||||
highlight
|
||||
ruby
|
||||
%}
|
||||
{% assign foo = 'foobar' %}
|
||||
{% raw
|
||||
%}
|
||||
def print_hi(name)
|
||||
puts "Hi, #{name}"
|
||||
end
|
||||
print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{%
|
||||
endraw
|
||||
%}
|
||||
{%
|
||||
endhighlight
|
||||
%}
|
||||
|
||||
So let's talk business.
|
||||
|
||||
@@ -2,10 +2,20 @@
|
||||
layout: post
|
||||
---
|
||||
|
||||
{% if page.layout == "post" %}
|
||||
You’ll find this post in your `_posts` directory.
|
||||
{%
|
||||
highlight
|
||||
ruby
|
||||
%}
|
||||
{% assign foo = 'foobar' %}
|
||||
{% raw
|
||||
%}
|
||||
def print_hi(name)
|
||||
puts "Hi, #{name}"
|
||||
end
|
||||
|
||||
{% else %}
|
||||
print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{% endraw %}
|
||||
{% endhighlight %}
|
||||
|
||||
To add new posts, simply add a file in the `_posts` directory.
|
||||
{% endif %}
|
||||
So let's talk business.
|
||||
|
||||
29
test/source/_posts/2018-11-15-excerpt-liquid-block.md
Normal file
29
test/source/_posts/2018-11-15-excerpt-liquid-block.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: liquid_block excerpt test with open tags in excerpt
|
||||
layout: post
|
||||
---
|
||||
|
||||
{% assign company = "Yoyodyne" %}
|
||||
{% do_nothing_other %}
|
||||
{% do_nothing %}
|
||||
{% unless false %}
|
||||
{% for i in (1..10) %}
|
||||
{% if true %}
|
||||
{% raw %}
|
||||
EVIL! PURE AND SIMPLE FROM THE EIGHTH DIMENSION!
|
||||
{% endraw %}
|
||||
{% elsif false %}
|
||||
No matter where you go, there you are.
|
||||
{% break %}
|
||||
{% else %}
|
||||
{% case company %}
|
||||
{% when "Yoyodyne" %}
|
||||
Buckaroo Banzai
|
||||
{% else %}
|
||||
{% continue %}
|
||||
|
||||
{% endcase %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endunless %}
|
||||
{% enddo_nothing %}
|
||||
1
test/source/symlink-test/symlinked-file-outside-source
Symbolic link
1
test/source/symlink-test/symlinked-file-outside-source
Symbolic link
@@ -0,0 +1 @@
|
||||
/etc/passwd
|
||||
@@ -5,7 +5,7 @@ require "helper"
|
||||
class TestEntryFilter < JekyllUnitTest
|
||||
context "Filtering entries" do
|
||||
setup do
|
||||
@site = Site.new(site_configuration)
|
||||
@site = fixture_site
|
||||
end
|
||||
|
||||
should "filter entries" do
|
||||
@@ -87,7 +87,7 @@ class TestEntryFilter < JekyllUnitTest
|
||||
# no support for symlinks on Windows
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
site = Site.new(site_configuration("safe" => true))
|
||||
site = fixture_site("safe" => true)
|
||||
site.reader.read_directories("symlink-test")
|
||||
|
||||
assert_equal %w(main.scss symlinked-file).length, site.pages.length
|
||||
@@ -99,11 +99,22 @@ class TestEntryFilter < JekyllUnitTest
|
||||
# no support for symlinks on Windows
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
site = Site.new(site_configuration)
|
||||
@site.reader.read_directories("symlink-test")
|
||||
refute_equal [], @site.pages
|
||||
refute_equal [], @site.static_files
|
||||
end
|
||||
|
||||
should "include only safe symlinks in safe mode even when included" do
|
||||
# no support for symlinks on Windows
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
site = fixture_site("safe" => true, "include" => ["symlinked-file-outside-source"])
|
||||
site.reader.read_directories("symlink-test")
|
||||
refute_equal [], site.pages
|
||||
refute_equal [], site.static_files
|
||||
|
||||
# rubocop:disable Performance/FixedSize
|
||||
assert_equal %w(main.scss symlinked-file).length, site.pages.length
|
||||
refute_includes site.static_files.map(&:name), "symlinked-file-outside-source"
|
||||
# rubocop:enable Performance/FixedSize
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -185,12 +185,17 @@ class TestExcerpt < JekyllUnitTest
|
||||
@post = setup_post("2018-01-28-open-liquid-block-excerpt.markdown")
|
||||
@excerpt = @post.data["excerpt"]
|
||||
|
||||
assert_includes @post.content, "{% if"
|
||||
refute_includes @post.content.split("\n\n")[0], "{% endif %}"
|
||||
head = @post.content.split("\n\n")[0]
|
||||
|
||||
assert_includes @post.content, "{%\n highlight\n"
|
||||
assert_includes @post.content, "{% raw"
|
||||
refute_includes head, "{% endraw %}"
|
||||
refute_includes head, "{% endhighlight %}"
|
||||
end
|
||||
|
||||
should "be appended to as necessary and generated" do
|
||||
assert_includes @excerpt.content, "{% endif %}"
|
||||
assert_includes @excerpt.content, "{% endraw %}"
|
||||
assert_includes @excerpt.content, "{% endhighlight %}"
|
||||
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
|
||||
end
|
||||
end
|
||||
@@ -202,13 +207,19 @@ class TestExcerpt < JekyllUnitTest
|
||||
@post = setup_post("2018-01-28-closed-liquid-block-excerpt.markdown")
|
||||
@excerpt = @post.data["excerpt"]
|
||||
|
||||
assert_includes @post.content, "{% if"
|
||||
assert_includes @post.content.split("\n\n")[0], "{% endif %}"
|
||||
head = @post.content.split("\n\n")[0]
|
||||
|
||||
assert_includes @post.content, "{%\n highlight\n"
|
||||
assert_includes @post.content, "{% raw"
|
||||
assert_includes head, "{%\n endraw\n%}"
|
||||
assert_includes head, "{%\n endhighlight\n%}"
|
||||
end
|
||||
|
||||
should "not be appended to but generated as is" do
|
||||
assert_includes @excerpt.content, "{% endif %}"
|
||||
refute_includes @excerpt.content, "{% endif %}\n\n{% endif %}"
|
||||
assert_includes @excerpt.content, "{%\n endraw\n%}"
|
||||
assert_includes @excerpt.content, "{%\n endhighlight\n%}"
|
||||
refute_includes @excerpt.content, "{%\n endraw\n%}\n\n{% endraw %}"
|
||||
refute_includes @excerpt.content, "{%\n endhighlight\n%}\n\n{% endhighlight %}"
|
||||
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
|
||||
end
|
||||
end
|
||||
@@ -264,4 +275,29 @@ class TestExcerpt < JekyllUnitTest
|
||||
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
|
||||
end
|
||||
end
|
||||
|
||||
context "An excerpt with Liquid tags" do
|
||||
setup do
|
||||
clear_dest
|
||||
@site = fixture_site
|
||||
@post = setup_post("2018-11-15-excerpt-liquid-block.md")
|
||||
@excerpt = @post.data["excerpt"]
|
||||
|
||||
assert_includes @post.content.split("\n\n")[0].strip, "{% continue %}"
|
||||
assert_equal true, Jekyll::DoNothingBlock.ancestors.include?(Liquid::Block)
|
||||
assert_equal false, Jekyll::DoNothingOther.ancestors.include?(Liquid::Block)
|
||||
assert_match "Jekyll::DoNothingBlock", Liquid::Template.tags["do_nothing"].name
|
||||
assert_match "Jekyll::DoNothingOther", Liquid::Template.tags["do_nothing_other"].name
|
||||
end
|
||||
|
||||
should "close open block tags, including custom tags, and ignore others" do
|
||||
assert_includes @excerpt.content, "{% endcase %}"
|
||||
assert_includes @excerpt.content, "{% endif %}"
|
||||
assert_includes @excerpt.content, "{% endfor %}"
|
||||
assert_includes @excerpt.content, "{% endunless %}"
|
||||
assert_includes @excerpt.content, "{% enddo_nothing %}"
|
||||
refute_includes @excerpt.content, "{% enddo_nothing_other %}"
|
||||
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestGeneratedSite < JekyllUnitTest
|
||||
end
|
||||
|
||||
should "ensure post count is as expected" do
|
||||
assert_equal 57, @site.posts.size
|
||||
assert_equal 58, @site.posts.size
|
||||
end
|
||||
|
||||
should "insert site.posts into the index" do
|
||||
|
||||
@@ -3,10 +3,17 @@
|
||||
require "helper"
|
||||
|
||||
class TestKramdown < JekyllUnitTest
|
||||
def fixture_converter(config)
|
||||
site_config = Utils.deep_merge_hashes({ "markdown" => "kramdown" }, config)
|
||||
site = fixture_site(site_config)
|
||||
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
|
||||
converter.setup
|
||||
converter
|
||||
end
|
||||
|
||||
context "kramdown" do
|
||||
setup do
|
||||
@config = {
|
||||
"markdown" => "kramdown",
|
||||
"kramdown" => {
|
||||
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
||||
"entity_output" => "as_char",
|
||||
@@ -29,12 +36,11 @@ class TestKramdown < JekyllUnitTest
|
||||
@config["kramdown"]["syntax_highlighter_opts"].keys
|
||||
|
||||
@config = Jekyll.configuration(@config)
|
||||
@markdown = Converters::Markdown.new(@config)
|
||||
@markdown.setup
|
||||
@converter = fixture_converter(@config)
|
||||
end
|
||||
|
||||
should "fill symbolized keys into config for compatibility with kramdown" do
|
||||
kramdown_config = @markdown.instance_variable_get(:@parser)
|
||||
kramdown_config = @converter.instance_variable_get(:@parser)
|
||||
.instance_variable_get(:@config)
|
||||
|
||||
@kramdown_config_keys.each do |key|
|
||||
@@ -54,20 +60,70 @@ class TestKramdown < JekyllUnitTest
|
||||
end
|
||||
|
||||
should "run Kramdown" do
|
||||
assert_equal "<h1>Some Header</h1>", @markdown.convert("# Some Header #").strip
|
||||
assert_equal "<h1>Some Header</h1>", @converter.convert("# Some Header #").strip
|
||||
end
|
||||
|
||||
should "should log kramdown warnings" do
|
||||
allow_any_instance_of(Kramdown::Document).to receive(:warnings).and_return(["foo"])
|
||||
expect(Jekyll.logger).to receive(:warn).with("Kramdown warning:", "foo")
|
||||
@markdown.convert("Something")
|
||||
@converter.convert("Something")
|
||||
end
|
||||
|
||||
should "render fenced code blocks with syntax highlighting" do
|
||||
result = nokogiri_fragment(@converter.convert(<<~MARKDOWN))
|
||||
~~~ruby
|
||||
puts "Hello World"
|
||||
~~~
|
||||
MARKDOWN
|
||||
div_highlight = Rouge.version.to_i == 1 ? "" : ">div.highlight"
|
||||
selector = "div.highlighter-rouge#{div_highlight}>pre.highlight>code"
|
||||
refute(result.css(selector).empty?, result.to_html)
|
||||
end
|
||||
|
||||
context "when configured" do
|
||||
setup do
|
||||
@source = <<~TEXT
|
||||
## Code Sample
|
||||
|
||||
def ruby_fu
|
||||
"Hello"
|
||||
end
|
||||
TEXT
|
||||
end
|
||||
|
||||
should "have 'plaintext' as the default syntax_highlighter language" do
|
||||
converter = fixture_converter(@config)
|
||||
parser = converter.instance_variable_get(:@parser)
|
||||
parser_config = parser.instance_variable_get(:@config)
|
||||
|
||||
assert_equal "plaintext", parser_config.dig("syntax_highlighter_opts", "default_lang")
|
||||
end
|
||||
|
||||
should "accept the specified default syntax_highlighter language" do
|
||||
override = {
|
||||
"kramdown" => {
|
||||
"syntax_highlighter_opts" => {
|
||||
"default_lang" => "yaml",
|
||||
},
|
||||
},
|
||||
}
|
||||
converter = fixture_converter(Utils.deep_merge_hashes(@config, override))
|
||||
parser = converter.instance_variable_get(:@parser)
|
||||
parser_config = parser.instance_variable_get(:@config)
|
||||
|
||||
assert_equal "yaml", parser_config.dig("syntax_highlighter_opts", "default_lang")
|
||||
refute_match %r!<div class="language-plaintext!, converter.convert(@source)
|
||||
refute_match %r!<div class="language-html!, converter.convert(@source)
|
||||
assert_match %r!<div class="language-yaml!, converter.convert(@source)
|
||||
end
|
||||
end
|
||||
|
||||
context "when asked to convert smart quotes" do
|
||||
should "convert" do
|
||||
converter = fixture_converter(@config)
|
||||
assert_match(
|
||||
%r!<p>(“|“)Pit(’|’)hy(”|”)<\/p>!,
|
||||
@markdown.convert(%("Pit'hy")).strip
|
||||
converter.convert(%("Pit'hy")).strip
|
||||
)
|
||||
end
|
||||
|
||||
@@ -78,37 +134,23 @@ class TestKramdown < JekyllUnitTest
|
||||
"smart_quotes" => "lsaquo,rsaquo,laquo,raquo",
|
||||
},
|
||||
}
|
||||
|
||||
markdown = Converters::Markdown.new(Utils.deep_merge_hashes(@config, override))
|
||||
converter = fixture_converter(Utils.deep_merge_hashes(@config, override))
|
||||
assert_match %r!<p>(«|«)Pit(›|›)hy(»|»)<\/p>!, \
|
||||
markdown.convert(%("Pit'hy")).strip
|
||||
converter.convert(%("Pit'hy")).strip
|
||||
end
|
||||
end
|
||||
|
||||
should "render fenced code blocks with syntax highlighting" do
|
||||
result = nokogiri_fragment(@markdown.convert(Utils.strip_heredoc(<<-MARKDOWN)))
|
||||
~~~ruby
|
||||
puts "Hello World"
|
||||
~~~
|
||||
MARKDOWN
|
||||
div_highlight = ""
|
||||
div_highlight = ">div.highlight" unless Utils::Rouge.old_api?
|
||||
selector = "div.highlighter-rouge#{div_highlight}>pre.highlight>code"
|
||||
refute result.css(selector).empty?
|
||||
end
|
||||
|
||||
context "when a custom highlighter is chosen" do
|
||||
should "use the chosen highlighter if it's available" do
|
||||
override = {
|
||||
"highlighter" => nil,
|
||||
"markdown" => "kramdown",
|
||||
"kramdown" => {
|
||||
"syntax_highlighter" => :coderay,
|
||||
"syntax_highlighter" => "coderay",
|
||||
},
|
||||
}
|
||||
|
||||
markdown = Converters::Markdown.new(Utils.deep_merge_hashes(@config, override))
|
||||
result = nokogiri_fragment(markdown.convert(Utils.strip_heredoc(<<-MARKDOWN)))
|
||||
converter = fixture_converter(Utils.deep_merge_hashes(@config, override))
|
||||
result = nokogiri_fragment(converter.convert(<<~MARKDOWN))
|
||||
~~~ruby
|
||||
puts "Hello World"
|
||||
~~~
|
||||
@@ -120,7 +162,6 @@ class TestKramdown < JekyllUnitTest
|
||||
|
||||
should "support legacy enable_coderay... for now" do
|
||||
override = {
|
||||
"markdown" => "kramdown",
|
||||
"kramdown" => {
|
||||
"enable_coderay" => true,
|
||||
},
|
||||
@@ -128,8 +169,9 @@ class TestKramdown < JekyllUnitTest
|
||||
|
||||
@config.delete("highlighter")
|
||||
@config["kramdown"].delete("syntax_highlighter")
|
||||
markdown = Converters::Markdown.new(Utils.deep_merge_hashes(@config, override))
|
||||
result = nokogiri_fragment(markdown.convert(Utils.strip_heredoc(<<-MARKDOWN)))
|
||||
|
||||
converter = fixture_converter(Utils.deep_merge_hashes(@config, override))
|
||||
result = nokogiri_fragment(converter.convert(<<~MARKDOWN))
|
||||
~~~ruby
|
||||
puts "Hello World"
|
||||
~~~
|
||||
@@ -141,24 +183,26 @@ class TestKramdown < JekyllUnitTest
|
||||
end
|
||||
|
||||
should "move coderay to syntax_highlighter_opts" do
|
||||
original = Kramdown::Document.method(:new)
|
||||
markdown = Converters::Markdown.new(Utils.deep_merge_hashes(@config, {
|
||||
override = {
|
||||
"higlighter" => nil,
|
||||
"markdown" => "kramdown",
|
||||
"kramdown" => {
|
||||
"syntax_highlighter" => "coderay",
|
||||
"coderay" => {
|
||||
"hello" => "world",
|
||||
},
|
||||
},
|
||||
}))
|
||||
}
|
||||
original = Kramdown::Document.method(:new)
|
||||
converter = fixture_converter(
|
||||
Utils.deep_merge_hashes(@config, override)
|
||||
)
|
||||
|
||||
expect(Kramdown::Document).to receive(:new) do |arg1, hash|
|
||||
assert_equal hash["syntax_highlighter_opts"]["hello"], "world"
|
||||
original.call(arg1, hash)
|
||||
end
|
||||
|
||||
markdown.convert("hello world")
|
||||
converter.convert("hello world")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,5 +31,52 @@ class TestLayoutReader < JekyllUnitTest
|
||||
assert_equal LayoutReader.new(@site).layout_directory, source_dir("blah/_layouts")
|
||||
end
|
||||
end
|
||||
|
||||
context "when a layout is a symlink" do
|
||||
setup do
|
||||
symlink_if_allowed("/etc/passwd", source_dir("_layouts", "symlink.html"))
|
||||
|
||||
@site = fixture_site(
|
||||
"safe" => true,
|
||||
"include" => ["symlink.html"]
|
||||
)
|
||||
end
|
||||
|
||||
teardown do
|
||||
FileUtils.rm_f(source_dir("_layouts", "symlink.html"))
|
||||
end
|
||||
|
||||
should "only read the layouts which are in the site" do
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
layouts = LayoutReader.new(@site).read
|
||||
|
||||
refute layouts.key?("symlink"), "Should not read the symlinked layout"
|
||||
end
|
||||
end
|
||||
|
||||
context "with a theme" do
|
||||
setup do
|
||||
symlink_if_allowed("/etc/passwd", theme_dir("_layouts", "theme-symlink.html"))
|
||||
@site = fixture_site(
|
||||
"include" => ["theme-symlink.html"],
|
||||
"theme" => "test-theme",
|
||||
"safe" => true
|
||||
)
|
||||
end
|
||||
|
||||
teardown do
|
||||
FileUtils.rm_f(theme_dir("_layouts", "theme-symlink.html"))
|
||||
end
|
||||
|
||||
should "not read a symlink'd theme" do
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
layouts = LayoutReader.new(@site).read
|
||||
|
||||
refute layouts.key?("theme-symlink"), \
|
||||
"Should not read symlinked layout from theme"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -329,7 +329,7 @@ EOS
|
||||
%(<table class="rouge-table"><tbody>) +
|
||||
%(<tr><td class="gutter gl">) +
|
||||
%(<pre class="lineno">1\n</pre></td>) +
|
||||
%(<td class="code"><pre>test</pre></td></tr>) +
|
||||
%(<td class="code"><pre>test\n</pre></td></tr>) +
|
||||
%(</tbody></table>),
|
||||
@result
|
||||
)
|
||||
@@ -476,7 +476,7 @@ EOS
|
||||
expected = <<-EOS
|
||||
<p>This is not yet highlighted</p>\n
|
||||
<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
|
||||
</pre></td><td class="code"><pre><span class="nx">test</span></pre></td></tr></tbody></table></code></pre></figure>\n
|
||||
</pre></td><td class="code"><pre><span class="nx">test</span>\n</pre></td></tr></tbody></table></code></pre></figure>\n
|
||||
<p>This should not be highlighted, right?</p>
|
||||
EOS
|
||||
assert_match(expected, @result)
|
||||
|
||||
@@ -75,4 +75,29 @@ class TestThemeAssetsReader < JekyllUnitTest
|
||||
refute_file_with_relative_path site.pages, "assets/style.scss"
|
||||
end
|
||||
end
|
||||
|
||||
context "symlinked theme" do
|
||||
should "not read assets from symlinked theme" do
|
||||
skip_if_windows "Jekyll does not currently support symlinks on Windows."
|
||||
|
||||
begin
|
||||
tmp_dir = Dir.mktmpdir("jekyll-theme-test")
|
||||
File.open(File.join(tmp_dir, "test.txt"), "wb") { |f| f.write "content" }
|
||||
|
||||
theme_dir = File.join(__dir__, "fixtures", "test-theme-symlink")
|
||||
File.symlink(tmp_dir, File.join(theme_dir, "assets"))
|
||||
|
||||
site = fixture_site(
|
||||
"theme" => "test-theme-symlink",
|
||||
"theme-color" => "black"
|
||||
)
|
||||
ThemeAssetsReader.new(site).read
|
||||
|
||||
assert_empty site.static_files, "static file should not have been picked up"
|
||||
ensure
|
||||
FileUtils.rm_rf(tmp_dir)
|
||||
FileUtils.rm_rf(File.join(theme_dir, "assets"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user