BrettTerpstra.com - The Mad Science of Brett Terpstra https://brettterpstra.com/ WriteMapper - writing with mind maps https://brett.trpstra.net/link/535/16671800/writemapper-writing-with-mind-maps https://brett.trpstra.net/link/535/16671800/writemapper-writing-with-mind-maps Mind map, WriteMapper, writing, features, summary

总结: 本文介绍了作者使用思维导图进行长篇写作的方式,提到了他习惯使用的iThoughts和新尝试的WriteMapper应用。WriteMapper针对写作提供了专门设计的功能,包括编辑器、文档视图和键盘快捷键等特点。编辑器提供了标准的文本编辑功能,但缺少Markdown视图。文档视图方便查看整个文档,可以实时更新修改。键盘快捷键丰富,可以在偏好设置中自定义。除此之外,WriteMapper还具有导出和任务管理等功能,对开发者也友好。总的来说,WriteMapper是一款适合写作的工具,虽然价格较高,但功能齐全,易于移植,作者认为物有所值。

One of the major things I use mind maps for is developing longer-form writing. I do best spitting out all of my ideas for topics and chapters into a mind map, then editing the nodes into chapters and paragraphs. I’ve always done this with iThoughts, which has great keyboard shortcuts for navigating and switching between node and notes panels. Then I would view the piece as it came together using Marked’s iThoughts integration, and when it was in a mostly gelled state, I would export Markdown and continue editing in MultiMarkdown Composer.

I’m going to continue using iThoughts for as long as it survives (in case you missed it, it was announced recently that support and development has been discontinued). As I mentioned in a previous post, I’m going to trust MindNode to fill in the gap left behind when the time comes. But for writing, I’ve been playing with a new app called WriteMapper (which I mentioned previously in a Web Excursions post).

The WriteMapper way

WriteMapper is specifically designed for the above use case. It’s developed by a solo indie dev (Guan), who’s built it out into a very polished app.

Writing in mind map form makes it really easy to organize (and reorganize) content as you write, and to pop between topics as inspiration hits. You can write very specific pieces in each node, and easily arrange them in a way that makes sense, without having to plan far in advance. Sure, you can do the same thing with copy/paste in your editor, but I work best with the map layout.

As a side note, MultiMarkdown Composer has a great feature where you can open the Table of Contents view and drag sections around (based on headers) to reorganize the document. It reminds me of an old iOS app called Paragraphs, which I loved but I don’t think it stood the test of time.

I’m writing this post in WriteMapper right now, and I’m finding it very enjoyable.

WriteMapper features

The Editor

WriteMapper has a great editor built in. It’s a much more polished editing experience than writing in iThoughts was. It gives you all your standard shortcuts for bold, italics, and K for links, and it’s easy to add headlines, though most of those will be added using the node titles.

The editor is your basic plain text editor with a rich text overlay, a la IA Writer or to some extent Ulysses, but closer to a WYSYWIG editor in a platform like WordPress. It’s slick and comfortable to work in, though you can’t see a Markdown view, which I miss from some Markdown-based editors. The underlying format for the document is HTML, so you don’t have a lot of more “word processor” type features available, but for my own writing, that’s irrelevant. Anything I need to do that I can’t in plain text is done with plugins and extensions to my publishing platforms. You don’t get to choose your font for editing, which might bug some people.

As far as Markdown compatibility goes, it will convert some Markdown to the rich text view. Double asterisks will become bold, single will become italic, and inline links will work. However, if you try to hit undo after manually entering Markdown syntax, things can get weird. You’re best off using the built-in shortcuts for these features. Pasting Markdown doesn’t seem to get parsed, either.

If you select multiple lines and hit the bullet list shortcut, it will convert the lines into a bullet list. Hitting the shortcut again (or on any bulleted list) will remove the bullets. Hitting the shortcut for a numbered list behaves the same way, and will convert a bullet list to a numbered list.

You can insert images from file or URL. Most of the time I’m writing for a Jekyll system, where I have my own custom plugins for image handling, so I can just paste in my Liquid code for an image and WriteMapper doesn’t mess with it.

Autosave seems to be non-standard (to macOS). WriteMapper’s implementation can have a frequency set as often as one minute, but if you experience a crash (which I haven’t) you would lose everything up to the last auto save.

WriteMapper also implements spellchecking and autocorrect, and both of those seem to use standard macOS implementation. And for anything spell check chokes on, note that there’s an Add to Dictionary option in the right click menu, as opposed to the more standard “Learn spelling” option.

Document View

An essential feature of WriteMapper is the Document View. While you can traverse and edit your document as a mind map, you can also open Document View and edit it all as one piece. You can’t rearrange anything in Document View, though — for that you have to switch back to a map view.

Document View pretty much alleviates my need for Marked integration, as I can easily see my map formatted as a document, in map order, with a quick press of 4 (or whatever you customize the shortcut to). You can edit in Document view just like in a node view, and it has an outline view on the side for navigation. You can even open the Document View in another window and see changes you make to nodes appear in the full document on save, just like using it with Marked.

Keyboard Shortcuts

WriteMapper has plenty of keyboard shortcuts, but they’re very non-standard for a mind map app. You can, however, easily change the shortcuts in Preferences, and I now have it working more predictably (like Tab to add a child node). E pops you right into the editor for the selected node, and when you’re done editing, Escape will get you back to the map.

As I mentioned, in the document editor you have your standard word processor key combinations available, such as I and B. There are also shortcuts for block quotes, horizontal rules, and lists.

While they don’t show up in the Insert menu, there are also keyboard shortcuts for inline code and code blocks, and code blocks can be highlighted if you check the option in Preferences. Inserting Markdown syntax for these also works (three backticks works, indenting doesn’t).

Other Features

Map views can be linear, nested, or sprawl, which is more of a traditional mind map layout.

WriteMapper can export as Markdown or OPML, but can also export straight to HTML, Word, RTF, and other formats.

For developers, the file format is a basic JSON file with an array of nodes in document order, with the content stored as HTML, so integrating this with Marked will be simple, and recovering old documents if WriteMapper ever stops working will be entirely feasible. Which are important considerations to me.

The app can show you your total word count, character count, and reading time as you edit, and each node can be set to display its own word count. You can also set nodes to tasks and check them off as you complete them.

You can also open the same document in multiple windows for side-by-side editing of different chapters. You can’t have multiple documents open in tabs, as far as I can tell, but if I need two documents open at once, I need them both visible anyway for copying between the two.

WriteMapper also supposedly has some AI features, but I haven’t gotten it to accept my OpenAI key yet and haven’t spent much time figuring that out. I’ll do my own writing for now.

Wrapping up

In summary, WriteMapper is a great tool for writing. A few quirks, but fully capable for my own needs. The export options are robust, and the document format is standard enough to be easily portable. And being able to construct a piece in a mind map is exactly the way I want to write. WriteMapper isn’t cheap — a single license is US $89. I think it might be more comfortable in the $40-50 range, but I consider it money well spent and I’m happy to support continued development.

Check out WriteMapper here.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-05-02T15:13:00-05:00 Conductor fixes and improvements https://brett.trpstra.net/link/535/16667786/conductor-fixes-and-improvements https://brett.trpstra.net/link/535/16667786/conductor-fixes-and-improvements config, fixes, enhancements, track, sequence

总结: 文章介绍了对Conductor工具进行的重要修复和便捷改进。修复包括输出更丰富的信息和运行多个脚本的能力。增强部分包括显示标题和在条件满足时继续匹配条件。此外,除了详细介绍改进内容外,还列出了完整的更新日志,涵盖了各种新增、优化和修复。整体而言,Conductor工具得到了很大的功能提升和问题修复。

I’ve made some important fixes and handy improvements to the Marked Conductor since it was first published.

I’ve made my own config available as an example. Not all of the scripts are polished, but it’s complete enough to show how I’m using it. I still need to finish breaking my Jekyll preprocessor script into more manageable chunks, which is complicated because every little method has conditionals, but that’s coming. In the meantime, you can find my work in progress here.

Here’s the rundown.

Titles and STDERR Output

Conductor now outputs more helpful information to STDERR, which you can view in Marked using Help->Show Custom Processor Log. It will display a list of conditions met for the current document, along with any errors. You can also now add a title key to any track, and it will be used in the STDERR output instead of the full condition, which is handy for long conditions with lots of booleans. So instead of:

Condition met: tree contains .obsidian AND (extension is md OR extension is markdown)

You can just get:

Condition  met: Obsidian Document

Multiple scripts

Conductor can now run multiple scripts in sequence. There are two ways to do this.

  1. Instead of a script or command, you can use sequence. Then in an array list, you can define a series of - script: xxx and - command: xxx type lines and they’ll be run in order, with the output of one being passed to the next, getting the final output from the last script/command in the list.
  2. You can add continue: true to any track or block. Normally, Conductor stops processing when a condition is met. With continue: true, it will continue matching conditions after processing the one with the key, again passing the output of each one to the next. This allows you to, for example, run a preprocessor on a narrow selection of documents, and then run those through a more generalized processor that catches more documents than the narrow selection does.

Changelog

Here’s the full changelog since release.

NEW

  • Test for pandoc metadata (%%) with is pandoc or is not pandoc
  • Add sequence: key to allow running a series of scripts/commands, each piping to the next
  • Add continue: true for tracks to allow processing to continue after a script/command is successful
  • filename key for comparing to just filename (instead of full path)
  • Add is a tests for array, number, integer, and float
  • Tracks in YAML config can have a title key that will be shown in STDERR ‘Conditions met:’ output
  • Add does not contain handling for string and metadata comparisons
  • Added test for MMD metadata, either for presence of meta or for specific keys or key values
  • Allow has yaml or has meta (MultiMarkdown) as conditions

IMPROVED

  • Return NOCUSTOM if changes are not made by scripts/commands, even though condition was matched
  • Use YAML.load instead of .safe_load to allow more flexibility
  • Trap errors reading YAML and fail gracefully

FIXED

  • Use STDIN instead of reading file for conditionals
  • String tests read STDIN input, not reading the file itself, allowing for piping between multiple scripts
  • Always wait for STDIN or Marked will crash. Still possible to use $file in script/command values
  • More string encoding fixes
  • “path contains” was returning $PATH instead of the file path
  • First-run config creating directory instead of file
  • Frozen string/encoding issue on string comparisons
  • Encoding errors on string methods

Check out the Conductor project for more details!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-29T12:00:00-05:00 Life after iThoughts https://brett.trpstra.net/link/535/16666804/life-after-ithoughts https://brett.trpstra.net/link/535/16666804/life-after-ithoughts MindNode, iThoughts, sunsetting, Obsidian, Curio
总结:
iThoughts宣布即将停用,作者转向使用MindNode。MindNode拥有精美界面、活跃开发、支持Mac和iOS版本,能够打开iThoughts文件,导入Markdown文件,生成任务列表等功能。此外,Obsidian插件也能提供一定的思维导图功能,但相比MindNode功能有限。值得注意的是Curio内置的思维导图也是不错的选择。

So a lot of us are wondering what to do now that Toketaware has announced the sunsetting of the iThoughts mind mapping app for Mac and iOS. It’s very sad to see it go, but I expect the current version to continue working for a few years to come. That said, I tend to favor software that has at least somewhat of a future. So I’ve been testing the waters with some other contenders. The short story is I’m moving over to MindNode.

Why MindNode?

I’ve always appreciated MindNode (and even added support for it to Marked), but there were some things that made me prefer iThoughts over MindNode. After testing the latest version of MindNode, I can no longer remember what those things were. Probably the filtering and advanced searching in iThoughts, but for 90% of my mind map purposes, it looks like MindNode will do just fine. I think the last time I made the comparison, MindNode was lacking some of the features it has these days.

I’m not going into nearly the depth that Allison Sheridan did over on Podfeet with her mind map comparison, but I’ll list some of the pros of MindNode for my purposes:

  • Looks great
  • Actively developed
  • Mac and iOS versions
  • Opens iThoughts (.itmz) files, so I don’t have to fret about losing old mind maps
  • Imports Markdown files
  • Can create tasks from nodes (can’t do much with them other than check them off, but it’s handy for packing lists)
  • Exports Markdown and OPML, among other formats
  • Works with Marked (File->Advanced->Preview in Marked)
  • Good keyboard navigation with some customization options
  • Quick entry from tool bar
  • It’s on Setapp

Other options

If you’re an Obsidian user, there are some mind mapping plugins available. The “Enhancing Mind Maps” plugin is a decent option if you’re in Obsidian all the time anyway:

Pros:

  • Built into obsidian
  • Basic keyboard navigation
  • Transparent layer over plain Markdown files, easily portable and future-proof
  • Works great with Marked using the obsidian-md-filter processor (via Conductor!), and you can easily connect the two with my plugin (which is still waiting for acceptance into the Community Plugins…)

Cons:

  • Lacks a ton of features compared to MindNode

I would also point out that the mind mapping built into Curio is pretty good, and has the benefit of fitting into the crazy cool integrations that Curio provides, linking to other notes and objects, and fitting into an overall project management system.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-28T17:35:00-05:00 Introducing the Marked Conductor https://brett.trpstra.net/link/535/16664804/introducing-the-marked-conductor https://brett.trpstra.net/link/535/16664804/introducing-the-marked-conductor Marked, Conductor, YAML configuration, custom processors, conditional running

总结: 该篇文章介绍了最新的副产品——Marked,并详细描述了其背景和功能。Marked提供了使用Markdown(和预处理器)的选项,允许您在配置文件中使用自定义命令将其转换为HTML。借助Conductor,用户可以轻松设置自定义处理器,并根据条件在不同的讨论中执行不同的脚本或命令。Conductor支持各种条件匹配方式,如YAML frontmatter键匹配、内容匹配、文件或目录存在性检测等。该项目将受到使用Marked的Custom Processors的人的极大兴趣,无论您是一个熟练的脚本编写者还是只是想在不同文档中运行不同处理器的人,Conductor都能够轻松实现条件运行。待Obsidian插件被接受进入Community Plugins后,作者还将发布一篇关于如何在Obsidian中使用Marked的文章。

I’ve completed my latest side project, the Marked Conductor. Here’s the backstory:

Marked 2 offers the option to use Custom Processors (and Preprocessors) which allow you use Markdown (and other) flavors with your own commands to convert them to HTML. This is commonly used for processing with Pandoc. Personally, I use it to process my blog posts (and Bunch and other Jekyll help docs) with Kramdown and a bunch of special handlers for previewing the custom Liquid tags and plugins I’ve built, process TaskPaper files with their own functions, and process everything else with Marked’s built-in processors. In those scripts, you can use environment variables like $MARKED_EXT (the file’s extension) or $MARKED_ORIGIN (the file’s path) to fork the script and process differently based on things like file type or location. But my custom processor script was getting unwieldy with all of the conditions I was creating, and for people with limited scripting knowledge, it meant having to turn custom processors on and off based on the needs for the current document.

Enter Conductor. It’s a command line utility that can be set as the custom processor in Marked. It reads from a YAML configuration file where conditions are written in natural language (e.g. tree contains .obsidian) and trigger either a script or a command. Conditions can be booleans (extension is md AND tree contains .obsidian) or they can be nested infinitely to create forked “tracks” for handling any type of document. It offers ways of matching YAML frontmatter keys, matching content with strings or regular expressions, detecting whether a file or directory exists anywhere in the parent folders of the file, and more.

I won’t go into all of the features in this post, but they’re all detailed on the project page. The entire project is available on GitHub, but it’s published as a gem, so installation is as easy as running gem install marked-conductor. Running conductor once from the command line will build out all of the configuration directories and files. Then it’s just a matter of setting up your own tracks and actions.

I think this project will be of great interest to anyone using Custom Processors in Marked. Whether you’re an avid scripter who’s extended it in interesting ways, or just someone who might want Pandoc for documents in your “Work” folder, but Kramdown for documents in your “Blogging” folder, this project makes it very easy to run Custom Processors conditionally.

By the way, I’m waiting on my Obsidian plugin for Marked to be accepted into the Community Plugins. Once that happens, I have a post all about using Marked with Obsidian that I think Obsidian users will love. Stay tuned.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-25T13:27:00-05:00 Web Excursions for April 22, 2024 https://brett.trpstra.net/link/535/16657056/web-excursions-for-april-22-2024 https://brett.trpstra.net/link/535/16657056/web-excursions-for-april-22-2024 Google Cemetery, figlet/toilet ascii art, BetterTouchTool MacOS automation, Marked plugin for Obsidian, NordVPN

总结:
Google Cemetery提供了Google终止的产品列表,其中可能有一些你从未听说过的产品。xero提供了大量figlet/toilet ascii艺术字体。BetterTouchTool是一个可以用JavaScript进行MacOS自动化的工具。作者制作了一个适用于Obsidian的Marked插件。NordVPN不仅可以保护你的网络浏览安全,还可以让你的IP地址看起来来自任何国家。

Web excursions brought to you in partnership with NordVPN. Secure your internet browsing effectively and affordably.

Google Graveyard - Killed by Google

Killed by Google is the Google Graveyard. A full list of dead products killed by Google in the Google Cemetery. Up-to-date and shocking in scope. I bet there are a few on here you’d never even realized were a thing.

xero/figlet-fonts
A huge collection of figlet/toilet ascii art fonts from xero.
btt.js
BetterTouchTool MacOS automation in JS. I haven’t played with this yet but it looks really fun. Let me know if you take it for a spin.
ttscoff/Marked2-obsidian
I made a Marked plugin for Obsidian. It’s my first try and I really don’t know what I’m doing, but it seems to work perfectly. Waiting for it to be included in the Community Plugins for easy install (which could have happened by the time this goes live), but you can install from the source if you’re anxious.

NordVPN secures your internet browsing, plus it can make it look to services like you’re coming from any country. Check it out today.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-22T11:00:00-05:00 A plea to nvALT users https://brett.trpstra.net/link/535/16655625/a-plea-to-nvalt-users https://brett.trpstra.net/link/535/16655625/a-plea-to-nvalt-users nvALT, end of life, modernize, Markdown files, nvUltra
nvALT已经停止更新,目前几乎无法在现代操作系统上正常运行。建议用户将存储方式转为Markdown文件,以便顺利迁移到新的笔记系统。如果笔记存储为富文本文件(RTF),则需使用其他应用如nvUltra、The Archive或Obsidian。学习Markdown并不难,只需了解一些简单的语法规则。立即将存储方式改为纯文本文件,以免在nvALT无法运行时无法提取笔记。可能会为nvUltra编写导入器,但目前尚未实现。要获取nvUltra测试版,请通过网站联系链接发送邮件。

I’ve said this before, but I need to keep repeating it based on the number of queries I get. nvALT is at end of life, unless someone picks up the reigns and modernizes the (open source) code base. As it stands now, nvALT barely functions on modern OSs.

Fletcher Penney and I have designed nvALT’s successor, nvUltra, to work only with a folder full of Markdown files, which is the only way I recommend using nvALT. If your nvALT files are stored as individual Markdown files, switching to nvUltra is no problem, nor is switching to any other Notational-Velocity-like system. It will even work in Obsidian. But if you store your notes as a database only, you’re screwed when nvALT stops working for you.

So please, if nvALT is still running for you, go into Preferences->Notes->Storage and change “Store and read notes on disk as” to “Plain Text Files.” If your previous storage method was database, all of your notes will be immediately written out as plain text files, safe and secure and easy to port to a new (working) notes system. The files will now be in the same folder nvALT shows in the folder selector at the top of the Notes preference pane.

nvALT is not even working well enough for me to get a full screenshot. But here is my best attempt.

If your notes are stored as Rich Text Files (RTF), you’ll need to convert them to Markdown to make use of other apps like nvUltra, The Archive, or Obsidian. If you don’t know Markdown, don’t sweat it. It’s very easy to learn and it’s really just plain text, so as long as you know how to write, you’re already kind of writing Markdown. It’s only necessary to learn any syntax if you need to do things like create bulleted/numbered lists, add bold or italics, or create links.

So, again, please immediately switch your storage method to plain text files. The nvALT database format has no easy out for people ready to switch. I may try to write an importer for nvUltra (or generally to output Markdown), but I have not done so yet.

If you want on the nvUltra beta, email me through the contact link on nvultra.com.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-20T09:44:00-05:00 Back in my day... some thoughts on blogging then and now https://brett.trpstra.net/link/535/16642792/back-in-my-day-dot-dot-dot-some-thoughts-on-blogging-then-and-now https://brett.trpstra.net/link/535/16642792/back-in-my-day-dot-dot-dot-some-thoughts-on-blogging-then-and-now blogging, audience building, social media, sponsored posts, search engine traffic 总结:

这篇文章探讨了在过去10年中博客环境发生的变化。以前博客之间会互相分享,帮助建立观众群体,但现在社交媒体和搜索引擎的影响力增加,导致了独立博客的衰落。赞助文章的回报减少,搜索引擎流量下降,原创内容面临困境。作者认为当前的环境并不利于内容创作者,强调继续支持原创作品的重要性。

I’ve been blogging for over 20 years now, making websites for 28 years, and before all of that I was running a BBS that had users from all over the U.S. (but only one phone line/modem, so it was slow communication). And I’ve seen an unsettling shift over the last 10 years that I feel like writing about.

It used to be (10, 20 years ago) that birds of a feather in the blogging world would share each other’s work and sustainably build audiences together. I was part of an informal “network” of blogs that frequently shared each other’s posts, when they were noteworthy, and getting “seen” was as easy as making good content. Getting mentioned on a larger site meant measurable traffic and often new subscribers to your work, and it was a meaningful way of building an audience. The audience I currently have is largely a product of those days.

My larger projects brought in new readers. 20 years ago MoodBlast was my starting point, then the Blogsmith Bundle got attention from Merlin Man, Marked got attention from Daring Fireball, and all of that netted new traffic and more followers. These days, it’s a lot harder, and the attention of major players has much less impact. Bunch got a fair amount of press. Write-ups in major online media outlets, features from creators like David Sparks, and even some print publications worldwide. And I saw a swell in the number of downloads every time, but none of it filtered back to building my readership. Not the way MoodBlast or Marked did a decade ago.

I think I’m doing better work than ever, and it is getting noticed, it just doesn’t tip the needle anymore. I’m not suffering for traffic, but “new” traffic is definitely coming from unusual and unpredictable places that are nearly impossible to capitalize on. Even getting linked on Hacker News doesn’t tip the needle the way it used to (or the way getting Dugg used to. IYKYN.). Gone are the days, seemingly, when I could make something new and have “major” bloggers notice my work, and thus increase readership. I don’t even know how to scratch the surface of the largest blogs anymore, and many of the independent blogs that I could count on have gone the way of the Dodo. And I, at the age of 45, do not have the energy and “hustle” required to make it on new platforms. I will continue doing what I’m doing, and will probably eventually follow my peers into digital obscurity. It’s not that I steadfastly refuse to adapt to new things, I try new things all the time, it’s that these platforms have come to reward behavior I don’t think is beneficial to the end user, and I tend to opt out. I’m not going to “hustle” to make more money for someone else, which is the way we’ve allowed everything to become structured.

These days, we all share our links into the morass of social media, where even our own followers have a hit-or-miss chance of seeing them, thanks to The Algorithm. We “like” creators’ work, but it just becomes a little tick in a metric that’s really only useful to advertising companies whose money is primarily going to the platform provider, not the creators that provide its content. Social media sites are invested in keeping you, the viewer, on their platform, and sending you to a third-party site is detrimental to their ad sales and attention metrics. This doesn’t, in general, benefit the creators. It benefits the platform. Medium and Substack are truly profitable for a select few, with an intense amount of attention and energy (i.e. hustle) involved in getting there. Creation of original content is not, by and large, rewarded by any of these platforms, and you’re ultimately creating content for a corporation to use as they like. Fewer and fewer creators are actually owning the content they create, and it’s disheartening.

Side note: I’ve been reticent to take on new sponsors lately. The returns just aren’t there for the sponsor anymore. I don’t know why, honestly, but my readership is happy to click on links but hesitant to actually spend money. The economy? I don’t know. I just know that I charge a reasonable rate for sponsored posts, but the feedback I’ve gotten from sponsors over the last couple of years is that it didn’t pay off. Which sucks for all of us. So if you like my work and would like to fund me regardless of sponsors, please become a subscriber!

Search Engine traffic is down for many of us because the major engines’ output is flooded with ads and content that is, at best, knock-off content designed to spam the results. I think Google and Microsoft have given up on trying to quell the “SEO” hackers, or even keep up with them. And now they want to spew AI-generated detritus all over the place. Original content is dying, if not dead.

This is all to say that I recognize that things have changed. I just don’t think it’s for the better. Gone are the halcyon days of independent bloggers sharing original work, and the knowledge networks that cropped up between them. Gone are the days of a rising tide that lifts all boats. The tide is just Social Media, and it is, at my most generous, not concerned with the boats. I think, in fact, it’s actively hostile toward them.

I will continue to share noteworthy things I find via Web Excursions and reviews. If you have an article or project you’d like to show my audience, contact me one of the many ways I’m available. And again, if you want to support my work, it’s just a click away.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-05T15:46:00-05:00 CurlyQ and automated JavaScript execution https://brett.trpstra.net/link/535/16641718/curlyq-and-automated-javascript-execution https://brett.trpstra.net/link/535/16641718/curlyq-and-automated-javascript-execution gem install curlyq, JavaScript execution, screenshot command, execute subcommand, web automation tool

总结: 作者在文章中介绍了对CurlyQ工具的改进,包括添加JavaScript执行功能、改进截图命令、新增执行子命令等。通过对工具的升级,用户可以更方便地进行网页自动化操作,如保存网页截图、执行特定脚本等。这些改进将极大地提高用户的工作效率,特别适用于自动化文档生成等工作。CurlyQ的最新版本已可通过gem install curlyq进行更新或安装。

I’ve been wanting to add JavaScript execution to CurlyQ for a while and finally got around to it.

In case you’ve missed it, CurlyQ is my command-line web automation tool for fetching, parsing, and responding to web page content, designed to be used as part of a *NIX pipeline. It can grab titles, links, metadata, and more from any web page. As part of its functionality, it can also use Firefox or Chrome to save screenshots, and that’s part of what I’ve improved.

The screenshot command now accepts a --script parameter. This can be a JavaScript string, or - to read from STDIN, or a path to a file which will be read and executed before taking a screenshot. You can also now define an element ID to wait for before taking the screenshot (or executing the script) using --id ELEMENT_ID. As long as the ID is a valid element on the page, the screenshot will trigger once that element is loaded (via HTML or dynamically), with a timeout of 10 seconds. You can also define a --wait X flag in the command to wait for a specified number of seconds after executing a script before the screenshot is taken.

Further, I’ve added a new subcommand, execute, that has the same parameters as above and simply allows you to load a page in the browser and execute a script on it. I really wanted this because it’s the easiest way to automate NiftyMenu:

curlyq execute -b chrome -s "NiftyAPI.find('file/save').arrow().shoot('file-save')" file:///Users/ttscoff/Desktop/Code/niftymenu/dist/MultiMarkdown-Composer.html

That command will save a screenshot of the File->Save menu item for me, allowing me to fully automate menu screenshots for any of my apps. I can have NiftyMenu generate an up-to-date view of the app’s menu bar, with styling for the current OS, and output detailed screenshots with callouts automatically. This will be a huge timesaver when it comes to documentation.

You can update/install the latest version of CurlyQ with gem install curlyq. The improvements in this post are available as of version 0.0.12. Enjoy!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-04T13:24:00-05:00 On using a CDN https://brett.trpstra.net/link/535/16638813/on-using-a-cdn https://brett.trpstra.net/link/535/16638813/on-using-a-cdn CloudFront, CDN, AWS, performance, setup
总结:
文章介绍了如何通过使用CDN(如CloudFront)来提高网站性能,特别推荐使用AWS的CloudFront服务。通过将图片、CSS和JS等资源从CDN而不是服务器(如DreamHost)提供,可以显著提高网站加载速度。作者分享了如何设置CloudFront分发,以及如何进行版本控制和CDN预热。总体而言,使用CDN可以同时提高速度和降低成本。

If you run a website and aren’t serving your assets from a CDN, I want to highly recommend that you do so. I’ve seen significant performance improvements simply by redirecting my image, CSS, and JS requests to a CDN instead of serving them from a server like DreamHost. I like DreamHost just fine, but the time it takes to serve a file and the download speeds it offers are not… optimal.

The idea behind a CDN is that your assets are served from a speed-tuned network of servers that can deliver the fastest speeds using servers located as close as possible to the end user. I can serve up a 1MB image file in about 1/2 the time using a CDN versus serving directly from DreamHost.

CloudFront

I’ve found CloudFront (Amazon Web Services) to be the easiest to set up and the most affordable option. There are a few good options to explore, though. I haven’t done head-to-head testing of all available options, I just know that CloudFront offers some of the highest speeds and one of the most generous free-tier options.

I can serve all of my sites’ assets (Bunch, Marked 2, Dimspire.me, BrettTerpstra.com, and sundry others), including DMGs, zips, images, CSS/JS files, and more, from AWS for about $2/mo. My total AWS bill is $13/mo, and that includes my Glacier backups and S3 storage. Compared to $20/mo for CloudFlare, it’s a pretty easy decision for me. Some of the “fancier” CDNs can do things like serving different image formats and sizes based on path/query strings, but I haven’t been willing to shell out the cash for those.

I’m not going to do a full tutorial on setting up a CloudFront deployment for a website, but the basic steps are:

  1. Create an AWS account (if needed)
  2. Navigate to CloudFront
  3. Create a new distribution
  4. Set the origin to the url of your website
  5. Add a CNAME for your distribution
  6. Generate an SSL certificate (free through Amazon) for the distribution (requires DNS verification of ownership)

Most of the other options can be left to their defaults. Here’s a more in-depth tutorial. Total setup time is about 30 minutes, including waiting for DNS verification and spin-up time. Of course, then you have to modify your site to make use of the CDN. I have solutions for Jekyll and other SSG generators, if you care to ask. There are multiple WordPress plugins for handling this kind of thing as well.

Versioning

Files served from the CDN are heavily cached, meaning if you want to serve up a new version of a file, updated CSS for example, you need to “bust” the cache. This can be done by adding a query string, e.g. ?v=123 to the file url, but it’s preferable to use filename versioning. If you’re using Apache, you can just include this in your .htaccess:

<IfModule mod_rewrite.c>
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpe?g|gif|rb|json|svg|ico|webp|avif|webm|mp4|zip)$ $1.$3 [L]
</IfModule>

That will allow you to request image.123.jpg and it will serve up image.jpg, but the CDN will see that as a new file request and pull an up-to-date version of the file from the server.

In my Jekyll setup, I have a single version number for the whole site defined in _config.yml under a cachebuster key. In my templates I have some logic that determines when the site is rendering in production mode (JEKYLL_ENV=production), and when it is, it substitutes the CDN path and the version number into the URL. For example, if I’m in production mode, https://dimspire.me/assets/css/main.css will be written as https://cdn.dimspire.me/assets/css/main.123.css. As long as the 123 doesn’t change, the CDN will continue serving the same file, but if I bump it to 124, it will sync the latest version of the file from the server and cache it upon the first request.

Priming the CDN

If you want to avoid anybody having to wait for the CDN to ingest a file, cache it, and serve it on the first load, you can make a headers-only curl call to the asset. This is kind of silly, as once any one user in a region has loaded the new asset, it will be served instantly for subsequent loads. But just for fun, I’ll share my Rakefile task for syncing the CDN after a version bump:

class String
  # Outputs a string in a formatted color.
  # @param [<Integer, String>] color_code The code to use
  # @return [void]
  def colorize(color_code)
    "\033[#{color_code}m#{self}\033[0m"
  end

  def green
    colorize(32)
  end

  def red
    colorize(31)
  end
end

def chdir_base
  Dir.chdir(File.dirname(File.expand_path(__FILE__)))
end

def ok_failed(condition, sender=nil)
  res = condition ? "OK" : "FAILED"
  msg = sender ? sender + ": " + res : res
  warn msg
end

desc 'Sync CDN images'
task :sync_cdn do
  # Make sure we're in the base directory
  chdir_base
  
  # Use rsync to upload files to the server that pushes to CloudFront
  ok_failed system('rsync -criz assets/* dh:~/dimspire.me/assets/ &> /dev/null'), 'CDN Sync'
  
  # Read the current version (cachebuster) from the config file
  buster = YAML.load(IO.read('_config.yml'))['cachebuster'].sub(/^\./, '')
  
  # Iterate through all files in assets directory and its subdirectories
  Dir.glob('assets/**/*') do |f|
    # Only prime images and CSS/JS assets
    next unless File.extname(f) =~ /\.(webp|avif|gif|jpe?g|png|css|js|mp4|ogg)$/

    # Generate the CDN filename with the cachebuster inserted (e.g. image.123.jpg)
    asset = %(cdn.dimspire.me/#{f.strip.sub(/\.(\w{2,4})$/, ".#{buster}.\\1")})
  
    # Use curl to request headers for the image, and grep out whether it was a hit or miss
    res = `curl -Is #{asset}|grep --color=never X-Cache|sed 's/X-Cache: //'|sed 's/from cloudfront//'`.strip.upcase
  
    # Provide feedback in Terminal
    $stdout.print res =~ /HIT/ ? "\033[0KHIT #{asset}\r".green : "Priming #{asset}\n".red
  end
end

The only important part of that is curl -Is [ASSET], which does a headers-only request for the file, which will cause the CDN to ingest it if it isn’t already cached, without actually downloading it. Currently Dimspire.me has about 225 “Dimspirations,” each with 9 image versions (wallpapers, jpeg, webp and avif versions), and running this after a version bump (meaning none of the assets are cached) takes about five minutes for 2000+ assets. If I’m only adding new images and not bumping the version, this task takes under two minutes. Doing the simple curl call above on all of the assets that got “revved” (bumped) will mean that nobody has to wait for files to be initially cached, but again, this is pretty silly.

TLDR

If you run a website that serves a lot of images, CSS, or JavaScript, you can see significant performance improvements by using a CDN. CloudFront is, in my experience, the best combination of fast and affordable. If you want to see more of my Jekyll setup (Rakefile, templates, etc.), just ask. I’m always happy to share.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-02T16:03:00-05:00 Automating the Dimspirations workflow https://brett.trpstra.net/link/535/16637190/automating-the-dimspirations-workflow https://brett.trpstra.net/link/535/16637190/automating-the-dimspirations-workflow Affinity Photo, Automation, Dimspirations, Hazel, Rake 总结:

本文介绍了作者如何利用Affinity Photo和自动化工具来创建Dimspirations图像,并通过Hazel、RetroBatch、Rake等工具自动处理和发布。作者使用Hazel来监控并处理文件,Rake来生成Markdown文件并自动添加元数据,最后通过Howzit来部署网站。整个流程高度自动化,作者只需手动完成图像的创建和简单的编辑,整个发布过程高效顺畅。文章还涉及到了Affinity被Canva收购的猜测和对未来的担忧。整体来说,文章详细解释了作者的工作流程和自动化程序的运作,展示了高效简便的发布流程。

First, there seems to be a misconception that Dimspirations are generated with AI or some other such trickery. I want to assure you that, while the entire process of posting them is automated, each Dimspiration is lovingly crafted by me in Affinity Photo1.

I wanted to detail the automation though, partially for my own reference, and partially just because I’m pretty proud of the system.

The Template

First, I have a template I load up in Affinity Photo. It has guides for all of the various formats that will be produced from the single output file. All I have to do is make sure that the text and necessary parts of background images fit into the smallest guide rectangle, and that the rest of the space is filled with a reasonable amount of background image or matching color. The tallest output is the iPhone version, which on occasion just gets filled with a background color, but I can usually make a background pattern or image fit nicely for iPhone and still look good for all of the other formats.

Affinity Photo template

I have a Dimspirations Bunch that opens the template in Affinity Photo, loads up the Desktop and Dimspirations folder in Finder tabs (for keeping track of the rest of the process below), and opens up Adobe Stock in my browser for grabbing those sweet, sweet background images. So to get started on a bunch, I just hit Hyper-D, Shift-D (my assigned shortcuts in Bunch).

The new Dimspiration gets saved-as with a slugified version of the title I want it to have on the site, e.g. “The end of the world” gets saved as the-end-of-the-world.afphoto. Then I output a JPEG of the whole image with the same slug (populated by default), tag it with .dim in the save panel, and save it to the Desktop.

Hazel and RetroBatch

Hazel watches the Desktop for .dim JPEGS, removes the .dim tag, and automatically opens the image in a RetroBatch applet called “Dimspiration.”

RetroBatch applet

The RetroBatch applet saves various formats with -rb suffix (3 desktop wallpapers, 1 iPhone wallpaper, Twitter and Facebook preview images, an Instagram-ready version, and the 1x and 2x versions of the square image for the website). Upon writing the files, they then get sent to ImageOptim for optimization. The optimized files get saved to a new “Dimspirations” folder.

Hazel watches the “Dimspirations” folder and copies wallpaper formats to an upload folder, where Hazel (again) uploads those images to Flickr as screenshots in a DimPapers album, then deletes the copied files.

Hazel then moves all of the image files to the Dimspire.me website assets folder.

Rake and Howzit

I then open up iTerm (visor mode because I’m not an animal), switch to the dimspire.me directory, and run rake. The wallpaper download zips, WEBP and AVIF versions, and Markdown post are created. The Rake task looks for new JPEGs, extracts their base name, and generates Markdown files for any new ones. It automatically adds YAML frontmatter to each post:

  • A title extrapolated from the image slug, where end-of-the-world becomes “End of the world”
  • the base image slug, which is used to extrapolate the square and @2x versions for display
  • a “manifest” section with a list of files in the zip download
  • An ALT tag auto-generated with textra, which runs Apple’s built-in OCR on the image to extract its text
  • a short url created with a curl call to dim.moi
A dimspiration post

The Rake task outputs the Markdown file’s filename, which I can just ⌘-Click (iTerm) to open in MultiMarkdown Composer, where I double check the ALT tag and add a snarky caption as the body content.

In my Howzit buildnotes file I have sections for previewing and deploying, so I can just run howzit -r deploy to deploy the site, which calls the necessary Rake tasks and uses rsync to copy the entire rendered site to the server. CSS and JS (and all images) are served from a CDN which uses versioning like filename.1234.css, and if I want to upload changes to any of these files, I need to bump the version number before rendering, so the Howzit task will ask me upon deploy if it should bump the version. If I haven’t made any changes and have only added a new Dimspiration, I can just hit n and it will avoid clearing the CDN cache.

buildnotes.md for dimspire.me

The site runs on Jekyll, so mass updating the posts can be done just by searching and replacing in Markdown files. The Rakefile has tasks for updating all of the zip downloads with any new versions of the images that have been added (and updating the manifest data in every post with any changes), batch adding any missing ALT tags, and creating all missing WEBP and AVIF versions at once. Whenever I just run rake, all of these tasks execute in sequence, so every time I publish it’s filling in any missing pieces, not just the latest post. It takes about 20 seconds to run all of the tasks on all of the posts at this point, though the zip creation (which rebuilds all zips on every update) will take increasingly longer as the number of posts grows. I’ll deal with making it more incremental when that actually becomes a burden.

So my (manual) part of the process is:

  1. Lovingly craft a Dimspiration in Affinity Photo and save it to the Desktop
    • Wait a minute for Hazel/RetroBatch/ImageOption to do their things
  2. cd to the Dimspire.me website directory and run rake
  3. Open the created post and edit two lines
  4. Run howzit -r deploy (which with my aliases and fuzzy completion is just bld dep, and thanks to Fish’s directory-sensitive history, is just a matter of typing BF)

As always, if you have any questions about any part of this that you’d be interested in implementing on your own, please join us in the forum and ask away! And as always, I’d love it if you checked out Dimspirations and the Dimspirations Store.

  1. Affinity was recently acquired by Canva. How much are we betting that it switches from the sweet $50/version pricing to unaffordable subscription pricing within a year? They’ve promised to always keep it “reasonable,” but that’s a very subjective term. 

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-04-01T14:53:00-05:00 Web Excursions for March 29, 2024 https://brett.trpstra.net/link/535/16635234/web-excursions-for-march-29-2024 https://brett.trpstra.net/link/535/16635234/web-excursions-for-march-29-2024 mac app; intention setting; Terminal trick; native macOS email client; keycap replacement

总结: 这篇文章介绍了一款简单优雅的Mac应用程序,可以帮助用户设定意图并提醒他们专注工作。还分享了一个适用于Terminal爱好者的技巧,并推荐了一款优秀的原生macOS邮件客户端。最后提到了订购了一个键帽来替换现有的定制键帽。

Web excursions brought to you in partnership with CleanMyMac X, all the tools to speed up your Mac, in one app.

N₁₀ - Attention Management App for Mac
A simple, elegant Mac app that allows you to set an intention, define how much time you plan to put into it, and then just sit, quietly reminding you of what you want to be working on with subtle but all-encompassing animations. Perfect for those of us who say “OK, now I’m really going to work on this” and then find ourselves doing something entirely different within five minutes H/T Jason Rhemus and props to props to developer Sam Stephenson.
Again with man pages and BBEdit - All this
Really nice trick for Terminal junkies who use BBEdit. I have a similar trick for sublime, and one that opens man pages in Preview, but this one provides additional navigation that none of mine have.
Mimestream
“A native macOS email client for Gmail.” This looks so good, especially considering MailPlane is dead. If only I didn’t have iCloud and Exchange email accounts I need to deal with, too.
Interstellar Resin Keycap
I ordered this keycap to replace my custom rocket keycap that I use for my hyper key. Available in 2.25u (Enter) size. It should arrive today and I’m very excited. I’ll post pictures once I’ve installed it!

CleanMyMac X

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-03-29T12:10:00-05:00 Revisiting TagFiler and Vitag https://brett.trpstra.net/link/535/16628513/revisiting-tagfiler-and-vitag https://brett.trpstra.net/link/535/16628513/revisiting-tagfiler-and-vitag TagFiler, Vitag, tagging system, files, Finder 总结:

本文介绍了作者使用的两种文件标签系统,分别是TagFiler和Vitag。TagFiler是通过Finder标签进行文件整理的脚本,可以自定义“context”文件夹和相关标签,便于快速定位文件。Vitag则是用于在大量文件中快速添加标签的工具,可以在编辑器中编辑标签后一键保存,省时又方便。作者长期使用这两种工具,提高了文件整理效率,希望读者也能尝试并发现更多创新。

I haven’t mentioned this setup for a while and thought I’d remind everyone, especially newer readers, about a rabbit hole they might choose to go down. I haven’t updated or changed any of these scripts since posting, and they’re all still working well.

Part 1: TagFiler

Hazel screenshot

First up, I’ll mention TagFiler. This is a single script that runs via Hazel, sorting files into a shallow filesystem using Finder tags. You set up “context” folders which are tagged with =Context, e.g. =Work or =Personal. Then you create a shallow system of subfolders tagged with relevant keywords, preceded with @, e.g. @nvultra or @dimspirations. You can nest those @ folders as deep as you like, but the idea is to make it easy to target them. Then you tag individual files with #Context :subtopic, and subtopics can be nested like #Projects :nvultra:marketing:source to file in ~/Projects/nvultra/marketing/source files.

Finder window showing tags

The nice thing about these tags with punctuation is they create something like nested tagging, which Finder lacks. When searching with Spotlight (or HoudahSpot), you can search any part of a colon-separated tag (this works for any punctuation, TagFiler just uses colons). So with the above example, I can search for tag:nvultra tag:source and get the tagged file as a result. Then, when tagging files in Finder (or, again, HoudahSpot as it has great autocompletion for tagging), the tags will autocomplete as if they were nested, and just typing nvultra will bring up all of the colon-separated versions of the tag.

This tagging system has been working perfectly for me for years now. I collect all my files throughout the day on my Desktop and in my Downloads folder. Hazel tags new files with Purple, and then at the end of the day (or the beginning of the next one) I open up a saved search in HoudahSpot that shows me all Purple files in my main “inbox” folders. I can then use HoudahSpot’s autocompletion to tag the files appropriately, and Hazel just whisks them off to their target folder. This saved search could also just be a Smart Folder in Finder, but Smart Folders can’t narrow down to multiple specific directories. In HoudahSpot this can be accomplished using saved searches and filtering.

The nice thing about this system is that I can also find any TagFiler-tagged file using Spotlight without digging through the folders. But if anything ever happened to my tags (a metadata disaster…), I’d still have a reasonable folder structure for finding all of my files. It’s also nice when archiving projects to a NAS or other storage system that doesn’t have Spotlight searching.

Side Note: cdt

I have a little Bash function called cdt (with a fish companion function) for navigating TagFiler-tagged directories from Terminal. I don’t actually use it much as I have fuzzy_cd in my Fish setup and it’s a bit smarter in general. I can’t vouch that it still works as is, but if you wanted to dig in, let me know if you find issues.

Part 2: Vitag

So I do a majority of my tagging in Finder or HoudahSpot. But when I’m faced with a large number of files and want to tag them quickly and easily, I use vitag.

By the way, if you do your tagging in Finder, you can add a keyboard shortcut to make popping up the tag dialog keyboard-accessible.

Vitag loads up a list of files for the current directory (and optionally subdirectories) with bracketed tags after each filename in your editor of choice. I usually use Sublime Text with -e 'subl -w', but you can use Vim, NeoVim, BBEdit, VS Code, or any editor that has a CLI tool and the ability to wait on the command for the window to close (usually -w, but see the --help for your tool). You just edit the tags as plain text and when you save and close the file, all of the tags are changed on the files.

Vitag screenshot

There’s no autocomplete by default, although I have written a Sublime package (which I haven’t shared because it’s very custom) which helps me out with syntax highlighting, snippets, and autocomplete. For the most part, though, I rely on TextExpander snippets for contexts and common sub-tags.

Then I can just copy/paste as needed to fill out the whole batch, along with the search tools in the editor (at the end of a day most of my files in my inboxes will relate to just a couple of projects, so I can copy and paste many of the tags, sometimes modifying just the last element of a colon-separated tag).

For example, the first thing I do on a batch of “inbox” files is search for Purple and G through the results to add my tags. You could also remove any line that didn’t contain a tag like Purple — as long as the filename remains unchanged, deleting a line will have no effect in Vitag. Unlike tools like Vidir, Vitag only deals with tags.

You’ll notice a couple of files tagged with #x#. This is a special tag that I search for with Hazel, which deletes any file containing it. It’s my solution for deleting unneeded files when doing my cleanup. It actually moves to Trash rather than outright deleting as you’d get in Vidir, which provides the option for undoing.

So, to wrap up, there’s nothing new here. I’ve been using these tools for years. I just thought I’d share them again in case I first talked about them before you started reading. Let me know what innovations you have with your own tagging systems!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-03-22T11:39:00-05:00 Web Excursions for March 19, 2024 https://brett.trpstra.net/link/535/16624673/web-excursions-for-march-19-2024 https://brett.trpstra.net/link/535/16624673/web-excursions-for-march-19-2024 Deckset, Markdown, OCR, Ground News, CleanShot X

总结: 文章介绍了一些最新的网络资源和工具。其中提到了Deckset推出iOS版本,用户可以使用Markdown在iPhone/iPad上创建演示文稿。另外推荐了一款基于Markdown的演示工具,可能比Deckset更好。还介绍了一个只适用于macOS 13+的简单命令行工具,可以使用内置的OCR和转录框架。提到了Ground News这个工具,可以帮助用户了解不同观点的新闻,打破信息茧房。最后作者推荐了CleanShot X用于截图和录屏。文章结尾提到网站受到读者支持,保留所有材料版权。

Web excursions brought to you in partnership with CleanShot X, the absolute, hands-down best app for Mac screenshots. Get one of my all-time favorite apps here.

Deckset on the App Store
Just when I thought Deckset was dead, an iOS version is announced. Create presentations using Markdown, now on your iPhone/iPad.
iA Presenter
A newer option for Markdown-based presentations (from the creators of iA Writer and based on the same engine) that I think this might be even better than Deckset. Going to give it a test run for a while, but off the bat it looks really slick.
freedmand/textra
macOS 13+ only, a simple command line interface to the OS’s built-in OCR and transcription frameworks. The OCR works really well. Really, really well (I’m using it to add automatic ALT tags to Dimspirations and it deals with text in crazy fonts on crazy backgrounds). I haven’t gone far with testing the audio transcription, but I have high expectations.
Ground News
This is advertised on almost every YouTube channel I subscribe to, so I decided to check it out. It’s really good. If you want to break out of your news bubble and understand what the other side is hearing and thinking, Ground News provides all kinds of tools for doing so. Highly recommended. I’m trying to get my parents to use it, but even if they don’t, it helps me see the headlines that are going to affect them in their bubble so I’m not shocked when topics come up that I’ve seen no trace of previously.

I do all of my screenshots and screen recordings with CleanShot X. I love it to pieces. You should get it.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-03-19T10:33:00-05:00 Build a custom URL shortener https://brett.trpstra.net/link/535/16621740/build-a-custom-url-shortener https://brett.trpstra.net/link/535/16621740/build-a-custom-url-shortener URL shortener, custom domain, installation, features, inspiration

总结: 这篇文章介绍了作者如何搭建自己的URL缩短服务,并使用自定义域名。作者选择了现有的工具,进行了修改和定制,最终建立起了一个基本的URL缩短服务。作者详细介绍了安装步骤和新增的功能,以及使用的动机。通过自己的经验,作者希望能鼓舞读者也开展类似的有趣项目,并向大家推荐了一些其他的服务。

I wanted short urls for Dimspirations, and I wanted a custom domain name (dim.moi), but didn’t want to pay the somewhat exorbitant prices to do so with something like Bit.ly. So I set out to build my own URL shortener.

PHP/mySQL seemed like the path of least resistance on my current server setup, so I went looking for existing tools that met my needs without too much complication. I found Shorty by Mike Cao, a decade-old project that still worked just fine. I forked it and built a tool called [Shortly] on top of it. It uses all of the base code of Shorty with my own additions, so full credit for this goes to Mike, but it has enough changes specific to my needs that I’m not pushing my fork upstream.

Shortly is a basic URL shortener. You just have to register your short domain, set up basic PHP/mySQL hosting for it, and then install the files. So the total cost is one domain registration, plus whatever hosting you use for it. It requires very few resources, so a simple $5 shared hosting plan will work fine. I have multiple servers where adding new domains doesn’t cost me anything, so I went with a Dreamhost server for this and built it for just the cost of a .moi TLD ($30/yr, if I recall correctly).

The install instructions are detailed in the README and on the project page. It’s pretty simple, just creating a mySQL database and importing an SQL file to set up the simple database. In about 15 minutes you can have a custom URL shortener that outputs urls like dim.moi/eQ and passes them through to the full url on the target site. All of my Dimspirations now have short urls, and I can generate new ones with a simple curl call from my build system.

Here’s what I added to the script:

  • Allow limiting shortening to one domain
  • Allow forwarding of paths containing hyphens or which are not found in the database to be forwarded to a root url
  • Allow appending query strings to urls before shortening or forwarding
  • Accept format=qr and size=XXX to create QR codes for shortened urls
  • Add longURL keys to JSON and XML output
  • Default to plain text output format, perfect for curl calls

All of these settings are detailed in the README and commented in the config file.

For my particular needs, my shortener will only shorten URLs from dimspire.me, will forward unknown urls like dim.moi/ether-bunny to https://dimspire.me/dimspiration/ether-bunny/, and will append some UTM parameters to any url it shortens so I can track usage.

Part of the impetus for this was I wanted to include UTM parameters in the links I offered for sharing, but didn’t want to make ungainly URLs. With Shortly, I can add any query parameters I like to a url and end up with a simple https://dim.moi/fR url to share. And I can shorten https://dimspire.me/dimspiration/optimal-anxiety-level/ to https://dim.moi/optimal-anxiety-level/ without even using the API (as the unrecognized slug automatically gets forwarded to the base url dimspire.me/dimspiration/SLUG).

Hopefully this inspires some fun projects of your own, and revives a great little project that Mike Cao started. It’s such a simple concept that I’m sure there are dozens, if not hundreds, of permutations of it. This is just the one I found the easiest to hack away at and get running with minimal fuss. Check out the project page or the GitHub repo to get started.

As an aside that’s not worth it’s own post, I also set up a CloudFront instance that forwards from.ttscoff.me/(filename) from an S3 bucket, and added a Dropzone destination so I can just drag any file to Dropzone and get back a from.ttscoff.me URL with which I can share any file. It lacks all of the niceties of other file-sharing tools, but I’m running it for less than a dollar a month. Subdomain was free, and it doesn’t use enough bandwidth to really register as an expense in my Amazon plan. If you want any details on how to do this, just let me know.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-03-16T13:00:00-05:00 Dimspirations Merch! https://brett.trpstra.net/link/535/16598996/dimspirations-merch https://brett.trpstra.net/link/535/16598996/dimspirations-merch 打印和交付,Sellfy,merchandise,BrettTerpstra.com,支持者 总结: 作者在BrettTerpstra.com上推出了新的商品系列,使用Sellfy进行印刷和交付。他计划在未来扩大选择,并根据反馈调整定价。他希望读者喜欢他的作品,并提供支持。

I’ve created the initial round of merchandise for the Dimspirations Store. I know my sense of humor isn’t for everyone, which is why this whole project is on a different site.

I’ve started with some of my personal favorites as tees, mugs, and a 2024 calendar. The collection will grow over time (it’s print-on-demand, no cost to me to expand the selection). I’ll also adjust pricing based on feedback. I think the prices are pretty competitive based on what I’ve spent on merch myself.

I’m using Sellfy for the printing and delivery. I’ve used Spring in the past and checked out Printful and Cotton Bureau, but Sellfy seemed like the best solution with the most competitive pricing. I already paid for a 1-year package, so let’s hope it works out. If it does, I’ll probably relaunch the BrettTerpstra.com (Lab) merchandise there as well.

Please do check out the store, and if you like what you see, toss a couple bucks my way. And if you don’t see what you want, be sure to upvote your favorites Dimspirations by clicking the devil below each one. If you have special requests, of course let me know.

I’ll admit, this one is my favorite:

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-03-02T10:12:00-06:00 Web Excursions for February 29, 2024 https://brett.trpstra.net/link/535/16597352/web-excursions-for-february-29-2024 https://brett.trpstra.net/link/535/16597352/web-excursions-for-february-29-2024 Alfred, Bunch, Colorful nihilist memes, Hyper Key, Backblaze

总结: Alfred的workflow Cluster与Bunch紧密集成,使生活变得更加轻松。还有色彩缤纷的虚无主义迷因来提高心情。此外,还有macOS上简单而强大的键盘增强工具,Backblaze可安全可靠地将整个计算机数据备份到云端。 Matt Webb的帖子谈论了科技走入了一个令人不安的境地,但或许这并不是件坏事。

Web excursions brought to you in partnership with Backblaze. Back up everything.

Cluster (for Bunch)
Cluster is an Alfred workflow for use with Bunch, written by Stephen Millard. Closely integrates Bunch functionality with Alfred to make life even easier. I’m not an Alfred user myself, so I haven’t stress tested it, but if you are, please do and let Stephen and I know how it goes!
Nihilisa Frank on Tumblr
Colorful nihilist memes to make your day. Thanks to @adamrice for pointing this out.
Superkey
Simple and powerful keyboard enhancement on macOS. Want to add the Hyper Key with no fuss? Want to navigate your screen without touching your trackpad/mouse? This app looks really great at $16. h/t Mike Harahan on the forum.
Tech has graduated from the Star Trek era to the Douglas Adams age (Interconnected)
This post from Matt Webb speaks to me. Yes, tech has gone into a wobbly place better envisioned by Douglas Adams than by Gene Roddenberry, but maybe that’s an ok thing.

Backblaze securely backs up your entire computer to the cloud, affordably and reliably. I trust it with all my data. Check it out today.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-29T15:04:00-06:00 How to Compose Reminder Emails [Sponsor] https://brett.trpstra.net/link/535/16596954/how-to-compose-reminder-emails-sponsor https://brett.trpstra.net/link/535/16596954/how-to-compose-reminder-emails-sponsor 关键词: 提醒邮件, 礼貌问候, 提供背景, 具体说明, 行动号召 总结:

本文介绍了如何撰写礼貌、清晰、具有行动能力的提醒邮件,以帮助确保工作任务按时完成。首先,要以礼貌的问候开头,然后提供提醒的背景和相关上下文,接着具体说明需要关注的任务或事件,并包括行动号召,最后要表达感激之情并以礼貌的方式结束邮件。文章还介绍了一种名为SaneBox的邮箱管理工具,可以避免使用提醒邮件,提高工作效率。

Thanks to Sanebox for sponsoring BrettTerpstra.com again this week! This one is longer than the usual sponsored post, but full of great tips whether you use SaneBox or not (but you should!).

Effective communication is key in the workplace. With it, we can complete tasks on time and meet sales goals. Yet, essential messages can sometimes get lost in our busy inboxes.

This is where reminder emails come into play—they serve as gentle nudges to keep tasks on track without being overly intrusive. Crafting a reminder email that is polite, clear, and actionable requires finesse. Luckily, these best practices and examples can help you write an effective reminder email that helps you achieve your goals without sounding rude.

1. Begin with a Polite Greeting

Start your reminder email with a courteous greeting to set a positive tone. Whether you’re addressing a colleague, client, or team member, a friendly salutation can go a long way in fostering goodwill.

Example

Subject: Friendly Reminder: Upcoming Team Meeting
Dear [Recipient’s Name],

I hope this email finds you well. I wanted to gently remind you about our upcoming team meeting scheduled for [date and time]. Your presence and input are highly valued, so we look forward to you joining us.

2. Provide Context

Clearly state the purpose of your email and provide relevant context to jog the recipient’s memory. Be concise yet comprehensive, ensuring that the recipient understands why the reminder is necessary and what action is expected from them.

Example

As our project deadline is approaching, it’s crucial that we finalize the presentation slides by [deadline date]. Your expertise in [specific area] will be invaluable in ensuring the success of this project. Please review the attached draft and provide your feedback at your earliest convenience.

3. Be Specific

Specify the task or event that requires attention, including any pertinent details such as deadlines, locations, or action items. Avoid vague language that could lead to confusion or misunderstanding.

Example

Please submit the quarterly sales report by [deadline date]. This report is essential for our planning and decision-making processes. Please don’t hesitate to reach out if you require any assistance or additional information.

4. Include a Call to Action

Clearly outline the steps the recipient needs to take and any deadlines associated with those actions. A call to action provides clarity and encourages prompt response or action.

Example

To confirm your attendance, please RSVP by clicking on the following link: [RSVP link]. If you cannot attend, kindly let us know so we can make the necessary arrangements.

If you are concerned your call to action may not be strong enough or elicit a timely response, you can always use the SaneReminders feature from SaneBox to help you follow up later on. Think of it like a timer: you specify the information with an @sanebox.com email in the To or CC line, and SaneBox takes care of the rest.

5. Express Appreciation

Express gratitude for the recipient’s cooperation and assistance. Acknowledging their efforts reinforces positive behavior and encourages continued collaboration.

Example

Thank you for your attention to this matter and for your continued dedication to our team’s success. Your contributions are truly valued and appreciated.

6. Use a Polite Closing

End your email with a polite closing that leaves a positive impression. A courteous farewell demonstrates professionalism and respect for the recipient’s time.

Example

Once again, thank you for your cooperation. We look forward to your prompt response. Please don’t hesitate to contact me with any questions or concerns.

Avoid Email Reminders Altogether With SaneBox

Writing an effective reminder email requires a balance of politeness, clarity, and specificity. However, your workplace can avoid lost messages and overloaded inboxes altogether by utilizing a mailbox management app like SaneBox.

SaneBox is an incredible inbox management tool that can save you hours per week thanks to seamlessly organizing and filtering emails. Once you set up SaneBox, the email management tool will classify incoming messages into folders based on their importance. This way, you can quickly view essential messages that require a response and leave the rest for later.

Effective communication is the cornerstone of productivity and success in any endeavor. Don’t be the reason someone needs to send you reminder emails: gain control over your email with SaneBox. Check out SaneBox today and save $25!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-29T08:55:00-06:00 Dimspire.me on Product Hunt https://brett.trpstra.net/link/535/16596955/dimspire-dot-me-on-product-hunt https://brett.trpstra.net/link/535/16596955/dimspire-dot-me-on-product-hunt site, collection, review, support, materials 总结:

文章提到了新网站的推出,作者对网站的付出和希望得到评论的愿望,以及对读者的支持。网站包含了虚无主义的灵感和壁纸。作者期待读者的支持和评论。

On a whim I’ve put the new Dimspire.me site up on Product Hunt. I’ve been putting a lot of love into it and even if I were to stop now, I think it’s a great collection of nihilist inspirations (and wallpapers), enough to last quite a while. I’d love it if you’d take a second and leave a review.

Thanks!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-29T08:52:00-06:00 Dimspirations in your feed https://brett.trpstra.net/link/535/16590869/dimspirations-in-your-feed https://brett.trpstra.net/link/535/16590869/dimspirations-in-your-feed RSS feed, subscription, email, monetize, political 这是一篇关于Dimspire Me网站的文章,介绍了他们新增了RSS feed订阅和通过邮件订阅的功能。同时作者表示如果网站有商业化可能的话,将通过出售商品来实现,而不是收费订阅。作者还表示会尽量减少涉及政治的内容,因为有些读者对此表示反感。最后作者呼吁读者点赞和分享这篇文章以及支持他们的项目。总结:文章介绍了Dimspire Me网站新增的订阅功能以及未来可能进行商业化运营的打算,同时表示会尽量减少政治相关内容。

I’ve added (well, fixed) the RSS feed for Dimspire.me. You can now subscribe via your favorite feed reader at Dimspirations RSS (or just enter https://dimspire.me in your subscribe field, the feeds are discoverable). The feed is available in XML and JSON flavors, and each entry just contains a pithy description and one image.

You can also sign up to receive Dimspirations in your email, max one email per day, and only when there’s new stuff:

Thanks for supporting this little project. I’ve decided if I ever monetize it, it will be through merch (posters, calendars, coffee mugs, etc.). So the wallpapers and dismal inspirations will continue to be free online.

P.S. I’ve received some flack for occasionally going “political” with the Dimspirations. I don’t think things like being disgusted by a lack of gun control, being anti-genocide, or laughing at manufactured outrage are extreme political views, but I promise to keep those to a minimum. Sometimes I get a little fired up — don’t let it scare you away.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-24T11:08:00-06:00 Dimspire.me https://brett.trpstra.net/link/535/16588973/dimspire-dot-me https://brett.trpstra.net/link/535/16588973/dimspire-dot-me Jekyll, insomnia, website, automation, dimspirations

总结: 这篇文章讲述了作者因失眠而产生创造力,制作了一个名为Dimspirations的网站。网站基于Jekyll架构,具有自动化功能,可以生成不同尺寸的壁纸,包括iPhone版本和方形版本。作者描述了网站的页面结构和功能,包括随机生成Dimspirations的功能和下载按钮的实现方法。作者还提到了对于网站的未来计划。整篇文章表达了作者对于自己创作的热情和对网站的期望。

I couldn’t sleep last night. I’m not manic, I’m just going through this months-long bout of insomnia. At least I don’t think I’m manic. It doesn’t have any of the characteristics of my usual mania. And up until last night I wasn’t even getting out of bed when I couldn’t sleep. But last night I did, and I made you a website.

Introducing Dimspire.me. It’s built on Jekyll and has a bunch of automations. I can essentially create a “dimspiration” using an Affinity Photo template, and then RetroBatch will output wallpaper sizes (including iPhone) and square versions for posting and populating the gallery. Just running rake will find new photos added to the assets folder and generate posts for them, which will then populate the index pages. It should be pretty simple to maintain. All documented in a Howzit notes file, of course.

The site is pretty simple: a homepage with description and the latest few posts, a “Dimspirations” page that’s essentially a blog post index but done in gallery fashion, and a random dimspiration page that will just throw single random dimspirations at you. Fun stuff.

When viewing a single Dimspiration (by clicking on any thumbnail), you get some cool UI showing edges of the previous and next Dimspiration. I like it, anyway. There’s still some work to do on certain breakpoints, but overall the styling should work on any device. And every Dimspiration page has a download button, where you can download all available versions of the current Dimspiration. This is accomplished by a Rake task that parses every post, extracts the YAML key that defines the image for the page, then zips up every file in the assets directory that matches it. It creates a manifest table that shows what’s in the zip file, with each individual file linked. So when there are wallpaper versions of a Dimspiration, you can download the set or follow a link to a specific version. Took a little thinking and tweaking, but I think it’s a good solution.

I hope you enjoy it. It’s cathartic for me to create these, and they’re getting better with time. I’m not going to try to monetize any of this at this point, but I’ve watermarked all the images so if you share them, they should trace back to me. Speaking of, I do still need to consider adding share buttons to these… but it always freaks me out how much data social sites collect when you include their button, so I’ll need to figure out ways around that. We’ll call that “next step.”

Love always,
Brett

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-22T13:43:00-06:00 Keep It — Write notes, keep things, and find them again [Sponsor] https://brett.trpstra.net/link/535/16588628/keep-it-write-notes-keep-things-and-find-them-again-sponsor https://brett.trpstra.net/link/535/16588628/keep-it-write-notes-keep-things-and-find-them-again-sponsor 笔记本,整理,多平台,存储,自动化
Keep It是一个多平台的笔记本和组织工具,可用于编写笔记,保存网页链接,存储文档、图片或任何类型的文件,并且可以通过标签、文件夹和其他方式进行整理。它可以存储在iCloud中,使笔记和文件可以在所有设备上访问,还可以通过AppleScript、Automator和Shortcuts app进行任务自动化。总结:Keep It是一个多功能的笔记和组织工具,能够整理、存储和共享各种类型的文件和笔记,并支持自动化操作。

Thanks to Keep It for sponsoring BrettTerpstra.com this week! If you’re looking for a way to keep all of your information at your fingertips, readily findable, without locking yourself into a database-based system like Evernote, Keep It is a great solution.

Keep It is a notebook and organizer, ideal for writing notes, keeping web links, storing documents, images or any kind of file, and finding them again. Available on Mac, iPhone and iPad, Keep It is the destination for all those things you need to put somewhere, confident you will find them again later.

Create notes with built-in styles that look good and read well on all your devices. Notes can contain checklists, bulleted and numbered lists, links, dividers, images and other attachments.

Or if you prefer writing in Markdown, Keep It includes an editor with syntax highlighting, word count, tools for formatting text, inserting links and images, and a customizable preview.

Keep It can edit its own notes, rich text, plain text and Markdown files, add highlights and notes to PDFs, and show previews for images, web pages and most other documents. Any kind of file can be added to Keep It and opened in its original app for editing.

Keep It integrates well with macOS and iOS. On Mac, you can save files to one of Keep It’s folders in the Finder or standard Open and Save panels. On iPad and iPhone, see Keep It’s files in the Files app, and the standard document browser used by most apps.

Save web links to Keep It in any app via its Share extension. Choose to save them as PDFs or web archives for offline reading, or convert them to editable notes.

Keep It has a number of ways to organize your files – tags hierarchical folders, mirrored in the Finder and Files app, color-coded labels, and bundles, where items can be in more than one bundle at a time. Other lists include the Recents list to see things you’ve added or viewed lately, with the latest shown at the top. Favorites provide quick access. Quick File lets you file things without taking your hands off the keyboard.

Keep It can search the content of most files, recognize text in scanned PDFs and images, and prominent features in images. While searching, suggestions appear as you type, allowing you to narrow down results to exactly what you need, and build complex searches with ease. Searches can be saved for later reuse. Quick Open lets you open anything just by typing its name.

Keep It’s Tag Filter makes finding things by tags easy, and works with search and the selected list. Choose a tag to see all the tagged items and any other relevant tags; choose another tag to drill down further.

Keep It can store everything in iCloud, so your notes and files will be available across all your Macs, and iOS devices. Keep It can also share top-level folders and individual items with other Keep It users via iCloud.

Tasks in Keep It can be automated with AppleScript, Automator and the Shortcuts app. Grab a free trial Mac, iPhone, or iPad and check it out today!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-22T08:00:00-06:00 A Cerakey ceramic keycap review https://brett.trpstra.net/link/535/16580751/a-cerakey-ceramic-keycap-review https://brett.trpstra.net/link/535/16580751/a-cerakey-ceramic-keycap-review ceramic keycaps, backlit, sound, pros and cons, personal experience

总结: 这篇文章介绍了作者购买陶瓷键帽的经验。键帽在背光下呈现出独特的外观,但字体在背光下比较难辨认。此外,键帽的声音也有所改变,失去了原本机械键盘的特有“咔嗒”声。作者个人认为这是个人取向的问题。总之,作者对陶瓷键帽的使用体验较为满意,但也提到了一些改进的空间。

I recently purchased some Cerakey ceramic keycaps for my Ultimate Hacking Keyboard. When I mentioned the purchase on Mastodon, I got a few replies asking for a review, as multiple people had been considering the purchase. So here it is.

Note: I have 3 cats. I tried to clean the keyboard up as much as possible before I took photos, but if you have cats, you know how that can go. I did my best.

The Look

Here’s how the keys look sans backlighting:

Keyboard halves connected, unlit
Keyboard split, unlit

I originally ordered the “Crazed” keycaps (pictured below), but after paying for them I was notified that there was an error between actual stock and what Shopify listed, so instead they sent me two sets, in Canal Blue and Water Blue. So I combined them, as seen above. The Q–R keys of the left half are Canal Blue, the right half is Water Blue.

I really like the crackled look of the Crazed keys, so I might order those in the future when they’re back in stock:

Crazed Cerakeys

One nice thing about ceramic keycaps is the way they glow when backlit. If you don’t have a backlit keyboard, you’ll only be concerned with the sound and weight, which I’ll detail below. But if you have backlighting:

Keyboard halves connected, backlit
Side view of the Cerakeys lit
Comparison of shine-through PBTs and Cerakey legends

Unlike shine-through keycaps, the legends are actually harder to read when backlit. I’m a touch typist and never look at my keys, so it’s kind of a moot point for me. The only time I need to look at the keyboard is when I’m typing a number without my fingers on the home row (e.g. 2FA auth code when I’m also holding my phone). If you hunt and peck and have a backlit keyboard, you might want to think twice.

Seriously, the overall aesthetic of backlit ceramics is (to me) the coolest I’ve seen. This will depend on personal preference, and there are plenty of backlighting setups I’ve never tried, but:

Keyboard split, backlit

The keys have a shine to them. They look like a polished plastic. I guess they look like what you’d expect a laquered ceramic surface to look like. I find it pleasing, but again, it’s going to depend on personal preference.

If you like multi-colored keyboards, you’re going to drop some cash as Cerakey only sells full sets in one color. I would love it if you could combine colors to create a custom layout. I would also appreciate being able to get single custom keys, as the UHK has a very unique layout that no standard keycap set will cover. While I was customizing, I went ahead and ordered the 1.75U space bars that the UHK uses from Asymplex (h/t @BrokenFlows).

The Sound

My box white switches with ceramic keys have less click, which at first blush is a con to me. I picked the box white switches for my UHK because they had what I found to be the perfect amount of clickiness with PBT keycaps. The ceramic keys remove most of the click, and replace it with a pretty bassy thock. I’m currently deciding whether that’s a compromise I’m willing to make, or whether I’m going to swap them out for blue switches (or go back to PBT keycaps).

To be fair, hit softly and one-at-a-time, they still click just fine. It’s just the thunder of rapid-fire typing that lacks the click I find so satisfying on my mechanical keyboards.

Here’s how the ceramic keycaps sound on my UHK with Box White switches:

"Cerakey on Box White"

Here’s how the original PBT keycaps sound:

"PBT on Box White"

Next to each other for comparison:

"Comparison on Box White"

And just for reference, here’s the Cerakey on a Cherry Blue switch:

"Cerakey on Cherry Blue"

And for comparison, PBT on Cherry Blue:

"PBT on Cherry Blue"

Cons

I would consider the loss of click a con, but that’s an entirely personal opinion. As described above, Cherry Blue switches actually sound pretty good. Basically like Box White switches with PBT keycaps.

The one thing that does bug me is there’s no discernible bump on the F and J keys, so I do have to look down to find the home row. I’m going to fix this with a home brew solution, eventually. Maybe a little epoxy and some Sugru. Most glues and resins won’t stick to the ceramic surface, so this is going to take a little work. I don’t have feeling in the tips of my fingers on my right hand (I don’t know why, this only happened in the last 10 years), so I need a big bump to be able to feel it. This is probably less of a problem for others, but in recent years it’s taken a little customization for me, even when there are ridges on the F and J.

The harder-to-read legends on backlit ceramic keys is a little bit of a bummer. As I said above, it doesn’t really affect me, but it might be something to note.

Neither Pro Nor Con

The keys are slippery. This is kind of a non-issue, it turns out. I thought the slick surface of the keys would affect my typing speed and error rate, but it really doesn’t. If anything I actually type a little faster on these, but it’s a negligible difference.

In Summary

I’m going to use these for a couple months and see if I miss the PBT keys at all. So far I don’t, and I love the look. I would like to get the Crazed version eventually, but I’ve spent enough money on keycaps for a while. I’ll eventually want to replace the modifier keys, but will have to find a custom solution for those.

I have to decide how important the click I was used to is. I’m finding the overall sound of these pretty pleasing after a few days with them. But my modifier keys and space bars are still PBT, so I hear the click after every word. This makes the difference obvious, but also gives me a certain amount of satisfaction that might tide me over.

I hope this helps answer some questions. I take no responsibility for your purchase, but now you have the benefit of my experience.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-17T14:52:00-06:00 #dimspirations are back https://brett.trpstra.net/link/535/16571361/dimspirations-are-back https://brett.trpstra.net/link/535/16571361/dimspirations-are-back #dimspirations, automation, wallpaper, gallery, feedback 总结:

作者创建了一个名为#dimspirations的系列“inspirational”海报,并自动化了壁纸格式的创建。作者考虑建立一个易于维护的网站来展示这些作品,并考虑通过Patreon等方式获取支持。读者被邀请分享反馈和建议。

I’ve started creating Dimspirations again, my depressing-but-actually-realistic collection of “inspirational” posters. You can follow the hashtag #dimspirations on Twitter, Facebook, Mastodon, or Instagram for new posts. I’ve also automated the process of creating wallpaper-formatted version of them which get uploaded to Flickr and are also available as a zip (containing 5120x3200 and 2048x1366 versions). I should probably add an iPhone ratio to the automation, but they get harder to resize vertically from one image. Anyway, if you’re in the mood to be “dimspired,” check them out.

By the way, if you’ve never checked it out, the “Other Stuff” section (where my wallpapers are located) has some fun projects in it. Fun for me, anyway.

Side tangent: I own the domain dimspire.me, and have always meant to find a way to make an easy-to-maintain gallery out of these. Probably a blog-style thing with daily or weekly dimspirations, with basic comments functionality and links to download the square or wallpaper versions. The index page would just be a thumbnail gallery with the main image from each post. It might actually be nice to do a paywall and have the wallpaper versions supported by Patreon or something. I don’t know if anyone would actually pay for these. I’ve seen similar projects sold as books, and I feel like the designs are actually pretty good for print, so maybe someday. Anyway, my inclination is to do this site in Jekyll (which I’m very adept at), but would be open to any suggestions as to what the best way to accomplish this would be. I’m not even opposed to WordPress with some custom plugins (which I’m also surprisingly adept at), which would be pretty easy to automate and then I could use MarsEdit to maintain it. Still pondering.

In the meantime, please share your feedback (and any suggestions, should the dimspiration strike)!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-12T12:02:00-06:00 Web Excursions for February 12, 2024 https://brett.trpstra.net/link/535/16571248/web-excursions-for-february-12-2024 https://brett.trpstra.net/link/535/16571248/web-excursions-for-february-12-2024 Find Any File, iThoughts, photo library, GUI, BrettTerpstra.com

总结: 本文介绍了几款实用的工具和应用,其中包括Find Any File,这是一款更新不断的应用,可以帮助用户进行准确的文件搜索,并且可以搜索NAS;iThoughts则是一款思维导图工具,虽然开发者已经停止更新,但仍然是一款值得推荐的应用;此外,还有一款用于整理照片库的工具,以及一款可以直接编辑Mac应用偏好设置的GUI工具。BrettTerpstra.com也提供了支持,读者可以选择是否点赞或分享。

Web excursions brought to you in partnership with MindMeister, the best collaborative mind mapping software out there.

Find Any File
I’ve mentioned HoudahSpot plenty of times, but there’s an app that’s been around since about 2005 that has been continually updated and only costs $6-10 that’s worth checking out if you constantly run into hard-to-find files. One major benefit of Find Any File is that it can search your NAS and doesn’t rely on Spotlight for indexing. Searches can be a little slow but they are VERY accurate. Allows saving searches and search templates, and can export found files as a list for use in scripting app… uses a pay-what-you-can shareware model (oh, the old days!). Here’s a great review from Allison Sheridan with much more detail.
toketaWare has ceased trading
If you’ve followed me for the last few years, you know I swear by iThoughts for my mind mapping needs (of which I have a lot). I’m pretty devastated to see that the developer has moved on and there will be no future releases of the app on any platform. I checked in with him, he says he’s fine, he just moved on. Fair enough. Now I have to pick a new favorite mind mapping tool. Open to your thoughts!
Photoscope - Storage Cleaner on the App Store
A tool for cleaning up your photo library by easily selecting the best image from sets of multiple/burst photos. Well done and easy to use.
Prefs Editor
From the same developer who makes Find Any File, a very handy GUI for directly editing any Mac app’s preferences. Especially great for apps that have “esoteric” or hidden preferences that require using defaults commands in Terminal. Free!

Check out MindMeister and start brainstorming, collaborating, and boosting productivity.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-12T09:57:00-06:00 Convert nvALT RTF files to Markdown https://brett.trpstra.net/link/535/16565808/convert-nvalt-rtf-files-to-markdown https://brett.trpstra.net/link/535/16565808/convert-nvalt-rtf-files-to-markdown nvALT, RTF, Markdown, Shortcut, Conversion
这篇文章介绍了一个将RTF文件转换为Markdown的快捷方式,帮助那些想从nvALT转移到其他应用的用户。作者提到了从nvALT转移到nvUltra或Obsidian等Markdown应用的情况,并分享了一个使用Shortcuts的解决方案。他还提到了对Shortcuts的使用方法和可能的问题,并鼓励读者提出改进建议或疑问。总的来说,这篇文章是一个为nvALT用户提供帮助的实用指南。

总结: 这篇文章介绍了如何使用Shortcuts将RTF文件转换为Markdown,以帮助nvALT用户迁移到其他应用。提供了详细的使用方法和可能的问题,并鼓励读者参与讨论。

I’ve been working with a former nvALT user who stored all of their files in RTF format. Ideally, people switching from nvALT to another app — be it nvUltra, Obsidian, or anything Markdown-based — would already be storing their notes as individual text files. If nvALT is still working for you, make that change now and give it a chance to write all the new files to disk. However, if the conversion isn’t what you hoped for, or nvALT is no longer working on your machine and you’re stuck with a bunch of RTF files, I’ve pulled together a solution.

Thanks for the assist

A big thanks to those on the forum and some help from Mastodon, especially @atnbueno and @jackwellborn, for helping me get a grasp on some more advanced Shortcuts implementations. The following solution should work with zero extra dependencies, i.e. you don’t have to install Pandoc or anything like that.

Usage

To use the Shortcut, just download below, double click to unzip, and then double click the resulting .shortcut file to add it to the Shortcuts app. Then just run it from the main screen (click the Play icon). It will first ask you for a source folder, at which point you’ll select the folder containing all of the RTF files. You may be presented with some permissions dialogs as it parses and converts the files, mostly around allowing access to web domains. Don’t worry, the Shortcut isn’t actually accessing those domains or sending any information to them. Once the conversion has run, you’ll get another file dialog at which point you’ll create or select an output folder for the Markdown files.

I’ve tested this on a collection of about 500 notes and it works pretty well. There are some things that don’t convert quite right, especially when lists are created in RTF using individual bullet markers. Those aren’t recognized as lists and will not be converted to Markdown lists. They still look correct in the output, though.

Download

nvALT RTF to Markdown Shortcut v1.0.0

A Shortcut to convert a folder of RTF files into Markdown for use in apps like Obsidian or nvUltra.

Published 02/08/24.

Updated 02/08/24. Changelog

DonateMore info…

Give it a shot. If you’re a Shortcuts pro and have suggestions for improving it, let me know. If you’re new to this stuff (like I am) and run into problems, leave a comment or join the forum and let me know. We’ll figure it out together.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-02-08T11:23:00-06:00 Checking for a VPN connection part 2 https://brett.trpstra.net/link/535/16553334/checking-for-a-vpn-connection-part-2 https://brett.trpstra.net/link/535/16553334/checking-for-a-vpn-connection-part-2 scutil, VPN连接, 脚本, grep, 网络接口 VPN连接状态检测的脚本可以通过使用scutil命令和grep来进行。通过检查返回值来确定VPN连接的状态,这个脚本可以让你更清晰地监控VPN的连接情况。总结: scutil命令和grep在脚本中被用来检测VPN连接状态,让你能够更有效地管理网络接口变化。

Ok, so I wrote yesterday about a solution for checking your VPN connection via a network interface change, but it turns out there’s a better way to do it. I discovered it shortly after posting (StackExchange thread), and received a few comments mentioning it. So here’s part two.

The command is scutil, used for managing (s)ystem (c)onfiguration parameters. The command scutil --nc list will show your available VPN devices and their state, either Connected or Disconnected. By doing a case-sensitive grep for Connected we can determine if one or more is connected.

So now the script just look like:

#!/bin/bash

while true; do
  RES=`scutil --nc list | grep -c Connected`
  [[ $RES == 0 ]] && break
  sleep 1
done

say "VPN disconnected"

The scutil --nc list | grep -c Connected should return 0 if no VPN is connected, which you can then use to light up a button, integrate into launch/quit scripts, etc. Just a cleaner way to do what I showed yesterday.

Trevor Manternach has an interesting post using this trick with Wirecast and Bartender.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-30T10:14:00-06:00 Checking for a VPN connection from the command line https://brett.trpstra.net/link/535/16552042/checking-for-a-vpn-connection-from-the-command-line https://brett.trpstra.net/link/535/16552042/checking-for-a-vpn-connection-from-the-command-line ifconfig,VPN连接,shell脚本,Mac,自动化
总结:
本文介绍了如何使用ifconfig和shell脚本来检测VPN连接是否处于活动状态,并在连接断开时终止应用程序。通过查找特定的网络接口来确定VPN连接状态,并使用grep命令来测试连接是否处于活动状态。作者提出了使用循环的Bash脚本来监测VPN连接状态,并在连接断开时执行特定命令。同时,还提到了可以将这些方法应用于自动化工具,如BetterTouchTool。

I got a question from a reader about how to test if a VPN connection is active and terminate an app if it isn’t. There’s probably a way to do this with Keyboard Maestro or BetterTouchTool or something, but to keep things interesting, I wanted to find a way to do it with just shell scripts.

VPN connection indicators

I think the easiest, most universal way to determine if a VPN is connected is by searching for a specific interface that changes when connected. When I connect Nord, for example, I get a new network interface called utun4. I don’t know how universal this is, but you can figure out what changes happen in interfaces by comparing the output of ifconfig when the VPN is connected vs. disconnected.

The following instructions are Mac-specific, using the tools pbcopy and pbpaste to access the system clipboard rather than creating multiple files. In fact, I’m not even positive ifconfig is available on all systems, so if anyone wants to contribute instructions for other platforms, please do.

Caveat: I do not understand the ifconfig command at all and have never used it for anything but listing network interfaces. There may be a far more succinct way to do the following.

To determine the interface changes on a Mac:

In Bash:

# Disconnect VPN
$ ifconfig -a | pbcopy
# Connect VPN
$ diff <(ifconfig -a) <(pbpaste)

In Zsh:

# Disconnect VPN
$ ifconfig -a | pbcopy
# Connect VPN
$ diff =(ifconfig -a) =(pbpaste)

In Fish:

# Disconnect VPN
$ ifconfig -a | pbcopy
# Connect VPN
$ diff (ifconfig -a|psub) (pbpaste|psub)

The result should look something like:

142a143,146
> utun4: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1420
>       options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
>       inet 10.5.0.2 --> 10.5.0.2 netmask 0xffff0000
>       nd6 options=201<PERFORMNUD,DAD>

Testing for connection

Now you have an interface name (utun4 above) that you can grep for to test whether the VPN is active. A simple loop in a Bash script will allow you to take action when the connection is disconnected. This little script assumes the VPN is connected when it starts, loops until the network interface we’re looking for disappears (grep --count returns 0), then executes the command after the loop.

#!/bin/bash

while true; do
  RES=`ifconfig -a | grep -c utun4`
  [[ $RES == 0 ]] && break
  sleep 1
done

say "VPN disconnected"

Perfect if you wanted to, say, stop a torrent client if the VPN wasn’t active. You could embelish it into a launch script that checked for the VPN first, launching an app when the VPN is connected, then polled for the VPN to be disconnected, terminating the app if it is.

Of course, the simple ifconfig -a | grep -c utun4 line could be used as part of a BetterTouchTool widget to display an alert on your Stream Deck when the VPN was connected, or to run any kind of automations on a polling basis. If I had more complex applications for this, I’d switch over to using BetterTouchTool.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-29T13:55:00-06:00 ScreenFloat 2 -- Power up your screenshots [Sponsor] https://brett.trpstra.net/link/535/16547664/screenfloat-2-power-up-your-screenshots-sponsor https://brett.trpstra.net/link/535/16547664/screenfloat-2-power-up-your-screenshots-sponsor ScreenFloat, features, capture, annotations, organization 总结:

ScreenFloat是一个强大的屏幕截图工具,具有多种新功能和工具,包括截图、标注、组织等。它可以让用户轻松地进行屏幕截图、录制屏幕、添加标注和整理截图,非常方便实用。ScreensFloat的新版本提供了诸多升级,能够让用户更加高效地进行屏幕截图和管理。

Thanks to ScreenFloat for sponsoring BrettTerpstra.com this week! I was a frequent user of the original version, and I’m very excited to see version 2 released. It’s chock full of new features and tools that set it apart from the competition.

Hi, my name’s Matthias, I’m the developer of Yoink, Transloader, and Tameno, among others.

Allow me to introduce another one of my apps to you: ScreenFloat. Over eleven years after its initial v1 release, and after more than a year and a half of development, ScreenFloat 2 is finally here — rebuilt from the ground up, based on the core functionality that made it so beloved, but improving it in numerous, incredibly useful ways.

Capture screenshots, record your screen, or take timed screenshots. Re-capture shots without painstakingly reframing them. Import from your clipboard, other apps, your Desktop, or your iOS devices.

Float screenshots and recordings above all your other windows, apps and spaces, so information or reference material is always visible, no matter what you do. It’s like picture-in-picture, but for your captures.

Texts, faces and barcodes are detected in every shot you take and can effortlessly be extracted/copied and non-destructively redacted with a simple right-click.

Mark up and annotate your screenshots with lines, arrows, checkmarks, highlights, smart bullet points, redactions and more. All non-destructively, so you can always go back and make changes or restore the original capture.

Pick colors from any floating shot. Crop, “fold”, resize, rotate, “de-retinize”, trim, and mute your shots.

Sharing floating shots is just a file drag away, with on-the-fly changing of file format and sizing options, whether or not annotations should be included, and more.

Set up double-click workflows for repetitive tasks, like de-retinize the shot, resize it to 75% and then attach it to an email.

Your captures are stored in ScreenFloat’s Shots Browser, where you can name, tag, favorite and rate them, and organize them with folders and smart folders. They can also (optionally) be synchronized across your Macs over iCloud.

Find all your shots system-wide or in the Shots Browser by their metadata — including detected text and barcode content.

And more!

A screenshot is just a screenshot. Until you use ScreenFloat. Check it out today.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-25T08:00:00-06:00 Web Excursions for January 18, 2024 https://brett.trpstra.net/link/535/16539501/web-excursions-for-january-18-2024 https://brett.trpstra.net/link/535/16539501/web-excursions-for-january-18-2024 ScreenFloat, CleanShot X, macOS, Backblaze, keybindings 总结:

本文介绍了Matthias Gansrigler发布的ScreenFloat v2,以及macOS中隐藏的代理图标的显示技巧。另外还推荐了一款可以调查macOS文本系统按键绑定的应用程序。同时还提到了一个有关双相情感障碍生活的纪录片。文章最后介绍了Backblaze,这是一款用于将计算机数据安全备份到云端的工具。

Web excursions brought to you in partnership with Backblaze. Back up everything.

Eternal Storms Software - ScreenFloat
Matthias Gansrigler has released v2 of ScreenFloat, one of my favorite apps from years ago. A lot of its functionality was replaced by CleanShot X for me in recent years, but the shots browser, tagging, and smart folders set it apart. The basic idea is you can float a screenshot above all other windows and it follows you between spaces, but v2 goes a lot further. Check it out.
TipBITS: Always Show Window Proxy Icons
Back in 2020 I published a tip to make the now-hidden proxy icons in macOS show up instantly on rollover, but it turns out that since then Apple has added a preference to just show them all the time. Thanks to Pim for pointing this out.
davidbalbert/KeyBinding-Inspector
An app to survey your macOS text system keybindings. I’ve been writing a lot about editing the DefaultKeyBinding.dict file, and this app makes it easy to peruse what key combinations are doing what. The biggest shortfall is that it doesn’t handle nested bindings (multi-keystroke), but it does successfully ignore those and show you everything else.
Commit Art
Turn your contributions into a tangible piece of art! Mine for 2023 is a documentation of my bipolar type 2 life.

Backblaze securely backs up your entire computer to the cloud, affordably and reliably. I trust it with all my data. Check it out today.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-18T13:44:00-06:00 Screenshots with CurlyQ https://brett.trpstra.net/link/535/16537593/screenshots-with-curlyq https://brett.trpstra.net/link/535/16537593/screenshots-with-curlyq 截图功能, 动态网页, Selenium, CurlyQ, 改进 总结: 本文介绍了CurlyQ工具的新功能和改进。首先是返回结果的格式统一为数组,即使只有一个结果。其次是添加了--query功能,可以使用jq-like语法查询多个项目,进行属性比较等。最后介绍了CurlyQ的截图功能,通过Selenium可以对动态网页进行截图,并提供了详细的命令行参数说明。文章强调了CurlyQ仍在持续改进,并欢迎读者的反馈和建议。

I’ve been putting a little more time into CurlyQ this week, as I’m able.

First thing to note is a breaking change: it will always return an array now, even if there’s only one result. I had waffled on this a little, but for predictability in scripting it really always needs to be a consistent format. So even a single-string result, e.g. a command that targets a single element with --search and then uses .source in the query (which previously would have just returned the source string for the matched tag) will now return an array containing a single string.

Secondly, I’ve put a considerable amount of effort into the --query feature. You can now use jq-like syntax to query multiple items in an array, use dot-syntax for attribute comparisons, and use comparisons (like ^=) on hashes, returning true if any value in the hash matches the query. Still, if you want the full power of something like jq or yq, you can just pipe the output to either and work with more familiar tools.

But on to a cool thing. I mentioned CurlyQ’s screenshot capability in the intro post, but it’s received some improvements, and I thought it deserved a little more detail.

I incorporated Selenium to allow scraping of dynamic web pages. One of the features Selenium provides is screenshots saved from the browser of choice. Thus CurlyQ has a screenshot feature:

curlyq screenshot -b 'firefox' -t 'full' -o 'screenshot_name' URL

The --browser flag (-b) determines whether it uses Chrome or Firefox, and the selected browser must be installed on your system. The full-page capture (-t full) is only available with Firefox. Chrome can only output visible (the visible part of the page on first load) and print, a print version of the page with @media print styling applied. Firefox can output all types.

The --type flag (-t) accepts full, visible, and print. With -t full and -b firefox, you get a full-length version of the rendered page, including offscreen elements. All of these can be abbreviated to their first letter, e.g. -t f or -b c.

The --output flag (-o) is required and determines the path/name of the output file. Providing just a name will save the file to the current directory. Extensions can be provided but will be changed depending on output type, .png for full and visible, .pdf for print. So you can just provide a name without extension and CurlyQ will apply the appropriate extension.

As a side note, saving a screenshot with -t print will output a PDF with actual text that can be searched by Spotlight (and other tools). So you could ostensibly use CurlyQ to crawl an entire site (by parsing the links subcommand output and spidering) and save every page to a searchable PDF. I don’t know offhand why you’d do that, but it’s possible.

CurlyQ is still being refined and your input is welcome. Join me on the Forum, or just message me on Mastodon with suggestions and bug reports.

See the project page for full details.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-17T14:26:00-06:00 Bartender giveaway! https://brett.trpstra.net/link/535/16534736/bartender-giveaway https://brett.trpstra.net/link/535/16534736/bartender-giveaway Bartender, giveaway, macOS, menu bar, workflow

总结: 这篇文章介绍了一次Bartender软件的赠送活动,该软件可以管理Mac的菜单栏,让用户将不经常使用的菜单项移动到次要菜单中,通过快捷键和触发器控制菜单栏项目,提高工作效率。活动将于1月19日抽出10名获奖者,每人获得价值16美元的Bartender软件一份。参与者需要提供名和姓才能参加抽奖。此外,文章还介绍了网站,提到了BrettTerpstra.com受到读者支持,作者也征集下一个赠送活动的建议。

I’m excited to offer the next giveaway, 10 licenses ($16 value each) for Bartender. Bartender tames your Mac menu bar. You can move all the stuff you don’t always need to see into a secondary menu bar, navigate the menu bar(s) with shortcuts, and even control menu bar items like Time Machine, Battery, and Wi-fi.

From the developer:

Bartender is an award-winning app for macOS that superpowers your menu bar, giving you total control over your menu bar items, what’s displayed, and when, with menu bar items only showing when you need them. Bartender improves your workflow with quick reveal, search, custom hotkeys and triggers, and lots more.

Check out the Bartender site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, January 19, at 12pm Central. The drawing is for 10 licenses ($16 value each) for Bartender, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through September, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-15T08:00:00-06:00 The Keyboard Maestro giveaway winner! https://brett.trpstra.net/link/535/16532758/the-keyboard-maestro-giveaway-winner https://brett.trpstra.net/link/535/16532758/the-keyboard-maestro-giveaway-winner Keyboard Maestro, giveaway, winner, discount, automation
这是一篇关于键盘大师软件的赠品活动的文章。文章宣布了赢家的名单,并提供了未中奖者的购买折扣码。同时,还展示了未来几个月的赠品活动清单,并向读者提供了参与和分享的方式。总体来说,这篇文章是在宣传和促销键盘大师软件,吸引读者参与和支持作者的活动。

总结: 键盘大师赠品活动的宣传和促销,赢家名单公布,未中奖者折扣码公布,未来赠品活动清单公布,吸引读者参与。

The Keyboard Maestro giveaway has ended, and I have a winner to announce!

The winners!

Congratulations to:

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Keyboard Maestro is still worth checking out. You can still save 20% off of Keyboard Maestro with the coupon TERPSTRA! The automation possibilities are endless.

Next up is Bartender. Check back every Monday through September, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-12T12:15:00-06:00 Introducing CurlyQ, a pipeline-oriented curl helper https://brett.trpstra.net/link/535/16526283/introducing-curlyq-a-pipeline-oriented-curl-helper https://brett.trpstra.net/link/535/16526283/introducing-curlyq-a-pipeline-oriented-curl-helper 工具, 网页抓取, 元数据, 图像, 功能 这个工具叫做CurlyQ,是一个网页抓取助手,不仅可以获取网页内容,还可以提供元数据、页面图像、页面链接等内容,并且可以处理动态页面和截取截图。它设计成为脚本管道的一部分,可以轻松实现获取页面标题、找到页面上最大的图像或检查并验证页面上的所有链接等功能。CurlyQ还具有多种用户代理字符串配置以及元数据处理功能。它还支持JSON响应处理、页面元素检索以及截图功能。未来版本将支持POST请求功能。如果你对这个工具有任何需求或意见,请在GitHub上的讨论中提出。希望这个工具能成为一个通用的网页抓取工具。

总结: 这个工具叫CurlyQ,是一个网页抓取助手,支持获取网页内容、元数据处理、页面元素检索、截图等功能。希望能成为一个通用的网页抓取工具。

Today I’m releasing an initial version of my latest tool, CurlyQ. It’s a work in progress, though should be immediately useful to those who need it. I need your input on where it goes next, what’s missing, and what you’d like to do with it that it can’t handle yet. Join me in the forum to discuss1!

CurlyQ is a helper for the curl command, with some extra functionality. Sure, it can grab the contents of a web page, but it can also provide a breakdown of all of the metadata, page images, page links, and can work with dynamic pages (where the page is loaded by a JavaScript call and the raw source is empty except for script tags). It will even do screenshots. It’s designed to alleviate some of the chores when scraping web pages or getting JSON responses.

A Scripter’s Tool

CurlyQ is designed to be part of a scripting pipeline, making it as simple as possible to do something like get a page’s title, find the largest image on the page, or examine and validate all the links on a page. You can query the results based on any attribute of the returned tag, showing, for example, only links with a rel=me attribute or a paragraph with a certain class. The tags subcommand can output a hierarchy of all tags on the page, with each parent tag containing a tags key with its immediate children, on down the line. This can be queried and filtered using command line flags.

Failure Prevention

This tool has multiple User Agent strings configured and can accept custom headers. If a request fails, it will try again with various User Agent strings. This is because some sites block pages with certain (or missing) User Agents, and some don’t, so it has a built-in retry. It can also handle pages that respond with gzipped data using --compressed on the command line. If you don’t use --compressed and it detects gzipped data, it will quietly fail and notify you that you need to add the flag. I may make this an automatic fallback in the future. You can also specify a browser as a fallback (Chrome or Firefox), so if regular curling fails or is blocked, it can actually load the page in a web browser and retrieve/process the source from the window.

Retrieving Page Elements

CurlyQ also incorporates Nokogiri, allowing it to perform element selection using CSS selectors or XPaths. For example, the html command accepts --search 'article header h3' to return an array of all h3s contained in a header tag inside an article tag on the page. It can output as JSON or YAML, and for queries that target a specific element or key in the response, you can output raw strings.

There are also tools for extracting content between two strings, returning an array of all matches on the page. The idea is that in cases where you need to extract content that might not be easily located with tags, you can provide before/after strings to extract the necessary information.

Ready, Set, Shoot

CurlyQ can take several types of screenshots: full page (one long PNG), visible page (just the part of the page initially visible in the browser), or the print output, applying @media print stylesheets. It doesn’t currently offer any type of image manipulation, but it might someday at least be able to create miniature versions (thumbnails) automatically.

The screenshot capability works best with Firefox. You can shoot the visible part of pages using Chrome, but to get full-page screenshots, Firefox is required. CurlyQ uses Selenium to load up an instance of the selected browser and grab the rendered source or take a screenshot. The source is fed through the same processor as a regular curl call, so most aspects remain the same. The result is missing response header info, though. CurlyQ does not aim to be a full web automation tool, for that you’ll want to get accustomed to using a headless browser in your scripting language of choice.

JSON Handling

There’s very limited support for handling JSON responses. It currently only handles GET requests and allows you to specify request headers, returning response headers as well as the pretty-printed (optional) results of parsing the JSON, all as one JSON or YAML blob. It’s assumed that you’ll do any handling of the results using something like jq or yq. It can cycle through User Agent strings to find one that works and elegantly return a response code and headers on errors.

What’s Next

One major area that’s missing right now is the ability to make requests other than GET. I would like to add POST capabilities, accepting data from command line flags or just passing it a JSON blob on STDIN or from a file. That’s for the next version, though.

I would greatly appreciate feedback on this tool. If you have a use for something like it, but it doesn’t do quite what you need, please list your use cases and expectations in the Issues on GitHub. I’d love to flesh this out into an all-purpose web scraping tool.

See the CurlyQ project page for more details on installation and usage. I look forward to your feedback (in the forum or on GitHub), positive or negative!

  1. Leaving a comment on this page will automatically create a new forum topic if there isn’t one, or add to an existing topic. 

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-10T10:48:00-06:00 Keyboard Maestro giveaway! https://brett.trpstra.net/link/535/16522882/keyboard-maestro-giveaway https://brett.trpstra.net/link/535/16522882/keyboard-maestro-giveaway Keyboard Maestro, giveaway, automation, Mac, efficiency

总结: 本文介绍了一次Keyboard Maestro软件的抽奖活动,该软件价值36美元,可用于Mac自动化操作。软件可以帮助用户提高效率,无论是高级用户还是初学者都可以从中受益。抽奖活动将在特定日期进行抽奖,参与者需要在特定网站上注册以参与。文章最后还提到了对该系列活动的期待以及作者网站的支持。

I’m excited to offer the next giveaway, a license ($36 value) for Keyboard Maestro. Keyboard Maestro is an insanely powerful app for automation on your Mac that no power user should be without. It can automate literally everything. Power users will love it, but everyday users can greatly benefit from the shortcuts and triggers that Keyboard Maestro offers with a simple drag-and-drop configuration.

From the developer:

Whether you are a power user or just getting started, your time is precious. So don’t waste it. You can quickly benefit from Keyboard Maestro. Let Keyboard Maestro help make your Mac life more pleasant and efficient. With so many possible actions that you can combine together, including flow control, conditions and looping actions, you can automate almost any task, from the trivial to very complex multi-application reporting systems.

Check out the Keyboard Maestro site for more info.

Sign up below to enter. A winner will be randomly drawn on Friday, January 12, at 12pm Central. The drawing is for a license ($36 value) for Keyboard Maestro. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through September, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-08T08:00:00-06:00 The App Tamer giveaway winners! https://brett.trpstra.net/link/535/16520840/the-app-tamer-giveaway-winners https://brett.trpstra.net/link/535/16520840/the-app-tamer-giveaway-winners App Tamer, giveaway, winners, coupon, next giveaway

总结: App Tamer的赠品活动已经结束,获奖者已经公布。恭喜Delaine Taylor和Kevin Cline获奖。未获奖的人可以使用折扣码BRETT-ATM-2023获得20%的优惠。下一个赠品活动将在2024年的9月份举行。同时,网站上还有其他众多精彩的应用程序。读者可以在网站上进行购买支持。

The App Tamer giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Delaine Taylor
  • Kevin Cline

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but App Tamer is still worth checking out. If you want your apps to run faster, it’s a no-brainer. You can still save 20% using the coupon BRETT-ATM-2023 at checkout.

By the way, App Tamer is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is Keyboard Maestro. Check back every Monday through September, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-05T13:00:00-06:00 App Tamer giveaway! https://brett.trpstra.net/link/535/16514852/app-tamer-giveaway https://brett.trpstra.net/link/535/16514852/app-tamer-giveaway App Tamer, giveaway, licenses, control, CPU 总结: 这篇文章介绍了一个App Tamer的赠品活动,价值每个14.95美元的license。这个应用可以帮助控制CPU,并预设了一些应用程序的CPU和电池使用。活动截止日期为1月5日,中午12点。需要提供名和姓才能参加抽奖。如果想要提供自己的应用程序参加赠品,需要联系作者。另外,还可以通过点赞或分享文章来支持作者。

I’m excited to offer the next giveaway, 2 licenses ($14.95 value each) for App Tamer. Got unruly applications? App Tamer helps you take control of your CPU by controlling how much access your apps have to it. Throttle apps that take up too much CPU, speeding up the apps you’re using most.

From the developer:

App Tamer will automatically slow down or pause your applications whenever you’re not using them, greatly reducing their CPU use. App Tamer even comes pre-configured to automatically reduce the CPU and battery usage of Safari, Firefox, Google Chrome, Spotlight, Time Machine, Photoshop, Illustrator, Word and many other applications.

Check out the App Tamer site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, January 05, at 12pm Central. The drawing is for 2 licenses ($14.95 value each) for App Tamer, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through September, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2024-01-01T08:00:00-06:00 JavaScript Lyric embed for SearchLink https://brett.trpstra.net/link/535/16512963/javascript-lyric-embed-for-searchlink https://brett.trpstra.net/link/535/16512963/javascript-lyric-embed-for-searchlink Lyrics plugin, JavaScript, Genius.com, embed, annotations

总结: Lyrics插件现在可以嵌入来自Genius.com的JavaScript版本的歌词,包括注释。通过查询!lyricjs SEARCH STRING来使用。BrettTerpstra.com网站支持这个插件。

Another silly little rabbit hole I’ve gone down… The Lyrics plugin for SearchLink can now embed the JavaScript version of lyrics from Genius.com, complete with annotations.

The query is !lyricjs SEARCH STRING. Running !lyricjs Blood in the Cut K.flay will output this:

<div id='rg_embed_link_2835612' class='rg_embed_link' data-song-id='2835612'>
Read <a href='https://genius.com/Kflay-blood-in-the-cut-lyrics'>K.Flay – Blood in the Cut</a> on Genius
</div>
<script crossorigin src='//genius.com/songs/2835612/embed.js'></script>

Which will render on a live page as:

Note that the embed script uses a cross-origin request and won’t work in your local notes, but will work when published as HTML (to a blog or elsewhere).

The Lyrics plugin is included in the distribution, but also available in the Plugins repository for separate install and examination.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-29T15:00:00-06:00 The Curio giveaway winner! https://brett.trpstra.net/link/535/16512869/the-curio-giveaway-winner https://brett.trpstra.net/link/535/16512869/the-curio-giveaway-winner Curio giveaway, 获奖者, 优惠券, 下一个赠品活动, 应用建议
Curio赠品活动已经结束,获奖者已经公布。获奖者是Alan Mahon。未获奖的人可以使用优惠券TERPSTRA27享受27%的折扣。下一个赠品活动会在每个周一发布。想要建议应用的话可以在社交媒体上联系作者。

The Curio giveaway has ended, and I have a winner to announce!

The winners!

Congratulations to:

  • Alan Mahon

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Curio is still worth checking out. You can still save 27% (in honor of Curio’s 27th release) using the coupon TERPSTRA27. If you brainstorm, manage projects, or just love to research, Curio is a must-have.

Next up is App Tamer. Check back every Monday through September, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-29T12:11:00-06:00 Updated Bitlyize Service https://brett.trpstra.net/link/535/16509323/updated-bitlyize-service https://brett.trpstra.net/link/535/16509323/updated-bitlyize-service Bitlyize, Bit.ly API, shortened links, analytics, Ruby
总结:
这篇文章介绍了对Bitlyize服务进行升级,使其能够与Bit.ly API v4兼容,实现长链接的解析和替换为与您的账户相连的短链接。此外,还介绍了如何获取Bit.ly的token并进行配置、安装Ruby等操作。文章还提到了Bitlyize服务的功能和下载包含的几种服务。同时,作者还提到了如何利用类似Alfred这样的应用进行服务操作,以及对于Amazon和iTunes链接的相关内容。

I hope you’ve had nice holidays!

I’ve updated my Bitlyize service to work with v4 of the Bit.ly API. It parses the input for all URLs and replaces them with shortened links connected to your account. Not only can this make long links more readable, it gives you some analytics on how often the links are used (and deeper analytics like country of origin, referrer, and other data). If you pass it a Bit.ly-shortened link, it will expand it to its original URL.

The downside to shortened links is you can’t tell where they go, which can make them seem a little sketchy. You get to weigh the tradeoffs there. This service makes it easy to expand shortened URLs in place, though.

By the way, shortened links aren’t just obscured for readers and recipients, they’re opaque to future you as well. If you want to use short links for blogging or note taking, I recommend using the !bitly function of SearchLink, which can give you title attributes. It requires separate configuration, but then instead of just a bit.ly link, you can run !bitly ++t Brett Terpstra project searchlink and get [SearchLink](https://bit.ly/47lzuXS "SearchLink"), which is a bit more descriptive. You can also just pass it a long url like [Marked 2.6.18](!bitly https://brettterpstra.com/2023/01/03/marked-2-dot-6-18-with-100-percent-less-jitter/) and get [Marked 2.6.18](https://bit.ly/3ieHDcH "Marked 2.6.18 with 100% less jitter").

These Services require Ruby, which is no longer included with macOS by default. You can get it by installing the Apple Command Line Tools, or see this article for information on installing Ruby with Homebrew/ASDF. You don’t need Rails or anything after the Installing Ruby section in the latter article.

Anyway, download the Service below, double click to install, then set up a configuration file. The file should be located at ~/.config/bitly/config.yaml and only needs two settings:

---
:token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
:domain: 'bit.ly'

To get your token, log into your Bit.ly account. If you don’t have one, you can create a free one. The whole point of using Bit.ly for this is to have trackable links, so you definitely need an associated account. Once logged in, go to https://app.bitly.com/settings/api. You’ll see a field where you can enter your account password (the same one you logged in with), then click Generate Token.

Assuming a correct password, you’ll be presented with a long alphanumeric string. That’s what you’ll copy into the :token: setting in your config file.

The :domain: setting is for users who’ve set up a custom domain. If you haven’t, you can just leave this set to ‘bit.ly’.

Once configured, just select any text containing at least one valid URL, run Services->Bitlyize (either from app menu or by right clicking) and give it a couple seconds to contact the API.

If you’re curious about how I’m running Services these days, as shown in the movie above, that’s an app called Paletro that gives you a command pallete in any app. Available on Setapp.

This Bitlyize Services will swap whatever type of link its passed, so if your text contains both long and short URLs, the long ones will be shortened and the short ones will be lengthened. If your text contains a mix of short and long urls and you want them all to be either shortened or lengthened, use the Shorten or Expand Services individually.

Download

The download includes a few services, Bitlyize and Bitlyize to Clipboard, as well as Bitly Shorten, Bitly Expand and Bitly Preview. The base Bitlyize Service will auto-detect link type and either shorten or expand them. The Clipboard version simply outputs the result to the clipboard rather than trying to paste it, so you can use it on selected text in non-editable fields. The Shorten/Expand versions will only shorten or lengthen, rather than swapping whatever type is detected. The Preview version is designed to run on a single shortened link and show you a preview of the lengthened version for verification/safety before clicking a short link.

If you want quick previews of multiple urls, shortened or long, I recommend my CheckURLs PopClip Extension.

Bitlyize Service v2.0.0

An OS X Service for quickly creating bit.ly short urls

Published 04/30/14.

Updated 12/24/23. Changelog

DonateMore info…

This version no longer adds affiliate codes to Amazon and iTunes links. iTunes doesn’t really pay out anymore, at least for apps, and Amazon has their own URL shortener that I haven’t figured out a way to tap into programmatically yet.

If you’re curious, here’s the script used in all of the Bitly Services. You can modify its utility by changing the function and output settings as shown in the comments.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-26T08:00:00-06:00 Weather forecasts for SearchLink https://brett.trpstra.net/link/535/16508012/weather-forecasts-for-searchlink https://brett.trpstra.net/link/535/16508012/weather-forecasts-for-searchlink Minnesota, Christmas, plugin, weather, SearchLink

总结: 插件开发人员在明尼苏达度过温暖的圣诞节,创建了一个快速插件,用于检索指定地点的天气信息。插件支持通过邮编或城市名和州名来获取当前地点的天气情况。除了当前天气外,还可以显示当天的小时预报。该插件使用了代码以及API密钥,可以展示实时天气数据,并且可以自定义温度显示格式。搜索类型可以用缩写形式,而且该插件的开发过程也展示了SearchLink的可扩展性。

It’s unseasonably warm for Christmas here in Minnesota. It’s 50° out. To mark the weird occasion, I created a quick plugin for SearchLink that lets you run a search like:

!current 55987

And get:

Weather for Winona, Minnesota on 2023-12-25 at 12:53 PM: 51.8 and Light rain

The plugin only outputs ‘embed’ style, it won’t provide a URL for your forecast. It’s just meant to inject actual weather data in your writing.

You can input a zip code or city name and region/state and it will give you the current conditions for that location.

There’s also a version that gives you the hourly forecast for the current day as Markdown table:

!forecast winona, mn

Forecast for Winona, Minnesota on 2023-12-25: Moderate rain 53.7/48.7
Currently: 51.8 and Light rain

8am 10am 12pm 2pm 4pm 6pm 8pm
Overcast Patchy rain possible Light rain Light drizzle Light rain Light rain Light rain
49.1 51.0 51.8 52.0 51.8 51.2 50.8

This uses code from Journal, and isn’t meant to be overly detailed or comprehensive, just an easy way to include the current weather in whatever you happen to be writing. Silly, I know, but I already had most of the code.

To use the plugin, grab the weather.rb file from the GitHub SearchLink Plugins repo and place it in ~/.local/searchlink/plugins/weather.rb. Then you’ll need an API key from https://weatherapi.com. Just sign up for a free account and go to https://www.weatherapi.com/my/. You’ll see your API key at the top. Add that to your ~/.searchlink config file like so:

weather_api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
weather_temp_in: f

Note the weather_temp_in: setting, which can be ‘c’ or ‘f’ to get your temps in your local format. Then just run !current or !weather searches using a zip/city name as the search terms. Enjoy!

The search type can be shortened to 3-4 characters, e.g. !current can just be !cur and !forecast can just be !for or !fore. !weather and !wea also work for current conditions.

This is just another example of how extensible SearchLink is. If you’re interested in creating your own plugins for any kind of search, it’s pretty easy! By the way, I added a couple new classes, Curl::Html and Curl::Json which make it super easy to retrive an HTML or JSON response from a given URL and extract tags/title/data from them. And the SL.ddg() method makes doing Google/DuckDuckGo searches a one-line affair, so anything you want to search for, the tools are there! If you have any questions about using any of these (or about SearchLink in general) feel free to ask them in the forums!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-25T13:10:00-06:00 Curio giveaway! https://brett.trpstra.net/link/535/16507897/curio-giveaway https://brett.trpstra.net/link/535/16507897/curio-giveaway Curio, Pro license, giveaway, BrettTerpstra.com, productivity

这篇文章介绍了一个价值$119的Curio Pro许可证的赠送活动,以及Curio应用的功能和特点。该应用可以帮助用户进行大脑风暴、管理研究、项目和数字生活,并包括多个人工智能集成,帮助用户提高生产力。活动要求参与者在BrettTerpstra.com上注册,且需要提供名和姓以便生成许可码。文章同时提到了BrettTerpstra.com的其他相关活动和赞助。整体而言,这是一篇介绍赠品活动的文章,同时也是对Curio应用功能的简要介绍。

总结: 文章介绍了Curio Pro许可证的赠送活动,以及Curio应用的功能和特点,包括对活动的要求和相关赞助信息。

🎄 Merry Christmas! I’m excited to offer the next giveaway, a Pro license ($119 value) for Curio. Curio is the perfect app for managing your brainstorms, your research, your projects, and your digital life. A Curio “space” is a blank canvas on which you can add notes, web pages, pdfs, images, mind maps, outlines, and more. All searchable and linkable, and even shareable. Version 27 is freshly out and ready to take it to the next level. It even includes multiple AI integrations to assist with research.

From the developer:

Take notes. Organize files. Collect research. Brainstorm in mind maps. Track tasks with to-do lists or Kanban stacks. Drop in an equation. Sketch out an idea. Get more productive! Curio’s intuitive, freeform notebook environment provides all the integrated tools you need to be more productive and focus on getting things done.

Check out the Curio site for more info.

Sign up below to enter. A winner will be randomly drawn on Friday, December 29, at 12pm Central. The drawing is for a Pro license ($119 value) for Curio. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through September, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-25T08:00:00-06:00 A few Ruby snippets for scripters https://brett.trpstra.net/link/535/16506834/a-few-ruby-snippets-for-scripters https://brett.trpstra.net/link/535/16506834/a-few-ruby-snippets-for-scripters 关键词: Ruby, macOS, 转码, 数字舍入, URL 编码 总结:

这篇文章介绍了使用Ruby进行自动化和字符串操作脚本的技巧,包括转码、检查macOS、获取macOS版本、数字舍入、人类可读的文件大小、URL 编码等。这些技巧对于想要成为Ruby脚本程序员的人非常有用。还分享了一个剪贴板预览的壳函数,方便在任何shell中使用。

I do most of my automation and string manipulation scripting using Ruby. I know it’s not the most popular language these days, but it’s the one I know the best (thanks to my days of hacking on TextMate bundles) and it’s usually the fastest way for me to solve a problem. I have reams of snippets saved (and easily accessible with Snibbets) and thought I’d share a few that are useful for everyday scripting on macOS.

Scrub

Scrub uses the encode function to switch a string to UTF-16 discarding invalid characters (gremlins), then back to UTF-8. Applied as a String method, you can then use input.scrub to get clean text with all gremlins removed.

class ::String
  def scrub
    encode('utf-16', invalid: :replace).encode('utf-8')
  end

  def scrub!
    replace scrub
  end
end

Check for macOS

This can be modified or turned into a case statement to determine operating system. I often only need it to check if I can run Mac-only tools like pbcopy or not.

`uname`.strip == "Darwin"

Get macOS version

Just in case your script needs to behave differently across OS versions:

def macos_version
  begin
    `sw_vers`.strip.each_line do |line|
      if line.strip =~ /ProductVersion:\s+([\d.]+)$/
        return Regexp.last_match(1).to_f
      end
    end
    return 0
  rescue
    warn 'Failed to retrieve macOS version'
    Process.exit 1
  end
end

Rounding numbers

class ::Numeric
  # Round to nearest 5
  def round5
    ((self * 0.2).round / 0.2)
  end

  # Round to nearest 10
  def round10
    ((self * 0.1).round / 0.1)
  end
end

Human-readable file size

The #to_human method will convert 293592035 to “280MB”.

class Numeric
    def to_human
        units = %w{B KB MB GB TB}
        e = (Math.log(self)/Math.log(1024)).floor
        s = "%.1f" % (to_f / 1024**e)
        s.sub(/\.?0*$/, units[e])
    end
end

print File.size(File.expand_path(ARGV[0])).to_human

URL encoding

I used to use the CGI library for url encoding, but it doesn’t properly percent-encode spaces as %20, but rather as +, which breaks a lot of applications. The solution (as opposed to doing a manual search and replace) is to use the ERB library instead:

require 'erb'
ERB::Util.url_encode('string to encode')

Get a single keypress

For dialogs where you want to act as soon as a key is pressed without requiring pressing Return:

def get_keypress
    system "stty raw -echo"
    STDIN.getc
ensure
    system "stty -raw echo"
end
    
key = get_keypress.chr

Get the longest string in an array of strings

Of limited utility but I use it all the time when doing search algorithms:

class ::Array
  def longest_element
    group_by(&:size).max.last[0]
    # Leave off the [0] to get an array containing all of the longest elements when there's a tie
  end
end

p ['short', 'longest', 'longer'].longest_element
#=> "longest"

Symbolize hash keys

If you’re creating nested hash objects that end up with a mix of string and symbol keys, the easiest thing to do is symbolize all keys. #to_sym won’t do anything if the key is already a symbol.

class ::Hash
  # Turn all keys into symbols, including nested hashes
  def symbolize_keys
    each_with_object({}) { |(k, v), hsh| hsh[k.to_sym] = v.is_a?(Hash) ? v.symbolize_keys : v }
  end
end

# >> h = {'one' => 2, 'two' => { 'three' => 4 } }
# >> h.symbolize_keys
# {
#   :one => 2,
#   :two => {
#     :three => 4
#   }
# }

I hope that’s useful for aspiring Ruby scripters. If there’s interest, I can post (tons) more, but I also hope to get better about creating Gists that could be more easily searchable as a reference. The next step for Snibbets?

Bonus tip: Clipboard Preview

There’s a shell function I use frequently, easily replicable in any shell. It just shows you the contents of your clipboard (assuming text) without requiring a paste:

pbpaste | cat

In Fish that looks like:

# Defined in /Users/ttscoff/.config/fish/functions/cbp.fish @ line 1
function cbp --description 'ClipBoard Preview'
  pbpaste | cat
end

Like I said, useful in any shell as a way to ensure what you think is on your clipboard actually is. Just type cbp and get a preview before pasting anywhere.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-23T11:51:00-06:00 The Kaleidoscope giveaway winner! https://brett.trpstra.net/link/535/16506266/the-kaleidoscope-giveaway-winner https://brett.trpstra.net/link/535/16506266/the-kaleidoscope-giveaway-winner Kaleidoscope, winner, giveaway, coupon, September

Kaleidoscope举办的赠品活动已经结束了,获奖者是Ken Bavier。未中奖的人可以使用TERPSTRA优惠券节省订阅费用,下一个赠品活动将在2024年9月每周一举行,读者可以在社交媒体上关注BrettTerpstra.com获取更多信息。

The Kaleidoscope giveaway has ended, and I have a winner to announce!

The winners!

Congratulations to Ken Bavier!

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Kaleidoscope is still worth checking out. You can still save 20% on your subscription with the coupon TERPSTRA! If you work with text or images (especially code), you’ll love it. It’s the best diff app out there, and worth every penny.

Next up is Curio. Check back every Monday through September, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-22T12:03:00-06:00 Multi-keystroke keybindings https://brett.trpstra.net/link/535/16506205/multi-keystroke-keybindings https://brett.trpstra.net/link/535/16506205/multi-keystroke-keybindings 键绑定,多重按键组合,PLIST,Markdown,快捷键

总结: 本文介绍了如何利用多重按键组合来创建自定义的键绑定。作者使用了PLIST文件来定义不同的键绑定,并且可以进行多级嵌套,使得可以创建具有逻辑和记忆性的键盘快捷键。这种方法可以大大扩展可用的快捷键组合,同时也提高了使用效率。文章还提到了Markdown命令的多级嵌套例子,进一步展示了这种方法的灵活性和实用性。建议读者可以查阅作者的博客以获得更多灵感。

Ok, this one will probably wrap up this little run of key binding tricks. It’s been fun, though, and I’d love to answer any questions I can in the forum.

If you’ve ever examined my master DefaultKeyBinding.dict (or even looked at the readme), you’ll see that I make use of a lot of multi-stroke key combos. There are only so many key combinations available, and you’re bound to run out of ones that don’t conflict with other shortcuts on your system. But with the magic of multi-stroke bindings, you can take one available shortcut and add secondary “child” shortcuts with the whole keyboard available for assignment again.

For example, the SearchLink bindings I use start with G. So I press that, then I can type a single letter to determine what type of SearchLink syntax gets inserted, e.g. G followed by M inserts an IMDB search.

To create a mutli-stroke binding, you just nest a PLIST inside of the root PLIST, keyed off the initial key combination:

{
"^@g" = { // SearchLink commands
    // IMDB Search
    "m" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](!imdb)", moveRight:, deleteBackward:, moveLeft:);
 };
}

Going Deeper

You can actually continue nesting, creating three-or-more -stroke sequences, though I don’t know how many of those I could keep track of. Mnemonics do make it easy, though. I use a three-deep setting for my Markdown link insertions, where I type W (the container for most of my Markdown commands, a throwback to the Blogsmith Bundle for TextMate), then L (for link), then either C (to paste from clipboard), or T to insert just the brackets with https:// selected in the url.

{
  "^@w" = { // Multi-stroke Markdown commands
    "l" = { // Markdown link
      // create a link for selected text, cursor between () `[selected text]([cursor])`
      "t" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "]()", moveRight:, deleteBackward:, moveLeft:, setMark:, insertText:, "https://", selectToMark:); // link text
      // create a link for selected text, inserting clipboard as url `[[cursor]selected text](clipboard contents)`
      "c" = (setMark:, moveRight:, insertText:, " ", deleteToMark:, insertText:, " [", moveLeft:, deleteBackward:, moveRight:, yank:, moveLeft:, insertText:, "](", setMark:, pasteAsPlainText:, insertText:, ")", moveRight:, deleteBackward:, moveLeft:, selectToMark:); // link with clipboard
    };
  };
}

These sequences open up pretty much limitless possibilities for memorably (mnemonic) keyboard shortcuts. You create a logical grouping on an open shortcut, and then assign single letters that are meaningful and easy to remember in context. These nested keystrokes can also use modifier keys, but I like the fact that once I’m inside of the main grouping, I only need single letters and not weird key combinations.

As always, check out the KeyBindings project for more inspiration. Have fun!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-22T10:54:00-06:00 More keybindings: Text editing shortcuts https://brett.trpstra.net/link/535/16505229/more-keybindings-text-editing-shortcuts https://brett.trpstra.net/link/535/16505229/more-keybindings-text-editing-shortcuts Text editing shortcuts, DefaultKeyBinding.dict, ⌘⏎, moving lines, Danish Cocoa文本字段在Mac上的兼容性问题;⌘⏎命令在任何Cocoa文本字段上都可以使用,可以用于快速插入空行,但需要注意与应用程序的特殊功能冲突问题;对默认的⌥O进行了重新绑定,以及如何在文本文档中编辑这些绑定;如何在文本中移动当前行并进行缩进;提到了在丹麦、挪威、法罗群岛和南萨米语中会存在特殊字符的输入问题。

总结: 这篇文章主要介绍了在Mac上使用DefaultKeyBinding.dict文件对文本编辑快捷键进行重新绑定的方法,以及如何移动行和缩进文本。同时也提到了在丹麦、挪威、法罗群岛和南萨米语中输入特殊字符的问题。

I guess it’s keybinding week this week. I’ve talked about the kill ring and repeat binding, but I’ve been digging in and revamping my own DefaultKeyBinding.dict file, so I keep wanting to share some of the cooler things it can do because I know the file in the project is pretty massive and hard to parse.

There are a ton of text editing shortcuts in my bindings (that’s basically their sole purpose), but I wanted to highlight just a few that I use so often I don’t even think about it.

TextMate Command-Return

First, . TextMate was the first place I ever saw this, but now it’s pretty standard in most text editors, from Byword to nvUltra, VS Code to Sublime. When you hit , it moves your cursor to the end of the current line/paragraph and inserts a new line, no matter where you are in the paragraph. And will do the same but before the current line/paragraph. It allows you to be editing in the middle of a graf, then just hit to start typing again, saving use of the mouse or arrow keys to get to the new insertion point.

This keybinding will work in any Cocoa text field on your Mac, so it’s no longer limited to your favorite coding app. It works in TextEdit, Mail, Pages (but not Word), and in apps like Bear, Day One, or NotePlan. Just about anywhere that uses native text fields.

The first version I’ll show you is the most universal. The reason for this is that is frequently used by apps for special purposes, and the app’s keybindings will override your system-wide keybindings. So having a less-common shortcut makes this more available. I actually include both versions in my .dict file, and when I’m in an app that overrides , I just switch to using this version.

I use O for these, but note that doing so will mean you can’t just type the slashed-O symbol (Ø) anymore1. If you never type that symbol, then you’re fine, but if you do use it, you might want to consider a different shortcut.

To use any of the examples in this post, you’ll just add them to ~/Library/KeyBindings/DefaultKeyBinding.dict, a directory and text file you can create if it doesn’t exist. The examples include the outer curly brackets, but if you’re adding to an existing set of keybindings, only copy the portion inside of the curly brackets and place it within the existing outer curly brackets in your file.

If you’re combining multiple examples from this post, you only want one set of curly brackets at the root, and then the contents can be appended within those curly brackets.

Here are the bindings using O as the shortcut:

{
// blank line after current (Option-O)
"~o" = (moveToEndOfParagraph:, insertNewline:);
// blank line before current (Option-Shift-O)
"~O" = (moveToBeginningOfParagraph:, moveLeft:, insertNewline:);
}

And here are the same bindings using :

{
// TextMate Command-Return (Command Return)
"@\U000D" = (moveToEndOfParagraph:, insertNewline:);
// Insert blank line above paragraph (Command Shift Return)
"@$\U000D" = (moveToBeginningOfParagraph:, moveLeft:, insertNewline:);
}

Remember that any time you edit the DefaultKeyBinding.dict file, you have to restart open apps for the new bindings to be recognized.

Moving lines around

This is another binding that’s quite common in more advanced editors: the ability to move the current line up or down, and to increase/decrease indentation. In Sublime Text these are bound to -Arrow keys. I use the Sublime bindings in VS Code, so I’m not sure what they are there by default. But It’s so nice to have these in any app, you can bind them to whatever shortcuts make sense to you. They won’t override the native bindings in your favorite apps, so you can duplicate whatever you use most.

With these installed, you can be anywhere in a paragraph and move the entire graf up and down, and back and forth. In keybinding terminology, a paragraph is any text that has a line break or BOF at its start, and ends in a line break. So in a Markdown unordered list, each list item is a paragraph.

{
// > Line motion with arrow keys
// move line up (Control-Command-Up Arrow)
"^@\UF700" = (selectParagraph:, setMark:, deleteToMark:, moveLeft:, moveToBeginningOfParagraph:, yank:, moveLeft:, selectToMark:, moveLeft:);
// move line down (Control-Command-Down Arrow)
"^@\UF701" = (selectParagraph:, setMark:, deleteToMark:, moveToEndOfParagraph:, moveRight:, setMark:, yank:, moveLeft:, selectToMark:);
// indent line (Control-Command-Right Arrow)
"^@\UF703" = (setMark:, moveToBeginningOfParagraph:, insertText:, "\t", swapWithMark:, moveRight:);
// outdent line (one tab or char) (Control-Command-Left Arrow)
"^@\UF702" = (setMark:, moveToBeginningOfParagraph:, moveRight:, deleteBackward:, swapWithMark:, moveLeft:);
}

In case you were wondering, the list items in the animation were generated using the Increment Templated service.

Note that these bindings aren’t very smart or context-aware. If you try to outdent a paragraph that’s already at the left border, it will instead remove the first character. And it doesn’t respect newlines between paragraphs very well, so if you have three paragraphs with newlines between them, and then attempt to move the last one to the second spot, you’ll need to add back the newline after moving. Which is where the TextMate bindings above come in super handy.

They also use a tab for indentation, which works great for outdenting lines that are indented with tabs. If, however, the indentation is spaces, the outdent binding will only delete one space at a time.

If you’re already used to Vim keybindings, you may want to try the same setup using hjkl. I’ve found that these combinations conflict with a few different apps’ global shortcuts on my own system, but your mileage may vary. The arrow key version works everywhere for me, so this is just an example of alternative bindings.

{
// move line up
"^@k" = (selectParagraph:, setMark:, deleteToMark:, moveLeft:, moveToBeginningOfParagraph:, yank:, moveLeft:, selectToMark:, moveLeft:);
// move line down
"^@j" = (selectParagraph:, setMark:, deleteToMark:, moveToEndOfParagraph:, moveRight:, setMark:, yank:, moveLeft:, selectToMark:);
// indent line
"^@l" = (setMark:, moveToBeginningOfParagraph:, insertText:, "\t", swapWithMark:, moveRight:);
// outdent line (one tab or char)
"^@h" = (setMark:, moveToBeginningOfParagraph:, moveRight:, deleteBackward:, swapWithMark:, moveLeft:);
}

Check out the KeyBindings project for more!

  1. This will likely only be a problem for people writing in Danish, Norwegion, Faroese, or Southern Sámi languages. 

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-21T15:57:00-06:00 HoudahSpot: Powerful file search -- skip filing, start finding [Sponsor] https://brett.trpstra.net/link/535/16504780/houdahspot-powerful-file-search-skip-filing-start-finding-sponsor https://brett.trpstra.net/link/535/16504780/houdahspot-powerful-file-search-skip-filing-start-finding-sponsor 关键词: HoudahSpot, 搜索文件, macOS, 提高效率, 优惠码 总结: HoudahSpot 是一款强大的 Mac 文件搜索工具,比 Spotlight 更为高级,可以快速方便地搜索文件并进行管理。通过使用 HoudahSpot,用户可以根据文件名、文本内容、类型和日期等元数据进行搜索,并通过拖拽文件来优化搜索条件。此外,HoudahSpot 还提供了优惠码 TERPSTRA2023,可以享受 30% 的折扣。这款工具可以帮助用户提高搜索文件的效率,节省时间提高工作效率。

Thanks to HoudahSpot for sponsoring BrettTerpstra.com this week! I’ve been using it for years and swear by it as a way to find files that Spotlight can’t, quickly and easily.

HoudahSpot is a powerful tool for finding and managing files on your Mac, with features beyond Spotlight.

Have you shifted — by choice or by default — from organizing files in folder hierarchies to searching as your method of “filing?” You already appreciate the value of fast searches using macOS Spotlight. HoudahSpot is the next-level solution that fills the gaps in Spotlight’s functionality.

Are you tired of wasting your time searching for files on your Mac? When Spotlight falls short, HoudahSpot takes productivity to a new level. To put it bluntly, HoudahSpot is like steroids for Spotlight on macOS.

Think of HoudahSpot as an advanced, productivity-oriented version of Spotlight:

  • Search for files using by name, text content, kind, date, and other metadata
  • Start and refine searches with just a few clicks
  • Combine any number of criteria to narrow down the list of results
  • Sort search results and assess relevance by author, image resolution, video length, etc.
  • Preview file content and text matches in context
  • Customize default search criteria, search locations, columns, and sort order to fit your workflow

HoudahSpot Tip: Find Files “By Example”

If you have found a file with similar properties to the files you need, you can use it to refine your search. Just drag that example file to the search pane to update the search criteria. For instance, suppose you are looking for the master file – a Photoshop, Affinity Designer, or similar file – used to create a JPEG image uploaded to your website. Chances are that both the master file and the final JPEG were last modified on the same date. Drag the JPEG to a “Modified” criterion in HoudahSpot’s search pane. Search criteria will update and limit search results to files modified on the same day as the JPEG.

Of course, the same idea works to prune excess results from your search results: Remove files that share a property with a file you know not to be relevant. You can, for example, drag the folder containing one of the search results to the location exclusion list. Your search results will no longer include files from the folder you deem irrelevant.

HoudahSpot is free to try. If you make use of search in your daily computer usage, try HoudahSpot today! Use the coupon code TERPSTRA2023 for a 30% discount on single user and on family licenses through December 31.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-21T08:00:00-06:00 macOS keybinding tricks: the repeat count binding https://brett.trpstra.net/link/535/16502539/macos-keybinding-tricks-the-repeat-count-binding https://brett.trpstra.net/link/535/16502539/macos-keybinding-tricks-the-repeat-count-binding Vim, macOS, 快捷键, 重复操作, 文本编辑器
总结:
本文介绍了在macOS上利用快捷键来实现重复操作的技巧。通过设置特定的快捷键,用户可以在文本编辑器中使用数字来指定重复次数,从而提高编辑效率。同时,作者还分享了一些使用这一技巧的场景,以及一些注意事项。

Another trick for readers interested in honing their keyboard-fu on macOS.

In Vim, most operations have can have a count specified in the keystrokes for the command, e.g. 3dd to delete 3 lines. You can do similar in any Cocoa text field (all Apple apps, plus most native apps). You just need to specify a keyboard shortcut to use before the count. Then you can hit that keyboard shortcut, type a number (X) and then hit a key or key combination to have that event repeated X times.

To set the repeat shortcut:

defaults write -g NSRepeatCountBinding -string "~r"

The above would set the repeat binding to R. Use the following shortcuts when defining the operator, being sure not to overwrite a keyboard shortcut you use elsewhere (control-option combinations are pretty safe):

Symbol Modifier
~ Option
@ Command
^ Control
$ Shift

You can use any combination of symbols when defining your shortcut. I like R (~r) because it has no conflicts that I know of and is easily reachable with my left hand. Also there’s a mnemonic quality with “r” for “repeat.” Choose whatever you like.

Once the above defaults command is run, relaunch whatever app you want to test it in. It will work in TextEdit, nvUltra, Bear, Pages… most apps that you would use on your Mac. But a restart of the app will be required for the new bindings to be recognized.

Now, type your selected shortcut (R if you didn’t change it), then type a number (any number of digits), then type “x”. If you typed <SHORTCUT>10x, you should get xxxxxxxxxx. This works with both character insertions and movement keys and text operations. For example, if you type <SHORTCUT>5 and then hit , it would delete backwards 5 words. Each step of the repeat process is stored in the undo buffer, so undoing it would require five Zs. This is actually a feature, because if you’re estimating how many words back to delete but guess wrong, you can undo a couple to restore them individually.

One niche example use for this is when you want to insert a redacted password or API key when you’re writing. You know the length of the password or key should be 20 characters, so you just type R20x and get a string of x’s of the appropriate length. Or if you want to select the previous 3 words in the current line, just type R3. Much like Vim, it takes a second of thought to figure out how many times you want to repeat an action, and in some cases it’s faster to just hit the key that number of times. But give it a go and make a conscious effort to use it for a while, I bet it will stick.

Weirdly this trick doesn’t work for V, which is disappointing because one very common use I could see for it would be to copy something and then paste it X number of times. I can’t explain why that doesn’t work.

Hope that leads to some fun/increased productivity for folks willing to try it. If you have any favorite keyboard tricks, please feel free to share in the comments!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-19T15:12:00-06:00 macOS keybinding tricks: The kill ring https://brett.trpstra.net/link/535/16501154/macos-keybinding-tricks-the-kill-ring https://brett.trpstra.net/link/535/16501154/macos-keybinding-tricks-the-kill-ring Keybinding, macOS, Emacs, Clipboard manager, Terminal 总结:

本文介绍了如何在macOS中使用键盘绑定技巧来增强文本编辑功能,包括使用Emacs风格的快捷键和创建剪贴板管理器。作者提到了如何在终端中创建一个“kill ring”来存储剪切的文本,然后通过编辑默认键绑定文件来创建新的功能。最后,作者建议读者在BrettTerpstra.com上查看更多相关内容。

So you may have seen my KeyBindings project before. It’s an insanely large collection of keybinding tricks that work in any macOS text field. Well, any native cocoa field. You won’t have much luck in Electron or other non-native text editors. But for most uses, including in Safari, Mail, Notes, nvUltra, and most of the Markdown editors, the tricks work great. You can do things like adding TextMate-style to any editor to create a new line no matter where your caret1 (cursor) is in the line.

I’ve written a bit about all of this before (and see the KeyBinding series), but I’ll recap the basics for this tip, since it’s been a while. To wit, you can create a (plain text) file located at ~/Library/KeyBindings/DefaultKeyBinding.dict that tells every macOS app what to do when you hit certain keys, and you can override all kinds of defaults and add new functionality by editing it. If that file already exists, you can just add to it. I’ll offer more details when we get to that part of the trick.

Emacs Keybindings

You already have emacs-style shortcuts available, including K to delete (kill) to end of line, U to delete to beginning of line, and Y to paste (yank) text that was cut using either of the kill commands. You can delete an entire line by hitting A (go to beginning of line) and then K, then paste that line somewhere else with Y. Try it. You don’t have to do anything to enable this, it’s always been built into macOS. I think it also works on iOS, but I don’t have an external keyboard hooked up to test it out with right now. Let me know in the comments.

Bonus tip: T will transpose the characters to the left and right of the caret, allowing you to easily change frutive to furtive with one keystroke.

So this tip is a way to make this cut/paste process more useful. You’ve probably used (or at least seen) clipboard managers before. I use LaunchBar for this, but there are plenty of apps like Paste that can do it. Basically every time you cut or copy something, it gets added to a list in your clipboard manager, allowing you to paste anything you’ve copied elsewhere, rather than just the last thing you copied. I wouldn’t want to function without one. Those apps don’t work with the kill commands, though. So here’s what you can do instead.

Create the Kill Ring

First, run this command in Terminal:

defaults write -g NSTextKillRingSize -int 6

That creates a “kill ring” with 6 slots. Every time you cut, the text will be stored in the next available slot, cycling back to the beginning when the 6 slots are full. You can make that number anything you want, but be aware that to use items stored in the kill ring, you’ll have to cycle through them until you get to the one you want, and empty slots will still have to be cycled through. Which generally would mean pasting them all in a row, which is where the next part of the trick comes in.

Edit the Keybindings

  1. If you already have a file at ~/Library/KeyBindings/DefaultKeyBinding.dict, open it in a text editor and add the keybinding inside of the main curly brackets that already exist in the file. If you don’t have that file, create a new, empty text file in your text editor of choice.
  2. If you’re working with an empty file, first insert a pair of curly brackets before inserting the text below. If you already have an existing DefaultKeyBinding.dict file, then just add the following between the existing parent curly brackets:

    "^y" = (yankAndSelect:);
  3. Save the file (as ~/Library/KeyBindings/DefaultKeyBinding.dict if it’s new).
  4. Running apps will need to be restarted to recognize the new keybindings.

In this circumstance, “yank” means “paste” from the register, as opposed to the Vim vernacular where it means “copy” (which makes more sense 🤷🏻‍♂️). So now, pressing Y (“^y”) will paste the next item from the kill ring, and immediately select it (yankAndSelect:), so pressing Y again will overwrite what you just pasted with the next item in the kill ring. If there are registers in the kill ring that haven’t been filled yet, it will paste an empty string, but you can just keep hitting Y to cycle back around to where your populated registers are.

Note: The kill ring is shared between documents in the same app, but generally not between apps.

To try it out, restart your text editor (if it was running when you changed the DefaultKeyBinding.dict file) and write several lines of text in a text field:

this is line 1
this is line 2
this is line 3
this is line 4

Put your caret at the beginning of each line and press K, once for each line (use arrow keys and A to get to each line start). Then, put your caret anywhere and type Y repeatedly. You should see your cut lines pasted and replaced in place. Note that these commands do register in the undo buffer, so if you cycle past the one you wanted, you can usually use Z to go backwards through the list. The kill ring is LIFO, so you’ll get your results in the reverse order you added them to the ring.

Have fun! If that was interesting to you, be sure to check out the rest of the KeyBindings project.

  1. I’ll be referring to the text insertion point as a caret in this post, just because I’m feeling pedantic today. 

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-18T13:57:00-06:00 Kaleidoscope giveaway! https://brett.trpstra.net/link/535/16500870/kaleidoscope-giveaway https://brett.trpstra.net/link/535/16500870/kaleidoscope-giveaway 订阅, 赠品, 软件, 抽奖, 配合

总结: Brett Terpstra网站举办了一次Kaleidoscope软件一年订阅(价值96美元)的赠品活动,该软件是macOS上最强大的文件比对和合并工具,能够快速找出文本和图像文件以及整个文件夹中的差异。参与者需要在指定日期前填写姓名并在Brett Terpstra网站上进行报名,以参与抽奖。同时,Brett Terpstra还提到了推广这个活动的方式,以及他网站的赞助商和相关内容。

I’m excited to offer the next giveaway, a 1-year subscription ($96 value) for Kaleidoscope. There is no better program for diffing on macOS. From code to prose to images, see what changed with fine granularity. Plus great new Git integration!

From the developer:

Spot the differences in text and image files, or even folders full of files. Review changes in seconds, with the world’s most powerful file comparison and merge app.

Check out the Kaleidoscope site for more info.

Sign up below to enter. A winner will be randomly drawn on Friday, December 22, at 12pm Central. The drawing is for a 1-year subscription ($96 value) for Kaleidoscope. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through September, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-18T08:00:00-06:00 Ruby Regexp::scan with MatchData https://brett.trpstra.net/link/535/16498512/ruby-regexp-scan-with-matchdata https://brett.trpstra.net/link/535/16498512/ruby-regexp-scan-with-matchdata 关键词: Ruby, 字符串处理, 正则表达式, 匹配, 方法 Ruby编程语言中有许多字符串处理方法,通过正则表达式进行匹配和扫描是常见的操作。作者在文章中分享了如何通过组合使用match_scan和matches方法,将正则表达式匹配的结果转换成包含各项值的哈希数组。这种方法可以方便地从字符串中提取想要的数据,极大地简化了字符串处理的复杂度。这对于正在学习Ruby脚本编写的初学者来说是非常有用的技巧。

总结: Ruby编程中的字符串处理和正则表达式匹配可以通过match_scan和matches方法简化,让数据提取更加方便和灵活。

This post will only be of interest to people writing scripts in Ruby. Seriously, zero utility if you’re not using Ruby. Though I would be curious how you accomplish the same thing in other languages like Rust and Python, because I’ve never gotten too deep with string manipulation in anything other than Ruby, Swift, and Objective-C. If you care to leave a comment with pointers, I’m all ears.

I do a lot of string manipulation in Ruby. One of the things that always gets me is that the Regexp::match method returns groups but only matches the first instance. To match all instances for enumeration, you have to use Regexp::scan. But scan doesn’t include groups (i.e. MatchData). So a while back I figured out the solution, and I thought I’d share it for any aspiring Ruby scripters.

The trick is to map scan results and replace each result with Regexp::last_match, which includes groups (and named groups) from the last regex that was run. Thus:

str.to_enum(:scan, regex).map { Regexp.last_match }

results in an array of MatchData. Then you can iterate through it and use indexes or group names to pull out particular groups of each match.

I’ve combined this with a few other methods to create a general string handling routine that I use regularly.

# frozen_string_literal: true

# String helpers
class ::String
  def match_scan(regex)
    to_enum(:scan, regex).map { Regexp.last_match }
  end

  def matches(regex)
    match_scan(regex).match_to_h.map(&:symbolize_keys)
  end
end

# Array helpers
class ::Array
  def match_to_h
    map { |m| m.named_captures.each_with_object({}) { |(k, v), h| h[k] = v&.strip } }
  end
end

# Hash helpers
class ::Hash
  def symbolize_keys
    each_with_object({}) { |(k, v), hsh| hsh[k.to_sym] = v.is_a?(Hash) ? v.symbolize_keys : v }
  end
end

With the above methods available, you can do something like:

str = <<~EOEMAILS
  Arthur P. Dent <arthur@example.com>
  Ford Prefect <perfect@example.com>
  Zaphod Beeblebrox <zaph@example.com>
  Mrs. Alice Beeblebrox <zaphsfav@example.com>
  Slartibartfast <fjordmaster@example.com>
  Marvin the Paranoid Android <planetbrain@example.com>
EOEMAILS

rx = /(?<prefix>\S+\. )?(?<first>.*?)(?:( (?<middle>\w+\.?))*(?: (?<last>[\w-]+)))? <(?<email>.*?)>/i

pp str.matches(rx)

Running that results in:

[{:prefix=>nil,
  :first=>"Arthur",
  :middle=>"P.",
  :last=>"Dent",
  :email=>"arthur@example.com"},
 {:prefix=>nil,
  :first=>"Ford",
  :middle=>nil,
  :last=>"Prefect",
  :email=>"perfect@example.com"},
 {:prefix=>nil,
  :first=>"Zaphod",
  :middle=>nil,
  :last=>"Beeblebrox",
  :email=>"zaph@example.com"},
 {:prefix=>"Mrs.",
  :first=>"Alice",
  :middle=>nil,
  :last=>"Beeblebrox",
  :email=>"zaphsfav@example.com"},
 {:prefix=>nil,
  :first=>"Slartibartfast",
  :middle=>nil,
  :last=>nil,
  :email=>"fjordmaster@example.com"},
 {:prefix=>nil,
  :first=>"Marvin",
  :middle=>"Paranoid",
  :last=>"Android",
  :email=>"planetbrain@example.com"}]

That’s a silly example, but hopefully you can see the utility of turning a regular expression into an array of hashes containing the individual values of each match extracted by scanning the string.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-17T15:38:00-06:00 The SpamSieve giveaway winners! https://brett.trpstra.net/link/535/16497258/the-spamsieve-giveaway-winners https://brett.trpstra.net/link/535/16497258/the-spamsieve-giveaway-winners 赢家, 电子邮件, 优惠码, 应用程序, 赞助 赢家: Garrett Coakley和Daniel Matz是本次抽奖活动的赢家。 电子邮件: 获胜者应该已经收到了包含详细信息的电子邮件。 优惠码: 如果没有赢得奖品,可以使用优惠码TERPSTRA2023享受20%的购买折扣。 应用程序: 下次的抽奖活动将涉及新的应用程序。 赞助: BrettTerpstra.com得到读者的支持。 总结:

本文宣布了SpamSieve抽奖活动的获胜者,并提供了购买折扣码。还宣布了接下来几个月的抽奖活动将涉及新的应用程序。文章最后提到了BrettTerpstra.com得到读者的支持。

The SpamSieve giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Garrett Coakley
  • Daniel Matz

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but SpamSieve is still worth checking out. If you’re tired of spam, it’s a purchase you won’t regret. You can still save 20% on your purchase with the code TERPSTRA2023 at the C-Command store.

Next up is Kaleidoscope. Check back every Monday through September, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-15T12:24:00-06:00 Web Excursions for December 11, 2023 https://brett.trpstra.net/link/535/16490884/web-excursions-for-december-11-2023 https://brett.trpstra.net/link/535/16490884/web-excursions-for-december-11-2023 Finder tags, Catalogs, Automation possibilities, Todo apps, Mind maps

总结: 本文介绍了关于Finder标签的使用方式,作者对目录和某个软件开发者的致敬,以及一些实用的链接创建方法。另外还介绍了一款被称为“适合讨厌待办事项应用程序的人”的待办事项应用程序,以及结合了心智图和生成式人工智能的工具。

Web excursions brought to you in partnership with MindMeister, the best collaborative mind mapping software out there.

Do You Use It? Finder Tags See Focused Use
I haven’t written about tagging for a long time because I felt like, at this point, I’ve convinced everyone who could be convinced about their usefulness. That still appears to be true, but this TidBits article talks a little bit more about the ways people use Finder tags.
DAK and the Golden Age of Gadget Catalogs
Oh my god, I loved these catalogs and this tribute from Cabel is an amazing read and a well-deserved homage.
CleanCocoa/OpenAny: macOS app and file launching springboard
Create a link to open any file directly in any app. Some interesting automation possibilities. From the developer behind TableFlip.
Finalist
You probably know I’m an OmniFocus guy, but I’m always trying the latest in todo apps. This one bills itself as “a todo app for people who hate todo apps,” and it looks pretty great for exactly those people. “Works just like Notes, with smarts of a calendar.”
WriteMapper — Content writing tool that uses AI and mind maps.
You know I love me some mind maps, especially for content development, and I’m fascinated by the possibilities of generative AI, and along comes a tool that uses both.

Check out MindMeister and start brainstorming, collaborating, and boosting productivity.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-11T14:47:00-06:00 SpamSieve giveaway! https://brett.trpstra.net/link/535/16490522/spamsieve-giveaway https://brett.trpstra.net/link/535/16490522/spamsieve-giveaway SpamSieve, giveaway, email setup, filtering, licenses

这是一篇关于SpamSieve软件赠送活动的文章。活动提供了2份价值39.99美元的许可证,该软件可以强大地过滤垃圾邮件。SpamSieve通过贝叶斯垃圾邮件过滤提供了准确的过滤效果,并且支持多种邮件账户类型。此次活动将在12月15日下午12点中部时间进行随机抽奖,每位幸运者将获得一份许可证。参与者需提供名和姓才能符合资格。同时,文章还提到了对BrettTerpstra.com的支持以及未来可能会举办的类似活动。

I’m excited to offer the next giveaway, 2 licenses ($39.99 value each) for SpamSieve. SpamSieve provides powerful spam filtering for any email setup. It learns and adapts to your mail, so it’s able to block nearly all spam. Use it instead of or in addition to your current junk mail filtering.

From the developer:

SpamSieve gives you back your inbox, using powerful Bayesian spam filtering to provide amazing accuracy that’s constantly improving. Works with IMAP, Exchange, and POP mail accounts.

Check out the SpamSieve site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, December 15, at 12pm Central. The drawing is for 2 licenses ($39.99 value each) for SpamSieve, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-11T08:00:00-06:00 Brett's Favorites 2023 Part II https://brett.trpstra.net/link/535/16488991/bretts-favorites-2023-part-ii https://brett.trpstra.net/link/535/16488991/bretts-favorites-2023-part-ii 时间追踪 应用 笔记软件 太空 科幻书籍 健康心理厨房工具消费品

总结:
文章提到了作者最喜爱的应用和书籍,包括时间追踪应用Timing和Noteplan,以及作者对科幻小说和心理治疗的介绍。此外,还有关于厨房工具和其他硬件的推荐。

I decided to make a “Brett’s Favorites 2023” part 2. I missed a few things in the first list. This will be a shorter post, but should cover some gaps I left in the first one.

Apps I Missed

Timing
I use Timing every day for keeping track of how I spend my time on my computer (and my iPhone). When I start a new project, at the end of the day I open up the main window and add rules by dragging and dropping relevant files and keywords, so time spend on that project is automatically tracked moving forward. I even made an importer for Doing that combines my time tracking with my What Was I Doing? file.
Noteplan
I got back into Noteplan in the latter half of 2023. I love the idea of combining my notes and brainstorming with scheduling, todos, and time blocking. All using Markdown. It’s a beautiful idea and superbly executed.

A Little Fiction

I read a ton in 2023, mostly via audiobooks. So “read” might be a stretch, but I do love audiobooks. I won’t list everything I’ve read here, but a couple of standouts:

Flux by Jeremy Robinson
I read so many books from Jeremy Robinson this year. He weaves excellent sci-fi stories. Also check out Infinite. The twists are insidiously satisfying.
In the lives of Puppets by TJ Klune
There’s a space for queer Sci-Fi, and TJ Klune does an amazing job of occupying it. This book takes the idea of a future dominated by robots and few (one?) remaining human and makes it a truly heartwarming journey. Thanks to Jesse Darst for cluing me into this one.

Therapuetic

No Bad Parts by Richard C. Schwartz
I’ve been doing a lot of therapy this year and only recently discovered Internal Family Systems, which has been a game changer. I won’t explain the psychology of it here, but if you want to learn more about the parts of you that might prevent you from being your true self, definitely check this out. I bought the e-book version for my Kindle, but also bought the audiobook version for its guided meditations.
What My Bones Know: A Memoir of Healing from Complex Trauma
This was the year I realized I had Complex PTSD, and I did a lot of reading around it. This one serves more as a memoir than a treatment plan, so take it along with some actual therapy. A lot of hope here, though.
Overtired
The Mental Health Corner on Overtired means a lot to me. I get to share my journey through CPTSD, ADHD, and Bipolar, as well as hear from people who go through very similar things to me. It’s kind of its own version of therapy (though it can’t replace actual therapy.) If you have issues of your own, you’ll probably be able to relate to me, Christina, and Jeff as we share. I recommend checking it out.

Kitchen

The Wicked Healthy Cookbook
If you’re vegan or aspiring to be, this book is a must-have. Truly delicious food and techniques that even a non-vegan can appreciate. I’m pescatarian for the time being, but cooking without meat, dairy, or (in my case) gluten means I’m always looking for recipes that actually taste amazing but fit my diet.
The Vegan Chinese Kitchen
I’ve been into Chinese cooking lately, and it’s pretty easy to make it vegan. I also recommend Yeung Man Cooking (also available as a digital version for $20), and the author has a YouTube channel worth checking out.
Misen Carbon Steel Pans
I have been through countless non-stick pan solutions over the years. I long for the convenience, but nothing seemed to stand the test of time. Our trusty cast iron pan outlasted all of them by miles, and with a good chain mail scrubber1, they’re very easy to care for. Then I tried carbon steel pans and have decided that that’s the way forward. They become more non-stick over time as a a natural result of material and seasoning, rather than quickly losing some chemical coating and becoming a stickier mess than your typical aluminum pan. I admit I’m awful at properly caring for non-stick pans, which is why I needed a solution that just got better the more you used it (and could handle high heats). Misen has always impressed me, and their carbon steel pans have proven to be an excellent solution.
Milk Street Nakiri
My favorite chef’s knife is still my Misen, but this “vegetable knife” is pretty amazing. It’s a great form factor, and I love it. If you want to spend about half as much, there are plenty of similar options. I can vouch for the Milk Street one, though. Lightweight, sharp, textured blade for gripping between thumb and forefinger.
Tumbler Diamond Rolling Knife Sharpener
I love a sharp kitchen knife, but have never been great at sharpening myself or sending my knives off for professional sharpening. That’s why I jumped on this when I discovered it, and it’s been 100% worth the investment. Definitely get the strop, too.

Other Hardware

I said I didn’t buy a lot of hardware this year, but I dug through my Amazon purchases and found the stuff that I actually love.

Elgato Stream Deck Pedal
I’m all in on Elgato stuff, from my Wave XLR to my multiple Stream Decks. But what was missing was buttons for my feet, and the Stream Deck Pedal has filled that gap nicely. I tried a few other, cheaper USB pedal solutions before I gave in and purchased this, and I’ll tell you that nothing else works as well. Whether you need a cough button, control over your Twitch stream lighting, or just want to be able to launch an automation with your foot, it’s a lot of fun.
Minoston Z-Wave Outlet Mini Plug-in Socket
I’m only dipping my toes in Homekit, with a lot of hope for Matter, but for now my home automation is mostly Insteon and Z-Wave. These little plugs have made automating the Christmas lights I use for warming up various rooms super easy.
Tineco Pure ONE S15 Pet Smart Cordless Vacuum Cleaner
I was a big fan of Dyson stick vacuums, but they kept breaking on me. Too much maintenance. So I decided to try something new. This one has been excellent. I’ve been using it for about 6 months and have only had to clean it once. Plus I love/hate the little headlight it has on it; I love it because it helps me see all the grit I’m picking up, but I hate it because it makes it obvious when I’m going too fast.
  1. Wait, you didn’t know about chain mail? You can scrub the living hell out of a cast iron (or carbon steel) pan with chain mail and it won’t destroy the seasoning or cause any rusting. If you like heavy cookware, you need one of these. Do not use it on a non-stick pan. 

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-09T15:18:00-06:00 The Soulver giveaway winners! https://brett.trpstra.net/link/535/16488230/the-soulver-giveaway-winners https://brett.trpstra.net/link/535/16488230/the-soulver-giveaway-winners Soulver, winners, giveaway, discount, apps

总结: Soulver的赠品活动已经结束,获奖名单已经公布。获奖者是Knut Focke、Chris Metze、René Quesnel和Vihang Khare。未中奖者可以使用折扣码BrettTerpstra获得30%的折扣。接下来的赠品活动将在2024年8月的每个星期一举行。读者可以在社交媒体上关注最新消息。BrettTerpstra.com通过读者支持。

The Soulver giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Knut Focke
  • Chris Metze
  • René Quesnel
  • Vihang Khare

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Soulver is still worth checking out. You can still save 30% off the direct version using the code BrettTerpstra. It will revolutionize your problem solving.

By the way, Soulver is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is SpamSieve. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-08T13:00:00-06:00 Brett's Favorites 2023 https://brett.trpstra.net/link/535/16487596/bretts-favorites-2023 https://brett.trpstra.net/link/535/16487596/bretts-favorites-2023 Setapp, Apps, iOS, Mac, Favorites 总结: 本文介绍了作者在过去一年里喜欢的各种Mac和iOS应用程序,包括一些老牌但仍然很棒的应用,以及一些新的应用。作者还提到了一些硬件设备,以及他个人的一些项目,包括编码工作。这些应用和项目对作者的工作和生活有着重要的作用。

Welcome to my yearly post about stuff I’ve loved in the last year. I love doing this because it reminds me how amazing the Mac/iOS app ecosystem is these days. I can’t list every app I use in this post, it would take forever, but I can highlight some of the outstanding ones. I’m going to do this all in one epic post this year. It’s going to get long. You could always use Gather to convert it to Markdown, and then make use of all of Marked’s navigation tools 😇.

Apps available on Setapp will be noted. As I mention frequently, Setapp is a great deal at $10/month for 200+ excellent apps. If you’re a Setapp user, you should always try to use the Setapp version of your favorite apps to make sure the developer gets a piece of your subscription! If you’re not, you should seriously consider signing up. This link gives me a little kickback when you join!

The categories are presented with items in no particular order. I could have made them alphabetical, or attempted to rank them, but no, I present you with an unorganized stream of consciousness. Welcome to the inside of my head.

The Old But Awesome Stuff

I’m going to quickly list some repeats that are still favorites here at the top. These are apps I’ve used for years and still rely on every day, but I’ve talked about them plenty and you’ve probably heard about them before. So just a quick list of my perennial favorites.

HoudahSpot
Find everything on your Mac, even the stuff that Spotlight misses.
iThoughtsX Setapp
My favorite mind mapping tool. All the power and flexibility you need without becoming a chore to use. This one is on the giveaway list, so stay tuned for that next year!
Curio
The ever-evolving brainstorming/project management tool that continues to amaze. Watch for a giveaway coming soon (New Year’s Day!).
1Password
With the new Passkey and Authenticator possibilities in 1Password, it’s a no-brainer for me. I’ve trusted it for years and it’s never let me down.
BetterTouchTool Setapp
I talk about BetterTouchTool all the time. Maybe too much. But it’s the most amazing automation tool I’ve found. Second place for me is Keyboard Maestro, which just got a new version (v11) in the last few months.
MailMate
The stalwart email app for Mac that I depend on. Customizable shortcut keys, plugin architecture, Markdown capabilities… I’ve never found anything close.
Choosy
Choosy is long in the tooth but still working great. Instead of opening a link in your default browser, you can pop up a selection of any browser on your system, and you can create rules for handling different types of links with specific browsers.
Hazel
I use Hazel every day, but I don’t even think about it most of the time. It just sits in the background, managing my files and doing crazy automations when I give a file a certain naming pattern or put it in a certain folder. For example, if I save an image to my desktop with a name like brettsfavorites2023@2x%%r1600ohc.png, Hazel will (r)esize it to 1600px width, (c)onvert it to JPEG, create a (h)alf-size 1x version, and (o)ptimize the images. Then I just drag the results to a Dropzone target to have them added to my blog and an image tag for the pair placed in my clipboard.
Bartender Setapp
Without Bartender my menu bar would be out of control. But with it, I can hide all of the menu bar icons I don’t need all of the time, and quickly access them with a hotkey search.
Default Folder X Setapp
Early in the Sonoma release DFX stopped working for me (all fixed now), and I didn’t realize exactly how dependent on it I was until it wasn’t there anymore. Save and open dialogs on your Mac need this.
PopClip
I use PopClip all day, every day. It pops up a menu every time you select text with your mouse. The available extensions are outstanding, and I have my own custom actions, too. One example is my URL Preview extension, so when I use SearchLink to grab a URL for an app I’m writing about but I’m not sure the result is correct, I just select the url and click the preview button in the popup. I get a tiny little web browser floating over my text, and if it’s the correct link, I hit escape and go back to writing.
TextExpander
You hear about TextExpander every month when they sponsor this blog, so it makes this quicker list. It’s another app that, on the occasion it stops working, so do I. I don’t even remember how to type some of the things it makes automatic for me. One example is sending nvUltra beta invites. I just hit R to reply to an email request, type ,,nvub, and have an email with all of the necessary links and info ready to send. Or I can generate a new license for Marked by typing ,,mlic, and TextExpander will use the Paddle API to make me a license and insert all of the text I would send to explain how to use it. And I just linked that reference to Marked by typing /m. Infinite possibilities.
TaskPaper Setapp
I have a TaskPaper file in every project folder, and I use tools like na to quickly manage them from the command line. But nothing beats opening up the actual TaskPaper app for speedy task management and ease of use with lots of keyboard shortcuts.
Hookmark Setapp
I’ve preached the Hookmark gospel a lot here. Their recent improvements to the “bookmarking” concept (plus the Pinboard integration) have made this an invaluable tool for keeping my projects together. I have this post linked to a few web pages, my nvUltra notes on it, and the Markdown versions of previous installments of my Favorites series for reference. I just hit my shortcut key and navigate between them with ease.

New(ish) Stuff

OmniFocus 4
The latest version of OmniFocus is a major revamp of the app. I don’t think it will be available in time for this post to go up, but let me at least tease it by saying if you love OmniFocus already, you’re going to love v4, and if you’ve disliked it in the past for any reason, it’s time to give it another look. An honorary mention here goes to Things — the latest version is a top-notch app, especially if OmniFocus just feels more powerful than you need.
MacUpdater
This app has quickly become one of my day-to-day favorites. It keeps all of my apps up-to-date without me having to deal with download/install prompts every time I launch them. See the release notes for an update if you want to, install available updates with a single click, and always have the latest and greatest versions of apps ready to run. It auto-scans for updates in the background, so you don’t even have to remember to check it to keep everything updated.
Ivory
I’m all in on Mastodon, and all out on Twitter. And Ivory is my favorite Mastodon client on both Mac and iOS. It does everything I need it to, beautifully. If you ever enjoyed TweetBot, this is kind of that, but for Mastodon.
Tailscale
What a great tool. I hook it up to my GitHub account and then every device on my network is accessible through a private VPN from anywhere in the world. I have it running on all of my Macs, my iPad, and my Synology, and I can get direct access to any device without any additional hassle.
Kaleidoscope
Kaleidoscope has made huge bounds in functionality this year. It was already my diff tool of choice (on any platform), but they’ve added new integrations, debugging features, and awesome support for Git history and merging. (Full disclosure, Kaleidoscope has sponsored this blog. This opinion is unpaid!)
Descript
I can’t imagine making podcasts without Descript anymore. It does fairly reliable transcriptions, but the real magic is that you can edit the podcast by editing the text of the transcription. Makes it easy to search for parts you remember need an edit, remove filler words, and add things like chapter titles and cover art to make a ready-to-publish MP3.
Paletro Setapp
I think I’ve mentioned this one before, but if you like command palettes in your favorite editor (e.g. P in Sublime), this adds the same concept to any app on your Mac. Hit the keyboard shortcut and every menu item (including Quick Actions and Services) are instantly available via keyboard.
Screens Setapp
I use Screens all the time for connecting to my various Macs, especially the mini that runs headless in my basement. Versus the Screen Sharing tools in macOS, it adds Screens Connect, which helps you connect to known machines from anywhere, stored credentials, and curtain mode, which masks the display of the remote Mac you connect to. Clipboard sharing, display selection (when there are multiple montiors), and easy drag-and-drop file transfers make it a pretty seamless experience.
Dato
I can’t use Fantastical with my work calendar, unfortunately (if I could, I’d be using that). But Dato works with my calendar, shows a great summary of calendar events in my menu bar, and makes joining a Zoom call a one-click process from either the menu bar or the notifications it provides. Solid tool that I use daily.
Affinity Photo
The Affinity apps continue to blow me away, and I use Affinity Photo almost daily. It completely replaced Photoshop for me a couple of years ago. Honorable mentions to Acorn and RetroBatch from Flying Meat for regularly helping me with my image processing.
iTerm
I’ve tried all the terminal apps that have been popping up. Warp is great, for sure. But I always come back to iTerm. It got so many of the special features right that it feels like all the other developers are just trying to keep up with it.
Loopback
I love Rogue Amoeba (also a previous sponsor), and Loopback is an amazing tool for audio routing. If you, like me, have multiple audio inputs and outputs, it makes creating virtual devices for them (or any combination of them) a drag-and-drop affair. For example, I use my Echo Dot for playing Spotify music, and route it through my Komplete 6 as a secondary input. I created a Loopback device that combines that secondary input with my main computer audio and adds the ability to mute the device using the media keys.
Bike Setapp
Bike is a new entrant this year. I generally think in mind maps, but there’s always a place for a solid outliner. I used to use Tree, but it fell into disrepair, and Bike is coming along nicely. As you would expect from Hog Bay Software, the query tools and automation capabilities are receiving lots of love. Plus the file format is just text (HTML, to be precise) and your outlines can be used anywhere. Much like TaskPaper, it’s easy to automate using command line tools, but more fun to work with inside the app.
TextBuddy
I love TextBuddy so much. It does everything you want to do with text, from wrapping/unwrapping, escaping, translating, converting tabs to spaces, even reading text from images and working with it. And it does it elegantly with keyboard shortcuts. No buttons to hit, just paste your text (or send it via Service shortcut), hit T and type to find the conversion you want to run. It’s even extensible with JavaScript, and can also run your favorite Services (like SearchLink!).
DevUtils Setapp
This is another new one to me. It’s a collection of simple tools a developer would make use of, such as url encoding, JSON formatting/validation, JSON/YAML conversion, Unix Time converter, and dozens of others. It can detect what type of data is on your clipboard when you click its menu bar icon, offering an accurate guess of which tool(s) you’ll need to handle it. It can also copy straight back to clipboard, so some things are simply a matter of copying text, clicking the icon (global and Service shortcuts available), and pasting the result.
Tower
I’ve mentioned Tower before (also a previous sponsor), but it’s come a long way this year. One of the most ingenious features is the undo command (Z) that can undo literally any Git operation. You know, the ones that usually require filtering through the reflog and making cherry pick commits to fix. It makes using Git a pleasure, and taps into all of the powerful features it offers, just with drag and drop instead of command line futzing.
CleanShot X Setapp
I mentioned this one last year, but I would be remiss not to let you know how much I love it again. CleanShot X is one of the most useful and elegant utilities on the Mac right now. For all your screenshot needs, including things like automatic email pixelation and annotation, it just can’t be beat.

iOS

I haven’t found a lot of new stuff on iOS that I love this last year, but mostly because I primarily use my phone for email, messaging, and gaming. There are a few standouts in my daily use, though.

Spark
Spark gets a mention as my favorite email client. I haven’t sprung for the premium features, I find that the base package does everything I need it to. Smart inbox, easily configured sidebar, snoozing, pinning, and great search. Combined with SaneBox (sponsor) and MailMate on my Mac, I’m quite happy with my email management system.
Finity
Rabbi Eric Linder introduced me to this game and it did the impossible task of replacing Threes, my all-time favorite waiting room game. It’s an infinite puzzle that you’ll never beat, but it’s so much fun to play.
Grindstone
Grindstone is still one of my favorite games. Even though I’ve 3-starred all the levels, they offer daily challenges with worldwide leaderboards that keep me coming back.
Artifact
Apple News hasn’t impressed me that much lately, but Artifact is a constant source of headlines I actually care about, across multiple categories. And the AI-generated summaries are great. It will even rewrite headlines to be less click-baity if enough people report them.
Night Vision
I don’t use this app as often as the others, but I like the concept. It makes your iPhone’s LiDAR camera available as a kind of night vision camera, allowing you to see objects in complete darkness. Handy for stumbling through the house at night when you can’t sleep but don’t want to wake anybody up.

Hardware

I apparently didn’t buy much other hardware this year, and my list is pretty much exactly the same as last year’s. Check it out here. I will mention my UHK, though:

Ultimate Hacking Keyboard
My perennial favorite keyboard, and I got the V2 this year with box white switches, wooden wrist rests, and the new thumb modules. I’ve gotten a few other people on board with this one and haven’t heard about anybody being disappointed with the purchase. I’m typing on it right now and loving it. UHK recently released the Riser 60, a mechanism for getting steeper tenting (two halves raised in the middle). Ordered mine immediately, just waiting for it to ship!

Personal Projects

I did a lot of coding this year. My bipolar has been stable for the last 6 months, so I’m taking a healthier-than-usual approach to coding. No all-night coding binges, just steady improvements of some of my favorite tools.

SearchLink
SearchLink is a child who takes care of me in my old age. I put a lot of love into it, and it works to make my life easier. If you haven’t seen it, it makes writing a post like this one a cinch. I haven’t switched over to my browser once since I started writing. I just give it text like [Kaleidoscope](!s +mac) and hit the keyboard shortcut, and it inserts a link (with title attribute) to the app in question. Works for dozens of search types. I recently added back Google searching using the API (as opposed to scraping DuckDuckGO, though that’s still available), and my results are 99% correct on the first try.
NA (Next Action)
I made a lot of progress on NA this year, converting it to a gem, adding the ability to update and modify tasks, and improving overall performance. As I mentioned above, I use TaskPaper-formatted files in every one of my projects to track bugs, todos, and feature requests, and NA makes working with those files from the command line easy and fun.
Marked 2
Marked didn’t see as much innovation as usual this last year, but it continues to do what it does very well: previewing Markdown and exporting HTML and beautiful PDFs. Multi-document features, writing tools, regex searching, bookmarking in long documents… it does it all. The biggest challenge this year was updating for Sonoma, which broke significant parts of Marked.
Bunch
Bunch got a ton of love early this year. It’s been stable for a few months now, almost every feature request handled and all bugs squashed (that were squashable). It’s received coverage on multiple sites and even print write-ups in a couple of magazines. I’m pretty proud of it as a project, and think it fits nicely into the Mac automation space.
mdless
mdless was my most recent coding obsession, and probably my last one for the year. It previews Markdown on the command line, outputting formatted text to your terminal. Perfect for reading those README files after you clone a project! Combined with Gather (a previous coding obsession this year), it can actually work as a Lynx-style browser.
nvUltra
I know, I know. It’s so close. The beta is very, very stable, we’re just working on a couple of refinements (and some MAS purchase issues) before release. If you’re reading this and you’re not on the beta already, contact me to get added.

Well, that’s my wrap-up for 2023. Hopefully you found some gems along the way. If you have apps you think I should check out, please come tell me about them in the forum! (If you comment on this post, it will automatically create a forum topic).

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-08T10:31:00-06:00 Backblaze makes it astonishingly easy to store, use, and protect data [Sponsor] https://brett.trpstra.net/link/535/16486039/backblaze-makes-it-astonishingly-easy-to-store-use-and-protect-data-sponsor https://brett.trpstra.net/link/535/16486039/backblaze-makes-it-astonishingly-easy-to-store-use-and-protect-data-sponsor Backblaze, backup, security, data storage, affordable 总结:

本文介绍了Backblaze的云备份服务,该服务提供了自动备份、数据安全、多种还原选项等功能。用户可以使用Backblaze来保护个人和企业的文件和数据,提供了各种安全措施保护数据的安全性。除此之外,Backblaze还受到多家权威媒体的推荐,用户可以通过试用期了解服务,并选择不同的许可选项来节省费用。整体来说,Backblaze提供了便捷、安全、可靠、价格实惠的数据存储解决方案。

Thanks to Backblaze for sponsoring BrettTerpstra.com this week! I’ve been a user for years and it’s saved my hide many times. It’s so easy to set up, and just as importantly, easy to restore files whenever needed. Everybody should have a good cloud backup, and Backblaze is the best I’ve found.

Backblaze Computer Backup offers unlimited and automatic backup for individuals and businesses for just $9/month.

With Backblaze, you can back up documents, photos, music, movies, and more to the cloud. Available for both Macs and PCs, it’s easy and automatic—all you have to do is create an account and your files will start backing up. You can even back up external drives! Backblaze has over three exabytes of data under storage and has restored 55+ billion files for customers.

In the event of hardware failure, accidents, or ransomware, Backblaze offers multiple restore options—you can access your data from anywhere in the world with our web and mobile apps for iOS and Android. You can download files from the web or receive a USB hard drive with all your data shipped to your door. If you return the hard drive within 30 days, you get a full refund!

Protect business data and manage backups for your organization through a centrally-managed admin. Deploying Backblaze on thousands of workstations across your organization is easy!

We offer 30 days of Version History by default and one-year file retention for free so you don’t have to worry about accidentally deleting your data or keeping old file versions. For extra protection, you can upgrade to Forever Version History for just $0.006/GB per month.

Backblaze takes security seriously. All data is stored in our secure data centers with 24-hour staff, biometric security, and redundant power. Here are a few of our security measures:

  • You can use a private encryption key for additional security, ensuring only this key can unlock your backup.
  • Files are encrypted before being transmitted over SSL and stored encrypted.
  • Backblaze’s code is native to Mac and PC and doesn’t use Java.
  • Two-factor verification via ToTP and SMS is available for all Backblaze accounts.

Backblaze is recommended by The New York Times, Inc. Magazine, MacWorld, PCWorld, Lifewire, Wired, Tom’s Guide, 9to5Mac, and more. Recently listed on the NASDAQ Stock Exchange under BLZE, Backblaze is committed more than ever to bringing easy and affordable data storage that you can trust.

Backblaze Computer Backup starts at $9/month. You can save $9 annually by signing up for an annual license, or save $27 when you sign up for a two year license.

Get started with a 15-day no credit card required free trial by going to backblaze.com/terpstra.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-07T08:49:00-06:00 mdless with document transclusion https://brett.trpstra.net/link/535/16484987/mdless-with-document-transclusion https://brett.trpstra.net/link/535/16484987/mdless-with-document-transclusion MultiMarkdown, transclusion, file, include, path

总结: 最新版本的编码工具包含了MultiMarkdown,并且增加了文件引入的功能。通过使用双大括号插入另一个文件的内容,路径可以是相对或绝对路径,还可以在元数据中指定transclude base。这个功能对大部分用户来说可能并不是非常有用,但对一些用户来说会非常方便。

The latest version of mdless, my most recent coding obsession, now includes MultiMarkdown document transclusion.

File transclusion is the ability to tell MultiMarkdown to insert the contents of another file inside the current file being processed.

You can include a document by inserting a relative path between two pairs of curly brackets:

{{myfile.md}}

The path is relative to the current document, which won’t work if you’re piping text to mdless. In that case it would need to be an absolute path, or have transclude base specified in the metadata.

To provide a base for transclusion paths, just add transclude base to your document’s metadata, either as MultiMarkdown metadata, or as a YAML header:

transclude base: ~/Documents/myproject/chapters

It’s probably not a super useful feature to 90% of mdless users, but should be handy for some.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-06T13:51:00-06:00 The SaneBox giveaway winners! https://brett.trpstra.net/link/535/16484889/the-sanebox-giveaway-winners https://brett.trpstra.net/link/535/16484889/the-sanebox-giveaway-winners SaneBox, winners, subscription, discount, email service BrettTerpstra.com, giveaway, readers, support, promotion

总结: SaneBox举行了抽奖活动,五位幸运读者获得了1年订阅SaneBox的奖励。未中奖的读者也可使用优惠码获得订阅折扣。BrettTerpstra.com受到读者支持,正在举行活动并提供促销。

Well, the SaneBox drawing has happened I have winners to announce! The following readers have won a 1-year subscription to the handiest email service out there!

  • Andreas Lauritzen
  • Dániel Krausz
  • Jamie Peloquin
  • Esteban Umerez
  • Greg Johnson

Congrats to the winners! If you didn’t win, I’d still recommend checking out SaneBox. Use this link to save $25 on your subscription. It will bring a sanity to your email that you’ve only imagined was possible.

Don’t forget to sign up for the Soulver giveaway that’s happening Friday!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-05T12:11:00-06:00 Soulver giveaway! https://brett.trpstra.net/link/535/16481839/soulver-giveaway https://brett.trpstra.net/link/535/16481839/soulver-giveaway Soulver, calculator, notepad, giveaway, license
Soulver是一款智能替代计算器应用,结合了记事本和计算器的功能,能够使用文字和数字一起进行计算,自动保存工作内容,四个Soulver许可证价值34.95美元每个将在12月8日抽出获奖者。进入抽奖需要提供名字和姓氏,RSS订阅者需要访问网站参与。该系列活动将持续到2024年8月,并且欢迎提出你想看到的应用程序。

I’m excited to offer the next giveaway, 4 licenses ($34.95 value each) for Soulver. Ever wish you could type out a math problem in words and have the answers handed to you? Soulver combines a notepad with a calculator and gives you instant answers.

From the developer:

Soulver is a smart replacement for your calculator app. Use it to work things out, explore different scenarios and play around with numbers. You can use words alongside numbers and almost never encounter an error. And all your work is automatically saved for you so you can reference it later.

Check out the Soulver site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, December 08, at 12pm Central. The drawing is for 4 licenses ($34.95 value each) for Soulver, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-04T08:00:00-06:00 The Tower giveaway winners! https://brett.trpstra.net/link/535/16479203/the-tower-giveaway-winners https://brett.trpstra.net/link/535/16479203/the-tower-giveaway-winners Tower giveaway, winners, announcement, discount, next giveaways 总结:

本文是关于Tower赠品活动的结束和获奖者的公布。获奖者是Suzuki Airi和Gavin Jerman。未中奖的人可以参加新用户50%折扣活动。同时,文章还提到了未来的赠品活动。读者可以通过订阅或者关注作者的社交媒体得到最新信息。整个活动由Brett Terpstra支持。

The Tower giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Suzuki Airi
  • Gavin Jerman

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Tower is still worth checking out. If you use Git for anything, Tower can make your life easier. Until Dec 5th you can get 50% off for new users on any plan. Just visit git-tower.com to purchase.

Next up is Soulver. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-12-01T12:15:00-06:00 mdless gets all the colors https://brett.trpstra.net/link/535/16477495/mdless-gets-all-the-colors https://brett.trpstra.net/link/535/16477495/mdless-gets-all-the-colors 改进,主题,颜色代码,TaskPaper渲染,更新日志

总结: 该文章介绍了mdless 2.1.6版本的更新,包括使用十六进制颜色代码进行主题设置,解决了列表和段落中颜色显示的问题,改进了TaskPaper的渲染和自动检测功能,并新增了显示更新日志的--changes标志。

I just pushed v2.1.6 of mdless. Once all these 2.0 changes are confirmed to be stable, I’ll let this project go for a while, but right now there’s lots to improve on and I’m enjoying it as a way to blow off steam.

The biggest change in 2.1.6 is the ability to use hex codes when theming. If you didn’t know, the first time mdless is run, it saves a theme file to ~/.config/mdless/mdless.theme. You can edit this file to change what colors different elements display as. You can also create additional NAME.theme files and trigger them with --theme NAME, or set the :theme: setting in your ~/.config/mdless/config.yml.

With the latest version, you can use 3 or 6-digit RGB codes in addition to color names. Where previously you were limited to the default ANSI colors like red, blue, magenta, cyan, etc., you can now insert something like eccc87 where a color name would usually go. You can affect background colors by prefixing with bg or on_, e.g. bgeccc87. The depth of color that can be displayed depends on your terminal, but at minimum this opens up 256 colors for theming, a 32x increase in options.

I also fixed a couple of issues where span elements in list items would cause the coloration to change. And when there’s a space between list items, they get rendered as paragraphs within list items (standard for most Markdown parsers), causing the coloring to be unexpectedly the same as regular paragraphs. Now mdless strips out regular paragraph coloring on paragraphs contained in list items, so every paragraph within a list gets the list item coloring.

In TaskPaper rendering, documents will now respond to --list to list projects, and --section to list just certain project(s) contents. These no longer have to be numeric (for Markdown or TaskPaper); fuzzy text matching can pick a section (or multiple sections) for you. I also improved the TaskPaper auto-detection by adding a routine that removes all lines that match project or task regular expressions, and if there’s nothing left, it assumes it’s a TaskPaper document. Let me know how this works in the real world.

Lastly, I added a --changes flag that will display the changelog (using mdless for readability), so when you update you can see what changed just by running mdless --changes.

Check out the project page for the full changelog and more details!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-30T10:47:00-06:00 SaneBox giveaway surprise! https://brett.trpstra.net/link/535/16477304/sanebox-giveaway-surprise https://brett.trpstra.net/link/535/16477304/sanebox-giveaway-surprise SaneBox, giveaway, email, subscription, BrettTerpstra.com 总结:

本文介绍了SaneBox赞助BrettTerpstra.com,并提供5个免费1年订阅SaneBox的机会。SaneBox是一个帮助你保持电子邮件收件箱清洁的服务,通过训练可以将特定类型的电子邮件移动到自定义文件夹中,创造一个干净的收件箱。另外,@SaneBlackHole功能可以将某些发件人的邮件屏蔽,让其在不经过退订或请求删除数据的情况下消失。想要参与抽奖的读者需要在BrettTerpstra.com上查看并分享此文章。

Thanks to SaneBox for sponsoring BrettTerpstra.com this week! Instead of a monthly sponsored post this month, the good folks at SaneBox have decided to join my giveaway series and offer 5 free 1-year subscriptions to SaneBox to BrettTerpstra.com readers. Just sign up below for a chance to win.

If you somehow haven’t heard of SaneBox yet, it’s a service that keeps your email inbox clean. You can train certain types of emails to go to your @SaneLater folder, or any custom folder, just by moving an email once. Future emails like it will automatically go to that folder. Forget setting up complicated filters and rules, a week of training and you’ll have a clean inbox that contains only the messages you actually need to see. I especially love the @SaneBlackHole feature which lets me banish certain senders to a, well, black hole, where their messages disappear and I don’t have to go through any hassle of unsubscribing or requesting data removal to stop the incoming messages.

Sign up below for a chance at one of 5 1-year subscriptions, a $299 value. Winners will be drawn next Wednesday, December 6th.

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-30T08:00:00-06:00 Tower giveaway! https://brett.trpstra.net/link/535/16469906/tower-giveaway https://brett.trpstra.net/link/535/16469906/tower-giveaway Git GUI, Tower, giveaway, sign up, BrettTerpstra.com

1. 一篇关于Git GUI Tower的介绍和赠品的文章,作者提供了两个1年价值99美元的Tower许可证作为赠品。 2. 要参加赠品需要在作者的网站上注册,每个参与者需要提供名字和姓氏。 3. 赠品于12月1日进行抽奖,每个获奖者将获得一个1年价值99美元的Tower许可证。 4. 作者承诺未来几年每周都会举办赠品活动,读者可以期待更多的赠品。 5. 作者表示网站内容需要读者的支持,鼓励读者点赞和分享。

总结: 本文介绍了一次关于Tower Git GUI的赠品活动,包括如何参与、赠品内容和未来赠品的计划,以及对读者们的呼吁。

I’m excited to offer the next giveaway, 2 1-year licenses ($99 value each) for Tower. Tower is the absolute best Git GUI out there. If you use Git for work or personal projects, its in-depth integration with the entire Git toolset makes life easier, even if you’re already well-versed in the command line. It includes great GitHub integration for pull requests and issues.

From the developer:

All of Git’s Power (And None of the Pain). Pull Requests, Single-line staging, Interactive Rebase, Submodules, Git LFS, Git-Flow, File History, Blame, Cherry-Pick.

Check out the Tower site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, December 01, at 12pm Central. The drawing is for 2 1-year licenses ($99 value each) for Tower, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-27T08:00:00-06:00 mdless updates for Thanksgiving weekend https://brett.trpstra.net/link/535/16468853/mdless-updates-for-thanksgiving-weekend https://brett.trpstra.net/link/535/16468853/mdless-updates-for-thanksgiving-weekend 更新, 配置文件, 内联样式, 任务清单, 强调标记
内联样式和嵌套列表是在版本2.0中进行了重大更新,解决了代码和列表的格式问题,可以在命令行和配置文件中进行永久性设置。另外,还加入了任务清单的高亮显示,链接格式、强调标记等多种Markdown处理选项,方便用户根据需要进行设置。

总结: 更新配置文件后,mdless版本2.0解决了内联样式和嵌套列表的格式问题,同时增加了任务清单的高亮显示,丰富了Markdown处理选项,提升用户的使用体验。

I made a few major updates to mdless 2.0 (first announced a couple days ago) over the holiday weekend. Note that you can make all of the new options permanent in the config file (see Easily Update Config). Options specified on the command line will always override anything in the config file, so you can disable options permanently but enable them on a per-run basis using command line flags.

Inline Styling

The first problem I ran into was that if a link, emphasis, or other inline element came in the middle of a line, everything after that element would fail to be styled. So I added in a routine that I created for Doing that can take the text preceding an element and determine what the escape sequence would be at the end of that text, right before the new element. Then I can restore that sequence after the new element.

Nested Lists

Second, and this was a real pain, nested lists weren’t working. Like at all. I didn’t notice it at first because my test files had very basic lists in them, but lists were being flattened, ordered list sequencing was completely out of whack, and nested paragraphs and code blocks within lists were getting totally borked. Fixing this was a pain. Redcarpet only provides “text” and “type” to the list rendering functions, so you have no idea if it’s nested, at what level, etc. You can start a class variable counter and increment it with each ordered item, but as soon as it nests or starts a new list, you’re in trouble, and lists aren’t rendered in sequence anyway, so an array structure to keep track of them is impossible. They’re rendered inside out, so any kind of basic counter will be off as soon as you have a nested ordered list. Fixing this took me three days, and I went through a dozen solutions before one worked. I think the current solution is pretty solid, seems to handle all of the aforementioned issues and maintain accurate numbering with multiple nested, ordered lists. Also indents paragraphs and code blocks within lists.

I am running into an issue where a numbered item can sometimes have an unnecessary line break after it. I haven’t yet been able to track down where that’s coming from. Also, nested code blocks are indented, but one less indent than their parent list item. These will be fixed in future releases.

TaskPaper highlighting

I also added TaskPaper highlighting to mdless. You can run it with --taskpaper true to force TaskPaper highlighting, or run it with --taskpaper auto to detect TaskPaper formatting either from the file extension or test whether it has at least 1 project and 6 total tasks between projects based on regular expressions. Not the most elegant way to detect it, I’m sure, but it seems to work well in my testing. You can add:

:taskpaper: :auto

to ~/.config/mdless/config.yml to make auto a permanent setting (or use true or false to force it either way).

If TaskPaper highlighting is enabled, no other Markdown processing will be done. TaskPaper formatting intersects with Markdown formatting in ways that can cause unpredictable results. So @tags and values are highlighted, project names are highlighted, and task markers get colored. Other than that, it’s just displayed as is.

As mentioned in an update to the 2.0 announcement, mdless can now render links as inline, reference, or reference-per-paragraph, grouping the references below the paragraph or element that refers to them. Just run with --links paragraph or --links reference to enable either, and these can be made permanent in the config file by adding :links: :reference (or :inline or :paragraph).

Emphasis Markers

The initial release hid the markers around emphasis, e.g. **bold** would just render as bold, applying colors from your theme but leaving out the ** surrounding it. That’s now configurable in the theme settings:

emphasis:
  bold: b
  bold_character: "**"
  italic: u i
  italic_character: "_"
  bold-italic: b u i

You can leave the character settings empty to not display any characters at all (as per previous behavior).

Other Markdown Rendering Options

Redcarpet has flags available for lax spacing (requiring newlines around HTML blocks) and intra-emphasis (where a_underscored_filename would get rendered with italics in the middle). Disabling intra-emphasis means that underscored filenames (and other words) stay as is.

These can be implemented in mdless using --[no-]intra-emphasis and --[no-]lax-spacing, and both options can be made permanent in the config file.

:lax_spacing: true
:intra_emphasis: false

This one is simple, I just added highlighting for [[wiki links]]. It can be toggled with --[no-]wiki-links and uses the colors specified for link brackets and link text. Make it permanent with :wiki_links: true.

Easily Update Config

By the way, you can overwrite the config file with current command line flags and any new keys that have been added by running with --update-config. Any other flags on the command line will be set in the config, and any new keys that may have been added since your config file was created will be added with their default values.

The config file is found at ~/.config/mdless/config.yml. Options specified there can be overridden by using command line flags at any time. This file is automatically written on the first run where the file doesn’t exist, so you can scrap preferences and start again just by deleting the file and running mdless (any command line options used on that first run will be set in the config file, otherwise the default value for each option will be used).

Other Stuff

  • Pad numbers on headline listing to preserve indentation
  • Image rendering with chafa improved, still have to figure out a way to make sure content breaks properly around the embedded image
  • Only detect mmd headers on first line
  • Scrub invalid UTF-8 in document to remove characters that break regexes

Check out the project page for installation and usage details.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-26T13:24:00-06:00 The Default Folder X giveaway winners! https://brett.trpstra.net/link/535/16467738/the-default-folder-x-giveaway-winners https://brett.trpstra.net/link/535/16467738/the-default-folder-x-giveaway-winners Default Folder X, winners, giveaway, coupon, apps

Default Folder X举办的赠品活动已经结束,获奖者已经产生。恭喜Alexander Allori和Michael X获奖。未获奖的人可以使用优惠券BRETT-DFX-2023享受20%的折扣。未来几个月还会有更多的赠品活动。同时,可以向Brett Terpstra.com推荐你想要看到的应用程序。感谢读者的支持。

The Default Folder X giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Alexander Allori
  • Michael X

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Default Folder X is still worth checking out. Trust me, you need this. You might not realize how limited your standard open and save dialogs are until you’ve experienced Default Folder X. You can still save 20% by using the coupon BRETT-DFX-2023 at checkout.

By the way, Default Folder X is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is Tower. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-24T13:00:00-06:00 mdless 2.0 https://brett.trpstra.net/link/535/16466517/mdless-2-dot-0 https://brett.trpstra.net/link/535/16466517/mdless-2-dot-0 Markdown, mdless, update, terminal handling, code highlighting 更新了mdless至2.0版本,进行了完全改版,采用了新的Markdown解析方式,并且加入了自定义渲染和前后处理。表格清理效果更好,脚注可以更灵活地显示在段落后或者末尾。代码高亮更加准确,有序列表也可以正确显示编号。整体来说,是一个很大的进步。如果你在终端里使用Markdown并花费时间在README文件上,可以试试使用mdless来代替打开浏览器或者编辑器预览。详情和安装指南请参考链接。

I’ve updated mdless to 2.0. Well, 2.0.5 at this point. It’s a complete overhaul of the command line Markdown parser/viewer.

It’s been a pretty popular project, and is being used on all kinds of OSs, but it got frustrating as the whole thing was based on regular expressions for parsing and users expected it to handle some more complex markup than it could. So for the reboot, I switched to using RedCarpet for parsing, then added my own terminal handling to that via a custom renderer and pre/post processing.

Table cleanup is better than ever. Footnotes can still be displayed directly after the paragraph that references them, or at the end of the display. Code highlighting (with Pygments) is more accurate than ever. Ordered lists are properly numbered, regardless of the numbering in the Markdown. There are a few differences in the way things like code blocks nested in lists are displayed (they’re no longer indented), but overall it’s a big step up.

If you’re into Markdown and spend time in the Terminal, let mdless display those README files for you, rather than opening up a dedicated viewer or editor with a preview. See the project page for more details and installation instructions.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-23T09:19:00-06:00 Default Folder X giveaway! https://brett.trpstra.net/link/535/16461612/default-folder-x-giveaway https://brett.trpstra.net/link/535/16461612/default-folder-x-giveaway Default Folder X, macOS, giveaway, sign up, app 在brettterpstra.com的最新赠品活动中,我们有机会赢得两个总值为39.95美元的Default Folder X许可证。这个macOS的惊人扩展使文件夹导航变得更加容易,标记变得更好,并实现了灵活的收藏夹功能,还允许为每个应用程序设置特定的默认文件夹。登录参与抽奖,必须提供名和姓,赠品将在11月24日中午12点中央时间随机抽取。此外,还要关注更多未来的赠品活动。总结: Default Folder X是macOS的一个优秀扩展,可以使文件夹导航更加高效,提供灵活的收藏夹功能,以及为每个应用程序设置特定的默认文件夹。要参与赠品活动,需要在brettterpstra.com上查看详情并提供完整的姓名。

I’m excited to offer the next giveaway, 2 licenses ($39.95 value each) for Default Folder X. Default Folder X is an amazing extension for your open and save dialogs on macOS. It makes navigating folders easier, tagging better, and implements flexible favorites and allows specific default folders for every app. You can set up favorite folders, accessible with keyboard shortcuts, have every app track it’s most recent save-to folder, and much more.

From the developer:

Make your Open and Save dialogs work as quickly as you do. Track recently used files and folders in every app, reopen recently closed Finder windows, Copy and Move files in file dialogs.

Check out the Default Folder X site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, November 24, at 12pm Central. The drawing is for 2 licenses ($39.95 value each) for Default Folder X, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

New rule: All signups must have a first and last name in order to be eligible. Entries with only a first name will be skipped by the giveaway robot. A lot of the vendors in this series require first and last names for generating license codes, and your cooperation is appreciated!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-20T08:00:00-06:00 The Noteplan giveaway winners! https://brett.trpstra.net/link/535/16459610/the-noteplan-giveaway-winners https://brett.trpstra.net/link/535/16459610/the-noteplan-giveaway-winners Noteplan, winners, giveaway, apps, suggestions
Noteplan举办的赠品活动已经结束,获奖者已经公布。如果你没赢得奖品,可以考虑购买Noteplan,这是一个非常棒的便携式笔记、待办事项和项目管理解决方案。BrettTerpstra.com每周都会进行赠品活动,接下来的赠品活动包括……如果你对某个应用程序有兴趣,可以在社交媒体上联系作者。此外,他提到网站的支持来源于读者,保留所有权利。

总结: Noteplan举办了赠品活动,公布了获奖者名单。未中奖的人可以考虑购买Noteplan。BrettTerpstra.com每周都会进行赠品活动,保留所有权利。

The Noteplan giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Erik Wessel-Berg
  • David Blue
  • Brandon Ballentine
  • Carley Knight
  • Paolo Sturbini

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Noteplan is still worth checking out. If you like portable solutions for managing notes, todos, and projects, you can’t beat Noteplan.

By the way, Noteplan is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is Default Folder X. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-17T13:00:00-06:00 Kaleidoscope 4.3: Improved Git Merge Context and Git File History [Sponsor] https://brett.trpstra.net/link/535/16457520/kaleidoscope-4-dot-3-improved-git-merge-context-and-git-file-history-sponsor https://brett.trpstra.net/link/535/16457520/kaleidoscope-4-dot-3-improved-git-merge-context-and-git-file-history-sponsor Kaleidoscope, file comparison, Git merges, features, coupon code

总结: Kaleidoscope是一款强大的文件比较应用程序,特别适用于代码和Git合并。最新的Kaleidoscope 4.3版本提供了许多创新功能,包括改进的Git Merge Context Shelf和Git File History,支持文件重命名和分支名称显示,以及Markdown内容的美观渲染。该应用还提供了各种实用功能,如语法着色、比较转换为可内联编辑的合并文档、文本过滤器等。订阅费用为每月8美元,并且学生和教师可获得更多折扣。

Thanks to Kaleidoscope for sponsoring BrettTerpstra.com this week! This app just keeps getting better. If you have any need for comparing files (especially if you code and do Git merges), it can’t be beat.

Review versions of text and image files—and even folders full of files—with the world’s most powerful file comparison app. Kaleidoscope gives you powerful tools to use at each stage of the development cycle.

The brand new Kaleidoscope 4.3 continues to innovate by improving the previously introduced Git Merge Context Shelf and Git File History. Kaleidoscope now also detects file renames and shows branch names. When used with a service such as GitHub, GitLab or Bitbucket, Kaleidoscope now supports jumping to commits, branches, and tickets referenced in commit messages. And it beautifully renders Markdown content in commit messages, which makes browsing and comparing commits so much nicer.

Here are some of the features we added in Kaleidoscope 4:

  • Syntax coloring, with multiple built-in themes.
  • Transform any comparison into a merge document that can be edited inline.
  • Text filters to clean up diffs by removing irrelevant data, such as time stamps, object addresses and unique identifiers.
  • Kaleidoscope Prism, a new helper app in the menu bar to quickly launch comparisons even if Kaleidoscope is not running.
  • Debugger integration for Python developers.
  • File properties show metadata, including size, file type, dates, and encoding.
  • A welcome window that speeds up the processes of creating new comparisons or finding recent ones.

Subscriptions start at $8 per month for a yearly plan. Use the coupon code TERPSTRA (valid until December 31, 2023) to get 20% off for the first year. As a student or teacher, the price is reduced even further.

Learn more about Kaleidoscope and start your 14-day free trial today.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-16T08:00:00-06:00 Noteplan giveaway! https://brett.trpstra.net/link/535/16449348/noteplan-giveaway https://brett.trpstra.net/link/535/16449348/noteplan-giveaway Noteplan, giveaway, subscription, Markdown, organization

这是一篇关于Noteplan软件的赠阅活动的文章。文章介绍了Noteplan软件的特点和功能,表示有5个1年订阅的赠阅活动。软件支持Markdown格式,可以用于组织笔记和任务。活动的截止日期是11月17日,赢家会在当天抽出。文章最后还提到了之后会有更多的赠阅活动,并鼓励读者参与。整体来看,这是一篇为了推广Noteplan软件而进行的赠阅活动文章。

I’m excited to offer the next giveaway, 5 1-year subscriptions ($99 value each) for Noteplan. If you love plain text (and Markdown), you’re going to love Noteplan for organizing all your notes and todos. Using plain text, you can create daily logs, digital bullet journals, track todos, and keep cross-linked notes for all your stuff. Also check out the web version coming soon!

From the developer:

Use the flexibility of Markdown to quickly create tasks. Add options for repeating to dos, easily move tasks into the future, and add tags and mentions. Speed up your workflow with natural language input and autocompletion of tags, mentions, and links.

Check out the Noteplan site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, November 17, at 12pm Central. The drawing is for 5 1-year subscriptions ($99 value each) for Noteplan, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-13T08:00:00-06:00 The Hazel giveaway winners! https://brett.trpstra.net/link/535/16440511/the-hazel-giveaway-winners https://brett.trpstra.net/link/535/16440511/the-hazel-giveaway-winners Hazel giveaway, winners, coupon, next giveaways, Brett Terpstra 总结:

文章宣布了Hazel赠品活动的获奖名单,同时提供了未中奖者使用折扣码购买产品的机会。接着介绍了即将举行的下一个赠品活动,并鼓励读者参与。最后,鼓励读者通过社交媒体分享或点赞,并表达了对读者支持的感谢。

The Hazel giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Bruno Martinelli
  • Mike
  • Simeon Attaway
  • Federico
  • Will

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Hazel is still worth checking out (and I know you’re interested because there was a record number of entries for this one). It will revolutionize your file management and has all kinds of possibilities for automation. You can still use the coupon TERPSTRA2023 to get 20% off (click here to apply).

Next up is Noteplan. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-10T12:30:00-06:00 Halp: Universal help for Fish https://brett.trpstra.net/link/535/16436713/halp-universal-help-for-fish https://brett.trpstra.net/link/535/16436713/halp-universal-help-for-fish Fish, help, command, function, editor
总结:
这篇文章介绍了作者将自己的通用“help”命令移植到了Fish上。通过使用halp命令,用户可以方便地获取命令的帮助信息,无需考虑帮助信息来自哪个渠道。作者还提到了安装该函数的方法,以及如何编辑该函数以适应用户需求。此外,作者还分享了一个有用的Fish函数,可以让用户使用自己喜欢的文本编辑器编辑Fish函数。最后,作者鼓励读者查看他的公共Fish函数,并邀请他们点赞或分享这篇文章。

I’ve had it out there for a while, but I thought I’d point out that I’ve ported my universal “help” command to Fish. halp removes the hassle of figuring out whether a command’s help comes from man CMD, help CMD, CMD -h, or type CMD. Just run halp CMD (where CMD is the command you want help on) and it will figure out the rest.

To install the function, just save the halp.fish file to ~/.config/fish/functions. Once there, you can just type halp CMD to get an appropriate help screen, whether it has a man page, a help page, command line help, or is an alias or function. By default it’s set up to use Dash for Fish native commands (rather than opening your browser), but you can edit the function to change that (see the comments). That requires that you’ve installed the Fish docset (Dash Preferences->Downloads->User Contributed). My local version of the function also replaces the man $cmd line with open "dash://man%3A$cmd" to open man pages in Dash (requires the manpage docset). Edit as needed to make it work for you.

As an aside, if you regularly edit Fish functions, it can be handy to use your favorite text editor rather than Vim or the internal editor. I have a function called funcsubl that wraps the funced command with subl -w and autosaves after closing the window. You can modify this to work with any editor, you just need a “wait” flag (like subl -w). Here’s my version.

Check out all my public Fish functions in the GitHub repo.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-08T11:46:00-06:00 Hazel giveaway! https://brett.trpstra.net/link/535/16431556/hazel-giveaway https://brett.trpstra.net/link/535/16431556/hazel-giveaway Hazel、automations、files、sort、giveaway Hazel是一个可以根据文件的更改情况创建自动化的软件,可以对PDF文件进行自动归档、对下载文件进行分类、对新图像进行优化处理等。它支持根据文件名、日期或属性的组合进行重命名、分类和标签等操作。并且结合强大的模式匹配功能,可以根据自己的方式来处理文件。本次活动为Hazel的五个授权证书进行抽奖赠送,价值42美元每个,抽奖将在11月10日中午12点(中央标准时间)进行。活动截止时间见文章。此外,本文提到如果通过RSS阅读此篇文章,需要到brettterpstra.com上进行参与。还有更多类似的赠送活动将会在未来进行。

I’m excited to offer the next giveaway, 5 licenses ($42 value each) for Hazel. Hazel lets you create automations based on changes to files, allowing you to do things like automatically filing PDFs, sorting downloads, running optimizations on new images, or just about any file operation you can imagine.

From the developer:

Hazel can open, archive, tag and even upload. You can have Hazel rename your files or sort them into subfolders based on name, date or whatever combination of attributes you choose. Coupled with Hazel’s powerful pattern matching, you can create workflows to process your files, your way.

Check out the Hazel site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, November 10, at 12pm Central. The drawing is for 5 licenses ($42 value each) for Hazel, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-06T08:00:00-06:00 SearchLink gets Google Search back https://brett.trpstra.net/link/535/16429946/searchlink-gets-google-search-back https://brett.trpstra.net/link/535/16429946/searchlink-gets-google-search-back Google, API key, searches, SearchLink, DuckDuckGo

总结: Google现在再次提供API key来进行搜索,每天免费搜索限制为100次。用户可以将自己的API key添加到配置文件中,以便在搜索时使用Google的功能。如果当天用完了100次搜索,系统会自动切换回之前的DuckDuckGo搜索配置。使用Google进行搜索不会引起新的隐私问题,因为这些搜索不包含任何追踪数据。SL.ddg()方法在使用插件时也会测试是否存在API key,并且在可用时将使用Google。用户需要安装最新版本的SearchLink,并生成自己的API key。

So it turns out Google now offers an API (once again). It’s limited to 100 searches per day for the free version, so I don’t want to put my API key into the public distribution of SearchLink, but if you want to tap into Google’s power for your searches, you can now add your own API key to the config and get 100 searches per day for free. If you should, for whatever reason, run out of searches in a day, it should gracefully switch out to the previous DuckDuckGo configuration.

The !g search will now test for the presence of a Google API key, and if it exists, use Google for the search. You can also use !gg to force a Google search. If there’s not a key set up, it will continue operating as it has using DuckDuckGo. As far as privacy concerns go, these searches don’t include any tracking data, so using Google in this manner shouldn’t present any new issues. For anyone creating plugins, the SL.ddg() method will also test for an API key and use Google if available.

To use this, install the latest version (download below) and then see the wiki page I created to generate your own key.

Enjoy!

SearchLink v2.3.53

Generate Markdown links from web searches without leaving your editor.

Published 11/10/14.

Updated 11/05/23. Changelog

DonateMore info…

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-05T16:27:00-06:00 The WordCounter giveaway winners! https://brett.trpstra.net/link/535/16428225/the-wordcounter-giveaway-winners https://brett.trpstra.net/link/535/16428225/the-wordcounter-giveaway-winners WordCounter giveaway, winners, announcement, tracking writing productivity, save 33% off purchase, next giveaways. 总结:

WordCounter的赠品活动已经结束,并且我有要宣布的获奖者!获奖者是Chris、Nick Taylor和Carley E Knight。如果你没收到邮件,请查看邮件中的详细信息。如果你没有赢得奖品,很抱歉,但你可以从今天开始追踪你的写作产出,并获得折扣优惠33%,使用代码DONTBESAD。接下来是下一个赠品活动,请每周一通过2024年8月检查,获取更多的赠品。下一个赠品包括:(这里省略具体赠品)。如果你想要推荐一个你想在这个系列中见到的应用,请在Twitter上或电子邮件中告诉我,并加入通知列表。喜欢或分享这篇文章。BrettTerpstra.com由像你一样的读者支持。所有材料 ©2023 Brett Terpstra。

The WordCounter giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Chris
  • Nick Taylor
  • Carley E Knight

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but WordCounter is still worth checking out. You can start tracking your writing productivity today, and get going for NaNoWriMo! You can still save 33% off your purchase using the code DONTBESAD when you buy!

Next up is Hazel. Check back every Monday through August, 2024 for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-03T13:00:00-05:00 Tower - making Git easy (and enjoyable!) to use [Sponsor] https://brett.trpstra.net/link/535/16422495/tower-making-git-easy-and-enjoyable-to-use-sponsor https://brett.trpstra.net/link/535/16422495/tower-making-git-easy-and-enjoyable-to-use-sponsor Tower、Git、features、操作、方便、易用、撤销、重拍、合并、分支、代码改动、软件团队使用、折扣优惠、学生教师免费。 总结:

总结:Tower是一款专为使Git操作变得简单和愉快而设计的应用程序。它拥有多项功能,方便用户进行Git操作,包括撤销操作、重拍提交、合并冲突、分支管理和代码改动识别等。许多世界顶级的软件团队都在使用Tower进行日常工作,而且使用代码TERPSTRA25还可享受25%的折扣优惠。对于学生和教师,Tower Pro更是免费提供。

Thanks to Tower for sponsoring BrettTerpstra.com this week! I swear by this app, and anyone who uses Git for any part of their work or play should check it out.

Tower’s mission is simple: to make Git easy and enjoyable for everyone.

All the features of our native Git client have been carefully crafted with this specific goal in mind. Here are five examples:

  1. Undo any Git operation by simply pressing CMD+Z (or CTRL+Z on Windows). This convenient keystroke allows you to easily roll back any mistakes made.
  2. Use Drag and Drop to efficiently reorder commits, cherry-pick, merge/rebase branches, or create pull requests.
  3. Solve merge conflicts easily with Tower’s Merge Wizard, which provides clear context about the conflict.
  4. Review your repository’s branches with Tower’s “Branches Review” feature. This feature helps identify stale branches or those that have already been fully merged.
  5. Enable Syntax Coloring to quickly identify changes made in every diff. Tower supports almost 200 languages, making it easy to spot differences in code.

Some of the world’s best software teams use Tower every day - on both macOS and Windows.

Learn more about Tower and begin your 30-day free trial today! Use code TERPSTRA25 to get 25% off your first year. And if you are a student or teacher, you can get Tower Pro for free!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-02T08:00:00-05:00 Web Excursions for November 01, 2023 https://brett.trpstra.net/link/535/16420745/web-excursions-for-november-01-2023 https://brett.trpstra.net/link/535/16420745/web-excursions-for-november-01-2023 teleprompter, iOS/Mac, web version, Alfred workflow, Notes, console.table() 总结: teleprompter是一个简单的概念,但很多人都搞砸了。Teleprompter Premium是我最喜欢的iOS/Mac应用,同一开发商刚刚发布了一个网络版。它的价格比我预期的要高一些,但在11月3日之前注册可以获得终身50%的折扣。 很高兴看到新版本的Alfred workflow开始流行。它可以基于模板文件创建新项目。 我必须承认,Notes已经成为了一个强大的应用程序。我从来没有想到苹果会对它进行如此多的开发。 我终于明白了console.table()的实用性。 Backblaze可以安全地将您整个计算机备份到云端,价格实惠可靠。我非常信任它来保护我的所有数据。

Web excursions brought to you in partnership with Backblaze. Back up everything.

CloudPrompter
The idea of a teleprompter is simple, yet so many people screw it up. Teleprompter Premium is my favorite on iOS/Mac, and the same devs have just released a web version of the same. It’s a bit pricier than I think it should be, but you can get a lifetime 50% discount for signing up before Nov 3rd.
“Planter” redux for Alfred
Nice to see a new version of Planter taking root. An Alfred workflow for creating new projects based on a template file.
A Closer Look at Apple Notes’ Smart Folders
I have to admit Notes has become a killer app. I never would have guessed Apple would put this much development into it.
Quick tip: Getting all links from any web site into a spreadsheet using browser developer tools
I finally get how useful console.table() can be.

Backblaze securely backs up your entire computer to the cloud, affordably and reliably. I trust it with all my data. Check it out today.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-01T14:00:00-05:00 Searchlink, not just for searching https://brett.trpstra.net/link/535/16420225/searchlink-not-just-for-searching https://brett.trpstra.net/link/535/16420225/searchlink-not-just-for-searching SearchLink, plugins, text filter, calendar, MakeADate. 总结: SearchLink是一个用于链接网站、应用程序页面、Gist嵌入以及其他博客、网页写作或展示注释的工具。文章介绍了如何安装和贡献插件,并提供了一些示例代码。此外,还介绍了几种可以使用SearchLink的插件,包括MixCase(用于随机大写字符)、Calendar(插入Markdown日历)、MakeADate(插入格式化日期)。该文章鼓励读者通过查看提供的代码,生成自己的插件,并鼓励分享。

First, I’ve created a repo for SearchLink plugins. This is mostly going to be example code, but you might find some useful ones in there. If you’ve never checked out SearchLink and do any kind of writing that requires linking to web sites/pages, app landing pages, Gist embeds, or basically any kind of blogging, web writing, or show notes, you should check it out.

See the plugin repository for details on installing and contributing. All of the available searches in SearchLink are defined as plugins, so you can also use those as examples.

Text Filters

One thing I wanted to explore was using SearchLink for more than just searches. I created a couple proofs of concept as plugins. Some of these make more sense as TextExpander snippets, but I wanted to experiment, so here’s what I came up with.

MixCase

This plugin is a text filter that will turn !mix A string of text into A STRInG of TExT, randomly capitalizing characters. It’s just to demonstrate how easily a text filter can be implemented (if you know a little Ruby, anyway).

Calendar

Another example of a text filter. This one can insert a Markdown calendar for any month and year. You can define the month and year like !cal 5 2024 to get a calendar for May, 2024. If you use !cal now it will insert a calendar for the current month and year. It can also print how many days are in a month with !days 2 2024 to show how many days are in February in 2024. Silly, and again would probably be better as a TextExpander snippet, but I’m just experimenting with extending SearchLink.

MakeADate

This is a port of a TextExpander snippet I use. It takes a natural language date and inserts a formatted date. It provides the following formats:

Abbr Result
!ddate tomorrow 8am 2023-11-02 8:00am
!dshort 2/2/24 6:30am 2024-2-2 6:30am
!diso tomorrow 1pm 2023-11-02 13:00
!dlong tomorrow 8am Thursday, November 2nd, 2023 at 8:00am

All of the searches can be abbreviated to two letters, with !diso becoming !di, !dlong becoming !dl, etc.

This plugin requires that PHP be installed on the system, either with the Apple Command Line Utilties (I think), or with Homebrew (brew install php).

Contributing

Use the fully-commented code in lyrics.rb (documented in the SearchLink wiki) to generate your own plugins, and reference the existing searches for inspiration. Feel free to fork and submit a PR to the plugin repository if you create something you’d like to share!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-11-01T10:01:00-05:00 SearchLink Fixes https://brett.trpstra.net/link/535/16416050/searchlink-fixes https://brett.trpstra.net/link/535/16416050/searchlink-fixes 2.3.50, DuckDuckGo, fixes, tests, SearchLink v2.3.50 修复了DuckDuckGo响应中的一些问题,目前通过了所有测试,除了一个。该版本能够将网页搜索转换为Markdown链接。源代码托管在GitHub上,可以将其编译为命令行使用的gem。每个搜索都是SearchLink,并且可以很容易地添加新的搜索类型。如果您对SearchLink进行了扩展,请务必提交Pull Request,并参与开发。可以在链接中下载该版本,并查看详细信息。总结: 2.3.50版本修复了DuckDuckGo响应中的问题。该版本通过了大多数测试,但仍有一个测试未通过。SearchLink可以将网页搜索转换为Markdown链接,并提供了扩展功能。源代码托管在GitHub上,可以将其编译为命令行使用的gem。项目欢迎开发者提交Pull Request参与开发。

SearchLink 2.3.50 is out and contains fixes for some recent changes in DuckDuckGo’s responses. It currently passes all tests except for one (TMDB is returning a movie for the search result “Brad Pitt”, rather than the actor page, and when I add “actor” to the search it dumps out to IMDB, which I don’t fully understand).

Don’t forget that the source code is all neatly organized on GitHub and you can compile the whole thing as a gem for command line usage, if you like. Every search is a plugin and you can add new search types pretty easily. If you do extend SearchLink at all, be sure to make a Pull Request and be part of the development!

Download below, and see the SearchLink project page for more details!

SearchLink v2.3.50

Generate Markdown links from web searches without leaving your editor.

Published 11/10/14.

Updated 10/29/23. Changelog

DonateMore info…

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-30T09:19:00-05:00 WordCounter giveaway! https://brett.trpstra.net/link/535/16415970/wordcounter-giveaway https://brett.trpstra.net/link/535/16415970/wordcounter-giveaway WordCounter, giveaway, licenses, writing productivity, tracking words

总结:这篇文章介绍了一个名为WordCounter的应用程序,以及一个赠品活动,提供3个价值19.99美元的许可证。WordCounter是一个可以追踪写作生产力的应用程序,能够记录你每天的写作成果和目标,并且可以在任何应用程序中自动记录写作量。它将写作过程中所产生的字数作为度量标准,给予作家实时反馈和鼓励,并且保留了每天的成就记录,帮助作家找到最适合他们的写作环境。想要参加赠品活动的读者需要在指定时间内报名。文章最后还提到了未来几年的赠品活动,并鼓励读者推荐希望在活动中推广的应用程序。

I’m excited to offer the next giveaway, 3 licenses ($19.99 value each) for WordCounter. Just in time for NaNoWriMo, WordCounter is an app for writers who want to track the most important metric in their daily goal: how many words you write and where. It records your writing productivity automatically in any app, allowing you to just write.

From the developer:

The WordCounter gives immediate feedback on your productivity as a writer, encourages you by showing you your daily output, gives you clarity about your daily goals, keeps a complete history of your daily achievements, assists with finding your perfect writing environment, counts what counts: words – the ultimate metric for writing.

Check out the WordCounter site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, November 03, at 12pm Central. The drawing is for 3 licenses ($19.99 value each) for WordCounter, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August, 2024 (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list or follow me on Mastodon so you can be (among) the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-30T08:00:00-05:00 The Scrivener giveaway winners! https://brett.trpstra.net/link/535/16413505/the-scrivener-giveaway-winners https://brett.trpstra.net/link/535/16413505/the-scrivener-giveaway-winners Scrivener, giveaway, winners, coupon, next giveaways

总结: Scrivener的赠品活动已经结束,其中的赢家是Philip Zastrow,David Lynch和paul kesselma。如果你没有赢得赠品,可以使用优惠券Brett-Scriv-2023来购买Scrivener并节省20%的费用。下一轮的赠品活动将在未来的几个星期内进行,有关具体信息,请访问网站。请在社交媒体上点赞或分享此文章以获取更多相关信息。

The Scrivener giveaway has ended, and I have winners to announce!

The winners!

Congratulations to:

  • Philip Zastrow
  • David Lynch
  • paul kesselma

You should have received an email with details, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Scrivener is still worth checking out. If you’re a writer, you really should be using Scrivener, and you can still save 20% off using the coupon Brett-Scriv-2023 at checkout. You’ll want it for NaNoWriMo, or just for your next writing project!

Next up is WordCounter. Check back every Monday through August for more giveaways. The next giveaways include:

See the full list of upcoming giveaways!

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-27T13:00:00-05:00 Sanebox and implementing the Eisenhower Matrix [Sponsor] https://brett.trpstra.net/link/535/16411504/sanebox-and-implementing-the-eisenhower-matrix-sponsor https://brett.trpstra.net/link/535/16411504/sanebox-and-implementing-the-eisenhower-matrix-sponsor SaneBox, email management, Eisenhower Matrix, organized, efficient

总结: SaneBox是一个高级的电子邮件管理工具,通过与Eisenhower Matrix(艾森豪威尔矩阵)的结合,能够帮助用户实现电子邮件的高效整理和组织。通过创建自定义文件夹并将电子邮件分类到不同的象限,SaneBox可以根据用户的喜好和优先级来自动过滤和整理邮件。这种方法使用户能够将电子邮件管理变得有条不紊,从而获得一个独特的个性化电子邮件体验。如果你被一大堆电子邮件淹没,感到压力大,不妨尝试一下SaneBox和Eisenhower Matrix的组合。对于那些希望有一个高效有序的电子邮箱系统的人来说,这是一个值得尝试的选择。

Thanks to Sanebox for sponsoring BrettTerpstra.com again this week! I don’t know what I’d do without it!

Envision your email as a bustling conference hall, filled with diverse attendees. Professional correspondences, casual updates, informative newsletters, enticing promotions, and the occasional unwelcome intruder all vying for your attention. Now, consider a seasoned curator (inspired by the Eisenhower Matrix) coordinating the event, teamed up with an expert organizer (the prowess of SaneBox) to streamline the flow and ensure a harmonious gathering. This is the synergy we’re spotlighting.

SaneBox, our sophisticated digital tool, acquires proficiency much like a dedicated student mastering a new subject. Each interaction with your emails refines its algorithm, enhancing its efficiency. When combined with the strategic principles of the Eisenhower Matrix, which prioritizes tasks based on urgency and significance, you’re presented with a seamlessly integrated email management system.

Let’s get practical. The Custom Folders inside of SaneBox let you decide what’s important to you and where it belongs on the Eisenhower Matrix. Start by creating folders for each quadrant. The traditional Eisenhower Matrix works like this:

  • Urgent and Important (Quadrant I): These are tasks that need immediate attention and are crucial to your goals.
  • Not Urgent but Important (Quadrant II): These are tasks that contribute to your long-term goals and values but don’t require immediate attention.
  • Urgent but Not Important (Quadrant III): These tasks demand your immediate attention but aren’t critical to reaching your long-term goals.
  • Neither Urgent nor Important (Quadrant IV): These are the tasks that provide little to no value and can often be deferred or even deleted.

Once you’ve created your folders (and named them whatever you want), start moving emails into their appropriate places. It won’t take long for SaneBox to learn what’s important to you. Then you can be selective about which folders get attention and when.

But it’s more than just cleaning up. This method helps shape an email experience that feels uniquely yours. Merging the practical approach of the Eisenhower Matrix with SaneBox’s functions, your inbox goes from being chaotic to organized and manageable.

If you’re among those buried under a mountain of emails, feeling the strain, it’s worth trying the combination of SaneBox and the Eisenhower Matrix. And remember, signing up today can even get you a $25 discount on any subscription. Your emails deserve a system that works.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-26T08:00:00-05:00 Introducing the BrettTerpstra.com Forum https://brett.trpstra.net/link/535/16408585/introducing-the-brettterpstra-dot-com-forum https://brett.trpstra.net/link/535/16408585/introducing-the-brettterpstra-dot-com-forum nerdy, forum, projects, interaction, community

总结: 作者创建了一个名为"nerdy"的论坛,目的是为了集中讨论各种项目并增加与读者的互动。作者之前的项目讨论都分散在不同的地方,现在希望通过这个统一的论坛来解决这个问题。作者选择论坛的原因是因为它是异步的,可以按照自己的时间参与讨论,并通过邮件通知了解回复。论坛的网址是forum.brettterpstra.com,作者使用了DigitalOcean和Mailgun来提供托管和通知的服务。此外,作者还将博客评论转移到了论坛上,并邀请读者来参与讨论。最后,作者希望读者能积极参与,并将读者的社群变得更活跃。

I’ve created a forum for discussing all things nerdy, the BrettTerpstra.com Forum. I wanted a place to have conversations about my various projects, but also to allow more interaction with my readers. I’ll be active on it, and I hope you will too.

Right now every one of my projects has different discussion forums, mostly hosted on GitHub, but they’re separated by project and there’s no unified place for support, questions, feature requests, and actual interaction. This is my attempt to consolidate and also increase interaction with the community.

I’m nervous about launching this because I fear nobody will talk and I’ll feel unpopular, but I won’t know until I try. I know, one more place to be active online, one more source of notifications, yet another place to chat. I know we all have too many of these. I chose this format over a Discord server or other synchronous communication because I like that it’s _a_synchronous. You can show up when you feel like it, and just get email notifications about responses to your conversations, waiting until you have the time to add to the discussion.

The forum is at forum.brettterpstra.com. Here’s a special invite link that will get you in and give you immediate access to introduce yourself and join/start a conversation.

I set this up using the Discord droplet on DigitalOcean, which is a very affordable way to host cloud applications, if you’re ever interested in building your own. I’m also using a free account at Mailgun to handle notification emails and such.

I’ve switched the comments on this blog over to using the forum as an embed. Each blog post will create a new topic on the forum, and you’ll be able to discuss and add comments via Discourse. It will require login (you can log in with GitHub or email), but should offer a saner way to handle comments on my posts. Give it a shot on this one and let me know what you think! In the process I’ve lost all comment history, but it is what it is.

I sincerely hope you’ll join, participate, and make a community out of my readership. Don’t be shy. I have 20,000 site viewers, 35,000 RSS subscribers, 13,000 Twitter followers, 2500 Mastodon followers, 9000 GitHub stars, and yet I still have a hard time getting interaction… I’d love to hear from you!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-24T12:14:00-05:00 Scrivener giveaway! https://brett.trpstra.net/link/535/16406637/scrivener-giveaway https://brett.trpstra.net/link/535/16406637/scrivener-giveaway Scrivener, writers, giveaway, licenses, app

总结: 这篇文章介绍了一次赠送活动,提供了3个Scrivener的许可证作为奖品。Scrivener是一款针对作家的终极应用程序,可以帮助组织故事、添加研究文献并提供各种写作支持。它拥有故事组织功能、角色追踪和完整的写作工具,是市面上最全面的写作应用程序之一。这次赠送活动将在10月27日中午12点随机抽取三名获奖者,每人获得一份价值59美元的Scrivener许可证。此外,文章还提到Scrivener被各类作家广泛使用,并不会教你如何写作,而是提供你开始写作和保持写作所需要的一切。在文章最后还提到了BrettTerpstra.com网站以及其他即将进行的赠送活动。

I’m excited to offer the next giveaway, 3 licenses ($59 value each) for Scrivener. Scrivener is the ultimate app for writers. Organize your story, add research, and get to writing with full support for notes, links, footnotes, rich text, Markdown and so much more. With story organization features, character tracking, and a complete set of writing tools, it’s the most fully-fledged writing app you’ll find. Get ready for NaNoWriMo! (By the way, it also integrates well with Marked 2.)

From the developer:

Scrivener is the go-to app for writers of all kinds, used every day by best-selling novelists, screenwriters, non-fiction writers, students, academics, lawyers, journalists, translators and more. Scrivener won’t tell you how to write—it simply provides everything you need to start writing and keep writing.

Check out the Scrivener site for more info.

Sign up below to enter. Winners will be randomly drawn on Friday, October 27, at 12pm Central. The drawing is for 3 licenses ($59 value each) for Scrivener, one per winner. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through August (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list so you can be the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-23T08:00:00-05:00 iTunesIcon updated https://brett.trpstra.net/link/535/16405699/itunesicon-updated https://brett.trpstra.net/link/535/16405699/itunesicon-updated grabicon.rb, iTunes, app icon, automating giveaways, ImageMagick 抓取 iTunes 中的应用图标需要使用 grabicon.rb 脚本,该脚本可以自动化抓取应用程序的图标并进行处理。脚本支持定义平台(mac、iOS、iPad、iPhone)和图标大小(小、中、大或特定像素尺寸),如果本地应用程序找不到图标,则会在 iTunes 中搜索并返回第一个结果。对于 Mac 平台,可以从 Assets 文件中提取图标以获取更高分辨率的图标。对于 iOS 平台,脚本会自动进行圆角处理和调整图像大小。脚本还提供了多种选项和参数来定制图标的抓取和保存。该脚本作为自动化抓取应用图标的一部分,并且非常实用。 总结:

grabicon.rb 是一个用于从 iTunes 抓取应用图标的脚本工具。这个工具可以根据定义的平台和大小抓取图标。支持的平台有 Mac、iOS、iPad、iPhone,支持的大小有 small、medium、large 或者特定的像素尺寸。在搜索本地应用图标时,如果找不到匹配的图标,则会转而搜索 iTunes 并返回第一个结果。对于 Mac 平台,可以从 Assets 文件中提取图标以获得更高的分辨率。对于 iOS 平台,脚本会自动进行圆角处理和图像调整。脚本提供多种选项来定制图标的抓取和保存。该脚本已经通过 ImageMagick 进行了测试,可以正常工作并提供了很大的实用性。

A long time ago I published a tool called iTunesIcon that would grab an app icon from iTunes. It worked well in its time, but has been mostly broken in recent years. It was designed mostly for writers who were reviewing apps and needed to get an app’s icon for artwork, but could be used by anyone with a need for such things.

As part of automating the giveaways I’m running, I’ve had a need to start grabbing app icons again, so I’ve revived the project. This script requires installing ImageMagick for rounding the corners of iOS icons (brew install imagemagick).

I previously had a shell function called geticonpng that read a local app’s icon file. These days, most local Mac apps tend to store their icons in Assets.car archives, so the default .icns file only has images up to 256 pixels in most cases. I’ve worked around that. And when a local icon can’t be found, I’m falling back to searching iTunes, replicating the behavior of iTunesIcon. This script handles the following:

  • Allow defining platform (mac, iOS, iPad, iPhone)
  • Allow defining size (small, medium, large, or specific pixel dimensions)
  • If the platform is Mac, test for a local copy from which to extract the icon
  • If the platform is iOS or a local Mac app isn’t found, search iTunes and return the first result
  • If the platform is Mac and a local version is found, extract the icon from the Assets file to allow higher resolutions
  • If the platform is iOS, automatically round the corners and resize the image

Here’s the (Ruby) script. It handles all of the above.

Platform can be defined in two ways:

  1. Use the -d DEVICE flag when running the script. This can be ios, iphone, ipad, or mac
  2. Add a modifier to the search terms in the form of @ios, @iphone, @ipad, or @mac, e.g. OmniFocus @ipad

Similarly, size can be defined using:

  1. Use the -s SIZE flag, which can be s(mall), m(edium), or l(arge) or a specific pixel dimension (square), e.g. grabicon.rb -s small OmniFocus
  2. Use a modifier in the search terms in the form of %s(mall), %m(edium), %l(arge) or a specific pixel dimension, e.g. OmniFocus %1024

Modifiers in the search terms override flags given to the script.

If a local copy can be found, the asset will be extracted at any size specified. If searching iTunes, you’re generally limited to 1024px, depending on the assets the app has provided. The nearest icon format will be downloaded, and ImageMagick will convert to specific pixel dimensions. Note that when downloading an iOS icon, the artwork provided is square, so the script will round the corners and add 10% padding around the icon (using ImageMagick) to offer similar dimensions to what Mac icons have or what you see on your iOS device screen.

All options:

Usage: grabicon.rb 'APP NAME/SEARCH TERM' [@PLATFORM] [%SIZE]
       @ and % modifiers override options

OPTIONS:
    -p, --preview                    Show a Quick Look preview after saving
    -s, --size SIZE                  Size to save (small, medium, large, or pixels)
    -d, --device PLATFORM            Platform to search (mac, ios, iphone, ipad)
    -o, --output PATH                Path to save icon to (default ~/Desktop/ICON.png)
    -h, --help                       Display this screen

This is working well for me so far. I’ll publish the rest of the giveaway automation in the future, as it uses some ImageMagick commands I think might be useful to other people. But for now, this is the new iTunesIcon script.

To install the script, save the raw version to a file called grabicon.rb in your PATH, and then run chmod a+x PATH/TO/grabicon.rb. Once that’s done, just run grabicon.rb -h to see available options.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-22T15:27:00-05:00 Automating the giveaways https://brett.trpstra.net/link/535/16394621/automating-the-giveaways https://brett.trpstra.net/link/535/16394621/automating-the-giveaways 自动化、赠品、开发者、订阅、时间跟踪

总结: 这篇文章讲述了作者在博客上进行一系列赠品活动的情况。作者自豪地分享了他建立的令人印象深刻的自动化系统,用于管理赠品活动的各个方面。作者通过一个主YAML文件来管理每个赠品的信息,并使用脚本生成包括赠品公告、电子邮件、中奖者名单等在内的各种组成部分。赠品的实施方式可以是邮件、优惠券或代码,具体取决于开发者的偏好。作者还分享了他使用的各种脚本和工具,以及这些自动化流程带来了巨大的时间节省。最后,作者提到他愿意提供帮助,包括分享代码、免费的咨询以及收费的自定义开发服务。

You may have noticed I’m running a series of giveaways on this blog. Literally every developer I’ve reached out to has been willing to put up 1-10 licenses or 1-year subscriptions for their app, and I’m extremely pleased with the list I’ve put together. In an effort to keep track of all of them, I’ve built some (if I do say so myself) impressive automation around this project, and I thought I’d share. It’s some mad science, but it’s working great and I kinda want to brag about it.

For every giveaway, there are 5 major pieces:

  1. The announcement post containing the form to enter for the drawing, on Monday
  2. An announcement email to subscribers linking to the announcement post, also on Monday
  3. A followup email on Thursday reminding subscribers there’s still time to enter
  4. A drawing of the winners, and notification emails sent to them, on Friday
  5. An announcement post listing the winner’s names and upcoming giveaways, also on Friday

So here’s how it works. I have a master YAML file where each giveaway has the following info:

- app_name: Timing
  contact: [Hookmark link to email conversation with developer]
  dev_email: Daniel Gräfe <REDACTED>
  keywords: [productivity, time tracking, timing]
  dev_link: https://timingapp.com/
  offer: a 1-year subscription ($108 value)
  number_of_prizes: 1
  followup: I guarantee it will be useful for anyone who needs to know where they spend there time, for any reason.
  fulfillment: emails
  giveaway_slug: [secret giveaway slug]
  blurb: >
    I use Timing daily and it's helped me automatically track time that I would never have had the discipline to
    manage on my own. Billable hours, time I spend on personal projects, time I spend gaming, pretty much
    anything I do on my Mac, my iPhone, or my iPad gets tracked and I can easily categorize based on rules
    (that are as easy as dragging and dropping to generate). I even integrated it with
    [Doing](https://brettterpstra.com/projects/doing/) for adding depth to my "What Was I Doing" tracking.
  dev_blurb: >
    Just keep focusing on your work while Timing records your time automatically, then review your time when you
    want to. Record time faster than ever with just a few clicks. See when you worked on what and how
    productive you were.
  screenshot: /uploads/2023/09/timingscreenshot.jpg
  setapp: true

It takes me about 10 minutes to build an entry. I have to write out my personal blurb, get a developer blurb from the website, and generate images including a screenshot (usually pulled from the website and automatically sized and converted by a Hazel script when I save it to my desktop) and a blog header and winner post header1. (Social sharing images and WEBP versions are automatically generated from the header images using RetroBatch.) So that’s the bulk of the creation time.

Slotting a new giveaway in is simply a matter of adding a new entry like above to the YAML array, and I can slot them in at any point and all of the dates will adjust accordingly.

When my giveaways.rb script runs, it goes through this YAML file and generates all of the pieces mentioned above. It has a start date hardcoded for the start of this series, and then for each giveaway entry it adds 7 days, and sets a drawing date for the following Friday. It uses ERB templates to generate the giveaway announcement (including blurbs and screenshot), the two emails, and the winner announcement (including the followup text). The winner announcement, which gets saved to my drafts folder, includes a note letting me know exactly what command to run to execute the drawing, including how many winners to draw, where to pull the fulfillment codes from, etc. The winner announcement is also “hooked” to the conversation with the developer using Hookmark, so I can easily jump back to it. It also creates a list of upcoming giveaways, saved twice, once to a Markdown file with the secret slugs used to populate and query the Firebase database for the drawing, and once to a list that becomes publicly viewable.

The fulfillment key can be one of emails, coupons, or codes, and depends on the developer’s preference for fulfilling the giveaway. If there are coupons or codes, those get a YAML array listing them and they’re written out to an individual YAML file that the Giveaway Robot will read. The Giveaway Robot (the script that does the random picking of entrants) reads the appropriate type of fulfillment file and sends a notification email to each of the winners containing a link, a redeem code, or notification that their email has been shared with the developer (who gets cc’d based on the dev_email setting) who will be in touch with a license.

The emails that are generated are in Markdown format, saved locally. On the week that a giveaway is going to run, I run a script called create_giveaway_emails.rb APP_NAME, where app name is just something like App Tamer or Timing. That will find and render the generated Markdown files, apply my BrettTerpstra.com styling, and use the Sendy API to create and schedule both emails for the week.

All of these moving pieces of this are a lot to track, so the script includes notes at every pertinent point letting me know which script needs to be run, and also generates a calendar entry with an alert that links (Hookmark) to the necessary notes, which literally tell me exactly which command to run and what to do with the output.

There’s a Jekyll plugin that generates and runs the giveaway form. I just include:

{% giveaway SLUG ISO_END_DATE %}

which is generated automatically by the giveaways.rb script in the announcement post, and all entries will go to a Firebase database named for the SLUG. At the end of the giveaway, I just give the same slug to the “robot” and it uses random number generation to pick winners. The robot (run by the command in the winner announcement post note) generates emails to the winners, saves a list of names and emails, and outputs a list of winner names to the Terminal, ready for pasting into the winner announcement post. Actually it also uses pbcopy to put the list right into my clipboard and opens the winner post for pasting…

So, aside from the time it took to build all of this automation, my effort per giveaway is:

  • email discussion with the developer, nailing down number of copies and fulfillment options, 10m elapsed time per giveaway
  • edit the master YAML file with details, 10m
  • run the giveaways.rb script, 5s
  • on Sunday
    • edit and publish the generated giveaway post for the week, 2m
    • run the create_giveaway_emails.rb script to generate the emails, 5s
    • double check the emails and scheduling because I don’t fully trust the automation, 2m
  • on Wednesday
    • share the giveaway reminder to social media, 5m
  • on Friday
    • run the giveaway robot using the command already saved in the winners post, 1m
    • edit the giveaway post with the list of winners returned by the robot, 2m

So, now that the automation is built, it takes me approximately 23 minutes to add and run a giveaway. This would take me at least 3 hours per week if I were doing this manually every time, with the multiple posts, the multiple emails, and the drawing/notification, plus all of the tracking down of previous conversations and handling of codes for every giveaway. So this automation is easily saving me almost 3 hours per giveaway, and with nearly 40 giveaways currently lined up (and growing), that’s almost 120 hours of time saved already. Easily worth the ~8 hours I put into building it.

I doubt all of the scripts behind this will be of use to anyone else as is, but if you want to create any kind of similar automation, I’m available to help. If you just want to see my code to alter on your own, I’ll share it for free, and if you want to hire me to build something out for you, I charge a reasonable hourly fee. If I ever lose my cushy corporate job, this is exactly the kind of thing I would love to freelance on, so keep me in mind for that fateful day.

  1. All of these header images are the same background with an app icon rotated and positioned in the hand of the “giveaway robot,” but I haven’t yet been able to automate the generation of these images. I just need to extract a PNG from the app (easy), then size, rotate, and position it over a static background. RetroBatch can’t do it, so if anyone has any grand ideas, I’d love to hear them. I bet ImageMagick could do this, but I get into rabbit holes when I start looking into it… 

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-14T08:00:00-05:00 The Hookmark giveaway winner! https://brett.trpstra.net/link/535/16394031/the-hookmark-giveaway-winner https://brett.trpstra.net/link/535/16394031/the-hookmark-giveaway-winner Hookmark giveaway, winner, congratulations, coupon, upcoming apps 总结: Hookmark赠品活动已经结束,获奖者是Marcus Phelan。如果你没有获胜,可以使用优惠券TTSCOFF在接下来的一周内享受30%的折扣。接下来是其他的应用赠品活动,可以在BrettTerpstra.com上获取更多信息。总的来说,这篇文章主要是宣布了Hookmark赠品活动的获胜者,同时提供了优惠信息和未来的赠品活动预告,希望读者可以关注并参与。

The Hookmark giveaway has ended, and I have a winner to announce!

The winners!

Congratulations to:

  • Marcus Phelan

You should have received an email and the developer will be in touch, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Hookmark is still worth checking out. It will change the way you work. You can still save 30% off for the next week using coupon TTSCOFF at checkout (click on Add Discount)!

By the way, Hookmark is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is TextExpander. Check back every Monday through June for more giveaways.

Other upcoming apps include:

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-13T12:35:00-05:00 Hookmark giveaway! https://brett.trpstra.net/link/535/16386371/hookmark-giveaway https://brett.trpstra.net/link/535/16386371/hookmark-giveaway Pro license, Hookmark, giveaway, tool, track Pro license是本文介绍的奖品,Hookmark是一个工具,通过这个工具可以追踪一切,包括链接、笔记、文档和任务。文章宣布的是一次赠品活动,随机抽取一个人获得Hookmark的Pro许可证。Hookmark可以将用户的研究和开发内容连接在一起,并且可以与其他应用程序进行连接。截止日期为10月13日,读者需要在brettterpstra.com上阅读此文章才能参加活动。总结:Pro许可证,赠品活动,用于追踪的工具,与其他应用程序连接,需要在brettterpstra.com上参加活动

I’m excited to offer the next giveaway, a Pro license ($69.99 value) for Hookmark. Hookmark is the ultimate tool for keeping track of all of your stuff. Your links, your notes, your documents, your tasks… Hookmark makes everything linkable and provides easy navigation between related objects. It takes a minute to work it into your workflow, but once you do, you’ll wonder how you lived without it.

From the developer:

Hookmark connects information in and between great apps such as Obsidian, Bookends, Zotero, DEVONthink, Craft, OmniOutliner Pro, Bike, Curio, Marked2, TextMate, Scrivener, Tinderbox, GoodTask, Nisus Writer, Nitro PDF, Skim, Sketch, Bike, OmniGraffle, HoudahSpot, LibreOffice, MailMate, Airmail, Apple Mail, Word, Excel, Powerpoint, BBEdit, Things and many more. Hookmark links your research and development!

Check out the Hookmark site for more info.

Sign up below to enter. A winner will be randomly drawn on Friday, October 13, at 12pm Central. The drawing is for a Pro license ($69.99 value) for Hookmark. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through April (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list so you can be the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-09T08:00:00-05:00 Marked and Bear https://brett.trpstra.net/link/535/16385532/marked-and-bear https://brett.trpstra.net/link/535/16385532/marked-and-bear Marked, Bear compatibility, Sonoma, custom preprocessor, syntax handling.

总结: 这篇文章介绍了最近发布的Marked版本修复了与Bear兼容性的问题,并提供了一个定制的预处理器来处理Bear语法。通过使用Bear样式和预处理器,用户可以在Marked中获得与Bear相同的预览样式,也可以选择自定义样式。用户可以按照文章提供的步骤来安装Bear样式和预处理器。文章还介绍了如何处理Bear特定的语法,并提供了相应的代码示例。最后,文章提到了可能将来直接在Marked中添加对Bear语法的支持的可能性。

Recent releases of Marked have fixed Bear compatibility on Sonoma. As part of this, I’ve updated the Bear style for Marked, and written a little custom preprocessor to handle Bear’s (CommonMark) syntax properly. If you want a Marked preview styled to look exactly like Bear (with all of Marked’s options for export, navigation, and other features), you can use the Bear style in combination with the preprocessor, but if you just want Bear’s syntax properly interpreted, you can use the preprocessor with the style of your choosing1.

To get the Bear style, go the the Style Gallery and open the Bear style. Click “Install” to add it to Marked in one click.

For the custom preprocessor to work, you’ll need Ruby available on your system. As far as I know, Ruby is still distributed with macOS (for now), and if you open Terminal and run which ruby, you should get a path back, e.g. /usr/bin/ruby. If this isn’t the case for you and you need further help, please post on the support forum and I’ll update the instructions as needed.

For handling Bear’s specific syntax, like [[links]], underlining, and strikethrough, you’ll need a custom preprocessor. Save the following to a file called bear-preprocessor.rb in a safe folder (one you won’t move in the future).

#!/usr/bin/env ruby
# frozen_string_literal: true

require 'cgi'

input = $stdin.read.force_encoding('utf-8')

input.gsub!(/\[\[(?<content>.*?)\]\]/) do
  m = Regexp.last_match
  title = CGI.escape(m['content']).gsub(/\+/, '%20')
  callback = CGI.escape("bear://x-callback-url/create?title=#{title}").gsub(/\+/, '%20')
  "[#{m['content']}](bear://x-callback-url/open-note?title=#{title}&x-error=#{callback})"
end

input.gsub!(/==(.*?)==/, '<mark>\1</mark>')

input.gsub!(/~~(.*?)~~/, '<del>\1</del>')

input.gsub!(/~(.*?)~/, '<span class="underline">\1</span>')

puts input

Open terminal and run chmod a+x /path/to/file/bear-preprocessor.rb. That will make it executable, then you can just add /path/to/file/bear-preprocessor.rb as your custom preprocessor path in Marked->Advanced preferences. (To get the absolute path for a file, right click it in Finder, hold down Option, and click ‘Copy “bear-preprocess.rb” as Pathname’. That will put the absolute path to the file in your clipboard, which you can paste for both the chmod command and the Custom Preprocessor field.)

This script will convert [[wiki links]] into Bear internal links, which will open linked notes in Bear when clicked, and handle special cases like ~~strikethrough~~, ~underline~, and ==highlighting==`.

In addition, you’ll want to set your Processor to MultiMarkdown and enable “#Text is tag” and the sub-item “Style tags” in Preferences->Processor. Note that the #tag processing will only work if you’re not using a custom processor (custom preprocessor like above won’t override it).

If you need additional help setting this up, just ping me on http://support.markedapp.com.

If you’re using a non-Bear Style and want underlines formatted, you can modify a custom Style or add the following to Marked->Preferences->Style->Additional CSS and modify as desired:

.underline {
border-bottom: 1px solid rgb(222, 84, 86);;
}

I might eventually add support for Bear (CommonMark) syntax directly to Marked, but the whole purpose of the preprocessor functionality was to handle cases like this, and linking to Bear documents internally should be a case-by-case decision. The same part of the custom preprocessor that handles [[links]] could be repurposed for any system that allows internal [[linking]] and has a url handler syntax (like nvUltra, which I’ll post a preprocessor for when it’s available2, or Obsidian). You can also always set up CommonMark as a custom processor to get full compatibility.

  1. It won’t include underline styling unless you add it to your Style, as detailed below 

  2. you don’t believe me at this point, which is fully understandable, but it really is coming. 

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-08T17:31:00-05:00 The Timing giveaway winner! https://brett.trpstra.net/link/535/16383214/the-timing-giveaway-winner https://brett.trpstra.net/link/535/16383214/the-timing-giveaway-winner Timing, giveaway, winner, email, apps

总结: 本文是关于Timing抽奖活动的结果公布,其中获奖者Scott Willsey将收到邮件并得到开发者联系。文章提到Timing可帮助人们了解自己的时间使用情况,并推荐了其他一些优秀的应用。接下来是每周一次的抽奖活动,并可以提出对其他应用的建议。

The Timing giveaway has ended, and I have a winner to announce!

The winners!

Congratulations to:

  • Scott Willsey

You should have received an email and the developer will be in touch, please let me know if you didn’t hear anything!

But I didn’t win!

If you didn’t win, sorry, but Timing is still worth checking out. I guarantee it will be useful for anyone who needs to know where they spend there time, for any reason.

By the way, Timing is also available on Setapp, along with hundreds of other amazing apps. You should probably get a subscription.

Next up is Hookmark. Check back every Monday through April for more giveaways.

Other upcoming apps include:

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for notifications!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-06T13:00:00-05:00 Marked and Bunch updates for Sonoma https://brett.trpstra.net/link/535/16381661/marked-and-bunch-updates-for-sonoma https://brett.trpstra.net/link/535/16381661/marked-and-bunch-updates-for-sonoma Marked, Bunch Beta, fixes, Sonoma, updates

总结: 这篇文章简要介绍了Marked和Bunch Beta的更新情况,这些更新主要解决了Sonoma上的问题,并修复了一些功能失效的情况。文章提到,Marked更新已经在直接购买渠道上线,并在Setapp和Mac App Store上进行审核中,而Bunch Beta版本的更新则主要修复了Sonoma上的问题,并且需要用户的反馈确认功能是否正常。

Just a quick note to let you know that there are new versions of Marked and Bunch Beta with some fixes for Sonoma.

The Marked update is live for direct customers, and in review for Setapp and Mac App Store customers. Watch for updates on your channel. It fixes an issue that prevented Marked from opening any files on Sonoma, and also crashes when using with Drafts’ or Bear’s “Preview in Marked” features. It should solve the issue for all versions of macOS.

The Bunch update is specifically to fix modifier keys not working when clicking Bunches in the menu. E.g. you’re supposed to be able to Cmd-Click a Bunch and open the text file in your editor of choice instead of launching it, and this wasn’t working anymore. The current release of the Beta should solve it. I would love some feedback on whether it’s working for you on Sonoma, and additionally whether I broke it for people on earlier versions of macOS. If the fix is solid, I’ll release it to the main channel. You can download the beta on the Downloads page.

Thanks for any feedback!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-05T12:11:00-05:00 Dropzone 4, the essential drag & drop productivity enhancer [Sponsor] https://brett.trpstra.net/link/535/16381391/dropzone-4-the-essential-drag-and-drop-productivity-enhancer-sponsor https://brett.trpstra.net/link/535/16381391/dropzone-4-the-essential-drag-and-drop-productivity-enhancer-sponsor Dropzone, Mac, productivity, shortcuts, drag-and-drop

总结: Dropzone是一个用于Mac的应用程序,它通过简化拖放操作,提高用户的日常工作效率。用户可以将常用操作设置为快捷方式,然后通过将文件拖放到相应的快捷图标上,执行保存的操作。Dropzone还具有许多自定义功能,用户可以根据自己的需求创建适合自己日常工作流程的快捷方式。此外,Dropzone还支持将文件上传到各种云服务,并提供扩展插件支持。现在,读者可以通过使用折扣码获取Dropzone 4 Pro终身许可证享受15%的折扣。

Thanks to Dropzone for sponsoring BrettTerpstra.com this week! I’ve been a Dropzone fan for many years now, and use it daily for everything from processing images to sharing files via my S3 account.

Dropzone brings everyday productivity shortcuts to your Mac. Set up your frequently used actions in the Dropzone interface, then simply drag and drop files into the shortcut icons to perform your saved actions. Move, copy, and share files in an instant, or even develop your own timesaving actions.

🚀 Drag-and-Drop Simplicity: Dropzone 4 lets you effortlessly drag and drop files and folders to your most-used destinations, whether it’s a specific folder, cloud service, or application. It will turbocharge drag & drop and help you get things done faster.

📁 Customizable Actions: Tailor Dropzone 4 to your unique needs with a plethora of customizable actions. Create workflows that suit your daily routine, from resizing images or shortening URLs to sending files via email, all with a simple drag-and-drop.

🗃️ Stash files for later: Drop Bar allows you to keep files handy you know you’ll need later, instead of having to dig them up from their folders. Simply drop files into Dropzone’s holding area, and they’ll stay put until you’re ready to use them again. The holding area is a feature you won’t want to give up, proving incredibly useful for putting together documents that pull in from many sources.

🌐 Cloud Integration: Upload to your favorite cloud services like Imgur, Google Drive, YouTube, SFTP servers and many more.

🧩 Extensive Plugin Support: Expand Dropzone 4’s capabilities with our library of actions available from aptonic.com/actions

🌟 Updated and improved for macOS Sonoma

Ready to supercharge your Mac experience? Join the thousands of satisfied users who have already discovered the magic of Dropzone 4. Download it today and transform the way you use drag & drop on your Mac.

For a limited time for BrettTerpstra.com readers, we’re also offering a 15% discount off a Dropzone 4 Pro Lifetime License with the coupon code BRETTTERPSTRA. Click here to receive the discount.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-05T08:00:00-05:00 Timing giveaway! https://brett.trpstra.net/link/535/16374917/timing-giveaway https://brett.trpstra.net/link/535/16374917/timing-giveaway giveaway, 1-year subscription, Timing, time tracking, productivity

总结: 这篇文章介绍了一项抽奖活动,奖品是一年期的订阅费用为108美元的Timing软件。该软件可以自动追踪时间,帮助用户记录工作时间、个人项目时间、游戏时间等,并且可以根据规则进行分类。文章还介绍了Timing的功能和优势,鼓励读者参与抽奖活动。

I’m excited to offer the next giveaway, a 1-year subscription ($108 value) for Timing. I use Timing daily and it’s helped me automatically track time that I would never have had the discipline to manage on my own. Billable hours, time I spend on personal projects, time I spend gaming, pretty much anything I do on my Mac, my iPhone, or my iPad gets tracked and I can easily categorize based on rules (that are as easy as dragging and dropping to generate). I even integrated it with Doing for adding depth to my “What Was I Doing” tracking.

From the developer:

Just keep focusing on your work while Timing records your time automatically, then review your time when you want to. Record time faster than ever with just a few clicks. See when you worked on what and how productive you were.

Check out the Timing site for more info.

Sign up below to enter. A winner will be randomly drawn on Friday, October 06, at 12pm Central. The drawing is for a 1-year subscription ($108 value) for Timing. Note that if you’re reading this via RSS, you’ll need to visit this post on brettterpstra.com to enter!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through April (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list so you can be the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-10-02T08:00:00-05:00 Historical weather for Journal CLI https://brett.trpstra.net/link/535/16373194/historical-weather-for-journal-cli https://brett.trpstra.net/link/535/16373194/historical-weather-for-journal-cli 更新、命令行日志工具、历史天气数据、月相、数据收集、心情信息、翻译等

总结: 这篇文章介绍了命令行日志工具的更新内容,包括可以添加过去日期的自然语言参数,获取历史天气数据,以及跟踪月相等功能。作者对工具的使用感到满意,并愿意帮助他人提供更多帮助。

I pushed a couple updates to Journal, my command line journaling tool today.

As a reminder, you can add a natural language argument to your journal command which will set the date of the entry, e.g. journal mood "yesterday 8pm". This allows you to create entries in post with historical data you might have missed. One thing that it didn’t do well, though, is to get the correct weather for any weather type questions in the journal when using past dates. This latest update is able to get historical weather data and insert it correctly in the entry. No changes required for the user, just enter a past date and Journal will figure it out.

Second, I’ve noticed my mood and sleep shifts with the moon phase. I’m not into astrology or anything, but that seemed like useful data to track and start to draw better conclusions from. So now a question type of weather.forecast will include the moon phase as a moon_phase key, and you can use weather.moon to get just the moon phase for its own entry. The forecast in Markdown will also now include the moon phase.

That’s it, just tying up some loose ends. Journal is working pretty well for me to collect data and provide my therapist with detailed mood/behavior information. Let me know if there’s anything it doesn’t do that might help you out!

The latest version can be installed with gem install journal-cli. Visit the Journal project page for more info.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-30T11:11:00-05:00 The CleanShot X giveaway winners! https://brett.trpstra.net/link/535/16372125/the-cleanshot-x-giveaway-winners https://brett.trpstra.net/link/535/16372125/the-cleanshot-x-giveaway-winners CleanShot X giveaway, winners, app for screenshots, automatic time tracking, upcoming apps

总结: 这篇文章宣布了CleanShot X赠品活动的获奖者,并推荐了一些其他值得注意的应用程序。同时,还提到了接下来的自动时间跟踪应用程序以及如何提前获得早期访问权限。

The Winners

The CleanShot X giveaway has ended, and I have three winners to announce!

Congratulations to:

  • Scott Rychnowski
  • Darren Everden
  • David Brown

Each winner should have received an email with a redeem link/code, please let me know if you didn’t hear anything!

But I Didn’t Win!

If you didn’t win, sorry, but CleanShot X is still worth checking out. It’s by far the best app for screenshots on the Mac, no matter where or how you’re using them.

You should also consider a subscription to Setapp, which will include CleanShot X among a couple hundred other amazing apps.

Coming Soon

Next up is Timing (the perfect app for automatic time tracking on Mac). Check back every Monday through December for more giveaways. Upcoming apps include:

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for early access!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-29T12:00:00-05:00 Automatically sort emails to custom folders with Sanebox [Sponsor] https://brett.trpstra.net/link/535/16369625/automatically-sort-emails-to-custom-folders-with-sanebox-sponsor https://brett.trpstra.net/link/535/16369625/automatically-sort-emails-to-custom-folders-with-sanebox-sponsor SaneBox, email clutter, custom folders, personalized email experience, adaptive technology

总结: SaneBox是一个强大的电子邮件管理工具,通过其自定义文件夹功能,用户可以根据自己的喜好和优先级来将邮件分类整理,从而创造一个个性化的电子邮件体验。这个功能的灵活性使用户能够根据工作习惯和优先级自由自在地组织邮件,提高工作效率。SaneBox的自适应技术将用户置于核心位置,为用户提供更高效、个性化的邮件管理服务。如果您还在为杂乱的收件箱而烦恼,不妨尝试一下SaneBox的自定义文件夹功能吧。

Thanks to Sanebox for sponsoring BrettTerpstra.com again this week! I just trained 3 new senders into custom Sanebox folders today (just by moving an email from them once) and will never have to see them in my Inbox again, and will be able to easily locate them when I do want to see them. It’s so easy!

SaneBox is once again under the spotlight for their cutting-edge solutions to the age-old problem of email clutter. Having earned the endorsement of seasoned professionals, it’s worth diving deeper into another feature that makes SaneBox the power tool for email management. One feature that is particularly enchanting? Custom Folders.

Imagine this: You receive countless emails daily from various sources. Newsletters from your favorite brands, updates from work, personal emails, bulk offers, and then, those pesky spam mails. Now, think of an assistant who not only sorts your emails but also does it exactly how you would. That means keeping in mind your unique preferences and priorities. That’s what SaneBox’s Custom Folder feature offers.

At the core of SaneBox is its learning ability. For example, as you shuffle emails in and out of folders like @SaneLater or @SaneBlackHole, SaneBox observes. Over time, it finds patterns in your preferences and ensures similar emails find their rightful place automatically in the future. It’s like training your dog to fetch. Once it learns which toy is its favorite, it fetches it every single time.

One particularly intriguing aspect of this feature is the flexibility it offers. Let’s say you’re working on a project, and you want all communications about it to be in one place. Simply create a Custom Folder named “@ProjectX.” As you get emails related to the project, drag a few to the new folder, and then SaneBox will quickly learn to play fetch.

The beauty of SaneBox’s Custom Folder feature lies in its adaptability. It’s not just about categorizing. It’s about creating an email ecosystem that aligns with your work habits and priorities. The more seamless a process is, the more likely you’ll be to use it. So that adaptability is critical.

In essence, SaneBox’s Custom Folder feature is more than just about organization. It’s about crafting a personalized email experience. It’s a testament to how adaptive technology can be when it’s designed with the user at its core.

If you’re still juggling with emails and feeling the stress of a cluttered inbox, perhaps it’s time to give SaneBox’s Custom Folder feature a try. And remember, signing up today can even get you a $25 discount on any subscription. Make your email work for you, not the other way around!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-28T08:00:00-05:00 Web Excursions for September 26, 2023 https://brett.trpstra.net/link/535/16366906/web-excursions-for-september-26-2023 https://brett.trpstra.net/link/535/16366906/web-excursions-for-september-26-2023 Snailed It, Rosemary Orchard, apps, Alex Hay, passing Dr. Drang, Apple Backblaze, drive stats report, SSD edition, hard drive reliability ffmpeg BrettTerpstra.com, readers, support 总结:

Snailed It接管了Alex Hay开发的几个应用程序,这些应用程序将得到关爱和照顾。Dr. Drang对Apple的技术痴迷让人爱不释手。Backblaze发布了半年一次的驱动统计报告(SSD版),他们收集的硬盘可靠性数据令人印象深刻。我从未知道ffmpeg可以做到这一点。BrettTerpstra.com得到读者的支持。

Web excursions brought to you in partnership with MindMeister, the best collaborative mind mapping software out there.

Toolbox Pro, Logger for Shortcuts, and Nautomate
Snailed It, run by my friend Rosemary Orchard, has taken custody of several apps developed by Alex Hay after his tragic passing last March. They’re in good hands, and will see the love he would want them to.
iPhone 15 Pro facts and estimates
I love it when Dr. Drang nerds out about Apple stuff.
The SSD Edition: 2023 Drive Stats Mid-Year Review
The semi-annual drive stats report from Backblaze is out (SSD edition). I love the amount of data they collect on hard drive reliability.
Adding sound wave overlays to videos and pictures using FFMPEG | Christian Heilmann
I did not know ffmpeg could do this. Thanks, Christian!

Check out MindMeister and start brainstorming, collaborating, and boosting productivity.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-26T13:44:00-05:00 CleanShot X giveaway! https://brett.trpstra.net/link/535/16364871/cleanshot-x-giveaway https://brett.trpstra.net/link/535/16364871/cleanshot-x-giveaway Mac apps, screenshot/recording app, elegant, giveaway, Brett Terpstra.com

总结: 这篇文章介绍了一款被作者认为是过去几年中最好的Mac应用程序,它是一款功能强大的屏幕截图/录制应用程序,同时还具备高度优雅的设计。作者还提供了三个价值29美元的许可证的赠品活动。

I’m super excited about this one, as I consider CleanShot X to be one of the best Mac apps developed in the last few years. Hands down the best screenshot/recording app, but also just a highly elegant app all around.

Note that if you’re reading this via RSS, you’ll need to visit the site to enter! Check out the CleanShot X website for more details on this amazing app.

I have three licenses ($29 value) to offer to BrettTerpstra.com readers. Sign up below and I’ll draw random winners on Friday, September 29th.

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

Stay tuned for more giveaways every week through December (and maybe beyond).

If you have an app you’d love to see featured in this series of giveaways, let me know. Also be sure to sign up for the mailing list so you can be the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-25T08:00:00-05:00 The Tap Forms giveaway winners! https://brett.trpstra.net/link/535/16361586/the-tap-forms-giveaway-winners https://brett.trpstra.net/link/535/16361586/the-tap-forms-giveaway-winners Tap Forms, giveaway, winners, database app, coupon 总结: 这篇文章宣布了Tap Forms的抽奖结果,同时还提供了一个以30%折扣购买直接版本的优惠券。文章还预告了接下来几周的抽奖活动,并鼓励读者在社交媒体上分享该帖子。

The Winners

The Tap Forms giveaway has ended, and I have two winners to announce!

Congratulations to:

  • Jonathan Laniado
  • Doug Lionetti

(I swear the giveaway robot has no preference for last names starting with L. It’s purely chance.)

Each winner should have received an email with a redeem link/code, please let me know if you didn’t hear anything!

But I Didn’t Win!

If you didn’t win, sorry, but Tap Forms is still worth checking out. You can easily store and work with any kind of data. It’s the missing database app for Mac and iOS. If you didn’t win, you can still save 30% on the direct version with the coupon BRETT-TF5-2023. Go to the site and click the Buy Now for Mac button to use the coupon, or download the free trial version and enter the coupon when using the in-app purchase.

Coming Soon

Next up is CleanShot X (the best screenshot app there is). Check back every Monday through December for more giveaways. Upcoming apps include:

If you want to suggest an app you’d like to see in this series, let me know on Twitter or Mastodon, and join the email list for early access!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-22T13:00:00-05:00 Journal updates with weather types and conditional questions https://brett.trpstra.net/link/535/16357253/journal-updates-with-weather-types-and-conditional-questions https://brett.trpstra.net/link/535/16357253/journal-updates-with-weather-types-and-conditional-questions journal-cli, 更新, 特性, 条件, bug fixes.

总结: 这篇文章介绍了 journal-cli 的更新内容,包括新特性和 bug 修复。用户现在可以根据指定的条件来确定是否提问,并且可以添加不同类型的天气数据。还提到了一些 bug 修复和一些使用上的注意事项。

In case you missed it, I recently released Journal, a CLI for keeping a journal with structured data that can be queried and analyzed. An update is live with a couple of nifty new features.

First, instead of just a type of weather for a question (which inserts the current condition and daily forecast), you can now specify sub-types of weather.current and/or weather.forecast. This outputs separate data entries to the JSON, and creates individual answers in the Markdown/Day One versions. You can still just use weather as the type to insert all data.

Second, you can now apply conditions to questions to determine whether they’ll be asked or not when creating an entry. Right now only time-based conditions are implemented, but I plan to add some functionality around basing a question’s appearance on the answer to a previous question, like “if health rating is less than 5, display the health notes question.” But for now you can add condition: before noon or condition: > 2pm to any question or section to only display the question(s) at certain times of day.

I needed these conditions because I like to create a mood entry in the morning with data about sleep and coffee, and in the evening I don’t want to repeat that data, but do want to ask some different questions about how the day went. I could create two separate journals for these, but this way I can compile all of my data in one file. Questions that are skipped get a null entry in the JSON, so when I’m parsing I just test for nil and skip entries that don’t contain the information I’m trying to output. Unanswered questions don’t get added to the Markdown/Day One entries at all.

This release includes a couple of bug fixes as well. I recently removed the requirement for the gum CLI, if it doesn’t exist it will now just use Readline for input. When using the gum inputs, you can’t CTRL-c to cancel an entry, which I’m trying to figure out a way around right now.

Update using gem install journal-cli. Visit the project page for more info and installation instructions.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-20T09:46:00-05:00 Tap Forms for Mac giveaway! https://brett.trpstra.net/link/535/16354183/tap-forms-for-mac-giveaway https://brett.trpstra.net/link/535/16354183/tap-forms-for-mac-giveaway BrettTerpstra.com, giveaways, Tap Forms, Mac version, free licenses

总结: BrettTerpstra.com开始了免费赠品活动,其中包括两个免费的Tap Forms for Mac许可证。Tap Forms是一款出色的数据库产品,可以让您在任何设备上组织和访问数据。此次赠品活动专为Mac版本而设。参与者需在指定时间内报名参加,赢家将有机会节省50美元购买费用。此活动是系列活动中的第一款免费软件赠品,将会有更多开发者提供免费软件,敬请期待。

I’m starting up giveaways again on BrettTerpstra.com, and I’m exited to kick it off with 2 free licenses for Tap Forms for Mac. It’s an amazing database product that lets you organize and access your data on any device. It’s available on Mac, iPhone, iPad and even Apple Watch. This giveaway is specifically for the Mac version.

From the developer:

Accounts, recipes, expenses, inventory — life is full of things that we don’t want to forget or misplace. Tap Forms helps you organize all kinds of things in one place — secure, searchable, and accessible on your Mac, iPhone, iPad, and Apple Watch.

Check out the Tap Forms site for more info.

Sign up below to enter. Two winners will be randomly drawn on Friday, Sept 22, at 12pm Central. Tap Forms for Mac costs $49.99, so this is a great chance at saving $50!

Giveaway ends in...

You need to view this post on brettterpstra.com to enter.

I reached out to my mailing list to see what products people were interested in, and Tap Forms was a top pick. I have several more developers lined up to offer free stuff, so stay tuned. If you have an app you’d love to see featured, let me know. Also be sure to sign up for the mailing list so you can be the first to know about these!

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-18T08:00:00-05:00 A silly Jekyll plugin and a big Marked sale https://brett.trpstra.net/link/535/16349238/a-silly-jekyll-plugin-and-a-big-marked-sale https://brett.trpstra.net/link/535/16349238/a-silly-jekyll-plugin-and-a-big-marked-sale Jekyll plugin, countdown, 40% off sale, coupon, September 16th,

总结: 这篇文章介绍了一个Jekyll插件,可以用来实现倒计时功能。作者通过插件创建了一个倒计时,用于促销活动。文章中提到了一个40%折扣销售,截止日期是9月16日,使用特定的优惠码可以享受折扣优惠。

So, a long time ago I wrote this Jekyll plugin that does countdowns and I don’t think I ever really used it. You just give it an end date and it inserts a countdown into the post. But I needed something to count down to, so I’m running a 40% off Marked sale using the coupon COOLPLUGINBRO until Saturday, September 16th. Here’s your countdown:

Sale ends in...

Did it work? I hope so. Use this link to apply the coupon directly, or enter COOLPLUGINBRO at checkout. Learn more about Marked at marked2app.com.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-14T13:14:00-05:00 So you think you know productivity? [Sponsor] https://brett.trpstra.net/link/535/16348948/so-you-think-you-know-productivity https://brett.trpstra.net/link/535/16348948/so-you-think-you-know-productivity TextExpander, productivity methods, boost productivity, text expansion, save time. 总结: 本文介绍了TextExpander这一工具赞助BrettTerpstra.com网站,并提到了它可以帮助节省时间、提高生产力的特点。文章还列举了20种不同的生产力方法,包括番茄工作法、80/20法则和时间分块等,并介绍了TextExpander如何帮助用户在各行各业中提高工作效率。最后,文章提到了TextExpander的免费试用期和折扣码。通过text expansion,可以快速输入长文本,有助于节省时间和提高工作效率。

Thanks to TextExpander for sponsoring BrettTerpstra.com this week! I can’t count the number of hours I save using TextExpander. Oh wait, I can, because they email you a report every week to let you know…

So you think you know productivity? Can you name 20 different productivity methods?

Maybe you’ve heard of the Pomodoro method, the 80/20 rule, or time blocking, but have you heard of Eat the Frog? Have you set SMART goals for 2024? Ever developed an Eisenhower Matrix?

Over at the TextExpander blog, we’ve cataloged 20 of these productivity habits. There are lots of ways to boost your productivity.

One of the best ways to boost your productivity is through text expansion. Type something short and get something long. Do you find yourself writing the same emails repeatedly? Why? Let TextExpander handle it and save yourself hours and even days every year.

And that applies to pretty much every industry that involves typing:

TextExpander can handle short messages, emails, code, or pretty much any text you can throw at it, including formatted text and hyperlinks.

Try it out free for 30 days. Check out TextExpander today and get 20% off using the code TERPSTRA.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-14T08:00:00-05:00 Journal and integrations https://brett.trpstra.net/link/535/16342944/journal-and-integrations https://brett.trpstra.net/link/535/16342944/journal-and-integrations 日期类型、字典类型、集成应用、JSON格式、功能扩展

总结: 本文介绍了对Journal软件的功能改进,包括日期类型和字典类型的定义,以及与Obsidian等应用的集成。通过引入YAML数据,可以更好地控制结构化数据,便于构建分析工具。此外,文章还提到了版本更新和软件安装方法。

I’ve made some changes to Journal (I didn’t mess with the data format this time) that add some functionality and will maybe help with integrating with some apps like Obisidian.

First, you can now define a date type. Date entries will be parsed from natural language into date objects, so on the command line you can enter something like “yesterday 5pm” or “july 20 12pm” and get a proper date object added to your JSON and Markdown entries. Great for things like logging book review dates, workout days, etc.

You can also now define a dictionary type for a question, which along with a key definition creates a nested data set with any dot notation keys that match. So you can define the following:

mood:
  sections:
  - title: "Status"
    key: status
    questions:
      - key: health
        type: dictionary
      - key: health.rating
        type: numeric
        prompt: Health Rating
        min: 1
        max: 10
      - key: health.notes
      type: multiline
        prompt: Health Notes

The data that gets output will include this format in the JSON:

{
  "mood": {
    "status": {
      "health": {
        "rating": 5,
        "notes": "Just some notes on my health"
      }
    }
  }
}

This allows for more control over the structured data. It won’t be a big deal for most people as answers were already nested within section keys and could be grouped using dot syntax, this just allows the structure to go one level deeper which may help with building analytics tools.

The big change that will allow more integrations with apps like Obsidian is that all numeric and date answers are now included as YAML front matter in any individual Markdown files created. This will allow integration with existing tools like Obsidian Dataview, which allows you to create data views based on YAML data in your Obsidian notes. By pointing Journal to your Vault folder, you can have journal entries added to your vault and queryable with Dataview. I haven’t tested this, I just noted that it should be possible with the addition of the YAML data. For the time being I’m not including any string responses in the YAML, as that seems redundant since they’re also included in the body text and available to search.

This update won’t affect data saved to single Markdown files or added to Day One. If you have any ideas about how this could be made more useful, please let me know! Either via the Discussions or by contacting me directly.

Version 1.0.19 is out now, just install or upgrade with gem install journal-cli. See the project page for more details.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-11T11:10:00-05:00 More na updates https://brett.trpstra.net/link/535/16340947/more-na-updates https://brett.trpstra.net/link/535/16340947/more-na-updates Command line tool, na, theming, new commands, changelog, TaskPaper files.

总结: 这篇文章介绍了命令行工具na的最新版本更新,包括了主题设置、新的命令和修复的问题等内容。na是一个用于读取和修改TaskPaper文件的工具。更新后的na版本增加了主题设置功能,使得用户可以自定义操作的颜色输出。此外,还添加了一些新的命令和改进,以及修复了一些问题。详细的更新内容可以在文章的changelog中查看。

I’ve put some more time into both Journal and na. The latest version of na represents quite a few hours of tinkering. See the na project page for full details. In case you’ve missed in previously, na is my command line tool for reading and modifying TaskPaper files in your projects.

I think the biggest thing I’ve added is theming. You can now control the colorized output of your actions using a file at ~/.local/share/na/theme.yaml. That file is automatically written by na if it runs and it doesn’t exist, and once it’s there, it should be pretty self explanatory. You can use {y} type placeholders (that would make the following text yellow, a full list of color abbreviations is at the top of the file), and you can also use {#RGB} and {#RRGGBB} codes to get specific colors outside of the usual ANSI coloring.

I’ve added new commands like tag (see na help tag), and a new --restore option to several commands for removing the @done tag from actions. There’s also a --replace flag you can tie into na update --search SEARCH_STRING --replace REPLACE_STRING to perform (wildcard-compatible) search and replace. Add --regex to do a regex search and replace.

There’s a bunch of other new stuff, so I’ll just post the collected changelog.

NEW

  • Global option --include_ext can be configured to use full extension when displaying filenames, allowing for command-clicking to open in compatible terminals
  • Tag command
  • Add --save NAME to na next to save more complex queries and run with na saved NAME (or just na NAME)
  • na saved --select flag to allow interactive selection of search(es)
  • Open the todos database in an editor with na todos --edit
  • A theme file is written to ~/.local/share/na/theme.yaml where you can modify the colors used for all displays
  • Allow TAG=~PATTERN comparison for regex matching in na tagged
  • na undo command to undo last change or last change to file specified in arguments
  • na update --search OLD_TEXT --replace NEW_TEXT (added –replace)

IMPROVED

  • When displaying actions wider than the screen, wrap at words and indent 2 spaces from start of action (after prefix)
  • When not showing notes, add an asterisk at the end of an action
  • When showing notes, indent to the beginning of the action
  • Add --project to archive, complete, and update to move a modified action to a new project when saving
  • Allow na saved --delete to handle multiple arguments
  • Allow wildcards when deleting saved searches
  • Refactor request for input, no change to user experience
  • Refined wildcard (?*) handling
  • Better error message for na next when no todo is matched
  • If STDOUT isn’t a TTY, don’t enable pagination, regardless of global setting
  • Disable pagination when using –omnifocus
  • Allow –find or –grep as synonyms for –search
  • --in TODO option for na complete
  • If a search string contains @tags and –exact or –regex isn’t specified, the @tags will be extracted and passed as a –tagged search.
  • Tag handling (including values and comparisons) in tags extracted from search strings
  • na complete --project PROJ flag to move to a specific project
  • na restore --project PROJ flag to move restored action to
  • Exit gracefully if tagged command is run with invalid arguments
  • Display action affected when using update command

FIXED

  • Change default :dirname coloring to fix an occasional highlighting issue
  • Error when creating new project in todo file
  • Error when last_modified.txt hasn’t been written yet
  • Nil error in action.pretty
  • Date tags containing hyphens triggered OR searches because they were initially interpreted as negative tag searches
  • Templating irregularities
  • Error thrown when running without $EDITOR variable defined in environment
  • New project not being added when requested
  • Error when na add --to PROJECT was a project that didn’t exist
  • --no-color wasn’t stripping templated hex codes
  • Escape search for tokens to allow parenthesis and other reserved characters

More details on the project page!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-09T09:00:00-05:00 Timing -- automatic time tracking for Mac AND iOS [Sponsor] https://brett.trpstra.net/link/535/16338321/timing-automatic-time-tracking-for-mac-and-ios-sponsor https://brett.trpstra.net/link/535/16338321/timing-automatic-time-tracking-for-mac-and-ios-sponsor Timing, time tracking, app, vertical timeline, productivity

总结:
这篇文章介绍了Timing这款时间追踪应用的特点和优势。Timing可以自动跟踪用户使用各种应用、文档和网站的时间,并根据规则自动分类。它还可以导入iPhone和iPad的使用时间,提供完整的设备使用情况。此外,Timing还可以导入iPhone的电话记录和日历事件,确保不会漏掉任何会议和通话时间。Timing的全新垂直时间轴界面方便了用户快速了解时间分配情况。它是一款全面而易于使用的时间追踪应用,可以帮助用户更好地管理时间和提高工作效率。

Thanks to Timing for sponsoring BrettTerpstra.com this week! I’ve loved Timing for years, and the new vertical timeline view is an awesome upgrade to one of my most-used apps.

Time is your most precious resource. You need to know how you are spending it.

But time tracking is no fun.

Timing fixes that.
It automatically tracks all your time, without you lifting a finger:

  • Timing records how long you use each app, document, and website — without start/stop timers. These timmes can also be automatically categorized using rules, so you don’t have to do it manually.
  • It imports your iPhone and iPad usage from Screen Time, giving you a complete picture of all your device usage. No other time tracking app for Mac does this!
  • In addition, Timing will also import phone calls from your iPhone, so those don’t get lost.
  • The same goes for meetings you attend: Timing will automatically show events from your calendar, so you never forget to record time spent in meetings again.
  • But even when a meeting isn’t on your calendar, Timing automatically recognizes when a call ends and lets you record time for it, so that no meeting goes untracked.
  • Similarly, when you return to your Mac after a break, Timing will ask you what you did during your time away.

All of these features are optional and configurable, of course. And its brand-new vertical timeline makes it even easier to see what you did at a glance.

Timing is the one time-tracking app that will really give you a complete picture of where your time goes, all while taking you much less time to maintain than other time trackers.

Not convinced yet? Read what Brett himself has to say about Timing.
(Spoiler alert: He likes it, and it helps him be more productive.)
Or download the free 30-day trial today and get 10% off for the first year! And if you had tried Timing before and would like to give it another shot, feel free to reach out and we’ll send you a new trial.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-07T08:00:00-05:00 Important Journal CLI updates https://brett.trpstra.net/link/535/16338322/important-journal-cli-updates https://brett.trpstra.net/link/535/16338322/important-journal-cli-updates dot syntax, nested keys, data format, custom folders, tool usefulness

总结:
这篇文章介绍了一个工具的更新内容,修复了使用点语法嵌套键时出现的问题,并添加了自定义文件夹选项来保存条目。这些改进使得工具更加实用。

Just a couple quick updates to the Journal CLI I published yesterday that I wanted everyone who was trying it out to know about before they have too much data in it.

First, if keys were nested using dot syntax, e.g. health.rating and health.sleep, it would create a hash like:

{ 
  "health": {
    "health": {
      "rating" : 5, 
      "sleep": 7 
   }  
}

As you can see, the “health” key got doubled and nested inside of the section key. This isn’t the way it was supposed to work with the dot syntax. Version 1.0.15 fixes this, if a key is repeated it’s merged with the parent key instead of nesting.

I also added options for defining custom folders to save entries in. At the top level you can include entries_folder with a path to any folder on your system. Journals will all save to that folder with subdirectories for each of their keys. You can instead define entries_folder within a journal definition, allowing each journal to have a custom location. JSON and Markdown will be written to these folders based on settings.

That should help make this tool a bit more useful, sorry for changing the data format, but better sooner than later. Check out the project page for more details.

Like or share this post .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-07T08:00:00-05:00 Journal, a CLI for journaling https://brett.trpstra.net/link/535/16334303/journal-a-cli-for-journaling https://brett.trpstra.net/link/535/16334303/journal-a-cli-for-journaling couple's therapy, neurodivergence, command-line tool, data collection, journaling

总结:
这篇文章介绍了一种命令行工具,用于在夫妻治疗中收集数据并进行日记记录。这个工具可以处理数字、字符串和多行输入,并且可以创建Day One和Markdown版本的条目。它还可以记录每天的天气情况。虽然还没有实现查询数据集的功能,但作者认为通过统计分析可以对数据进行跟踪和相关性分析。通过这个工具,作者能够获得自己的情绪和日志的概览。希望这个工具能对其他人也有帮助。

I recently started couple’s therapy to try and improve the often-complicated relationship between myself (ADHD, bipolar) and my partner (autistic) and all of the unique problems that combination of neurodivergence presents. As part of this, I was asked to keep a journal containing certain data points. I started off journaling in Day One, but immediately realized that I was collecting some numeric data that I wouldn’t be able to do anything with unless it was stored in a database format of some kind. So I wrote a tool.

Journal is a command-line tool that takes a configuration of journals, sections, and questions, presents the questions on the command line, and records the answers to JSON, as well as optionally creating Day One and Markdown versions of the entries. It can handle numeric data, string and multiline input, as well as automatically recording the daily weather for each entry.

To use it you need Gum installed (brew install gum). If you want to use the Day One integration, you’ll also need to install the Day One CLI. Those are the only prerequisites. You can just use gem install journal-cli to get the journal command set up. It can handle multiple journal configurations and multiple output formats. It takes some configuration, but it’s very flexible (and will probably get more flexible as new needs arise).

I haven’t written the part of this that can query the datasets created yet. That’s going to be pretty individualized based on your needs, but I think everything should be there in the JSON to allow tracking and correlations with a little statistical analysis work. I’ll dig into it more once I’ve collected enough data. In the meantime, it’s also creating nicely-formatted Day One entries so I can get an overview of my moods and journals.

See the project page for details on setup and configuration. Hopefully others will find this useful, too!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]> 2023-09-06T00:00:00-05:00 A bit more na work https://brett.trpstra.net/link/535/16322833/a-bit-more-na-work https://brett.trpstra.net/link/535/16322833/a-bit-more-na-work I went on a trip to Minneapolis this weekend. It went really well; I saw some great friends, ate some great food, and spent some early mornings coding at the hotel. I was just coding to kill time when I couldn’t sleep, and playing with na seemed like the perfect way to do it.

The first thing I did was take a second stab at “decomposing” the main binary so that each command had its own file, just to make maintenance easier. Finally got that working properly. It won’t change anything for the user, but it’s so much nicer to look at.

In addition to the complete and archive commands I added last week, the update command now has a --restore flag that can be used to remove the @done tag from an action or actions. It’s the same as using --remove done, but I find it just a little more intuitive. This flag is mirrored as an na restore [SEARCH] (or na unfinish [SEARCH]) command.

I also added pagination, so for output that is longer than your screen, it will now pause using less or more if available, letting you page through with shortcut keys. This also applies to the help command, so it’s easier to wade through the extensive documentation that the command provides. You can disable this with na --no-pager [COMMAND], a setting which can be saved to your config.

I added an na completed command to view @done actions. It accepts --before, --on, and --after flags that recognize natural language dates and can be combined. You can also use --tagged TAG to find actions tagged with any combination of tags (use comma separated list or use the flag multiple times, include a + to make a tag mandatory, ! to negate). Any arguments passed to the command will function as a tokenized text search. And, of course, you can run it with --save [NAME] to save a complex search for later use with the na saved command.

Speaking of saved searches, I also changed the saved command to allow multiple saved searches to run at once. So now if you have a saved search for low priority and one for medium priority, you can run them both together with na saved lowprio medprio and get combined results.

Also:

  • --done flag not working on na next
  • Missing descriptions in help examples
  • When replacing a priority tag, remove any space before it the action text
  • Detect @tags in search strings and convert them to tag search with comparisons

Check out the project page for installation and usage details.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-30T12:02:00-05:00
Stem the tide of unread emails with SaneBox Digest from SaneBox [Sponsor] https://brett.trpstra.net/link/535/16311855/stem-the-tide-of-unread-emails-with-sanebox-digest-from-sanebox-sponsor https://brett.trpstra.net/link/535/16311855/stem-the-tide-of-unread-emails-with-sanebox-digest-from-sanebox-sponsor Thanks to SaneBox for sponsoring BrettTerpstra.com again this week! I rely on my SaneBox Digest to get an overview of all the emails that (thankfully) skipped my inbox without having to wade through them all. Highly recommend!

Drowning in a deluge of daily emails and struggling to keep up with the significant ones? Enter SaneBox Digest, an exceptional feature of SaneBox that offers you a concise summary of your email activity. Instead of constantly wading through piles of unimportant emails, the Digest provides you with a neat overview of your day’s communications at a glance.

More than just a quick recap, the Digest integrates flawlessly into your SaneBox journey. It delivers a daily or weekly email that lists your unread messages and summarizes their content, enabling you to pinpoint crucial communications without being overwhelmed by the inconsequential ones. Think of it as your inbox’s personal news broadcaster, highlighting the headlines while filtering out the noise. With the Digest, you’re empowered to take control of your emails and ensure you’re always in the loop without the unnecessary clutter.

Check out SaneBox today and save $25!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-24T08:00:00-05:00
Some na updates and new commands https://brett.trpstra.net/link/535/16308395/some-na-updates-and-new-commands https://brett.trpstra.net/link/535/16308395/some-na-updates-and-new-commands I’ve updated na with some new stuff I thought I’d share.

First off, I wanted an easy way to archive all @done actions in one swoop without having to use a lot of flags and switches to locate them and move them. So I added an archive command, which takes a search string as an argument, but also has a --done switch that will archive all @done tasks. So you can just run na archive --done, select the file to affect if there are multiple available, and presto, “archive all finished” is done, just like in TaskPaper.

NAME
    archive - Mark an action as @done and archive

SYNOPSIS

    na [global options] archive [command options] ACTION

COMMAND OPTIONS
    --all             - Act on all matches immediately (no menu)
    -d, --depth=DEPTH - Search for files X directories deep (default: 1)
    --done            - Archive all done tasks
    -e, --regex       - Interpret search pattern as regular expression
    --file=PATH       - Specify the file to search for the task (default: none)
    -n, --note        - Prompt for additional notes. Input will be appended to any existing note. If STDIN input (piped) is detected, it
                        will be used as a note.
    -o, --overwrite   - Overwrite note instead of appending
    --tagged=TAG      - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
    -x, --exact       - Match pattern exactly

EXAMPLE

    # Find "An existing task", mark @done if needed, and move to archive
    na archive "An existing task"

I also added a complete command that will add a @done tag to whatever action matches your search (menu provided for multiple results), or all matches using the --all switch. It’s basically a shortcut for na update --finish SEARCH_STRING. It’s aliased as finish as well. Both the archive and complete commands have a --note switch that allows you to add a note (prompted if there’s nothing piped to it). All of the matching options from the update command are available, including --tagged for searching by tag and --regex for doing a regular expression search. complete has a --archive switch that will simultaneously add a @done tag and move the action to the Archive.

NAME
    complete - Find and mark an action as @done

SYNOPSIS

    na [global options] complete [command options] ACTION

COMMAND OPTIONS
    -a, --archive     - Add a @done tag to action and move to Archive
    --all             - Act on all matches immediately (no menu)
    -d, --depth=DEPTH - Search for files X directories deep (default: 1)
    -e, --regex       - Interpret search pattern as regular expression
    --file=PATH       - Specify the file to search for the task (default: none)
    -n, --note        - Prompt for additional notes. Input will be appended to any existing note. If STDIN input (piped) is detected, it
                        will be used as a note.
    -o, --overwrite   - Overwrite note instead of appending
    --tagged=TAG      - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
    -x, --exact       - Match pattern exactly

EXAMPLES

    # Find "An existing task" and mark @done
    na complete "An existing task"

    # Alias for complete
    na finish "An existing task"

I know of a few people making extensive use of na. If you’re among them and have a feature request, don’t be shy about posting an issue or contacting me directly.

Check out the project page for more info.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-22T08:00:00-05:00
Convert RegExRX native files to Markdown snippets https://brett.trpstra.net/link/535/16306720/convert-regexrx-native-files-to-markdown-snippets https://brett.trpstra.net/link/535/16306720/convert-regexrx-native-files-to-markdown-snippets I love RegExRX for testing regular expressions. It has all the features I could want from such an app, including the ability to copy a working regex out prepared for a range of languages. It’s what I’ve stuck with for years.

As I experiment with my regexes, I’ll save them in RegExRX, creating a .regexrx file in my Snippets folder (where Snibbets works). In order to make these searchable with Snibbets, I use a script to convert the XML-based .regexrx file to a Markdown file with the flags, search string, and the replace string and test text if they exist. I turned this into a gem for anyone who should happen to run into such a need.

You can install the tool with gem install regexrx2md. Once installed, just use regexrx2md -o MARKDOWN_DIRECTORY SOURCE_DIRECTORY to output a bunch of Markdown files from a directory of .regexrx files. You can also convert a single file just by providing a file link as the argument instead of a directory.

There are options for manipulating the filename, the Markdown template, and the output directory. See the docs for more info. While I hope this is useful to someone, it was something I useful enough to me to invest the time in, so it’s already paid off sufficiently. I just thought I’d share… just in case.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-21T08:00:00-05:00
Kaleidoscope 4.1: Now with Git File History (and a special coupon) [Sponsor] https://brett.trpstra.net/link/535/16300740/kaleidoscope-4-dot-1-now-with-git-file-history-and-a-special-coupon-sponsor https://brett.trpstra.net/link/535/16300740/kaleidoscope-4-dot-1-now-with-git-file-history-and-a-special-coupon-sponsor Thanks to Kaleidoscope for sponsoring BrettTerpstra.com again this week! The addition of Git History diffing is excellent, and I’m excited to share it with everybody.

Review versions of text and image files — and even folders full of files — with the world’s most powerful file comparison app. Kaleidoscope gives you powerful tools to use at each stage of the development cycle.

Now with version 4.1, Kaleidoscope continues to innovate by directly integrating with Git to show you a history for a single file. This makes it incredibly easy to track changes to a file over time. Check out this blog post for a detailed overview of how you can use this powerful new integration.

As Michael Tsai wrote: “… Kaleidoscope makes some of these tasks really easy. There are many ways to get it to open a single file, and then it automatically loads the history (and even the previous version, if you want). It’s easy to navigate the history to pick which versions you want to compare. I’ve seen many different apps implement this type of interface, and Kaleidoscope’s version may be the best.”

Dave Verwer: “The UI of clicking through the history of a file with A and B buttons is simple and brilliant.”

In case you missed it, here are some of the most exciting features we added to Kaleidoscope with version 4:

  • Syntax coloring, with multiple built-in themes.
  • Transform any comparison into a merge document that can be edited inline.
  • Text filters to clean up diffs by removing irrelevant data, such as time stamps, object addresses and unique identifiers.
  • Kaleidoscope Prism, a new helper app in the menu bar to quickly launch comparisons even if Kaleidoscope is not running.
  • Debugger integration for Python developers.
  • File properties show metadata, including size, file type, dates, and encoding.
  • A welcome window that speeds up the processes of creating new comparisons or finding recent ones.

Subscriptions start at $8 per month for a yearly plan. Use the coupon code TERPSTRA (valid until August 31, 2023) to get 20% off for the first year. Check it out today!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-17T08:00:00-05:00
Web Excursions for August 14, 2023 https://brett.trpstra.net/link/535/16296073/web-excursions-for-august-14-2023 https://brett.trpstra.net/link/535/16296073/web-excursions-for-august-14-2023 Brett holding map

Web excursions brought to you in partnership with CleanMyMac X, all the tools to speed up your Mac, in one app.

zmd: Access Handy Utilities and Services in CLI
zmd (zmd.ee) is an experiment by Mighil. It hosts a bunch of handy ulities and services you can access in CLI via curl.
BatchPhoto 5
Batch photo processing app BatchPhoto just released version 5, updated for modern platforms and OSs, and adding SFTP upload and hot folders.
Instant Coffee – Bold Bean Coffee Roasters
I’ve been using this instant coffee when traveling for years. It won’t beat a cup from your favorite brewing setup, but it beats the pants off of most coffees they offer in hotel rooms. Just add hot water and stir.
Kelly R. Minter (Ask a Therapist) - YouTube
Another great resource for CPTSD and RTS, with special interest in LGBTQ+ folks.
Angel DeSantis - YouTube
Angel is a YouTuber who grew up in an apocalyptic christian cult and offers tips on dealing with Religious Trauma Syndrome and Complex PTSD. I’ve found her very helpful lately.

CleanMyMac X

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-14T11:05:00-05:00
Orchard Resales: get yourself a Mac mini, cheap [Sponsor] https://brett.trpstra.net/link/535/16281370/orchard-resales-get-yourself-a-mac-mini-cheap-sponsor https://brett.trpstra.net/link/535/16281370/orchard-resales-get-yourself-a-mac-mini-cheap-sponsor Thanks to Orchard Resales for sponsoring BrettTerpstra.com this week! If you’re looking for an older Mac mini to use as a server or entertainment center, you can pick up used 2012/2014 models dirt cheap!

I use a 2012 Mac mini as a basement server, running headless (no keyboard or monitor) and controlled over screen sharing. It runs Docker (and a few containers that give me things like network speed charts and VPN tunneling), Plex, and all of my home automation with all of my controllers hooked up to its USB ports. I also have a Synology, but you can easily set up file storage and serving with a Mac mini and a big external RAID drive. The one I run in my basement is a 2012 with a 500GB SSD and 16GB RAM. I’ve never needed to upgrade it any further to get everything I need out of it.

Want to set up your own, or have another use in mind for an old mini? Well, thanks to Orchard Resales you can pick one up for as little as $50 US. Deck one out with 16GB of RAM and an SSD and you’ll come out around $100. For a whole server, and it’s as easy to set up as using a Mac. And if you need spare parts, you can get non-functional Mac minis starting at just $15.

No, these can’t run the latest macOS, but for 99% of uses, they don’t need to, and if you’re really into it, you can use OpenCore Legacy Patcher to get all the functionality you need.

Check out Orchard Resales today and get started with your own server! Or buy a bunch and make a server farm!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-03T08:00:00-05:00
Sanebox: your email lifesaver [Sponsor] https://brett.trpstra.net/link/535/16278141/sanebox-your-email-lifesaver https://brett.trpstra.net/link/535/16278141/sanebox-your-email-lifesaver Thanks to Sanebox for sponsoring BrettTerpstra.com again this week! I’ve been using it for years and I can’t imagine my email inbox without it.

Drowning in emails? Enter SaneBox — your lifesaver. It’s a VIP service that sifts through your inbox, separates the important from the trivial, and serves up a neat digest. It works with any email provider, saving you 12+ precious hours every month.

But that’s not all. Fed up with pesky marketers? SaneBlackHole sends them packing with one click. Worried about forgotten follow-ups? SaneReminders has got your back. Too many non-urgent emails? Just hit the SaneSnooze button. And those countless attachments? SaneAttachments organizes them in your Dropbox, Evernote, Box - you name it.

TechCrunch, Forbes, The New York Times, all vouch for it. Sign up today and save $25 on any subscription. It’s about time we tamed our inboxes.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-08-01T09:45:00-05:00
Personal update: CPTSD edition https://brett.trpstra.net/link/535/16275514/personal-update-cptsd-edition https://brett.trpstra.net/link/535/16275514/personal-update-cptsd-edition I’m afraid you’ve been seeing a lot of sponsored posts and not enough posts from me lately, so I thought I’d try to explain why.

After a relationship in my life was destabilized and I had an outsized reaction to it, I started trying to figure out what was going on with me. I was pointed toward Complex PTSD and from there I discovered that Religious Trauma Syndrome, while not a part of the DSM, was a recognized thing, and that the causes and symptoms fit me perfectly.

I’ve spent the last couple of weeks trying to unpack what this means for me. So much of the me I’ve come to know is explained by this: my attention issues, my memory problems, my emotional dysregulation, my drug addictions, and even my Bipolar Disorder can all be tied to RTS and CPTSD.

I grew up as a “different” kid in a fundamentalist church. As a young child I had urges and thoughts that I constantly feared would send me to hell. When I wasn’t worried about my eternal soul, I was worried about my non-Christian friends and their eternal souls. By the time I was in Middle School I was drinking and trying to cope with what amounts to a constant fight or flight response, in addition to grief.

Being neurodivergent, queer, and highly sensitive was not a good combination for me in the church I grew up in. And I was taught to put all of my value, all credit for my successes, and all forms of attachment into God, not earthly things. So when I decided the church wasn’t good for me (or, in my mind, for anyone), I had the secondary trauma of leaving. Becoming emotionally estranged from my family, losing my Christian friends, and losing a god, the one thing that I had ever believed could save me. I still have a lot to learn about attachment theory, but it’s safe to say that I never felt securely attached to any people in my life, from my earliest memories. Which, to be fair, are very sparse, because a symptom of CPTSD is amnesia, if I understand it correctly. I’ve always wondered why everyone else remembered so many things from their younger years and I only had occasional memories of moments. Not events, not periods, nothing substantial, only snippets. I couldn’t remember who was there, how I felt about them, only whether I felt safe or scared in that moment. And most of what I remember is feeling scared.

I started therapy with a new counselor last week. She actually has a psychology PhD and does trauma-informed therapy, and I think she’ll be much more helpful than my last therapist. I have high hopes. All I know is that if it doesn’t work out I absolutely have to keep working to find a good fit, because this shit is more than I know how to deal with on my own, and I can’t expect the people in my life to deal with it for me. All of my insecurities have been laid bare, I’m reacting to the world from a raw and frightened place non-stop, and it’s exhausting. I need to learn how to find security, validation, and love within myself and not depend on external sources just to exist. And that’s something I never learned how to do as a Christian. It’s been 30 years since I stopped believing, and I’m still not a whole person.

I’m an atheist these days, and it was a hard fought battle against my ingrained thoughts. I declared myself agnostic in my late teens, but it seriously took 20 years for me to stop looking over my shoulder and wondering if I was making a serious mistake that would definitely doom me to eternity in Hell. I’m over that now, I think, but I still watch anti-theist YouTube all the time, and it makes me wonder if part of me is still scared. I don’t have any interest in the god of the Bible — he’s a real asshole. And I was raised to believe that any other version of God was heresy — even other sects of Christians were going to hell. If you didn’t worship the specific version of God that was defined by my church, you were going to burn. So if I can’t accept that religion, then there’s no religion that would calm my nervous system. It was trained into me as a child. I’m constitutionally incapable of having Faith (capital F), and I was taught that without Faith you’re doomed, and now I’m just trying to put it all behind me. I’m flailing a bit.

I had to tell my parents I couldn’t see them for Saturday morning breakfast for a while. They’ve always been kind to me. They (and their friends) have prayed for my eternal soul. They raised me the way they were raised and I don’t blame them for repeating the trauma. But every time I see them I’m re-traumatized and I didn’t realize what was happening until now. I’ve been to the hospital multiple times with heart problems, and guess what? It was almost always within 24 hours of having breakfast with my parents. I’ve decided that’s not a coincidence. They were very understanding, and I really believe they want the best for me, I just can’t disassociate them from my childhood trauma. Hopefully I can let go of that and reestablish a relationship with my parents.

So that’s why I haven’t been writing. I’ve been trying to grapple with 45 years of fear I had successfully avoided until now. I’ll be back. I’m reading, I’m going to therapy, I’m working to understand and develop tools for moving forward. I’m going to be stronger for having all of this laid bare and being forced to deal with it.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-07-30T15:04:00-05:00
BetterTouchTool: Introducing floating menus [Sponsor] https://brett.trpstra.net/link/535/16251230/bettertouchtool-introducing-floating-menus-sponsor https://brett.trpstra.net/link/535/16251230/bettertouchtool-introducing-floating-menus-sponsor Thanks to BetterTouchTool for sponsoring BrettTerpstra.com this week! I am a huge fan of BetterTouchTool and use it all day every day on my Mac. I wouldn’t know what to do without it. From customizing my keyboard shortcuts to adding infinite gestures to my trackpad to running my entire Stream Deck setup, there’s nothing this little utility can’t do.

I think BetterTouchTool is well known to readers of this blog (thanks Brett!), so I won’t go into the details of the many things you can do with it. Instead I want to promote a powerful new feature that has been added to BTT recently and is currently in beta phase: Floating Menus.

Imagine them as highly flexible, widget-like menus that you can place virtually anywhere on your screen.  You can attach them to specific positions in specific windows, to specific screens, the current mouse position and many more. You can specify whether they float on top, stick them to your desktop or have them behave like normal windows (and more). 

They can always be visible, expand on mouse hover or be shown/hidden via any trigger in BTT.

A Floating Menu contains either standard buttons, or widgets like sliders or even web view items. Their appearance is completely customizable. All items are fully scriptable via AppleScript or Javascript, and soon there will be a plugin system to load custom widgets.

The Floating Menus will soon become the basis for numerous existing BetterTouchTool features, such as Stream Deck and Notch Bar support and several predefined actions. These will gradually transition to utilize the Floating Menu rendering and scripting engine making them more flexible and robust by streamlining maintenance & future development.

Additionally, the upcoming (entirely new) version of the iOS BTT Remote app will be capable of rendering your custom Floating Menus on your iPhone or iPad. 

You can find various Floating Menu examples on share.folivora.ai. For example have a look at the Notch menu, which is invisible by default but expands from your Macbook’s Notch on hover. Another nice example is the “Mini Emoji Menu” preset: it places a little transparent dot on the left edge of the active window, which, when hovered, shows multiple custom emoji which you can insert by clicking.

The documentation for this new feature is already available, and you can always come to the community site to discuss or request features. Now that I have a solid working base, I can easily built on it, so please report any bugs and request any feature you can think of!

Try BetterTouchTool now (45 day free trial) or go and purchase a license with this 20% coupon code: BTBTT2023.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-07-20T08:00:00-05:00
Web Excursions for June 29, 2023 https://brett.trpstra.net/link/535/16214159/web-excursions-for-june-29-2023 https://brett.trpstra.net/link/535/16214159/web-excursions-for-june-29-2023 Brett holding map

Web excursions brought to you in partnership with Setapp. Get access to hundreds of Mac and iOS apps for one low monthly subscription fee.

Post-Twitter Diaspora Options
Some opinions on Mastodon and Bluesky. Personally I wish ill of Bluesky and have high hopes for Mastodon. But I’m certain it won’t pan out like that.
Brave Search No Longer Using Bing
A Michael Tsai two-fer this week.

Their own index, based on Tailcat, is working better than DuckDuckGo/Bing for me now. Hopefully, Apple will add built-in support to Safari. Worth testing out, even if Brave isn’t going to be my primary browser…

Xnapper
I’m still a die-hard CleanShot fan, but this little tool makes some gorgeous screenshots ready for social sharing, with tools for auto-balancing, changing backgrounds, and redacting email addresses and other text. Simple and beautiful.
Pixabay
A large collection of excellent royalty-free photos and audio tracks.
LaunchBar/Ask-ChatGPT
A ChatGPT LaunchBar action. Allows continuing conversation, predefined prompts, clipboard interaction, and can open results as a Markdown file ready for use.

Check out Setapp today and get access to the best Mac and iOS apps out there.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-06-29T11:58:00-05:00
Sanebox, your email concierge [Sponsor] https://brett.trpstra.net/link/535/16213929/sanebox-your-email-concierge-sponsor https://brett.trpstra.net/link/535/16213929/sanebox-your-email-concierge-sponsor As I’ve said before, I’m a long time user and lover of Sanebox. Thanks to them for sponsoring again this week. Here’s a user story from Thomas Yuan.

Well, here’s a funny thing: I started using SaneBox because my email was an utter disaster, and I needed something to save me from the deluge. Little did I know that I was stepping into a world where email isn’t just manageable, it’s… well, sane. I know, I know…

SaneBox is like having your own personal email concierge. It’s not just a filter - oh no, that’s underselling it. It’s like a highly-trained butler who goes through your mail, knows what’s important, and presents you with only the choicest pieces of correspondence.

Everything else? Neatly sorted away, out of sight, out of mind.

Setting up SaneBox is as easy as pie. And I’m not talking about some complicated lattice-top apple pie here. I mean one of those simple, comforting pumpkin pies. You just connect your email account, and voila, SaneBox starts its magic. It learns from your actions, your patterns, tailoring its sorting to your specific needs.

Now, the main feature here is the @SaneLater folder. It’s like a second inbox, except it’s where all the non-urgent emails go to hang out. Newsletter from that one store you bought socks from 3 years ago? That’s a @SaneLater item. Automated system alert about a software update? You bet that’s going in @SaneLater.

What’s more, you can customize it to your heart’s content. There’s @SaneBlackHole for those pesky emails you never want to see again, and @SaneNews for newsletters and the like. You can even create your own folders, and SaneBox will learn to sort your emails accordingly.

And don’t get me started on @SaneReminders. Ever sent an email and needed a reminder if nobody replies? Just CC or BCC to 1week@sanebox.com, and if there’s no reply in a week, it pops back up in your inbox. It’s like a boomerang made out of pure organizational power.

Sure, there are other email management tools out there. But SaneBox stands out for its simplicity, its flexibility, and, most of all, its effectiveness. It’s like it took my unruly, wild-west email inbox and turned it into a sleek, streamlined, email-answering machine. And, in a world where every spare minute counts, who wouldn’t want that?

So, if you’ve got an email inbox that’s more like a black hole, give SaneBox a whirl. I promise you, you won’t be disappointed. It’s affordable, efficient, and pretty darn fun to use.

And here’s a pro tip: if you’re ever unsure about a feature, just explore their help center. It’s packed with useful guides and tips. It’s like the cherry on top of the SaneBox sundae.

SaneBox isn’t just a tool, it’s a lifestyle change. It’s a way to take back control of your inbox and, by extension, your digital life. It’s helped me, and I’m pretty sure it’ll help you too. So why wait? Start living the sane way today.

Sanebox is an inexpensive choice. You can get a free trial to experience the difference in email management without any commitment. Plus, the app offers flexible monthly plans starting at just $7.

Check out SaneBox today, sign up and save $25 on your subscription.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-06-29T08:00:00-05:00
Remembering Yeti https://brett.trpstra.net/link/535/16210634/remembering-yeti https://brett.trpstra.net/link/535/16210634/remembering-yeti Yeti the cat

My cat died a couple weeks ago. I had him for 20 years and he’s left a large hole in my life. I know not everybody gets cats the way cat people do, but he was honestly one of my closest friends. I just wanted to write a bit about him now that the grief is a bit less raw and just remember him for the legend he was.

My ex and I were around when Yeti’s mom had her litter. She had health problems and sadly had to be euthanized shortly after Yeti and his siblings were weaned. I had my pick of the litter. I had recently lost a tuxedo cat (Trouble) to a pit bull attack, and thought I’d take the one tuxedo in the litter. Aditi’s mom suggested I also take this one bashful kitten who had a hairline similar to mine. I agreed. Jezebel (the Tuxedo) became Aditi’s cat, and Yeti almost immediately became very bonded to me. I’ve always been thankful I was talked into taking him.

Yeti and Jezebel

Both Yeti and Jezebel were polydactyl, and Yeti’s front paws had six toes each. I almost named him Big Foot, but given his long, thick white hair, “Yeti” seemed more apropos.

Yeti displayed what can only be anthropomorphized as “empathy.” He always understood when I was sad or sick and would lay by me, placing one paw on my thigh, or curl up on the couch behind me and put his paw on my shoulder. And when I was happy or comfortable, he would be in my lap. He loved to sit facing me with his paws on my chest and give me nose bumps. He learned very young that licking my nose repeatedly was a bit painful, and would just give one lick or tap and then stop.

Speaking of understanding pain, Yeti learned at a very young age that his claws and teeth hurt me, and after he got past the part of his life where he would try to climb my leg with his sharp little kitten claws, he never bit or scratched anybody, ever. I once held him while a urinary crystal was removed through his urethra; he held onto my arm and yowled, but never clawed or bit, which was impressive. I think if someone was squeezing a rock through my private bits I would probably try to bite the nearest arm I could.

Yeti resting his paw on my shoulder

Jezebel passed away under the care of Aditi a few years back. We honestly never expected Yeti to outlive her, but he lived to 19 years and 9 months and I enjoyed every minute of it. I’ve spent more time with Yeti than with any human in my entire life. He was always around. I never even saw my parents that much from 0-18. And I’ve never had a romantic relationship longer than about 13 years. So Yeti was my longest relationship and the “partner” I’ve spent the most of my life with. I appreciate humans and all, but Yeti and I never had a fight or even a misunderstanding. He was just always there for me. I gave him all my love, and he returned it.

Yeti crawling into Elle's shirt

Yeti has been living with my partner Elle and I for about 5 years now. It took him a while, but he eventually accepted Elle as his other person. He worked his way into her heart and Elle loved him as much as I did. He helped pull our little “family” together, and I know she’s missing him right now, too.

The last couple years have been full of health scares. He went from 20 pounds to 6 pounds at the end. He had a bout of pancreatitis, and then kidney failure. We’d been expecting him to die for quite a while now, so we had plenty of time to prepare for this. And he gave me the best ending I could imagine…

Yeti saying goodbye

He was energetic and loving on Thursday, and then at 2am on Friday he crawled under my covers and fell asleep. That was the last time he moved on his own. He spent the day with me Friday, with his paw in my hand or on my leg. I would place him in the middle of the couch and then work on my laptop on the side, and he would pull himself over to me to put his paw on me or bury his head in my thigh. I took him to bed with me that night. On Saturday at 5:15am, I rolled over and put my hand on him. He took two deep breaths and then exhaled his last. Man, he waited until I woke up to say goodbye. Seriously, he was the most caring cat you’ll ever meet.

I will always miss Yeti, but he gave me a great 20 years in the prime of my life. I’m not nearly as devastated as I thought I’d be. It was all so peaceful. He stayed by me all the way to the end, and I’ll be eternally grateful that he passed peacefully at home and I didn’t have to make the decision to end his life in a cold vet’s office. I’ve done that with beloved pets a dozen times over the years, and it’s a horrible thing to go through. Yeti gave me a fairy tale of an ending.

I made a video out of 20 years’ worth of pictures. It’s too long, but if you want to enjoy it and have the patience for it, consider it my tribute to the best cat ever.

YouTube Video

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-06-27T11:19:00-05:00
Snibbets 2.0.34 https://brett.trpstra.net/link/535/16195268/snibbets-2-dot-0-34 https://brett.trpstra.net/link/535/16195268/snibbets-2-dot-0-34 I released a new version of Snibbets this morning that solves one peculiarity: if you have multiple snippets in one file but any of them don’t contain code blocks, then the titles and display would get weird.

Now you can have sections of a snippet file (separated by ATX headers) that contain just notes. If a section contains just notes and no code, then the notes will be output for that section, even when not using --notes or having all_notes: true set in config.

This just allows for uses of Snibbets as both a note reference and a snippet manager. It probably won’t effect people who are using it “as intended,” but opens up new use cases.

To get the latest version, use gem install snibbets. See the project page for more details.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-06-17T09:43:00-05:00
Doing with multiple sections https://brett.trpstra.net/link/535/16160573/doing-with-multiple-sections https://brett.trpstra.net/link/535/16160573/doing-with-multiple-sections Funny story: I got a feature request for mdless to allow multiple sections to be specified in the output, but I misread the notification as a request for Doing. So I spent a couple hours adding multiple section handling to an array of Doing commands and happily reported the result to the user, who was very confused by the version number I gave him. I apologized and have now added multiple section handling to mdless, which was a lot less work than adding it to Doing. So I might as well write a blog post about the Doing feature nobody asked for, I guess.

Most of Doing’s many commands allow for the specification of a particular section, e.g. the show command can limit its results to just one section, or the tag command can tag the last X entries from a given section. Now, almost all of these commands can take multiple sections, either specified as -s section1,section2 or by using multiple -s flags in the same command, e.g. doing show -s currently -s later.

This allows a little more flexibility, especially for display commands. It also means you can perform actions on a more limited set of entries without limiting it to just a single set. It (obviously) doesn’t apply to the now command or other entry commands because an entry can only be in one section.

By the way, section names are fuzzy matched, so you can specify that you want results from both Currently and Later (assuming you have such sections) with -s curr,lat.

If I expand this further, I’ll allow negative arguments as well, such as doing show -s -archive to exclude the Archive section. But for now it’s just multiple sections.

That’s all for now, just figured I’d mention it since I put the effort into it. You can update to the latest with gem install doing (which might require sudo, depending on your setup).

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-06-03T11:54:00-05:00
Some Ultimate Hacking Keyboard configuration tips https://brett.trpstra.net/link/535/16150699/some-ultimate-hacking-keyboard-configuration-tips https://brett.trpstra.net/link/535/16150699/some-ultimate-hacking-keyboard-configuration-tips uhk-key-cluster-rb.jpg

This post will only be of interest to those using the Ultimate Hacking Keyboard (UHK), specifically with the lefthand key cluster module. I recently added some customizations I thought might be worth mentioning to those who happen to have this setup. For those who don’t, maybe read on and be tempted by the possibilities…

The latest version of the Agent software for the UHK allows the definition of up to four additional Function layers, or sets of keys that are mapped when a modifier is held down. You’re probably used to the Mod layer, which is how you turn I/J/K/L into arrow keys, etc. when you hold the Mod key, and the Fn layer, which turns 1 into F1 when you hold the Fn key. By clicking the down arrow on the layer bar, you can now check boxes next to Fn2-Fn5 layers to enable them. Then you can assign keys to trigger them, which is where the key cluster module comes in.

The key cluster module provides 3 extra keys to the right of your B key and Space key (by default it’s the Mod key, but I swap my Mod and Space keys). I initially assigned these to R on the top (B when Mod is held, creating Run and Build buttons in Xcode and other IDEs, and a Refresh button in most other apps), and Enter and Backspace on the bottom two keys (Numpad Return and Forward Delete when Mod or Fn is held). But then I realized they could further function as triggers for other layers.

You can assign a secondary function to any key, which is an action that’s performed when it’s held while another key is pressed. For example, I change the default Mouse key into Caps Lock (which becomes my Hyper key along with Karabiner Elements), and use the secondary function on the Tab key so that when it’s held in combination with other keys, it triggers the Mouse layer.

The bottom left key of the module is a very natural reach for the left thumb, and was the first layer I created. I added a Fn2 layer, and then assigned the secondary function of that key to trigger the Fn2 layer when held. Now I can map anything on the right side, and on the left side I can map anything easily reached by my remaining fingers when my left thumb is holding the module key down.

I assigned A-G (home row) keys to F20-F24, which I then use with BetterTouchTool to trigger actions. I also assigned the block of keys from Y-O down to N-. on the right side to produce characters I commonly use in coding, such as curly/square/angle brackets. It took a while to get used to using those instead of reaching for the actual keys, but it does speed things up with a little practice.

Then I added a Fn3 layer, and made it so that when the right bottom button of the module was held, the other two buttons turn into PgUp and PgDown, and B and Space turn into Home and End. This is essentially the same as holding down my (repositioned) right Mod key and using the arrow cluster on my right hand, but gives me easy one-handed left-handed scrolling while my right hand is on the trackpad. I haven’t added anything else to that layer yet.

The top key on the module triggers the Fn4 layer, which simply turns the bottom two keys into [ and ] for forward back navigation.

I’ll expand the Fn3/4 keymaps as I find needs for them, but one step at a time. I’ve made the mistake of programming complex layers (and entire other keymaps) and then having to make extensive cheat sheets to remember where everything is until I develop muscle memory for them.

Bonus tip: The Fn layer by default only affects the number keys, so there’s a whole lot of room for mapping other functions to letter keys. I turn a block of keys on the right to be media controls:

I hope that provides some interesting ideas for your own customizations. If you’re interested in this kind of thing but haven’t looked into the UHK, I highly recommend checking it out. Splurge on the wrist wrests and the key module!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-05-27T12:20:00-05:00
Never let your email inbox exceed its quota again [Sponsor] https://brett.trpstra.net/link/535/16132268/never-let-your-email-inbox-exceed-its-quota-again-sponsor https://brett.trpstra.net/link/535/16132268/never-let-your-email-inbox-exceed-its-quota-again-sponsor Thanks to Sanebox for sponsoring BrettTerpstra.com this week! Sanebox has just introduced a new feature called Deep Clean, a way to reclaim your storage quota with smart batch deletes of old emails. Check it out for free and save yourself the headache of running out of space.

Is your email close to going over its storage limit? With our new free tool Deep Clean, you’ll never have to worry again. Use Deep Clean to quickly sort and delete unnecessary emails in bulk so you never have to pay for extra storage again. The best part? It’s free.

Get It for Free

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-05-18T10:40:00-05:00
NiftyMenu update for Ventura https://brett.trpstra.net/link/535/16105972/niftymenu-update-for-ventura https://brett.trpstra.net/link/535/16105972/niftymenu-update-for-ventura niftymenuheader-rb.jpg

Not so long ago I wrote a little script that would generate an HTML playground of any MacOS app’s menu bar, primarily for the purpose of generating screenshots. It has a full automation API and you can script screenshots with fuzzy name matching, meaning menu items names and positions can change and your automated screenshots will still work. It’s a very specific use case, but I shared it because it took way too much time and I would love it if it helped even one other person.

Yesterday I updated the menu styling to match Ventura, which uses new submenu indicators, slightly smaller font sizes by default, and slight changes to background opacity and hue. The results should look like a passable rendition of the latest operating system now. You can check out the demo here.

NiftyMenu also got its own project page on this site, with full documentation and installation instructions.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-05-04T08:51:00-05:00
Web Excursions for April 29, 2023 https://brett.trpstra.net/link/535/16097178/web-excursions-for-april-29-2023 https://brett.trpstra.net/link/535/16097178/web-excursions-for-april-29-2023 Brett holding map

Web excursions brought to you in partnership with Backblaze. Back up everything.

Everything wrong with Twitter’s new verification system.
I lost my blue checkmark in April, and by the time it happened, I was grateful to have it gone. It used to actually mean something, now it’s just a badge of support for Musk and his leadership.
Default Folder X 6.0: A tour of what’s new
Love the Quick Search idea. Beta is available for download if you’re a registered DFX user.
Pixelmator Photo gets AI-powered selective adjustments and a new
Pixelmator is now Photomator, and comes with AI selection tools that are very tempting.
Auto Tape Wrapping Machine Is Amazing For Cable Management
I wish I was handier (and had a lot more tools), this is exactly the kind of hack I would love to build on a whim.
What the Chef!?
Enter your available ingredients, get a recipe to use them. In my experimentation, it actually did a great job without requiring a grocery store trip for additional ingredients.

Backblaze securely backs up your entire computer to the cloud, affordably and reliably. I trust it with all my data. Check it out today.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-29T10:15:00-05:00
SaneBox could be your secret weapon against email overload [Sponsor] https://brett.trpstra.net/link/535/16094378/sanebox-could-be-your-secret-weapon-against-email-overload-sponsor https://brett.trpstra.net/link/535/16094378/sanebox-could-be-your-secret-weapon-against-email-overload-sponsor Thanks to SaneBox for sponsoring BrettTerpstra.com again this week! I don’t know what I would do without it.

Ever feel like you’re drowning in a sea of emails? You’re not alone. We know the struggle of managing important emails while fighting spam messages with flashy sales. For every 10 emails from sources you don’t even remember subscribing to, you get one important one. When you find it, it feels like you’ve already finished a long task, doesn’t it?

Finding important messages shouldn’t feel like a battle between you and your inbox. In fact, why do you have to sort through all these unimportant files in the first place?

In a world of relentless digital communication, email overload is a common struggle. But SaneBox can help you to conquer your inbox once and for all! Using AI, SaneBox learns your email habits and sorts incoming messages precisely, so you can achieve the ultimate victory: a perfectly organized inbox.

Let’s explore this service in a quick overview!

Why SaneBox Stands Out

  • AI-Powered: SaneBox’s algorithms learn your email behavior and customize your inbox management experience. So, if you want to see your favorite brand’s discounts in the same inbox as your collaborator’s messages, you’ve got it!
  • Personalized Prioritization: High-priority emails stay in your main inbox, while lower-priority messages move to a separate folder for later review.
  • Focus-Driven Features: With tools like Do Not Disturb, you can pause incoming emails and concentrate on your tasks without distractions. You can come back to them whenever you’re ready.
  • Universal Compatibility: SaneBox works with any email service. So whether you’re using Gmail, Yahoo, or Outlook, you can tame that inbox.

Key SaneBox Features

  • Smart Filtering: Automatically sorts emails based on your habits and priorities as soon as they reach your inbox. It’s like having a personal assistant to filter your inbox (but without the awkward daily interactions).
  • SaneNoReplies: Tracks messages you’ve sent without a response, making it easy to follow up.
  • Customizable Folders: Organize your emails effortlessly with custom-made folders for all your categories and priorities.

When it comes to pricing, Sanebox is an inexpensive choice. You can get a free trial to experience the difference in email management without any commitment. Plus, the app offers flexible monthly plans starting at just $7. It’s really that affordable!

Check out SaneBox today, sign up today and save $25 on your subscription.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-27T08:00:00-05:00
Web Excursions for April 25, 2023 https://brett.trpstra.net/link/535/16091472/web-excursions-for-april-25-2023 https://brett.trpstra.net/link/535/16091472/web-excursions-for-april-25-2023 Brett holding map

Web excursions brought to you in partnership with Backblaze. Back up everything.

Swell AI: Automate writing podcast shownotes & articles

Swell AI automates writing articles, summaries, social posts, time-stamped show notes and more for your podcasts and videos.

Luciole - Typeface

Luciole (French for “firefly”) is a new typeface developed explicitly for visually impaired people.

LetsAsk.AI
Another way to build a chatbot for a website, using your own data. Tested it out with the Marked help website, did a pretty good job. Not good enough to include the chatbot in the help yet, but I see potential.
kudoai/duckduckgpt

DuckDuckGo add-on that brings the magic of ChatGPT to search results.

Trackify
Analytics for Spotify. If you like seeing your music listening quantified in various ways, this is an intriguing service for just that.

Backblaze securely backs up your entire computer to the cloud, affordably and reliably. I trust it with all my data. Check it out today.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-25T12:48:00-05:00
Static blogs and Mastodon https://brett.trpstra.net/link/535/16087044/static-blogs-and-mastodon https://brett.trpstra.net/link/535/16087044/static-blogs-and-mastodon mastodon-rss-rb.jpg

I use FeedPress to handle this blog’s RSS feeds. It reads my statically-generated RSS feed and gives me subscriber stats, as well as the ability to send new posts to social media endpoints. But it lacks Mastodon integration, and I’m spending most of my time on Mastodon lately (find me at @ttscoff@nojack.easydns.ca). So I wanted my new posts on this blog to automatically post to Mastodon. The script in this post could be used with any blog that generates an RSS feed, but is mostly geared toward static blogs.

I got started with a post from Dr. Drang called “Announcing New Posts on Mastodon”. It included a Python script that I referenced to create a Ruby script for my needs. Thanks to the Doc for getting me started!

You can find the script here. See below for configuration and usage.

Configuration

To configure the script, at minimum, you need your Mastodon endpoint and an auth key. Your endpoint is generally your Mastodon instance URL with /api/v1/statuses appended to it, e.g. https://mastodon.social/api/v1/statuses. I’m not sure if this is ever not the case. The auth key can be generated by going to your Mastodon homepage, clicking the Settings gear icon, and choosing Development. Create a new application with any name, your blog url as the website, and leave the Redirect URI as is. Make sure it at least has permission to write:statuses. You’ll then see a client key, a client secret, and an access token. All you need is the access token for this script.

Set up the script by updating MASTODON_ENDPOINT (as described above) and MASTODON_AUTH (with your access token).

You’ll also need to configure the RSS feed. The script can parse JSON or XML feeds of your blog (local files or URLs) to find the latest post. If you want to use a JSON feed, set JSON_FEED to either a local JSON file (~ is fine for your HOME directory) or a JSON feed url. If you’re using an XML feed, set JSON_FEED to nil, and set RSS_FEED to either a local file or url. With FeedPress, my JSON is generated from my XML and both feeds can take a few minutes to update, and the most immediate list of posts I have is the local atom.xml file generated with my site, so that’s what I have mine set to. That way I can run this script immediately after a new deploy and still get the latest post.

The rest of the settings in the script are the template used for the status (POST_TEMPLATE), an optional query string that can be appended to the URL for campaign tracking, etc. (QUERY_STRING), and then a few options for updating front matter. I imagine most people won’t need the front matter bit, but the options are commented if you need them.

It records what it posts to a local JSON file (location set with TOOTS_DB), so it won’t post the same thing twice. Optionally, it can go back and add a mastodon: [TOOT_URL] key to the original Markdown for the post. I’m using this to render a Mastodon link on each post that links to the toot so that people can reply/share it from their Mastodon account (since Mastodon doesn’t/can’t offer a “Toot This” link the way Twitter can, as far as I know)1. For most people this step is probably unnecessary, and can be disabled entirely by setting the ADD_FRONT_MATTER constant at the top of the script to false.

Usage

All of the necessary config is commented, should be pretty easy to get running. Rather than rely on Ruby’s Net/HTTP library, it just uses curl to make the call, so you need a curl binary available (this is default on most systems).

To use the script, save it as toot.rb and run chmod a+x toot.rb on it. If properly configured, you can just run ./toot.rb to toot the latest post from your feed. If you want to test, use --debug (or just -d), and it will set the visibility=direct parameter that will make the resulting Mastodon post show up only for you (private).

You can run ./toot.rb --last-ten to toot the last 10 posts. Use ./toot.rb -h to see available options.

By default, when the script creates a new toot, it will notify you on STDERR. It will also output NEW_TOOT: [TOOT_URI] to STDOUT, which is what I use to detect whether a new toot was created and trigger a rebuild. You can disable all output with --silent (or -s).

Updating Front Matter

If you want to use the front matter updating “as is” in the script, it requires that your blog posts be named to match the url. It takes the url path, substitutes slashes for dashes, and removes index.html and any trailing slash from the url to create the slug, then adds .md. So if your post is at https://brettterpstra.com/2023/04/21/im-on-shrooms-like-right-now/, the resulting file it will look for is 2023-04-21-im-on-shrooms-like-right-now.md. If your naming scheme is anything else, it would require manual editing to work.

For reference, I have this script run as part of my Rakefile :deploy task. Once the site is fully deployed, it runs toot.rb and toots the latest post. If the script returns NEW_TOOT on STDOUT (meaning the post has never been tooted before and the front matter for the tooted post has been updated), it will re-render and deploy the site again so that the Mastodon link on the newest post goes live. Presumably, although that’s about to be tested when I publish this post. It’s a bit of a hacky workaround, but I can’t toot it until the post is live, and I can’t get the Mastodon link until it’s tooted, so it takes twice to get it right. It will only ever toot a post once, so updates and re-renders won’t be doubled.

task :generate_deploy do
  # [Deploy tasks...]
  toot
end

def toot
  exe = File.join(__dir__, 'toot.rb')
  res = `#{exe}`.strip
  Rake::Task[:generate_deploy].invoke if res =~ /^NEW_TOOT/
end

In Closing

I hope that FeedPress eventually adds Mastodon sharing to its social services, but my current setup really likes having the actual URL for the associated Mastodon post available, so that wouldn’t do much good in this scenario anyway. I hope this script is helpful to other people using static blog setups and wanting Mastodon integration.

If you do generate your own RSS feed and don’t currently get statistics from it, I do recommend checking out FeedPress. It’s affordable, and great for blogs and podcasts.

Again, you can find the script in this gist.

  1. I considered just using JavaScript to load the JSON record that this script creates and inject a Mastodon link on the front end (avoiding multiple renders), but for a few reasons decided I’d rather add a hardcoded link at render time. 

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-21T12:49:00-05:00
Markdown to Bike conversion https://brett.trpstra.net/link/535/16078222/markdown-to-bike-conversion https://brett.trpstra.net/link/535/16078222/markdown-to-bike-conversion I’m liking outlining in Jesse Grossjean’s latest app, Bike, for my outlining needs. It’s a simple outliner that can save the content of its outlines to Bike files, OPML documents, or plain text. And its native document format is plain HTML that’s easy to work with.

As an aside, Jesse just released Shortcut actions for Bike, making it possible to do some automation of Bike and Bike documents. I haven’t played around with it much yet, but if you’re into Shortcuts, check out what’s available.

One thing that Bike lacks is an easy way to convert Markdown lists to Bike outlines. It can actually read indented plain text just fine, but the list markers are included in the node text, and blank lines become empty nodes instead of being compressed. Running a list through a Markdown processor and saving as .bike can often create an invalid file, as Bike requires every list item to contain a paragraph tag, not bare text.

I initially played around with running Markdown through a Markdown processor and then manipulating the output, but ultimately went with a much simpler version that compresses newlines and removes list markers, putting the resulting indented text in your clipboard. Pasting the result into a Bike document should almost always yield the expected result.

Save the script below as md_to_bike in your PATH and run chmod a+x path/to/md_to_bike. It can be called as a pipe or on a file. To call it as a pipe, run cat myfile.md | md_to_bike. To call it on a file, just provide the path to the file as an argument: mmd_to_bike path/to/myfile.md. The results will be placed in your clipboard, ready to paste into a Bike document.

md_to_bike.rbraw
"
#!/usr/bin/env ruby
# frozen_string_literal: true

# This script takes simple Markdown lists and converts them for use in
# Bike (https://www.hogbaysoftware.com/bike/), a Mac outliner app from
# Hog Bay Software.
#
# It doesn't handle nested code blocks or any non-list Markdown. It just
# turns simple lists into text Bike will recognize when it's pasted into
# a Bike document. Multiple paragraphs in a list item become additional
# nodes at the same level.

require 'shellwords'
require 'fcntl'

stdin = $stdin.read.strip if $stdin.stat.size.positive? || $stdin.fcntl(Fcntl::F_GETFL, 0).zero?

if !stdin && ARGV.count != 1
  exe = File.basename(__FILE__)
  puts "#{exe} requires one argument"
  puts "#{exe} [markdown file]"
  Process.exit 1
end

source = ARGV[0]

# Read input file
content = stdin ? stdin : IO.read(source).strip
# Remove spaces from empty lines
content.gsub!(/^\s*\n/, "\n")
# Replace consecutive empty lines with a single newline
content.gsub!(/\n+/, "\n")

# Replace 2 or 4 spaces with tabs (based on detected indentation)
m = content.match(/^ {2,4}/) # find first indentation
indentation = m ? m[0].length : 1 # determine whether first indent is 2 or 4 spaces
content.gsub!(/^( {#{indentation}})+(?=\S)/) do |m| # Replace leading spaces with tabs
  mtch = Regexp.last_match(0)
  mtch ? "\t" * (mtch.length / indentation) : m # tab * detected indent / detected indentation
end

# Replace markdown list markers
content.gsub!(/(\s*)[+*\-] /, '\1')

# Copy result to clibpoard
`echo #{Shellwords.escape(content)} | pbcopy`

puts "Results in clipboard. Paste into a Bike document."

Hope that’s of use to somebody.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-18T13:09:00-05:00
Snibbets plain text code snippet manager reborn https://brett.trpstra.net/link/535/16073537/snibbets-plain-text-code-snippet-manager-reborn https://brett.trpstra.net/link/535/16073537/snibbets-plain-text-code-snippet-manager-reborn Snibbets banner

Over 20 years of writing scripts and apps I’ve collected a lot of “snippets” of code that I save whenever I solve a problem and think I’ll want the solution again in the future. I like these snippets to include notes and links, and I need to be able to easily search them and grab the code when I need it without much effort. That’s why I wrote Snibbets back in 2020.

I’ve now refactored Snibbets as a gem and vastly improved its capabilities. I wanted the simplicity of creating snippets in nvUltra and searching them quickly from the command line, getting just the code I need with a few keystrokes. I keep iTerm in Visor mode, so it’s a hotkey away, and just as convenient as any quick find panel in a dedicated snippet management app.

Snibbets now has its own project page where you can read all about its features and options. You can also see all the code, file bug reports, and make feature requests on GitHub.

Here’s a quick overview, though.

Snippets Are Markdown Files

A snippet is just a Markdown file, where the filename becomes the title, optionally with additional extensions that help the syntax highlighter, e.g. symbolize hash keys.rb.md. The document can contain tags in MultiMarkdown metadata format, titles as # headlines, additional notes, and the code snippet either indented or fenced with optional language specifier. A single document can contain multiple snippets, separated with headlines as titles for each one.

Snippets all go into one folder. You don’t need to organize them into directories, that would defeat the purpose of the full text search in Snibbets. You can open that directory in any app that can handle it, such as nvUltra or Obsidian, and have full access for editing and creating new snippets.

Searching Your Snippets

To search your snippets, just run snibbets SEARCH TERMS. It will use a combination of Spotlight, find, and grep to find matches. If there’s more than one match, you’ll get a menu, and if the selected file contains more than one snippet, you’ll get a second menu. The code from the snippet is output to the console without any accompanying notes.

You can run with --edit to open the selected snippet in your editor to see all of the notes or update the code. You can also use --nvultra to open the snippet in nvUltra, assuming you’re on the beta. You can also run with --copy to copy just the code to your clipboard in addition to displaying it in the console. Run snibbets -h to see all available options.

Filtering

When multiple results/snippets are detected, a menu is generated. If you have fzf installed, it will be used for the menu, allowing fuzzy searching to narrow results. If you don’t have fzf but do have gum installed, that will be used and is almost as good for this purpose. Failing that, Snibbets will generate its own menu and you’ll have to enter a number to get the snippet. fzf and gum are far superior, so I recommend installing one or the other.

Syntax Highlighting

I put a lot of time into syntax highlighting. You can use either Pygments or Skylighting (separate installations), and you can configure the theme. Syntax definitions are picked up from the filename and from language specifiers on fenced code blocks. It looks really great using Skylighting and the Nord theme (as shown in the video above). To enable this, edit your config (snibbets --configure) to include:

highlight: true
highlighter: skylighting
highlight_theme: nord

Snibbets will avoid highlighting anything going to the clipboard or being piped or redirected to other commands. Keeps things tidy.

It’s a simple tool1, but it makes it feasible for me to store all of my code snippets in a way that allows nvUltra to become my main code snippet manager, and gives me instant access to any snippet from the command line. Just what I needed.

Check out the project page or see it on GitHub.

Support Brett's work with a donation, or sponsor me on GitHub!

  1. though you wouldn’t know it based on the number of hours I’ve put into it lately. 

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-16T10:33:00-05:00
Syntax highlighting is fun, and you won't believe this one weird trick https://brett.trpstra.net/link/535/16071938/syntax-highlighting-is-fun-and-you-wont-believe-this-one-weird-trick https://brett.trpstra.net/link/535/16071938/syntax-highlighting-is-fun-and-you-wont-believe-this-one-weird-trick highlighted code screenshot

Over the last couple of days I got obsessed with wrangling my code snippet collection, once again. It’s not healthy, but it is what it is. I dug back into Snibbets, a tool for managing code snippets as plain text Markdown files that I started back in 2020. I actually got it to a really good point today, but I’m realizing that it’s getting bloated enough that it needs to become a gem before I’m ready to hype it up. The current version and mostly-up-to-date documentation are up on GitHub, though, so feel free to peek in the meantime.

But that’s not what I’m here to tell you about. In the process of working on Snibbets, I wrote a little routine that could turn a file extension into a programming language name for tagging purposes, and vice versa. It seemed ripe for making a little one-off utility, so I’ve posted a standalone version to GitHub. I’m going to be using it when I’m doing technical writing and including code samples in languages I don’t usually work with. When you create a fenced code block, you can add a “lexer” to the opening fence, e.g. ~~~ruby, which helps most platforms with properly syntax highlighting it. But then I find myself working on someone else’s Terraform code and I’m unsure whether that’s a supported language for syntax highlighting. Now I can just run lexers.rb terraform or lexers.rb tf and it will tell me all about it. What the available lexers are, what common extensions are associated with it, you know, the works.

I built this by taking the output of pygmentize -L lexers and running it through a few regular expressions to make a parseable data set. Then I took the output of skylighting -l to add a few more lexers (though those don’t have extensions listed and I don’t know many of the more obscure ones, so that data serves to search for a valid lexer, but nothing else). The script itself just builds a queryable object out of the data and offers a few different ways to get at the data (you can see the whole set at the bottom of the script). The easiest way to use it is like I mentioned above: just pass a file extension or language name to it as an argument and it will give you back the info you need. There’s more documentation in the comments of the script.

Just thought I’d share it! Check out the gist if you’re interested.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-14T15:40:00-05:00
I forgot about the Titlecase API https://brett.trpstra.net/link/535/16070204/i-forgot-about-the-titlecase-api https://brett.trpstra.net/link/535/16070204/i-forgot-about-the-titlecase-api I made a little web service back in 2015 and somewhere in the following 7 years I forgot about it. I’ve been adding title-casing to various projects and plugins and keep writing new code for it… which was the whole reason I built the API to begin with.

It just accepts a text string and returns an AP titlecased version as plain text. That’s it. No bells or whistles, but if you need to incorporate title casing into a script or a Shortcut or anything else that can make a quick call to the web, it’s a great answer.

Just make a call to https://brettterpstra.com/titlecase/?title=the%20text%20to%20titlecase, where title= contains the url encoded string you want to title case. You can play with it on the test page, which will also show you the url to use to get the same result.

That’s all. It’s a silly little thing, but if I’ve forgotten about it, I bet everyone else did, too, and it might just be handy for someone.

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-13T14:32:00-05:00
Just checking in https://brett.trpstra.net/link/535/16068629/just-checking-in https://brett.trpstra.net/link/535/16068629/just-checking-in I haven’t been posting much besides sponsored posts and web excursions for a while now. I figured it was time for a checkin for the sake of those who check this blog regularly, and especially for the benefit of those who offer financial support to me and all my projects.

As you probably know, I have bipolar disorder. Most of my project releases and blogging spurts correlate with manic episodes. And manic episodes are bad for me — they result in a severe sleep deficit that is shortening my life. But I’ve been remarkably stable lately, the downside of which is no late night coding/creating binges or the inescapable bursting of ideas that I just have to share with the world. It means I do my job, I maintain and support my commercial software, I fix reported bugs in my free projects, and I go to bed. It doesn’t lead to a lot of fun software releases, blog posts, or new ideas in general. Sleep is good, stagnation kills me.

I’ve recently been realizing that my version of “stable” is more akin to depression. The thing is, I can’t take antidepressants without risking triggering a manic phase, which leaves me in a position where I either have to be depressed, or deal with the life-shortening effects of constant mood fluctuation. But I think I have a potential solution…


I removed the meat of this post because it was causing friction with my loved ones. I don’t want my activities to cause any undue harm, so I’ll save further sharing on this topic until everything is… decriminalized.


So that’s my check-in for now. You can hear more up-to-the-minute updates on my progress (as well as Jeff and Christina’s) by tuning into the Mental Health Corner on Overtired. I appreciate all of the support (monetary, pull requests, and even just kind emails) that you all have continued to provide for me. It really helps me stay motivated to maintain my 100+ projects and create new stuff!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-12T15:41:00-05:00
Keep your software up-to-date effortlessly with MacUpdater [Sponsor] https://brett.trpstra.net/link/535/16060213/keep-your-software-up-to-date-effortlessly-with-macupdater-sponsor https://brett.trpstra.net/link/535/16060213/keep-your-software-up-to-date-effortlessly-with-macupdater-sponsor Thanks to MacUpdater for sponsoring BrettTerpstra.com this week! I’m a dedicated user and swear by this app for keeping my system updated. The latest version just makes everything even easier.

MacUpdater scans and displays all installed software on your Mac — see at a glance which apps or plugins are out of date, and click to automatically update them!

  • MacUpdater provides version information for over 60,000 apps (and growing) and over 6,000 of the most popular apps can be updated directly from within MacUpdater with a single click
  • MacUpdater also now supports automatic, zero-click PKG installs
  • The Pro edition adds support for audio and media plugins
  • MacUpdater is flexible — you can control MacUpdater from the main app, the menubar, or the command line
  • It’s a universal build and fully compatible with Apple Silicon

What’s new in MacUpdater 3

  • Optional zero-click, fully-automatic, scheduled app updates (PRO)
  • Added Apple-silicon migration assistant to help move to new Macs
    • Find out which of your Rosetta-based apps could be ‘Apple Silicon’-native if you update or upgrade to the latest version
    • Find out which of your ‘Rosetta’ based apps could be Silicon-native if you reinstall them
  • Track supported branches other than the ‘Latest Version’
    • When an app vendor also supports an old branch of an app with further updates, users have the choice of either using the latest version or tracking the updates to the major version which they are using
    • You can see a list of apps that currently support this feature (more will be added based on user requests)
  • Select how apps should be updated (auto, custom updater, manual update)
  • Attach and display Finder-compatible tags and comments to your apps, and support custom homepages or updater apps via clickable comments

Save 15% on MacUpdater with code BRETTTERPSTRAQ1. Check it out today!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-06T08:00:00-05:00
Find which of your favorite apps are on Setapp, revisited https://brett.trpstra.net/link/535/16056931/find-which-of-your-favorite-apps-are-on-setapp-revisited https://brett.trpstra.net/link/535/16056931/find-which-of-your-favorite-apps-are-on-setapp-revisited Back in 2019 I wrote a little script that would parse your Applications folder and tell you which of your apps were available on Setapp. The goal was to help you figure out which apps you were already using that were also on Setapp, so you could use the Setapp version and direct a little of your subscription fee to your favorite developers.

The script parses the setapps/apps page to see what apps are available, and the markup has changed since I originally wrote the script. Thankfully, Chuck Plater updated the script in a fork to work with the current markup. I’ve implemented his changes in the original script and it’s once again working fine.

To use the script, save it to a text file called onsetapp.rb, then run chmod a+x onsetapp.rb on it. Once you’ve done that, you should be able to execute ./onsetapp.rb and get a list of applications you use that are also available on Setapp.

Thanks to Chuck for the fix. I hope all Setapp subscribers will go to the trouble of using the Setapp version of apps they already own, it really does help the developers (and this script makes it easy). If you’re not already a Setapp user, here’s my affiliate link to start using hundreds of apps for $10 a month.

onsetapp.rbraw
"
#!/usr/bin/env ruby
# encoding: utf-8

# Read /Applications/Setapp to get apps already installed
installed_setapp_apps = Dir.glob('/Applications/Setapp/*.app')
installed_setapp_apps.map! {|app|
  File.basename(app,'.app')
}

# Grab the All Apps page from Setapp to get all available apps
apps_page = `curl -SsL https://setapp.com/apps`
setapp_apps = apps_page.force_encoding('utf-8').scan(/<app-details\s*name=\"(.*?)\"/m).map {|match|
  match[0]
}

# Read /Applications for non-Setapp apps on the system
apps = Dir.glob('/Applications/*.app')
apps.map! {|app|
  basename = File.basename(app,'.app')
  # Setapp disallows version numbers in app names. Strip them from
  # /Application apps for consistency in matching
  basename.sub!(/\s*\d+$/,'')
  basename
}

setapp_apps.sort.uniq.each {|app|
  if apps.include?(app)
    # App is on Setapp
    out = "Setapp has: #{app}"
    if installed_setapp_apps.include?(app)
      # Setapp version is installed (or at least proxied)
      out += " (Installed)"
    end
    $stdout.puts out
  end
}

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-04-04T16:58:00-05:00
Curio 25 with Smart Collections [Sponsor] https://brett.trpstra.net/link/535/16026152/curio-25-with-smart-collections https://brett.trpstra.net/link/535/16026152/curio-25-with-smart-collections Thanks to Curio for sponsoring BrettTerpstra.com this week!

What if your digital notebook allowed you to create at-a-glance dashboards and checklists using queries to pull in and consolidate information from all across your project into lists, mind maps, or Kanban collections?

We call them Smart Collections and that’s what we’re introducing in Curio 25 Professional, the latest release of our flagship note-taking and brainstorming app for macOS.

Create a new list, mind map, or Kanban stack then specify a query expression. Immediately it will dynamically fill itself with matching figures from across your notebook. A query can be as simple as starts soon or #remind or as sophisticated as (@george priority>4) or due<2w or #active group:priority.

Even better, these dynamic collections contain live instances of the original figures. Edit an item’s text or change dates, tags, or other meta attributes, and those changes are instantly reflected back to the original figures.

In addition to Smart Collections, Curio 25’s Search shelf has been completely overhauled to support this powerful query language. And the query language itself, also used by Curio’s instant Quick Find feature, has been greatly extended with even more functionality to help you find exactly what you’re looking for.

Curio, first introduced almost 20 years ago, is the most advanced notebook application for note-taking, brainstorming, and research. It provides all the tools and functionality you need to be more productive and get stuff done.

New traditional license purchasers can save 20% using the code TERPSTRA. Visit zengobi.com to learn more today!

Like or share this post on Mastodon or .


BrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.

Twitter | Mastodon | GitHub | Privacy Policy

]]>
2023-03-16T08:00:00-05:00