OMG Markdown

Again, twitter erupted into its own little controversy. This time, @codinghorror got together with a bunch of smart fellas and tried to tame Markdown. This has sparked a lot of flame throwing with arguments ranging from hijacking what is, supposedly, John Gruber’s project to claiming that someone on the internet is a dick (you guessed that one!).

I sympathize that Markdown is something Gruber conceived and it has been a hell of a contribution to the community. I cannot think of writing today any other way. In fact, Markdown’s percolation has been astounding. It has been adopted as the de-facto input format across Github, StackOverflow, etc. and has a wonderful app ecosystem around it. However, it is a mistake to think that this happened because MD is so loosely defined.

I believe, MD has proliferated this far, not because it is an ambiguous, open to interpretation spec but in-spite of that. Just look at RSS or CSV. Every RSS-reader developer has some very quality things (NOT) to say about the standard. It’s a loose cannon and a pain in the butt to deal with. CSV? The simple, nice “standard”? Just try writing a parser for it!

Writing CSV code that works with files out there in the real world is a difficult task. The rabbit hole goes deep. Ruby CSV library is 2321 lines.

Markdown is getting there.

There are a lot of MD flavors. This is good. Most of these flavors implement core features differently. This is bad. As Markdown attains more and more popularity, the situation is just going to get worse. Remember the days when IE could not be bothered to care about standards compliant CSS implementations? This makes it hard for developers of services to roll out a simple MD parser to suit their needs. Instead, they need to go hunting for edge cases and account for all the different ways people can write the syntax. Makes it even more difficult to write apps which talk to each other. So, I do not concur with the argument that Markdown can succeed thru neglect. Proof? What people actually write in apps is some strict superset of MD which is defined by the developer. MD, as is used in practice, is not loose, not unsupervised. Problem is, there are too many cooks!

What I like about this effort to cast MD into a standard is that it will remove ambiguity from core features. This does not, in any way, strip anyone’s ability to extend MD. Implement the standard core and then expand on it to better suit your and your users’ needs. Most of the time, you won’t need to.

Back to the issue of name!

This is not a cogent argument. Overcast, for one, is not open source. It does not lend itself to forking. Markdown, on the other hand, is. However, Standard Markdown does violate MD’s BSD license:

Neither the name “Markdown” nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

So does MultiMarkdown. So does Github Flavored Markdown.
These are the two most popular implementations of MD and they use the word “Markdown” without reservation. Why the backlash now? Because, as opposed to those two, this one supposedly takes control away from John Gruber.

Control that he never exercised. “Markdown” has not changed in the slightest since Dec 2004. Any other spec out there that is as widely used and as stagnant? Do we have the audacity to claim that v1.0.1 was perfect in every way imaginable? Then why do we have so many extensions, forks, and flavors1?

John Gruber:

I’ve set up a public mailing list for discussion about Markdown. Any topic related to Markdown — both its formatting syntax and its software — is fair game for discussion. Anyone who is interested is welcome to join.

It’s my hope that the mailing list will lead to good ideas for future improvements to Markdown.

On the other end, on the Systematic episode from June 25th 2013, at 37:40 mark, Gruber attests:

I used to participate on that mailing list, but I don’t anymore. Cuz I kinda feel like it’s (MD is) is effectively done.

You should listen to it from that point on. Doesn’t take a lot to realize that MD needs some sort of stewardship and Gruber, respectfully, doesn’t feel the need to. However, I do not condone violating his license and if name is the point of contention, change away. Call it whatever. At this point, it’s becoming pedantic.

However, objections to the idea of standardization are ill-informed and superstitious. It’s a failure to understand what made MD a success. It’s the fear that Gruber alludes to in that Systematic episode at around 38:00:

What’s his name, Jeff Atwood, coding horror guy, every two years writes down something about how terrible I am at leading Markdown. [...]
In the mean time, Markdown pages on Daring Fireball get twice the page views they ever got before. And there are more and more systems everyday that come out with Markdown. And part of that is because actually I don’t screw it up.
(emphasis mine)

Fear of screwing up something that you do not know the cause of success of is not a healthy way to go about doing anything!


  1. Again, I am not against extensions. They serve a purpose. They make MD versatile enough for widespread use. But the existence of one particular flavor, MultiMarkdown, MMD, and its popularity speaks to the need for an actively revised spec that conforms to how people are using MD. 

Typos

I have always wondered why I am not so efficeint at reading materials on “the web” relative to my skill level in comprehending print or textbooks (digital or otherwise). I think I have a very substantiated hypothesis at this point: typos1. I cannot pretend to be very thorough with things I write, far from it. However, typos have a measurable and disturbing effect on my comprehension while reading a piece of text.

