I’d previous used the “/terminal style” commands to add colorized output from a script. The alternative method is encoding ANSI control codes into a string, so wrote a function that “wraps” some text with the needed escape to set text and background colors. The code is loosely based on a JavaScript/node project called “chalk.js”, see https://github.com/chalk/chalk - although this code only deals with 8-bit colors (e.g. no RGB codes).
The $CHALK function can be used inline/interpolation to add a to text in a string like so:
:put "$[$CHALK blue]hello world$[$CHALK no-style]"
Note: The colors need to be cleared to avoid the terminal using the last color set, this is done via “$CHALK no-style” which is included in-line above.
Or, If is provided as the 2nd argument to $CHALK function, it will be output via a :put in one-line.
$CHALK red "hello world" bold=yes inverse=yes
Another use case is using debug=yes as an option $CHALK, this will output the ANSI escape code formatted for use in a Mikrotik script – e.g. you can use $CHALK to make an ANSI string WITHOUT having CHALK function load “at runtime”.
[amm0@Mikrotik] /> $CHALK red debug=yes
\1B[31;49m
[amm0@Mikrotik] /> $CHALK no-style debug=yes
\1B[39;49m
[amm0@Mikrotik] /> :put "\1B[31;49mcut-and-pasted-codes\1B[39;49m"
cut-and-pasted-codes # (in bold red)
The available color are available using “$CHALK colors”:

As a bonus, there a “url” option that will generate a “clickable” URL in a modern terminal:
$CHALK url "http://example.com" text="Example Link"
Note: this does NOT work in the RouterOS terminal form winbox/webfig – however if you access the router using a SSH client, it create a clickable link with the URL in a Mac/Linux/WSL terminal.

To see some examples, you can use “$CHALK help”…
The actual code for the $CHALK function that will be have to add to the RouterOS, either by cut-and-paste to test, or via /system/script or /system/scheduler so it’s always loaded:
:global CHALK do={
# we may call ourselves for control codes, so declare that
:global CHALK
:local helptext "
\r\n $CHALK
\r\n generates ANSI codes that can be used in a string to add colorized text
\r\n
\r\n Basic Syntax:
\r\n $CHALK [] [inverse=yes] [[bold=yes]|[dim=yes]]
\r\n
\r\n Alternatively, use set background (bg=) color, instead of inverse=yes:
\r\n $CHALK [] bg= [[bold=yes]|[dim=yes]]
\r\n
\r\n View possible values of :
\r\n $CHALK colors
\r\n
\r\n Clear all ANSI formatting:
\r\n $CHALK reset
\r\n
\r\n Clear only foreground and background colors:
\r\n $CHALK no-style
\r\n
\r\n Generate a "clickable" URL (in select terminals only):
\r\n $CHALK url "http://example.com" text="Example Link"
\r\n
\r\n To see this page, use:
\r\n $CHALK help
\r\n
\r\n Example:
\r\n Print ("put") some text in cyan -
\r\n $CHALK cyan "hello world"
\r\n
\r\n Output blue text inside a string -
\r\n :put "$[$CHALK blue]hello world$[$CHALK no-style]"
\r\n
\r\n Shout bold text with background color (using inverse=yes) -
\r\n :put "$[$CHALK red inverse=yes bold=yes]HELLO WORLD$[$CHALK no-style]"
\r\n
\r\n Create a click-able URL -
\r\n :put "$[$CHALK url "http://www.mikrotik.com" text="Go to Mikrotik Website"]"
\r\n ** only works when connected via SSH & using "modern" terminal
\r\n
\r\n Show example colors -
\r\n $CHALK colors
\r\n "
# handle 8-bit color names
:local lookupcolor8 do={
:local color8 {
black={30;40};
red={31;41};
green={32;42};
yellow={33;43};
blue={34;44};
magenta={35;45};
cyan={36;46};
white={37;47};
"no-style"={39;49};
reset={0;0};
"bright-black"={90;0};
"gray"={90;100};
"grey"={90;100};
"bright-red"={91;101};
"bright-green"={92;103};
"bright-yellow"={93;104};
"bright-blue"={94;104};
"bright-magenta"={95;105};
"bright-cyan"={96;106};
"bright-white"={97;107}
}
:if ($1 = "as-array") do={:return $color8}
:if ([:typeof ($color8->$1)]="array") do={
:return ($color8->$1)
} else={
:return [:nothing]
}
}
:if ($1 = "color") do={
:if ([:typeof $2] = "str") do={
:local ccode [$lookupcolor8 $2]
:if ([:len $ccode] > 0) do={
:put $ccode
:return [:nothing]
} else={$CHALK colors}
} else={$CHALK colors}
}
:if ($1 = "colors") do={
:put "\t <color>\t\t $[$CHALK no-style inverse=yes]inverse=yes$[$CHALK reset]\t\t $[$CHALK no-style bold=yes]bold=yes$[$CHALK reset]\t\t $[$CHALK no-style dim=yes]dim=yes$[$CHALK reset]"
:foreach k,v in=[$lookupcolor8 as-array] do={
:local ntabs "\t"
:if ([:len $k] < 8 ) do={
:set ntabs "\t\t"
}
:put "\t$[$CHALK $k]$k$[$CHALK reset]$ntabs$[$CHALK $k inverse=yes]\t$k$[$CHALK reset]\t$[$CHALK $k bold=yes]$ntabs$k$[$CHALK reset]\t$[$CHALK $k dim=yes]$ntabs$k$[$CHALK reset]"
}
:return [:nothing]
}
:if ($1 = "help") do={
:put $helptext
:return [:nothing]
}
# handle clickable URLs
:if ($1 = "url") do={
:local lurl "http://example.com"
:if ([:typeof $2]="str") do={
:set lurl $2
} else={
:if ([:typeof $url]="str") do={
:set lurl $url
}
}
:local ltxt $lurl
:if ([:typeof $text]="str") do={
:set ltxt $text
}
:return "\1B]8;;$lurl\07$ltxt\1B]8;;\07"
}
# set default colors
:local c8str {mod="";fg="$([$lookupcolor8 no-style]->0)";bg="$([$lookupcolor8 no-style]->1)"}
# if the color name is the 1st arg, make the the foreground color
:if ([:typeof [$lookupcolor8 $1]] = "array") do={
:set ($c8str->"fg") ([$lookupcolor8 $1]->0)
}
# set default colors
# set the modifier...
# hidden=
:if ($hidden="yes") do={
:set ($c8str->"mod") "8;"
} else={
# inverse=
:if ($inverse="yes") do={
:set ($c8str->"mod") "7;"
}
# bold=
:if ($bold="yes") do={
:set ($c8str->"mod") "$($c8str->"mod")1;"
# set both bold=yes and light=yes? bold wins...
} else={
# dim=
:if ($dim="yes") do={
:set ($c8str->"mod") "$($c8str->"mod")2;"
}
}
}
# if bg= set, apply color
:if ([:typeof $bg]="str") do={
:if ([:typeof [$lookupcolor8 $bg]] = "array") do={
:set ($c8str->"bg") ([$lookupcolor8 $bg]->1)
} else={:error "bg=$bg is not a valid color"}
}
# build the output
:local rv "\1B[$($c8str->"mod")$($c8str->"fg");$($c8str->"bg")m"
# if debug=yes, show the ANSI codes instead
:if ($debug = "yes") do={
:return [:put "\\1B[$[:pick $rv 2 80]"]
}
# if the 2nd arg is text, or text= set,
:local ltext $2
:if ([:typeof $text]="str") do={
:set ltext $text
}
:if ([:typeof $ltext] = "str") do={
:return [:put "$rv$2$[$CHALK reset]"]
}
:return $rv
}
_The following GitHub gist was used as reference for the ANSI codes used here: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797_
TODO
- support “cls” and/or"clear-screen" to wipe screen
- reset should be just ]0m not ]0,49m
- debug=yes does not work with URL nor includes text if there was text provided
- add RGB support if an 3 element array is provided {R;G;B} as a color name
- should support ascii name for control codes (e.g. $CHALK esc or $CHALK bel)
- incorporate some “color prefix code” like + - etc to avoid needing inverse= dim=
- help should use $0 instead of assuming name is CHALK
edit 1/2: updated TODOs