Welcome to the lab.

Finally, new columns for iTextEditors

[Tweet : nvALT]

I posted an update on iTextEditors yesterday, and got a great response from people adding to and updating the list. This inspired me to finally add a couple of new criteria (that didn’t even exist when the original chart was created): Document Provider support and Split Screen support.

I had previously started to compile a list of apps supporting these features with the help of a few field testers, but the list of apps has changed significantly since then and I need some help with updating. If you look at the list, you’ll see most of the apps listed with a question mark in those columns. If you browse it and happen to know that an app does or does not support either feature, please let me know. And I’ll tell you what, you don’t even have to use the submission form in this case (though you’re still welcome to, and absolutely should if you’re submitting a new app). You can just let me know (via Twitter or the contact form) the name of the app and yes or no for one or both of those criteria.

Thanks for the help!

The dwindling number of iOS text editors

[Tweet : nvALT]

Over the weekend I weeded out the dead apps on my iTextEditors comparison chart and was surprised to find that over 30 of the 90 editors on the list were no longer available. I figured a few would be gone, but a third of them had gone the way of the dinosaur1.

Perhaps the cream has risen to the top and most people are settling on the leaders of the pack. Maybe there just isn’t that much money to go around in the iOS text editor market. I was definitely sad to see apps like Writing Kit and Trunk Notes call it quits, while some of the others I knew had morphed into different applications (e.g. Daedalus->Ulysses).

So I’d like to ask for the crowd to help me make sure iTextEditors is up to date with your current favorite apps. Check the chart, and if you don’t see yours (or any that you have on your mind at the time), please submit new forms for them. It will help keep this resource going even though Apple has ensured that I don’t personally make any money off it

Thanks in advance, and I’m looking forward to seeing what you’ve got!

P.S. please do use the submission form and don’t just name apps in the comments or on Twitter2. I don’t have the bandwidth to track down the details on every editor myself.

  1. Avoiding a Revelation 12:4 reference here…

  2. I already know this will be commonly disregarded/ignored, but I had to try.

Get better stats for your writing with Marked 2

[Tweet : nvALT]

I’ve put together a new screencast demonstrating some of the document statistics capabilities of Marked 2. In addition to being a great way to preview your Markdown documents as you work, Marked can go further to provide character and word counts, sentence and paragraph counts, various readability indexes, reading time, and even show progress toward your word target for the piece. Check it out!

YouTube Video

Be sure to check out some of the other Marked screencasts I’ve posted. Intrigued but not currently a user? Check out Marked 2 at marked2app.com!

The ultimate guide to DuckDuckGo

[Tweet : nvALT]

Disclosure: DuckDuckGo has sponsored this site in the past. This post is not paid for (or even authorized by) DuckDuckGo.

By now I’m sure you’ve heard of DuckDuckGo around the web (and I’ve been mentioning them for years). If you don’t already have the scoop, it’s the search engine that can serve as a complete replacement for Google (and Bing and whatever else you like), except it respects your privacy and security. And while Google does some cool tricks, DuckDuckGo does some even better ones.


Let’s start with the basics. To understand why you should be using a search engine like DuckDuckGo, read about the Filter Bubble and DuckDuckGo’s Privacy statement.

The biggest deal is that DuckDuckGo stops your searches from being aggregated and logged with personal identification information. This is a significant step in reducing the amount of profiling companies can do.

You can also add a proxy site, or even combine DuckDuckGo with Tor for ultimate privacy. DuckDuckGo operates its own Tor Exit Enclave.


DuckDuckGo has guides for adding the search engine to all of your browsers. Once you have it set as your default search engine, you’ll be able to use the URL bar in Chrome, Firefox, Safari, and others to search DuckDuckGo directly, just like you were with the (probably) default Google search engine.


There are a few settings you can change. These include theme and appearance settings and things like default safe search settings. You can also specify a region, which will then prioritize results from that region in your searches. Region search can be toggled on and off and even changed per search (see the dropdown at the top of any results page).

You can also disable ads. DuckDuckGo doesn’t monetize its users’ data, so it’s essentially ad-supported. But if you want to disable them, you can do so under Settings->General->Advertisements. Just be sure to support DDG by sharing it with friends.