For instance, while reading this:

You’ve already been stuck with this problem for the last 7 hours! You finally you give up and get back to your desk few hours later (after some sleep or a walk with your dog). Voi a la! You found the problem by doing nothing. Actually your mind found the problem!

You finally you give up… gave me an instant pause and I had to go back and reread the sentence before it. While doing that, I slightly lost the gist of what I was thinking from the last few paragraphs. While the brain has great discernment when it comes to identifying words spelled wrong, mine gets startled at grammatical mistakes. I immediately loose my train of thought.

This happens all to often, more so now than before. Up until 2010, most of what I read was either textbooks or newspapers (yes!). They are very thoroughly edited and seldom carry glaring errors of this kind. On the other hand, writing on the web is very sporadic and it shows. I love how open the web is and how anyone with something valuable to say (or not!) can do so, without a lot of hassle. However, apparently my brain still expects rigor and freaks out, ever so little, every single time it encounters an anomaly.

I hate it when that happens.


  1. Typos, here, mean spelling and grammatical errors. 

Material Design, my ¢2

Google’s design guidelines are very good, not in a light way either. Most designers I spoke to today seem very impressed and by just looking at Google’s mockups, it makes me want to make something of that flavor. There are some rough edges but that is to be expected from such a new paradigm. So, does this mean Android is going to be pretty now? Well yes and no.

Stock Android will look a lot better and so will apps from good, thoughtful developers. This still leaves a huge swath of apps behind which will continue to be written in PhoneGap or other horrid tools. It also leaves out carrier apps which are spam-loaded onto every device. There is little hope there.

What would it take to execute this monumental shift in design on Android? For one, better toolchain from Google that affirms first-party tools and reduces (if not eliminates) the need for alternative IDEs. Apple can move mountaints becuse it controls the stack, Google doesn’t. This also comes into play when you look at the hardware that Android runs on. Material Design, like iOS 7, emphasizes GPU intensive animations and fluid transitions. While top-of-the-line Android devices ship with ok graphics, there is a massive swath of Android devices which are being launched/sold today that compare with iPhone 4 in hardware specs and that relic from 2010 cannot play animations!

Should iOS designers, developers, users be worried that Android is now good at design? Non-sense. For one, this is a document, a set of guidelines. Execution is everything and Google still has to prove itself on that front. Second, it is generally good for technology that the most used operating system is finally becoming presentable. It will induce a sense of design sensibility in makers and create a demand for higher quality wares in users. That is good for everybody. Honestly, if Android wasn’t around, there would be nothing pushing iOS.

Oculus Drift

Facebook went ahead and bought Oculus Rift. This adds a few more billions to their Visa bill for this quarter. No big deal.

What I really want to know is what the end game is? Are big companies buying ingenious little startups to lock their place in the future? Seems to me like a state of profound confusion about where things might go. Deep learning? Personal robotics? VR? “Let’s buy a major innovator in every field and let them operate independently. If we ever inch towards a future that inclines towards a particular paradigms, we already have that skunk-works lab in our basement we can start funneling money in.”

This is pathetic. Influential companies like Google and Facebook employ some of the smartest people and are in a position to define that future. They can make it, not stalk it with spaghetti to throw at walls which haven’t been built yet.

How do people buy phones?

HTC might have revealed another great phone this week. Build quality looks incredible, specs excellent, and OS clean.

Joanna Stern quips:

Will anyone care?

Frankly, they won’t! They didn’t last year. So, we know now, specs don’t matter. Build quality doesn’t matter. Even the OS is immaterial given that most other non-Apple phones all run Android. It begs the question, how do people even buy phones anymore? What is the inspiration behind their choice?

Ads? Brand? Random pick?

I am losing interest now.

Simbol

Yesterday I launched Simbol, an app to quickly find and use symbols and special characters on the iPhone. I developed the app to address one of the most annoying things about writing on iOS: finding symbols. I am a mathematics major and also study quite a lot of physics. Both require a very frequent use of symbols and characters which aren’t found on QWERTY keyboards. OS X has a very handy keyboard and character viewer that carries a big chunk of the Unicode library. However, iOS has nothing that comes even remotely close. I created a library of LaTeX snippets in TextExpander but that mostly went away with iOS 7. As a result, I am practically unable to take notes on iOS in most of my classes.

I wasn’t sure that there were many people, besides myself, who would find something like this useful. However, the response from friends and new users has been great and you all seem to like the app1. I am glad! Looking at most of the user feedback, I believe it would help to know the direction Simbol is headed in.

This brings us to the motive of Simbol: Simbol is intended to be the Keyboard And Character Viewer for iOS. This involves bringing the app on par with OS X. That is an enormous number of entities for the current design to efficiently support. Thus, I am already working on rethinking the workflow. That’s all I can say today.

