Trigger match only the first highlighted word

Posted by Markomo on Fri 15 Nov 2024 01:41 PM — 19 posts, 29,341 views.

#0
Hello,

i use this trigger


<triggers>
  <trigger
   custom_colour="11"
   enabled="y"
   keep_evaluating="y"
   match="\b(?!(Ab|Abends|AP|D|UT|OT|P|Q|Abenteuerlich|Aber|Abermals|Abhanden|Abher|Abhin|Abseits|Absolut|Absonderlicherweise|Absurderweise|Abzueglich|Achtens|Achteraus|Achtern|Achtmal|Aehnlich|Aeusserst|Ah|Aha|Allda|Alldieweil|Alle|Allenaselang|Allenaslang|Allein|Allemal|Allenfalls|Allenthalben|Allerdings|Allerhoechstens|Allerorten|Allerseits|Allerspaetestens|Alleweg|Alleweil|Allgemach|Allig|Allseits|Allzeit|Allzu|Alsbald|Alsdann|Also|Alt|Alters|Altershalber|Am|Amtshalber|An|Anbei|Andante|Andantino|Anderenfalls|Anderenorts|Anderentags|Andererseits|Andernfalls|Andernorts|Anderntags|Anders|Anderswo|Anderweit|Andrerseits|Aneinander|Anfangs|Angst|Anhand|Anjetzt|Anno|Ansatzweise|Anscheinend|Ansonsten|Anstaendigerweise|Anstandshalber|Anstandslos|Anstatt|Anwesend|Apropos|Arschling|Attraktiv|Auch|Auf|Aufgrund|Aufhin|Aufi|Aufmerksam|Aufseiten|Aufwaerts|Aus|Auseinander|Zwischen|Zwischendurch)\b)([A-Z][A-Za-z0-9~'-]*)" <!-- Simple regex: Words only -->
   regexp="y"
   repeat="y"
   send_to="12"
   sequence="100"
  >
  <send>
if _G.parse_active then
  -- Get the entire word (highlighted in orange)
  local obj = "%0" -- Use %0 to get the entire word found
  Note("Found highlighted object: '" .. obj .. "'")

  -- Prüfen, ob ein gültiges Objekt erkannt wurde
  if not obj or obj == "" then
    Note("No valid highlighted object recognised.")
    return
  end

  -- Initialise the list of examined objects, if not available
  if not _G.parsed_objects then
    _G.parsed_objects = {}
  end

  -- Check whether the object has already been inspected
  if not _G.parsed_objects[obj] then
    _G.parsed_objects[obj] = true -- Mark as investigated
    Execute("b " .. obj)
    Note("Objekt '" .. obj .. "' is being investigated.")
  else
    Note("Objekt '" .. obj .. "' has already been analysed.")
  end
else
  if not _G.warned_about_inactive then
    Note("Parsing is not active. Please start with 'reset_b'")
    _G.warned_about_inactive = true
  end
end
  </send>
  </trigger>
</triggers>


The main problem is now. The trigger match only the first highlighted word.

https://ibb.co/ZWsTbgV

What am I doing wrong?

BR

PS: The RegEx trigger works perfectly -> https://ibb.co/MhNP3fH
Amended on Fri 15 Nov 2024 01:45 PM by Markomo
Australia Forum Administrator #1
Those screenshots are hard to read.

You don't need to put _G. in front of every global variable. If they are not declared local they are assumed to be global.

What are you expecting to see, exactly?

Repeating on the same line is for colouring words, not for executing the script multiple times. If you want to do something multiple times on one line, do that in the script itself (eg. do string.gmatch and then do the action you want on every match).
#2
Nick Gammon said:

Those screenshots are hard to read.

You don't need to put _G. in front of every global variable. If they are not declared local they are assumed to be global.

What are you expecting to see, exactly?

Repeating on the same line is for colouring words, not for executing the script multiple times. If you want to do something multiple times on one line, do that in the script itself (eg. do string.gmatch and then do the action you want on every match).


Thank you for your reply.

I want if it says "You see a tree and a house and a car." then the regex-trigger should colour "tree, house, car and I want the script to execute my commands tree, house, car.

Currently, however, it only does this for the first object. In my example "tree", it then cancels and goes to the next line.

BR
Australia Forum Administrator #3
This should work for you:


<triggers>
  <trigger
   enabled="y"
   expand_variables="y"
   match="^.*\b(@!objects)\b.*$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
for word in string.gmatch ("@objects", "%a+") do
  if string.match ("%0", "%%f[%%a]" .. word .. "%%f[%%A]") then
     Send ("examine " .. word)
  end -- if
end -- for
</send>
  </trigger>
</triggers>


Template:pasting
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.


