docs: function Pagedown(options) {
  
    options = options || {};
  
    if (typeof options.handler === "function") { //backwards compatible behavior
      options = {
        helpButton: options
      };
    }
    options.strings = options.strings || {};
    var getString = function (identifier) {
      return options.strings[identifier] || defaultsStrings[identifier];
    };
  
    function identity(x) {
      return x;
    }
  
    function returnFalse() {
      return false;
    }
  
    function HookCollection() { }
    HookCollection.prototype = {
  
      chain: function (hookname, func) {
        var original = this[hookname];
        if (!original) {
          throw new Error("unknown hook " + hookname);
        }
  
        if (original === identity) {
          this[hookname] = func;
        } else {
          this[hookname] = function () {
            var args = Array.prototype.slice.call(arguments, 0);
            args[0] = original.apply(null, args);
            return func.apply(null, args);
          };
        }
      },
      set: function (hookname, func) {
        if (!this[hookname]) {
          throw new Error("unknown hook " + hookname);
        }
        this[hookname] = func;
      },
      addNoop: function (hookname) {
        this[hookname] = identity;
      },
      addFalse: function (hookname) {
        this[hookname] = returnFalse;
      }
    };
  
    var hooks = this.hooks = new HookCollection();
    hooks.addNoop("onPreviewRefresh"); // called with no arguments after the preview has been refreshed
    hooks.addNoop("postBlockquoteCreation"); // called with the user's selection *after* the blockquote was created; should return the actual to-be-inserted text
    hooks.addFalse("insertImageDialog");
    /* called with one parameter: a callback to be called with the URL of the image. If the application creates
     * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen
     * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used.
     */
    hooks.addFalse("insertLinkDialog");
  
    var that = this,
      input;
  
    this.run = function () {
      if (input)
        return; // already initialized
  
      input = options.input;
      var commandManager = new CommandManager(hooks, getString);
      var uiManager;
  
      uiManager = new UIManager(input, commandManager);
  
      that.uiManager = uiManager;
    };
  
  }