Unknown2005-05-11 03:31:48
After I made the last post with the raw code for creating multiline triggers, "adrian" on the IRC channel (#lusternia on GamesNET) mentioned I should create a macro to do it all automatically. Well, I gave it a shot and this is what I came up with.
I wrote this macro more specifically for my defences script that I'm working on. I'll probably adjust it a bit for some other trigger heavy scripts (curing, combat, etc).
This macro is intended for use only in function form. It takes at least 3 parameters. The first is always the label for the trigger, which doubles as the name of the macro that contains the code you wish the trigger to run if matched. The second argument specifies whether the trigger is to match a defence going up, or down (this determines whether it's highlighted dark yellow or bright yellow. The remaining arguments are the regexps for each line.
The thing I really like about this is that the regexps for each line can be entered just as if you were entering a one-line trigger for that line. You don't need to worry about extra backslashes, or escaping the $ anchor, my script takes care of that for you.
For example, lets say you load the following code from a script while running TF:
That code generates all of the necessary defs and macros for the multiline triggers. After loading that in, I typed "/list" to see the result. This is the code the above script generated:
That generated code doesn't have any linebreaks of course. When you put the linebreaks and tabs back into those generated commands, as if they'd come from a script you wrote, you get the following:
Which is almost identical to the code I posted previously (I found a few bugs with how I understood backslash compression while designing this new script).
I'm not certain if this script takes into consideration all posibilities, however it works for everything I need it for right now. If anyone has any ideas on how to improve this script or a better approach to solving the multiline problem, I'd be very interested in discussing it with you.
CODE
;;; generate defence highlighting triggers
;;; syntax: gentrig_defence_hl('','','']])
/def gentrig_defence_hl = \\
  /if (({#} > 2) & (({2} =~ "up") | ({2} =~ "down"))) \\
    /let oneslash=\\\\ %; \\
    /let onepercent=%% %; \\
    /let onedollar=$$ %; \\
    /let label=%{1} %; \\
    /shift %; \\
    /if ({1} =~ "up") \\
      /let color=Cyellow %; \\
    /elseif ({1} =~ "down") \\
      /let color=BCyellow %; \\
    /endif %; \\
    /shift %; \\
    /let line_number=1 %; \\
    /let line=%{1} %; \\
    /let generated_trig= %; \\
    /test generated_trig:=strcat('/def -mregexp -n0 -p285 -F -a',{color},' -t"',{line},'" highlight_defences_',{label},'_line',{line_number},' = ') %; \\
    /shift %; \\
    /while ({#}) \\
      /test ++line_number %; \\
      /test line:=replace({oneslash},strrep({oneslash},pow(2,{line_number}-1)),{1}) %; \\
      /if (regmatch('.*\\$$',{line}) > 0) \\
        /test line:=substr({line},0,-1) %; \\
        /test line:=strcat({line},strrep({oneslash},pow(2,{line_number}-1)-1),{onedollar}) %; \\
      /endif %; \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p287 -F -a',{color},' -t"',{line},'" highlight_defences_',{label},'_line',{line_number},' = ') %; \\
      /test generated_trig:=strcat({generated_trig},'/undef highlight_defences_',{label},'_catch_all ',strrep({onepercent},{line_number}),'; ') %; \\
      /shift %; \\
    /done %; \\
    /test generated_trig:=strcat({generated_trig},'/',{label}) %; \\
    /if ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-1),'; ') %; \\
    /endif %; \\
    /while ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p286 -F -t".*" highlight_defences_',{label},'_catch_all = /undef highlight_defences_',{label},'_line',{line_number}) %; \\
      /if ({line_number} > 2) \\
        /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-2),'; ') %; \\
      /endif %; \\
      /test --line_number %; \\
    /done %; \\
    /eval -s0 %{generated_trig} %; \\
  /else \\
    /echol BCcyan 0 <<<< gentrig_defence error: incorrect arguments provided, must be,,]] %; \\
  /endif
