Separately, if you ever do need to use subroutines, here's an example, of:
- a subroutine, and
- a macro which uses that subroutine.
Subroutine example Macros.kmmacros (4,9 Ko)
Separately, if you ever do need to use subroutines, here's an example, of:
Subroutine example Macros.kmmacros (4,9 Ko)
Not sure that I have a picture of what you are trying to do there.
The Decode HTML Entities
action will resolve all entities in a document.
How do the multiple variables arise ?
What's in them ?
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?
Your filter suggestion is better (it saves me even more steps)
But now I have a situation where I want to feed it like 20 or more variables and
ooh thanks for this.
I have downloaded it.
However it gives me a headache trying to understand it. I wish there was a video tutorial.
What is return text ?
Is it like display text?
can do i like this:
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:
In another filter example I am changing some words for emojis like this:
It's just a whimsical thing - not important. But there are about 20 or 30 replacements.
That will filter the variable instance_ShortProductTitle
But next, I want to also do it for several other variables. This will take lots of copy and pasting. How would I do this using subroutines please?
oh really I can use that instead
I didn't know that it would make things better.
I will use Document Query Selector everywhere instead. I had no idea it made a difference! thanks!!
update on this -
the special filter is no longer required since using the Query Selector method to scrape the date - I can just do a standard filter
Just looking at the Return from subroutine
step for the first time.
What if I want it to always return the value to the source?
0 Subroutine example Macros.kmmacros (5.5 KB)
with
You were able to put a space between local_Source
and String
? Does String
need to be there? Is it creating a new variable?
From the Wiki, Manual, Variable Naming Rules:
- 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
woah variables can have spaces
That breaks my brain for some reason
Thank you, I did not know that!
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.)
instance_ShortProductTitle
)In the above screenshots (Macro2), the variable shown is instance_ShortProductTitle
. It will be the same variable throughout the entire "chain".
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
(BTW, if it's not clear Macro1 is the main macro. It is the one that will call Macro2, Macro3, Macro 4 etc)
i am trying to do this with my limited understanding.
This would stop me from having to make:
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:
%Variable%instance_Title%
(to return this variables value)%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:
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:
.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:
Save result to
would be the same as input
)What you have there is:
[(fromPattern, toPattern)]
A simpler architecture for it might be:
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.
Alternatively, of course, if you only ever use one unchanging substitution sheet, you could: