Echo with color.

Share your scripts and packages with other Mudlet users.
Denarii
Posts: 111
Joined: Thu Dec 03, 2009 10:54 pm

Echo with color.

Post 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 681 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
Last edited by Denarii on Sat Dec 05, 2009 7:57 pm, edited 2 times in total.

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Echo with color.

Post by Vadi »

Why hexadecimal?

JerleMinara
Posts: 7
Joined: Sat Dec 05, 2009 12:56 am

Re: Echo with color.

Post by JerleMinara »

I'll talk to heiko about getting rexlib bound in. No reason not to have regex-capable LUA!

Denarii
Posts: 111
Joined: Thu Dec 03, 2009 10:54 pm

Re: Echo with color.

Post 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

Denarii
Posts: 111
Joined: Thu Dec 03, 2009 10:54 pm

Re: Echo with color.

Post by Denarii »

Working on adding the ability to echo to other windows. Waiting for a resetFormat(windowName) option.

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Echo with color.

Post 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.

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Echo with color.

Post by Vadi »

Can you expand it to work on miniConsoles too?

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Echo with color.

Post 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.")

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Echo with color.

Post 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.

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Echo with color.

Post 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.")

Post Reply