Class: Mint::CssParser

Inherits:
Object
  • Object
show all
Defined in:
lib/mint/css_parser.rb

Overview

Parses CSS files to extract @import statements and calculate relative paths

Class Method Summary collapse

Class Method Details

.extract_imports(css_content) ⇒ Array<String>

Extracts @import statements from CSS content

Parameters:

  • css_content (String)

    the CSS content to parse

Returns:

  • (Array<String>)

    array of imported file paths



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/mint/css_parser.rb', line 11

def self.extract_imports(css_content)
  imports = []
  
  # Remove CSS comments first to avoid matching commented @import statements
  # Remove /* ... */ style comments
  css_without_comments = css_content.gsub(/\/\*.*?\*\//m, '')
  
  # Matched formats include:
  # @import "file.css";
  # @import 'file.css';
  # @import url("file.css");
  # @import url('file.css');
  css_without_comments.scan(/@import\s+(?:url\()?['"]([^'"]+)['"](?:\))?;?/i) do |match|
    imports << match[0]
  end
  
  imports
end

Generates HTML link tags for CSS files

Parameters:

  • css_file_paths (Array<String>)

    array of relative paths to CSS files

Returns:

  • (String)

    HTML link tags



90
91
92
93
94
# File 'lib/mint/css_parser.rb', line 90

def self.generate_link_tags(css_file_paths)
  css_file_paths.map do |css_path|
    %Q{<link rel="stylesheet" href="#{css_path}">}
  end.join("\n    ")
end

.resolve_css_file_recursive(css_file, html_dir, visited = Set.new) ⇒ Array<String>

Recursively resolves a CSS file and its imports

Parameters:

  • css_file (Pathname)

    absolute path to the CSS file as Pathname

  • html_dir (Pathname)

    directory of the HTML output file as Pathname

  • visited (Set) (defaults to: Set.new)

    set of already processed files to prevent circular imports

Returns:

  • (Array<String>)

    array of relative paths from HTML to CSS files



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/mint/css_parser.rb', line 36

def self.resolve_css_file_recursive(css_file, html_dir, visited = Set.new)
  css_files = []
  
  # Prevent circular imports
  return css_files if visited.include?(css_file.to_s)
  visited.add(css_file.to_s)
  
  return css_files unless css_file.exist? && css_file.extname == '.css'
  
  begin
    css_content = File.read(css_file)
    imports = extract_imports(css_content)
    
    # Recursively process imported files first (they should load before the file that imports them)
    imports.each do |import_path|
      import_file = (css_file.dirname + import_path).expand_path
      css_files.concat(resolve_css_file_recursive(import_file, html_dir, visited))
    end
    
    # Add this file after its imports
    relative_path = css_file.relative_path_from(html_dir).to_s
    css_files << relative_path unless css_files.include?(relative_path)
    
  rescue => _
    # If we can't read the CSS file, skip it
    # This allows the system to gracefully handle missing or unreadable files
  end
  
  css_files
end

.resolve_css_files(main_css_path, html_output_path) ⇒ Array<String>

Resolves all CSS files (main + imports) and calculates their paths relative to HTML output

Parameters:

  • main_css_path (String)

    absolute path to the main CSS file

  • html_output_path (String)

    absolute path to the HTML output file

Returns:

  • (Array<String>)

    array of relative paths from HTML to CSS files



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mint/css_parser.rb', line 72

def self.resolve_css_files(main_css_path, html_output_path)
  main_css_file = Pathname.new(main_css_path).expand_path
  html_file = Pathname.new(html_output_path).expand_path
  html_dir = html_file.dirname
  
  # If the file doesn't exist or isn't CSS, return just the relative path
  unless main_css_file.exist? && main_css_file.extname == '.css'
    return [main_css_file.relative_path_from(html_dir).to_s]
  end
  
  # Use recursive resolution
  resolve_css_file_recursive(main_css_file, html_dir)
end