diff --git a/README.md b/README.md new file mode 100644 index 0000000..a1491db --- /dev/null +++ b/README.md @@ -0,0 +1,259 @@ +## Introduction +PageDown is the JavaScript [Markdown](http://daringfireball.net/projects/markdown/) previewer used on [Stack Overflow](http://stackoverflow.com/) and the rest of the [Stack Exchange network](http://stackexchange.com/). It includes a Markdown-to-HTML converter and an in-page Markdown editor with live preview. + +While on the Stack Exchange sites PageDown is exclusively used on the client site (on the server side, [MarkdownSharp](http://code.google.com/p/markdownsharp/) is our friend), PageDown's converter also works in a server environment. So if your Node.JS application lets users enter Markdown, you can also use PageDown to convert it to HTML on the server side. + +The largest part is based on work by John Fraser, a.k.a. Attacklab. He created the converter under the name **Showdown** and the editor under the name **WMD**. See [this post on the Stack Exchange blog](http://blog.stackoverflow.com/2008/12/reverse-engineering-the-wmd-editor/) for some historical information. + +Over the years, we (the Stack Exchange team and others) have made quite a few changes, bug fixes etc., which is why we decided to publish the whole thing under a new name. This is not to mean we want to deprive John Fraser of any credits; he deserves lots. And you'll still be finding the letters "wmd" in a few places. + +It should be noted that Markdown is **not safe as far as user-entered input goes**. Pretty much anything is valid in Markdown, in particular something like ``. This PageDown repository includes the two plugins that Stack Exchange uses to sanitize the user's input; see the description of Markdown.Sanitizer.js below. + +In the demo/ folder, it also include usage examples. To see the editor at work, open demos/browsers/demo.html in your browser. To see the server side version at work, go to the demos/node folder and run `node demo.js`, then navigate your browser to http://localhost:8000. + +### node.js and npm + +The easiest way to get the Markdown converter working in node.js is by getting it [through npm](https://npmjs.org/package/pagedown). + +``` +$ npm install pagedown +$ node +``` + +```js +var pagedown = require("pagedown"); +var converter = new pagedown.Converter(); +var safeConverter = pagedown.getSanitizingConverter(); +converter.makeHtml("hello") +``` + +> hello + +```js +safeConverter.makeHtml("Hello doEvil();") ' +Hello doEvil(); +``` + +If you don't want to use npm, then follow the instructions below. + +## The three main files + +### Markdown.Converter.js + +#### In the browser + +Used in a regular browser environment, it provides a top-level object called `Markdown` with two properties: + +`Markdown.Converter` is a constructor that creates a converter object. Call this object's `makeHtml` method to turn Markdown into HTML: + +```js +var converter = new Markdown.Converter(); +document.write(converter.makeHtml("**I am bold!**")); +``` + +The constructor optionally takes an `OPTIONS` object as an argument. + +The only currently recognized option is `OPTIONS.nonAsciiLetters`. If this is truthy, the converter will work around JavaScript's lack of unicode support in regular expressions when handling bold and italic. For example, since intra-word emphasis is prevented, the asterisks in `w**or**d` will not cause bolding. However without the workaround, the same is not true if the letters are outside the ASCII range: `с**ло́в**о` will cause the middle part of the word to be bolded. + +If the workaround is enabled, latin and cyrillic will behave identically here. + +`Markdown.HookCollection` is a constructor that creates a very simple plugin hook collection. You can usually ignore it; it's exported because the Markdown Editor (see below) uses it as well. + +#### On the server + +If you're using it in a CommonJS environment (we'll just assume Node.JS from now on), those two properties are the module's exports. + +```js +var Converter = require("./Markdown.Converter").Converter; var converter = new Converter(); +console.log(converter.makeHtml("**I am bold!**")); +``` + +### Markdown.Sanitizer.js + +#### In the browser + +In a browser environment, this file has to be included after including Markdown.Converter.js. It adds a function named `getSanitizingConverter` to the `Markdown` object (created in the previous file). + +This function returns a converter object that has two plugins registered on the `postConversion` plugin hook. One of them sanitizes the output HTML to only include a list of whitelisted HTML tags. The other one attempts to balance opening/closing tags to prevent leaking formating if the HTML is displayed in the browser. + +```js +var converter = getSanitizingConverter(); +document.write(converter.makeHtml("bold"); // creates "alert(42);bold" +``` + +#### On the server + +Same thing, except that `getSanitizingConverter` is exported, and you don't need to load Markdown.Converter.js. + +```js +var converter = require("./Markdown.Sanitizer").getSanitizingConverter(); +console.log(converter.makeHtml("bold"); // creates "alert(42);bold" +``` + +### Markdown.Editor.js + +This file is only made for usage in the browser (obviously running it on the server neither makes sense nor works). + +It has to be included after Markdown.Converter.js, as it requires the top-level `Markdown` object and its `HookCollection` property. If you're not using the provided Markdown converter, you'll have to change this file to include these two things. + +The file adds the property `Markdown.Editor`, which is a constructor taking up to three arguments: + +- The first argument is required, and is the Markdown converter object (as created above) used for the editor's preview. + +- The second argument is optional, and is usually only necessary if you're using several editors within the same page. If given, this argument is a string, appended to the HTML element ids of the three elements used by the editor. + + By default, the editor looks for `#wmd-button-bar`, `#wmd-input`, and `#wmd-preview`. If you're using more than one editor, you of course can't give the second group of elements the same ids as the first, so you may create the second input box as `