Today I realized that you can enable a Share Extension for CleanShot X to pin any image to the screen — not just screenshots that you’ve taken. Then you can right-click or hit ⌘-E to open its excellent image editor to crop, add annotations, backgrounds, and more.
To enable it, go to System Settings → Privacy & Security → Extensions (at the bottom) → Sharing. There, you can enable both the ‘Pin to the Screen’ and ‘Annotate’ extensions from CleanShot, depending on your needs.
For months, I’ve been dragging images into Yoink just to use the ‘Open with…’ menu to get them in CleanShot. Turns out that functionality could have been just a single right-click away. 🤯
Working with basically any image in CleanShot is now so easy! ⌘
CleanShot X continues to impress and has further cemented its place as one of the very first apps I’ll put on a Mac.
Tips
Threads has taken the world by storm and established new playbooks, and although it isn’t my favorite social network, I’m enjoying kicking the tires and having a broader audience to share all my silly thoughts with again. That being said, since I’m still posting to Micro.blog first, I wanted an easy way to copy posts into Threads because it doesn’t support cross-posting from Micro.blog like other social destinations.
Enter Shortcuts: my jackknife of an automation tool. I ended up creating two shortcuts (‘Convert Text and Post to Threads’ and ‘Open Threads App’) that work together to make it as easy as currently possible to get posts into Threads. Seeing as Threads doesn’t have any native Shortcuts actions yet, I had to get a little clever about how to move the data from point A to point B. Spoiler: They use the ‘If’ and ‘Match Text’ actions copiously. Let’s dig in.
Matching and formatting the alt text first
Regular expressions are weird, but so powerful. ⌘
They say accessibility should be built-in right from the start and that’s true for my conversion shortcut, even if it wasn’t true for the Threads app at launch. For, gosh, probably three years now — yeah, ever since I started this blog — I’ve been diligent about adding descriptions for images that I post online. Image descriptions, or alt text, make the internet a better place for everyone. Folks who use screen readers to read the web deserve to know what is being shared in images, even if they can’t see them. Many social networks have a workflow for adding those descriptions — usually by tapping on a photo after it’s been uploaded — but Threads doesn’t support them yet. But since I write almost all of my social posts in Drafts using Markdown, the alt text can be isolated programmatically.
Markdown images are referenced using the syntax ![Alt text.](image-url.jpeg)
. So we use a ‘Match Text’ action that deploys a regular expression to match any text that lives within a set of square brackets ([]
) that is immediately preceded by an exclamation point (!
). I’m no regular expression guru, but ChatGPT is. After some back-and-forth explaining what I needed and then testing, I got this expression: (?<=!\[)(.*?)(?=\])
which gets the text in the brackets, but not the brackets themselves. The ‘Match Text’ action results in a list of matched items, so we’ll use that variable later to format the image descriptions just how we want them.
By having already matched the alt text first, we can manipulate the starting text without worrying about losing track of those descriptions later.
Accommodating for plurals
Four actions to add an “s”. ⌘
Here’s a bit that I’m proud of having figured out. Being a stickler for grammar, I wanted to make sure that if multiple images were shared I’d be able to correctly label them as the plural “image descriptions” as opposed to an “image description”. By counting up the number of matches — after checking if there are any matches to begin with, which is handy to distinguish so later we can control what happens if there were no images at all — we simply add a ‘Text’ action containing the single letter “s” I need to make “description” into its plural and set it as a variable.
It looks funny, but it works! ⌘
Next, we need to format the matched alt text how we want it to appear in the Threads post. Still within the ‘If’ block that controls what happens if more than one description is matched, we use a ‘Repeat with Each’ action to number each description using its repeat index and put it on its own line so that a listener can differentiate between the descriptions when they’re read aloud. Key here is to use an ‘Add to Variable’ action before it repeats so that it makes a list of the descriptions all within one variable. We’ll call the variable “matched-descriptions”.
In the ‘Otherwise’ part of the ‘If’ action, we know that just one description was matched. We get that matching text — no reformating necessary — and it gets added to a variable named the same “matched-descriptions” so that variable can be used either way.
Matched variable names for those matched descriptions. ⌘
Finally, we put it all together in one more ‘Text’ action. “Image Description” gets the ‘plural’ variable tacked on so it’ll get that extra “s” if necessary. The ‘matched-descriptions’ variable containing the numbered descriptions on their own lines gets put below the label.
But what’s all that whitespace for? ⌘
Creating an auto-threaded reply
The really cool bit in this step is how the alt text gets put automatically into its own threaded reply when it’s pasted into Threads. It turns out that you can hit the ‘return’ key three times when composing a thread to create a threaded reply before ever posting the first one. We put those same three line breaks ahead of the “Image Descriptions” label and — voilá! — we’ve easily separated the descriptions from the main post so that (1) they’re less annoying to people who don’t need to see them, and (2) we’re more likely to stick within the 500 character limit for each post.
Threadin’ be easy! ⌘
Here’s that whole flow after matching the alt text from the initial text input until we set it all as a new ‘alt-text’ variable:
Count, If, Repeat, oh my! ⌘
Even though Markdown is made to be human-readable (and I think clarifies what links should refer to when read as plain text), I want to be a good platform citizen of Threads. This means getting rid of the extra square brackets around linked text, and, of course, the text for Markdown-referenced images since they’ll be natively attached in the Threads app. But after all that we’ve done above, this should be a piece of cake!
Massaging out the Markdown is comparatively simple. ⌘
A match and replace-filled piece of cake that is. We go back to our old friend ‘Match Text’ with a new regular expression to match anything that looks like a Markdown reference to an image. This expression \n!\s*(.*)
finds a blank line followed by a new line starting with !
. Since I don’t start sentences with an exclamation point, I can be pretty sure that it’s an image reference. We replace that matched text with nothing, so it’s just deleted from the ‘starting-text’ variable.
Next, we want to get rid of the opening square bracket around linked text, so individual instances of those are likewise replaced with nothing. For the closing square bracket, we actually do replace it with some new text. In this case, we find instances of ](
and replace them with a blank space plus the opening parentheses. That separates the parentheses-enclosed URL from its linked text, which looks a little more natural in Threads.
Note that we’re replacing text in a continuous line of ‘Updated Text’ variables by just passing the result from one to the next.
To set up the actual final bit of text that will be posted to Threads, we use one last ‘Text’ action and call up just two variables: ‘converted-text’ and ‘alt-text’ without a space between them. That ‘alt-text’ variable won’t contain anything if there weren’t images in the input, but it will contain the necessary line breaks if there were, so we just place them right next to each other.
Opening the Threads app
We’ve done all this work, and we still haven’t even gotten to the Threads app yet. Thankfully, getting our newly-formatted text into Threads to post is quite simple.
Trust but verify. ⌘
But before we open the app, let’s make sure everything looks right. By adding a ‘Show Result’ action before copying it to the clipboard, we can ensure that nothing funny happened during the conversion process. For example, if there was body text separating the referenced images, that body text might get lost in the migration.
If it doesn’t look right, you can hit the ‘Cancel’ button when it’s showing the result to stop the shortcut from continuing and overwriting the clipboard.
I like having the option to stop the shortcut if it screws something up. ⌘
If it’s all good, we hit ‘Done’ and the shortcut copies the ‘final-text’ variable to the clipboard and ends with a ‘Run Shortcut’ action to run the ‘Open Threads App’ shortcut. Don’t worry about passing any variables to that ‘Run Shortcut’ action because we’re just going to use the clipboard anyway.
You might be wondering why we don’t just use an ‘Open App’ action on its own here to open the Threads app. This next screenshot should clue you in as to why:
Running shortcuts as functions are the best. ⌘
You see, Threads is an iOS-only app for now. You can, however, install the iOS app on your iPad where it’s pretty good in Stage Manager, and great for browsing alongside a Mac using Universal Control. By using an ‘If’ action to check if the Device Details → OS type is iOS (Shortcuts, thankfully, treats iOS and iPadOS as the same operating system) and only use the ‘Open App’ action in that case, while doing nothing on macOS.
It’s because I like to use Threads on iPad as a companion to my Mac that I use that ‘If’ block. I can run the shortcut on text from my Mac, and it won’t give me an error when the app isn’t installed. Instead, I just pop my cursor over onto the iPad, open Threads, and — thanks to the magic of the Universal Clipboard — paste the converted text into a new post. Or when run from an iPad or iPhone, the Threads app opens automatically, ready to go.
I don’t want to recreate that ‘If’ block every other time I want to programmatically open the Threads app, so splitting it off into its own shortcut makes it useful elsewhere.
And that’s it!
That wasn’t so hard, right? 😝 While employing relatively simple actions, these shortcuts use more advanced techniques to accommodate multiple scenarios, and are good to bear in mind as you build your own more versatile automations.
Get the shortcuts:
Let’s take a look at the whole flow in action:
You can reveal screenshots of both shortcuts from top to bottom below.
Show/hide the shortcuts
Convert Text and Post to Threads
It’s a honker. ⌘
Open Threads App
And a little guy. ⌘
Shortcuts
Tips
A weekly list of interesting things I found on the internet, posted on Sundays. Sometimes themed, often not.
1️⃣ Robb Knight made a neat tool to calculate the total time duration of a podcast across all its episodes, just from the RSS feed. [🔗 Robb Knight // podcast-duration.netlify.app]
2️⃣ Apple’s next update to macOS Ventura will fix a bug affecting the (nearly 14-year-old and discontinued) iPod shuffle. Now that’s what I call long-term software support! [🔗 Joe Rossignol // macrumors.com]
3️⃣ This video where 100 people were asked to scream at the top of their lungs is one of the best things I saw all week. Some people loved doing it, some didn’t. Some could produce a blood-curdling scream, and some were truly terrible at it. It’s an impressive array of humanity in the span of a few minutes. [▶️ Cut // youtube.com] (via kottke.org)
4️⃣ Strong contenders for the title of ‘World’s Best-Designed Emoji’, currently held by Apple, could be coming soon from Microsoft. But I’ve been fooled into thinking they were close before. [🔗 Umar Shakir // theverge.com]
5️⃣ A shockingly poignant reflection of our collective migration from one social media platform to another. [▶️ briefs.video]
6️⃣ Emojipedia.org has undergone a major redesign that knocks it out of the park in being easier to use, better laid out, and more comprehensive. They were already the authority on all things emoji, but that hasn’t had them resting on those laurels. The new design, in honor of their 10th anniversary and World Emoji Day tomorrow, pairs great with my ‘Emoji Meaning’ lookup shortcut. [🔗 Keith Broni // blog.emojipedia.org]
7️⃣ This story about thesis topics and thesis advisors got a laugh out of me. [📄 www3.nd.edu] (Via @pratik)
Take a Chance
Thanks for reading 7 Things. If you enjoyed these links or have something neat to share, please let me know.
7 Things
Deals! Deals! Deals! ⌘
Just a quick note to let you know that, thanks to the folks at Cotton Bureau, I’m now able to offer you $5 off any item in my store — provided it’s your first order. And you can get free shipping if you order by July 27!
So if you’ve had your eye on any designs — like the popular Triangles, Coach Lasso, Believe (Six Colors), I Used To Be Someone On Twitter, or the classic HeyDingus Logo — now’s a great time to buy! Everything comes as a t-shirt, sweatshirt, and even a onesie for the littlest fans. Some even come as phone cases.
How do you get the discount? Just browse the store using any of the links on this page or on my ‘Stuff I Love’ page for the discount to be automatically applied at checkout. If you run into problems, you can also just try my discount code: K8QWSGPK47
I really appreciate any purchase that you make as I get $5 back from each one, which will help me get closer to breaking even on costs for the site. And you get a great quality product! Everyone wins. 👕😄
Merch
TL;DR: Yes. The Instagram app is already too full by the admission of its product leader, and I think Reels is the best choice for booting out to its own app where it could thrive.
I’ve been thinking more about the record-breaking success that Meta has enjoyed with Threads. So much of its initial popularity can be ascribed to Instagram’s huge user base having a leg up on getting started there. Getting connected with your entire existing social graph with just a tap is an accelerant we haven’t seen put to use at this scale since Instagram itself used Twitter’s API, of all things, to bootstrap its network. Things really do come full circle, don’t they?
Building off Instagram’s account system and network is a playbook that has obviously worked for Meta and I’d bet will shake up plans and assumptions made there. But will it retroactively affect services built into, but not out of, Instagram? That is my question.
Instagram has ballooned from the darling indie photo-sharing app it was in 2010 to the visual content factory, shopping center, and ad powerhouse that it is today. Stories, Reels, Shopping, Messenger, even just videos — these are all things that we didn’t want to be added to Instagram in the first place but were shoved in anyway as they rode the tailwinds of each passing internet fad. But what if these ideas were given room to breathe in their own apps, able to evolve without cramming the Instagram interface and pissing off its users? I think Instagram’s head honcho, Adam Mosseri, is reconsidering that very proposition.
Here’s Mosseri discussing Threads being split out as its own app rather as a feature of the Instagram app:
Then there’s a separate app versus separate tab. Separate tab is tough. There’s only so much stuff you can shove in the app. It’s already feeling too complicated. We’re trying to actually simplify right now, and so it’s certainly working against that. And generally, when you build a separate tab, you find you want to push all that distribution through a feed invariably in order to bootstrap it. You kind of end up right back in that first problem.
It sure sounds to me like they regret putting so many features into Instagram and are actively working to rectify those decisions. If they’re considering moving something out, I would think a prime candidate should be Reels. Especially if a widespread TikTok ban goes into effect, US users are going to want something to fill that void, and fast. Something that already has the creators, brands, and friends that they want to follow. Now, whose M.O. does that sound like?
Reels could stay as part of Instagram — it’s been there long enough now for it to gain mindshare — but I don’t think it should. I already go to Instagram for three very distinct purposes: (1) keeping up with photo life updates from friends in the main timeline, (2) watching topical short-form videos from across my interests but mostly from people I don’t follow (Reels), and (3) direct messaging in Instagram Messenger with group chats and individuals — some of whom I don’t even follow! I have to jump around the interface so much that I often lose the thread (heh) of where I am in the app and what I’m doing. As standalone products, I would feel more confident in both consuming and creating for each one. Each would have its focus.
By leveraging my Instagram network as a starting point, I could pick and choose which accounts I want to follow in each app’s context. I can tell you that I’d follow way more people in Reels if it were disconnected from who I see in my Instagram-proper timeline. I’m already doing that with Threads. I might follow more of my group chat buddies. Right now, I just feel like I’d be bloating my Instagram experience further.
One final question: Will a similar deconstruction treatment ever come to Facebook? Or is its siloed, all-encompassing nature too baked in by now? Some people use Facebook as their primary (only?) window and megaphone into the web. I have a feeling that ripping features out of the big blue app would confuse more than help many of its users.
Matthew Cassinelli, with a glowing review of the Belkin 2-in-1 MagSafe Stand which looks perfect for iOS 17’s StandBy feature:
Especially on my desk where power outlets are at a minimum, getting two chargers out of one makes the difference for my setup. Plus, with the added benefit of StandBy in iOS 17, this charger has proved to be the perfect accessory for my personal accessories and helps augment my computing setup even when I’m not really using the phone — neat.
I particularly like Matthew’s use of his landscape-mounted phone as a dedicated place for YouTube. It used to be that my iPad on a laptop stand was that for me, but lately I’ve been actively using it in tandem with my Mac via Universal Control. I’m back to needing a YouTube device.
If I wasn’t on the hunt for a floating MagSafe charger that also works as a USB Hub for my Mac, this is the one I’d buy. And, yes, it’s on sale for Prime Day.
So clean, so good. (Image: Matthew Cassinelli) ⌘
Linked
On the same day I learned that the ‘Show Result’ action has gotten way more useful than ‘Show Alert’ for shortcut construction and debugging, I also thought of a new way to use ‘Show Alert’ to get better control over the flow of a shortcut. What is dead may never die! Or something like that. Anyway, let’s dig in.
I’ve never quite been satisfied with the options for putting up a menu in Shortcuts. ‘Choose from Menu’ is great and all, but it necessitates duplicating a lot of actions unless you really know your way around variables and set them up before the menu. Pairing ‘List’, ‘Choose from List’, and ‘If’ actions offer another avenue if you want to reuse the list of choices, or just pass something from the list on later. ‘Dictionary’ actions are another more complicated option. But sometimes all you want is something simple, just this or that.
That was the case for one of my most-used shortcuts which helps me set up a linked post for my blog. It takes a link shared from the share sheet and a quote that I’ve copied to the clipboard, asks me to write an original comment about the article, and then formats the foundation for the post including the post’s title, author, a link back to the original article, and the block quote all in Markdown. It’s great! But sometimes my quips are short, they get saved and are done. But other times my thoughts about the article run long, and I’d rather move into my writing environment in Drafts. What’s the best way to offer that flexibility? That’s where today’s tip comes in.
Until now, I’ve always just ended the shortcut which saves my draft to Drafts. If I want to continue writing, I open the app, navigate to that item, and then pick up where I left off. Not a huge hassle, but we all know that navigating through different interfaces introduces room for error and distraction — it’s better to keep it all contextual.
The simplest path, up until today, would have been to add a ‘Choose from Menu’ action with options to be done or to continue in Drafts. But if I was going to go through the trouble of making a change to my tried-and-true shortcut, I wanted more. I’m a big fan of checking my work and I wanted a preview of what I’d written so far. Enter ‘Show Alert’.
As I recently explained in another blog post, the ‘Show Alert’ action excels at popping up text with ‘Cancel’ and ‘OK’ buttons. ‘Cancel’ stops the shortcut in its tracks, while ‘OK’ moves on to the next action. That sounds pretty close to ‘Done’ and ‘Continue’, doesn’t it? The other advantage of the ‘Show Alert’ action is that you can customize the title of the alert separately from the body text of it. In the case of my shortcut for linked posts, this meant I could specify some explainer text to help me remember what the two buttons would do.
And what do those buttons do? You can probably guess. By adding an ‘Open Draft’ action after the ‘Show Alert’, if the shortcut continues (the ‘OK’ button) it will automatically open the draft I’m working on. Alternatively, if I tap ‘Cancel’, the shortcut just ends as usual. The draft was already saved before showing an alert, so there’s absolutely no harm in stopping it cold. The best part, since ‘Show Alert’ is made for showing text, I can pass in the content of the draft so far to double-check that it’s saved correctly either way!
I wish my body was this flexible! ⌘
With a little imagination, you can see how this technique will be useful elsewhere. You could use it to manage how a variable gets shared. Copy it to the clipboard before ‘Show Alert’ so that if you hit ‘Cancel’ that’s all you get. But after the alert, it could get more complicated, like opening a specific app. Or transforming text to another format. Or uploading the variable somewhere. These absolutely could be achieved with a ‘Choose from Menu’ action, but there’s something to be said for KISS (Keep It Simple, Silly). And, again, I’ll say that I really like that I can include a preview of the passed variable using this method.
If I had one suggestion for the Shortcuts team to improve this workflow, it would be to relabel the buttons to ‘Stop’ and ‘Continue’. Although less elegant, I think that would better explain what those buttons actually achieve and help my brain decide which one I should hit.
Actually, I do have a second suggestion. The ‘Show Alert’ action doesn’t allow scrolling text passed into the body of the alert like ‘Show Result’ does. This means that the buttons are obscured (but still work!) by longer amounts of text. My suggestion: Fix that. 😉
This could be better, but it gets the point across and is functional. ⌘
Shortcuts
Tips
Using the ‘Show Alert’ action copiously throughout the testing phase of building a shortcut has been the best way to check if you are getting the output you want. It works great for one particular reason: It has an optional ‘Cancel’ button which allows you to stop the shortcut, preventing it from going onto further actions if they aren’t ready. You can place it after an ‘If’ block to make sure the logic works out right. You can place it after a ‘Replace Text’ action to check that it alters the correct text. You can put it anywhere that you want to pause and verify a variable. There’s just one main drawback to the ’Show Alert’ action — it excels at showing text but not much else.
Not quite what I wanted. ⌘
You, the Shortcuts extraordinaire, are probably saying to yourself, “I know an action that does really well at showing any sort of result! Why doesn’t he just use that?” You’re thinking of the aptly-named ‘Show Result’ action. It does, indeed, do a great job of displaying images, videos, files, locations, and more — all in addition to text. But see benefit #1 of ‘Show Alert’. There’s no cancel button presented in ‘Show Result’.
At least not until (somewhat?) recently. Today, I learned that ‘Show Result’ can now include a ‘Cancel’ button alongside a ‘Done’ one! In fact, it always shows one. 🥳 If I had to guess, it was probably added as part of the 2022 beta software cycle last summer and I just never noticed. But I’m overjoyed now that we can use a better tool for debugging jobs.
There we go! ⌘
For years, I got by with pairing a ‘Show Result’ action immediately followed by ‘Show Alert’. But when you’re trying to check multiple steps, trying to move those two actions (around a glitchy interface) to the right place and in the right order, frustration abounds. There’s also the ‘Stop and Output’ action which some people said could be used to debug a shortcut, but that I never liked because you’d have to jump back into the Shortcuts editor and scroll all the way to the bottom of the shortcut to see what was output.
No alert, much scroll. Not good, Bob. ⌘
But all of that is in the past since ‘Show Result’ gained that glorious cancel button. You can place it anywhere you were using ‘Show Alert’ but with less fiddling around to pass variables into it and get previews for more things. Now we can have our nice results and cancel them too.
Shortcuts
Tips
Have you heard? We’re in the middle of one of the biggest shopping events of the year! Not that one, nor that one (although I did send my Mom recommendations for big savings on a Mac, monitor, and USB hub for that one). No, it’s the Indie Dev Sales event, running through tomorrow, July 12.
Come on, you know you want at least one of these apps. (Image: Matt Corey) ⌘
It seems like all the best apps on my gadgets are made by talented independent developers, so I’m thrilled and thankful to see that Matt Corey has put in the work to negotiate and consolidate huge deals on over 100 apps. Huge deals meaning 40%-60% off most apps.
To see the full list, check out the README file in the event’s GitHub repo (very developer-y, right?). Here are the apps on the list that I’ve tried out over the years and can wholeheartedly recommend:
Personal Best ($4.99 for the first year of Personal Best Pro, up to 50% off, use code PRIMEDAY2023)
HomePass for HomeKit ($1.99, 33% off)
HomeRun for HomeKit ($4.99 lifetime, 50% off)
Where To? — Search nearby places ($0.99 for Where To? Pro, 66% off first year)
Focused Work - Pomodoro Timer (30% off annual/monthly)
Tasks: Kanban & Todo lists (20% off)
MacWhisper Pro (€10, 50% off)
Spread the word!
Linked
I’ve been meaning to do a “nuke and pave” of my Mac mini for a couple of years now. Enough little things seem to take too long or are glitchy — image previews that won’t show in Messages, favorited folders that won’t stick around in iA Writer, apps that take tens of bounces in the dock to open — things that shouldn’t be slow or glitchy on an M1-powered Mac. I think I have, as they say, built up some cruft. I’ve migrated this system from an iMac to a MacBook to a Mac mini, so all my tweaks to the system and overlapping app features have been growing their roots for 10+ years. The best way forward, I think, is to do a total erase of the system and then set it up completely fresh.
And since the idea of this endeavor is to start completely over and set it up as a “new” Mac, I won’t be using Migration Assistant and my Time Machine backup to get me back up and going. Because, then, what would be the point? But, oh boy, do I have Time Machine backups just in case. I’ve been hitting that backup button all day.
Instead, I plan to use the ‘Set Up a New Mac’ checklist I keep in Apple Notes and that I’ve spent the last hour or so updating. I’ve noted all of the crucial applications and settings that I’ll need to install and configure for my Mac to feel like mine again. That has entailed taking a lot of screenshots of preference panes and picking through my applications folder, menu bar, Safari extensions, and Setapp installations. Not that I’ll be reinstalling everything again. Part of the goal of this is to leave behind the apps that aren’t serving their purpose any longer.
One thing that I’m a little nervous about, however, is what will happen to my legacy Time Machine backups after setting up the new system. I assume I’ll be able to access files from them by using its encryption password, but I’ve never tried using Time Machine from a user account that isn’t linked to an active backup chain. And when I set it up to start making new backups, I’m curious about how it’ll treat those two backup histories.
Further complicating this restoration process is the fact that my wife has her own user login on this machine. Her files are all saved to iCloud Drive and are likewise backed up to that Time Machine drive. But, again, I’m not completely sure about how setting up all her stuff sans-Migration Assistant will go. And not knowing gives me pause.
The worst case scenario, I suppose, is that it all goes poorly and then I just do a second ‘Erase All Content and Settings…’ and use Migration Assistant with my existing backups to get back to where I started. And I haven’t seen any widespread catastrophic recountings of setting up a Mac as new in my cursory web searches. I guess there’s only one way to find out…
The before pic. Goodbye, good buddy! Your soul deserves a rest. ⌘