Page 1 of 4

Echo with color.

Posted: Sat Dec 05, 2009 4:47 am
by Denarii
I've included comments explaining the function. For this to work you need to place this dll in your Mudlet folder:
rex_pcre.zip
(10.53 KiB) Downloaded 696 times
It's a win32 binary, if you're using Linux or OSX you may need to compile lrexlib (http://luaforge.net/projects/lrexlib/).

Lrexlib adds regex support within lua.

Code: Select all

rex = require"rex_pcre" or echo"\nFailed to load rex_pcre.dll."

--[[-------------------------------------------------------------------------------
-- Echo with color function.
-- Arg1: String to echo
-- Arg2: String containing value for foreground color in hexadecimal RGB format
-- Arg3: String containing value for background color in hexadecimal RGB format
--
-- Color changes can be made within the string using the format |cFRFGFB,BRBGBB
-- where FR is the foreground red value, FG is the foreground green value, FB
-- is the foreground blue value, BR is the background red value, etc. ,BRBGBB
-- is optional. |r can be used within the string to reset the colors to default.
-- 
-- The colors in arg2 and arg3 replace the normal defaults for your console.
-- So if you use cecho("|cff0000Testing |rTesting", "00ff00", "0000ff"),
-- the first Testing would be red on black and the second would be green on blue.
--]]-------------------------------------------------------------------------------

cecho = function(str, fgColor, bgColor, insert)
	local t = {}
	local reset, out
	if insert then
		out = function(str)
			insertText(str)
		end
	else
		out = function(str)
			echo(str)
		end
	end
	if fgColor then
		if bgColor then
			reset = function()
				local fr, fg, fb = rex.new("([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})"):match(fgColor)
				fr, fg, fb = tonumber(fr, 16), tonumber(fg, 16), tonumber(fb, 16)
				setFgColor(fr, fg, fb)
				local br, bg, bb = rex.new("([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})"):match(bgColor)
				br, bg, bb = tonumber(br, 16), tonumber(bg, 16), tonumber(bb, 16)
				setBgColor(br, bg, bb)
			end
		else
			reset = function()
				local fr, fg, fb = rex.new("([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})"):match(fgColor)
				fr, fg, fb = tonumber(fr, 16), tonumber(fg, 16), tonumber(fb, 16)
				setFgColor(fr, fg, fb)
			end
		end
	elseif bgColor then
		reset = function()
			local br, bg, bb = rex.new("([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})"):match(bgColor)
			br, bg, bb = tonumber(br, 16), tonumber(bg, 16), tonumber(bb, 16)
			setBgColor(br, bg, bb)
		end
	else
		reset = function()
			resetFormat()
		end
	end
	
	for s, fr, fg, fb, br, bg, bb, r in rex.split(str, [[(?:\|c([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2}),?([0-9a-fA-F]{2})?([0-9a-fA-F]{2})?([0-9a-fA-F]{2})?|(\|r))]]) do 
		local fore, back, color
		if fr and fg and fb then fore = { fr, fg, fb } end
		if br and bg and bb then back = { br, bg, bb } end
		if fore and back then 
			color = { ["fg"] = fore, ["bg"] = back }
		elseif fore then
			color = { ["fg"] = fore }
		end
		if s then table.insert(t, s) end
		if color then table.insert(t, color) end
		if r then table.insert(t, "r") end
	end
	
	for _, v in ipairs(t) do
		if type(v) == 'table' then
			local fr, fg, fb = unpack(v.fg)
			fr, fg, fb = tonumber(fr, 16), tonumber(fg, 16), tonumber(fb, 16)
			setFgColor(fr, fg, fb)
			if v.bg then
				local br, bg, bb = unpack(v.bg)
				br, bg, bb = tonumber(br, 16), tonumber(bg, 16), tonumber(bb, 16)
				setBgColor(br, bg, bb)
			end
		elseif v == "r" then
			reset()
		else
			out(v)
		end
	end
	resetFormat()
end

Re: Echo with color.

Posted: Sat Dec 05, 2009 1:50 pm
by Vadi
Why hexadecimal?

Re: Echo with color.

Posted: Sat Dec 05, 2009 7:32 pm
by JerleMinara
I'll talk to heiko about getting rexlib bound in. No reason not to have regex-capable LUA!

Re: Echo with color.

Posted: Sat Dec 05, 2009 7:57 pm
by Denarii
Added an option for making it use insertText() instead of echo().

And hexadecimal because that's what I'm used to when working with color and it's more concise. :p

Re: Echo with color.

Posted: Sun Dec 06, 2009 12:19 am
by Denarii
Working on adding the ability to echo to other windows. Waiting for a resetFormat(windowName) option.

Re: Echo with color.

Posted: Mon Dec 14, 2009 10:25 pm
by Iocun
I have a small alternative function to this, which doesn't allow for so many colors (just the named colors fg() and bg() accept), and currently only changes the foreground color. It's a very simple function though and quick to use.

Code: Select all

function cecho(s)
	for colour, text in string.gmatch("<white>"..s, "<([a-z_]+)>([^<>]+)") do
		fg(colour)
		echo(text)
	end
	resetFormat()
	echo("\n")
end
It is used like this: cecho("This <light_blue>is a text <gold>in many <orange>colors!")
I.e. just indicate a color change by the color name in angle brackets. The default color is white, so if you indicate nothing, it will echo in white. You can change this by changing the <white> in the above function to any other named color.

Oh, I added the echo("\n") at the end because I generally like my echos to be on a single line. Feel free to remove that if you wish.

Re: Echo with color.

Posted: Tue Dec 15, 2009 1:01 pm
by Vadi
Can you expand it to work on miniConsoles too?

Re: Echo with color.

Posted: Wed Dec 16, 2009 4:56 pm
by Iocun
This variant works in miniConsoles as well. Since fg() doesn't work in other windows than the main window (as far as I know), I have to translate the named colors into RGB values for setFgColor.

Code: Select all

function cechowin(win,s)
	for colour, text in string.gmatch("<white>"..s, "<([a-z_]+)>([^<>]+)") do
		setFgColor(win, color_table[colour][1], color_table[colour][2], color_table[colour][3])
		echo(win,text)
	end
	echo(win,"\n")
end
Example: cechowin("status", "This is<orange> a colorful<medium_spring_green> echo.\n")

Of course, if one prefers to work with RGB values right away, one might use this:

Code: Select all

function cechowin(win, s)
	for r,g,b,text in string.gmatch("<255,255,255>"..s, "<(%d+), ?(%d+), ?(%d+)>([^<>]+)") do
		setFgColor(win,r,g,b)
		echo(win, text)
	end
	echo(win, "\n")
end
Example: cechowin("status", "This is an <255,120,0>orange echo followed by something in <50,120,50> dark green.")

Re: Echo with color.

Posted: Wed Dec 16, 2009 9:56 pm
by Vadi
Would be great to have these be combined into one function - we'll include it as part of LuaGlobal then, and the hex version as checho.

Re: Echo with color.

Posted: Thu Dec 17, 2009 4:22 am
by Iocun
All right! I made this updated version. It does all the things the previous versions do: It recognizes named colors, as well as RGB values, you can optionally indicate a window name before the string, plus this new version also has background colors now!

Syntax for a color change is <fgcolor:bgcolor>
fgcolor can be a named color (such as dark_green) or a RGB value, separated by commas (such as 255,55,55).
Ditto for bgcolor. You can also mix up RGB values and named colors.
If you want to indicate only the fgcolor, simply write that color in angular brackets, e.g. <red>. The default bgcolor will then be black.
If you want to indicate only the bgcolor, write that color in angular brackets with the colon before it, e.g. <:green>. The default fgcolor will then be white.

Spaces should not matter, i.e. you can add spaces before and after the names and commas as you wish.

Code: Select all

function cecho(window,text)
	local win = text and window
	local s = text or window

	for color,text in string.gmatch("<white>"..s, "<([a-z_0-9, :]+)>([^<>]+)") do			
		local colist	=	string.split(color..":", "%s*:%s*")
		local fgcol	=	colist[1] ~= "" and colist[1] or "white"
		local bgcol	=	colist[2] ~= "" and colist[2] or "black"
		local FGrgb	=	color_table[fgcol] or string.split(fgcol, ",")
		local BGrgb	=	color_table[bgcol] or string.split(bgcol, ",")

		if win then
			setFgColor(win, FGrgb[1], FGrgb[2], FGrgb[3])
			setBgColor(win, BGrgb[1], BGrgb[2], BGrgb[3])
			echo(win,text)
		else
			setFgColor(FGrgb[1], FGrgb[2], FGrgb[3])
			setBgColor(BGrgb[1], BGrgb[2], BGrgb[3])
			echo(text)
		end			
	end

	if win then
		resetFormat(win)
		echo(win,"\n")	
	else
		resetFormat()
		echo("\n")
	end
end

Some example of its usage:

cecho("This is a <red>colourful <dark_green>echo.")

cecho("status", "This is a <red>colourful <dark_green>echo.")

cecho("This is a <orange:white> orange on white echo.")

cecho("This works also with <255,100,0:15,15,15>RGB < : 30,30,100>values.")

cecho("mywindow", "And < : blue>all <150,25 ,66 : red>kinds of <150 , 15 , 15> weird <red: white> mixes and spacings.")