Books app: system clipboard changes - infinite loop

Hi,

I was a bit annoyed that whenever I copy a text from a book it adds some extra texts to it.

For example, when I copy the "That’s your engineering vision." text, the following is put into the clipboard:

“That’s your engineering vision.”

Excerpt From
Staff Engineer: Leadership beyond the management track
Will Larson
This material may be protected by copyright.

I tried the following macro, but it is triggered infinitely until I am in the Books app.

Can you please help me to avoid this behavior? (I tried to use if-then-else, but it didn't work.)

Thank you!

When I try to copy from the Books app, the Copy command is disabled. So I can't copy anything. Maybe some books "enable" copying. If you tell me which book you are trying to copy from, maybe I can download the book and try it myself.

Your approach seems to be decent, but I can't test your approach since I don't have your book, and each book may have its own unique copy function.

If the copyright notice that you want to delete is the last line or two of the clipboard, that's really easy to fix. I think all you have to do is tweak your Search and Replace action. But I can't show you how to fix it because I don't have the same book that you have.

You can download any ePub and import it into Books via File → Import. I just did that with this one, and it worked. My clipboard looks exactly as shown above.

I don't have time to dig into the macro, though.

-rob.

I don't like the use of the "when the clipboard changes" trigger there... Since you are using the macro within a macro group that is active only when "Books" is the frontmost application, I wonder if you might like to trigger your macro using ⌘-C. That would surely be the most intuitive way, and it would not interfere with the standard use of that hotkey in other applications. Add a copy action to the start of your macro, of course.

Usually easiest to split a text and take the first part:

Pruned Excerpt From etc.kmmacros (2.7 KB)

Your macro triggers when the clipboard changes, but then it makes a mistake and actually changes the clipboard. Do you see the problem with doing that? That is, your macro will trigger itself and that gives you an infinite loop. That's not good!

There's probably a simple way to solve that by having your macro disable the group that it's in when it starts, then re-enables the group when it ends. I might fix that problem in a few minutes, but the first problem is that you need a way to remove the copyright text, which can be solved in different ways, but I would probably do it this way: (this will remove lines that contain the following phrase)

image

In a few more minutes I'll try to solve the infinite loop problem, and I may update this post at that time. Ok, here's what a working macro looks like:

You will have to place your macro into a group, which in my case is called "Test v3" and then this macro should work. That is, there should be no infinite loop.

1 Like

As others have said, you're using a clipboard change trigger and then in the macro you change the clipboard -- which triggers the macro again, and then again, and then again...

Another vote for using a hot key trigger instead, but if you want to use a clipboard trigger (perhaps so you can right-click and Copy) then the easiest way to prevent an infinite loop is to use an insta-quit semaphore lock and add a tiny delay at the end of your macro:

Clipboard Remove Copyright.kmmacros (2.7 KB)

The regex sort of matches what you've shown but is more forgiving of the copyright notice format. You may need to tweak it, for example if there's a blank line and linefeed after "...copyright."

You don't need to put it in a Group that is active only when Books is frontmost, but it's probably a good idea!

1 Like

Very smart! And creative! But I still prefer my method which isn't dependent on timing.

Thank you very much for all the help.

The reason for the infinite loop was clear: I wanted to fix this with the if-else-then, but I could not make it work. I also tried using semaphore. It somewhat worked, as the script was called only a few times and then stopped. So, practically, it did the job; I just didn't like that solution. I will try the deactivation trick.

I also tried the Cmd-C trigger; the issue was that, for some reason, the selected text was not on the clipboard but the previous one. (I tried to add some pause, but it still didn't work.)

1 Like

Are you saying that the current system clipboard held a different, newer, item, immediately after you had copied the text using the copy action? If so, that sounds worth debugging no matter which approach you eventually stick with. (Could it be that another macro or application is unexpectedly copying constantly, or is being simultaneously triggered?).

Not newer, but the previous one.

This was a very nice co-creation. It turned out, that even with activation deactivation I needed to add a little pause to avoid the macro being called infinitely. This became the final working macro:

Thank you for all the help.

1 Like

You don't need to use a variable -- you can do the replacement directly on the System Clipboard. Doing it directly can help in retaining text formatting, using a variable like you have will result in plain text -- either method can be "correct" depending on what you want to achieve.

2 Likes

The only reason an explicit pause is required is because otherwise the clipboard change is the final action -- add almost any other (sensible, by context) action after that and the pause is unnecessary.

And the obvious addition is activation of the target app, ready for pasting:

And, for OP at least, even your method is timing dependent -- without a pause, the Macro Group is being reactivated before the Engine has noticed/processed the clipboard change (IIRC from other discussions there's no "clipboard changed" event, the Engine has to continually poll for changes).

1 Like

Thank you very much for both of your comments. I really appreciate your focus on reducing waste in such a solution. (A value I appreciate as well.)

Amazing. As I always say, I learn something from you every day.