Simbol is something I created to address one of my pains of writing and working on iOS. It is really great to know that others find it useful. I can’t wait to share what’s in the works!

I would love to hear what you think, or if you have any feature requests. You can always find me on twitter: @gravicle, or email me here.


  1. Gabe at Macdrifter and Viticci at MacStories even reviewed the app! I did not expect that to happen! 

Taming TestFlight

While TestFlight is an incredibly useful service, it has been a bit of a skirmish for me to get around. The workflow can be very convoluted. I am not sure it is my own dense brain or the process is indeed intricate. So, I wanted to write a guide for my own reference and for new developers.

First, here are TestFlight’s guides for getting started:

However there are caveats, from Apple’s as well as TestFlight’s side which make the process a pain in the butt! So, here is the workflow that works for me. This is being written from the perspective of a developer.

  1. Setup
    1. If you don’t have a TF account, create one → TestFlight » Beta Testing On The Fly. If you have a tester account, flip the switch in ‘Account Settings’ to allow access to developer features → TestFlight » Your Account.
    2. Create a team if you don’t have one already. All apps uploaded to a team will be visible to all the team members. However, you can configure access to build granularly, as I discuss in 3.2.
    3. In your Xcode project, add and enable TF SDK → TestFlight » SDK. Follow the instructions that ship in ‘Readme.md’.
  2. Generating and uploading a build
    1. Set the deployment device to iOS Device in Xcode.
    2. Then archive a build. Product » Archive. If the build fails with an error about missing provisioning profile, set the appropriate team profile here: Build Setting » Code Signing » Provisioning Profile. If you set a distribution profile, TF will reject the build.
    3. Once the build is archived, organizer will pop-up: Distribute » Save For Enterprise or Ad Hoc Deployment.
    4. Having generated the IPA, upload it to TF → TestFlight » Dashboard. You can also use their desktop app → TestFlight » Tools.
  3. What devices have access?
    1. TF can read the provisioning profile that is embedded in your uploaded IPA. So, all the devices you have in you provisioning portal at the time of generating the IPA will show up in TF. Those devices which have associated TF accounts appear as testers’ names with device details, others will be just UDIDs.
    2. To see all the devices in the current profile follow these breadcrumbs: Apps » Your App » Build » Permissions (in the left-sidebar). Here you can granularly configure access.
  4. Inviting testers
    1. TF cannot directly add or modify devices in your developer account. However, it does send you a nice email with UDID and other device info from testers which you can use to add devices to the developer portal.
    2. Invite new testers via TF → TestFlight » Add a Teammate. Better than sending emails is just sharing recruitment links. Grab it here → TestFlight » Recruitment
    3. They will receive an email with an invite which they can follow to create a new account and/or install your provisioning profile on their device. Once they do so, you’ll receive an email with their device details. Sometimes, this can take a while; you need to wait this out or ask testers to send you their UDIDs manually[1].
    4. Add the device(s) to provisioning portal → iOS Devices – Apple Developer. You can upload the file(s) TF sent you in the email.
    5. Now, your new testers will show up in TF under Teammate Devices Not On This Profile. Apps will start showing up for new testers but they will be denied installation.
  5. Adding testers to profile
    1. The simplest way to add new testers to a TF profile is to upload a new build after refreshing Xcode[2]. To refresh Xcode: Preferences » Accounts » Select your Apple ID » View Details » Refresh arrow. Now generate a new IPA and upload it to TF. On the Permissions page for your build, check the new devices and voila.. Your testers will now have access (ask them to refresh the TF page in their browser).
    2. If you’re not ready to upload a new build, you can add new testers by updating the profile in TF.
      1. After adding devices in iOS Provisioning Portal, download the updated profile → iOS Provisioning Profiles – Apple Developer.
      2. In TF, on Permissions page: Update Profile » Upload.
      3. Check the new teammates/devices to permit them to install the build.
      4. Ask your testers to refresh TF on their devices and they will be prompted to install a new profile[3]. Once they do, they can access and install your apps!
      5. You won’t have to do this for new builds as they will come embedded with these new devices, as detailed in 5.1.

And that is that. TF is a little overwhelming for new users; I should know! If I missed anything or you need clarification about something, feel free to let me know or ask me @gravicle.

Happy building!


  1. Please ask them to not use apps like this. iOS 7 onwards Apple has blocked access to UDIDs and all these apps can return are advertising identifiers which are useless for distribution purposes. An alternative is to use iTunes → What’s my UDID?.  ↩

  2. You don’t have to. The changes might propagate in time, but it sometimes takes a long time for me. Refreshing ensures that new devices are included in the embedded profile.  ↩

  3. Another reason why this route is sub-optimal.  ↩

