Build a Markdown editor with Node Webkit and Ember

In my infinite free time I've been playing with Node Webkit and it is pretty awesome. So let's build a markdown editor using it. You can find the repo here

Getting setup

First of all we need to install Node Webkit so head on over here jump down to downloads and download the one relevant for your system (I'll be using Mac for the purpose of this guide). Go and place node-webkit in your applications folder.
One final thing then we're ready to go. I highly recommend that you use Sublime Text for the purposes of building Node Webkit apps. Head on over here and follow the instructions so that we can build our apps inside sublime. If you choose to not use sublime head on over here to read up on how to run Webkit apps.

First steps

Create a new folder called EmberMarkdown anywhere you like. In the root of the folder create package.json and make it look something like

{
  "name": "embermarkdown",
  "version": "0.0.1",
  "description": "Markdown writer with Ember and Node Webkit",
  "main": "index.html",
  "license": "MIT",
  "window": {
    "title": "Ember Markdown",
    "position": "center",
    "width": 1000,
    "height": 600,
    "toolbar": true
  },
  "dependencies": {
    "marked": "latest",
    "highlight.js": "latest"
  }
}

This should be fairly self explanitory except for maybe the window options. Here we set the title of our app, how wide and tall it should be, where it should be located on the screen when it loads initially and finally we set toolbar to true so that we'll be able to debug our application.
In the terminal go ahead and run npm install to install the dependencies.

Hello World!!!

Next steps will be to get something up on the screen. So create index.html in the root of the directory and make it look something like

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Ember Markdown</title>
</head>
<body>
  <h1>Hello World<h1>
</body>
</html>

Go ahead and build the app (either using Sublime Text or the instructions above) and voila. There is it in all of it's glory. Lets make it a bit more interesting. Head on over here and download a build of ace (I'm using src-min-noconflict). Create a js folder in the root of your directory, then a lib folder inside of it then put in the contents of ace right in there, renaming the folder to ace (i.e. if the folder is called src-min-noconflict rename that to ace).
Next we need to go and download Ember so head on over here and download the starter kit. From the starter kit go and copy over the contents of js/libs into the js/lib directory in our app. While your at it also create a blank app.js file in the root of the js directory.
Update your index.html to look something along the lines of

<!DOCTYPE html>
...
<body>
  <script src='js/lib/jquery-1.10.2.js'></script>
  <script src='js/lib/handlebars-1.1.2.js'></script>
  <script src='js/lib/ember-1.7.0.js'></script>
  <script src='js/lib/ace/ace.js'></script>
  <script src='js/app.js'></script>
</body>
</html>

Let's get editing

Let's get Ace up and running in our app. Inside our app.js let's create an Ember application

App = Ember.Application.create();

and while we're at it let's set up the model for our index route (which will be where we edit and render our markdown)

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return {
      body: ""
    }
  }
});

Now in our index view let's instanciate the Ace Editor like so

App.IndexView = Ember.View.extend({
  editor: null,
  didInsertElement: function() {
    this.editor = ace.edit("editor");
    this.editor.getSession().setMode("ace/mode/markdown");
    $('.ace_text-input').focus();
  }
});

Finally let's update our index.html to have a handlebar template for the application and index.

<body>
  <script type='text/x-handlebars' id='application'>
    {{outlet}}
  </script>
  <script type='text/x-handlebars' id='index'>
    <div id="editor">
    </div>
  </script>
  ...

We also need to set up a stylesheet so that our editor will actually show in the app so create a new directory called css in the root of the application and create a file called main.css inside and fill it as such

body, html{
  height: 100%;
}

#editor {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
}

Link to it in our index.html as such

...
  <link rel='stylesheet' href='css/main.css'>
</head>

build the application and we should be able to edit some text. Awesome!

Rendering some markdown

First we need to setup marked (what we will use to render our markdown). At the top of app.js add var marked = require('marked') and at the bottom of didInsertElement in App.IndexView add

    marked.setOptions({
      gfm: true,
      breaks: true,
      highlight: function (code) {
        return require('highlight.js').highlightAuto(code).value;
      }
    });

We're going to take advantage of computed properties in Ember to create our rendered markdown version. So firstly when someone starts typing into the text editor we want to update the body on our object. We can do that inside of our index view like so

  ...
  },
  keyUp: function() {
    this.get('controller').set('body', this.editor.getValue());
  }

Now we'll create our Index Controller and have create a computed property that will update whenever the body changes

App.IndexController = Ember.ObjectController.extend({
  renderedMarkdown: function() {
    var markdown = marked(this.get('body'));
    return markdown;
  }.property('body')
});

We're almost down. Update index.html to look like

...
<script type='text/x-handlebars' id='index'>
      <div id="editor">
      </div>
      <div id="markdown-preview">
        {{{renderedMarkdown}}}
      </div>
    </script>

Notice the {{{}}} as opposed to {{}}. This will prevent handlebars from escaping HTML and thus ensuring our markdown is rendered in all of it's glory.

At the bottom of main.css go ahead and add

#markdown-preview {
  position: absolute;
  overflow: scroll;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
}

If you go ahead and build now you should have a fully working markdown editor with a live preview.
To fancy it up a little bit let's add some styles.
For code highlighting we're using highlight.js so we can link to one of their included stylesheets like so

<link rel='stylesheet' href='node_modules/highlight.js/styles/github.css'>

and finally if you really want to make the markdown look fancy head on over here and download one of their fancy style sheets.
And their you have it!

Next Time*

*if their is a next time

We will create a menu bar and incoporate the ability to open and save markdown files.