ngage 0.0.0

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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/exe/ngage +55 -0
  4. data/lib/ngage.rb +3 -0
  5. data/lib/ngage/jekyll.rb +204 -0
  6. data/lib/ngage/jekyll/cleaner.rb +111 -0
  7. data/lib/ngage/jekyll/collection.rb +235 -0
  8. data/lib/ngage/jekyll/command.rb +103 -0
  9. data/lib/ngage/jekyll/commands/build.rb +93 -0
  10. data/lib/ngage/jekyll/commands/clean.rb +45 -0
  11. data/lib/ngage/jekyll/commands/doctor.rb +173 -0
  12. data/lib/ngage/jekyll/commands/help.rb +34 -0
  13. data/lib/ngage/jekyll/commands/new.rb +157 -0
  14. data/lib/ngage/jekyll/commands/new_theme.rb +42 -0
  15. data/lib/ngage/jekyll/commands/serve.rb +354 -0
  16. data/lib/ngage/jekyll/commands/serve/live_reload_reactor.rb +122 -0
  17. data/lib/ngage/jekyll/commands/serve/livereload_assets/livereload.js +1183 -0
  18. data/lib/ngage/jekyll/commands/serve/servlet.rb +203 -0
  19. data/lib/ngage/jekyll/commands/serve/websockets.rb +81 -0
  20. data/lib/ngage/jekyll/configuration.rb +391 -0
  21. data/lib/ngage/jekyll/converter.rb +54 -0
  22. data/lib/ngage/jekyll/converters/identity.rb +41 -0
  23. data/lib/ngage/jekyll/converters/markdown.rb +116 -0
  24. data/lib/ngage/jekyll/converters/markdown/kramdown_parser.rb +122 -0
  25. data/lib/ngage/jekyll/converters/smartypants.rb +70 -0
  26. data/lib/ngage/jekyll/convertible.rb +253 -0
  27. data/lib/ngage/jekyll/deprecator.rb +50 -0
  28. data/lib/ngage/jekyll/document.rb +503 -0
  29. data/lib/ngage/jekyll/drops/collection_drop.rb +20 -0
  30. data/lib/ngage/jekyll/drops/document_drop.rb +69 -0
  31. data/lib/ngage/jekyll/drops/drop.rb +209 -0
  32. data/lib/ngage/jekyll/drops/excerpt_drop.rb +15 -0
  33. data/lib/ngage/jekyll/drops/jekyll_drop.rb +32 -0
  34. data/lib/ngage/jekyll/drops/site_drop.rb +56 -0
  35. data/lib/ngage/jekyll/drops/static_file_drop.rb +14 -0
  36. data/lib/ngage/jekyll/drops/unified_payload_drop.rb +26 -0
  37. data/lib/ngage/jekyll/drops/url_drop.rb +89 -0
  38. data/lib/ngage/jekyll/entry_filter.rb +127 -0
  39. data/lib/ngage/jekyll/errors.rb +20 -0
  40. data/lib/ngage/jekyll/excerpt.rb +180 -0
  41. data/lib/ngage/jekyll/external.rb +76 -0
  42. data/lib/ngage/jekyll/filters.rb +390 -0
  43. data/lib/ngage/jekyll/filters/date_filters.rb +110 -0
  44. data/lib/ngage/jekyll/filters/grouping_filters.rb +64 -0
  45. data/lib/ngage/jekyll/filters/url_filters.rb +68 -0
  46. data/lib/ngage/jekyll/frontmatter_defaults.rb +233 -0
  47. data/lib/ngage/jekyll/generator.rb +5 -0
  48. data/lib/ngage/jekyll/hooks.rb +106 -0
  49. data/lib/ngage/jekyll/layout.rb +62 -0
  50. data/lib/ngage/jekyll/liquid_extensions.rb +22 -0
  51. data/lib/ngage/jekyll/liquid_renderer.rb +63 -0
  52. data/lib/ngage/jekyll/liquid_renderer/file.rb +56 -0
  53. data/lib/ngage/jekyll/liquid_renderer/table.rb +98 -0
  54. data/lib/ngage/jekyll/log_adapter.rb +151 -0
  55. data/lib/ngage/jekyll/mime.types +825 -0
  56. data/lib/ngage/jekyll/page.rb +185 -0
  57. data/lib/ngage/jekyll/page_without_a_file.rb +14 -0
  58. data/lib/ngage/jekyll/plugin.rb +92 -0
  59. data/lib/ngage/jekyll/plugin_manager.rb +115 -0
  60. data/lib/ngage/jekyll/publisher.rb +23 -0
  61. data/lib/ngage/jekyll/reader.rb +154 -0
  62. data/lib/ngage/jekyll/readers/collection_reader.rb +22 -0
  63. data/lib/ngage/jekyll/readers/data_reader.rb +75 -0
  64. data/lib/ngage/jekyll/readers/layout_reader.rb +70 -0
  65. data/lib/ngage/jekyll/readers/page_reader.rb +25 -0
  66. data/lib/ngage/jekyll/readers/post_reader.rb +72 -0
  67. data/lib/ngage/jekyll/readers/static_file_reader.rb +25 -0
  68. data/lib/ngage/jekyll/readers/theme_assets_reader.rb +51 -0
  69. data/lib/ngage/jekyll/regenerator.rb +195 -0
  70. data/lib/ngage/jekyll/related_posts.rb +52 -0
  71. data/lib/ngage/jekyll/renderer.rb +266 -0
  72. data/lib/ngage/jekyll/site.rb +476 -0
  73. data/lib/ngage/jekyll/static_file.rb +169 -0
  74. data/lib/ngage/jekyll/stevenson.rb +60 -0
  75. data/lib/ngage/jekyll/tags/highlight.rb +108 -0
  76. data/lib/ngage/jekyll/tags/include.rb +226 -0
  77. data/lib/ngage/jekyll/tags/link.rb +40 -0
  78. data/lib/ngage/jekyll/tags/post_url.rb +104 -0
  79. data/lib/ngage/jekyll/theme.rb +73 -0
  80. data/lib/ngage/jekyll/theme_builder.rb +121 -0
  81. data/lib/ngage/jekyll/url.rb +160 -0
  82. data/lib/ngage/jekyll/utils.rb +370 -0
  83. data/lib/ngage/jekyll/utils/ansi.rb +57 -0
  84. data/lib/ngage/jekyll/utils/exec.rb +26 -0
  85. data/lib/ngage/jekyll/utils/internet.rb +37 -0
  86. data/lib/ngage/jekyll/utils/platforms.rb +82 -0
  87. data/lib/ngage/jekyll/utils/thread_event.rb +31 -0
  88. data/lib/ngage/jekyll/utils/win_tz.rb +75 -0
  89. data/lib/ngage/site_template/.gitignore +5 -0
  90. data/lib/ngage/site_template/404.html +25 -0
  91. data/lib/ngage/site_template/_config.yml +47 -0
  92. data/lib/ngage/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -0
  93. data/lib/ngage/site_template/about.markdown +18 -0
  94. data/lib/ngage/site_template/index.markdown +6 -0
  95. data/lib/ngage/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  96. data/lib/ngage/theme_template/Gemfile +4 -0
  97. data/lib/ngage/theme_template/LICENSE.txt.erb +21 -0
  98. data/lib/ngage/theme_template/README.md.erb +52 -0
  99. data/lib/ngage/theme_template/_layouts/default.html +1 -0
  100. data/lib/ngage/theme_template/_layouts/page.html +5 -0
  101. data/lib/ngage/theme_template/_layouts/post.html +5 -0
  102. data/lib/ngage/theme_template/example/_config.yml.erb +1 -0
  103. data/lib/ngage/theme_template/example/_post.md +12 -0
  104. data/lib/ngage/theme_template/example/index.html +14 -0
  105. data/lib/ngage/theme_template/example/style.scss +7 -0
  106. data/lib/ngage/theme_template/gitignore.erb +6 -0
  107. data/lib/ngage/theme_template/theme.gemspec.erb +19 -0
  108. data/lib/ngage/version.rb +5 -0
  109. metadata +328 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class CollectionReader
