jekyll-docs 3.6.0 → 3.6.1

Sign up to get free protection for your applications and to get access to all the features.
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,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class UrlDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :cleaned_relative_path, :path
11
+ def_delegator :@obj, :output_ext, :output_ext
12
+
13
+ def collection
14
+ @obj.collection.label
15
+ end
16
+
17
+ def name
18
+ Utils.slugify(@obj.basename_without_ext)
19
+ end
20
+
21
+ def title
22
+ Utils.slugify(@obj.data["slug"], :mode => "pretty", :cased => true) ||
23
+ Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
24
+ end
25
+
26
+ def slug
27
+ Utils.slugify(@obj.data["slug"]) || Utils.slugify(@obj.basename_without_ext)
28
+ end
29
+
30
+ def categories
31
+ category_set = Set.new
32
+ Array(@obj.data["categories"]).each do |category|
33
+ category_set << category.to_s.downcase
34
+ end
35
+ category_set.to_a.join("/")
36
+ end
37
+
38
+ def year
39
+ @obj.date.strftime("%Y")
40
+ end
41
+
42
+ def month
43
+ @obj.date.strftime("%m")
44
+ end
45
+
46
+ def day
47
+ @obj.date.strftime("%d")
48
+ end
49
+
50
+ def hour
51
+ @obj.date.strftime("%H")
52
+ end
53
+
54
+ def minute
55
+ @obj.date.strftime("%M")
56
+ end
57
+
58
+ def second
59
+ @obj.date.strftime("%S")
60
+ end
61
+
62
+ def i_day
63
+ @obj.date.strftime("%-d")
64
+ end
65
+
66
+ def i_month
67
+ @obj.date.strftime("%-m")
68
+ end
69
+
70
+ def short_month
71
+ @obj.date.strftime("%b")
72
+ end
73
+
74
+ def short_year
75
+ @obj.date.strftime("%y")
76
+ end
77
+
78
+ def y_day
79
+ @obj.date.strftime("%j")
80
+ end
81
+
82
+ private
83
+ def fallback_data
84
+ {}
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class EntryFilter
5
+ attr_reader :site
6
+ SPECIAL_LEADING_CHARACTERS = [
7
+ ".", "_", "#", "~",
8
+ ].freeze
9
+
10
+ def initialize(site, base_directory = nil)
11
+ @site = site
12
+ @base_directory = derive_base_directory(
13
+ @site, base_directory.to_s.dup
14
+ )
15
+ end
16
+
17
+ def base_directory
18
+ @base_directory.to_s
19
+ end
20
+
21
+ def derive_base_directory(site, base_dir)
22
+ base_dir[site.source] = "" if base_dir.start_with?(site.source)
23
+ base_dir
24
+ end
25
+
26
+ def relative_to_source(entry)
27
+ File.join(
28
+ base_directory, entry
29
+ )
30
+ end
31
+
32
+ def filter(entries)
33
+ entries.reject do |e|
34
+ unless included?(e)
35
+ special?(e) || backup?(e) || excluded?(e) || symlink?(e)
36
+ end
37
+ end
38
+ end
39
+
40
+ def included?(entry)
41
+ glob_include?(site.include, entry) ||
42
+ glob_include?(site.include, File.basename(entry))
43
+ end
44
+
45
+ def special?(entry)
46
+ SPECIAL_LEADING_CHARACTERS.include?(entry[0..0]) ||
47
+ SPECIAL_LEADING_CHARACTERS.include?(File.basename(entry)[0..0])
48
+ end
49
+
50
+ def backup?(entry)
51
+ entry[-1..-1] == "~"
52
+ end
53
+
54
+ def excluded?(entry)
55
+ glob_include?(site.exclude, relative_to_source(entry)).tap do |excluded|
56
+ if excluded
57
+ Jekyll.logger.debug(
58
+ "EntryFilter:",
59
+ "excluded #{relative_to_source(entry)}"
60
+ )
61
+ end
62
+ end
63
+ end
64
+
65
+ # --
66
+ # Check if a file is a symlink.
67
+ # NOTE: This can be converted to allowing even in safe,
68
+ # since we use Pathutil#in_path? now.
69
+ # --
70
+ def symlink?(entry)
71
+ site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry)
72
+ end
73
+
74
+ # --
75
+ # NOTE: Pathutil#in_path? gets the realpath.
76
+ # @param [<Anything>] entry the entry you want to validate.
77
+ # Check if a path is outside of our given root.
78
+ # --
79
+ def symlink_outside_site_source?(entry)
80
+ !Pathutil.new(entry).in_path?(
81
+ site.in_source_dir
82
+ )
83
+ end
84
+
85
+ # --
86
+ # Check if an entry matches a specific pattern and return true,false.
87
+ # Returns true if path matches against any glob pattern.
88
+ # --
89
+ def glob_include?(enum, e)
90
+ entry = Pathutil.new(site.in_source_dir).join(e)
91
+ enum.any? do |exp|
92
+ # Users who send a Regexp knows what they want to
93
+ # exclude, so let them send a Regexp to exclude files,
94
+ # we will not bother caring if it works or not, it's
95
+ # on them at this point.
96
+
97
+ if exp.is_a?(Regexp)
98
+ entry =~ exp
99
+
100
+ else
101
+ item = Pathutil.new(site.in_source_dir).join(exp)
102
+
103
+ # If it's a directory they want to exclude, AKA
104
+ # ends with a "/" then we will go on to check and
105
+ # see if the entry falls within that path and
106
+ # exclude it if that's the case.
107
+
108
+ if e.end_with?("/")
109
+ entry.in_path?(
110
+ item
111
+ )
112
+
113
+ else
114
+ File.fnmatch?(item, entry) ||
115
+ entry.to_path.start_with?(
116
+ item
117
+ )
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Errors
5
+ FatalException = Class.new(::RuntimeError)
6
+
7
+ InvalidThemeName = Class.new(FatalException)
8
+
9
+ DropMutationException = Class.new(FatalException)
10
+ InvalidPermalinkError = Class.new(FatalException)
11
+ InvalidYAMLFrontMatterError = Class.new(FatalException)
12
+ MissingDependencyException = Class.new(FatalException)
13
+
14
+ InvalidDateError = Class.new(FatalException)
15
+ InvalidPostNameError = Class.new(FatalException)
16
+ PostURLError = Class.new(FatalException)
17
+ InvalidURLError = Class.new(FatalException)
18
+ InvalidConfigurationError = Class.new(FatalException)
19
+ end
20
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Excerpt
5
+ extend Forwardable
6
+
7
+ attr_accessor :doc
8
+ attr_accessor :content, :ext
9
+ attr_writer :output
10
+
11
+ def_delegators :@doc, :site, :name, :ext, :relative_path, :extname,
12
+ :render_with_liquid?, :collection, :related_posts,
13
+ :url, :next_doc, :previous_doc
14
+
15
+ # Initialize this Excerpt instance.
16
+ #
17
+ # doc - The Document.
18
+ #
19
+ # Returns the new Excerpt.
20
+ def initialize(doc)
21
+ self.doc = doc
22
+ self.content = extract_excerpt(doc.content)
23
+ end
24
+
25
+ # Fetch YAML front-matter data from related doc, without layout key
26
+ #
27
+ # Returns Hash of doc data
28
+ def data
29
+ @data ||= doc.data.dup
30
+ @data.delete("layout")
31
+ @data.delete("excerpt")
32
+ @data
33
+ end
34
+
35
+ def trigger_hooks(*); end
36
+
37
+ # 'Path' of the excerpt.
38
+ #
39
+ # Returns the path for the doc this excerpt belongs to with #excerpt appended
40
+ def path
41
+ File.join(doc.path, "#excerpt")
42
+ end
43
+
44
+ # Check if excerpt includes a string
45
+ #
46
+ # Returns true if the string passed in
47
+ def include?(something)
48
+ (output && output.include?(something)) || content.include?(something)
49
+ end
50
+
51
+ # The UID for this doc (useful in feeds).
52
+ # e.g. /2008/11/05/my-awesome-doc
53
+ #
54
+ # Returns the String UID.
55
+ def id
56
+ "#{doc.id}#excerpt"
57
+ end
58
+
59
+ def to_s
60
+ output || content
61
+ end
62
+
63
+ def to_liquid
64
+ Jekyll::Drops::ExcerptDrop.new(self)
65
+ end
66
+
67
+ # Returns the shorthand String identifier of this doc.
68
+ def inspect
69
+ "<Excerpt: #{self.id}>"
70
+ end
71
+
72
+ def output
73
+ @output ||= Renderer.new(doc.site, self, site.site_payload).run
74
+ end
75
+
76
+ def place_in_layout?
77
+ false
78
+ end
79
+
80
+ protected
81
+
82
+ # Internal: Extract excerpt from the content
83
+ #
84
+ # By default excerpt is your first paragraph of a doc: everything before
85
+ # the first two new lines:
86
+ #
87
+ # ---
88
+ # title: Example
89
+ # ---
90
+ #
91
+ # First paragraph with [link][1].
92
+ #
93
+ # Second paragraph.
94
+ #
95
+ # [1]: http://example.com/
96
+ #
97
+ # This is fairly good option for Markdown and Textile files. But might cause
98
+ # problems for HTML docs (which is quite unusual for Jekyll). If default
99
+ # excerpt delimiter is not good for you, you might want to set your own via
100
+ # configuration option `excerpt_separator`. For example, following is a good
101
+ # alternative for HTML docs:
102
+ #
103
+ # # file: _config.yml
104
+ # excerpt_separator: "<!-- more -->"
105
+ #
106
+ # Notice that all markdown-style link references will be appended to the
107
+ # excerpt. So the example doc above will have this excerpt source:
108
+ #
109
+ # First paragraph with [link][1].
110
+ #
111
+ # [1]: http://example.com/
112
+ #
113
+ # Excerpts are rendered same time as content is rendered.
114
+ #
115
+ # Returns excerpt String
116
+ def extract_excerpt(doc_content)
117
+ head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
118
+
119
+ if tail.empty?
120
+ head
121
+ else
122
+ head.to_s.dup << "\n\n" << tail.scan(%r!^ {0,3}\[[^\]]+\]:.+$!).join("\n")
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module External
5
+ class << self
6
+ #
7
+ # Gems that, if installed, should be loaded.
8
+ # Usually contain subcommands.
9
+ #
10
+ def blessed_gems
11
+ %w(
12
+ jekyll-docs
13
+ jekyll-import
14
+ )
15
+ end
16
+
17
+ #
18
+ # Require a gem or file if it's present, otherwise silently fail.
19
+ #
20
+ # names - a string gem name or array of gem names
21
+ #
22
+ def require_if_present(names)
23
+ Array(names).each do |name|
24
+ begin
25
+ require name
26
+ rescue LoadError
27
+ Jekyll.logger.debug "Couldn't load #{name}. Skipping."
28
+ yield(name, version_constraint(name)) if block_given?
29
+ false
30
+ end
31
+ end
32
+ end
33
+
34
+ #
35
+ # The version constraint required to activate a given gem.
36
+ # Usually the gem version requirement is "> 0," because any version
37
+ # will do. In the case of jekyll-docs, however, we require the exact
38
+ # same version as Jekyll.
39
+ #
40
+ # Returns a String version constraint in a parseable form for
41
+ # RubyGems.
42
+ def version_constraint(gem_name)
43
+ return "= #{Jekyll::VERSION}" if gem_name.to_s.eql?("jekyll-docs")
44
+ "> 0"
45
+ end
46
+
47
+ #
48
+ # Require a gem or gems. If it's not present, show a very nice error
49
+ # message that explains everything and is much more helpful than the
50
+ # normal LoadError.
51
+ #
52
+ # names - a string gem name or array of gem names
53
+ #
54
+ def require_with_graceful_fail(names)
55
+ Array(names).each do |name|
56
+ begin
57
+ Jekyll.logger.debug "Requiring:", name.to_s
58
+ require name
59
+ rescue LoadError => e
60
+ Jekyll.logger.error "Dependency Error:", <<-MSG
61
+ Yikes! It looks like you don't have #{name} or one of its dependencies installed.
62
+ In order to use Jekyll as currently configured, you'll need to install this gem.
63
+
64
+ The full error message from Ruby is: '#{e.message}'
65
+
66
+ If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
67
+ MSG
68
+ raise Jekyll::Errors::MissingDependencyException, name
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,430 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "addressable/uri"
4
+ require "json"
5
+ require "date"
6
+ require "liquid"
7
+
8
+ require_all "jekyll/filters"
9
+
10
+ module Jekyll
11
+ module Filters
12
+ include URLFilters
13
+ include GroupingFilters
14
+
15
+ # Convert a Markdown string into HTML output.
16
+ #
17
+ # input - The Markdown String to convert.
18
+ #
19
+ # Returns the HTML formatted String.
20
+ def markdownify(input)
21
+ site = @context.registers[:site]
22
+ converter = site.find_converter_instance(Jekyll::Converters::Markdown)
23
+ converter.convert(input.to_s)
24
+ end
25
+
26
+ # Convert quotes into smart quotes.
27
+ #
28
+ # input - The String to convert.
29
+ #
30
+ # Returns the smart-quotified String.
31
+ def smartify(input)
32
+ site = @context.registers[:site]
33
+ converter = site.find_converter_instance(Jekyll::Converters::SmartyPants)
34
+ converter.convert(input.to_s)
35
+ end
36
+
37
+ # Convert a Sass string into CSS output.
38
+ #
39
+ # input - The Sass String to convert.
40
+ #
41
+ # Returns the CSS formatted String.
42
+ def sassify(input)
43
+ site = @context.registers[:site]
44
+ converter = site.find_converter_instance(Jekyll::Converters::Sass)
45
+ converter.convert(input)
46
+ end
47
+
48
+ # Convert a Scss string into CSS output.
49
+ #
50
+ # input - The Scss String to convert.
51
+ #
52
+ # Returns the CSS formatted String.
53
+ def scssify(input)
54
+ site = @context.registers[:site]
55
+ converter = site.find_converter_instance(Jekyll::Converters::Scss)
56
+ converter.convert(input)
57
+ end
58
+
59
+ # Slugify a filename or title.
60
+ #
61
+ # input - The filename or title to slugify.
62
+ # mode - how string is slugified
63
+ #
64
+ # Returns the given filename or title as a lowercase URL String.
65
+ # See Utils.slugify for more detail.
66
+ def slugify(input, mode = nil)
67
+ Utils.slugify(input, :mode => mode)
68
+ end
69
+
70
+ # Format a date in short format e.g. "27 Jan 2011".
71
+ #
72
+ # date - the Time to format.
73
+ #
74
+ # Returns the formatting String.
75
+ def date_to_string(date)
76
+ time(date).strftime("%d %b %Y")
77
+ end
78
+
79
+ # Format a date in long format e.g. "27 January 2011".
80
+ #
81
+ # date - The Time to format.
82
+ #
83
+ # Returns the formatted String.
84
+ def date_to_long_string(date)
85
+ return date if date.to_s.empty?
86
+ time(date).strftime("%d %B %Y")
87
+ end
88
+
89
+ # Format a date for use in XML.
90
+ #
91
+ # date - The Time to format.
92
+ #
93
+ # Examples
94
+ #
95
+ # date_to_xmlschema(Time.now)
96
+ # # => "2011-04-24T20:34:46+08:00"
97
+ #
98
+ # Returns the formatted String.
99
+ def date_to_xmlschema(date)
100
+ return date if date.to_s.empty?
101
+ time(date).xmlschema
102
+ end
103
+
104
+ # Format a date according to RFC-822
105
+ #
106
+ # date - The Time to format.
107
+ #
108
+ # Examples
109
+ #
110
+ # date_to_rfc822(Time.now)
111
+ # # => "Sun, 24 Apr 2011 12:34:46 +0000"
112
+ #
113
+ # Returns the formatted String.
114
+ def date_to_rfc822(date)
115
+ return date if date.to_s.empty?
116
+ time(date).rfc822
117
+ end
118
+
119
+ # XML escape a string for use. Replaces any special characters with
120
+ # appropriate HTML entity replacements.
121
+ #
122
+ # input - The String to escape.
123
+ #
124
+ # Examples
125
+ #
126
+ # xml_escape('foo "bar" <baz>')
127
+ # # => "foo &quot;bar&quot; &lt;baz&gt;"
128
+ #
129
+ # Returns the escaped String.
130
+ def xml_escape(input)
131
+ input.to_s.encode(:xml => :attr).gsub(%r!\A"|"\Z!, "")
132
+ end
133
+
134
+ # CGI escape a string for use in a URL. Replaces any special characters
135
+ # with appropriate %XX replacements.
136
+ #
137
+ # input - The String to escape.
138
+ #
139
+ # Examples
140
+ #
141
+ # cgi_escape('foo,bar;baz?')
142
+ # # => "foo%2Cbar%3Bbaz%3F"
143
+ #
144
+ # Returns the escaped String.
145
+ def cgi_escape(input)
146
+ CGI.escape(input)
147
+ end
148
+
149
+ # URI escape a string.
150
+ #
151
+ # input - The String to escape.
152
+ #
153
+ # Examples
154
+ #
155
+ # uri_escape('foo, bar \\baz?')
156
+ # # => "foo,%20bar%20%5Cbaz?"
157
+ #
158
+ # Returns the escaped String.
159
+ def uri_escape(input)
160
+ Addressable::URI.normalize_component(input)
161
+ end
162
+
163
+ # Replace any whitespace in the input string with a single space
164
+ #
165
+ # input - The String on which to operate.
166
+ #
167
+ # Returns the formatted String
168
+ def normalize_whitespace(input)
169
+ input.to_s.gsub(%r!\s+!, " ").strip
170
+ end
171
+
172
+ # Count the number of words in the input string.
173
+ #
174
+ # input - The String on which to operate.
175
+ #
176
+ # Returns the Integer word count.
177
+ def number_of_words(input)
178
+ input.split.length
179
+ end
180
+
181
+ # Join an array of things into a string by separating with commas and the
182
+ # word "and" for the last one.
183
+ #
184
+ # array - The Array of Strings to join.
185
+ # connector - Word used to connect the last 2 items in the array
186
+ #
187
+ # Examples
188
+ #
189
+ # array_to_sentence_string(["apples", "oranges", "grapes"])
190
+ # # => "apples, oranges, and grapes"
191
+ #
192
+ # Returns the formatted String.
193
+ def array_to_sentence_string(array, connector = "and")
194
+ case array.length
195
+ when 0
196
+ ""
197
+ when 1
198
+ array[0].to_s
199
+ when 2
200
+ "#{array[0]} #{connector} #{array[1]}"
201
+ else
202
+ "#{array[0...-1].join(", ")}, #{connector} #{array[-1]}"
203
+ end
204
+ end
205
+
206
+ # Convert the input into json string
207
+ #
208
+ # input - The Array or Hash to be converted
209
+ #
210
+ # Returns the converted json string
211
+ def jsonify(input)
212
+ as_liquid(input).to_json
213
+ end
214
+
215
+ # Filter an array of objects
216
+ #
217
+ # input - the object array
218
+ # property - property within each object to filter by
219
+ # value - desired value
220
+ #
221
+ # Returns the filtered array of objects
222
+ def where(input, property, value)
223
+ return input unless input.respond_to?(:select)
224
+ input = input.values if input.is_a?(Hash)
225
+ input.select do |object|
226
+ Array(item_property(object, property)).map(&:to_s).include?(value.to_s)
227
+ end || []
228
+ end
229
+
230
+ # Filters an array of objects against an expression
231
+ #
232
+ # input - the object array
233
+ # variable - the variable to assign each item to in the expression
234
+ # expression - a Liquid comparison expression passed in as a string
235
+ #
236
+ # Returns the filtered array of objects
237
+ def where_exp(input, variable, expression)
238
+ return input unless input.respond_to?(:select)
239
+ input = input.values if input.is_a?(Hash) # FIXME
240
+
241
+ condition = parse_condition(expression)
242
+ @context.stack do
243
+ input.select do |object|
244
+ @context[variable] = object
245
+ condition.evaluate(@context)
246
+ end
247
+ end || []
248
+ end
249
+
250
+ # Convert the input into integer
251
+ #
252
+ # input - the object string
253
+ #
254
+ # Returns the integer value
255
+ def to_integer(input)
256
+ return 1 if input == true
257
+ return 0 if input == false
258
+ input.to_i
259
+ end
260
+
261
+ # Sort an array of objects
262
+ #
263
+ # input - the object array
264
+ # property - property within each object to filter by
265
+ # nils ('first' | 'last') - nils appear before or after non-nil values
266
+ #
267
+ # Returns the filtered array of objects
268
+ def sort(input, property = nil, nils = "first")
269
+ if input.nil?
270
+ raise ArgumentError, "Cannot sort a null object."
271
+ end
272
+ if property.nil?
273
+ input.sort
274
+ else
275
+ if nils == "first"
276
+ order = - 1
277
+ elsif nils == "last"
278
+ order = + 1
279
+ else
280
+ raise ArgumentError, "Invalid nils order: " \
281
+ "'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
282
+ end
283
+
284
+ sort_input(input, property, order)
285
+ end
286
+ end
287
+
288
+ def pop(array, num = 1)
289
+ return array unless array.is_a?(Array)
290
+ num = Liquid::Utils.to_integer(num)
291
+ new_ary = array.dup
292
+ new_ary.pop(num)
293
+ new_ary
294
+ end
295
+
296
+ def push(array, input)
297
+ return array unless array.is_a?(Array)
298
+ new_ary = array.dup
299
+ new_ary.push(input)
300
+ new_ary
301
+ end
302
+
303
+ def shift(array, num = 1)
304
+ return array unless array.is_a?(Array)
305
+ num = Liquid::Utils.to_integer(num)
306
+ new_ary = array.dup
307
+ new_ary.shift(num)
308
+ new_ary
309
+ end
310
+
311
+ def unshift(array, input)
312
+ return array unless array.is_a?(Array)
313
+ new_ary = array.dup
314
+ new_ary.unshift(input)
315
+ new_ary
316
+ end
317
+
318
+ def sample(input, num = 1)
319
+ return input unless input.respond_to?(:sample)
320
+ num = Liquid::Utils.to_integer(num) rescue 1
321
+ if num == 1
322
+ input.sample
323
+ else
324
+ input.sample(num)
325
+ end
326
+ end
327
+
328
+ # Convert an object into its String representation for debugging
329
+ #
330
+ # input - The Object to be converted
331
+ #
332
+ # Returns a String representation of the object.
333
+ def inspect(input)
334
+ xml_escape(input.inspect)
335
+ end
336
+
337
+ private
338
+
339
+ # Sort the input Enumerable by the given property.
340
+ # If the property doesn't exist, return the sort order respective of
341
+ # which item doesn't have the property.
342
+ # We also utilize the Schwartzian transform to make this more efficient.
343
+ def sort_input(input, property, order)
344
+ input.map { |item| [item_property(item, property), item] }
345
+ .sort! do |apple_info, orange_info|
346
+ apple_property = apple_info.first
347
+ orange_property = orange_info.first
348
+
349
+ if !apple_property.nil? && orange_property.nil?
350
+ - order
351
+ elsif apple_property.nil? && !orange_property.nil?
352
+ + order
353
+ else
354
+ apple_property <=> orange_property
355
+ end
356
+ end
357
+ .map!(&:last)
358
+ end
359
+
360
+ private
361
+ def time(input)
362
+ date = Liquid::Utils.to_date(input)
363
+ unless date.respond_to?(:to_time)
364
+ raise Errors::InvalidDateError,
365
+ "Invalid Date: '#{input.inspect}' is not a valid datetime."
366
+ end
367
+ date.to_time.dup.localtime
368
+ end
369
+
370
+ private
371
+ def item_property(item, property)
372
+ if item.respond_to?(:to_liquid)
373
+ property.to_s.split(".").reduce(item.to_liquid) do |subvalue, attribute|
374
+ subvalue[attribute]
375
+ end
376
+ elsif item.respond_to?(:data)
377
+ item.data[property.to_s]
378
+ else
379
+ item[property.to_s]
380
+ end
381
+ end
382
+
383
+ private
384
+ def as_liquid(item)
385
+ case item
386
+ when Hash
387
+ pairs = item.map { |k, v| as_liquid([k, v]) }
388
+ Hash[pairs]
389
+ when Array
390
+ item.map { |i| as_liquid(i) }
391
+ else
392
+ if item.respond_to?(:to_liquid)
393
+ liquidated = item.to_liquid
394
+ # prevent infinite recursion for simple types (which return `self`)
395
+ if liquidated == item
396
+ item
397
+ else
398
+ as_liquid(liquidated)
399
+ end
400
+ else
401
+ item
402
+ end
403
+ end
404
+ end
405
+
406
+ # Parse a string to a Liquid Condition
407
+ private
408
+ def parse_condition(exp)
409
+ parser = Liquid::Parser.new(exp)
410
+ left_expr = parser.expression
411
+ operator = parser.consume?(:comparison)
412
+ condition =
413
+ if operator
414
+ Liquid::Condition.new(Liquid::Expression.parse(left_expr),
415
+ operator,
416
+ Liquid::Expression.parse(parser.expression))
417
+ else
418
+ Liquid::Condition.new(Liquid::Expression.parse(left_expr))
419
+ end
420
+ parser.consume(:end_of_string)
421
+
422
+ condition
423
+ end
424
+
425
+ end
426
+ end
427
+
428
+ Liquid::Template.register_filter(
429
+ Jekyll::Filters
430
+ )