tigefa 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.markdown +91 -0
  3. data/Gemfile +2 -0
  4. data/History.markdown +871 -0
  5. data/LICENSE +15 -14
  6. data/README.markdown +59 -0
  7. data/Rakefile +298 -0
  8. data/bin/tigefa +158 -0
  9. data/cucumber.yml +3 -0
  10. data/features/create_sites.feature +141 -0
  11. data/features/data.feature +65 -0
  12. data/features/drafts.feature +25 -0
  13. data/features/embed_filters.feature +60 -0
  14. data/features/include_tag.feature +57 -0
  15. data/features/markdown.feature +67 -0
  16. data/features/pagination.feature +82 -0
  17. data/features/permalinks.feature +85 -0
  18. data/features/post_data.feature +214 -0
  19. data/features/post_excerpts.feature +50 -0
  20. data/features/site_configuration.feature +235 -0
  21. data/features/site_data.feature +107 -0
  22. data/features/step_definitions/tigefa_steps.rb +189 -0
  23. data/features/support/env.rb +75 -0
  24. data/lib/site_template/.gitignore +1 -0
  25. data/lib/site_template/_config.yml +3 -0
  26. data/lib/site_template/_layouts/default.html +44 -0
  27. data/lib/site_template/_layouts/post.html +9 -0
  28. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +24 -0
  29. data/lib/site_template/css/main.css +160 -0
  30. data/lib/site_template/css/syntax.css +60 -0
  31. data/lib/site_template/index.html +13 -0
  32. data/lib/tigefa/cleaner.rb +73 -0
  33. data/lib/tigefa/command.rb +27 -0
  34. data/lib/tigefa/commands/build.rb +70 -0
  35. data/lib/tigefa/commands/doctor.rb +67 -0
  36. data/lib/tigefa/commands/new.rb +67 -0
  37. data/lib/tigefa/commands/serve.rb +65 -0
  38. data/lib/tigefa/configuration.rb +238 -0
  39. data/lib/tigefa/converter.rb +48 -0
  40. data/lib/tigefa/converters/identity.rb +21 -0
  41. data/lib/tigefa/converters/markdown/kramdown_parser.rb +29 -0
  42. data/lib/tigefa/converters/markdown/maruku_parser.rb +56 -0
  43. data/lib/tigefa/converters/markdown/rdiscount_parser.rb +37 -0
  44. data/lib/tigefa/converters/markdown/redcarpet_parser.rb +70 -0
  45. data/lib/tigefa/converters/markdown.rb +43 -0
  46. data/lib/tigefa/converters/textile.rb +50 -0
  47. data/lib/tigefa/convertible.rb +174 -0
  48. data/lib/tigefa/core_ext.rb +90 -0
  49. data/lib/tigefa/deprecator.rb +36 -0
  50. data/lib/tigefa/draft.rb +35 -0
  51. data/lib/tigefa/entry_filter.rb +35 -0
  52. data/lib/tigefa/errors.rb +4 -0
  53. data/lib/tigefa/excerpt.rb +113 -0
  54. data/lib/tigefa/filters.rb +174 -0
  55. data/lib/tigefa/generator.rb +4 -0
  56. data/lib/tigefa/generators/pagination.rb +217 -0
  57. data/lib/tigefa/layout.rb +45 -0
  58. data/lib/tigefa/mime.types +85 -0
  59. data/lib/tigefa/page.rb +160 -0
  60. data/lib/tigefa/plugin.rb +75 -0
  61. data/lib/tigefa/post.rb +312 -0
  62. data/lib/tigefa/related_posts.rb +59 -0
  63. data/lib/tigefa/site.rb +427 -0
  64. data/lib/tigefa/static_file.rb +70 -0
  65. data/lib/tigefa/stevenson.rb +89 -0
  66. data/lib/tigefa/tags/gist.rb +48 -0
  67. data/lib/tigefa/tags/highlight.rb +85 -0
  68. data/lib/tigefa/tags/include.rb +134 -0
  69. data/lib/tigefa/tags/post_url.rb +63 -0
  70. data/lib/tigefa/url.rb +69 -0
  71. data/lib/tigefa.rb +98 -4
  72. data/script/bootstrap +2 -0
  73. data/site/.gitignore +4 -0
  74. data/site/CNAME +1 -0
  75. data/site/README +1 -0
  76. data/site/_config.yml +6 -0
  77. data/site/_includes/analytics.html +32 -0
  78. data/site/_includes/docs_contents.html +16 -0
  79. data/site/_includes/docs_contents_mobile.html +23 -0
  80. data/site/_includes/docs_option.html +11 -0
  81. data/site/_includes/docs_ul.html +20 -0
  82. data/site/_includes/footer.html +15 -0
  83. data/site/_includes/header.html +18 -0
  84. data/site/_includes/news_contents.html +23 -0
  85. data/site/_includes/news_contents_mobile.html +11 -0
  86. data/site/_includes/news_item.html +24 -0
  87. data/site/_includes/primary-nav-items.html +14 -0
  88. data/site/_includes/section_nav.html +22 -0
  89. data/site/_includes/top.html +17 -0
  90. data/site/_layouts/default.html +12 -0
  91. data/site/_layouts/docs.html +23 -0
  92. data/site/_layouts/news.html +19 -0
  93. data/site/_layouts/news_item.html +27 -0
  94. data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
  95. data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
  96. data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
  97. data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
  98. data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
  99. data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
  100. data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
  101. data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
  102. data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
  103. data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
  104. data/site/_posts/2013-10-28-jekyll-1-3-0-rc1-released.markdown +19 -0
  105. data/site/_posts/2013-11-04-jekyll-1-3-0-released.markdown +43 -0
  106. data/site/_posts/2013-11-26-jekyll-1-3-1-released.markdown +21 -0
  107. data/site/_posts/2013-12-07-jekyll-1-4-0-released.markdown +30 -0
  108. data/site/_posts/2013-12-16-jekyll-1-4-2-released.markdown +18 -0
  109. data/site/_posts/2014-01-13-jekyll-1-4-3-released.markdown +27 -0
  110. data/site/css/gridism.css +110 -0
  111. data/site/css/normalize.css +1 -0
  112. data/site/css/pygments.css +70 -0
  113. data/site/css/style.css +946 -0
  114. data/site/docs/configuration.md +375 -0
  115. data/site/docs/contributing.md +128 -0
  116. data/site/docs/datafiles.md +63 -0
  117. data/site/docs/deployment-methods.md +109 -0
  118. data/site/docs/drafts.md +21 -0
  119. data/site/docs/extras.md +56 -0
  120. data/site/docs/frontmatter.md +180 -0
  121. data/site/docs/github-pages.md +91 -0
  122. data/site/docs/heroku.md +9 -0
  123. data/site/docs/history.md +866 -0
  124. data/site/docs/index.md +52 -0
  125. data/site/docs/installation.md +76 -0
  126. data/site/docs/migrations.md +11 -0
  127. data/site/docs/pages.md +86 -0
  128. data/site/docs/pagination.md +211 -0
  129. data/site/docs/permalinks.md +180 -0
  130. data/site/docs/plugins.md +534 -0
  131. data/site/docs/posts.md +181 -0
  132. data/site/docs/quickstart.md +32 -0
  133. data/site/docs/resources.md +46 -0
  134. data/site/docs/sites.md +29 -0
  135. data/site/docs/structure.md +190 -0
  136. data/site/docs/templates.md +339 -0
  137. data/site/docs/troubleshooting.md +150 -0
  138. data/site/docs/upgrading.md +146 -0
  139. data/site/docs/usage.md +63 -0
  140. data/site/docs/variables.md +322 -0
  141. data/site/favicon.png +0 -0
  142. data/site/feed.xml +36 -0
  143. data/site/freenode.txt +1 -0
  144. data/site/img/article-footer.png +0 -0
  145. data/site/img/footer-arrow.png +0 -0
  146. data/site/img/footer-logo.png +0 -0
  147. data/site/img/logo-2x.png +0 -0
  148. data/site/img/octojekyll.png +0 -0
  149. data/site/img/tube.png +0 -0
  150. data/site/img/tube1x.png +0 -0
  151. data/site/index.html +90 -0
  152. data/site/js/modernizr-2.5.3.min.js +4 -0
  153. data/site/news/index.html +10 -0
  154. data/site/news/releases/index.html +10 -0
  155. data/test/fixtures/broken_front_matter1.erb +5 -0
  156. data/test/fixtures/broken_front_matter2.erb +4 -0
  157. data/test/fixtures/broken_front_matter3.erb +7 -0
  158. data/test/fixtures/exploit_front_matter.erb +4 -0
  159. data/test/fixtures/front_matter.erb +4 -0
  160. data/test/helper.rb +65 -0
  161. data/test/source/+/foo.md +7 -0
  162. data/test/source/.htaccess +8 -0
  163. data/test/source/_config.dev.toml +2 -0
  164. data/test/source/_data/languages.yml +2 -0
  165. data/test/source/_data/members.yaml +7 -0
  166. data/test/source/_data/products.yml +1 -0
  167. data/test/source/_includes/params.html +7 -0
  168. data/test/source/_includes/sig.markdown +3 -0
  169. data/test/source/_includes/tmp +1 -0
  170. data/test/source/_layouts/default.html +27 -0
  171. data/test/source/_layouts/post/simple.html +1 -0
  172. data/test/source/_layouts/simple.html +1 -0
  173. data/test/source/_plugins/dummy.rb +8 -0
  174. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  175. data/test/source/_posts/2008-02-02-published.textile +8 -0
  176. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  177. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  178. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  179. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  180. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  181. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  182. data/test/source/_posts/2009-01-27-category.textile +7 -0
  183. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  184. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  185. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  186. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  187. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  188. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  189. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  190. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  191. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  192. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  193. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  194. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  195. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  196. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  197. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  198. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  199. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  200. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  201. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  202. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  203. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  204. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  205. data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
  206. data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
  207. data/test/source/_posts/2014-01-06-permalink-traversal.md +5 -0
  208. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  209. data/test/source/about.html +6 -0
  210. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  211. data/test/source/contacts/bar.html +5 -0
  212. data/test/source/contacts/index.html +5 -0
  213. data/test/source/contacts.html +5 -0
  214. data/test/source/css/screen.css +76 -0
  215. data/test/source/deal.with.dots.html +7 -0
  216. data/test/source/exploit.md +5 -0
  217. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  218. data/test/source/index.html +22 -0
  219. data/test/source/products.yml +4 -0
  220. data/test/source/sitemap.xml +32 -0
  221. data/test/source/symlink-test/_data +1 -0
  222. data/test/source/symlink-test/symlinked-dir +1 -0
  223. data/test/source/symlink-test/symlinked-file +1 -0
  224. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  225. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  226. data/test/suite.rb +11 -0
  227. data/test/test_command.rb +39 -0
  228. data/test/test_configuration.rb +181 -0
  229. data/test/test_convertible.rb +51 -0
  230. data/test/test_core_ext.rb +88 -0
  231. data/test/test_entry_filter.rb +74 -0
  232. data/test/test_excerpt.rb +78 -0
  233. data/test/test_filters.rb +113 -0
  234. data/test/test_generated_site.rb +83 -0
  235. data/test/test_kramdown.rb +62 -0
  236. data/test/test_new_command.rb +104 -0
  237. data/test/test_page.rb +212 -0
  238. data/test/test_pager.rb +116 -0
  239. data/test/test_post.rb +592 -0
  240. data/test/test_rdiscount.rb +22 -0
  241. data/test/test_redcarpet.rb +61 -0
  242. data/test/test_redcloth.rb +86 -0
  243. data/test/test_related_posts.rb +47 -0
  244. data/test/test_site.rb +333 -0
  245. data/test/test_tags.rb +490 -0
  246. data/test/test_url.rb +28 -0
  247. data/tigefa.gemspec +306 -0
  248. metadata +575 -45
  249. data/README.md +0 -4
