Author Topic: {STRINGSEGMENT:} token  (Read 8110 times)

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
{STRINGSEGMENT:} token
« on: January 14, 2017, 04:11:04 PM »
The new "{CMDSEGMENT:}" token in v1.6.1.20 will come in quite handy, perhaps the same functionality for other strings would as well.

I know it could be done using an inline snippet using String.Split(), but a token makes it much more accessible.

An optional parameter to specify the character(s) to split on would make it even more powerful.


I know, I know, give an inch and they'll take a mile ::)


EDIT: A use case that is seemingly becoming more common for a token such as this is the splitting of numeric sequences into digits.

For that purpose, something like the following would be very useful:

"{TXTSEGMENT:}", which retrieves a character, where an input value of "180 360" would have "{TXTSEGMENT:0}" return "1", "{TXTSEGMENT:1}" return "8", and so on.

"{TXTSEGMENT::}", which retrieves part of a string, split by a given separator string, where an input value of "180 360" would have "{TXTSEGMENT:0: }" would return "180", and "{TXTSEGMENT:1}" would return "360".
« Last Edit: April 30, 2020, 01:54:14 PM by Pfeil »

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: {STRINGSEGMENT:} token
« Reply #1 on: January 14, 2017, 06:51:37 PM »
Could I bother you for a quick example?  I'm a little dense tonight o_O

Thinking some BBQ might help.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
Re: {STRINGSEGMENT:} token
« Reply #2 on: January 14, 2017, 09:33:43 PM »
It should probably be "{TXTSEGMENT:}" instead, to match VoiceAttack terminology.

To be honest, personally I'd mostly abuse it to replace long Conditional lookup tables(This example uses three vehicles, in reality it'd be up to 120 in up to 10 different garages):
Where did I park my [Mini Cooper;Chieftain Tank;Robin Reliant]
Code: [Select]
Set Text [Vehicles] to 'Mini Cooper\0\1/Chieftain Tank\1\1/Robin Reliant\1\2'
Set Text [Garages] to '14 Fake Street/438 Fictional Drive'
Set small int (condition) [~Counter] value to 0
Start Loop While : [{TXTSEGMENT:{SMALL:~Counter}}] Does Not Equal ''
    Begin Text Compare : [{TXTSEGMENT:Vehicles:{SMALL:~Counter}:/}] Contains '{CMDSEGMENT:5}'
        Say, 'Your {CMDSEGMENT:5} is parked at {TXTSEGMENT:Garages:"{TXTSEGMENT:"{TXTSEGMENT:Vehicles:{SMALL:~Counter}:/}":1:\}":/} in spot {TXTSEGMENT:"{TXTSEGMENT:Vehicles:{SMALL:~Counter}:/}":2:\}'
        Exit Command
    Else
        Set small int (condition) [~Counter] value as incremented by 1
    End Condition
End Loop
Write '[Red] Error in lookup: Text not found' to log
So I'd say "Where did I park my Chieftain Tank", and VoiceAttack would reply "Your Chieftain Tank is parked at 438 Fictional Drive in spot 1".

I'd also use this output to fetch my car, so I could say "Get me my Mini Cooper", and VoiceAttack would navigate the menus to select the correct garage, followed by the parking spot within said garage, to retrieve the vehicle for me.


Token syntax could be:
Code: [Select]
{TXTSEGMENT:variableSource / value: intVariableIndex / int value: textVariableSplitCharacters / text value

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
Re: {STRINGSEGMENT:} token
« Reply #3 on: February 09, 2017, 05:27:31 PM »
I've gotten around to actually using this token(rather than just testing it with random things), and I can't help but feel the documentation is lacking:

The example given is:
Quote
‘build [1..10][bulldogs;wolves;strikers][please;]’
Which does not make it clear in the least that instead of functioning like String.Split() and splitting by separator(s)(I figured it just separated on "space"), it actually separates dynamic and/or non-dynamic sections.

E.G. applying "{CMDSEGMENT:1}" on the command phrase "Larry, Curly, and [Moe;Sherlock]", will not in fact return "Curly", but rather "Moe", or "Sherlock".

This is also why I put in this feature request, as it seemed logical to me that String.Split() shouldn't be hard to adapt.
Now I understand why my request wasn't clear, as I had completely misunderstood the functionality of the token in the first place.


As an aside, the token had stopped working altogether in v1.6.1.27, and still wouldn't work in v1.6.1.30(reboot included), however that's magically fixed itself after reverting to v1.6.1.20 and a few versions in between.
Computers are wonderful, aren't they.
« Last Edit: February 09, 2017, 05:35:53 PM by Pfeil »

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: {STRINGSEGMENT:} token
« Reply #4 on: February 09, 2017, 07:48:34 PM »
Do you have an example of what's not working?  It seems to work fine for me, even with your three stooges example.

If you just right-click execute from the editor, it will fail 100%.  It relies on you speaking one of the dynamic phrases to know what to retrieve.

As far as a string split, it's still on paper.  I don't have an ETA for it.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
Re: {STRINGSEGMENT:} token
« Reply #5 on: February 09, 2017, 07:51:03 PM »
Do you have an example of what's not working?
It's working fine now. I added the "Computers are wonderful, aren't they." bit because the whole thing was intended to be "said in passing".


My observation, as such, is that the actual functionality of the token would be better explained if the example in the documentation used multiple words per section, to emphasize that it's not getting split word-per-word.

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: {STRINGSEGMENT:} token
« Reply #6 on: February 09, 2017, 08:36:49 PM »
‘build [1..10][bulldogs;wolves;strikers][please;]’

should be

‘build;assemble;create[1..10][bulldogs;wolves;strikers][please;]’  ?

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
Re: {STRINGSEGMENT:} token
« Reply #7 on: February 09, 2017, 09:07:35 PM »
The way it's presented currently implies:
"One two [three;3] four five" will split into "One", "two", "three" or "3", "four", and "five"

What actually happens is that it splits into:
"One two", "three" or "3", and "four five"

If the user is only presented with:
"One [two;2] three" splits into "One", "Two" or "2", and "Three"
Where coincidentally every split is always one word(thus why is referred to "String.Split()"), it may be expected that something like:
"One two three" will split into "One", "two", and "three", even though it won't because there are no dynamic sections within the command name.


To make it as clear as possible, I would include a list of what the example actually splits into.

Something like:
"Select car [1..10] and send it to the[pits;garage;track][please;]"

If now you say "select car 9 and send it to the garage",
"{CMDSEGMENT:0}" will produce "select car"
"{CMDSEGMENT:1}" will produce "9"
"{CMDSEGMENT:2}" will produce "and send it to the"
"{CMDSEGMENT:3}" will produce "garage"
"{CMDSEGMENT:4}" will produce "", as the optional "please" was not spoken
"{CMDSEGMENT:5}" will produce "Not Set", as there are only five possible segments to this command name