jekyll-docs 3.6.0 → 3.6.1

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.
Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jekyll.rb +195 -0
  3. data/lib/jekyll/cleaner.rb +110 -0
  4. data/lib/jekyll/collection.rb +230 -0
  5. data/lib/jekyll/command.rb +78 -0
  6. data/lib/jekyll/commands/build.rb +102 -0
  7. data/lib/jekyll/commands/clean.rb +43 -0
  8. data/lib/jekyll/commands/doctor.rb +153 -0
  9. data/lib/jekyll/commands/help.rb +34 -0
  10. data/lib/jekyll/commands/new.rb +156 -0
  11. data/lib/jekyll/commands/new_theme.rb +40 -0
  12. data/lib/jekyll/commands/serve.rb +245 -0
  13. data/lib/jekyll/commands/serve/servlet.rb +62 -0
  14. data/lib/jekyll/configuration.rb +410 -0
  15. data/lib/jekyll/converter.rb +54 -0
  16. data/lib/jekyll/converters/identity.rb +23 -0
  17. data/lib/jekyll/converters/markdown.rb +104 -0
  18. data/lib/jekyll/converters/markdown/kramdown_parser.rb +123 -0
  19. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +35 -0
  20. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +108 -0
  21. data/lib/jekyll/converters/smartypants.rb +36 -0
  22. data/lib/jekyll/convertible.rb +251 -0
  23. data/lib/jekyll/deprecator.rb +52 -0
  24. data/lib/jekyll/document.rb +507 -0
  25. data/lib/jekyll/drops/collection_drop.rb +22 -0
  26. data/lib/jekyll/drops/document_drop.rb +69 -0
  27. data/lib/jekyll/drops/drop.rb +214 -0
  28. data/lib/jekyll/drops/excerpt_drop.rb +15 -0
  29. data/lib/jekyll/drops/jekyll_drop.rb +33 -0
  30. data/lib/jekyll/drops/site_drop.rb +47 -0
  31. data/lib/jekyll/drops/static_file_drop.rb +13 -0
  32. data/lib/jekyll/drops/unified_payload_drop.rb +25 -0
  33. data/lib/jekyll/drops/url_drop.rb +88 -0
  34. data/lib/jekyll/entry_filter.rb +123 -0
  35. data/lib/jekyll/errors.rb +20 -0
  36. data/lib/jekyll/excerpt.rb +126 -0
  37. data/lib/jekyll/external.rb +74 -0
  38. data/lib/jekyll/filters.rb +430 -0
  39. data/lib/jekyll/filters/grouping_filters.rb +65 -0
  40. data/lib/jekyll/filters/url_filters.rb +60 -0
  41. data/lib/jekyll/frontmatter_defaults.rb +197 -0
  42. data/lib/jekyll/generator.rb +5 -0
  43. data/lib/jekyll/hooks.rb +104 -0
  44. data/lib/jekyll/layout.rb +62 -0
  45. data/lib/jekyll/liquid_extensions.rb +24 -0
  46. data/lib/jekyll/liquid_renderer.rb +49 -0
  47. data/lib/jekyll/liquid_renderer/file.rb +56 -0
  48. data/lib/jekyll/liquid_renderer/table.rb +96 -0
  49. data/lib/jekyll/log_adapter.rb +147 -0
  50. data/lib/jekyll/mime.types +825 -0
  51. data/lib/jekyll/page.rb +187 -0
  52. data/lib/jekyll/plugin.rb +98 -0
  53. data/lib/jekyll/plugin_manager.rb +113 -0
  54. data/lib/jekyll/publisher.rb +23 -0
  55. data/lib/jekyll/reader.rb +134 -0
  56. data/lib/jekyll/readers/collection_reader.rb +22 -0
  57. data/lib/jekyll/readers/data_reader.rb +77 -0
  58. data/lib/jekyll/readers/layout_reader.rb +71 -0
  59. data/lib/jekyll/readers/page_reader.rb +25 -0
  60. data/lib/jekyll/readers/post_reader.rb +72 -0
  61. data/lib/jekyll/readers/static_file_reader.rb +25 -0
  62. data/lib/jekyll/readers/theme_assets_reader.rb +49 -0
  63. data/lib/jekyll/regenerator.rb +201 -0
  64. data/lib/jekyll/related_posts.rb +52 -0
  65. data/lib/jekyll/renderer.rb +269 -0
  66. data/lib/jekyll/site.rb +471 -0
  67. data/lib/jekyll/static_file.rb +162 -0
  68. data/lib/jekyll/stevenson.rb +61 -0
  69. data/lib/jekyll/tags/highlight.rb +141 -0
  70. data/lib/jekyll/tags/include.rb +215 -0
  71. data/lib/jekyll/tags/link.rb +37 -0
  72. data/lib/jekyll/tags/post_url.rb +103 -0
  73. data/lib/jekyll/theme.rb +68 -0
  74. data/lib/jekyll/theme_builder.rb +119 -0
  75. data/lib/jekyll/url.rb +161 -0
  76. data/lib/jekyll/utils.rb +337 -0
  77. data/lib/jekyll/utils/ansi.rb +59 -0
  78. data/lib/jekyll/utils/exec.rb +27 -0
  79. data/lib/jekyll/utils/platforms.rb +82 -0
  80. data/lib/jekyll/utils/rouge.rb +21 -0
  81. data/lib/jekyll/utils/win_tz.rb +75 -0
  82. data/lib/jekyll/version.rb +5 -0
  83. data/lib/site_template/404.html +24 -0
  84. data/lib/site_template/_config.yml +43 -0
  85. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +25 -0
  86. data/lib/site_template/about.md +18 -0
  87. data/lib/site_template/index.md +6 -0
  88. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  89. data/lib/theme_template/Gemfile +4 -0
  90. data/lib/theme_template/LICENSE.txt.erb +21 -0
  91. data/lib/theme_template/README.md.erb +52 -0
  92. data/lib/theme_template/_layouts/default.html +1 -0
  93. data/lib/theme_template/_layouts/page.html +5 -0
  94. data/lib/theme_template/_layouts/post.html +5 -0
  95. data/lib/theme_template/example/_config.yml.erb +1 -0
  96. data/lib/theme_template/example/_post.md +12 -0
  97. data/lib/theme_template/example/index.html +14 -0
  98. data/lib/theme_template/example/style.scss +7 -0
  99. data/lib/theme_template/gitignore.erb +5 -0
  100. data/lib/theme_template/theme.gemspec.erb +19 -0
  101. metadata +103 -156
  102. data/lib/jekyll-docs.rb +0 -31
  103. data/site/404.html +0 -153
  104. data/site/CNAME +0 -1
  105. data/site/community/index.html +0 -299
  106. data/site/conduct/index.html +0 -10
  107. data/site/css/screen.css +0 -1
  108. data/site/docs/assets/index.html +0 -724
  109. data/site/docs/code_of_conduct/index.html +0 -730
  110. data/site/docs/collections/index.html +0 -1097
  111. data/site/docs/conduct/index.html +0 -744
  112. data/site/docs/configuration/index.html +0 -1403
  113. data/site/docs/continuous-integration/buddyworks/index.html +0 -726
  114. data/site/docs/continuous-integration/circleci/index.html +0 -757
  115. data/site/docs/continuous-integration/index.html +0 -681
  116. data/site/docs/continuous-integration/travis-ci/index.html +0 -891
  117. data/site/docs/contributing/index.html +0 -863
  118. data/site/docs/datafiles/index.html +0 -780
  119. data/site/docs/deployment-methods/index.html +0 -875
  120. data/site/docs/drafts/index.html +0 -636
  121. data/site/docs/extras/index.html +0 -689
  122. data/site/docs/frontmatter/index.html +0 -807
  123. data/site/docs/github-pages/index.html +0 -819
  124. data/site/docs/history/index.html +0 -3955
  125. data/site/docs/home/index.html +0 -644
  126. data/site/docs/includes/index.html +0 -800
  127. data/site/docs/index.html +0 -10
  128. data/site/docs/installation/index.html +0 -732
  129. data/site/docs/maintaining/affinity-team-captain/index.html +0 -706
  130. data/site/docs/maintaining/avoiding-burnout/index.html +0 -709
  131. data/site/docs/maintaining/becoming-a-maintainer/index.html +0 -717
  132. data/site/docs/maintaining/index.html +0 -713
  133. data/site/docs/maintaining/merging-a-pull-request/index.html +0 -747
  134. data/site/docs/maintaining/reviewing-a-pull-request/index.html +0 -725
  135. data/site/docs/maintaining/special-labels/index.html +0 -705
  136. data/site/docs/maintaining/triaging-an-issue/index.html +0 -735
  137. data/site/docs/migrations/index.html +0 -647
  138. data/site/docs/pages/index.html +0 -695
  139. data/site/docs/pagination/index.html +0 -870
  140. data/site/docs/permalinks/index.html +0 -1027
  141. data/site/docs/plugins/index.html +0 -1800
  142. data/site/docs/posts/index.html +0 -858
  143. data/site/docs/quickstart/index.html +0 -650
  144. data/site/docs/resources/index.html +0 -769
  145. data/site/docs/sites/index.html +0 -702
  146. data/site/docs/static-files/index.html +0 -720
  147. data/site/docs/structure/index.html +0 -822
  148. data/site/docs/templates/index.html +0 -1208
  149. data/site/docs/themes/index.html +0 -935
  150. data/site/docs/troubleshooting/index.html +0 -893
  151. data/site/docs/upgrading/0-to-2/index.html +0 -826
  152. data/site/docs/upgrading/2-to-3/index.html +0 -824
  153. data/site/docs/upgrading/index.html +0 -693
  154. data/site/docs/usage/index.html +0 -705
  155. data/site/docs/variables/index.html +0 -1048
  156. data/site/docs/windows/index.html +0 -799
  157. data/site/favicon.ico +0 -0
  158. data/site/feed.xml +0 -372
  159. data/site/fonts/FontAwesome.eot +0 -0
  160. data/site/fonts/FontAwesome.svg +0 -12
  161. data/site/fonts/FontAwesome.ttf +0 -0
  162. data/site/fonts/FontAwesome.woff +0 -0
  163. data/site/github.html +0 -10
  164. data/site/help/index.html +0 -244
  165. data/site/icomoon-selection.json +0 -96
  166. data/site/img/article-footer.png +0 -0
  167. data/site/img/footer-arrow.png +0 -0
  168. data/site/img/footer-logo.png +0 -0
  169. data/site/img/jekyll-sticker.jpg +0 -0
  170. data/site/img/jekylllayoutconcept.png +0 -0
  171. data/site/img/logo-2x.png +0 -0
  172. data/site/img/logo-rss.png +0 -0
  173. data/site/img/octojekyll.png +0 -0
  174. data/site/index.html +0 -267
  175. data/site/issues.html +0 -10
  176. data/site/js/html5shiv.min.js +0 -4
  177. data/site/js/respond.min.js +0 -5
  178. data/site/latest_version.txt +0 -1
  179. data/site/news/2013/05/05/jekyll-1-0-0-released/index.html +0 -570
  180. data/site/news/2013/05/08/jekyll-1-0-1-released/index.html +0 -570
  181. data/site/news/2013/05/12/jekyll-1-0-2-released/index.html +0 -571
  182. data/site/news/2013/06/07/jekyll-1-0-3-released/index.html +0 -568
  183. data/site/news/2013/07/14/jekyll-1-1-0-released/index.html +0 -570
  184. data/site/news/2013/07/24/jekyll-1-1-1-released/index.html +0 -569
  185. data/site/news/2013/07/25/jekyll-1-0-4-released/index.html +0 -565
  186. data/site/news/2013/07/25/jekyll-1-1-2-released/index.html +0 -565
  187. data/site/news/2013/09/06/jekyll-1-2-0-released/index.html +0 -572
  188. data/site/news/2013/09/14/jekyll-1-2-1-released/index.html +0 -566
  189. data/site/news/2013/10/28/jekyll-1-3-0-rc1-released/index.html +0 -564
  190. data/site/news/2013/11/04/jekyll-1-3-0-released/index.html +0 -599
  191. data/site/news/2013/11/26/jekyll-1-3-1-released/index.html +0 -568
  192. data/site/news/2013/12/07/jekyll-1-4-0-released/index.html +0 -583
  193. data/site/news/2013/12/09/jekyll-1-4-1-released/index.html +0 -565
  194. data/site/news/2013/12/16/jekyll-1-4-2-released/index.html +0 -564
  195. data/site/news/2014/01/13/jekyll-1-4-3-released/index.html +0 -573
  196. data/site/news/2014/03/24/jekyll-1-5-0-released/index.html +0 -564
  197. data/site/news/2014/03/27/jekyll-1-5-1-released/index.html +0 -569
  198. data/site/news/2014/05/06/jekyll-turns-2-0-0/index.html +0 -585
  199. data/site/news/2014/05/08/jekyll-2-0-3-released/index.html +0 -565
  200. data/site/news/2014/06/04/jekyll-stickers-1-dollar-stickermule/index.html +0 -567
  201. data/site/news/2014/06/28/jekyll-turns-21-i-mean-2-1-0/index.html +0 -582
  202. data/site/news/2014/07/01/jekyll-2-1-1-released/index.html +0 -579
  203. data/site/news/2014/07/29/jekyll-2-2-0-released/index.html +0 -568
  204. data/site/news/2014/08/10/jekyll-2-3-0-released/index.html +0 -588
  205. data/site/news/2014/09/09/jekyll-2-4-0-released/index.html +0 -574
  206. data/site/news/2014/11/05/jekylls-midlife-crisis-jekyll-turns-2-5-0/index.html +0 -597
  207. data/site/news/2014/11/09/jekyll-2-5-1-released/index.html +0 -575
  208. data/site/news/2014/11/12/jekyll-2-5-2-released/index.html +0 -565
  209. data/site/news/2014/12/17/alfredxing-welcome-to-jekyll-core/index.html +0 -572
  210. data/site/news/2014/12/22/jekyll-2-5-3-released/index.html +0 -567
  211. data/site/news/2015/01/20/jekyll-meet-and-greet/index.html +0 -568
  212. data/site/news/2015/01/24/jekyll-3-0-0-beta1-released/index.html +0 -588
  213. data/site/news/2015/02/26/introducing-jekyll-talk/index.html +0 -563
  214. data/site/news/2015/10/26/jekyll-3-0-released/index.html +0 -592
  215. data/site/news/2015/11/17/jekyll-3-0-1-released/index.html +0 -576
  216. data/site/news/2016/01/20/jekyll-3-0-2-released/index.html +0 -566
  217. data/site/news/2016/01/24/jekyll-3-1-0-released/index.html +0 -599
  218. data/site/news/2016/01/28/jekyll-3-1-1-released/index.html +0 -583
  219. data/site/news/2016/02/08/jekyll-3-0-3-released/index.html +0 -578
  220. data/site/news/2016/02/19/jekyll-3-1-2-released/index.html +0 -569
  221. data/site/news/2016/03/10/making-it-easier-to-contribute-to-jekyll/index.html +0 -565
  222. data/site/news/2016/04/19/jekyll-3-0-4-released/index.html +0 -571
  223. data/site/news/2016/04/19/jekyll-3-1-3-released/index.html +0 -566
  224. data/site/news/2016/04/26/jekyll-3-0-5-released/index.html +0 -572
  225. data/site/news/2016/05/18/jekyll-3-1-4-released/index.html +0 -576
  226. data/site/news/2016/05/18/jekyll-3-1-5-released/index.html +0 -564
  227. data/site/news/2016/05/19/jekyll-3-1-6-released/index.html +0 -566
  228. data/site/news/2016/06/03/update-on-jekyll-s-google-summer-of-code-projects/index.html +0 -567
  229. data/site/news/2016/07/26/jekyll-3-2-0-released/index.html +0 -676
  230. data/site/news/2016/08/02/jekyll-3-2-1-released/index.html +0 -571
  231. data/site/news/2016/08/24/jekyll-admin-initial-release/index.html +0 -566
  232. data/site/news/2016/10/06/jekyll-3-3-is-here/index.html +0 -645
  233. data/site/news/2016/11/14/jekyll-3-3-1-released/index.html +0 -569
  234. data/site/news/2017/01/18/jekyll-3-4-0-released/index.html +0 -592
  235. data/site/news/2017/03/02/jekyll-3-4-1-released/index.html +0 -649
  236. data/site/news/2017/03/09/jekyll-3-4-2-released/index.html +0 -598
  237. data/site/news/2017/03/21/jekyll-3-4-3-released/index.html +0 -594
  238. data/site/news/2017/06/15/jekyll-3-5-0-released/index.html +0 -589
  239. data/site/news/2017/07/17/jekyll-3-5-1-released/index.html +0 -569
  240. data/site/news/2017/08/12/jekyll-3-5-2-released/index.html +0 -573
  241. data/site/news/2017/09/21/jekyll-3-6-0-released/index.html +0 -565
  242. data/site/news/index.html +0 -3609
  243. data/site/news/releases/index.html +0 -3344
  244. data/site/philosophy.html +0 -46
  245. data/site/readme.md +0 -23
  246. data/site/robots.txt +0 -1
  247. data/site/sitemap.xml +0 -485
  248. data/site/tutorials/convert-site-to-jekyll/index.html +0 -793
  249. data/site/tutorials/custom-404-page/index.html +0 -358
  250. data/site/tutorials/home/index.html +0 -323
  251. data/site/tutorials/index.html +0 -10
  252. data/site/tutorials/navigation/index.html +0 -872
  253. data/site/tutorials/orderofinterpretation/index.html +0 -441
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Tags
5
+ class Link < Liquid::Tag
6
+ class << self
7
+ def tag_name
8
+ self.name.split("::").last.downcase
9
+ end
10
+ end
11
+
12
+ def initialize(tag_name, relative_path, tokens)
13
+ super
14
+
15
+ @relative_path = relative_path.strip
16
+ end
17
+
18
+ def render(context)
19
+ site = context.registers[:site]
20
+
21
+ site.each_site_file do |item|
22
+ return item.url if item.relative_path == @relative_path
23
+ # This takes care of the case for static files that have a leading /
24
+ return item.url if item.relative_path == "/#{@relative_path}"
25
+ end
26
+
27
+ raise ArgumentError, <<-MSG
28
+ Could not find document '#{@relative_path}' in tag '#{self.class.tag_name}'.
29
+
30
+ Make sure the document exists and the path is correct.
31
+ MSG
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ Liquid::Template.register_tag(Jekyll::Tags::Link.tag_name, Jekyll::Tags::Link)
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Tags
5
+ class PostComparer
6
+ MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!
7
+
8
+ attr_reader :path, :date, :slug, :name
9
+
10
+ def initialize(name)
11
+ @name = name
12
+
13
+ all, @path, @date, @slug = *name.sub(%r!^/!, "").match(MATCHER)
14
+ unless all
15
+ raise Jekyll::Errors::InvalidPostNameError,
16
+ "'#{name}' does not contain valid date and/or title."
17
+ end
18
+
19
+ escaped_slug = Regexp.escape(slug)
20
+ @name_regex = %r!^_posts/#{path}#{date}-#{escaped_slug}\.[^.]+|
21
+ ^#{path}_posts/?#{date}-#{escaped_slug}\.[^.]+!x
22
+ end
23
+
24
+ def post_date
25
+ @post_date ||= Utils.parse_date(date,
26
+ "\"#{date}\" does not contain valid date and/or title.")
27
+ end
28
+
29
+ def ==(other)
30
+ other.relative_path.match(@name_regex)
31
+ end
32
+
33
+ def deprecated_equality(other)
34
+ slug == post_slug(other) &&
35
+ post_date.year == other.date.year &&
36
+ post_date.month == other.date.month &&
37
+ post_date.day == other.date.day
38
+ end
39
+
40
+ private
41
+ # Construct the directory-aware post slug for a Jekyll::Post
42
+ #
43
+ # other - the Jekyll::Post
44
+ #
45
+ # Returns the post slug with the subdirectory (relative to _posts)
46
+ def post_slug(other)
47
+ path = other.basename.split("/")[0...-1].join("/")
48
+ if path.nil? || path == ""
49
+ other.data["slug"]
50
+ else
51
+ path + "/" + other.data["slug"]
52
+ end
53
+ end
54
+ end
55
+
56
+ class PostUrl < Liquid::Tag
57
+ def initialize(tag_name, post, tokens)
58
+ super
59
+ @orig_post = post.strip
60
+ begin
61
+ @post = PostComparer.new(@orig_post)
62
+ rescue => e
63
+ raise Jekyll::Errors::PostURLError, <<-MSG
64
+ Could not parse name of post "#{@orig_post}" in tag 'post_url'.
65
+
66
+ Make sure the post exists and the name is correct.
67
+
68
+ #{e.class}: #{e.message}
69
+ MSG
70
+ end
71
+ end
72
+
73
+ def render(context)
74
+ site = context.registers[:site]
75
+
76
+ site.posts.docs.each do |p|
77
+ return p.url if @post == p
78
+ end
79
+
80
+ # New matching method did not match, fall back to old method
81
+ # with deprecation warning if this matches
82
+
83
+ site.posts.docs.each do |p|
84
+ next unless @post.deprecated_equality p
85
+ Jekyll::Deprecator.deprecation_message "A call to "\
86
+ "'{% post_url #{@post.name} %}' did not match " \
87
+ "a post using the new matching method of checking name " \
88
+ "(path-date-slug) equality. Please make sure that you " \
89
+ "change this tag to match the post's name exactly."
90
+ return p.url
91
+ end
92
+
93
+ raise Jekyll::Errors::PostURLError, <<-MSG
94
+ Could not find post "#{@orig_post}" in tag 'post_url'.
95
+
96
+ Make sure the post exists and the name is correct.
97
+ MSG
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ Liquid::Template.register_tag("post_url", Jekyll::Tags::PostUrl)
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Theme
5
+ extend Forwardable
6
+ attr_reader :name
7
+ def_delegator :gemspec, :version, :version
8
+
9
+ def initialize(name)
10
+ @name = name.downcase.strip
11
+ configure_sass
12
+ end
13
+
14
+ def root
15
+ # Must use File.realpath to resolve symlinks created by rbenv
16
+ # Otherwise, Jekyll.sanitized path with prepend the unresolved root
17
+ @root ||= File.realpath(gemspec.full_gem_path)
18
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
19
+ nil
20
+ end
21
+
22
+ def includes_path
23
+ path_for "_includes".freeze
24
+ end
25
+
26
+ def layouts_path
27
+ path_for "_layouts".freeze
28
+ end
29
+
30
+ def sass_path
31
+ path_for "_sass".freeze
32
+ end
33
+
34
+ def assets_path
35
+ path_for "assets".freeze
36
+ end
37
+
38
+ def configure_sass
39
+ return unless sass_path
40
+ require "sass"
41
+ Sass.load_paths << sass_path
42
+ end
43
+
44
+ def runtime_dependencies
45
+ gemspec.runtime_dependencies
46
+ end
47
+
48
+ private
49
+
50
+ def path_for(folder)
51
+ path = realpath_for(folder)
52
+ path if path && File.directory?(path)
53
+ end
54
+
55
+ def realpath_for(folder)
56
+ File.realpath(Jekyll.sanitized_path(root, folder.to_s))
57
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
58
+ nil
59
+ end
60
+
61
+ def gemspec
62
+ @gemspec ||= Gem::Specification.find_by_name(name)
63
+ rescue Gem::LoadError
64
+ raise Jekyll::Errors::MissingDependencyException,
65
+ "The #{name} theme could not be found."
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Jekyll::ThemeBuilder
4
+ SCAFFOLD_DIRECTORIES = %w(
5
+ assets _layouts _includes _sass
6
+ ).freeze
7
+
8
+ attr_reader :name, :path, :code_of_conduct
9
+
10
+ def initialize(theme_name, opts)
11
+ @name = theme_name.to_s.tr(" ", "_").gsub(%r!_+!, "_")
12
+ @path = Pathname.new(File.expand_path(name, Dir.pwd))
13
+ @code_of_conduct = !!opts["code_of_conduct"]
14
+ end
15
+
16
+ def create!
17
+ create_directories
18
+ create_starter_files
19
+ create_gemspec
20
+ create_accessories
21
+ initialize_git_repo
22
+ end
23
+
24
+ private
25
+
26
+ def root
27
+ @root ||= Pathname.new(File.expand_path("../", __dir__))
28
+ end
29
+
30
+ def template_file(filename)
31
+ [
32
+ root.join("theme_template", "#{filename}.erb"),
33
+ root.join("theme_template", filename.to_s),
34
+ ].find(&:exist?)
35
+ end
36
+
37
+ def template(filename)
38
+ erb.render(template_file(filename).read)
39
+ end
40
+
41
+ def erb
42
+ @erb ||= ERBRenderer.new(self)
43
+ end
44
+
45
+ def mkdir_p(directories)
46
+ Array(directories).each do |directory|
47
+ full_path = path.join(directory)
48
+ Jekyll.logger.info "create", full_path.to_s
49
+ FileUtils.mkdir_p(full_path)
50
+ end
51
+ end
52
+
53
+ def write_file(filename, contents)
54
+ full_path = path.join(filename)
55
+ Jekyll.logger.info "create", full_path.to_s
56
+ File.write(full_path, contents)
57
+ end
58
+
59
+ def create_directories
60
+ mkdir_p(SCAFFOLD_DIRECTORIES)
61
+ end
62
+
63
+ def create_starter_files
64
+ %w(page post default).each do |layout|
65
+ write_file("_layouts/#{layout}.html", template("_layouts/#{layout}.html"))
66
+ end
67
+ end
68
+
69
+ def create_gemspec
70
+ write_file("Gemfile", template("Gemfile"))
71
+ write_file("#{name}.gemspec", template("theme.gemspec"))
72
+ end
73
+
74
+ def create_accessories
75
+ accessories = %w(README.md LICENSE.txt)
76
+ accessories << "CODE_OF_CONDUCT.md" if code_of_conduct
77
+ accessories.each do |filename|
78
+ write_file(filename, template(filename))
79
+ end
80
+ end
81
+
82
+ def initialize_git_repo
83
+ Jekyll.logger.info "initialize", path.join(".git").to_s
84
+ Dir.chdir(path.to_s) { `git init` }
85
+ write_file(".gitignore", template("gitignore"))
86
+ end
87
+
88
+ def user_name
89
+ @user_name ||= `git config user.name`.chomp
90
+ end
91
+
92
+ def user_email
93
+ @user_email ||= `git config user.email`.chomp
94
+ end
95
+
96
+ class ERBRenderer
97
+ extend Forwardable
98
+
99
+ def_delegator :@theme_builder, :name, :theme_name
100
+ def_delegator :@theme_builder, :user_name, :user_name
101
+ def_delegator :@theme_builder, :user_email, :user_email
102
+
103
+ def initialize(theme_builder)
104
+ @theme_builder = theme_builder
105
+ end
106
+
107
+ def jekyll_version_with_minor
108
+ Jekyll::VERSION.split(".").take(2).join(".")
109
+ end
110
+
111
+ def theme_directories
112
+ SCAFFOLD_DIRECTORIES
113
+ end
114
+
115
+ def render(contents)
116
+ ERB.new(contents).result binding
117
+ end
118
+ end
119
+ end
data/lib/jekyll/url.rb ADDED
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "addressable/uri"
4
+
5
+ # Public: Methods that generate a URL for a resource such as a Post or a Page.
6
+ #
7
+ # Examples
8
+ #
9
+ # URL.new({
10
+ # :template => /:categories/:title.html",
11
+ # :placeholders => {:categories => "ruby", :title => "something"}
12
+ # }).to_s
13
+ #
14
+ module Jekyll
15
+ class URL
16
+ # options - One of :permalink or :template must be supplied.
17
+ # :template - The String used as template for URL generation,
18
+ # for example "/:path/:basename:output_ext", where
19
+ # a placeholder is prefixed with a colon.
20
+ # :placeholders - A hash containing the placeholders which will be
21
+ # replaced when used inside the template. E.g.
22
+ # { "year" => Time.now.strftime("%Y") } would replace
23
+ # the placeholder ":year" with the current year.
24
+ # :permalink - If supplied, no URL will be generated from the
25
+ # template. Instead, the given permalink will be
26
+ # used as URL.
27
+ def initialize(options)
28
+ @template = options[:template]
29
+ @placeholders = options[:placeholders] || {}
30
+ @permalink = options[:permalink]
31
+
32
+ if (@template || @permalink).nil?
33
+ raise ArgumentError, "One of :template or :permalink must be supplied."
34
+ end
35
+ end
36
+
37
+ # The generated relative URL of the resource
38
+ #
39
+ # Returns the String URL
40
+ def to_s
41
+ sanitize_url(generated_permalink || generated_url)
42
+ end
43
+
44
+ # Generates a URL from the permalink
45
+ #
46
+ # Returns the _unsanitized String URL
47
+ def generated_permalink
48
+ (@generated_permalink ||= generate_url(@permalink)) if @permalink
49
+ end
50
+
51
+ # Generates a URL from the template
52
+ #
53
+ # Returns the unsanitized String URL
54
+ def generated_url
55
+ @generated_url ||= generate_url(@template)
56
+ end
57
+
58
+ # Internal: Generate the URL by replacing all placeholders with their
59
+ # respective values in the given template
60
+ #
61
+ # Returns the unsanitized String URL
62
+ def generate_url(template)
63
+ if @placeholders.is_a? Drops::UrlDrop
64
+ generate_url_from_drop(template)
65
+ else
66
+ generate_url_from_hash(template)
67
+ end
68
+ end
69
+
70
+ def generate_url_from_hash(template)
71
+ @placeholders.inject(template) do |result, token|
72
+ break result if result.index(":").nil?
73
+ if token.last.nil?
74
+ # Remove leading "/" to avoid generating urls with `//`
75
+ result.gsub(%r!/:#{token.first}!, "")
76
+ else
77
+ result.gsub(%r!:#{token.first}!, self.class.escape_path(token.last))
78
+ end
79
+ end
80
+ end
81
+
82
+ # We include underscores in keys to allow for 'i_month' and so forth.
83
+ # This poses a problem for keys which are followed by an underscore
84
+ # but the underscore is not part of the key, e.g. '/:month_:day'.
85
+ # That should be :month and :day, but our key extraction regexp isn't
86
+ # smart enough to know that so we have to make it an explicit
87
+ # possibility.
88
+ def possible_keys(key)
89
+ if key.end_with?("_")
90
+ [key, key.chomp("_")]
91
+ else
92
+ [key]
93
+ end
94
+ end
95
+
96
+ def generate_url_from_drop(template)
97
+ template.gsub(%r!:([a-z_]+)!) do |match|
98
+ pool = possible_keys(match.sub(":", ""))
99
+
100
+ winner = pool.find { |key| @placeholders.key?(key) }
101
+ if winner.nil?
102
+ raise NoMethodError,
103
+ "The URL template doesn't have #{pool.join(" or ")} keys. "\
104
+ "Check your permalink template!"
105
+ end
106
+
107
+ value = @placeholders[winner]
108
+ value = "" if value.nil?
109
+ replacement = self.class.escape_path(value)
110
+
111
+ match.sub(":#{winner}", replacement)
112
+ end.gsub(%r!//!, "/".freeze)
113
+ end
114
+
115
+ # Returns a sanitized String URL, stripping "../../" and multiples of "/",
116
+ # as well as the beginning "/" so we can enforce and ensure it.
117
+
118
+ def sanitize_url(str)
119
+ "/" + str.gsub(%r!/{2,}!, "/").gsub(%r!\.+/|\A/+!, "")
120
+ end
121
+
122
+ # Escapes a path to be a valid URL path segment
123
+ #
124
+ # path - The path to be escaped.
125
+ #
126
+ # Examples:
127
+ #
128
+ # URL.escape_path("/a b")
129
+ # # => "/a%20b"
130
+ #
131
+ # Returns the escaped path.
132
+ def self.escape_path(path)
133
+ # Because URI.escape doesn't escape "?", "[" and "]" by default,
134
+ # specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
135
+ #
136
+ # URI path segment is defined in RFC 3986 as follows:
137
+ # segment = *pchar
138
+ # pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
139
+ # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
140
+ # pct-encoded = "%" HEXDIG HEXDIG
141
+ # sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
142
+ # / "*" / "+" / "," / ";" / "="
143
+ path = Addressable::URI.encode(path)
144
+ path.encode("utf-8").sub("#", "%23")
145
+ end
146
+
147
+ # Unescapes a URL path segment
148
+ #
149
+ # path - The path to be unescaped.
150
+ #
151
+ # Examples:
152
+ #
153
+ # URL.unescape_path("/a%20b")
154
+ # # => "/a b"
155
+ #
156
+ # Returns the unescaped path.
157
+ def self.unescape_path(path)
158
+ Addressable::URI.unencode(path.encode("utf-8"))
159
+ end
160
+ end
161
+ end