I scrape various elements from a large HTML document
I then filter each variable (to decode HTML entities)
Are you suggesting that, rather, I should decode the big HTML document and THEN scrape?
Well stepping back a bit, its easier to extract text from a webpage using things like document.querySelector, which completely avoid all these issues with HTML entity decoding.
There are probably plenty of examples here, but you could start by looking at a contribution like:
Variable names must start with a letter, and then can contain letters, numbers, spaces, or underscores.
local_Source String is a unique variable, different from local_Source
If you add a Return Result Action into a Subroutine it will always return the specified value as a result to the Execute Subroutine Action that called it. In the calling/returning end the value will be stored in the variable you define in the Execute Subroutine Action.
In your example subroutine macro you do not set any value to the local_Result variable, therefore it will return empty.
I am not sure what exactly you’d like to return, but if you where to specify your %Variable%instance_Title% in the Return Result Action, it would return that variables content, saving it in the calling end to the local_Result variable that you’ve specified in the Execute Subroutine Action.
EDIT: The checkbox in the Subroutines header field, the one labeled "Returning a value", needs to be checked for it to be true, that the Return Result always returns, of course
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
Building on what I wrote in my last reply, you should, in itself, be able to do what you ask here, if you:
In the subroutine end set the Return Result Actions text field to %Variable%instance_Title% (to return this variables value)
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
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.
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:
Pairs: A Keyboard Maestro %Variable% reference to a text containing one line for each substitution pair.
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.