structure ANSIColor: sig datatype color = DEFAULT | BLACK | RED | GREEN | YELLOW | BLUE | MAGENTA | CYAN | WHITE | BRIGHT_BLACK | BRIGHT_RED | BRIGHT_GREEN | BRIGHT_YELLOW | BRIGHT_BLUE | BRIGHT_MAGENTA | BRIGHT_CYAN | BRIGHT_WHITE val fromString: string -> color option val asForeground: color -> string option val asBackground: color -> string option end = struct datatype color = DEFAULT | BLACK | RED | GREEN | YELLOW | BLUE | MAGENTA | CYAN | WHITE | BRIGHT_BLACK | BRIGHT_RED | BRIGHT_GREEN | BRIGHT_YELLOW | BRIGHT_BLUE | BRIGHT_MAGENTA | BRIGHT_CYAN | BRIGHT_WHITE fun fromString "default" = SOME DEFAULT | fromString "black" = SOME BLACK | fromString "red" = SOME RED | fromString "green" = SOME GREEN | fromString "yellow" = SOME YELLOW | fromString "blue" = SOME BLUE | fromString "magenta" = SOME MAGENTA | fromString "cyan" = SOME CYAN | fromString "white" = SOME WHITE | fromString "brightblack" = SOME BRIGHT_BLACK | fromString "brightred" = SOME BRIGHT_RED | fromString "brightgreen" = SOME BRIGHT_GREEN | fromString "brightyellow" = SOME BRIGHT_YELLOW | fromString "brightblue" = SOME BRIGHT_BLUE | fromString "brightmagenta" = SOME BRIGHT_MAGENTA | fromString "brightcyan" = SOME BRIGHT_CYAN | fromString "brightwhite" = SOME BRIGHT_WHITE | fromString _ = NONE fun asForeground DEFAULT = NONE | asForeground BLACK = SOME "30" | asForeground RED = SOME "31" | asForeground GREEN = SOME "32" | asForeground YELLOW = SOME "33" | asForeground BLUE = SOME "34" | asForeground MAGENTA = SOME "35" | asForeground CYAN = SOME "36" | asForeground WHITE = SOME "37" | asForeground BRIGHT_BLACK = SOME "90" | asForeground BRIGHT_RED = SOME "91" | asForeground BRIGHT_GREEN = SOME "92" | asForeground BRIGHT_YELLOW = SOME "93" | asForeground BRIGHT_BLUE = SOME "94" | asForeground BRIGHT_MAGENTA = SOME "95" | asForeground BRIGHT_CYAN = SOME "96" | asForeground BRIGHT_WHITE = SOME "97" fun asBackground DEFAULT = NONE | asBackground BLACK = SOME "40" | asBackground RED = SOME "41" | asBackground GREEN = SOME "42" | asBackground YELLOW = SOME "43" | asBackground BLUE = SOME "44" | asBackground MAGENTA = SOME "45" | asBackground CYAN = SOME "46" | asBackground WHITE = SOME "47" | asBackground BRIGHT_BLACK = SOME "100" | asBackground BRIGHT_RED = SOME "101" | asBackground BRIGHT_GREEN = SOME "102" | asBackground BRIGHT_YELLOW = SOME "103" | asBackground BRIGHT_BLUE = SOME "104" | asBackground BRIGHT_MAGENTA = SOME "105" | asBackground BRIGHT_CYAN = SOME "106" | asBackground BRIGHT_WHITE = SOME "107" end; structure ANSIStyle: sig type style = { foreground: ANSIColor.color option , background: ANSIColor.color option , bold: bool , dim: bool , underline: bool , blink: bool , reverse: bool , italic: bool , strike: bool } val defaultStyle: style val toString: style -> string val resetAll: string end = struct type style = { foreground: ANSIColor.color option , background: ANSIColor.color option , bold: bool , dim: bool , underline: bool , blink: bool , reverse: bool , italic: bool , strike: bool } val defaultStyle: style = { foreground = NONE , background = NONE , bold = false , dim = false , underline = false , blink = false , reverse = false , italic = false , strike = false } fun prependOption (SOME x, xs) = x :: xs | prependOption (NONE, xs) = xs fun toString ({ foreground , background , bold , dim , underline , blink , reverse , italic , strike }: style) = let val attrs = [] val attrs = if strike then "9" :: attrs else attrs val attrs = if reverse then "7" :: attrs else attrs val attrs = if blink then "5" :: attrs else attrs val attrs = if underline then "4" :: attrs else attrs val attrs = if italic then "3" :: attrs else attrs val attrs = if dim then "2" :: attrs else attrs val attrs = if bold then "1" :: attrs else attrs val attrs = prependOption (Option.mapPartial ANSIColor.asBackground background, attrs) val attrs = prependOption (Option.mapPartial ANSIColor.asForeground foreground, attrs) in "\027[" ^ String.concatWith ";" attrs ^ "m" end val resetAll: string = "\027[0m" end;