Now you need to put the words you are looking for into a variable named "objects" in (World configuration -> Scripting -> Variables), for example:


<variables>
  <variable name="objects">tree|house|car</variable>
</variables>


Each word needs to be separated by a "|" symbol, like above. What the trigger does is match any of those words, and, if found, then runs the script that searches for all of those words in the matching text and examines each one it finds. The stuff about %%f is for a "frontier" pattern which basically restricts matches to a word boundary.

Test



I see a treehouse, house and car here.
examine house
examine car


It examined the house and car but not the treehouse because that was not a word on its own.
Amended on Sat 16 Nov 2024 09:20 PM by Nick Gammon
#4
Interesting approach, but unfortunately that doesn't help me, because I want all the words highlighted in orange to be looked at. Otherwise I would have to extract the words from each room in order to explore them. I thought Mushclient would offer a function that can automatically capture highlighted words.

I still hope that you have a more practical approach for me. As you have seen in my screenshot, there is a lot of text and "German" is a difficult language ;)

Thanks Nick!
Amended on Fri 22 Nov 2024 03:04 AM by Nick Gammon
Australia Forum Administrator #5
In what way does my solution not work for you?
#6
Nick Gammon said:

In what way does my solution not work for you?


You wrote that I would have to put every single word into a variable. The texts of all the rooms in my mud are far too different for that.

Quote:

Now you need to put the words you are looking for into a variable named "objects" in (World configuration -> Scripting -> Variables), for example:


<variables>
<variable name="objects">tree|house|car</variable>
</variables>


Each word needs to be separated by a "|" symbol, like above. What the trigger does is match any of those words, and, if found, then runs the script that searches for all of those words in the matching text and examines each one it finds. The stuff about %%f is for a "frontier" pattern which basically restricts matches to a word boundary.
Australia Forum Administrator #7
I don't understand the difficulty here. You already have all the words in your first post. All you have to do is make a variable (in the World configuration -> Scripting -> Variables) named "objects" and copy/paste the words into it:



Ab|Abends|AP|D|UT|OT|P|Q|Abenteuerlich|Aber|Abermals|Abhanden|Abher|Abhin|Abseits|Absolut|Absonderlicherweise|Absurderweise|Abzueglich|Achtens|Achteraus|Achtern|Achtmal|Aehnlich|Aeusserst|Ah|Aha|Allda|Alldieweil|Alle|Allenaselang|Allenaslang|Allein|Allemal|Allenfalls|Allenthalben|Allerdings|Allerhoechstens|Allerorten|Allerseits|Allerspaetestens|Alleweg|Alleweil|Allgemach|Allig|Allseits|Allzeit|Allzu|Alsbald|Alsdann|Also|Alt|Alters|Altershalber|Am|Amtshalber|An|Anbei|Andante|Andantino|Anderenfalls|Anderenorts|Anderentags|Andererseits|Andernfalls|Andernorts|Anderntags|Anders|Anderswo|Anderweit|Andrerseits|Aneinander|Anfangs|Angst|Anhand|Anjetzt|Anno|Ansatzweise|Anscheinend|Ansonsten|Anstaendigerweise|Anstandshalber|Anstandslos|Anstatt|Anwesend|Apropos|Arschling|Attraktiv|Auch|Auf|Aufgrund|Aufhin|Aufi|Aufmerksam|Aufseiten|Aufwaerts|Aus|Auseinander|Zwischen|Zwischendurch
Amended on Mon 18 Nov 2024 08:33 PM by Nick Gammon
#8
Nick Gammon said:

I don't understand the difficulty here. You already have all the words in your first post. All you have to do is make a variable (in the World configuration -> Scripting -> Variables) named "objects" and copy/paste the words into it:



Ab|Abends|AP|D|UT|OT|P|Q|Abenteuerlich|Aber|Abermals|Abhanden|Abher|Abhin|Abseits|Absolut|Absonderlicherweise|Absurderweise|Abzueglich|Achtens|Achteraus|Achtern|Achtmal|Aehnlich|Aeusserst|Ah|Aha|Allda|Alldieweil|Alle|Allenaselang|Allenaslang|Allein|Allemal|Allenfalls|Allenthalben|Allerdings|Allerhoechstens|Allerorten|Allerseits|Allerspaetestens|Alleweg|Alleweil|Allgemach|Allig|Allseits|Allzeit|Allzu|Alsbald|Alsdann|Also|Alt|Alters|Altershalber|Am|Amtshalber|An|Anbei|Andante|Andantino|Anderenfalls|Anderenorts|Anderentags|Andererseits|Andernfalls|Andernorts|Anderntags|Anders|Anderswo|Anderweit|Andrerseits|Aneinander|Anfangs|Angst|Anhand|Anjetzt|Anno|Ansatzweise|Anscheinend|Ansonsten|Anstaendigerweise|Anstandshalber|Anstandslos|Anstatt|Anwesend|Apropos|Arschling|Attraktiv|Auch|Auf|Aufgrund|Aufhin|Aufi|Aufmerksam|Aufseiten|Aufwaerts|Aus|Auseinander|Zwischen|Zwischendurch



