Compare commits

...

65 Commits

Author SHA1 Message Date
Parker Moore
8fe3a5d59b Release 💎 3.9.0 2020-08-05 14:48:04 -04:00
Parker Moore
331361aee6 Update jekyll 3.9.0 release post 2020-08-05 14:28:18 -04:00
Parker Moore
8681d67d76 Update history.markdown 2020-08-05 14:25:22 -04:00
Parker Moore
917c7b13ad [3.x] Add default language for kramdown syntax highlighting (#8325)
Merge pull request 8325
2020-08-05 14:19:26 -04:00
Parker Moore
a6e21936a5 [3.x] Add 3.9.0 release post (#8323)
Merge pull request 8323
2020-08-05 14:16:49 -04:00
Parker Moore
f98b2492fc Merge pull request #8322 from jekyll/3.9-kramdown-v2-upgrade
[3.x] kramdown v2 upgrade
2020-08-05 11:33:35 -04:00
Parker Moore
071913e350 Require kramdown-parser-gfm gracefully.
Co-authored-by: Ashwin Maroli <ashmaroli@users.noreply.github.com>
2020-08-05 10:49:56 -04:00
Frank Taillandier
82fc6ba01c Update features/collections.feature
Co-authored-by: Ashwin Maroli <ashmaroli@users.noreply.github.com>
2020-08-05 13:26:21 +02:00
Parker Moore
0ac94d7766 Rewrite kramdown and rouge versions in script/default-site 2020-08-04 11:46:35 -04:00
Parker Moore
5a2f8d7279 Skip this scenario when using Kramdown v1 since it doesn't support guess_lang 2020-08-04 10:59:35 -04:00
Ashwin Maroli
382002ae42 Rouge 1.x doesn't render a div wrapper 2020-08-04 13:02:53 +05:30
Parker Moore
5b90cecbc9 'jekyll new' should add kramdown-parser-gfm to its gemfile 2020-08-03 17:39:19 -04:00
Ashwin Maroli
9bfd37570b Update unit tests for Kramdown-based converter (#8014)
Merge pull request 8014

Co-authored-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 17:29:15 -04:00
Parker Moore
cbde121dc4 Don't bundle kramdown-parser-gfm by default. 2020-08-03 17:01:19 -04:00
Parker Moore
5db0b067be Fix rubocop offenses 2020-08-03 16:53:32 -04:00
Parker Moore
ae1d7c5aa2 By default, the kramdown version will be 2.x, so add the other gems by default in that case 2020-08-03 16:53:25 -04:00
Parker Moore
687785a00d Allow kramdown v1.17 and v2 and up. 2020-08-03 16:29:36 -04:00
Parker Moore
ac7b264112 Test on Ruby 2.5 and up, only 2020-08-03 16:04:21 -04:00
Ashwin Maroli
7683292976 mathjax engine is still bundled within kramdown
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:49:53 -04:00
Ashwin Maroli
24515914b4 Require at least kramdown-2.1
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:49:53 -04:00
Ashwin Maroli
d276dc2698 Appease RuboCop
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:46:52 -04:00
Ashwin Maroli
262d950b27 Add "kramdown-syntax-coderay" to Gemfile
gem "coderay" is a dependency of "kramdown-syntax-coderay". So there's no
need to list it separately

Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:46:52 -04:00
Ashwin Maroli
2ca200bc2d Remove kramdown listing from Gemfile
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:46:26 -04:00
Ashwin Maroli
56862cac6c load kramdown extensions based on configuration
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:46:06 -04:00
Ashwin Maroli
82128692f5 Add 'kramdown-parser-gfm' as a runtime dependency
Since we default `kramdown.input` config to "GFM"

Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:43:54 -04:00
Ashwin Maroli
fbc79f6605 Bump kramdown to v2.0
Signed-off-by: Parker Moore <parkrmoore@gmail.com>
2020-08-03 13:43:21 -04:00
Frank Taillandier
e894f830fa Release 💎 3.8.7 2020-05-08 16:55:07 +02:00
Frank Taillandier
51a65754bf chore(release): v3.8.7 💎
- Prevent console warnings with Ruby 2.7 (#8125)
2020-05-08 16:54:47 +02:00
Ashwin Maroli
ce68268aaa Update history to reflect merge of #8125 [ci skip] 2020-04-16 22:39:11 +05:30
Ashwin Maroli
9e4b4f2bd1 Backport #7948 for v3.8.x (#8125)
Attain Ruby 3.0 compatibility
This backports 389eb88 to 3.8-stable

Additionally backports 51d1366 for v3.8.x

Includes additional changes to appease RuboCop
Includes additional changes to CI configs
2020-04-16 22:33:17 +05:30
Parker Moore
7ff9a885b8 Release 💎 3.8.6 2019-07-02 16:53:35 -04:00
Parker Moore
5c4e125dad 3.8.6: add release note for 3c06609406 2019-07-02 16:52:01 -04:00
Frank Taillandier
cc5c850a03 Fix year 2019-07-02 21:37:14 +02:00
Frank Taillandier
72d853779f Update release date 2019-07-02 21:31:54 +02:00
Parker Moore
c945c48b79 Merge pull request #7735 from jekyll/3-8-6-release-notes
Create 3.8.6 release notes
2019-07-02 11:50:49 -04:00
Parker Moore
27e1433ee0 Create 3.8.6 release notes 2019-07-02 11:27:02 -04:00
Ashwin Maroli
9c574f779f Backport #7679 for v3.8.x (#7734)
Update log output for an invalid theme directory
2019-07-02 00:53:44 +05:30
Parker Moore
47b67f1222 Add all backports since 3.8.5 2019-06-27 11:50:41 -04:00
Ashwin Maroli
b8d5a04b57 Backport #7697 for v3.8.x (#7722)
Memoize SiteDrop#documents to reduce allocations
2019-06-27 00:25:10 +05:30
Ashwin Maroli
8701fdbc29 Backport #7709 to 3.8-stable branch
Update TestTags in sync with Rouge v3.4 (#7709)
2019-06-26 12:30:11 +05:30
Ashwin Maroli
f29c72e0b9 Backport #7213 and #7633 for v3.8.x (#7690)
Merge pull request 7690
2019-06-05 08:45:58 -04:00
Ashwin Maroli
fbeadab63f Backport #7684 for v3.8.x (#7689)
Merge pull request 7689
2019-05-31 11:31:45 -04:00
Ashwin Maroli
3c06609406 Install platform-specific gems as required 2019-03-18 11:25:31 +05:30
Ashwin Maroli
f3b6877a39 Backport regex-escape-site-path from #7568 to 3.8-stable (#7573) 2019-03-17 11:40:46 +05:30
Ashwin Maroli
c2dff2cd15 Fix CI builds on older Ruby versions (#7567)
* Fix CI builds on older Ruby versions
* Use Bundler available by default
* Remove deprecated Travis configuration
2019-03-13 22:59:13 +05:30
Parker Moore
cb11099394 Merge pull request #7467 from jekyll/3.8-stable-backport-7382
Backport #7382 for v3.8.x: Excerpt handling of custom and intermediate tags
2019-03-13 10:46:22 -04:00
Parker Moore
17efa2a485 Merge pull request #7424 from jekyll/3.8-stable-backport-7419
Backport #7419 for v3.8.x: Theme gems: ensure directories aren't symlinks
2019-03-13 10:18:07 -04:00
Kyle Barbour
02133f4e1f Backport excerpt-liquid from 7382 to 3.8-stable 2019-01-07 17:10:22 +05:30
Ashwin Maroli
77208fac2c Merge branch '3.8-stable' into 3.8-stable-backport-7419 2018-12-18 22:51:17 +05:30
Ashwin Maroli
f157093ab3 Backport c368fec to 3.8-stable
Create symlink only if target is accessible (#7429)
2018-12-18 22:47:46 +05:30
Parker Moore
a395dfe27c Skip theme dir symlink test if Windows. 2018-12-17 16:34:39 -05:00
Ashwin Maroli
889af57f03 Merge branch '3.8-stable' into this branch 2018-12-15 00:22:56 +05:30
Ashwin Maroli
b5772dc787 Backport e41c427 to 3.8-stable
CI: Build stable branches during backport
2018-12-15 00:03:59 +05:30
olivia hugger
21d8def9ed Backport 564f773 to 3.8-stable
test for stable and backport branches on travis
2018-12-14 23:35:16 +05:30
Parker Moore
f15804423e Fix linting issue with lines being too long. 2018-12-14 10:31:08 -05:00
Parker Moore
511ea72d05 Backport ensure-realpath-for-theme-dirs-is-in-theme-dir from #7419 to 3.8-stable 2018-12-14 10:12:56 -05:00
olivia
41c82448ae Release 💎 3.8.5 2018-11-04 21:19:54 +01:00
olivia
ee35322193 Prepare 3.8.5 release 2018-11-04 21:17:46 +01:00
olivia hugger
a7e8f08bea Merge pull request #7352 from jekyll/3.8-backport-7250
Backport #7250 to 3.8.x
2018-11-04 20:54:58 +01:00
Frank Taillandier
a4171db345 style: Metrics/LineLength 2018-11-04 20:52:35 +01:00
Frank Taillandier
aedb403afd style: fix offenses 2018-11-04 20:45:28 +01:00
Ashwin Maroli
924ca62bd2 Re-implement handling Liquid blocks in excerpts (#7250)
Merge pull request 7250
2018-11-04 20:08:01 +01:00
Frank Taillandier
cc52cac81a Release 💎 3.8.4 2018-09-18 23:50:26 +02:00
Frank Taillandier
91abe9f741 Release 💎 3.8.4 2018-09-18 23:49:03 +02:00
Parker Moore
d9a2758ff6 3.8.x: security: fix include bypass of EntryFilter#filter symlink check (#7228)
Merge pull request 7228
2018-09-18 12:24:15 -04:00
48 changed files with 753 additions and 128 deletions

View File

@@ -53,6 +53,8 @@ Layout/EmptyComment:
Enabled: false
Layout/EndAlignment:
Severity: error
Lint/SplatKeywordArguments:
Enabled: false
Lint/UnreachableCode:
Severity: error
Lint/UselessAccessModifier:

View File

@@ -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
View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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}

View 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!

View 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!

View File

@@ -1 +1 @@
3.8.3
3.9.0

View File

@@ -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 }}"

View 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"

View File

@@ -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 }}"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,
},

View File

@@ -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]

View File

@@ -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))

View File

@@ -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))

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Jekyll
VERSION = "3.8.3".freeze
VERSION = "3.9.0".freeze
end

View File

@@ -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
View 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

View 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>

View File

@@ -0,0 +1,5 @@
---
layout: default
---
Message: {{ content }}

View 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

View 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

View File

@@ -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

View 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)

View File

@@ -2,10 +2,23 @@
layout: post
---
{% if
page.layout == "post" %}
Youll 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.

View File

@@ -2,10 +2,20 @@
layout: post
---
{% if page.layout == "post" %}
Youll 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.

View 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 %}

View File

@@ -0,0 +1 @@
/etc/passwd

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>(&#8220;|“)Pit(&#8217;|)hy(&#8221;|”)<\/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>(&#171;|«)Pit(&#8250;|)hy(&#187;|»)<\/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

View File

@@ -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

View File

@@ -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)

View File

@@ -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