@@ -0,0 +1,174 @@
1
+ require 'uri'
2
+ require 'json'
3
+
4
+ module TigefaTigefa
5
+ module Filters
6
+ # Convert a Textile string into HTML output.
7
+ #
8
+ # input - The Textile String to convert.
9
+ #
10
+ # Returns the HTML formatted String.
11
+ def textilize(input)
12
+ site = @context.registers[:site]
13
+ converter = site.getConverterImpl(TigefaTigefa::Converters::Textile)
14
+ converter.convert(input)
15
+ end
16
+
17
+ # Convert a Markdown string into HTML output.
18
+ #
19
+ # input - The Markdown String to convert.
20
+ #
21
+ # Returns the HTML formatted String.
22
+ def markdownify(input)
23
+ site = @context.registers[:site]
24
+ converter = site.getConverterImpl(TigefaTigefa::Converters::Markdown)
25
+ converter.convert(input)
26
+ end
27
+
28
+ # Format a date in short format e.g. "27 Jan 2011".
29
+ #
30
+ # date - the Time to format.
31
+ #
32
+ # Returns the formatting String.
33
+ def date_to_string(date)
34
+ time(date).strftime("%d %b %Y")
35
+ end
36
+
37
+ # Format a date in long format e.g. "27 January 2011".
38
+ #
39
+ # date - The Time to format.
40
+ #
41
+ # Returns the formatted String.
42
+ def date_to_long_string(date)
43
+ time(date).strftime("%d %B %Y")
44
+ end
45
+
46
+ # Format a date for use in XML.
47
+ #
48
+ # date - The Time to format.
49
+ #
50
+ # Examples
51
+ #
52
+ # date_to_xmlschema(Time.now)
53
+ # # => "2011-04-24T20:34:46+08:00"
54
+ #
55
+ # Returns the formatted String.
56
+ def date_to_xmlschema(date)
57
+ time(date).xmlschema
58
+ end
59
+
60
+ # Format a date according to RFC-822
61
+ #
62
+ # date - The Time to format.
63
+ #
64
+ # Examples
65
+ #
66
+ # date_to_rfc822(Time.now)
67
+ # # => "Sun, 24 Apr 2011 12:34:46 +0000"
68
+ #
69
+ # Returns the formatted String.
70
+ def date_to_rfc822(date)
71
+ time(date).rfc822
72
+ end
73
+
74
+ # XML escape a string for use. Replaces any special characters with
75
+ # appropriate HTML entity replacements.
76
+ #
77
+ # input - The String to escape.
78
+ #
79
+ # Examples
80
+ #
81
+ # xml_escape('foo "bar" <baz>')
82
+ # # => "foo &quot;bar&quot; &lt;baz&gt;"
83
+ #
84
+ # Returns the escaped String.
85
+ def xml_escape(input)
86
+ CGI.escapeHTML(input)
87
+ end
88
+
89
+ # CGI escape a string for use in a URL. Replaces any special characters
90
+ # with appropriate %XX replacements.
91
+ #
92
+ # input - The String to escape.
93
+ #
94
+ # Examples
95
+ #
96
+ # cgi_escape('foo,bar;baz?')
97
+ # # => "foo%2Cbar%3Bbaz%3F"
98
+ #
99
+ # Returns the escaped String.
100
+ def cgi_escape(input)
101
+ CGI::escape(input)
102
+ end
103
+
104
+ # URI escape a string.
105
+ #
106
+ # input - The String to escape.
107
+ #
108
+ # Examples
109
+ #
110
+ # uri_escape('foo, bar \\baz?')
111
+ # # => "foo,%20bar%20%5Cbaz?"
112
+ #
113
+ # Returns the escaped String.
114
+ def uri_escape(input)
115
+ URI.escape(input)
116
+ end
117
+
118
+ # Count the number of words in the input string.
119
+ #
120
+ # input - The String on which to operate.
121
+ #
122
+ # Returns the Integer word count.
123
+ def number_of_words(input)
124
+ input.split.length
125
+ end
126
+
127
+ # Join an array of things into a string by separating with commes and the
128
+ # word "and" for the last one.
129
+ #
130
+ # array - The Array of Strings to join.
131
+ #
132
+ # Examples
133
+ #
134
+ # array_to_sentence_string(["apples", "oranges", "grapes"])
135
+ # # => "apples, oranges, and grapes"
136
+ #
137
+ # Returns the formatted String.
138
+ def array_to_sentence_string(array)
139
+ connector = "and"
140
+ case array.length
141
+ when 0
142
+ ""
143
+ when 1
144
+ array[0].to_s
145
+ when 2
146
+ "#{array[0]} #{connector} #{array[1]}"
147
+ else
148
+ "#{array[0...-1].join(', ')}, #{connector} #{array[-1]}"
149
+ end
150
+ end
151
+
152
+ # Convert the input into json string
153
+ #
154
+ # input - The Array or Hash to be converted
155
+ #
156
+ # Returns the converted json string
157
+ def jsonify(input)
158
+ input.to_json
159
+ end
160
+
161
+ private
162
+ def time(input)
163
+ case input
164
+ when Time
165
+ input
166
+ when String
167
+ Time.parse(input)
168
+ else
169
+ Tigefa.logger.error "Invalid Date:", "'#{input}' is not a valid datetime."
170
+ exit(1)
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,4 @@
1
+ module Tigefa
2
+ class Generator < Plugin
3
+ end
4
+ end
@@ -0,0 +1,217 @@
1
+ module Tigefa
2
+ module Generators
3
+ class Pagination < Generator
4
+ # This generator is safe from arbitrary code execution.
5
+ safe true
6
+
7
+ # This generator should be passive with regard to its execution
8
+ priority :lowest
9
+
10
+ # Generate paginated pages if necessary.
11
+ #
12
+ # site - The Site.
13
+ #
14
+ # Returns nothing.
15
+ def generate(site)
16
+ if Pager.pagination_enabled?(site)
17
+ if template = template_page(site)
18
+ paginate(site, template)
19
+ else
20
+ Tigefa.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find " +
21
+ "an index.html page to use as the pagination template. Skipping pagination."
22
+ end
23
+ end
24
+ end
25
+
26
+ # Paginates the blog's posts. Renders the index.html file into paginated
27
+ # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
28
+ # site-wide data.
29
+ #
30
+ # site - The Site.
31
+ # page - The index.html Page that requires pagination.
32
+ #
33
+ # {"paginator" => { "page" => <Number>,
34
+ # "per_page" => <Number>,
35
+ # "posts" => [<Post>],
36
+ # "total_posts" => <Number>,
37
+ # "total_pages" => <Number>,
38
+ # "previous_page" => <Number>,
39
+ # "next_page" => <Number> }}
40
+ def paginate(site, page)
41
+ all_posts = site.site_payload['site']['posts']
42
+ pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
43
+ (1..pages).each do |num_page|
44
+ pager = Pager.new(site, num_page, all_posts, pages)
45
+ if num_page > 1
46
+ newpage = Page.new(site, site.source, page.dir, page.name)
47
+ newpage.pager = pager
48
+ newpage.dir = Pager.paginate_path(site, num_page)
49
+ site.pages << newpage
50
+ else
51
+ page.pager = pager
52
+ end
53
+ end
54
+ end
55
+
56
+ # Static: Fetch the URL of the template page. Used to determine the
57
+ # path to the first pager in the series.
58
+ #
59
+ # site - the Tigefa::Site object
60
+ #
61
+ # Returns the url of the template page
62
+ def self.first_page_url(site)
63
+ if page = Pagination.new.template_page(site)
64
+ page.url
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ # Public: Find the Tigefa::Page which will act as the pager template
71
+ #
72
+ # site - the Tigefa::Site object
73
+ #
74
+ # Returns the Tigefa::Page which will act as the pager template
75
+ def template_page(site)
76
+ site.pages.dup.select do |page|
77
+ Pager.pagination_candidate?(site.config, page)
78
+ end.sort do |one, two|
79
+ two.path.size <=> one.path.size
80
+ end.first
81
+ end
82
+ end
83
+ end
84
+
85
+ class Pager
86
+ attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
87
+ :previous_page, :previous_page_path, :next_page, :next_page_path
88
+
89
+ # Calculate the number of pages.
90
+ #
91
+ # all_posts - The Array of all Posts.
92
+ # per_page - The Integer of entries per page.
93
+ #
94
+ # Returns the Integer number of pages.
95
+ def self.calculate_pages(all_posts, per_page)
96
+ (all_posts.size.to_f / per_page.to_i).ceil
97
+ end
98
+
99
+ # Determine if pagination is enabled the site.
100
+ #
101
+ # site - the Jekyll::Site object
102
+ #
103
+ # Returns true if pagination is enabled, false otherwise.
104
+ def self.pagination_enabled?(site)
105
+ !site.config['paginate'].nil? &&
106
+ site.pages.size > 0
107
+ end
108
+
109
+ # Static: Determine if a page is a possible candidate to be a template page.
110
+ # Page's name must be `index.html` and exist in any of the directories
111
+ # between the site source and `paginate_path`.
112
+ #
113
+ # config - the site configuration hash
114
+ # page - the Jekyll::Page about which we're inquiring
115
+ #
116
+ # Returns true if the
117
+ def self.pagination_candidate?(config, page)
118
+ page_dir = File.dirname(File.expand_path(remove_leading_slash(page.path), config['source']))
119
+ paginate_path = remove_leading_slash(config['paginate_path'])
120
+ paginate_path = File.expand_path(paginate_path, config['source'])
121
+ page.name == 'index.html' &&
122
+ in_hierarchy(config['source'], page_dir, File.dirname(paginate_path))
123
+ end
124
+
125
+ # Determine if the subdirectories of the two paths are the same relative to source
126
+ #
127
+ # source - the site source
128
+ # page_dir - the directory of the Jekyll::Page
129
+ # paginate_path - the absolute paginate path (from root of FS)
130
+ #
131
+ # Returns whether the subdirectories are the same relative to source
132
+ def self.in_hierarchy(source, page_dir, paginate_path)
133
+ return false if paginate_path == File.dirname(paginate_path)
134
+ return false if paginate_path == Pathname.new(source).parent
135
+ page_dir == paginate_path ||
136
+ in_hierarchy(source, page_dir, File.dirname(paginate_path))
137
+ end
138
+
139
+ # Static: Return the pagination path of the page
140
+ #
141
+ # site - the Jekyll::Site object
142
+ # num_page - the pagination page number
143
+ #
144
+ # Returns the pagination path as a string
145
+ def self.paginate_path(site, num_page)
146
+ return nil if num_page.nil?
147
+ return Generators::Pagination.first_page_url(site) if num_page <= 1
148
+ format = site.config['paginate_path']
149
+ format = format.sub(':num', num_page.to_s)
150
+ ensure_leading_slash(format)
151
+ end
152
+
153
+ # Static: Return a String version of the input which has a leading slash.
154
+ # If the input already has a forward slash in position zero, it will be
155
+ # returned unchanged.
156
+ #
157
+ # path - a String path
158
+ #
159
+ # Returns the path with a leading slash
160
+ def self.ensure_leading_slash(path)
161
+ path[0..0] == "/" ? path : "/#{path}"
162
+ end
163
+
164
+ # Static: Return a String version of the input without a leading slash.
165
+ #
166
+ # path - a String path
167
+ #
168
+ # Returns the input without the leading slash
169
+ def self.remove_leading_slash(path)
170
+ ensure_leading_slash(path)[1..-1]
171
+ end
172
+
173
+ # Initialize a new Pager.
174
+ #
175
+ # site - the Jekyll::Site object
176
+ # page - The Integer page number.
177
+ # all_posts - The Array of all the site's Posts.
178
+ # num_pages - The Integer number of pages or nil if you'd like the number
179
+ # of pages calculated.
180
+ def initialize(site, page, all_posts, num_pages = nil)
181
+ @page = page
182
+ @per_page = site.config['paginate'].to_i
183
+ @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
184
+
185
+ if @page > @total_pages
186
+ raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
187
+ end
188
+
189
+ init = (@page - 1) * @per_page
190
+ offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
191
+
192
+ @total_posts = all_posts.size
193
+ @posts = all_posts[init..offset]
194
+ @previous_page = @page != 1 ? @page - 1 : nil
195
+ @previous_page_path = Pager.paginate_path(site, @previous_page)
196
+ @next_page = @page != @total_pages ? @page + 1 : nil
197
+ @next_page_path = Pager.paginate_path(site, @next_page)
198
+ end
199
+
200
+ # Convert this Pager's data to a Hash suitable for use by Liquid.
201
+ #
202
+ # Returns the Hash representation of this Pager.
203
+ def to_liquid
204
+ {
205
+ 'page' => page,
206
+ 'per_page' => per_page,
207
+ 'posts' => posts,
208
+ 'total_posts' => total_posts,
209
+ 'total_pages' => total_pages,
210
+ 'previous_page' => previous_page,
211
+ 'previous_page_path' => previous_page_path,
212
+ 'next_page' => next_page,
213
+ 'next_page_path' => next_page_path
214
+ }
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,45 @@
1
+ module Tigefa
2
+ class Layout
3
+ include Convertible
4
+
5
+ # Gets the Site object.
6
+ attr_reader :site
7
+
8
+ # Gets the name of this layout.
9
+ attr_reader :name
10
+
11
+ # Gets/Sets the extension of this layout.
12
+ attr_accessor :ext
13
+
14
+ # Gets/Sets the Hash that holds the metadata for this layout.
15
+ attr_accessor :data
16
+
17
+ # Gets/Sets the content of this layout.
18
+ attr_accessor :content
19
+
20
+ # Initialize a new Layout.
21
+ #
22
+ # site - The Site.
23
+ # base - The String path to the source.
24
+ # name - The String filename of the post file.
25
+ def initialize(site, base, name)
26
+ @site = site
27
+ @base = base
28
+ @name = name
29
+
30
+ self.data = {}
31
+
32
+ self.process(name)
33
+ self.read_yaml(base, name)
34
+ end
35
+
36
+ # Extract information from the layout filename.
37
+ #
38
+ # name - The String filename of the layout file.
39
+ #
40
+ # Returns nothing.
41
+ def process(name)
42
+ self.ext = File.extname(name)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,85 @@
1
+ # These are the same MIME types that GitHub Pages uses as of 17 Mar 2013.
2
+
3
+ text/html html htm shtml
4
+ text/css css
5
+ text/xml xml rss xsl
6
+ image/gif gif
7
+ image/jpeg jpeg jpg
8
+ application/x-javascript js
9
+ application/atom+xml atom
10
+
11
+ text/mathml mml
12
+ text/plain txt
13
+ text/vnd.sun.j2me.app-descriptor jad
14
+ text/vnd.wap.wml wml
15
+ text/x-component htc
16
+ text/cache-manifest manifest appcache
17
+ text/coffeescript coffee
18
+ text/plain pde
19
+ text/plain md markdown
20
+
21
+ image/png png
22
+ image/svg+xml svg
23
+ image/tiff tif tiff
24
+ image/vnd.wap.wbmp wbmp
25
+ image/x-icon ico
26
+ image/x-jng jng
27
+ image/x-ms-bmp bmp
28
+
29
+ application/json json
30
+ application/java-archive jar ear
31
+ application/mac-binhex40 hqx
32
+ application/msword doc
33
+ application/pdf pdf
34
+ application/postscript ps eps ai
35
+ application/rdf+xml rdf
36
+ application/rtf rtf
37
+ text/vcard vcf vcard
38
+ application/vnd.apple.pkpass pkpass
39
+ application/vnd.ms-excel xls
40
+ application/vnd.ms-powerpoint ppt
41
+ application/vnd.wap.wmlc wmlc
42
+ application/xhtml+xml xhtml
43
+ application/x-chrome-extension crx
44
+ application/x-cocoa cco
45
+ application/x-font-ttf ttf
46
+ application/x-java-archive-diff jardiff
47
+ application/x-java-jnlp-file jnlp
48
+ application/x-makeself run
49
+ application/x-ns-proxy-autoconfig pac
50
+ application/x-perl pl pm
51
+ application/x-pilot prc pdb
52
+ application/x-rar-compressed rar
53
+ application/x-redhat-package-manager rpm
54
+ application/x-sea sea
55
+ application/x-shockwave-flash swf
56
+ application/x-stuffit sit
57
+ application/x-tcl tcl tk
58
+ application/x-web-app-manifest+json webapp
59
+ application/x-x509-ca-cert der pem crt
60
+ application/x-xpinstall xpi
61
+ application/x-zip war
62
+ application/zip zip
63
+
64
+ application/octet-stream bin exe dll
65
+ application/octet-stream deb
66
+ application/octet-stream dmg
67
+ application/octet-stream eot
68
+ application/octet-stream iso img
69
+ application/octet-stream msi msp msm
70
+
71
+ audio/midi mid midi kar
72
+ audio/mpeg mp3
73
+ audio/x-realaudio ra
74
+ audio/ogg ogg
75
+
76
+ video/3gpp 3gpp 3gp
77
+ video/mpeg mpeg mpg
78
+ video/quicktime mov
79
+ video/x-flv flv
80
+ video/x-mng mng
81
+ video/x-ms-asf asx asf
82
+ video/x-ms-wmv wmv
83
+ video/x-msvideo avi
84
+ video/ogg ogv
85
+ video/webm webm
@@ -0,0 +1,160 @@
1
+ module Tigefa
2
+ class Page
3
+ include Convertible
4
+
5
+ attr_writer :dir
6
+ attr_accessor :site, :pager
7
+ attr_accessor :name, :ext, :basename
8
+ attr_accessor :data, :content, :output
9
+
10
+ # Attributes for Liquid templates
11
+ ATTRIBUTES_FOR_LIQUID = %w[
12
+ url
13
+ content
14
+ path
15
+ ]
16
+
17
+ # Initialize a new Page.
18
+ #
19
+ # site - The Site object.
20
+ # base - The String path to the source.
21
+ # dir - The String path between the source and the file.
22
+ # name - The String filename of the file.
23
+ def initialize(site, base, dir, name)
24
+ @site = site
25
+ @base = base
26
+ @dir = dir
27
+ @name = name
28
+
29
+ self.process(name)
30
+ self.read_yaml(File.join(base, dir), name)
31
+ end
32
+
33
+ # The generated directory into which the page will be placed
34
+ # upon generation. This is derived from the permalink or, if
35
+ # permalink is absent, we be '/'
36
+ #
37
+ # Returns the String destination directory.
38
+ def dir
39
+ url[-1, 1] == '/' ? url : File.dirname(url)
40
+ end
41
+
42
+ # The full path and filename of the post. Defined in the YAML of the post
43
+ # body.
44
+ #
45
+ # Returns the String permalink or nil if none has been set.
46
+ def permalink
47
+ return nil if self.data.nil? || self.data['permalink'].nil?
48
+ if site.config['relative_permalinks']
49
+ File.join(@dir, self.data['permalink'])
50
+ else
51
+ self.data['permalink']
52
+ end
53
+ end
54
+
55
+ # The template of the permalink.
56
+ #
57
+ # Returns the template String.
58
+ def template
59
+ if self.site.permalink_style == :pretty
60
+ if index? && html?
61
+ "/:path/"
62
+ elsif html?
63
+ "/:path/:basename/"
64
+ else
65
+ "/:path/:basename:output_ext"
66
+ end
67
+ else
68
+ "/:path/:basename:output_ext"
69
+ end
70
+ end
71
+
72
+ # The generated relative url of this page. e.g. /about.html.
73
+ #
74
+ # Returns the String url.
75
+ def url
76
+ @url ||= URL.new({
77
+ :template => template,
78
+ :placeholders => url_placeholders,
79
+ :permalink => permalink
80
+ }).to_s
81
+ end
82
+
83
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
84
+ # desired placeholder replacements. For details see "url.rb"
85
+ def url_placeholders
86
+ {
87
+ :path => @dir,
88
+ :basename => self.basename,
89
+ :output_ext => self.output_ext
90
+ }
91
+ end
92
+
93
+ # Extract information from the page filename.
94
+ #
95
+ # name - The String filename of the page file.
96
+ #
97
+ # Returns nothing.
98
+ def process(name)
99
+ self.ext = File.extname(name)
100
+ self.basename = name[0 .. -self.ext.length-1]
101
+ end
102
+
103
+ # Add any necessary layouts to this post
104
+ #
105
+ # layouts - The Hash of {"name" => "layout"}.
106
+ # site_payload - The site payload Hash.
107
+ #
108
+ # Returns nothing.
109
+ def render(layouts, site_payload)
110
+ payload = {
111
+ "page" => self.to_liquid,
112
+ 'paginator' => pager.to_liquid
113
+ }.deep_merge(site_payload)
114
+
115
+ do_layout(payload, layouts)
116
+ end
117
+
118
+ # The path to the source file
119
+ #
120
+ # Returns the path to the source file
121
+ def path
122
+ self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
123
+ end
124
+
125
+ # The path to the page source file, relative to the site source
126
+ def relative_path
127
+ File.join(@dir, @name)
128
+ end
129
+
130
+ # Obtain destination path.
131
+ #
132
+ # dest - The String path to the destination dir.
133
+ #
134
+ # Returns the destination file path String.
135
+ def destination(dest)
136
+ path = File.join(dest, File.expand_path(self.url, "/"))
137
+ path = File.join(path, "index.html") if self.url =~ /\/$/
138
+ path
139
+ end
140
+
141
+ # Returns the object as a debug String.
142
+ def inspect
143
+ "#<Tigefa:Page @name=#{self.name.inspect}>"
144
+ end
145
+
146
+ # Returns the Boolean of whether this Page is HTML or not.
147
+ def html?
148
+ output_ext == '.html'
149
+ end
150
+
151
+ # Returns the Boolean of whether this Page is an index file or not.
152
+ def index?
153
+ basename == 'index'
154
+ end
155
+
156
+ def uses_relative_permalinks
157
+ permalink && @dir != "" && site.config['relative_permalinks']
158
+ end
159
+ end
160
+ end