Paste and highlight

Title says it all. I’m looking to paste and then highlight the exact string I just pasted.

If by “highlight” you mean “select”, you could do this:

  1. In KM, count the number of words in the text you plan to paste
  2. Do the paste
  3. Repeat this keystroke for the number of words: OPTION + SHIFT + LEFTARROW

Let me elaborate. What I’m hoping for is to have a macro that will select whatever word or words I’m pasting.

So I need some sort of KM logic that will count the number of words in my clipboard for me and then execute that many OPTION + SHIFT + LEFT ARROW keystrokes.

In an Execute action, using JavaScript with 'ignore result', a rough start could be sketched out with something like:

Paste words and select.kmmacros (18.4 KB)

var	se = Application("System Events"),
	a = Application.currentApplication(),
	i = (a.includeStandardAdditions = a).theClipboard().split(/\w+/).length;

se.keystroke("V", {
	using: "command down"
});

while (1 < i--)
	se.keyCode(123, {
		using: ["option down", "shift down"]
	});

No two apps will agree on exactly what constitutes a word, so despite being slower, characters is probably better. Something like this:

  • Set Variable ‘Contents’ to Text ‘This is a test.’
  • Insert Text ‘%Variable%Contents%’ by Pasting
  • Filter Variable ‘Contents’ with Character Count
  • Repeat Actions Contents Times
    • Type the ⇧Left Arrow Keystroke

1 Like

Peter, thanks for your example. I have been struggling with how to use the "Word Count" (or "Character Count") option on the Filter Variable action.
Is the variable replaced with the count? Couldn't find this anywhere in the docs.

Now I'm trying to use the "Repeat Actions" action, and I don't see how to use a variable for the number of times. How do I do this?

Yes, like all filters, the source is replaced with the new value. So “Hello” is replaced with “5”.

Also in the Repeat count field, like all numeric fields, you can put a calculation. As soon as you start typing anything other than a number the field will expand to allow more room for the calculation.

OK, thanks.

It would be really nice if we can set the results of the Filter action to a new variable.

Heh. You can:

  • Set Variable "New Variable" to text "%Variable%Old Variable%
  • Filter Variable "New Variable"

But I'll note it down for an addition to the Filter actions. It's easier to do with 7.0's new Gear action menu where I can hide away extraneous options like this.

Thanks Peter.

FYI, it’s a bit counterintuitive for a variable with text contents to be changed to a numeric results (like count). I completely get Filter actions that filters out some text, but counts are not really filters, as I normally think of them. :wink:

Just a thought, a feature that provides properties of a text variable/clipboard would be more intuitive. For example:
Set variable NumWords to MyText.WordCount

Continuing the discussion from Paste and highlight:

Thanks Peter.

I'm having some trouble getting this to work.

It looks fine - did you try it?

The “Contents” is in red simply because it currently does not have a numeric value.

Click Try on the first action to set the variable, and then Try on the third action to filter it, and then the Contents value will be valid and will stop being angry in the fourth action.

In your last Action, you need to add the action to type the keystroke I suggested above in my step #3.

I might also suggest that you will progress faster, and learn more, with some trial-and-error using KM macros, and make better use of Google. When you reach an impasse in programming (and KM is one form of programming) try different things until you succeed, or reach a real roadblock. Then reach out to others for help. Good luck!

2 Likes

Ah that did it. I was assuming it wasn’t working since the pictures didn’t look exactly the same haha.

It’s late here, so I’ll post the completed macro with context tomorrow. Thanks for the help as usual.

1 Like

( Quick thought – if the goal of the post-paste selection is to speed up applying a rich-text format afterwards, you may be able to have that done in the clipboard automatically, before the paste occurs )

Big thanks to @peternlewis and @JMichaelTX for their help on this. Here is the completed macro.
Link Text Plus.kmmacros (26.4 KB)

Why I Needed It

