Module: Tina4::ScssCompiler

Defined in:
lib/tina4/scss_compiler.rb

Constant Summary collapse

SCSS_DIRS =
%w[src/scss scss src/styles styles].freeze
CSS_OUTPUT =
"src/public/css"

Class Method Summary collapse

Class Method Details

.add_import_path(path) ⇒ Object

Add a search path for @import resolution.



15
16
17
18
# File 'lib/tina4/scss_compiler.rb', line 15

def add_import_path(path)
  @import_paths ||= []
  @import_paths << path
end

.compile(source) ⇒ Object

Compile an SCSS string to CSS.



28
29
30
31
32
33
34
35
36
37
# File 'lib/tina4/scss_compiler.rb', line 28

def compile(source)
  @variables ||= {}
  @import_paths ||= []
  # Inject preset variables
  unless @variables.empty?
    var_block = @variables.map { |k, v| "$#{k}: #{v};" }.join("\n")
    source = "#{var_block}\n#{source}"
  end
  basic_compile(source, @import_paths.first || Dir.pwd)
end

.compile_all(root_dir = Dir.pwd) ⇒ Object

Compile all .scss files from known directories.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/tina4/scss_compiler.rb', line 40

def compile_all(root_dir = Dir.pwd)
  output_dir = File.join(root_dir, CSS_OUTPUT)
  FileUtils.mkdir_p(output_dir)

  SCSS_DIRS.each do |dir|
    scss_dir = File.join(root_dir, dir)
    next unless Dir.exist?(scss_dir)

    Dir.glob(File.join(scss_dir, "**/*.scss")).each do |scss_file|
      next if File.basename(scss_file).start_with?("_") # Skip partials
      compile_file(scss_file, output_dir, scss_dir)
    end
  end
end

.compile_file(scss_file, output_dir = nil, base_dir = nil) ⇒ Object

Compile a single SCSS file. If output_dir is provided, writes CSS there. Always returns the compiled CSS string.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/tina4/scss_compiler.rb', line 57

def compile_file(scss_file, output_dir = nil, base_dir = nil)
  base_dir ||= File.dirname(scss_file)
  scss_content = File.read(scss_file)
  css_content = compile_scss(scss_content, File.dirname(scss_file))

  if output_dir
    relative = scss_file.sub(base_dir, "").sub(/\.scss$/, ".css")
    css_file = File.join(output_dir, relative)
    FileUtils.mkdir_p(File.dirname(css_file))
    existing = File.exist?(css_file) ? File.read(css_file) : nil
    if existing != css_content
      File.write(css_file, css_content)
      Tina4::Log.debug("Compiled SCSS: #{scss_file} -> #{css_file}")
    end
  end

  css_content
rescue => e
  Tina4::Log.error("SCSS compilation failed: #{scss_file} - #{e.message}")
  ""
end

.compile_scss(content, base_dir) ⇒ Object

Compile an SCSS content string with a base directory for import resolution.



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/tina4/scss_compiler.rb', line 80

def compile_scss(content, base_dir)
  # Try sassc gem first
  begin
    require "sassc"
    return SassC::Engine.new(content, style: :expanded, load_paths: [base_dir]).render
  rescue LoadError
    # Fall through to basic compiler
  end

  # Basic SCSS to CSS conversion (handles common patterns)
  basic_compile(content, base_dir)
end

.set_variable(name, value) ⇒ Object

Set a variable that will be available during compilation.



21
22
23
24
25
# File 'lib/tina4/scss_compiler.rb', line 21

def set_variable(name, value)
  @variables ||= {}
  name = name.sub(/^\$/, "")
  @variables[name] = value
end