5
+ SPECIAL_COLLECTIONS = %w(posts data).freeze
6
+
7
+ attr_reader :site, :content
8
+ def initialize(site)
9
+ @site = site
10
+ @content = {}
11
+ end
12
+
13
+ # Read in all collections specified in the configuration
14
+ #
15
+ # Returns nothing.
16
+ def read
17
+ site.collections.each_value do |collection|
18
+ collection.read unless SPECIAL_COLLECTIONS.include?(collection.label)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class DataReader
5
+ attr_reader :site, :content
6
+ def initialize(site)
7
+ @site = site
8
+ @content = {}
9
+ @entry_filter = EntryFilter.new(site)
10
+ end
11
+
12
+ # Read all the files in <dir> and adds them to @content
13
+ #
14
+ # dir - The String relative path of the directory to read.
15
+ #
16
+ # Returns @content, a Hash of the .yaml, .yml,
17
+ # .json, and .csv files in the base directory
18
+ def read(dir)
19
+ base = site.in_source_dir(dir)
20
+ read_data_to(base, @content)
21
+ @content
22
+ end
23
+
24
+ # Read and parse all .yaml, .yml, .json, .csv and .tsv
25
+ # files under <dir> and add them to the <data> variable.
26
+ #
27
+ # dir - The string absolute path of the directory to read.
28
+ # data - The variable to which data will be added.
29
+ #
30
+ # Returns nothing
31
+ def read_data_to(dir, data)
32
+ return unless File.directory?(dir) && !@entry_filter.symlink?(dir)
33
+
34
+ entries = Dir.chdir(dir) do
35
+ Dir["*.{yaml,yml,json,csv,tsv}"] + Dir["*"].select { |fn| File.directory?(fn) }
36
+ end
37
+
38
+ entries.each do |entry|
39
+ path = @site.in_source_dir(dir, entry)
40
+ next if @entry_filter.symlink?(path)
41
+
42
+ if File.directory?(path)
43
+ read_data_to(path, data[sanitize_filename(entry)] = {})
44
+ else
45
+ key = sanitize_filename(File.basename(entry, ".*"))
46
+ data[key] = read_data_file(path)
47
+ end
48
+ end
49
+ end
50
+
51
+ # Determines how to read a data file.
52
+ #
53
+ # Returns the contents of the data file.
54
+ def read_data_file(path)
55
+ case File.extname(path).downcase
56
+ when ".csv"
57
+ CSV.read(path,
58
+ :headers => true,
59
+ :encoding => site.config["encoding"]).map(&:to_hash)
60
+ when ".tsv"
61
+ CSV.read(path,
62
+ :col_sep => "\t",
63
+ :headers => true,
64
+ :encoding => site.config["encoding"]).map(&:to_hash)
65
+ else
66
+ SafeYAML.load_file(path)
67
+ end
68
+ end
69
+
70
+ def sanitize_filename(name)
71
+ name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
72
+ .gsub(%r!\s+!, "_")
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class LayoutReader
5
+ attr_reader :site
6
+ def initialize(site)
7
+ @site = site
8
+ @layouts = {}
9
+ end
10
+
11
+ def read
12
+ layout_entries.each do |layout_file|
13
+ @layouts[layout_name(layout_file)] = \
14
+ Layout.new(site, layout_directory, layout_file)
15
+ end
16
+
17
+ theme_layout_entries.each do |layout_file|
18
+ @layouts[layout_name(layout_file)] ||= \
19
+ Layout.new(site, theme_layout_directory, layout_file)
20
+ end
21
+
22
+ @layouts
23
+ end
24
+
25
+ def layout_directory
26
+ @layout_directory ||= (layout_directory_in_cwd || layout_directory_inside_source)
27
+ end
28
+
29
+ def theme_layout_directory
30
+ @theme_layout_directory ||= site.theme.layouts_path if site.theme
31
+ end
32
+
33
+ private
34
+
35
+ def layout_entries
36
+ entries_in layout_directory
37
+ end
38
+
39
+ def theme_layout_entries
40
+ theme_layout_directory ? entries_in(theme_layout_directory) : []
41
+ end
42
+
43
+ def entries_in(dir)
44
+ entries = []
45
+ within(dir) do
46
+ entries = EntryFilter.new(site).filter(Dir["**/*.*"])
47
+ end
48
+ entries
49
+ end
50
+
51
+ def layout_name(file)
52
+ file.split(".")[0..-2].join(".")
53
+ end
54
+
55
+ def within(directory)
56
+ return unless File.exist?(directory)
57
+
58
+ Dir.chdir(directory) { yield }
59
+ end
60
+
61
+ def layout_directory_inside_source
62
+ site.in_source_dir(site.config["layouts_dir"])
63
+ end
64
+
65
+ def layout_directory_in_cwd
66
+ dir = Jekyll.sanitized_path(Dir.pwd, site.config["layouts_dir"])
67
+ dir if File.directory?(dir) && !site.safe
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class PageReader
5
+ attr_reader :site, :dir, :unfiltered_content
6
+ def initialize(site, dir)
7
+ @site = site
8
+ @dir = dir
9
+ @unfiltered_content = []
10
+ end
11
+
12
+ # Read all the files in <source>/<dir>/ for Yaml header and create a new Page
13
+ # object for each file.
14
+ #
15
+ # dir - The String relative path of the directory to read.
16
+ #
17
+ # Returns an array of static pages.
18
+ def read(files)
19
+ files.map do |page|
20
+ @unfiltered_content << Page.new(@site, @site.source, @dir, page)
21
+ end
22
+ @unfiltered_content.select { |page| site.publisher.publish?(page) }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class PostReader
5
+ attr_reader :site, :unfiltered_content
6
+ def initialize(site)
7
+ @site = site
8
+ end
9
+
10
+ # Read all the files in <source>/<dir>/_drafts and create a new
11
+ # Document object with each one.
12
+ #
13
+ # dir - The String relative path of the directory to read.
14
+ #
15
+ # Returns nothing.
16
+ def read_drafts(dir)
17
+ read_publishable(dir, "_drafts", Document::DATELESS_FILENAME_MATCHER)
18
+ end
19
+
20
+ # Read all the files in <source>/<dir>/_posts and create a new Document
21
+ # object with each one.
22
+ #
23
+ # dir - The String relative path of the directory to read.
24
+ #
25
+ # Returns nothing.
26
+ def read_posts(dir)
27
+ read_publishable(dir, "_posts", Document::DATE_FILENAME_MATCHER)
28
+ end
29
+
30
+ # Read all the files in <source>/<dir>/<magic_dir> and create a new
31
+ # Document object with each one insofar as it matches the regexp matcher.
32
+ #
33
+ # dir - The String relative path of the directory to read.
34
+ #
35
+ # Returns nothing.
36
+ def read_publishable(dir, magic_dir, matcher)
37
+ read_content(dir, magic_dir, matcher).tap { |docs| docs.each(&:read) }
38
+ .select do |doc|
39
+ if doc.content.valid_encoding?
40
+ site.publisher.publish?(doc).tap do |will_publish|
41
+ if !will_publish && site.publisher.hidden_in_the_future?(doc)
42
+ Jekyll.logger.debug "Skipping:", "#{doc.relative_path} has a future date"
43
+ end
44
+ end
45
+ else
46
+ Jekyll.logger.debug "Skipping:", "#{doc.relative_path} is not valid UTF-8"
47
+ false
48
+ end
49
+ end
50
+ end
51
+
52
+ # Read all the content files from <source>/<dir>/magic_dir
53
+ # and return them with the type klass.
54
+ #
55
+ # dir - The String relative path of the directory to read.
56
+ # magic_dir - The String relative directory to <dir>,
57
+ # looks for content here.
58
+ # klass - The return type of the content.
59
+ #
60
+ # Returns klass type of content files
61
+ def read_content(dir, magic_dir, matcher)
62
+ @site.reader.get_entries(dir, magic_dir).map do |entry|
63
+ next unless entry =~ matcher
64
+
65
+ path = @site.in_source_dir(File.join(dir, magic_dir, entry))
66
+ Document.new(path,
67
+ :site => @site,
68
+ :collection => @site.posts)
69
+ end.reject(&:nil?)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class StaticFileReader
5
+ attr_reader :site, :dir, :unfiltered_content
6
+ def initialize(site, dir)
7
+ @site = site
8
+ @dir = dir
9
+ @unfiltered_content = []
10
+ end
11
+
12
+ # Read all the files in <source>/<dir>/ for Yaml header and create a new Page
13
+ # object for each file.
14
+ #
15
+ # dir - The String relative path of the directory to read.
16
+ #
17
+ # Returns an array of static files.
18
+ def read(files)
19
+ files.map do |file|
20
+ @unfiltered_content << StaticFile.new(@site, @site.source, @dir, file)
21
+ end
22
+ @unfiltered_content
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class ThemeAssetsReader
5
+ attr_reader :site
6
+ def initialize(site)
7
+ @site = site
8
+ end
9
+
10
+ def read
11
+ return unless site.theme&.assets_path
12
+
13
+ Find.find(site.theme.assets_path) do |path|
14
+ next if File.directory?(path)
15
+
16
+ if File.symlink?(path)
17
+ Jekyll.logger.warn "Theme reader:", "Ignored symlinked asset: #{path}"
18
+ else
19
+ read_theme_asset(path)
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def read_theme_asset(path)
27
+ base = site.theme.root
28
+ dir = File.dirname(path.sub("#{site.theme.root}/", ""))
29
+ name = File.basename(path)
30
+
31
+ if Utils.has_yaml_header?(path)
32
+ append_unless_exists site.pages,
33
+ Jekyll::Page.new(site, base, dir, name)
34
+ else
35
+ append_unless_exists site.static_files,
36
+ Jekyll::StaticFile.new(site, base, "/#{dir}", name)
37
+ end
38
+ end
39
+
40
+ def append_unless_exists(haystack, new_item)
41
+ if haystack.any? { |file| file.relative_path == new_item.relative_path }
42
+ Jekyll.logger.debug "Theme:",
43
+ "Ignoring #{new_item.relative_path} in theme due to existing file " \
44
+ "with that path in site."
45
+ return
46
+ end
47
+
48
+ haystack << new_item
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Regenerator
5
+ attr_reader :site, :metadata, :cache
6
+ attr_accessor :disabled
7
+ private :disabled, :disabled=
8
+
9
+ def initialize(site)
10
+ @site = site
11
+
12
+ # Read metadata from file
13
+ read_metadata
14
+
15
+ # Initialize cache to an empty hash
16
+ clear_cache
17
+ end
18
+
19
+ # Checks if a renderable object needs to be regenerated
20
+ #
21
+ # Returns a boolean.
22
+ def regenerate?(document)
23
+ return true if disabled
24
+
25
+ case document
26
+ when Page
27
+ regenerate_page?(document)
28
+ when Document
29
+ regenerate_document?(document)
30
+ else
31
+ source_path = document.respond_to?(:path) ? document.path : nil
32
+ dest_path = document.destination(@site.dest) if document.respond_to?(:destination)
33
+ source_modified_or_dest_missing?(source_path, dest_path)
34
+ end
35
+ end
36
+
37
+ # Add a path to the metadata
38
+ #
39
+ # Returns true, also on failure.
40
+ def add(path)
41
+ return true unless File.exist?(path)
42
+
43
+ metadata[path] = {
44
+ "mtime" => File.mtime(path),
45
+ "deps" => [],
46
+ }
47
+ cache[path] = true
48
+ end
49
+
50
+ # Force a path to regenerate
51
+ #
52
+ # Returns true.
53
+ def force(path)
54
+ cache[path] = true
55
+ end
56
+
57
+ # Clear the metadata and cache
58
+ #
59
+ # Returns nothing
60
+ def clear
61
+ @metadata = {}
62
+ clear_cache
63
+ end
64
+
65
+ # Clear just the cache
66
+ #
67
+ # Returns nothing
68
+ def clear_cache
69
+ @cache = {}
70
+ end
71
+
72
+ # Checks if the source has been modified or the
73
+ # destination is missing
74
+ #
75
+ # returns a boolean
76
+ def source_modified_or_dest_missing?(source_path, dest_path)
77
+ modified?(source_path) || (dest_path && !File.exist?(dest_path))
78
+ end
79
+
80
+ # Checks if a path's (or one of its dependencies)
81
+ # mtime has changed
82
+ #
83
+ # Returns a boolean.
84
+ def modified?(path)
85
+ return true if disabled?
86
+
87
+ # objects that don't have a path are always regenerated
88
+ return true if path.nil?
89
+
90
+ # Check for path in cache
91
+ return cache[path] if cache.key? path
92
+
93
+ if metadata[path]
94
+ # If we have seen this file before,
95
+ # check if it or one of its dependencies has been modified
96
+ existing_file_modified?(path)
97
+ else
98
+ # If we have not seen this file before, add it to the metadata and regenerate it
99
+ add(path)
100
+ end
101
+ end
102
+
103
+ # Add a dependency of a path
104
+ #
105
+ # Returns nothing.
106
+ def add_dependency(path, dependency)
107
+ return if metadata[path].nil? || disabled
108
+
109
+ unless metadata[path]["deps"].include? dependency
110
+ metadata[path]["deps"] << dependency
111
+ add(dependency) unless metadata.include?(dependency)
112
+ end
113
+ regenerate? dependency
114
+ end
115
+
116
+ # Write the metadata to disk
117
+ #
118
+ # Returns nothing.
119
+ def write_metadata
120
+ unless disabled?
121
+ Jekyll.logger.debug "Writing Metadata:", ".jekyll-metadata"
122
+ File.binwrite(metadata_file, Marshal.dump(metadata))
123
+ end
124
+ end
125
+
126
+ # Produce the absolute path of the metadata file
127
+ #
128
+ # Returns the String path of the file.
129
+ def metadata_file
130
+ @metadata_file ||= site.in_source_dir(".jekyll-metadata")
131
+ end
132
+
133
+ # Check if metadata has been disabled
134
+ #
135
+ # Returns a Boolean (true for disabled, false for enabled).
136
+ def disabled?
137
+ self.disabled = !site.incremental? if disabled.nil?
138
+ disabled
139
+ end
140
+
141
+ private
142
+
143
+ # Read metadata from the metadata file, if no file is found,
144
+ # initialize with an empty hash
145
+ #
146
+ # Returns the read metadata.
147
+ def read_metadata
148
+ @metadata =
149
+ if !disabled? && File.file?(metadata_file)
150
+ content = File.binread(metadata_file)
151
+
152
+ begin
153
+ Marshal.load(content)
154
+ rescue TypeError
155
+ SafeYAML.load(content)
156
+ rescue ArgumentError => e
157
+ Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
158
+ {}
159
+ end
160
+ else
161
+ {}
162
+ end
163
+ end
164
+
165
+ def regenerate_page?(document)
166
+ document.asset_file? || document.data["regenerate"] ||
167
+ source_modified_or_dest_missing?(
168
+ site.in_source_dir(document.relative_path), document.destination(@site.dest)
169
+ )
170
+ end
171
+
172
+ def regenerate_document?(document)
173
+ !document.write? || document.data["regenerate"] ||
174
+ source_modified_or_dest_missing?(
175
+ document.path, document.destination(@site.dest)
176
+ )
177
+ end
178
+
179
+ def existing_file_modified?(path)
180
+ # If one of this file dependencies have been modified,
181
+ # set the regeneration bit for both the dependency and the file to true
182
+ metadata[path]["deps"].each do |dependency|
183
+ return cache[dependency] = cache[path] = true if modified?(dependency)
184
+ end
185
+
186
+ if File.exist?(path) && metadata[path]["mtime"].eql?(File.mtime(path))
187
+ # If this file has not been modified, set the regeneration bit to false
188
+ cache[path] = false
189
+ else
190
+ # If it has been modified, set it to true
191
+ add(path)
192
+ end
193
+ end
194
+ end
195
+ end