In Evernote, I'm frequently linking text to websites. I wanted a way of quickly copying a quote or passage from a webpage I'm reading, paste it to a note, and have that passage link back to the webpage.

The If Then Else is in there to account for if I happened to copy the page URL second.

Looks good Tom.

One question. In the 3rd Action from the bottom you have:

Paste from Named Clipboard 'URL clip'

I don't see where you set the "URL clip" clipboard.
How is that done?

Great idea! Do you by any chance have an AppleScript (or other) function to create a rich-text hyperlink suitable for pasting into any rich text document?

Select a para or two on a web page, and try this. It puts RTF, including a hyperlink to the source, into the clipboard.

A rough indicative draft. I leave two things as an exercise for the reader : -)

  1. Add a bit of CSS to get the font and style you want
  2. Encode any special characters in the copied text as HTML entities

( I know you're still holding off on Yosemite, so I've sketched it in Applescript. JavaScript is probably the more obvious tool to reach for with this kind of thing.

Copy from web as linked RTF.kmmacros (26.4 KB)

on run
	tell application "Keyboard Maestro Engine"
		set lstNameTab to {}
		set lstParas to {}
		set strLinkHTML to ""
		set strParasHTML to ""
		
		-- LIST OF COPIED PARAGRAPHS
		set lstParas to paragraphs of (my EscapeChars(the clipboard as Unicode text))
		
		-- NAME AND URL OF WEB PAGE
		set lstVars to (variables where name = "nameAndURL") as list
		if length of lstVars > 0 then
			set strNameTabUrl to value of item 1 of lstVars
			set {dlm, my text item delimiters} to {my text item delimiters, tab}
			set lstNameTab to text items of strNameTabUrl
			set my text item delimiters to dlm
		end if
		
		-- NAME AND URL AS HTML LINK
		if length of lstNameTab > 1 then
			set strLinkHTML to "<a href=\"" & item 2 of lstNameTab & "\">" & item 1 of lstNameTab & "</a>"
		end if
		
		-- APPENDED TO PARAS AS 'SOURCE:'
		set end of lstParas to "Source: " & strLinkHTML
		
		-- ALL WRAPPED IN <P> TAGS
		set {dlm, my text item delimiters} to {my text item delimiters, "</p><p>"}
		set strHTML to "<p>" & (lstParas as text) & "</p>"
		set my text item delimiters to dlm
		
		-- REWRITTEN AS RTF AND COPIED TO THE CLIPBOARD
		set strCMD to "echo " & quoted form of strHTML & " | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf"
		do shell script strCMD
	end tell
end run

on EscapeChars(str)
	-- QUOTE < > & ETC
	set strEncoded to (do shell script "python -c 'import sys; from xml.sax.saxutils import quoteattr; print quoteattr(sys.argv[1])' " & ¬
		quoted form of str)
	
	-- ENCODE DIACRITICS AND SPECIAL CHARACTERS
	set lstChars to characters of strEncoded
	repeat with i from 1 to length of lstChars
		set lngCode to id of item i of lstChars
		if lngCode > 127 then set item i of lstChars to ("&#" & lngCode as string) & ";"
	end repeat
	lstChars as Unicode text
end EscapeChars
1 Like

PS I notice this lurking in my library. It looks slow but it may give you a start with encoding special characters for the HTML stage of the script:

on EscapeChars(str)
	-- QUOTE < > & ETC
	set strEncoded to (do shell script "python -c 'import sys; from xml.sax.saxutils import quoteattr; print quoteattr(sys.argv[1])' " & ¬
		quoted form of str)
	
	-- ENCODE DIACRITICS AND SPECIAL CHARACTERS
	set lstChars to characters of strEncoded
	repeat with i from 1 to length of lstChars
		set lngCode to id of item i of lstChars
		if lngCode > 127 then set item i of lstChars to ("&#" & lngCode as string) & ";"
	end repeat
	lstChars as Unicode text
end EscapeChars
1 Like