Ah, I understand the confusion now. All these words are an exclusion list and not words that are marked in orange. This is appropriate at the end of the regex.


<triggers>
  <trigger
   custom_colour="11"
   enabled="y"
   keep_evaluating="y"
   match="\b(?!(Ab|any number of other words|Zwischendurch)\b)([A-Z][A-Za-z0-9~'-]*)"
   regexp="y"
   repeat="y"
   send_to="12"
   sequence="60"
  >
  </trigger>
</triggers>
Australia Forum Administrator #9
Just to be clear then, you want to examine every word on every line that arrives, unless it is in your exclusion list?
#10
Nick Gammon said:

Just to be clear then, you want to examine every word on every line that arrives, unless it is in your exclusion list?


Yes. All orange highlighted words
Australia Forum Administrator #11
OK, so assuming you set up the "objects" variable as described above (your exclusion list) then this should do it:


<triggers>
  <trigger
   enabled="y"
   match="*"
   send_to="12"
   sequence="100"
  >
  <send>

local input_line = [===[%0]===]
local exclusions = { }

-- build table of exclusion words
for word in string.gmatch (GetVariable ("objects"), "%a+") do
  exclusions [word] = true
end -- for each excluasio

for word in string.gmatch (input_line, "[A-Z][A-Za-z0-9~'%-]+") do
  if not word [exclusions] then
    Note ("examine " .. word)
  end -- if
end -- for

</send>
  </trigger>
</triggers>



What that does is process every word of every line, looking for words starting with a capital (uppercase) letter, and then check against the exclusion list. If not found, it examines it.

Test:


Die schweren Antriebe enes Raungleiters dreohnen laut itgendwo am nordoestlichen Himmel
examine Die
examine Antriebe
examine Raungleiters
examine Himmel


Forgive me if I misspelt some of your German words, the screenshot was very hard to read.
Amended on Wed 20 Nov 2024 05:39 AM by Nick Gammon
#12
You don't have to apologise for anything. I am very grateful that you are taking the time. The trigger option with * is not an option, because otherwise the trigger takes everything and I also have to extend the exclusion list with the prompt and special characters and other mud-specific stuff. This might generate endless loops.
Amended on Fri 22 Nov 2024 03:02 AM by Nick Gammon
Australia Forum Administrator #13
If you want to match only certain lines then you have to specify, somehow, which lines are going to be tested and which ones are not, which I don't see you doing in your original post.
#14
Nick Gammon said:

If you want to match only certain lines then you have to specify, somehow, which lines are going to be tested and which ones are not, which I don't see you doing in your original post.


That's right. I thought that was logical, as I only wanted to highlight all the orange-coloured words. Hence the problem where I said "it only takes the first word of each line".

if _G.parse_active then
-- Get the entire word (highlighted in orange)
local obj = "%0" -- Use %0 to get the entire word found
Note("Found highlighted object: '" .. obj .. "'")

So you don't have a solution to my problem?
Australia Forum Administrator #15
It's very unclear from your posts and your screenshots whether you coloured the words orange in the trigger, or if the MUD did. If the MUD did you could match on every line, and then go through the style runs and look for words in orange.

Template:faq=33
Please read the MUSHclient FAQ - point 33.
#16
Nick Gammon said:

It's very unclear from your posts and your screenshots whether you coloured the words orange in the trigger, or if the MUD did. If the MUD did you could match on every line, and then go through the style runs and look for words in orange.

(faq=33)


Then I apologise. I thought you saw it on the trigger itself. It uses "orange" as a highlight.

I'll have a look at your FAQ point and get back to you if I'm stuck. :)
Amended on Fri 22 Nov 2024 10:11 PM by Markomo
Australia Forum Administrator #17
Yes, but ...

In your first post you colour in orange all words not in the exclusion list, and say you want to examine all those words.

Then when I proposed a solution that examined all words not in the exclusion list, you said that was too many words and you only wanted to examine the orange ones. What am I missing?
#18
Nick Gammon said:

Yes, but ...

In your first post you colour in orange all words not in the exclusion list, and say you want to examine all those words.

Then when I proposed a solution that examined all words not in the exclusion list, you said that was too many words and you only wanted to examine the orange ones. What am I missing?


I would like to apologise again. I will write exactly what my goal is in future threads.