;;; syntax: gentrig_defence_hl('
/def gentrig_defence_hl = \\
  /if (({#} > 2) & (({2} =~ "up") | ({2} =~ "down"))) \\
    /let oneslash=\\\\ %; \\
    /let onepercent=%% %; \\
    /let onedollar=$$ %; \\
    /let label=%{1} %; \\
    /shift %; \\
    /if ({1} =~ "up") \\
      /let color=Cyellow %; \\
    /elseif ({1} =~ "down") \\
      /let color=BCyellow %; \\
    /endif %; \\
    /shift %; \\
    /let line_number=1 %; \\
    /let line=%{1} %; \\
    /let generated_trig= %; \\
    /test generated_trig:=strcat('/def -mregexp -n0 -p285 -F -a',{color},' -t"',{line},'" highlight_defences_',{label},'_line',{line_number},' = ') %; \\
    /shift %; \\
    /while ({#}) \\
      /test ++line_number %; \\
      /test line:=replace({oneslash},strrep({oneslash},pow(2,{line_number}-1)),{1}) %; \\
      /if (regmatch('.*\\$$',{line}) > 0) \\
        /test line:=substr({line},0,-1) %; \\
        /test line:=strcat({line},strrep({oneslash},pow(2,{line_number}-1)-1),{onedollar}) %; \\
      /endif %; \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p287 -F -a',{color},' -t"',{line},'" highlight_defences_',{label},'_line',{line_number},' = ') %; \\
      /test generated_trig:=strcat({generated_trig},'/undef highlight_defences_',{label},'_catch_all ',strrep({onepercent},{line_number}),'; ') %; \\
      /shift %; \\
    /done %; \\
    /test generated_trig:=strcat({generated_trig},'/',{label}) %; \\
    /if ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-1),'; ') %; \\
    /endif %; \\
    /while ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p286 -F -t".*" highlight_defences_',{label},'_catch_all = /undef highlight_defences_',{label},'_line',{line_number}) %; \\
      /if ({line_number} > 2) \\
        /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-2),'; ') %; \\
      /endif %; \\
      /test --line_number %; \\
    /done %; \\
    /eval -s0 %{generated_trig} %; \\
  /else \\
    /echol BCcyan 0 <<<< gentrig_defence error: incorrect arguments provided, must be
  /endif
I wrote this macro more specifically for my defences script that I'm working on. I'll probably adjust it a bit for some other trigger heavy scripts (curing, combat, etc).
This macro is intended for use only in function form. It takes at least 3 parameters. The first is always the label for the trigger, which doubles as the name of the macro that contains the code you wish the trigger to run if matched. The second argument specifies whether the trigger is to match a defence going up, or down (this determines whether it's highlighted dark yellow or bright yellow. The remaining arguments are the regexps for each line.
The thing I really like about this is that the regexps for each line can be entered just as if you were entering a one-line trigger for that line. You don't need to worry about extra backslashes, or escaping the $ anchor, my script takes care of that for you.
For example, lets say you load the following code from a script while running TF:
CODE
;;; breathe
/test gentrig_defence_hl('breathe_up','up',\\
    '^You take a few deep breaths to prepare your body for a marathon workout\\.$')
/def breathe_up = /set defence_breathe=1
;;; acquisitio
/test gentrig_defence_hl('acquisitio_up','up',\\
    '^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $',\\
    '^around greedily for something to add to your hoard\\.$')
/test gentrig_defence_hl('acquisitio_down','down',\\
    '^You allow the charm of Acquisitio to leave you and are no longer gripped by an $',\\
    '^unnatural need to accumulate things\\.$')
/def acquisitio_up = /set defence_acquisitio=1
/def acquisitio_down = /set defence_acquisitio=0
;;; yellow
/test gentrig_defence_hl('yellow_up','up',\\
    '^Pressing your hands together before you, you concentrate on your solar plexus $',\\
    '^chakra\\. A golden glow suffuses your solar plexus and your body swells with $',\\
    '^power\\.$')
/def yellow_up = /set defence_yellow=1
/test gentrig_defence_hl('breathe_up','up',\\
    '^You take a few deep breaths to prepare your body for a marathon workout\\.$')
/def breathe_up = /set defence_breathe=1
;;; acquisitio
/test gentrig_defence_hl('acquisitio_up','up',\\
    '^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $',\\
    '^around greedily for something to add to your hoard\\.$')
/test gentrig_defence_hl('acquisitio_down','down',\\
    '^You allow the charm of Acquisitio to leave you and are no longer gripped by an $',\\
    '^unnatural need to accumulate things\\.$')
/def acquisitio_up = /set defence_acquisitio=1
/def acquisitio_down = /set defence_acquisitio=0
;;; yellow
/test gentrig_defence_hl('yellow_up','up',\\
    '^Pressing your hands together before you, you concentrate on your solar plexus $',\\
    '^chakra\\. A golden glow suffuses your solar plexus and your body swells with $',\\
    '^power\\.$')
/def yellow_up = /set defence_yellow=1
That code generates all of the necessary defs and macros for the multiline triggers. After loading that in, I typed "/list" to see the result. This is the code the above script generated:
CODE
% 1358: /def -Fp285 -aCyellow -mregexp -t'^You take a few deep breaths to prepare your body for a marathon workout\\\\.$' highlight_defences_breathe_up_line1 = /breathe_up
% 1359: /def breathe_up = /set defence_breathe=1
% 1360: /def -Fp285 -aCyellow -mregexp -t'^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $' highlight_defences_acquisitio_up_line1 = /def -mregexp -n1 -p287 -F -aCyellow -t"^around greedily for something to add to your hoard\\\\.\\$" highlight_defences_acquisitio_up_line2 = /undef highlight_defences_acquisitio_up_catch_all %%; /acquisitio_up %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_up_catch_all = /undef highlight_defences_acquisitio_up_line2
% 1361: /def -Fp285 -aBCyellow -mregexp -t'^You allow the charm of Acquisitio to leave you and are no longer gripped by an $' highlight_defences_acquisitio_down_line1 = /def -mregexp -n1 -p287 -F -aBCyellow -t"^unnatural need to accumulate things\\\\.\\$" highlight_defences_acquisitio_down_line2 = /undef highlight_defences_acquisitio_down_catch_all %%; /acquisitio_down %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_down_catch_all = /undef highlight_defences_acquisitio_down_line2
% 1362: /def acquisitio_up = /set defence_acquisitio=1
% 1363: /def acquisitio_down = /set defence_acquisitio=0
% 1364: /def -Fp285 -aCyellow -mregexp -t'^Pressing your hands together before you, you concentrate on your solar plexus $' highlight_defences_yellow_up_line1 = /def -mregexp -n1 -p287 -F -aCyellow -t"^chakra\\\\. A golden glow suffuses your solar plexus and your body swells with \\$" highlight_defences_yellow_up_line2 = /undef highlight_defences_yellow_up_catch_all %%; /def -mregexp -n1 -p287 -F -aCyellow -t"^power\\\\\\\\.\\\\\\$" highlight_defences_yellow_up_line3 = /undef highlight_defences_yellow_up_catch_all %%%; /yellow_up %%; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line3 %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line2
% 1365: /def yellow_up = /set defence_yellow=1
% 1359: /def breathe_up = /set defence_breathe=1
% 1360: /def -Fp285 -aCyellow -mregexp -t'^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $' highlight_defences_acquisitio_up_line1 = /def -mregexp -n1 -p287 -F -aCyellow -t"^around greedily for something to add to your hoard\\\\.\\$" highlight_defences_acquisitio_up_line2 = /undef highlight_defences_acquisitio_up_catch_all %%; /acquisitio_up %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_up_catch_all = /undef highlight_defences_acquisitio_up_line2
% 1361: /def -Fp285 -aBCyellow -mregexp -t'^You allow the charm of Acquisitio to leave you and are no longer gripped by an $' highlight_defences_acquisitio_down_line1 = /def -mregexp -n1 -p287 -F -aBCyellow -t"^unnatural need to accumulate things\\\\.\\$" highlight_defences_acquisitio_down_line2 = /undef highlight_defences_acquisitio_down_catch_all %%; /acquisitio_down %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_down_catch_all = /undef highlight_defences_acquisitio_down_line2
% 1362: /def acquisitio_up = /set defence_acquisitio=1
% 1363: /def acquisitio_down = /set defence_acquisitio=0
% 1364: /def -Fp285 -aCyellow -mregexp -t'^Pressing your hands together before you, you concentrate on your solar plexus $' highlight_defences_yellow_up_line1 = /def -mregexp -n1 -p287 -F -aCyellow -t"^chakra\\\\. A golden glow suffuses your solar plexus and your body swells with \\$" highlight_defences_yellow_up_line2 = /undef highlight_defences_yellow_up_catch_all %%; /def -mregexp -n1 -p287 -F -aCyellow -t"^power\\\\\\\\.\\\\\\$" highlight_defences_yellow_up_line3 = /undef highlight_defences_yellow_up_catch_all %%%; /yellow_up %%; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line3 %; /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line2
% 1365: /def yellow_up = /set defence_yellow=1
That generated code doesn't have any linebreaks of course. When you put the linebreaks and tabs back into those generated commands, as if they'd come from a script you wrote, you get the following:
CODE
/def -Fp285 -aCyellow -mregexp -t'^You take a few deep breaths to prepare your body for a marathon workout\\\\.$' highlight_defences_breathe_up_line1 = \\
  /breathe_up
/def breathe_up = /set defence_breathe=1
/def -Fp285 -aCyellow -mregexp -t'^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $' highlight_defences_acquisitio_up_line1 = \\
  /def -mregexp -n1 -p287 -F -aCyellow -t"^around greedily for something to add to your hoard\\\\.\\$" highlight_defences_acquisitio_up_line2 = \\
    /undef highlight_defences_acquisitio_up_catch_all %%; \\
    /acquisitio_up %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_up_catch_all = /undef highlight_defences_acquisitio_up_line2
/def -Fp285 -aBCyellow -mregexp -t'^You allow the charm of Acquisitio to leave you and are no longer gripped by an $' highlight_defences_acquisitio_down_line1 = \\
  /def -mregexp -n1 -p287 -F -aBCyellow -t"^unnatural need to accumulate things\\\\.\\$" highlight_defences_acquisitio_down_line2 = \\
    /undef highlight_defences_acquisitio_down_catch_all %%; \\
    /acquisitio_down %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_down_catch_all = /undef highlight_defences_acquisitio_down_line2
/def acquisitio_up = /set defence_acquisitio=1
/def acquisitio_down = /set defence_acquisitio=0
/def -Fp285 -aCyellow -mregexp -t'^Pressing your hands together before you, you concentrate on your solar plexus $' highlight_defences_yellow_up_line1 = \\
  /def -mregexp -n1 -p287 -F -aCyellow -t"^chakra\\\\. A golden glow suffuses your solar plexus and your body swells with \\$" highlight_defences_yellow_up_line2 = \\
    /undef highlight_defences_yellow_up_catch_all %%; \\
    /def -mregexp -n1 -p287 -F -aCyellow -t"^power\\\\\\\\.\\\\\\$" highlight_defences_yellow_up_line3 = \\
      /undef highlight_defences_yellow_up_catch_all %%%; \\
      /yellow_up %%; \\
    /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line3 %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line2
/def yellow_up = /set defence_yellow=1
  /breathe_up
/def breathe_up = /set defence_breathe=1
/def -Fp285 -aCyellow -mregexp -t'^Chanting the ritual of Acquisitio to yourself, you narrow your eyes and look $' highlight_defences_acquisitio_up_line1 = \\
  /def -mregexp -n1 -p287 -F -aCyellow -t"^around greedily for something to add to your hoard\\\\.\\$" highlight_defences_acquisitio_up_line2 = \\
    /undef highlight_defences_acquisitio_up_catch_all %%; \\
    /acquisitio_up %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_up_catch_all = /undef highlight_defences_acquisitio_up_line2
/def -Fp285 -aBCyellow -mregexp -t'^You allow the charm of Acquisitio to leave you and are no longer gripped by an $' highlight_defences_acquisitio_down_line1 = \\
  /def -mregexp -n1 -p287 -F -aBCyellow -t"^unnatural need to accumulate things\\\\.\\$" highlight_defences_acquisitio_down_line2 = \\
    /undef highlight_defences_acquisitio_down_catch_all %%; \\
    /acquisitio_down %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_acquisitio_down_catch_all = /undef highlight_defences_acquisitio_down_line2
/def acquisitio_up = /set defence_acquisitio=1
/def acquisitio_down = /set defence_acquisitio=0
/def -Fp285 -aCyellow -mregexp -t'^Pressing your hands together before you, you concentrate on your solar plexus $' highlight_defences_yellow_up_line1 = \\
  /def -mregexp -n1 -p287 -F -aCyellow -t"^chakra\\\\. A golden glow suffuses your solar plexus and your body swells with \\$" highlight_defences_yellow_up_line2 = \\
    /undef highlight_defences_yellow_up_catch_all %%; \\
    /def -mregexp -n1 -p287 -F -aCyellow -t"^power\\\\\\\\.\\\\\\$" highlight_defences_yellow_up_line3 = \\
      /undef highlight_defences_yellow_up_catch_all %%%; \\
      /yellow_up %%; \\
    /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line3 %; \\
  /def -mregexp -n1 -p286 -F -t".*" highlight_defences_yellow_up_catch_all = /undef highlight_defences_yellow_up_line2
/def yellow_up = /set defence_yellow=1
Which is almost identical to the code I posted previously (I found a few bugs with how I understood backslash compression while designing this new script).
I'm not certain if this script takes into consideration all posibilities, however it works for everything I need it for right now. If anyone has any ideas on how to improve this script or a better approach to solving the multiline problem, I'd be very interested in discussing it with you.
Unknown2005-05-11 20:21:18
You are a genius Druth. You saved myself and possibly others from having their brains exploded due to extensive "smacking it against a wall". Your efforts and contributions are greatly appreciated. Now, I just need to get some time and start coding again...
Unknown2005-05-12 15:03:38
Bug discovered in previous version.
The initial version of my multi-line trigger code posted above appeared to work fine at first. However, I was having problems with it matching INVOKE SERPENT, which is 4-lines long. The first three lines matched fine, however the fourth did not.
In testing I used the /TRIGGER command to send text to my system as if I was Lusternia (see /help trigger if you're unfamiliar with it). The serpent triggers worked fine in testing, however, when connected to lusternia and testing it they did not. I spent some time looking over debugging logs and found the error, but it still confuses me a bit. The way in which it failed on line four should've also happened on lines 2 and 3 if it was going to fail. My best guess is that for longer more complicated triggers (> 3 lines long), TF doesn't have enough time to get everything executed in the right order and gets bogged down.
The problem was that I was only using 3 levels of priority. The lowest for the first line, the second for the catch_all triggers, and the highest for lines >1. The new approach uses many more priority levels which takes care of the error. The downside to this is that the number of lines you can match is dependant on the number of priority levels you have available to you. The new approach requires 2 levels of priority for each line you wish to match. So if you want to match a 4-line trigger, you need to have 8 priority levels available.
Technically this shouldn't be a real problem, since the maximum priority level is equal to the largest possible integer, which is huge. The problem will come into play with how you setup your priority levels ahead of time. I had reserved 5-10 priority levels for each of my different types of highlighting. In most cases this would probably be enough, but I went ahead and expanded that to 50 levels available. This means I can match 25 lines and not run into problems with crossing priority levels and interfering with other scripts in my system. I'll probably never want to match more than 5 or 6 lines (10-12 priority levels), but I figured better safe than sorry.
Note:
If you're not using my colored logging script the old code should work fine for you. You just need to make one small change; make the triggers that match the actual lines you supply the macro not fall-thru (remove the -F option from the trigger definition).
Here's the new code:
I'll use serpent as an example. If you load this code into your system...
...this is the (nicely formated so you can read it here) trigger macro that gets generated:
The initial version of my multi-line trigger code posted above appeared to work fine at first. However, I was having problems with it matching INVOKE SERPENT, which is 4-lines long. The first three lines matched fine, however the fourth did not.
In testing I used the /TRIGGER command to send text to my system as if I was Lusternia (see /help trigger if you're unfamiliar with it). The serpent triggers worked fine in testing, however, when connected to lusternia and testing it they did not. I spent some time looking over debugging logs and found the error, but it still confuses me a bit. The way in which it failed on line four should've also happened on lines 2 and 3 if it was going to fail. My best guess is that for longer more complicated triggers (> 3 lines long), TF doesn't have enough time to get everything executed in the right order and gets bogged down.
The problem was that I was only using 3 levels of priority. The lowest for the first line, the second for the catch_all triggers, and the highest for lines >1. The new approach uses many more priority levels which takes care of the error. The downside to this is that the number of lines you can match is dependant on the number of priority levels you have available to you. The new approach requires 2 levels of priority for each line you wish to match. So if you want to match a 4-line trigger, you need to have 8 priority levels available.
Technically this shouldn't be a real problem, since the maximum priority level is equal to the largest possible integer, which is huge. The problem will come into play with how you setup your priority levels ahead of time. I had reserved 5-10 priority levels for each of my different types of highlighting. In most cases this would probably be enough, but I went ahead and expanded that to 50 levels available. This means I can match 25 lines and not run into problems with crossing priority levels and interfering with other scripts in my system. I'll probably never want to match more than 5 or 6 lines (10-12 priority levels), but I figured better safe than sorry.
Note:
If you're not using my colored logging script the old code should work fine for you. You just need to make one small change; make the triggers that match the actual lines you supply the macro not fall-thru (remove the -F option from the trigger definition).
Here's the new code:
CODE
;;; generate defence highlighting triggers
;;; syntax: defences_gentrig_hl('','','']])
;;; note: the current priority scheme will only allow up to 25-line triggers for defences (see tfrc.tf).
/def defences_gentrig_hl = \\
  /if (({#} > 2) & (({2} =~ "up") | ({2} =~ "down") | ({2} =~ "none"))) \\
    /let oneslash=\\\\ %; \\
    /let onepercent=%% %; \\
    /let onedollar=$$ %; \\
    /let label=%{1} %; \\
    /let priority=400 %; \\
    /shift %; \\
    /if ({1} =~ "up") \\
      /let color=Cyellow %; \\
    /elseif ({1} =~ "down") \\
      /let color=BCyellow %; \\
    /elseif ({1} =~ "none") \\
      /let color= %; \\
    /endif %; \\
    /shift %; \\
    /let line_number=1 %; \\
    /let line=%{1} %; \\
    /let generated_trig= %; \\
    /test generated_trig:=strcat('/def -mregexp -n0 -p',{priority},' -F -ax',{color},' -t"',{line},'" highlight_',{label},'_line',{line_number},' = ') %; \\
    /shift %; \\
    /while ({#}) \\
      /test ++line_number %; \\
      /test priority += 2 %; \\
      /test line:=replace({oneslash},strrep({oneslash},pow(2,{line_number}-1)),{1}) %; \\
      /if (regmatch('.*\\$$',{line}) > 0) \\
        /test line:=substr({line},0,-1) %; \\
        /test line:=strcat({line},strrep({oneslash},pow(2,{line_number}-1)-1),{onedollar}) %; \\
      /endif %; \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p',{priority},' -F -ax',{color},' -t"',{line},'" highlight_',{label},'_line',{line_number},' = ') %; \\
      /test generated_trig:=strcat({generated_trig},'/undef highlight_',{label},'_catch_all_but_line',{line_number},' ',strrep({onepercent},{line_number}),'; ') %; \\
      /shift %; \\
    /done %; \\
    /test generated_trig:=strcat({generated_trig},'/',{label}) %; \\
    /if ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-1),'; ') %; \\
    /endif %; \\
    /test --priority %; \\
    /while ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p',{priority},' -F -t".*" highlight_',{label},'_catch_all_but_line',{line_number},' = /undef highlight_',{label},'_line',{line_number}) %; \\
      /if ({line_number} > 2) \\
        /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-2),'; ') %; \\
      /endif %; \\
      /test priority -= 2 %; \\
      /test --line_number %; \\
    /done %; \\
    /eval -s0 %{generated_trig} %; \\
  /else \\
    /echol BCcyan 0 <<<< gentrig_defence error: incorrect arguments provided, must be,,]] %; \\
  /endif
;;; syntax: defences_gentrig_hl('
;;; note: the current priority scheme will only allow up to 25-line triggers for defences (see tfrc.tf).
/def defences_gentrig_hl = \\
  /if (({#} > 2) & (({2} =~ "up") | ({2} =~ "down") | ({2} =~ "none"))) \\
    /let oneslash=\\\\ %; \\
    /let onepercent=%% %; \\
    /let onedollar=$$ %; \\
    /let label=%{1} %; \\
    /let priority=400 %; \\
    /shift %; \\
    /if ({1} =~ "up") \\
      /let color=Cyellow %; \\
    /elseif ({1} =~ "down") \\
      /let color=BCyellow %; \\
    /elseif ({1} =~ "none") \\
      /let color= %; \\
    /endif %; \\
    /shift %; \\
    /let line_number=1 %; \\
    /let line=%{1} %; \\
    /let generated_trig= %; \\
    /test generated_trig:=strcat('/def -mregexp -n0 -p',{priority},' -F -ax',{color},' -t"',{line},'" highlight_',{label},'_line',{line_number},' = ') %; \\
    /shift %; \\
    /while ({#}) \\
      /test ++line_number %; \\
      /test priority += 2 %; \\
      /test line:=replace({oneslash},strrep({oneslash},pow(2,{line_number}-1)),{1}) %; \\
      /if (regmatch('.*\\$$',{line}) > 0) \\
        /test line:=substr({line},0,-1) %; \\
        /test line:=strcat({line},strrep({oneslash},pow(2,{line_number}-1)-1),{onedollar}) %; \\
      /endif %; \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p',{priority},' -F -ax',{color},' -t"',{line},'" highlight_',{label},'_line',{line_number},' = ') %; \\
      /test generated_trig:=strcat({generated_trig},'/undef highlight_',{label},'_catch_all_but_line',{line_number},' ',strrep({onepercent},{line_number}),'; ') %; \\
      /shift %; \\
    /done %; \\
    /test generated_trig:=strcat({generated_trig},'/',{label}) %; \\
    /if ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-1),'; ') %; \\
    /endif %; \\
    /test --priority %; \\
    /while ({line_number} > 1) \\
      /test generated_trig:=strcat({generated_trig},'/def -mregexp -n1 -p',{priority},' -F -t".*" highlight_',{label},'_catch_all_but_line',{line_number},' = /undef highlight_',{label},'_line',{line_number}) %; \\
      /if ({line_number} > 2) \\
        /test generated_trig:=strcat({generated_trig},' ',strrep({onepercent},{line_number}-2),'; ') %; \\
      /endif %; \\
      /test priority -= 2 %; \\
      /test --line_number %; \\
    /done %; \\
    /eval -s0 %{generated_trig} %; \\
  /else \\
    /echol BCcyan 0 <<<< gentrig_defence error: incorrect arguments provided, must be
  /endif
I'll use serpent as an example. If you load this code into your system...
CODE
;;; serpent
;;; up
/test defences_gentrig_hl('defences_serpent_up','up',\\
    '^Pressing your hands together before you, you concentrate on all your chakras $',\\
    '^together\\. A serpent of rainbow energy surges up from the root of your spine and$',\\
    '^travels to the top of your head, bursting forth from your crown chakra and $',\\
    '^surrounding you with an aura of prismatic energy\\.$')
;;; up
/test defences_gentrig_hl('defences_serpent_up','up',\\
    '^Pressing your hands together before you, you concentrate on all your chakras $',\\
    '^together\\. A serpent of rainbow energy surges up from the root of your spine and$',\\
    '^travels to the top of your head, bursting forth from your crown chakra and $',\\
    '^surrounding you with an aura of prismatic energy\\.$')
...this is the (nicely formated so you can read it here) trigger macro that gets generated:
CODE
/def -Fp400 -axCyellow -mregexp -t'^Pressing your hands together before you, you concentrate on all your chakras $' highlight_defences_serpent_up_line1 = \\
  /def -mregexp -n1 -p402 -F -axCyellow -t"^together\\\\. A serpent of rainbow energy surges up from the root of your spine and\\$" highlight_defences_serpent_up_line2 = \\
    /undef highlight_defences_serpent_up_catch_all_but_line2 %%; \\
    /def -mregexp -n1 -p404 -F -axCyellow -t"^travels to the top of your head, bursting forth from your crown chakra and \\\\\\$" highlight_defences_serpent_up_line3 = \\
      /undef highlight_defences_serpent_up_catch_all_but_line3 %%%; \\
      /def -mregexp -n1 -p406 -F -axCyellow -t"^surrounding you with an aura of prismatic energy\\\\\\\\\\\\\\\\.\\\\\\\\\\\\\\$" highlight_defences_serpent_up_line4 = \\
        /undef highlight_defences_serpent_up_catch_all_but_line4 %%%%; \\
        /defences_serpent_up %%%; \\
      /def -mregexp -n1 -p405 -F -t".*" highlight_defences_serpent_up_catch_all_but_line4 = /undef highlight_defences_serpent_up_line4 %%; \\
    /def -mregexp -n1 -p403 -F -t".*" highlight_defences_serpent_up_catch_all_but_line3 = /undef highlight_defences_serpent_up_line3 %; \\
  /def -mregexp -n1 -p401 -F -t".*" highlight_defences_serpent_up_catch_all_but_line2 = /undef highlight_defences_serpent_up_line2
  /def -mregexp -n1 -p402 -F -axCyellow -t"^together\\\\. A serpent of rainbow energy surges up from the root of your spine and\\$" highlight_defences_serpent_up_line2 = \\
    /undef highlight_defences_serpent_up_catch_all_but_line2 %%; \\
    /def -mregexp -n1 -p404 -F -axCyellow -t"^travels to the top of your head, bursting forth from your crown chakra and \\\\\\$" highlight_defences_serpent_up_line3 = \\
      /undef highlight_defences_serpent_up_catch_all_but_line3 %%%; \\
      /def -mregexp -n1 -p406 -F -axCyellow -t"^surrounding you with an aura of prismatic energy\\\\\\\\\\\\\\\\.\\\\\\\\\\\\\\$" highlight_defences_serpent_up_line4 = \\
        /undef highlight_defences_serpent_up_catch_all_but_line4 %%%%; \\
        /defences_serpent_up %%%; \\
      /def -mregexp -n1 -p405 -F -t".*" highlight_defences_serpent_up_catch_all_but_line4 = /undef highlight_defences_serpent_up_line4 %%; \\
    /def -mregexp -n1 -p403 -F -t".*" highlight_defences_serpent_up_catch_all_but_line3 = /undef highlight_defences_serpent_up_line3 %; \\
  /def -mregexp -n1 -p401 -F -t".*" highlight_defences_serpent_up_catch_all_but_line2 = /undef highlight_defences_serpent_up_line2