Search Syntax

The search syntax is very similar to Google’s, so if you’re familiar with that you won’t need to learn much. Obviously you can just search a bunch of words, but there are a few additional syntaxes you can use to refine results.

First, you can exclude words from the results by adding a minus (-) before the word. This doesn’t ban the word, but de-prioritizes it in the search results. Conversely, you can use + to increase the priority of a word.

If you add a category at the end of a search, those results will show up first. These include “images,” “videos,” “news,” and others.

DuckDuckGo has an equivalent to the old “I’m Feeling Lucky” search on Google. DuckDuckGo calls theirs “I’m Feeling Ducky,” and you do it by simply adding a backslash (\) at the beginning of the search terms. You’ll automatically be redirected to the first search result.

You can specify a preferred format for results with filetype: or f: searches. Personally, I only use these for f:pdf searches, but I’m sure there are other types some might find useful.

Site-specific searches are handy, and the results are often better than using a given site’s internal search. Specify these with site:[domain] (or just s:[domain]) anywhere in your search terms. You can also get to site-specific searches by clicking the “More results” link on any search result in the list. If you want to include multiple sites, you can use “OR” with multiple site:domain queries, or separate multiple domains with commas (no spaces). You can also restrict results to a top level domain (region) by including a TLD, e.g. site:co.uk. Also note that you can use the - operator to exclude a certain site from the results.