Grace Hopper →

The most important thing I’ve accomplished, other than building the compiler, is training young people. They come to me, you know, and say, “Do you think we can do this?” I say, “Try it.” And I back ‘em up. They need that. I keep track of them as they get older and I stir ‘em up at intervals so they don’t forget to take chances.”

-Grace Hopper

Custom stylesheets on iOS

Today Caltech published the third volume of The Feynman Lectures making me jump all around, not quite unlike when the first volume became available. Having bought an iPad Air and loving it very much, I use it for most of my reading and studying. Feynman lectures looked quite unappealing on the iPad curtesy of the persistent “Buy Now” menu floating in the right-top corner and the tiny font size. To rectify this, I started looking for a way to load custom stylesheets is Safari on the iPad. I tried using Provisioning Profiles but could not figure how to make them work. Then, I stumbled across this tutorial on Juicy Studio detailing the process of creating an accessibility stylesheet bookmarklet. It basically solved the issue for me. Here is a page from the HTML version of The Feynman Lectures before and after.


How to do it yourselves?

  • Create a stylesheet, upload it to your hosting account and grab a direct link to the .css file.
  • Paste the link in place of STYLESHEET-LINK-HERE in the following JS

javascript:(function()%7Bif%20(!document.getElementById(‘someuniqueid’))%7Bvar%20objHead%20=%20document.getElementsByTagName(‘head’);%20if%20(objHead%5B0%5D)%7Bif%20(document.createElementNS%20&&%20objHead%5B0%5D.tagName%20==%20’head‘)%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElementNS(‘http://www.w3.org/1999/xhtml’,%20’link’));%20else%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElement(‘link’));%20objCSS.id%20=%20’someuniqueid‘;%20objCSS.rel%20=%20’stylesheet’;%20objCSS.href%20=%20’STYLESHEET-LINK-HERE‘;%20objCSS.type%20=%20’text/css’;%7D%7D%7D)()

  • Create a bookmarklet with the given code. If you need help with this, here is a helpful video; except that you’ll erase the URL and paste the JS we just edited instead of editing the URL.
  • Place the bookmarklets in “Bookmarks”, i.e. on the top level. This will allow you quick access.

Here is the bookmarklet I created for Feynman Lectures.

javascript:(function()%7Bif%20(!document.getElementById('someuniqueid'))%7Bvar%20objHead%20=%20document.getElementsByTagName('head');%20if%20(objHead%5B0%5D)%7Bif%20(document.createElementNS%20&&%20objHead%5B0%5D.tagName%20==%20'head')%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElementNS('http://www.w3.org/1999/xhtml',%20'link'));%20else%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElement('link'));%20objCSS.id%20=%20'someuniqueid';%20objCSS.rel%20=%20'stylesheet';%20objCSS.href%20=%20'http://culturedpixel.com/custom-stylesheets/fy.css';%20objCSS.type%20=%20'text/css';%7D%7D%7D)()

Here is another with dark mode!

javascript:(function()%7Bif%20(!document.getElementById('someuniqueid'))%7Bvar%20objHead%20=%20document.getElementsByTagName('head');%20if%20(objHead%5B0%5D)%7Bif%20(document.createElementNS%20&&%20objHead%5B0%5D.tagName%20==%20'head')%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElementNS('http://www.w3.org/1999/xhtml',%20'link'));%20else%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElement('link'));%20objCSS.id%20=%20'someuniqueid';%20objCSS.rel%20=%20'stylesheet';%20objCSS.href%20=%20'http://culturedpixel.com/custom-stylesheets/fy-dark.css';%20objCSS.type%20=%20'text/css';%7D%7D%7D)()

Here is one that I adapted from the Beautipedia Safari Extension. It makes Wikipedia a bit better than the “Reader” view on the iPad and you don’t even have to go to another app.

javascript:(function()%7Bif%20(!document.getElementById('someuniqueid'))%7Bvar%20objHead%20=%20document.getElementsByTagName('head');%20if%20(objHead%5B0%5D)%7Bif%20(document.createElementNS%20&&%20objHead%5B0%5D.tagName%20==%20'head')%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElementNS('http://www.w3.org/1999/xhtml',%20'link'));%20else%20var%20objCSS%20=%20objHead%5B0%5D.appendChild(document.createElement('link'));%20objCSS.id%20=%20'someuniqueid';%20objCSS.rel%20=%20'stylesheet';%20objCSS.href%20=%20'http://culturedpixel.com/custom-stylesheets/beautipedia/beautipedia.css';%20objCSS.type%20=%20'text/css';%7D%7D%7D)()

Before and after shots: