Highlighting mixed with gagging...

Posted by Larkin on Thu 16 Jul 2009 06:30 PM — 7 posts, 29,560 views.

#0
I've got scripts that a lot of people use and build on, so I'm trying to keep things relatively general and compartmentalized. Well, now I've got a large script for doing mapping in Lusternia and it has triggers to gag certain lines and then redisplay them with my own colors and prepended/appended text, such as adding a room's vnum after you scry a person's location.

This is pretty slick by itself, but when I combine it with my name highlighting script, the names are no longer highlighted because the mapper trigger gags the line and displays it without the changes to the styles.

I'll try to post the basic gist of what I'm doing without filling up pages and pages with the whole script. If anyone has any suggestions for a way around this, please let me know. Thanks.

<triggers>
  <trigger
   enabled="y"
   match="^You make out the scent of [A-Z][a-z]+ coming from (.+?)$"
   name="mapper_locate_scent__"
   omit_from_log="y"
   omit_from_output="y"
   regexp="y"
   script="mapper_locate_local"
   sequence="10000"
  >
  </trigger>
</triggers>


function mapper_locate_local(name, line, wildcards, styles)
  for _,v in ipairs(styles) do
    ColourTell(RGBColourToName(v.textcolour), RGBColourToName(v.backcolour), v.text)
  end

  -- Snipped code to append the room's vnum after the triggered line

  Note("")
end


<triggers>
  <trigger
   custom_colour="8"
   enabled="y"
   expand_variables="y"
   keep_evaluating="y"
   make_underline="y"
   match="\b(@!player_names)\b"
   name="color_players__"
   regexp="y"
   repeat="y"
   sequence="10000"
  >
  </trigger>
</triggers>

Australia Forum Administrator #1
Your basic problem is that MUSHclient makes a single copy of the style runs of the incoming line, before calling all your triggers. This is more efficient than doing it for every one of possibly thousands of triggers. However if a trigger changes the styles (eg. by colouring) then that is not reflected in the saved style runs.

All I can suggest doing is, in the code that displays the amended line, do a bit of extra processing to colour the words at that point - that is, amend the style runs yourself.

This would be reasonably easy if the word in question is in a single style. Then you just look at each style, and within that do a string.find to see if your word exists. If so, split that style into 3 parts:

  • Before the word (keep in same colour)
  • The word itself (change the colour)
  • After the word (keep in original colour)


So basically, a table.remove for the existing style, followed by three table.inserts (checking if any are zero-length would probably help).
#2
I figured I'd have to roll this functionality together into some sort of central "colorizer" system, but I was hoping there was some trick with sequencing to make this work.

Could you explain a little more about the remove/insert code? Not quite sure I'm following you there on where the styles are modified and eventually displayed (in the setup I have or some new setup).
Australia Forum Administrator #3
Well, I changed my mind about the removing of styles, as I could see that removing from a table whilst stepping through it could be a problem. The example code below takes a line, looks for "o" in it, and recolours that.


test = {
  [1] = {
    textcolour = 12632256,
    backcolour = 0,
    length = 8,
    style = 0,
    text = "this is ",
    },
  [2] = {
    textcolour = 65535,
    backcolour = 0,
    length = 14,
    style = 1,
    text = "test of style ",
    },
  [3] = {
    textcolour = 16776960,
    backcolour = 0,
    length = 5,
    style = 1,
    text = "runs ",
    },
  [4] = {
    textcolour = 65280,
    backcolour = 0,
    length = 6,
    style = 1,
    text = "today ",
    },
  }

 -- display before amendment

  for _, v in ipairs (test) do
    ColourTell (RGBColourToName (v.textcolour), 
                RGBColourToName (v.backcolour), 
                v.text)  
  end -- for each style run
  Note ("")  -- wrap up line


  local new_styles = {}  -- copy style runs into here
  target = "o"

  for _, v in ipairs (test) do

    -- find target string in this style
    local s, e = v.text:find (target)  -- s = start, e = end

    if s then  -- if found

      -- copy part coming before the string
      if s > 1 then
        table.insert (new_styles, 
          {
          textcolour = v.textcolour,
          backcolour = v.backcolour,
          length = s - 1,
          text = v.text:sub (1, s - 1),
          })
       end -- if need to save first part

     -- replace with amended string
     table.insert (new_styles, 
        {
        textcolour = ColourNameToRGB "green",
        backcolour = ColourNameToRGB "white",
        length = e - s + 1,
        text = v.text:sub (s, e),
        })

      -- copy part coming after the string
      if e < v.length then
        table.insert (new_styles, 
          {
          textcolour = v.textcolour,
          backcolour = v.backcolour,
          length = v.length - e,
          text = v.text:sub (e + 1),
          })
       end -- if need to save last part 
    else
      table.insert (new_styles, v)  -- just copy entire style run over
    end -- if

  end -- for

 -- display after amendment

  for _, v in ipairs (new_styles) do
    ColourTell (RGBColourToName (v.textcolour), 
                RGBColourToName (v.backcolour), 
                v.text)  
  end -- for each style run
  Note ("")  -- wrap up line



The "test" table is an example of how a style run might look. The test displays the line before and after (try running in the Immediate window).

The middle loop copies the entire style run to a new table, amending each style if necessary if the target word is detected.
Amended on Fri 17 Jul 2009 07:40 AM by Nick Gammon
#4
Thanks! I'll find a way to make this work for what I need now, hopefully.
#5
I have the basics of this working the way I want, but is there any way to draw the text with an underline?

Australia Forum Administrator #6
http://www.gammon.com.au/scripts/doc.php?function=NoteStyle

eg.

NoteStyle (2); -- set underline style bit
ColourNote ("blue", "", "hello, world");