{"id":196,"date":"2014-05-30T19:17:22","date_gmt":"2014-05-30T23:17:22","guid":{"rendered":"http:\/\/julianvidal.com\/blog\/?p=196"},"modified":"2014-05-30T19:17:22","modified_gmt":"2014-05-30T23:17:22","slug":"how-to-create-custom-textwrangler-filters-with-php","status":"publish","type":"post","link":"https:\/\/julianvidal.com\/blog\/how-to-create-custom-textwrangler-filters-with-php\/","title":{"rendered":"How to create custom TextWrangler filters with PHP"},"content":{"rendered":"<p>I&#8217;ve been using TextWrangler \u00a0for years because it&#8217;s fast, it has all I need and best of all it&#8217;s free. Even though I don&#8217;t use it as an IDE, many times I wish it had a few features such as\u00a0auto-formatting JSON strings. Fortunately, it is very easy to write custom text filters and use them from within TextWrangler. I will show you how to write a &#8220;Pretty JSON&#8221; filter which takes any valid JSON string and formats it so that it is easier for humans to read while still remaining valid JSON. I will be using php\u00a0to achieve this.<\/p>\n<p>First we need to write the script. It needs to be able to run as a shell script so you will need to include a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Shebang_(Unix)\" target=\"_blank\">shebang<\/a>\u00a0pointing to your php executable. To find your php executable, open a Terminal window and type:<\/p>\n<pre class=\"lang:sh decode:true\">$which php<\/pre>\n<p>The <em>which<\/em> command tells you the full path to a\u00a0program on your path. The output should look something similar to this:<\/p>\n<pre class=\"crayon-selected\">\/usr\/bin\/php<\/pre>\n<p>In this case, my php path is \/usr\/bin\/php. We will be using that for our shebang.<\/p>\n<p>Then you need to make a php program that can take input from stdin and output to stdout. Here&#8217;s the full php\u00a0script we will be using:<\/p>\n<pre class=\"lang:php decode:true\">#!\/usr\/bin\/php \r\n&lt;?php\r\n\r\n$data = file_get_contents('php:\/\/stdin');\r\n\r\n$json = json_decode($data);\r\n\r\nif ($json == null) {\r\n    \/\/ Problem decoding json\r\n    return $data;\r\n}\r\n\r\necho json_encode($json, JSON_PRETTY_PRINT);<\/pre>\n<p>Basically we capture whatever came from stdin into $data and then decode it into $json. Since the input could be invalid JSON\u00a0we want to return it untouched in case of error. This is important because if our php program produces any errors, you will then see it in TextWrangler when you use your filter and lose the original data. If\u00a0we return the original data in case of error,\u00a0our filter will appear to do nothing which is much better than losing the original data.<\/p>\n<p>Lastly, we return the newly encoded string except that we used\u00a0JSON_PRETTY_PRINT so that php will add extra whitespace to our string.<\/p>\n<p>Save this\u00a0script\u00a0somewhere and copy (or create a symlink like I did) to TextWrangler&#8217;s filters\u00a0dir. This is located here:<\/p>\n<pre class=\"p1\">~\/Library\/Application Support\/TextWrangler\/Text Filters<\/pre>\n<p>Note that the name of the file minus the extension will become the name of the text filter inside TextWrangler so you should give it something meaningful.<\/p>\n<p>Now open up TextWrangler (I believe you need to restart it if you already had it open). Under the menu &#8220;Text&#8221;, the very first option should be a drop-down menu called &#8220;Apply Text Filters&#8221; and in there should be your filter. Let&#8217;s give it a try. Type this into a blank document:<\/p>\n<pre>{\"testing\":123,\"hello\":\"world\"}<\/pre>\n<p>After you run your new filter your text should look like this:<\/p>\n<pre>{\r\n \"testing\": 123,\r\n \"hello\": \"world\"\r\n}<\/pre>\n<p>Note that the filter could be written in any language, and you can even use already available utilities like aws, sed, etc, to automate everyday tasks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been using TextWrangler \u00a0for years because it&#8217;s fast, it has all I need and best of all it&#8217;s free. Even though I don&#8217;t use it as an IDE, many times I wish it had a few features such as\u00a0auto-formatting JSON strings. Fortunately, it is very easy to write custom text filters and use them [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":198,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_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":""},"categories":[18,2],"tags":[34,35],"class_list":["post-196","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-programming","tag-php","tag-textwrangler"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/julianvidal.com\/blog\/wp-content\/uploads\/textwrangler_text_filters.jpg?fit=450%2C300&quality=89&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/palO2H-3a","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/posts\/196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/comments?post=196"}],"version-history":[{"count":4,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/posts\/196\/revisions"}],"predecessor-version":[{"id":201,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/posts\/196\/revisions\/201"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/media\/198"}],"wp:attachment":[{"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/media?parent=196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/categories?post=196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/julianvidal.com\/blog\/wp-json\/wp\/v2\/tags?post=196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}