Boolean searches always get more complex than is usually needed, but DuckDuckGo offers full support for AND/OR searches and parenthetical groupings. By default, all terms are combined with AND (use double quotes to search for an exact phrase). Using AND or OR only affects the words adjacent to the boolean, so markdown editor OR previewer searches for ((markdown)AND((editor)OR(previewer)). As you can see from that example, typing out the full boolean search version is far more cumbersome than just running the original search. In most cases an OR search that doesn’t make sense in plain text is probably easiest as two different searches. You can also combine phrases by using double quotes, e.g. "markdown previewer" OR "markdown editor".

You can prioritize results by where the terms appear using intitle: (in the page title), inbody: (in the text of the page), and inurl: (in the actual URL of the page).

You can add !safeon or !safeoff to a search to toggle Safe Search for that search only. You can also specify a region for a single search using region:[region code], or use region:none to disable region-prioritization for that search.

Keyboard Shortcuts

There are a few keyboard shortcuts that can make DuckDuckGo a pleasure to use. You’re typing your search anyway, why take your hands off the keyboard to navigate the results?

Use j and k or the up and down arrows to navigate through individual results. Once a result is highlighted, you can hit Return to open it (or o), or use Cmd/CTRL-Return to open it in the background. Using v will open it in a new tab instead. If you hit return right after a results page loads, it will automatically navigate to the top result’s link.

While a result is highlighted, you can also use d to perform a search for additional results from the same site (domain search).

You can navigate in the search page itself, too. Use left and right to switch between the tabs of search results (news, video, answer, etc.). Use m to focus the search results. Jump back to the search bar using /, and jump back to the top of the page with t.

You can also use s to accept the “did you mean” suggestion and correct misspellings with a single keystroke.

Bang Searches

Bang searches are searches that begin with an exclamation point (commonly referred to as “bang”) followed by an identifier. They act as shortcuts for redirecting a search to a specific site, allowing you to use DuckDuckGo to search everything from Amazon to YouTube to your favorite news site, using their own internal searches. These aren’t site-specific searches, almost all of them take you to the site’s search page and pass your search on to it (with the benefit of masking some of your private info in the process).

There are so many bang searches that they have their own search engine. If you search a site regularly, punch it in there and chances are there will be a shortcut you can use to search it right from your DuckDuckGo homepage (or your URL bar, if DDG is your default search engine). Heck, even my site has a bang search (!terp, which I’m embarrassingly flattered to find…) .

Some of my most common bang searches are !a for Amazon and !g for Google (with some privacy protection) when DDG just can’t find what I’m looking for (which is increasingly rare).

Some other favorites of mine:

  • Media
    • !img: DDG image search
    • !gimg: Google image search
    • !v: DDG video search
    • !yt: YouTube
    • !gv: Google video search
    • !hulu: Hulu
    • !nf: Netflix
    • !flickr: Flickr
      • !flickrcc: Flickr Creative Commons
    • !giphy: Giphy
  • News/Info
    • !imdb: IMDB
    • !wiki: wikipedia
    • !nyt: New York Times
    • !lifehacker or !lh: Lifehacker
    • !di Dictionary.com
    • !terp: brettterpstra.com
  • Google (almost all Google services are searchable)
    • !gcal: Google Calendar
    • !gdocs: Google Docs
    • !gfonts: Google Fonts
    • !tr: Google Translate
  • Other stuff
    • !ia: Internet Archive
    • !pib: Pirate Bay
    • !wu: Weather Underground

Instant Answers

Despite this being the last section of the post, Instant Answers are by far the coolest feature of DuckDuckGo. You can find a complete list of all the cool tricks available at the dev site, but I’ll highlight a few of my current favorites.

If a search yields recipes, the top search result will be a whole bar of links to recipe sites, complete with images.
You can input all kinds of math questions and get a calculator with the answer. Try basic math (3 * 45 + (12 - 4)) or use intuitive descriptions like 1251 minus 40% or 2 Dozen - 4.
You can also get a loan payment calculator with a search like loan 100000 at 5% with 20% down for 10 years
Code snippets
If you start a search off with a coding language, DDG will try to locate an answered StackOverflow question and provide the summary right in the search results. Sometimes this shows up as a sidebar. Try ruby for loop or jquery .Ajaxsuccess.
Even without a language specified, if the search matches a verified answer on StackOverflow, that answer is summarized at the top of the results.
Cheat sheets
End your search with “cheat sheet” to find myriad summaries of keyboard shortcuts and other tips. Try vim cheat sheet (be sure to click “Show more”)
Searching for calendar will give you a calendar for the current month. You can also add a date to see any month, i.e. calendar feb 2015.
Search for HTML characters
Use html chars to get a list of all HTML characters, or search for a specific character. Try html bullet. You can also get ASCII codes (Ascii Table).
The latest XKCD comic. It even has an “explain it” link that goes to explainxkcd.com.
Get an explanation of any emoji just by entering it in the search box. Most text emoticons will return a result from Wikipedia as well.
Social handles
Search for a Twitter handle (e.g. @ttscoff) and the top result will be the image and bio for that account.
Is it raining
Just try it.
Get the current outlook just by searching weather (if your location is available), or search a specific location with weather [location]. Yes, Google can do this too, but the point here is not using Google…
Generate a password or pass phrase
Generate a random password by searching password [X] where [X] is the number of characters to match. password 20 yields something like “LKA5u9ahTmQRi4zERwuR”.
You can also search for random passphrase to get a 4-word passphrase like “grass staleness yelling stopped”.
Shorten URLs
Just search shorten [url] to get back an is.gd shortened link. You can also expand shortened urls with expand [short url]. And if you want to go with a QR code, just search qr [url or text] to generate one on the fly.
Generate any length of random text with [x] [words|sentences|paragraphs] of lorem ipsum.
URL Encoding
For developers, you can handily url encode any text by searching url encode [text]. Related, you can convert UNIX timestamps with unix time 2147483647
Start a stopwatch just by searching stopwatch. You can start a countdown timer with a search like timer 5 minutes, and you can use the plus button next to the timer to add multiple timers.
Make text bigger with figlet [text]. The standard figlet fonts are available, and you can change the font by using figlet [fontname] text.

And that is your complete guide (or at least a starting point for further exploration) to my favorite search engine. While DuckDuckGo has a fraction of the ubiquity of Google, it’s gotten so good that, for me, David has made Goliath obsolete. Start searching at duckduckgo.com.

Amazon affiliates and automated contextual snippets in Jekyll

[Tweet : nvALT]

Whenever I link to an Amazon product on this blog, I use an affiliate link through the Amazon Affiliate program. They pay me a nominal amount for the referral and it doesn’t cost my users anything. I don’t always add a disclaimer for these links, but when I do I often mention that “clicking this link helps support the site.” It turns out — as pointed out to me by a reader (thanks Jean) — you’re not supposed to do that. But there is a standard disclosure provided by Amazon that I’ll be including on this site from now on.

Here’s the fun part of the post (and from here on out it’s specifically for Jekyll bloggers): my Jekyll site will now automatically add the aforementioned disclaimer any time I use an Amazon affiliate link. This just takes a few steps, which I’ll cover briefly. If you want to implement something like this on a Jekyll site and run into any issues with my explanation, I’d be happy to offer more guidance if you want to contact me1. I imagine it would be easy enough on other sites, and I’ve created WordPress plugins that do similar as well.

I want the disclosure paragraph to automatically be included whenever I use an Amazon affiliate link, but not on posts where I don’t. The first thing I did was add a Liquid filter that can simply return true if any form of an affiliate link url is found in the post content. I added this to my own set of filters, but you can set up a new file in /plugins/ if you need to:

module MyLiquidFilters
  # Checks if the post contains amazon affiliate links
  def has_amazon(input)
    input =~ /(https:\/\/amzn.to|tag=brettterpstra-20|amazon.com\/shop\/ttscoff)/i ? true : false

  Liquid::Template.register_filter self

This matches shortened links (amzn.to), links with my affiliate tag in the query parameters (tag=), and my storefront (/shop/). You’ll note two of the patterns in the regular expression are for things specific to me: brettterpstra-20 is my own affiliate tag, and /shop/ttscoff is my storefront. (And hey, because I just linked it, the disclosure will now show up on this post. Neat.) You’ll need to change those to your own tag and storefront, optionally removing the storefront match entirely if you don’t have one.

Add an Include Template

You could put the markup right into your article template, but I like to use includes because I actually use a bunch of different versions of this (I’ll show a few examples at the end). In _includes/amazon_affiliate.html, I have this (again, you’ll want to edit slightly to fit your own site):

<p class="disclosure">BrettTerpstra.com is a participant in the
Amazon Services LLC Associates Program, an affiliate advertising
program designed to provide a means to earn fees when linking to
Amazon.com and affiliated sites.</p>

Just for reference, I use the following in my site styles. Obviously, personal taste.

p.disclosure {
  font-size: .75em;
  background: #efefef;
  padding: 1em;
  font-style: italic;
  border: dotted 3px #ccc;
  border-radius: 10px;

Adding to the Template

To put this all to use, I use the Liquid filter to conditionally include the HTML in my article.html template:

{% capture amazon %}{{ content | has_amazon }}{% endcapture %}
{% if amazon == 'true' %}{% include custom/amazon_affiliate.html %}{% endif %}

It passes the content of the post through the has_amazon filter I defined at the beginning and captures the result to a variable. If the post content contains a match for any part of the regex, “amazon” gets set to true. Then I can just use a Liquid conditional to include the affiliate disclosure HTML in the article body.

There’s likely a more succinct way to do this in Liquid, i.e. skipping the capture step, but that’s what I got to work…

Other Examples

I do similar things with various other conditions. Most of them use post tags or classes from my YAML headers to trigger other includes. For example:

  • Web Excursions get a snippet at the top automatically when the YAML includes post_class: bookmarks:

      {% if page.post_class == 'bookmarks' %}
      {% include custom/excursions.html %}
      {% endif %}

    You can see this in action on any Web Excursions post. post_class is meta that I use to apply the icons to right of each title on the index pages.

  • Tips from my Bash Fun series (series: Bash Fun in the YAML) get a snippet at the end pointing to Ryan Irelan’s video series:

      {% if page.series == 'Bash Fun' %}
      {% include custom/shelltricks.html %}
      {% endif %}

    You can see this on any post in that series. I have a whole custom Jekyll setup for doing post series that I might share that at some point. You’ll also note that the blog automatically includes other posts from the current post’s series at the end as part of that plugin.

  • Similarly, posts with a ‘podcasting’ tag get a link to Aaron Dowd’s podcasting course:

      {% if page.tags contains 'podcasting' %}
      {% include custom/successful-podcasting.html %}
      {% endif %}

    See that happen on the last post where I actually talked about podcasting

Between my custom meta, tags, and content filters, I can have my blog automatically take care of remembering to mention (or disclaim) certain things any time the context is appropriate. It’s worth a bit of extra hacking for the time saved by not having to keep a checklist for each post.

  1. Oh, and I fixed the contact form, in case you’re one of the many people who DM’d me elsewhere because it wasn’t working…

BrettTerpstra.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means to earn fees when linking to Amazon.com and affiliated sites.

Your security and privacy: next steps

[Tweet : nvALT]

As I mentioned previously, I’m working to make this site as respectful of privacy as it can possibly be. To that end, it was pointed out to me by a reader (thanks @maclm) that the comment system I’ve been using, Disqus, is actually pretty bad for privacy and tracking. Hilton Lipschitz wrote about this back in 2018, and I’m just slow to catch up, apparently. Since most people reply to me on Twitter anyway, I don’t have such lively discussions on the blog that I’m willing to make a tradeoff on this.

After a little searching, I found RemarkBox, a comment system that doesn’t track you or store private information not necessary to its functionality. It was built by a solo developer as an alternative to Disqus. I’ll be testing it out for a while. One feature of RemarkBox is that you can comment without logging in. You’ll get an email, and if you verify it by clicking the link, you can change your display name and link your comments in the future. It will store your username and email, and your IP address for abuse prevention, but privately and will never sell your info to a third party.

I’m also removing Carbon ads from the site. There’s not a high enough click-through rate to justify the audience data collection they’re doing. I’ll rely only on sponsors and reader support to keep this site running. And some affiliate links, sans data collection, which I’ll be writing more about shortly.

So no Google, no Facebook, no private data collection by Disqus or advertising services. I feel better, how about you? You can help me test out the new comment system by telling me what you think of it down below… :)1.

  1. I try to never use emoticons on my blog—they always feel like a cheap way to do something I could more effectively do in prose—but this time it just seemed appropriate. I do feel dirty, though.

Marked 2.5.31

[Tweet : nvALT]

Marked 2.5.31 is available via automatic update, the Mac App Store, and Setapp. It’s all fixes this time around, but I took care of a bunch of little bugs.

If you happened to grab the automatic update for the direct version during a brief window where I put out an accidentally-sandboxed version (symptoms include being asked to register again, custom processor permission errors, and a loss of preferences), please download from the website and overwrite the app in your Applications folder. Everything will be fine moving forward!

Marked 2.5.31


  • Header text without footer text causes lines to split across pages in paginated pdf export
  • Invisibles (section headers, synopses, comments) in Fountain script changing pagination behavior
  • More GitHub styling issues (paragraph padding, table cell padding)
  • More Dark Mode compatibility issues
  • Close button on detailed statistics sheet disappears in Dark Mode
  • RTL detection JavaScript in HTML export when RTL detection disabled
  • FontAwesome included in HTML export when not using Leanpub interpreter
  • Syntax Highlighting JavaScript included when highlighting is deselected in export options

Grab the Marked 2 update via your channel of choice and enjoy the smoother sailing!

Web Excursions for February 26, 2019

[Tweet : nvALT]

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

iPad Diaries: Using a Mac from iOS, Part 1 - Finder Folders, Siri Shortcuts, and App Windows with Keyboard Maestro
A lot of great tips and tricks from Federico Viticci on creating a tight workflow between Mac and iOS. Of special note to me is the bit about FileExplorer, which I’ve come to love since discovering it in this article.
As a side note, Dr. Drang has a small gripe with FileExplorer vs. FileBrowser.
Matomo: #1 Secure Open Web Analytics Platform
I recently wrote about security and privacy changes on this site, and talked about needing a replacement for Google Analytics on Marked2App.com. Alex pointed out Matomo in the comments and it’s exactly what I needed.
Security Checklist
Pointed out to me by Adam Wood, this is a complete (yet approachable) checklist for staying safe on the internet, as a continuation of the privacy themes I’ve been bringing up lately.
Laziness Does Not Exist
I wish I’d had more teachers who understood mental health the way Devon Price does. As someone who suffers from ADHD and BPD, I often feel “lazy” and consider my procrastination a moral failing. That needs to stop.
Brett’s Top Picks on Amazon
If you’re looking for gifts or just want to splurge on yourself, I’ve compiled an Amazon storefront filled with 70 Top Picks from Systematic (returning from hiatus shortly, if you were wondering…).

CleanMyMac X

BrettTerpstra.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means to earn fees when linking to Amazon.com and affiliated sites.

Your security and privacy

[Tweet : nvALT]

I’ve made a few changes to my sites to be more in line with my own thoughts on privacy and security. When I’m using the internet, I use ad blockers, a VPN, and secure DNS on all of my devices, yet I’ve still been running websites that collect unnecessary data for Google and which don’t provide standard encryption. That’s changed, and more changes are coming.

Long Live Encryption

It took me too long, but I finally have both BrettTerpstra.com and Marked2App.com switched over to SSL, and both now force https:// access. I definitely considered it a priority on Marked’s site because that one initiates commercial transactions.

I’ll admit that the final incentive to switch both sites over was the recent push among web browsers to call out insecure sites in the url bar, which is embarrassing enough to prompt real action. Good on you, browsers. While all credit card transactions on Marked2App.com have always taken place through Paddle’s secure server, it still promotes significantly more confidence to have the origin not show Not Secure in the url bar.

Even after the advent of Let’s Encrypt, which offers free SSL certificates for everyone, I had issues implementing SSL with my current MAMP setup on a macOS system. I ended up switching both sites over to a shared host that had Let’s Encrypt built in and made it a much easier process to add the certificates. Then a simple .htaccess rule forces every request to switch to https. Most of the headache at that point was just revising all of my deploy setups; setting up private key SSH, git and git hooks, and various back end scripts that needed fixing.

Side note, I’ve also added TOS and Privacy statements to Marked2App.com. Thanks to George Browning from Zengobi for assistance with that.

I’ve dealt with most of the issues for users caused by the changes in the server environment and the URL itself. Nothing major, but if you notice anything broken here or on marked2app.com, please let me know.

I’d love to get Marky switched over to SSL soon, but I have to figure out how to do it and maintain the delicate combination of python, ruby, node, and PHP scripts that it relies on, which makes switching to a shared server environment a pain. The only reason I’ve been able to run it thus far is that I have full control over the server and can deal with security issues myself. I’ll get it there, and it’ll be nice to avoid all of the insecure request issues that pop up when using the Marky API and bookmarklets on secure pages. (For those interested, I think I may end up rewriting the whole thing in Node and running a Passenger instance.)

Death to Big Data

I’ve mentioned the switch in my analytics before, but I’ll include it in this post as well: I’ve ditched Google Analytics on BrettTerpstra.com and switched entirely to Fathom. I’m no longer collecting demographic information (not even location), user behavior, and other privacy-invading statistics, and I’m not helping Google collect info on my readers. I haven’t made the same switch on Marked2App.com because the information provided by Google Analytics is vital enough in a commercial sense that I need to find a more capable but less invasive replacement for Google there. If you have any great recommendations that can handle custom tracking events, A/B testing, and provide extensive reporting while not tracking or reporting to Big Data, please share!

I’ve never included buttons from Facebook or Twitter and never plan to. The only data collection left on this site is an audience tracker from Carbon, the small ad that displays in the sidebar. Ad blockers have made that ad pay less and less, so whether I continue allowing that is debatable at this point. If you want to help me make that decision, support me directly by pitching in a bit.

A Small Step

I’m fully aware that my changes here make almost no difference in the grand scheme of things, but now my sites are operated closer to the way I’d prefer every site operated. For the rest of the web, I recommend a VPN (currently quite happy with NordVPN), secure DNS (I use CloudFlare, OpenDNS, and EasyDNS), and a good blocker for trackers and ads like Ghostery or a secure browser like Brave.

We’ll talk about Facebook once I’ve finally deleted my account and can speak without hypocrisy. In the meantime, if you have any more suggestions for things I could be doing better in the areas of security and privacy, please feel free to let me know, either via Twitter or contact me directly. Thanks for being a reader!