module Jekyll::Gzip::Compressor

The module that does the compressing using Zlib.

Public Class Methods

compress_directory(dir, site) click to toggle source

Takes a directory path and maps over the files within compressing them in place.

@example

Jekyll::Gzip::Compressor.compress_directory("~/blog/_site", site)

@param dir [Pathname, String] The path to a directory of files ready for

compression.

@param site [Jekyll::Site] An instance of the `Jekyll::Site` used for

config.

@return void

# File lib/jekyll/gzip/compressor.rb, line 51
def self.compress_directory(dir, site)
  extensions = zippable_extensions(site).join(',')
  replace_file = replace_files(site)
  files = Dir.glob(File.join(dir, "**", "*{#{extensions}}"))
  files.each do |file|
    next unless regenerate?(file, site)

    compress_file(
      file,
      extensions: extensions,
      replace_file: replace_file
    )
  end
end
compress_file(file_name, extensions: [], replace_file: false) click to toggle source

Takes a file name and an array of extensions. If the file name extension matches one of the extensions in the array then the file is loaded and compressed using Zlib, outputting the gzipped file under the name of the original file with an extra .gz extension.

@example

Jekyll::Gzip::Compressor.compress_file("~/blog/_site/index.html")

@param file_name [String] The file name of the file we want to compress @param extensions [Array<String>] The extensions of files that will be

compressed.

@param replace_file [Boolean] Whether the origina file should be

replaced or written alongside the original with a `.gz` extension

@return void

# File lib/jekyll/gzip/compressor.rb, line 82
def self.compress_file(file_name, extensions: [], replace_file: false)
  return unless extensions.include?(File.extname(file_name))
  zipped = zipped(file_name, replace_file)
  file_content = IO.binread(file_name)

  Jekyll.logger.debug "Gzip: #{zipped}"

  Zlib::GzipWriter.open(zipped, Zlib::BEST_COMPRESSION) do |gz|
    gz.mtime = File.mtime(file_name)
    gz.orig_name = file_name
    gz.write file_content
  end
end
compress_site(site) click to toggle source

Takes an instance of Jekyll::Site and maps over the site files, compressing them in the destination directory. @example

site = Jekyll::Site.new(site_config)
Jekyll::Gzip::Compressor.compress_site(site)

@param site [Jekyll::Site] A Jekyll::Site object that has generated its

site files ready for compression.

@return void

# File lib/jekyll/gzip/compressor.rb, line 26
def self.compress_site(site)
  site.each_site_file do |file|
    next unless regenerate? file.destination(site.dest), site

    compress_file(
      file.destination(site.dest),
      extensions: zippable_extensions(site),
      replace_file: replace_files(site)
    )
  end
end

Private Class Methods

is_already_gzipped?(file) click to toggle source

First two bytes of a gzipped file are 1f and 8b. This tests for those bytes.

# File lib/jekyll/gzip/compressor.rb, line 128
def self.is_already_gzipped?(file)
  ["1f", "8b"] == File.read(file, 2).unpack("H2H2")
end
regenerate?(file, site) click to toggle source

Compresses the file if the site is built incrementally and the source was modified or the compressed file doesn't exist

# File lib/jekyll/gzip/compressor.rb, line 112
def self.regenerate?(file, site)
  zipped = zipped(file, replace_files(site))

  # Definitely generate the file if it doesn't exist yet.
  return true unless File.exist? zipped
  # If we are replacing files and this file is not a gzip file, then it
  # has been edited so we need to re-gzip it in place.
  return !is_already_gzipped?(file) if replace_files(site)

  # If the modified time of the new file is greater than the modified time
  # of the old file, then we need to regenerate.
  File.mtime(file) > File.mtime(zipped)
end
replace_files(site) click to toggle source
# File lib/jekyll/gzip/compressor.rb, line 106
def self.replace_files(site)
  site.config.dig("gzip", "replace_files") || Jekyll::Gzip::DEFAULT_CONFIG.fetch("replace_files")
end
zippable_extensions(site) click to toggle source
# File lib/jekyll/gzip/compressor.rb, line 102
def self.zippable_extensions(site)
  site.config.dig("gzip", "extensions") || Jekyll::Gzip::DEFAULT_CONFIG.fetch("extensions")
end
zipped(file_name, replace_file) click to toggle source
# File lib/jekyll/gzip/compressor.rb, line 98
def self.zipped(file_name, replace_file)
  replace_file ? file_name : "#{file_name}.gz"
end