{"id":10177,"date":"2014-09-30T23:37:44","date_gmt":"2014-09-30T23:37:44","guid":{"rendered":"https:\/\/www.bartbusschots.ie\/s\/?p=10177"},"modified":"2014-09-30T23:39:51","modified_gmt":"2014-09-30T23:39:51","slug":"os-x-service-for-markdown-link-creation","status":"publish","type":"post","link":"https:\/\/www.bartbusschots.ie\/s\/2014\/09\/30\/os-x-service-for-markdown-link-creation\/","title":{"rendered":"OS X Service for Markdown Link Creation"},"content":{"rendered":"<p>At the request of listeners I&#8217;m going to be publishing a big list of links with future <a href=\"http:\/\/lets-talk.ie\/apple\" title=\"Let's Talk Apple Podcast\" target=\"_blank\">Let&#8217;s Talk Apple<\/a> shows. The logical format for me to create those notes in is <a href=\"http:\/\/daringfireball.net\/projects\/markdown\/\" title=\"Markdown Homepage\" target=\"_blank\">Markdown<\/a> &#8211; it&#8217;s plain text, and quick and easy for me to add new items and re-arrange them into logical groupings. for the most part markdown has little to no overhead, but when it comes to links there is a little work. What I wanted was a way of automatically taking a URL, and turning it into a markdown link where the text for the link is the site the story is from with \/&#8230; after it.<\/p>\n<p>When all is done I want to turn a url like <code>http:\/\/www.macobserver.com\/tmo\/article\/every-important-link-from-apples-9-9-event-on-one-page<\/code> into a link that looks like: <a href=\"http:\/\/www.macobserver.com\/tmo\/article\/every-important-link-from-apples-9-9-event-on-one-page\" target=\"_blank\">www.macobserver.com\/&#8230;<\/a>. In other words, I need to take the URL above as input, and turn it into the following Markdown code:<\/p>\n<pre>\r\n[www.macobserver.com\/...](http:\/\/www.macobserver.com\/tmo\/article\/every-important-link-from-apples-9-9-event-on-one-page)\r\n<\/pre>\n<p>My reason for choosing this format is that I want to give obvious credit to the sources of the stories, but not waste screen real-estate on long URLs.<\/p>\n<p>Perl&#8217;s <a href=\"http:\/\/search.cpan.org\/perldoc?URI\" title=\"Perl URI Module\" target=\"_blank\">URI module<\/a> can interpret URLs, and easily extract the host part of the URL, OS X Services can take selected text as input and replace it with processed output, Automator can create OS X Services, and Automator can execute Perl code. By putting all these pieces together I was able to solve my problem in just 20 minutes with a few clicks and a few lines of code.<\/p>\n<p>You can just download the service with the link below, or you can read on to see how it&#8217;s done.<\/p>\n<h3 style=\"text-align:center\"><a href=\"https:\/\/www.bartbusschots.ie\/downloads\/OSXServices\/md%20-%20linkify%20URL.zip\" title=\"Download OS X Service\">Download OS X Service &#8230;<\/a><\/h3>\n<p><!--more--><\/p>\n<p>The first step is to open Automator, create a new Service. At the top of the workflow configure the service so it receives selected text in any app, and replaces the existing text:<\/p>\n<p style=\"text-align:center\"><img decoding=\"async\" src=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.10.48.png\" alt=\"Automator Text Service\" width=\"480\" class=\"alignnone size-full wp-image-10178\" srcset=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.10.48.png 510w, https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.10.48-300x31.png 300w\" sizes=\"(max-width: 510px) 100vw, 510px\" \/><\/p>\n<p>Next drag and drop in a <em>Run Shell Script<\/em> action and confiture it to use Perl and take input as arguments:<\/p>\n<p style=\"text-align:center\"><img decoding=\"async\" src=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.13.13.png\" alt=\"Automator Shell Script Action\" width=\"480\" class=\"alignnone size-full wp-image-10179\" srcset=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.13.13.png 544w, https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.13.13-300x175.png 300w\" sizes=\"(max-width: 544px) 100vw, 544px\" \/><\/p>\n<p>Finally, just add in the code to do the work:<\/p>\n<pre class=\"brush: perl; title: ; notranslate\" title=\"\">\r\nuse strict;\r\nuse warnings;\r\nuse URI;\r\n\r\n# loop through the passed args (expecting to get just one)\r\nARG:\r\nforeach my $arg (@ARGV) {\r\n\t# create a URI object form the received text\r\n\tmy $url = URI-&gt;new($arg);\r\n\r\n\t# if we didn&#039;t get a valid URL, just print back what we got in and call it a day\r\n\tunless($url-&gt;scheme() =~ m\/^https?$\/sx){\r\n\t\tprint $arg;\r\n\t\tnext ARG;\r\n\t}\r\n\r\n\t# assemble and print the markdown link\r\n\tprint q{&#x5B;}.$url-&gt;host().q{\/...](}.$url-&gt;canonical().q{)};\r\n}\r\n<\/pre>\n<p>What this code does it take the input, try parse it as a URL (using Perl&#8217;s URI module), if it&#8217;s not a URL, just return it exactly as it came in (so our service doesn&#8217;t gobble up text when used on a non-URL). If the URL is valid, print the Markdown code for the URL in the desired format.<\/p>\n<p>Once the code is in, save the service with a name of your choice (I went with <code>md - linkify URL<\/code>), and then just select some text in an app, and invoke it either by right-clicking the selecting the service, or access it via the Services menu in the app:<\/p>\n<p style=\"text-align:center\"><a href=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.21.25.png\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.21.25.png\" alt=\"Using OS X Service\" width=\"480\" class=\"alignnone size-full wp-image-10180\" srcset=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.21.25.png 914w, https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.21.25-300x160.png 300w\" sizes=\"(max-width: 914px) 100vw, 914px\" \/><\/a><\/p>\n<p>You can also add a keyboard shortcut for your new service by going to the <em>Shortcuts<\/em> tab in the <em>Keyboard<\/em> system preference pane:<\/p>\n<p style=\"text-align:center\"><a href=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.24.29.png\"><img decoding=\"async\" src=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.24.29.png\" alt=\"Setting Keyboard Shortcut\" width=\"480\" class=\"alignnone size-full wp-image-10181\" style=\"border:0px;\" srcset=\"https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.24.29.png 782w, https:\/\/www.bartbusschots.ie\/s\/wp-content\/uploads\/2014\/09\/Screen-Shot-2014-10-01-at-00.24.29-300x273.png 300w\" sizes=\"(max-width: 782px) 100vw, 782px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At the request of listeners I&#8217;m going to be publishing a big list of links with future Let&#8217;s Talk Apple shows. The logical format for me to create those notes in is Markdown &#8211; it&#8217;s plain text, and quick and easy for me to add new items and re-arrange them into logical groupings. for the [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[12,16],"tags":[269,531,26,267,456,457],"series":[],"class_list":["post-10177","post","type-post","status-publish","format-standard","hentry","category-computers-tech","category-programming","tag-automator","tag-markdown","tag-os-x","tag-perl","tag-services","tag-software-release"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7t9xK-2E9","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/10177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/comments?post=10177"}],"version-history":[{"count":5,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/10177\/revisions"}],"predecessor-version":[{"id":10186,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/10177\/revisions\/10186"}],"wp:attachment":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/media?parent=10177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/categories?post=10177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/tags?post=10177"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/series?post=10177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}