May 29, 2021 at 12:17 PM by Dr. Drang
… I personally much prefer the reference style… the reference style is just so much more readable.
And in the inline corner, Jason Snell:
But when I’m writing, pasting in URLs as I’m typing not only matches the way it’s done in HTML, it also allows me to keep my writing flow as much as possible. I type the text, I paste the link, and I keep writing. Naming a link, moving down, adding a link line, and then returning up to where I was—it breaks the flow.
Both are correct. Reference links are more readable1, but they take more time to write—at least if you’re writing in a dumb editor. When I make a Markdown link in an online forum, like the Automators forum, I always use inline links because I’m writing in an HTML text field, which is the dumbest of text editors.
But when I’m writing a blog post, I’m doing it in BBEdit, which has an AppleScript dictionary that can handle all of the cursor movement and pasting that Jason (rightly) dislikes. I don’t waste time or lose my train of thought in a lot of mousing around.
In the typical case, the web page I want to link to is the front page in Safari. To link some text to that page, I select the anchor text
and then type ⌃L to run myscript. It gets the URL of the front page in Safari, adds it to the bottom of the document with an incremented reference number, and surrounds the anchor text with brackets and the reference. The cursor is placed after the reference.
If there’s no text selected,does pretty much the same thing, but the anchor text is empty and the cursor is placed between the brackets for me to type it in.
Two scripts do the work. The first is a Python script called
nextreflink, which reads its input and returns the number of the next reference link. In the example above, because 5 was the last reference link number when the script was called,
nextreflink returned 6. Here’s the source code:
python: 1: #!/usr/bin/python 2: 3: import sys 4: import re 5: 6: text = sys.stdin.read() 7: reflinks = re.findall(r'^\[(\d+)\]: ', text, re.MULTILINE) 8: if len(reflinks) == 0: 9: print 1 10: else: 11: print max(int(x) for x in reflinks) + 1
You can tell I’ve been using this for a while because it’s written in Python 2.
There’s not much to this script. It scans the text it’s given, finds all the bracketed numbers followed by a colon and a space, determines the maximum of those numbers, and prints out one more than that number. If there are no reference links in the text, it prints 1.
nextreflink script is used by the AppleScript, which I have bound to the ⌃L key combination. It does all the tedious cursor movement and text insertion.
applescript: 1: -- Get the path to the Resources directory in the package. 2: tell application "Finder" to set cPath to container of container of (path to me) as text 3: set rPath to (quoted form of POSIX path of cPath) & "../Resources/" 4: 5: tell application "System Events" 6: set pNames to name of every process 7: if "Safari" is in pNames then 8: try 9: tell application "Safari" to set myURL to the URL of the front document 10: on error 11: do shell script "afplay /System/Library/Sounds/Funk.aiff" 12: return 13: end try 14: else 15: do shell script "afplay /System/Library/Sounds/Funk.aiff" 16: return 17: end if 18: end tell 19: 20: tell application "BBEdit" 21: set hereDoc to linefeed & contents of front document & linefeed & "XXXXXXXXXX" 22: set myRef to do shell script rPath & "nextreflink <<XXXXXXXXXX" & hereDoc 23: 24: if length of selection is 0 then 25: -- Add link with empty text and set the cursor between the brackets. 26: set curPt to characterOffset of selection 27: select insertion point before character curPt of front document 28: set selection to "[" & myRef & "]" 29: select insertion point after character curPt of front document 30: 31: else 32: -- Turn selected text into link and put cursor after the reference. 33: add prefix and suffix of selection prefix "[" suffix "]" & "[" & myRef & "]" 34: select insertion point after last character of selection 35: end if 36: 37: -- Add the reference at the bottom of the document and reset cursor. 38: set savePt to selection 39: select insertion point after last character of front document 40: set selection to "[" & myRef & "]: " & myURL & return 41: select savePt 42: activate 43: end tell
Lines 2–3 are a little tricky. I have both of these scripts saved in a BBEdit package (which is basically just a directory), and these two lines figure out the subdirectory where
nextreflink is saved and put that path into the
rPath gets used later when we call
nextreflink. If you want to use this system, you’ll have to figure out your own way to set
The next chunk of code gets the URL of the front page in Safari. That’s Line 9. The rest of it is just error handling code. A warning sounds if Safari isn’t running or if it’s running but has no open window.
The rest of the code does all the cursor movement and text insertion. First, Lines 21–22 send the text of the current BBEdit document to
nextreflink and save the number returned into the
myRef variable.2 If there’s no text selected in the document, Lines 26–29 insert a blank pair of brackets followed by the reference number in brackets at the cursor location. If there is text selected, Lines 33–34 surround it with brackets and put the bracketed reference number after it. Lines 39–40 add the reference number and URL to the bottom of the document, and Line 41 moves the cursor back up to where we were writing.
I’ve had similar systems set up for adding reference links in every editor I’ve used for writing blog posts. If an editor isn’t programmable enough to do this, I won’t use it for blogging.
There is another option for getting the ease of writing with inline links while ending up with the readability of reference links: Brett Terpstra’s Markdown Service Tools include a script that converts inline links to reference links. I don’t use Brett’s tools because I’ve built up my own over the years, but they get good reviews from those who do.
One last thing: Jason refers to inline links as the “lazy” style. I think my way of making reference links is just as lazy.
Jason argues that inline links are easier to edit because the URL is right next to the anchor. I would argue that link-checking in the raw Markdown source is holding it wrong. It’s much easier to check links by clicking them after the Markdown has been processed and opened in a web browser. ↩