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,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Kramdown::Parser::SmartyPants < Kramdown::Parser::Kramdown
4
+ def initialize(source, options)
5
+ super
6
+ @block_parsers = [:block_html]
7
+ @span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
8
+ end
9
+ end
10
+
11
+ module Jekyll
12
+ module Converters
13
+ class SmartyPants < Converter
14
+ safe true
15
+ priority :low
16
+
17
+ def initialize(config)
18
+ Jekyll::External.require_with_graceful_fail "kramdown"
19
+ @config = config["kramdown"].dup || {}
20
+ @config[:input] = :SmartyPants
21
+ end
22
+
23
+ def matches(_)
24
+ false
25
+ end
26
+
27
+ def output_ext(_)
28
+ nil
29
+ end
30
+
31
+ def convert(content)
32
+ Kramdown::Document.new(content, @config).to_html.chomp
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,251 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ # Convertible provides methods for converting a pagelike item
6
+ # from a certain type of markup into actual content
7
+ #
8
+ # Requires
9
+ # self.site -> Jekyll::Site
10
+ # self.content
11
+ # self.content=
12
+ # self.data=
13
+ # self.ext=
14
+ # self.output=
15
+ # self.name
16
+ # self.path
17
+ # self.type -> :page, :post or :draft
18
+
19
+ module Jekyll
20
+ module Convertible
21
+ # Returns the contents as a String.
22
+ def to_s
23
+ content || ""
24
+ end
25
+
26
+ # Whether the file is published or not, as indicated in YAML front-matter
27
+ def published?
28
+ !(data.key?("published") && data["published"] == false)
29
+ end
30
+
31
+ # Read the YAML frontmatter.
32
+ #
33
+ # base - The String path to the dir containing the file.
34
+ # name - The String filename of the file.
35
+ # opts - optional parameter to File.read, default at site configs
36
+ #
37
+ # Returns nothing.
38
+ # rubocop:disable Metrics/AbcSize
39
+ def read_yaml(base, name, opts = {})
40
+ filename = File.join(base, name)
41
+
42
+ begin
43
+ self.content = File.read(@path || site.in_source_dir(base, name),
44
+ Utils.merged_file_read_opts(site, opts))
45
+ if content =~ Document::YAML_FRONT_MATTER_REGEXP
46
+ self.content = $POSTMATCH
47
+ self.data = SafeYAML.load(Regexp.last_match(1))
48
+ end
49
+ rescue SyntaxError => e
50
+ Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
51
+ raise e if self.site.config["strict_front_matter"]
52
+ rescue => e
53
+ Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
54
+ raise e if self.site.config["strict_front_matter"]
55
+ end
56
+
57
+ self.data ||= {}
58
+
59
+ validate_data! filename
60
+ validate_permalink! filename
61
+
62
+ self.data
63
+ end
64
+ # rubocop:enable Metrics/AbcSize
65
+
66
+ def validate_data!(filename)
67
+ unless self.data.is_a?(Hash)
68
+ raise Errors::InvalidYAMLFrontMatterError,
69
+ "Invalid YAML front matter in #{filename}"
70
+ end
71
+ end
72
+
73
+ def validate_permalink!(filename)
74
+ if self.data["permalink"] && self.data["permalink"].to_s.empty?
75
+ raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
76
+ end
77
+ end
78
+
79
+ # Transform the contents based on the content type.
80
+ #
81
+ # Returns the transformed contents.
82
+ def transform
83
+ _renderer.convert(content)
84
+ end
85
+
86
+ # Determine the extension depending on content_type.
87
+ #
88
+ # Returns the String extension for the output file.
89
+ # e.g. ".html" for an HTML output file.
90
+ def output_ext
91
+ _renderer.output_ext
92
+ end
93
+
94
+ # Determine which converter to use based on this convertible's
95
+ # extension.
96
+ #
97
+ # Returns the Converter instance.
98
+ def converters
99
+ _renderer.converters
100
+ end
101
+
102
+ # Render Liquid in the content
103
+ #
104
+ # content - the raw Liquid content to render
105
+ # payload - the payload for Liquid
106
+ # info - the info for Liquid
107
+ #
108
+ # Returns the converted content
109
+ def render_liquid(content, payload, info, path)
110
+ _renderer.render_liquid(content, payload, info, path)
111
+ end
112
+ # rubocop: enable RescueException
113
+
114
+ # Convert this Convertible's data to a Hash suitable for use by Liquid.
115
+ #
116
+ # Returns the Hash representation of this Convertible.
117
+ def to_liquid(attrs = nil)
118
+ further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map do |attribute|
119
+ [attribute, send(attribute)]
120
+ end]
121
+
122
+ defaults = site.frontmatter_defaults.all(relative_path, type)
123
+ Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
124
+ end
125
+
126
+ # The type of a document,
127
+ # i.e., its classname downcase'd and to_sym'd.
128
+ #
129
+ # Returns the type of self.
130
+ def type
131
+ if is_a?(Page)
132
+ :pages
133
+ end
134
+ end
135
+
136
+ # returns the owner symbol for hook triggering
137
+ def hook_owner
138
+ if is_a?(Page)
139
+ :pages
140
+ end
141
+ end
142
+
143
+ # Determine whether the document is an asset file.
144
+ # Asset files include CoffeeScript files and Sass/SCSS files.
145
+ #
146
+ # Returns true if the extname belongs to the set of extensions
147
+ # that asset files use.
148
+ def asset_file?
149
+ sass_file? || coffeescript_file?
150
+ end
151
+
152
+ # Determine whether the document is a Sass file.
153
+ #
154
+ # Returns true if extname == .sass or .scss, false otherwise.
155
+ def sass_file?
156
+ %w(.sass .scss).include?(ext)
157
+ end
158
+
159
+ # Determine whether the document is a CoffeeScript file.
160
+ #
161
+ # Returns true if extname == .coffee, false otherwise.
162
+ def coffeescript_file?
163
+ ext == ".coffee"
164
+ end
165
+
166
+ # Determine whether the file should be rendered with Liquid.
167
+ #
168
+ # Always returns true.
169
+ def render_with_liquid?
170
+ true
171
+ end
172
+
173
+ # Determine whether the file should be placed into layouts.
174
+ #
175
+ # Returns false if the document is an asset file.
176
+ def place_in_layout?
177
+ !asset_file?
178
+ end
179
+
180
+ # Checks if the layout specified in the document actually exists
181
+ #
182
+ # layout - the layout to check
183
+ #
184
+ # Returns true if the layout is invalid, false if otherwise
185
+ def invalid_layout?(layout)
186
+ !data["layout"].nil? && layout.nil? && !(self.is_a? Jekyll::Excerpt)
187
+ end
188
+
189
+ # Recursively render layouts
190
+ #
191
+ # layouts - a list of the layouts
192
+ # payload - the payload for Liquid
193
+ # info - the info for Liquid
194
+ #
195
+ # Returns nothing
196
+ def render_all_layouts(layouts, payload, info)
197
+ _renderer.layouts = layouts
198
+ self.output = _renderer.place_in_layouts(output, payload, info)
199
+ ensure
200
+ @_renderer = nil # this will allow the modifications above to disappear
201
+ end
202
+
203
+ # Add any necessary layouts to this convertible document.
204
+ #
205
+ # payload - The site payload Drop or Hash.
206
+ # layouts - A Hash of {"name" => "layout"}.
207
+ #
208
+ # Returns nothing.
209
+ def do_layout(payload, layouts)
210
+ self.output = _renderer.tap do |renderer|
211
+ renderer.layouts = layouts
212
+ renderer.payload = payload
213
+ end.run
214
+
215
+ Jekyll.logger.debug "Post-Render Hooks:", self.relative_path
216
+ Jekyll::Hooks.trigger hook_owner, :post_render, self
217
+ ensure
218
+ @_renderer = nil # this will allow the modifications above to disappear
219
+ end
220
+
221
+ # Write the generated page file to the destination directory.
222
+ #
223
+ # dest - The String path to the destination dir.
224
+ #
225
+ # Returns nothing.
226
+ def write(dest)
227
+ path = destination(dest)
228
+ FileUtils.mkdir_p(File.dirname(path))
229
+ File.write(path, output, :mode => "wb")
230
+ Jekyll::Hooks.trigger hook_owner, :post_write, self
231
+ end
232
+
233
+ # Accessor for data properties by Liquid.
234
+ #
235
+ # property - The String name of the property to retrieve.
236
+ #
237
+ # Returns the String value or nil if the property isn't included.
238
+ def [](property)
239
+ if self.class::ATTRIBUTES_FOR_LIQUID.include?(property)
240
+ send(property)
241
+ else
242
+ data[property]
243
+ end
244
+ end
245
+
246
+ private
247
+ def _renderer
248
+ @_renderer ||= Jekyll::Renderer.new(site, self)
249
+ end
250
+ end
251
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Deprecator
5
+ extend self
6
+
7
+ def process(args)
8
+ arg_is_present? args, "--server", "The --server command has been replaced by the \
9
+ 'serve' subcommand."
10
+ arg_is_present? args, "--serve", "The --serve command has been replaced by the \
11
+ 'serve' subcommand."
12
+ arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
13
+ use the 'build' subcommand."
14
+ arg_is_present? args, "--auto", "The switch '--auto' has been replaced with \
15
+ '--watch'."
16
+ arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
17
+ the '--watch' switch."
18
+ arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \
19
+ favour of 'highlighter'."
20
+ arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in \
21
+ your config files."
22
+ arg_is_present? args, "--url", "The 'url' setting can only be set in your \
23
+ config files."
24
+ no_subcommand(args)
25
+ end
26
+
27
+ def no_subcommand(args)
28
+ unless args.empty? ||
29
+ args.first !~ %r(!/^--/!) || %w(--help --version).include?(args.first)
30
+ deprecation_message "Jekyll now uses subcommands instead of just switches. \
31
+ Run `jekyll help` to find out more."
32
+ abort
33
+ end
34
+ end
35
+
36
+ def arg_is_present?(args, deprecated_argument, message)
37
+ if args.include?(deprecated_argument)
38
+ deprecation_message(message)
39
+ end
40
+ end
41
+
42
+ def deprecation_message(message)
43
+ Jekyll.logger.warn "Deprecation:", message
44
+ end
45
+
46
+ def defaults_deprecate_type(old, current)
47
+ Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
48
+ Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use \
49
+ 'type: #{current}'."
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,507 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Document
5
+ include Comparable
6
+ extend Forwardable
7
+
8
+ attr_reader :path, :site, :extname, :collection
9
+ attr_accessor :content, :output
10
+
11
+ def_delegator :self, :read_post_data, :post_read
12
+
13
+ YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
14
+ DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!
15
+ DATE_FILENAME_MATCHER = %r!^(?:.+/)*(\d{2,4}-\d{1,2}-\d{1,2})-(.*)(\.[^.]+)$!
16
+
17
+ # Create a new Document.
18
+ #
19
+ # path - the path to the file
20
+ # relations - a hash with keys :site and :collection, the values of which
21
+ # are the Jekyll::Site and Jekyll::Collection to which this
22
+ # Document belong.
23
+ #
24
+ # Returns nothing.
25
+ def initialize(path, relations = {})
26
+ @site = relations[:site]
27
+ @path = path
28
+ @extname = File.extname(path)
29
+ @collection = relations[:collection]
30
+ @has_yaml_header = nil
31
+
32
+ if draft?
33
+ categories_from_path("_drafts")
34
+ else
35
+ categories_from_path(collection.relative_directory)
36
+ end
37
+
38
+ data.default_proc = proc do |_, key|
39
+ site.frontmatter_defaults.find(relative_path, collection.label, key)
40
+ end
41
+
42
+ trigger_hooks(:post_init)
43
+ end
44
+
45
+ # Fetch the Document's data.
46
+ #
47
+ # Returns a Hash containing the data. An empty hash is returned if
48
+ # no data was read.
49
+ def data
50
+ @data ||= {}
51
+ end
52
+
53
+ # Merge some data in with this document's data.
54
+ #
55
+ # Returns the merged data.
56
+ def merge_data!(other, source: "YAML front matter")
57
+ merge_categories!(other)
58
+ Utils.deep_merge_hashes!(data, other)
59
+ merge_date!(source)
60
+ data
61
+ end
62
+
63
+ def date
64
+ data["date"] ||= (draft? ? source_file_mtime : site.time)
65
+ end
66
+
67
+ def source_file_mtime
68
+ @source_file_mtime ||= File.mtime(path)
69
+ end
70
+
71
+ # Returns whether the document is a draft. This is only the case if
72
+ # the document is in the 'posts' collection but in a different
73
+ # directory than '_posts'.
74
+ #
75
+ # Returns whether the document is a draft.
76
+ def draft?
77
+ data["draft"] ||= relative_path.index(collection.relative_directory).nil? &&
78
+ collection.label == "posts"
79
+ end
80
+
81
+ # The path to the document, relative to the site source.
82
+ #
83
+ # Returns a String path which represents the relative path
84
+ # from the site source to this document
85
+ def relative_path
86
+ @relative_path ||= Pathutil.new(path).relative_path_from(site.source).to_s
87
+ end
88
+
89
+ # The output extension of the document.
90
+ #
91
+ # Returns the output extension
92
+ def output_ext
93
+ Jekyll::Renderer.new(site, self).output_ext
94
+ end
95
+
96
+ # The base filename of the document, without the file extname.
97
+ #
98
+ # Returns the basename without the file extname.
99
+ def basename_without_ext
100
+ @basename_without_ext ||= File.basename(path, ".*")
101
+ end
102
+
103
+ # The base filename of the document.
104
+ #
105
+ # Returns the base filename of the document.
106
+ def basename
107
+ @basename ||= File.basename(path)
108
+ end
109
+
110
+ # Produces a "cleaned" relative path.
111
+ # The "cleaned" relative path is the relative path without the extname
112
+ # and with the collection's directory removed as well.
113
+ # This method is useful when building the URL of the document.
114
+ #
115
+ # Examples:
116
+ # When relative_path is "_methods/site/generate.md":
117
+ # cleaned_relative_path
118
+ # # => "/site/generate"
119
+ #
120
+ # Returns the cleaned relative path of the document.
121
+ def cleaned_relative_path
122
+ @cleaned_relative_path ||=
123
+ relative_path[0..-extname.length - 1].sub(collection.relative_directory, "")
124
+ end
125
+
126
+ # Determine whether the document is a YAML file.
127
+ #
128
+ # Returns true if the extname is either .yml or .yaml, false otherwise.
129
+ def yaml_file?
130
+ %w(.yaml .yml).include?(extname)
131
+ end
132
+
133
+ # Determine whether the document is an asset file.
134
+ # Asset files include CoffeeScript files and Sass/SCSS files.
135
+ #
136
+ # Returns true if the extname belongs to the set of extensions
137
+ # that asset files use.
138
+ def asset_file?
139
+ sass_file? || coffeescript_file?
140
+ end
141
+
142
+ # Determine whether the document is a Sass file.
143
+ #
144
+ # Returns true if extname == .sass or .scss, false otherwise.
145
+ def sass_file?
146
+ %w(.sass .scss).include?(extname)
147
+ end
148
+
149
+ # Determine whether the document is a CoffeeScript file.
150
+ #
151
+ # Returns true if extname == .coffee, false otherwise.
152
+ def coffeescript_file?
153
+ extname == ".coffee"
154
+ end
155
+
156
+ # Determine whether the file should be rendered with Liquid.
157
+ #
158
+ # Returns false if the document is either an asset file or a yaml file,
159
+ # true otherwise.
160
+ def render_with_liquid?
161
+ !(coffeescript_file? || yaml_file?)
162
+ end
163
+
164
+ # Determine whether the file should be rendered with a layout.
165
+ #
166
+ # Returns true if the Front Matter specifies that `layout` is set to `none`.
167
+ def no_layout?
168
+ data["layout"] == "none"
169
+ end
170
+
171
+ # Determine whether the file should be placed into layouts.
172
+ #
173
+ # Returns false if the document is set to `layouts: none`, or is either an
174
+ # asset file or a yaml file. Returns true otherwise.
175
+ def place_in_layout?
176
+ !(asset_file? || yaml_file? || no_layout?)
177
+ end
178
+
179
+ # The URL template where the document would be accessible.
180
+ #
181
+ # Returns the URL template for the document.
182
+ def url_template
183
+ collection.url_template
184
+ end
185
+
186
+ # Construct a Hash of key-value pairs which contain a mapping between
187
+ # a key in the URL template and the corresponding value for this document.
188
+ #
189
+ # Returns the Hash of key-value pairs for replacement in the URL.
190
+ def url_placeholders
191
+ @url_placeholders ||= Drops::UrlDrop.new(self)
192
+ end
193
+
194
+ # The permalink for this Document.
195
+ # Permalink is set via the data Hash.
196
+ #
197
+ # Returns the permalink or nil if no permalink was set in the data.
198
+ def permalink
199
+ data && data.is_a?(Hash) && data["permalink"]
200
+ end
201
+
202
+ # The computed URL for the document. See `Jekyll::URL#to_s` for more details.
203
+ #
204
+ # Returns the computed URL for the document.
205
+ def url
206
+ @url ||= URL.new({
207
+ :template => url_template,
208
+ :placeholders => url_placeholders,
209
+ :permalink => permalink,
210
+ }).to_s
211
+ end
212
+
213
+ def [](key)
214
+ data[key]
215
+ end
216
+
217
+ # The full path to the output file.
218
+ #
219
+ # base_directory - the base path of the output directory
220
+ #
221
+ # Returns the full path to the output file of this document.
222
+ def destination(base_directory)
223
+ dest = site.in_dest_dir(base_directory)
224
+ path = site.in_dest_dir(dest, URL.unescape_path(url))
225
+ if url.end_with? "/"
226
+ path = File.join(path, "index.html")
227
+ else
228
+ path << output_ext unless path.end_with? output_ext
229
+ end
230
+ path
231
+ end
232
+
233
+ # Write the generated Document file to the destination directory.
234
+ #
235
+ # dest - The String path to the destination dir.
236
+ #
237
+ # Returns nothing.
238
+ def write(dest)
239
+ path = destination(dest)
240
+ FileUtils.mkdir_p(File.dirname(path))
241
+ File.write(path, output, :mode => "wb")
242
+
243
+ trigger_hooks(:post_write)
244
+ end
245
+
246
+ # Whether the file is published or not, as indicated in YAML front-matter
247
+ #
248
+ # Returns 'false' if the 'published' key is specified in the
249
+ # YAML front-matter and is 'false'. Otherwise returns 'true'.
250
+ def published?
251
+ !(data.key?("published") && data["published"] == false)
252
+ end
253
+
254
+ # Read in the file and assign the content and data based on the file contents.
255
+ # Merge the frontmatter of the file with the frontmatter default
256
+ # values
257
+ #
258
+ # Returns nothing.
259
+ def read(opts = {})
260
+ Jekyll.logger.debug "Reading:", relative_path
261
+
262
+ if yaml_file?
263
+ @data = SafeYAML.load_file(path)
264
+ else
265
+ begin
266
+ merge_defaults
267
+ read_content(opts)
268
+ read_post_data
269
+ rescue => e
270
+ handle_read_error(e)
271
+ end
272
+ end
273
+ end
274
+
275
+ # Create a Liquid-understandable version of this Document.
276
+ #
277
+ # Returns a Hash representing this Document's data.
278
+ def to_liquid
279
+ @to_liquid ||= Drops::DocumentDrop.new(self)
280
+ end
281
+
282
+ # The inspect string for this document.
283
+ # Includes the relative path and the collection label.
284
+ #
285
+ # Returns the inspect string for this document.
286
+ def inspect
287
+ "#<Jekyll::Document #{relative_path} collection=#{collection.label}>"
288
+ end
289
+
290
+ # The string representation for this document.
291
+ #
292
+ # Returns the content of the document
293
+ def to_s
294
+ output || content || "NO CONTENT"
295
+ end
296
+
297
+ # Compare this document against another document.
298
+ # Comparison is a comparison between the 2 paths of the documents.
299
+ #
300
+ # Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
301
+ # equal or greater than the other doc's path. See String#<=> for more details.
302
+ def <=>(other)
303
+ return nil unless other.respond_to?(:data)
304
+ cmp = data["date"] <=> other.data["date"]
305
+ cmp = path <=> other.path if cmp.nil? || cmp.zero?
306
+ cmp
307
+ end
308
+
309
+ # Determine whether this document should be written.
310
+ # Based on the Collection to which it belongs.
311
+ #
312
+ # True if the document has a collection and if that collection's #write?
313
+ # method returns true, otherwise false.
314
+ def write?
315
+ collection && collection.write?
316
+ end
317
+
318
+ # The Document excerpt_separator, from the YAML Front-Matter or site
319
+ # default excerpt_separator value
320
+ #
321
+ # Returns the document excerpt_separator
322
+ def excerpt_separator
323
+ (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
324
+ end
325
+
326
+ # Whether to generate an excerpt
327
+ #
328
+ # Returns true if the excerpt separator is configured.
329
+ def generate_excerpt?
330
+ !excerpt_separator.empty?
331
+ end
332
+
333
+ def next_doc
334
+ pos = collection.docs.index { |post| post.equal?(self) }
335
+ if pos && pos < collection.docs.length - 1
336
+ collection.docs[pos + 1]
337
+ end
338
+ end
339
+
340
+ def previous_doc
341
+ pos = collection.docs.index { |post| post.equal?(self) }
342
+ if pos && pos > 0
343
+ collection.docs[pos - 1]
344
+ end
345
+ end
346
+
347
+ def trigger_hooks(hook_name, *args)
348
+ Jekyll::Hooks.trigger collection.label.to_sym, hook_name, self, *args if collection
349
+ Jekyll::Hooks.trigger :documents, hook_name, self, *args
350
+ end
351
+
352
+ def id
353
+ @id ||= File.join(File.dirname(url), (data["slug"] || basename_without_ext).to_s)
354
+ end
355
+
356
+ # Calculate related posts.
357
+ #
358
+ # Returns an Array of related Posts.
359
+ def related_posts
360
+ Jekyll::RelatedPosts.new(self).build
361
+ end
362
+
363
+ # Override of normal respond_to? to match method_missing's logic for
364
+ # looking in @data.
365
+ def respond_to?(method, include_private = false)
366
+ data.key?(method.to_s) || super
367
+ end
368
+
369
+ # Override of method_missing to check in @data for the key.
370
+ def method_missing(method, *args, &blck)
371
+ if data.key?(method.to_s)
372
+ Jekyll::Deprecator.deprecation_message "Document##{method} is now a key "\
373
+ "in the #data hash."
374
+ Jekyll::Deprecator.deprecation_message "Called by #{caller(0..0)}."
375
+ data[method.to_s]
376
+ else
377
+ super
378
+ end
379
+ end
380
+
381
+ def respond_to_missing?(method, *)
382
+ data.key?(method.to_s) || super
383
+ end
384
+
385
+ # Add superdirectories of the special_dir to categories.
386
+ # In the case of es/_posts, 'es' is added as a category.
387
+ # In the case of _posts/es, 'es' is NOT added as a category.
388
+ #
389
+ # Returns nothing.
390
+ def categories_from_path(special_dir)
391
+ superdirs = relative_path.sub(%r!#{special_dir}(.*)!, "")
392
+ .split(File::SEPARATOR)
393
+ .reject do |c|
394
+ c.empty? || c == special_dir || c == basename
395
+ end
396
+ merge_data!({ "categories" => superdirs }, :source => "file path")
397
+ end
398
+
399
+ def populate_categories
400
+ merge_data!({
401
+ "categories" => (
402
+ Array(data["categories"]) + Utils.pluralized_array_from_hash(
403
+ data,
404
+ "category",
405
+ "categories"
406
+ )
407
+ ).map(&:to_s).flatten.uniq,
408
+ })
409
+ end
410
+
411
+ def populate_tags
412
+ merge_data!({
413
+ "tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten,
414
+ })
415
+ end
416
+
417
+ private
418
+ def merge_categories!(other)
419
+ if other.key?("categories") && !other["categories"].nil?
420
+ if other["categories"].is_a?(String)
421
+ other["categories"] = other["categories"].split(%r!\s+!).map(&:strip)
422
+ end
423
+ other["categories"] = (data["categories"] || []) | other["categories"]
424
+ end
425
+ end
426
+
427
+ private
428
+ def merge_date!(source)
429
+ if data.key?("date") && !data["date"].is_a?(Time)
430
+ data["date"] = Utils.parse_date(
431
+ data["date"].to_s,
432
+ "Document '#{relative_path}' does not have a valid date in the #{source}."
433
+ )
434
+ end
435
+ end
436
+
437
+ private
438
+ def merge_defaults
439
+ defaults = @site.frontmatter_defaults.all(
440
+ relative_path,
441
+ collection.label.to_sym
442
+ )
443
+ merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
444
+ end
445
+
446
+ private
447
+ def read_content(opts)
448
+ self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
449
+ if content =~ YAML_FRONT_MATTER_REGEXP
450
+ self.content = $POSTMATCH
451
+ data_file = SafeYAML.load(Regexp.last_match(1))
452
+ merge_data!(data_file, :source => "YAML front matter") if data_file
453
+ end
454
+ end
455
+
456
+ private
457
+ def read_post_data
458
+ populate_title
459
+ populate_categories
460
+ populate_tags
461
+ generate_excerpt
462
+ end
463
+
464
+ private
465
+ def handle_read_error(error)
466
+ if error.is_a? SyntaxError
467
+ Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
468
+ else
469
+ Jekyll.logger.error "Error:", "could not read file #{path}: #{error.message}"
470
+ end
471
+
472
+ if site.config["strict_front_matter"] || error.is_a?(Jekyll::Errors::FatalException)
473
+ raise error
474
+ end
475
+ end
476
+
477
+ private
478
+ def populate_title
479
+ if relative_path =~ DATE_FILENAME_MATCHER
480
+ date, slug, ext = Regexp.last_match.captures
481
+ modify_date(date)
482
+ elsif relative_path =~ DATELESS_FILENAME_MATCHER
483
+ slug, ext = Regexp.last_match.captures
484
+ end
485
+
486
+ # Try to ensure the user gets a title.
487
+ data["title"] ||= Utils.titleize_slug(slug)
488
+ # Only overwrite slug & ext if they aren't specified.
489
+ data["slug"] ||= slug
490
+ data["ext"] ||= ext
491
+ end
492
+
493
+ private
494
+ def modify_date(date)
495
+ if !data["date"] || data["date"].to_i == site.time.to_i
496
+ merge_data!({ "date" => date }, :source => "filename")
497
+ end
498
+ end
499
+
500
+ private
501
+ def generate_excerpt
502
+ if generate_excerpt?
503
+ data["excerpt"] ||= Jekyll::Excerpt.new(self)
504
+ end
505
+ end
506
+ end
507
+ end