Can a CSV or Similar List Be Used for Multiple Typed String Triggers

I want to create a macro that will allow typing a users first and last initial followed by @ and then automatically type their email address. This is easy enough to do on an individual basis, however we have anywhere from 20-40 people at the workplace, and some may come and go. Rather than adding a new macro for each individual person, is it possible to either maintain a CSV, or a list within keyboard maestro that would be able to create typed string triggers for each person?

Hey Jimmy,

See this thread on regular-expression-triggers.

You have to know a bit of regex to handle breaking up the trigger string and turning it into a query.

###Proof-of-concept:

Lookup Email Address.kmmacros (2.8 KB)

I've done this with AppleScript, because I could do it in 5 minutes or less.

If you want to use this macro you need to install the Satimage.osax AppleScript Extension.

It can all be done with Keyboard Maestro though.

The data file path is currently:   ~/Desktop/Email_Address_List.txt

But you can change that to anything you want.

The data file format is:

Christopher Stone		listmeister@thestoneforge.com
Larry Niven			ln@protector.net
Robert Heinlein			tanstaafl@pieinthesky.com

* Tabs are the required separator for names and email addresses.

NOTE: This macro is a simple proof-of-concept — it lacks sophistication and has only the most rudimentary error-checking.

You could really go crazy and add modifiers to lookup first-name and/or last-name or initials or part of the email address or a full-fledged regular expression.

-Chris

2 Likes

Great, thanks for that info!

Are you saying you could do this without AppleScript? If so, I would love to hear how. I know regular expressions, but how would you handle the lookup? A “for each line…” loop?

Challenge accepted.

The lookup can be done with a single regular expression, like this:

(?mi:(?s:.*)^l.* n.*\t(.*)(?s:.*))

As with most regular expressions, it looks complicated, but it breaks down into comprehensible pieces.

  • (?mi: means match with ^ and $ matching within Multiple lines, and case Insensitive.
  • (?s:.*) means match any sequence of zero or more any characters, treating it as a Single line, so . matches line ending characters.
  • ^ start of line
  • l - a letter, l in this case
  • .* - any sequence of zero or more characters
  • n - space, n.
  • .* - any sequence of zero or more characters
  • \t - tab
  • (.*) - capture any sequence of zero or more characters
  • (?s:.*) as above.

So here is a working example.

Lookup Name.kmmacros (5.2 KB)

1 Like

Hey Jack,

Peter beat me to the punch.   :sunglasses:

I see you can use a variable for a regular expression pattern, and that's outstanding. (I made the mistake of believing the capture list display and not testing.)

So I took a little different route and read the email address file directly with Perl.

I prefer to keep this sort of lookup table as a text file on disk, because it's generally easier to maintain (especially since BBEdit runs 24/7 on my system).

-Chris

Lookup Email Address.kmmacros (3.9 KB)

1 Like

The lookup can be done with a single regular expression, like this:

@peternlewis Interesting! So you set the regex to eat everything except the search hit, right?—so the matched text is all that remains?

So I took a little different route and read the email address file directly with Perl.

@ccstone Thank you! Yes, I agree, best to keep the file on disk. I like Peter’s method of writing the file to a variable to slice and dice it.

I don’t know any Perl, but I think I get the basic concept here—searching for a match and then printing it—is that right?

Correct, in my version, it matches the entire contents, and replaces it with just the match.

For this sort of thing, its cleaner if you can use the Search Variable action, since it can slice out just the match, but you can’t have the capture brackets () in the variable used in the search for that case. But an alternative would be something like:

Search Variable Trigger for (.)(.). saving in variables First and Second.
Search Variable Mapping for (?mi:^%VariableFirst%.* %Variable%Second%.\t(.)) saving in variable Result.

Its probably a slightly cleaner version than what I did originally (it was a bit late when I wrote it!).

Hey Jack,

Right. Perl reads the file directly line-by-line and searches for a match. If it finds the match the relevant portion of it is printed to standard-out in the terminal session.

Now I know the Search Variable Action can handle a variable for the seach-string I’ll rewrite the macro to be more efficient.

-Chris

Here's the slightly simplified version.

I prefer to read the file on disk directly as part of the search, because it saves other effort and cleanup.

Keyboard Maestro's variables use memory, so if you use a variable you really should zero it out at the end of the macro. (A few lines isn't much, but a few thousand starts adding up — and the more variables you have the more memory KM eats.)

If you use a variable you still need to read the file every time OR you need to check to see if the file has been modified and only read it again in that event. It's simpler to just read it every time.

Of course to make the macro a little more bomb-proof you need to check to see if the email-address-file actually exists and throw an error if it doesn't.

-Chris


Lookup Email Address v0.02.kmmacros (3.5 KB)

1 Like

This is really useful, thankyou.

How would it be possible to convert each email into a collection so that it could be looped over in a for each? I would like to use the for batching over a bunch of customer orders I have in a csv.

Hey Andrew,

You have not provided nearly enough information for us to help you.

What does your data look like?

What exactly do you want to do with it?

-Chris

I figured it out, i just had a csv with only the emails in it and set a loop to go over the lines.