How to find the colour of any character in a line

Posted by Nick Gammon on Thu 19 Apr 2007 12:56 AM — 3 posts, 27,655 views.

Australia Forum Administrator #0
Sometimes you need to find whether a certain part of a line from the MUD is in a particular colour (or just to simply find what the colour is).

The function below (in Lua) illustrates how you can "walk" the style runs to find which run belongs to a certain character. For example, to find the style of the character at column 10:


style = GetStyle (TriggerStyleRuns, 10)


Now you can find the colour like this:


textcolour = style.textcolour
backcolour = style.backcolour


This can be handy in a trigger where you need to detect (say), if a word is in red.

There are two ways you can get the style runs in Lua. The first is the fourth argument to a function called by a trigger. For example:


function my_trigger (name, line, wildcards, styles)

end -- function my_trigger


In this case "styles" is the table of style runs.

Another way is if you use "send to script (after omit)" then MUSHclient sets up a global variable called TriggerStyleRuns. That is for use inside the trigger, for example to omit the line from output and then redisplay it in a different way.

Here is the function:



--[[

GetStyle:
  Finds a style run corresponding to a given column 

  Returns nil if style run not found (eg. column out of range)

  If style run found returns: 
     * the style table (see below)
     * the character at that column
     * the style run number (eg. style 3)

The style table should contain the following:

  t.text        --> text of that (entire) style run
  t.length      --> length of the (entire) style run
  t.textcolour  --> text colour (RGB number)
  t.backcolour  --> background colour (RGB number)
  t.style       --> style bits (1=bold, 2=underline, 4=italic)

--]]

function GetStyle (styleRuns, wantedColumn)
local currentColumn = 1

   -- check arguments
   assert (type (styleRuns) == "table", 
           "First argument to GetStyle must be table of style runs")

   assert (type (wantedColumn) == "number" and wantedColumn >= 1, 
           "Second argument to GetStyle must be column number to find")

   -- go through each style
   for item, style in ipairs (styleRuns) do
     local position = wantedColumn - currentColumn + 1  -- where letter is in style
     currentColumn = currentColumn + style.length       -- next style starts here
     if currentColumn > wantedColumn then  -- if we are within this style
        return style, string.sub (style.text, position, position), item  -- done
     end -- if found column
   end -- for each style

   -- if not found: result is nil

end -- function GetStyle 



You pass it:

  • The table of style runs
  • The column you are interested in (starting at 1)


If the column is found, the function returns:

  • The style run associated with that column (see the comments above, you get the text, length, colours, and style bits).
  • The letter at that column (eg. the letter "b")
  • Which style run it was found in (eg. style 3)


If the column is not found, the function returns nil.

If you call it without a table as the first argument, or a number as the second argument, it raises an error.
Amended on Thu 19 Apr 2007 01:02 AM by Nick Gammon
Australia Forum Administrator #1
As an extension to this idea, we might need to find what column a particular word is in. This would be the first step to identifying the colour.

In this example, I use a trigger script to find the position of the word "bleeding" in a triggered line. Then we use GetStyle to find the colour of that word.


function my_trigger (name, line, wildcards, styles)
 
  -- find location of word
  col = string.find (line, "bleeding")
  if not col then
    return
  end -- word not found

  -- get style at that location
  style = GetStyle (styles, col)

  -- display it
  print ("word is in", RGBColourToName (style.textcolour))
 
end -- function my_trigger

Australia Forum Administrator #2
The GetStyle function is now incorporated in the file getstyle.lua which ships with MUSHclient 4.05 onwards.

So, to find a style you now just need to "require" it, like this:


require "getstyle"

style = GetStyle (styles, col)  -- find style for column "col" in "styles"