# $Id: parsefancy.rb,v 1.4 2005/06/29 20:57:12 vlietstra Exp $ # parsefancy module. # een funksie wat van die buitekant af gebruik moet word, parsefancy(string) # # Hierdie funksie wat 'n string as input en return 'n string wat geformat # is volgens ANSI controls codes volgens sekere van ons eie, meer leesbare # control 'codes'. Kyk na testparsefancy.rb in die base dir vir hans-on # examples # # Alle control codes is enclosed in [x] (die delimiters op die oomblik # Control strings is geseperate deur spaces # Spesiale control string is die vir kleure, waar fg:bg # met fg die foreground color, en bg die background color # gebruik word. Dit is moontlik om :bg te specify, wat net die # background stel, of fg: wat net die foreground stel # 'n spesiale case word gehandle waar jy net kan se fg vir foreground color # ook # # [] reset ook # i.e. "[red:green]Rooi op groen[]Gewone text[:swart]swart agtergrond # [underscore red:green]Rooi op groen, underscore # etc. $delimiter = ['<','>'] $codesmap = { # Foreground colors 'black' => '30', 'red' => '31', 'green' => '32', 'yellow' => '33', 'blue' => '34', 'magenta' => '35', 'cyan' => '36', 'white' => '37', # Background colors 'BGblack' => '40', 'BGred' => '41', 'BGgreen' => '42', 'BGyellow' => '43', 'BGblue' => '44', 'BGmagenta' => '45', 'BGcyan' => '46', 'BGwhite' => '47', # General codes 'reset' => '0', 'bright' => '1', 'dim' => '2', 'underscore' => '4', 'blink' => '5', 'reverse' => '7', 'hidden' => '8', } def parse_codes(str) codestring = "" if str == '' codelist = [$codesmap['reset']] else codelist = [] # get all the space seperated codes codes = str.split(' ') for code in codes # If the code has a : in it, it means it is a # color. fg:bg (either can be empty) if code.index(':') != nil colors = code.split(':') key = '%s' % colors[0] #foreground may be empty, then we skip it if key != "" codelist.push($codesmap[key]) end key = 'BG%s' % colors[1] #backghround may be empty, then we skip it if key != "BG" codelist.push($codesmap[key]) end else codelist.push($codesmap[code]) end end end # append the codes with spaces in between codelist.each { |c| codestring += "%s;" % c } # remove the last space codestring = codestring[0,codestring.length-1] return ("%c" % (27)) + "[%sm" % (codestring) end def color(str) newstr = "" i = 0 while i < str.length c = "%c" % (str[i]) if c == $delimiter[0] # if this is the last character, raise an exception if i == str.length-1 raise TypeError, "Open delimiter at end of string." end # if the next character is an open bracket, add it if ( ("%c" % (str[i+1])) == $delimiter[0]) newstr += $delimiter[0] i+=1 else # it's some other character, we need to find the first # close delimiter. k=i+1 while k < str.length # if at any stage we find another open delimiter # inside the previous delimiter, we raise an # exception if ( ("%c" % str[k] == $delimiter[0]) ) raise TypeError, "Open delimiter before close delimiter after open delimiter."+"\n#{str}" end if ( ("%c" % str[k] == $delimiter[1]) ) break end k+=1 end # if we reached the end of the string, it means # there is no close delimiter, raise an exception if k == str.length raise TypeError, "No matching close delimiter" end # commandstr will be all the characters we # found inside the brackets commandstr = str[i+1...k] newstr += parse_codes(commandstr) # update our string index to skip over all the characters # we have just assigned to commandstr i+=commandstr.length+2 # it's +2 to skip over the [ and ] end else newstr += c i+=1 end end return newstr + ("%c[0m" % (27)) end