module CodeRay module Encoders class HTML class CSS def initialize stylesheet = TOKENS @classes = Hash.new parse stylesheet end def [] *styles cl = @classes[styles.first] return '' unless cl style = false 1.upto(cl.size + 1) do |offset| break if style = cl[styles[offset .. -1]] end return style end private CSS_CLASS_PATTERN = / ( (?: # $1 = classes \s* \. [-\w]+ )+ ) \s* \{ ( [^\}]* ) # $2 = style \} \s* | ( . ) # $3 = error /mx def parse stylesheet stylesheet.scan CSS_CLASS_PATTERN do |classes, style, error| raise "CSS parse error: '#{error.inspect}' not recognized" if error styles = classes.scan(/[-\w]+/) cl = styles.pop @classes[cl] ||= Hash.new @classes[cl][styles] = style.strip end end MAIN = <<-'MAIN' .CodeRay { background-color: #f8f8f8; border: 1px solid silver; font-family: 'Courier New', 'Terminal', monospace; color: black; width: 100%; padding: 2px; } .CodeRay pre { margin: 0px; } div.CodeRay { } span.CodeRay { white-space: pre; border: 0; } table.CodeRay { border-collapse: collapse; } table.CodeRay td { padding: 2px 4px; vertical-align: top; } .CodeRay .line_numbers, .CodeRay .no { background-color: #def; color: gray; text-align: right; } .CodeRay .line_numbers tt { font-weight: bold; } .CodeRay .no { padding: 0px 4px; } .CodeRay .code { width: 100%; } .CodeRay .code { } .CodeRay .code pre { overflow: auto; } MAIN TOKENS = <<-'TOKENS' .af { color:#00C; } .an { color:#007; } .av { color:#700; } .aw { color:#C00; } .bi { color:#509; font-weight:bold; } .c { color:#888; } .ch { color:#04D; } .ch .k { color:#04D; } .ch .dl { color:#039; } .cl { color:#B06; font-weight:bold; } .co { color:#036; font-weight:bold; } .cr { color:#0A0; } .cv { color:#369; } .df { color:#099; font-weight:bold; } .di { color:#088; font-weight:bold; } .dl { color:black; } .do { color:#970; } .ds { color:#D42; font-weight:bold; } .e { color:#666; font-weight:bold; } .er { color:#F00; background-color:#FAA; } .ex { color:#F00; font-weight:bold; } .fl { color:#60E; font-weight:bold; } .fu { color:#06B; font-weight:bold; } .gv { color:#d70; font-weight:bold; } .hx { color:#058; font-weight:bold; } .i { color:#00D; font-weight:bold; } .ic { color:#B44; font-weight:bold; } .il { } .in { color:#B2B; font-weight:bold; } .iv { color:#33B; } .la { color:#970; font-weight:bold; } .lv { color:#963; } .oc { color:#40E; font-weight:bold; } .on { color:#000; font-weight:bold; } .pc { color:#038; font-weight:bold; } .pd { color:#369; font-weight:bold; } .pp { color:#579; } .pt { color:#339; font-weight:bold; } .r { color:#080; font-weight:bold; } .rx { background-color:#fff0ff; } .rx .k { color:#808; } .rx .dl { color:#404; } .rx .mod { color:#C2C; } .rx .fu { color:#404; font-weight: bold; } .s { background-color:#fff0f0; } .s .s { background-color:#ffe0e0; } .s .s .s { background-color:#ffd0d0; } .s .k { color:#D20; } .s .dl { color:#710; } .sh { background-color:#f0fff0; } .sh .k { color:#2B2; } .sh .dl { color:#161; } .sy { color:#A60; } .sy .k { color:#A60; } .sy .dl { color:#630; } .ta { color:#070; } .tf { color:#070; font-weight:bold; } .ts { color:#D70; font-weight:bold; } .ty { color:#339; font-weight:bold; } .v { color:#036; } .xt { color:#444; } TOKENS DEFAULT_STYLESHEET = MAIN + TOKENS.gsub(/^(?!$)/, '.CodeRay ') end end end end if $0 == __FILE__ require 'pp' pp CodeRay::Encoders::HTML::CSS.new end