Chris@0: module CodeRay Chris@0: module Encoders Chris@0: Chris@0: class HTML Chris@0: class CSS Chris@0: Chris@0: attr :stylesheet Chris@0: Chris@0: def CSS.load_stylesheet style = nil Chris@0: CodeRay::Styles[style] Chris@0: end Chris@0: Chris@0: def initialize style = :default Chris@0: @classes = Hash.new Chris@0: style = CSS.load_stylesheet style Chris@0: @stylesheet = [ Chris@0: style::CSS_MAIN_STYLES, Chris@0: style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ') Chris@0: ].join("\n") Chris@0: parse style::TOKEN_COLORS Chris@0: end Chris@0: Chris@0: def [] *styles Chris@0: cl = @classes[styles.first] Chris@0: return '' unless cl Chris@0: style = '' Chris@0: 1.upto(styles.size) do |offset| Chris@0: break if style = cl[styles[offset .. -1]] Chris@0: end Chris@0: # warn 'Style not found: %p' % [styles] if style.empty? Chris@0: return style Chris@0: end Chris@0: Chris@0: private Chris@0: Chris@0: CSS_CLASS_PATTERN = / Chris@0: ( # $1 = selectors Chris@0: (?: Chris@0: (?: \s* \. [-\w]+ )+ Chris@0: \s* ,? Chris@0: )+ Chris@0: ) Chris@0: \s* \{ \s* Chris@0: ( [^\}]+ )? # $2 = style Chris@0: \s* \} \s* Chris@0: | Chris@0: ( . ) # $3 = error Chris@0: /mx Chris@0: def parse stylesheet Chris@0: stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error| Chris@0: raise "CSS parse error: '#{error.inspect}' not recognized" if error Chris@0: for selector in selectors.split(',') Chris@0: classes = selector.scan(/[-\w]+/) Chris@0: cl = classes.pop Chris@0: @classes[cl] ||= Hash.new Chris@0: @classes[cl][classes] = style.to_s.strip.delete(' ').chomp(';') Chris@0: end Chris@0: end Chris@0: end Chris@0: Chris@0: end Chris@0: end Chris@0: Chris@0: end Chris@0: end Chris@0: Chris@0: if $0 == __FILE__ Chris@0: require 'pp' Chris@0: pp CodeRay::Encoders::HTML::CSS.new Chris@0: end