Skip to content

Instantly share code, notes, and snippets.

@tmeasday
Created January 7, 2012 02:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmeasday/1573516 to your computer and use it in GitHub Desktop.
Save tmeasday/1573516 to your computer and use it in GitHub Desktop.
A modified CSS splitter that allows you to extract a single part.
# copied from https://gist.github.com/1131536, thanks christian peters.
module CssSplitter
def self.split(infile, outdir = File.dirname(infile), max_selectors = 4095)
charset_statement, rules = self.read_rules(infile)
return if rules.nil?
self.partition_rules(rules, max_selectors).each_with_index do |ruleset, index|
next if index == 0 # no need to write out the first file
filename = File.join(outdir, File.basename(infile, File.extname(infile)) + "_#{index + 1}" + File.extname(infile))
output = File.new(filename, "w")
output.write charset_statement
output.write ruleset.join('')
end
end
def self.count_selectors(infile)
charset_statement, rules = self.read_rules(infile)
return if rules.nil?
p rules.length
rules.map{|r| count_selectors_of_rule(r)}.sum.tap do |result|
puts File.basename(infile) + " contains #{result} selectors."
end
end
# part is 1-based
def self.split_to_part(infile, part, max_selectors = 4095)
charset_statement, rules = self.read_rules(infile)
return if rules.nil?
rulesets = self.partition_rules(rules, max_selectors)
charset_statement + rulesets[part-1].join('')
end
def self.read_rules(infile)
raise "file could not be found: #{infile}" unless File.exists? infile
rules = IO.readlines(infile, "}")
return [nil, nil] if rules.first.nil?
charset_statement, rules[0] = rules.first.partition(/^\@charset[^;]+;/)[1,2]
return [charset_statement, rules]
end
# return an array of rulesets, each of which contains no more than max_selectors
def self.partition_rules(rules, max_selectors)
selectors_count = 0
rulesets = []
ruleset = []
rules.each do |rule|
rule_selectors_count = count_selectors_of_rule rule
selectors_count += rule_selectors_count
# Nothing happens until the selectors limit is reached for the first time
if selectors_count > max_selectors
# finish ruleset
rulesets << ruleset
# Prepare next ruleset
ruleset = []
# Reset count with current rule count
selectors_count = rule_selectors_count
end
ruleset << rule
end
rulesets << ruleset unless ruleset.empty? # final ruleset
rulesets
end
def self.count_selectors_of_rule(rule)
rule.partition(/\{/).first.scan(/,/).count.to_i + 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment