I need some guidance because while I thought I knew how to pull this, I don't and my research, in finding the correct multiline technique, has failed me.
Using regex, I'm trying to pull all the sentences with the word "generate". My regex, using regex.com works fine.
Here is the text and the matches (in bold), via regexr.com, that I'm aiming for is:
When we generate macros, we are creating automation tasks. AI may build workflows in future iterations. Maybe we can generate a robotic automator. The AI will also train and memorize the grammar structure I have created for them, and even continue generating more correlated grammar structures that I may not have explored yet. The way the generate works is quite ridiculous. Once created, everything works fine. It may be nice to judge but to generate is insane.
The output I'm aiming for is the following (can be in a window or a variable):
When we generate macros, we are creating automation tasks. Maybe we can generate a robotic automator. The way the generate works is quite ridiculous. It may be nice to judge but to generate is insane.
Can someone assist my failing? Here is the janky macro that I gave up on.
Have another go using the "For Each" action that uses your regex to extract the matching substrings to a Collection and then glues them back together to generate your output.
Wizard of @Nige_S , I can certainly do it the way you discussed. Thank you. It definitely works without any issues. Initially, I thought the solution would have more to do with using the expression "(?m) " in some way, perhaps as part of a broader pattern or context.
In addition, after cleaning up the lines, I also used a shell action with sed.
sed -n '/generate/p'
For those who encounter this issue, here is the macro with two possible solutions.:
It really comes down to how you define a "sentence" -- and remember that just because you can do everything in one shot with a complicated regex, there's no shame in using multiple simple KM actions instead!
For example, you could say that sentences are "the bits of text separated by a period and a space". Or multiple spaces, for the philistines who have never read The Mac is not a Typewriter
So you could "For Each" every sentence, then check if each contains "generate":
Or you might treat a sentence as "the text from immediately after a period (or the start of the string), up to and including the next (or the end of the string)". That makes it easy to include "and contains the word [Gg]enerate" in your pattern:
All these methods will include sentences that start with "Generate" -- you may or may not want that!
So many ways to do this, so little time to explore them all. As always, go with what makes sense to you and -- importantly -- what will still make sense in a month's time when you go to tweak the macro.
I knew you were lurking due to your LOVE of Regular Expressions! Thank you for providing another JSA option. I appreciate it. I'll definitely store this code. At with least this JSA code, I can comprehend what is happening.
As you teach us/me these JXA options, please show how to use a KM Variable within your code.
I see this code but my attempts fail as I don't know where exactly to put it:
var kme = Application("Keyboard Maestro Engine");
var value = kme.getvariable("VariableName");
Using the same text in your local_Source variable. Say you have a defined variable called "Local_Word" and Set Variable to text "Local_Word" is set to "grammar".
Read kmvar. as "get the value of the Keyboard Maestro variable", and whatever follows is the name of the variable -- local_Source in the original. So for your new macro you'd use kmvar.Local_Word instead.
"Get the value of the Keyboard Maestro variable named Local_Word."
I really appreciate the fabulous lessons that you, The Wizard (@Nige_S) and @_jims have provided! They have been incredibly insightful and informative. I will certainly make it a point to inquire more about JXA and its various functionalities. I plan to thoroughly review this material and keep the code for any upcoming macros that can utilize these actions.
Thank you so much for the time and effort in sharing this valuable information with me. It has truly been a great help!
I thought that kmvar. was analogous to the AS getvariable, i.e. you were calling for individual variables as and when you wanted them. But, if I'm reading it right (JS n00b alert!), your code says that all (or all selected) variables are passed in the object kmvar when the script instantiates, kmvar being a dictionary of varName:varValue pairs.
So it's actually the equivalent of environment variables in the shell script action. Which would make it even more sensible to only include the KM variables you want to use in the script.
Whereas (stretching even further out of my comfort zone!) the form
var kme = Application("Keyboard Maestro Engine");
var someVarNameStr = kme.getvariable("KMVarNameToGet") || 'Default Value if NOT Found';
which is populated, at initialisation, only as specified in the menu behind the small chevron to the left of the JS script text field.
Experiment will reveal, with the help of JSON.stringify, as above, that if you just check Include (All|No) Variables, that choice translates either to a super-populated, or wholly depopulated, kmvar object at the start, with no further changes.
And, of course:
no user-changes to that object are propagated back to Keyboard Maestro's own variable name-space, and
no KM variable name-space changes during the JXA action run cause any update of the kmvar object within the action's code evaluation space.
It's initialised, to your specification, at the start, and that's it.
More efficient, and more secure, than the pre-modern pattern.
(It's now a restricted binding in a local and temporary name-space, rather than a binding of all variable values in a global and persistent one)
And, of course, as you suggest, the Execute Shell Script action also has a small chevron menu in which you can limit which Keyboard Maestro values are bound to $KMVAR_ prefixed shell names.