class Epuber::Compiler::FileTypes::CSSFile

Constants

DECLARATION_TO_FILE_GROUP_MAP
URL_REGEXP

Public Instance Methods

process(compilation_context) click to toggle source

@param [Compiler::CompilationContext] compilation_context

# File lib/epuber/compiler/file_types/css_file.rb, line 29
def process(compilation_context)
  if destination_file_up_to_date?
    # HACK: for now, we need to process the file again, because we need to find linked files
    process_css(File.read(final_destination_path), compilation_context)
  else
    write_processed(process_css(File.read(abs_source_path), compilation_context))
  end
end
process_css(content, compilation_context) click to toggle source

Processes CSS file, resolves all linked files and adds them to file resolver

@param [String] content @param [Compiler::CompilationContext] compilation_context

@return [String]

# File lib/epuber/compiler/file_types/css_file.rb, line 45
def process_css(content, compilation_context)
  parser = UI.print_step_processing_time('css parsing') do
    parser = CssParser::Parser.new
    parser.load_string!(content)
    parser
  end

  # resolve links to files, add other linked resources and compute correct path
  UI.print_step_processing_time('resolving url()') do
    parser.each_rule_set do |rule_set, _media_types|
      # @type [CssParser::RuleSet::Declarations]
      declarations = rule_set.instance_eval { @declarations }
      declarations.each do |property, decl_value|
        decl_value.to_s.scan(URL_REGEXP) do
          url_function = Regexp.last_match(0)
          path = Regexp.last_match(1)
          if path.start_with?('"') && path.end_with?('"')
            path = path[1..-2]
            quote = '"'
          end
          if path.start_with?("'") && path.end_with?("'")
            path = path[1..-2]
            quote = "'"
          end

          next if path.start_with?('data:') || path.start_with?('http://') || path.start_with?('https://')

          resource_group = DECLARATION_TO_FILE_GROUP_MAP[property]
          new_url = SourceFile.resolve_relative_file(destination_path,
                                                     path,
                                                     compilation_context.file_resolver,
                                                     group: resource_group,
                                                     location: self)

          content = content.gsub(url_function, "url(#{quote}#{new_url}#{quote})") if new_url
        end
      end
    end
  end

  content
end