Reusing the same filter for multiple variables

oh I seeeee, so it's it's to hand the value/calculation back to the thing that called it.

(btw I have searched YouTube for video tutorials on subroutines but no-one has covered it yet. I also sub to ScreenCastsOnline and they haven't done subroutines either.) (I am very much an audiovisual leaner)

local_Result was there from ComplexPoints' example.
I don't actually want to use that variable. I would ideally like the result be saved to the original variable.

(to recap: I am passing a string through a chain of filters, one by one. I don't want to create a new variable at any time.)

So, imagine this is Macro2 (to emojify instance_ShortProductTitle)

In the above screenshots (Macro2), the variable shown is instance_ShortProductTitle. It will be the same variable throughout the entire "chain".

Making Macro3 (to emojify the brand name - instance_BrandName)

Right now , I call Macro2 from Macro1. But in order to do it for more variables, I must duplicate Macro2 to make Macro3 ... and then laboriously go down and change every single action to the next Variable (e.g. instance_BrandName)

This is inefficient because if I tweak some of the filters in Macro2, I must then also make the exact same edits in Macro 3

Macro1 is the Main Macro (the others are just called from this one)

(BTW, if it's not clear Macro1 is the main macro. It is the one that will call Macro2, Macro3, Macro 4 etc)

Possible to do all this using subroutines?

i am trying to do this with my limited understanding.
This would stop me from having to make:

  • Macro 4 (emojify the next variable)
  • Macro 5 (emojify the varaible after that)
  • etc.

Each would be identical apart from the variable being filtered.

Building on what I wrote in my last reply, you should, in itself, be able to do what you ask here, if you:

  1. In the subroutine end set the Return Result Actions text field to %Variable%instance_Title% (to return this variables value)
  2. And in the calling/returning end setting the "Saving result to", in the Execute Subroutine Action, to the same %Variable%instance_Title%

I am not by my computer now, and without testing I must admit I am not experienced enough with instance-variables to be sure*, but I think the instance variable should “return” the value from the sub macro, also without the Return Result Action.


However, if I read your macro correctly, it looks to me like nothing of this would work, as you, in your calling macros Execute Subroutine Action, are defining your instance_Title (as well as variables instance_Brand and instance_Variant) to be overwritten by the empty value from the local_Source variable. Removing %Variable%local_Source% from these three text fields seems like a good thing to do, as you are not defining that variable anywhere. If you instead add %Variable%instance_Title% to the text field labeled “_Title” you would send the value of the instance_Title through to the Subroutine. (But as written above, if I understand instance-variables correctly, I think sending this value to the Subroutine was already done by defining the variable with the instance-prefix, making it shared with any subroutine within the same executing instance).


*not really as experienced with Subroutines as I’d like either, so someone must correct me if they spot anything wrong or lacking in my understanding/explanation, but I hope/believe what I’ve write above to be true

For context, the instance_Title is scraped from an open Amazon Item page somewhere (using JavaScript in front browser window action)

I want to be able to pass this string - or any string - typically a sentence long, but could be just a word, or a few words, through this chain of search-and-replace filters.

A different Amazon page could be loaded a few seconds later. So it needs to happen fast and smoothly.

Suppose instance_Title was this product name:

Light Bulb for Women

As it is passes down the 'chain' it is convereted to

Light 💡for Women

and then

Light 💡 ♀

This is due to the find-and-replace filters (using RegEx) that I've shown.

I don't want to introduce any new variable names if I can just save to source

There are two different approaches here:

  • Constant names, the values of which don’t change
  • Mutable names, which have one value at one stage, and then another later on.

Debugging typically involves tracking down a confusion about what the value of a mutable name really is at a given point.

Avoiding mutability, and using constants wherever possible, turns out, perhaps unexpectedly, to be a very good way of reducing run-time complexity, and keeping well clear of the debug tar-pits.

for future readers: Subroutine to Get The Last Line Containing Specific Text helped me get my head around subroutines a bit more.

Can someone please tell me how I can convert my macro here into a subroutine:

:lipstick::lipstick::lipstick::lipstick:.kmmacros|attachment (76.8 KB)

I'm guessing it's not structured the correct way to be a subroutine, i.e. it's not possible.. reasons:

  • i actually want my variable itself to be a variable
  • the result i am returning needs to be saved the source (i.e. Save result to would be the same as input)

What you have there is:

  1. a list of pairs [(fromPattern, toPattern)]
  2. one operation which is applied to each pair in succession (search replace in a given text)

A simpler architecture for it might be:

  • A single text of several lines in which each line contains such a pair (separated consistently, for example by a tab character)
  • a For Each action over a collection consisting of each line in the list of substitution pairs.

Your subroutine could receive two parameters:

  1. Pairs: A Keyboard Maestro %Variable% reference to a text containing one line for each substitution pair.
  2. Source: A Keyboard Maestro %Variable% reference to the source text.

and it could return an updated (search-replaced) copy of the source text.


To extract the two distinct parts of each one-line (fromPattern, toPattern) pair, you could use a Keyboard Maestro Variable Array, with a specified delimiter character, and a one-based index.

1 Like

Alternatively, of course, if you only ever use one unchanging substitution sheet, you could:

  1. define the sheet inside your subroutine, and
  2. give the subroutine only one parameter - the reference to the source text.
1 Like