monad 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.markdown +91 -0
- data/Gemfile +1 -1
- data/History.markdown +772 -0
- data/{README.md → README.markdown} +5 -2
- data/Rakefile +163 -1
- data/bin/monad +86 -30
- data/features/create_sites.feature +54 -25
- data/features/data.feature +65 -0
- data/features/data_sources.feature +10 -10
- data/features/drafts.feature +5 -5
- data/features/embed_filters.feature +10 -10
- data/features/include_tag.feature +48 -0
- data/features/markdown.feature +5 -5
- data/features/pagination.feature +38 -10
- data/features/permalinks.feature +31 -11
- data/features/post_data.feature +41 -41
- data/features/post_excerpts.feature +50 -0
- data/features/site_configuration.feature +47 -26
- data/features/site_data.feature +30 -24
- data/features/step_definitions/{monad_steps.rb → jekyll_steps.rb} +66 -52
- data/features/support/env.rb +27 -8
- data/lib/jekyll.rb +99 -0
- data/lib/jekyll/cleaner.rb +73 -0
- data/lib/{monad → jekyll}/command.rb +6 -6
- data/lib/{monad → jekyll}/commands/build.rb +9 -9
- data/lib/jekyll/commands/doctor.rb +67 -0
- data/lib/jekyll/commands/new.rb +67 -0
- data/lib/jekyll/commands/serve.rb +65 -0
- data/lib/{monad → jekyll}/configuration.rb +60 -18
- data/lib/{monad → jekyll}/converter.rb +1 -1
- data/lib/{monad → jekyll}/converters/identity.rb +1 -1
- data/lib/{monad → jekyll}/converters/markdown.rb +2 -2
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +29 -0
- data/lib/{monad → jekyll}/converters/markdown/maruku_parser.rb +12 -8
- data/lib/{monad → jekyll}/converters/markdown/rdiscount_parser.rb +4 -2
- data/lib/{monad → jekyll}/converters/markdown/redcarpet_parser.rb +1 -1
- data/lib/{monad → jekyll}/converters/textile.rb +1 -1
- data/lib/{monad → jekyll}/convertible.rb +39 -17
- data/lib/{monad → jekyll}/core_ext.rb +22 -4
- data/lib/jekyll/deprecator.rb +36 -0
- data/lib/{monad → jekyll}/draft.rb +1 -1
- data/lib/{monad → jekyll}/drivers/json_driver.rb +1 -1
- data/lib/{monad → jekyll}/drivers/yaml_driver.rb +1 -1
- data/lib/{monad → jekyll}/errors.rb +1 -1
- data/lib/jekyll/excerpt.rb +113 -0
- data/lib/{monad → jekyll}/filters.rb +16 -6
- data/lib/{monad → jekyll}/generator.rb +1 -1
- data/lib/jekyll/generators/pagination.rb +214 -0
- data/lib/{monad → jekyll}/layout.rb +4 -1
- data/lib/{monad → jekyll}/mime.types +0 -0
- data/lib/{monad → jekyll}/page.rb +36 -39
- data/lib/{monad → jekyll}/plugin.rb +1 -1
- data/lib/{monad → jekyll}/post.rb +58 -123
- data/lib/jekyll/related_posts.rb +59 -0
- data/lib/{monad → jekyll}/site.rb +120 -123
- data/lib/{monad → jekyll}/static_file.rb +1 -1
- data/lib/jekyll/stevenson.rb +89 -0
- data/lib/jekyll/tags/gist.rb +48 -0
- data/lib/{monad → jekyll}/tags/highlight.rb +3 -3
- data/lib/jekyll/tags/include.rb +135 -0
- data/lib/{monad → jekyll}/tags/post_url.rb +8 -6
- data/lib/jekyll/url.rb +67 -0
- data/lib/monad.rb +36 -27
- data/lib/site_template/_config.yml +2 -1
- data/lib/site_template/_layouts/default.html +21 -23
- data/lib/site_template/_layouts/post.html +1 -1
- data/lib/site_template/_posts/{0000-00-00-welcome-to-monad.markdown.erb → 0000-00-00-welcome-to-jekyll.markdown.erb} +6 -6
- data/lib/site_template/css/main.css +22 -27
- data/lib/site_template/index.html +2 -2
- data/monad.gemspec +153 -52
- data/site/.gitignore +4 -0
- data/site/CNAME +1 -0
- data/site/README +1 -0
- data/site/_config.yml +6 -0
- data/site/_includes/analytics.html +32 -0
- data/site/_includes/docs_contents.html +16 -0
- data/site/_includes/docs_contents_mobile.html +23 -0
- data/site/_includes/docs_option.html +11 -0
- data/site/_includes/docs_ul.html +20 -0
- data/site/_includes/footer.html +15 -0
- data/site/_includes/header.html +18 -0
- data/site/_includes/news_contents.html +23 -0
- data/site/_includes/news_contents_mobile.html +11 -0
- data/site/_includes/news_item.html +24 -0
- data/site/_includes/primary-nav-items.html +14 -0
- data/site/_includes/section_nav.html +22 -0
- data/site/_includes/top.html +17 -0
- data/site/_layouts/default.html +12 -0
- data/site/_layouts/docs.html +23 -0
- data/site/_layouts/news.html +19 -0
- data/site/_layouts/news_item.html +27 -0
- data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
- data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
- data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
- data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
- data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
- data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
- data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
- data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
- data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
- data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
- data/site/css/gridism.css +110 -0
- data/site/css/normalize.css +1 -0
- data/site/css/pygments.css +70 -0
- data/site/css/style.css +946 -0
- data/site/docs/configuration.md +373 -0
- data/site/docs/contributing.md +128 -0
- data/site/docs/datafiles.md +63 -0
- data/site/docs/deployment-methods.md +109 -0
- data/site/docs/drafts.md +20 -0
- data/site/docs/extras.md +56 -0
- data/site/docs/frontmatter.md +180 -0
- data/site/docs/github-pages.md +91 -0
- data/site/docs/heroku.md +9 -0
- data/site/docs/history.md +722 -0
- data/site/docs/index.md +52 -0
- data/site/docs/installation.md +76 -0
- data/site/docs/migrations.md +257 -0
- data/site/docs/pages.md +86 -0
- data/site/docs/pagination.md +211 -0
- data/site/docs/permalinks.md +180 -0
- data/site/docs/plugins.md +508 -0
- data/site/docs/posts.md +181 -0
- data/site/docs/quickstart.md +32 -0
- data/site/docs/resources.md +46 -0
- data/site/docs/sites.md +29 -0
- data/site/docs/structure.md +190 -0
- data/site/docs/templates.md +319 -0
- data/site/docs/troubleshooting.md +150 -0
- data/site/docs/upgrading.md +146 -0
- data/site/docs/usage.md +63 -0
- data/site/docs/variables.md +322 -0
- data/site/favicon.png +0 -0
- data/site/feed.xml +36 -0
- data/site/freenode.txt +1 -0
- data/site/img/article-footer.png +0 -0
- data/site/img/footer-arrow.png +0 -0
- data/site/img/footer-logo.png +0 -0
- data/site/img/logo-2x.png +0 -0
- data/site/img/octojekyll.png +0 -0
- data/site/img/tube.png +0 -0
- data/site/img/tube1x.png +0 -0
- data/site/index.html +90 -0
- data/site/js/modernizr-2.5.3.min.js +4 -0
- data/site/news/index.html +10 -0
- data/site/news/releases/index.html +10 -0
- data/test/helper.rb +6 -3
- data/test/source/+/foo.md +7 -0
- data/test/source/_data/languages.yml +2 -0
- data/test/source/_data/members.yaml +7 -0
- data/test/source/_data/products.yml +4 -0
- data/test/source/_includes/params.html +7 -0
- data/test/source/_layouts/default.html +1 -1
- data/test/source/_layouts/post/simple.html +1 -0
- data/test/source/_plugins/dummy.rb +1 -1
- data/test/source/_posts/2013-01-02-post-excerpt.markdown +1 -1
- data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
- data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
- data/test/source/deal.with.dots.html +1 -1
- data/test/source/products.yml +4 -0
- data/test/test_configuration.rb +46 -11
- data/test/test_convertible.rb +2 -2
- data/test/test_excerpt.rb +78 -0
- data/test/test_filters.rb +4 -4
- data/test/test_generated_site.rb +13 -13
- data/test/test_json_driver.rb +9 -9
- data/test/test_kramdown.rb +32 -5
- data/test/test_new_command.rb +8 -8
- data/test/test_page.rb +12 -3
- data/test/test_pager.rb +34 -33
- data/test/test_post.rb +34 -26
- data/test/test_redcloth.rb +3 -3
- data/test/test_related_posts.rb +47 -0
- data/test/test_site.rb +102 -44
- data/test/test_tags.rb +168 -23
- data/test/test_url.rb +28 -0
- data/test/test_yaml_driver.rb +6 -6
- metadata +215 -137
- data/lib/monad/commands/doctor.rb +0 -29
- data/lib/monad/commands/new.rb +0 -50
- data/lib/monad/commands/serve.rb +0 -33
- data/lib/monad/converters/markdown/kramdown_parser.rb +0 -44
- data/lib/monad/deprecator.rb +0 -32
- data/lib/monad/generators/pagination.rb +0 -143
- data/lib/monad/logger.rb +0 -54
- data/lib/monad/tags/gist.rb +0 -30
- data/lib/monad/tags/include.rb +0 -37
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Jekyll
|
|
2
|
+
class Deprecator
|
|
3
|
+
def self.process(args)
|
|
4
|
+
no_subcommand(args)
|
|
5
|
+
arg_is_present? args, "--server", "The --server command has been replaced by the \
|
|
6
|
+
'serve' subcommand."
|
|
7
|
+
arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
|
|
8
|
+
use the 'build' subcommand."
|
|
9
|
+
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'."
|
|
10
|
+
arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
|
|
11
|
+
the '--watch' switch."
|
|
12
|
+
arg_is_present? args, "--pygments", "The 'pygments' setting can only be set in \
|
|
13
|
+
your config files."
|
|
14
|
+
arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in your \
|
|
15
|
+
config files."
|
|
16
|
+
arg_is_present? args, "--url", "The 'url' setting can only be set in your config files."
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.no_subcommand(args)
|
|
20
|
+
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
|
21
|
+
Jekyll.logger.error "Deprecation:", "Jekyll now uses subcommands instead of just \
|
|
22
|
+
switches. Run `jekyll help' to find out more."
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.arg_is_present?(args, deprecated_argument, message)
|
|
27
|
+
if args.include?(deprecated_argument)
|
|
28
|
+
deprecation_message(message)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.deprecation_message(message)
|
|
33
|
+
Jekyll.logger.error "Deprecation:", message
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module Jekyll
|
|
2
|
+
class Excerpt
|
|
3
|
+
include Convertible
|
|
4
|
+
|
|
5
|
+
attr_accessor :post
|
|
6
|
+
attr_accessor :content, :output, :ext
|
|
7
|
+
|
|
8
|
+
# Initialize this Post instance.
|
|
9
|
+
#
|
|
10
|
+
# site - The Site.
|
|
11
|
+
# base - The String path to the dir containing the post file.
|
|
12
|
+
# name - The String filename of the post file.
|
|
13
|
+
#
|
|
14
|
+
# Returns the new Post.
|
|
15
|
+
def initialize(post)
|
|
16
|
+
self.post = post
|
|
17
|
+
self.content = extract_excerpt(post.content)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
%w[site name ext].each do |meth|
|
|
21
|
+
define_method(meth) do
|
|
22
|
+
post.send(meth)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_liquid
|
|
27
|
+
post.to_liquid(Post::EXCERPT_ATTRIBUTES_FOR_LIQUID)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Fetch YAML front-matter data from related post, without layout key
|
|
31
|
+
#
|
|
32
|
+
# Returns Hash of post data
|
|
33
|
+
def data
|
|
34
|
+
@data ||= post.data.dup
|
|
35
|
+
@data.delete("layout")
|
|
36
|
+
@data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# 'Path' of the excerpt.
|
|
40
|
+
#
|
|
41
|
+
# Returns the path for the post this excerpt belongs to with #excerpt appended
|
|
42
|
+
def path
|
|
43
|
+
File.join(post.path, "#excerpt")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Check if excerpt includes a string
|
|
47
|
+
#
|
|
48
|
+
# Returns true if the string passed in
|
|
49
|
+
def include?(something)
|
|
50
|
+
(self.output && self.output.include?(something)) || self.content.include?(something)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# The UID for this post (useful in feeds).
|
|
54
|
+
# e.g. /2008/11/05/my-awesome-post
|
|
55
|
+
#
|
|
56
|
+
# Returns the String UID.
|
|
57
|
+
def id
|
|
58
|
+
File.join(post.dir, post.slug, "#excerpt")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_s
|
|
62
|
+
self.output || self.content
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Returns the shorthand String identifier of this Post.
|
|
66
|
+
def inspect
|
|
67
|
+
"<Excerpt: #{self.id}>"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
protected
|
|
71
|
+
|
|
72
|
+
# Internal: Extract excerpt from the content
|
|
73
|
+
#
|
|
74
|
+
# By default excerpt is your first paragraph of a post: everything before
|
|
75
|
+
# the first two new lines:
|
|
76
|
+
#
|
|
77
|
+
# ---
|
|
78
|
+
# title: Example
|
|
79
|
+
# ---
|
|
80
|
+
#
|
|
81
|
+
# First paragraph with [link][1].
|
|
82
|
+
#
|
|
83
|
+
# Second paragraph.
|
|
84
|
+
#
|
|
85
|
+
# [1]: http://example.com/
|
|
86
|
+
#
|
|
87
|
+
# This is fairly good option for Markdown and Textile files. But might cause
|
|
88
|
+
# problems for HTML posts (which is quite unusual for Jekyll). If default
|
|
89
|
+
# excerpt delimiter is not good for you, you might want to set your own via
|
|
90
|
+
# configuration option `excerpt_separator`. For example, following is a good
|
|
91
|
+
# alternative for HTML posts:
|
|
92
|
+
#
|
|
93
|
+
# # file: _config.yml
|
|
94
|
+
# excerpt_separator: "<!-- more -->"
|
|
95
|
+
#
|
|
96
|
+
# Notice that all markdown-style link references will be appended to the
|
|
97
|
+
# excerpt. So the example post above will have this excerpt source:
|
|
98
|
+
#
|
|
99
|
+
# First paragraph with [link][1].
|
|
100
|
+
#
|
|
101
|
+
# [1]: http://example.com/
|
|
102
|
+
#
|
|
103
|
+
# Excerpts are rendered same time as content is rendered.
|
|
104
|
+
#
|
|
105
|
+
# Returns excerpt String
|
|
106
|
+
def extract_excerpt(post_content)
|
|
107
|
+
separator = site.config['excerpt_separator']
|
|
108
|
+
head, _, tail = post_content.partition(separator)
|
|
109
|
+
|
|
110
|
+
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'uri'
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module Jekyll
|
|
4
4
|
module Filters
|
|
5
5
|
# Convert a Textile string into HTML output.
|
|
6
6
|
#
|
|
@@ -9,7 +9,7 @@ module Monad
|
|
|
9
9
|
# Returns the HTML formatted String.
|
|
10
10
|
def textilize(input)
|
|
11
11
|
site = @context.registers[:site]
|
|
12
|
-
converter = site.getConverterImpl(
|
|
12
|
+
converter = site.getConverterImpl(Jekyll::Converters::Textile)
|
|
13
13
|
converter.convert(input)
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ module Monad
|
|
|
20
20
|
# Returns the HTML formatted String.
|
|
21
21
|
def markdownify(input)
|
|
22
22
|
site = @context.registers[:site]
|
|
23
|
-
converter = site.getConverterImpl(
|
|
23
|
+
converter = site.getConverterImpl(Jekyll::Converters::Markdown)
|
|
24
24
|
converter.convert(input)
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -99,7 +99,17 @@ module Monad
|
|
|
99
99
|
def cgi_escape(input)
|
|
100
100
|
CGI::escape(input)
|
|
101
101
|
end
|
|
102
|
-
|
|
102
|
+
|
|
103
|
+
# URI escape a string.
|
|
104
|
+
#
|
|
105
|
+
# input - The String to escape.
|
|
106
|
+
#
|
|
107
|
+
# Examples
|
|
108
|
+
#
|
|
109
|
+
# uri_escape('foo, bar \\baz?')
|
|
110
|
+
# # => "foo,%20bar%20%5Cbaz?"
|
|
111
|
+
#
|
|
112
|
+
# Returns the escaped String.
|
|
103
113
|
def uri_escape(input)
|
|
104
114
|
URI.escape(input)
|
|
105
115
|
end
|
|
@@ -140,7 +150,7 @@ module Monad
|
|
|
140
150
|
|
|
141
151
|
# Convert the input into json string
|
|
142
152
|
#
|
|
143
|
-
# input - The Array
|
|
153
|
+
# input - The Array or Hash to be converted
|
|
144
154
|
#
|
|
145
155
|
# Returns the converted json string
|
|
146
156
|
def json(input)
|
|
@@ -155,7 +165,7 @@ module Monad
|
|
|
155
165
|
when String
|
|
156
166
|
Time.parse(input)
|
|
157
167
|
else
|
|
158
|
-
|
|
168
|
+
Jekyll.logger.error "Invalid Date:", "'#{input}' is not a valid datetime."
|
|
159
169
|
exit(1)
|
|
160
170
|
end
|
|
161
171
|
end
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
module Jekyll
|
|
2
|
+
module Generators
|
|
3
|
+
class Pagination < Generator
|
|
4
|
+
# This generator is safe from arbitrary code execution.
|
|
5
|
+
safe true
|
|
6
|
+
|
|
7
|
+
# Generate paginated pages if necessary.
|
|
8
|
+
#
|
|
9
|
+
# site - The Site.
|
|
10
|
+
#
|
|
11
|
+
# Returns nothing.
|
|
12
|
+
def generate(site)
|
|
13
|
+
if Pager.pagination_enabled?(site)
|
|
14
|
+
if template = template_page(site)
|
|
15
|
+
paginate(site, template)
|
|
16
|
+
else
|
|
17
|
+
Jekyll.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find" +
|
|
18
|
+
"an index.html page to use as the pagination template. Skipping pagination."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Paginates the blog's posts. Renders the index.html file into paginated
|
|
24
|
+
# directories, e.g.: page2/index.html, page3/index.html, etc and adds more
|
|
25
|
+
# site-wide data.
|
|
26
|
+
#
|
|
27
|
+
# site - The Site.
|
|
28
|
+
# page - The index.html Page that requires pagination.
|
|
29
|
+
#
|
|
30
|
+
# {"paginator" => { "page" => <Number>,
|
|
31
|
+
# "per_page" => <Number>,
|
|
32
|
+
# "posts" => [<Post>],
|
|
33
|
+
# "total_posts" => <Number>,
|
|
34
|
+
# "total_pages" => <Number>,
|
|
35
|
+
# "previous_page" => <Number>,
|
|
36
|
+
# "next_page" => <Number> }}
|
|
37
|
+
def paginate(site, page)
|
|
38
|
+
all_posts = site.site_payload['site']['posts']
|
|
39
|
+
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
|
|
40
|
+
(1..pages).each do |num_page|
|
|
41
|
+
pager = Pager.new(site, num_page, all_posts, pages)
|
|
42
|
+
if num_page > 1
|
|
43
|
+
newpage = Page.new(site, site.source, page.dir, page.name)
|
|
44
|
+
newpage.pager = pager
|
|
45
|
+
newpage.dir = Pager.paginate_path(site, num_page)
|
|
46
|
+
site.pages << newpage
|
|
47
|
+
else
|
|
48
|
+
page.pager = pager
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Static: Fetch the URL of the template page. Used to determine the
|
|
54
|
+
# path to the first pager in the series.
|
|
55
|
+
#
|
|
56
|
+
# site - the Jekyll::Site object
|
|
57
|
+
#
|
|
58
|
+
# Returns the url of the template page
|
|
59
|
+
def self.first_page_url(site)
|
|
60
|
+
if page = Pagination.new.template_page(site)
|
|
61
|
+
page.url
|
|
62
|
+
else
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Public: Find the Jekyll::Page which will act as the pager template
|
|
68
|
+
#
|
|
69
|
+
# site - the Jekyll::Site object
|
|
70
|
+
#
|
|
71
|
+
# Returns the Jekyll::Page which will act as the pager template
|
|
72
|
+
def template_page(site)
|
|
73
|
+
site.pages.dup.select do |page|
|
|
74
|
+
Pager.pagination_candidate?(site.config, page)
|
|
75
|
+
end.sort do |one, two|
|
|
76
|
+
two.path.size <=> one.path.size
|
|
77
|
+
end.first
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class Pager
|
|
83
|
+
attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
|
|
84
|
+
:previous_page, :previous_page_path, :next_page, :next_page_path
|
|
85
|
+
|
|
86
|
+
# Calculate the number of pages.
|
|
87
|
+
#
|
|
88
|
+
# all_posts - The Array of all Posts.
|
|
89
|
+
# per_page - The Integer of entries per page.
|
|
90
|
+
#
|
|
91
|
+
# Returns the Integer number of pages.
|
|
92
|
+
def self.calculate_pages(all_posts, per_page)
|
|
93
|
+
(all_posts.size.to_f / per_page.to_i).ceil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Determine if pagination is enabled the site.
|
|
97
|
+
#
|
|
98
|
+
# site - the Jekyll::Site object
|
|
99
|
+
#
|
|
100
|
+
# Returns true if pagination is enabled, false otherwise.
|
|
101
|
+
def self.pagination_enabled?(site)
|
|
102
|
+
!site.config['paginate'].nil? &&
|
|
103
|
+
site.pages.size > 0
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Static: Determine if a page is a possible candidate to be a template page.
|
|
107
|
+
# Page's name must be `index.html` and exist in any of the directories
|
|
108
|
+
# between the site source and `paginate_path`.
|
|
109
|
+
#
|
|
110
|
+
# config - the site configuration hash
|
|
111
|
+
# page - the Jekyll::Page about which we're inquiring
|
|
112
|
+
#
|
|
113
|
+
# Returns true if the
|
|
114
|
+
def self.pagination_candidate?(config, page)
|
|
115
|
+
page_dir = File.dirname(File.expand_path(remove_leading_slash(page.path), config['source']))
|
|
116
|
+
paginate_path = remove_leading_slash(config['paginate_path'])
|
|
117
|
+
paginate_path = File.expand_path(paginate_path, config['source'])
|
|
118
|
+
page.name == 'index.html' &&
|
|
119
|
+
in_hierarchy(config['source'], page_dir, File.dirname(paginate_path))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Determine if the subdirectories of the two paths are the same relative to source
|
|
123
|
+
#
|
|
124
|
+
# source - the site source
|
|
125
|
+
# page_dir - the directory of the Jekyll::Page
|
|
126
|
+
# paginate_path - the absolute paginate path (from root of FS)
|
|
127
|
+
#
|
|
128
|
+
# Returns whether the subdirectories are the same relative to source
|
|
129
|
+
def self.in_hierarchy(source, page_dir, paginate_path)
|
|
130
|
+
return false if paginate_path == File.dirname(paginate_path)
|
|
131
|
+
return false if paginate_path == Pathname.new(source).parent
|
|
132
|
+
page_dir == paginate_path ||
|
|
133
|
+
in_hierarchy(source, page_dir, File.dirname(paginate_path))
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Static: Return the pagination path of the page
|
|
137
|
+
#
|
|
138
|
+
# site - the Jekyll::Site object
|
|
139
|
+
# num_page - the pagination page number
|
|
140
|
+
#
|
|
141
|
+
# Returns the pagination path as a string
|
|
142
|
+
def self.paginate_path(site, num_page)
|
|
143
|
+
return nil if num_page.nil?
|
|
144
|
+
return Generators::Pagination.first_page_url(site) if num_page <= 1
|
|
145
|
+
format = site.config['paginate_path']
|
|
146
|
+
format = format.sub(':num', num_page.to_s)
|
|
147
|
+
ensure_leading_slash(format)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Static: Return a String version of the input which has a leading slash.
|
|
151
|
+
# If the input already has a forward slash in position zero, it will be
|
|
152
|
+
# returned unchanged.
|
|
153
|
+
#
|
|
154
|
+
# path - a String path
|
|
155
|
+
#
|
|
156
|
+
# Returns the path with a leading slash
|
|
157
|
+
def self.ensure_leading_slash(path)
|
|
158
|
+
path[0..0] == "/" ? path : "/#{path}"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Static: Return a String version of the input without a leading slash.
|
|
162
|
+
#
|
|
163
|
+
# path - a String path
|
|
164
|
+
#
|
|
165
|
+
# Returns the input without the leading slash
|
|
166
|
+
def self.remove_leading_slash(path)
|
|
167
|
+
ensure_leading_slash(path)[1..-1]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Initialize a new Pager.
|
|
171
|
+
#
|
|
172
|
+
# site - the Jekyll::Site object
|
|
173
|
+
# page - The Integer page number.
|
|
174
|
+
# all_posts - The Array of all the site's Posts.
|
|
175
|
+
# num_pages - The Integer number of pages or nil if you'd like the number
|
|
176
|
+
# of pages calculated.
|
|
177
|
+
def initialize(site, page, all_posts, num_pages = nil)
|
|
178
|
+
@page = page
|
|
179
|
+
@per_page = site.config['paginate'].to_i
|
|
180
|
+
@total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
|
|
181
|
+
|
|
182
|
+
if @page > @total_pages
|
|
183
|
+
raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
init = (@page - 1) * @per_page
|
|
187
|
+
offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
|
|
188
|
+
|
|
189
|
+
@total_posts = all_posts.size
|
|
190
|
+
@posts = all_posts[init..offset]
|
|
191
|
+
@previous_page = @page != 1 ? @page - 1 : nil
|
|
192
|
+
@previous_page_path = Pager.paginate_path(site, @previous_page)
|
|
193
|
+
@next_page = @page != @total_pages ? @page + 1 : nil
|
|
194
|
+
@next_page_path = Pager.paginate_path(site, @next_page)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Convert this Pager's data to a Hash suitable for use by Liquid.
|
|
198
|
+
#
|
|
199
|
+
# Returns the Hash representation of this Pager.
|
|
200
|
+
def to_liquid
|
|
201
|
+
{
|
|
202
|
+
'page' => page,
|
|
203
|
+
'per_page' => per_page,
|
|
204
|
+
'posts' => posts,
|
|
205
|
+
'total_posts' => total_posts,
|
|
206
|
+
'total_pages' => total_pages,
|
|
207
|
+
'previous_page' => previous_page,
|
|
208
|
+
'previous_page_path' => previous_page_path,
|
|
209
|
+
'next_page' => next_page,
|
|
210
|
+
'next_page_path' => next_page_path
|
|
211
|
+
}
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|