2013-08-09 06:14:12 +08:00
|
|
|
/*global Markdown:true BetterMarkdown:true */
|
2013-03-06 03:33:27 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
Contains methods to help us with markdown formatting.
|
|
|
|
|
|
|
|
@class Markdown
|
|
|
|
@namespace Discourse
|
|
|
|
@module Discourse
|
|
|
|
**/
|
|
|
|
Discourse.Markdown = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a raw string to a cooked markdown string.
|
|
|
|
|
|
|
|
@method cook
|
|
|
|
@param {String} raw the raw string we want to apply markdown to
|
|
|
|
@param {Object} opts the options for the rendering
|
2013-03-06 04:39:21 +08:00
|
|
|
@return {String} the cooked markdown string
|
2013-03-06 03:33:27 +08:00
|
|
|
**/
|
|
|
|
cook: function(raw, opts) {
|
|
|
|
if (!opts) opts = {};
|
|
|
|
|
|
|
|
// Make sure we've got a string
|
|
|
|
if (!raw) return "";
|
|
|
|
if (raw.length === 0) return "";
|
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
return this.markdownConverter(opts).makeHtml(raw);
|
2013-03-06 03:33:27 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-03-06 04:39:21 +08:00
|
|
|
Creates a new pagedown markdown editor, supplying i18n translations.
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
@method createEditor
|
|
|
|
@param {Object} converterOptions custom options for our markdown converter
|
|
|
|
@return {Markdown.Editor} the editor instance
|
2013-03-06 03:33:27 +08:00
|
|
|
**/
|
2013-03-06 04:39:21 +08:00
|
|
|
createEditor: function(converterOptions) {
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
if (!converterOptions) converterOptions = {};
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
// By default we always sanitize content in the editor
|
|
|
|
converterOptions.sanitize = true;
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
var markdownConverter = Discourse.Markdown.markdownConverter(converterOptions);
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
var editorOptions = {
|
|
|
|
strings: {
|
2013-07-09 07:32:16 +08:00
|
|
|
bold: I18n.t("composer.bold_title") + " <strong> Ctrl+B",
|
|
|
|
boldexample: I18n.t("composer.bold_text"),
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
italic: I18n.t("composer.italic_title") + " <em> Ctrl+I",
|
|
|
|
italicexample: I18n.t("composer.italic_text"),
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
link: I18n.t("composer.link_title") + " <a> Ctrl+L",
|
|
|
|
linkdescription: I18n.t("composer.link_description"),
|
|
|
|
linkdialog: "<p><b>" + I18n.t("composer.link_dialog_title") + "</b></p><p>http://example.com/ \"" +
|
|
|
|
I18n.t("composer.link_optional_text") + "\"</p>",
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
quote: I18n.t("composer.quote_title") + " <blockquote> Ctrl+Q",
|
|
|
|
quoteexample: I18n.t("composer.quote_text"),
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
code: I18n.t("composer.code_title") + " <pre><code> Ctrl+K",
|
|
|
|
codeexample: I18n.t("composer.code_text"),
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-15 05:44:50 +08:00
|
|
|
image: I18n.t("composer.upload_title") + " - Ctrl+G",
|
|
|
|
imagedescription: I18n.t("composer.upload_description"),
|
2013-03-06 03:33:27 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
olist: I18n.t("composer.olist_title") + " <ol> Ctrl+O",
|
|
|
|
ulist: I18n.t("composer.ulist_title") + " <ul> Ctrl+U",
|
|
|
|
litem: I18n.t("composer.list_item"),
|
2013-03-06 04:39:21 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
heading: I18n.t("composer.heading_title") + " <h1>/<h2> Ctrl+H",
|
|
|
|
headingexample: I18n.t("composer.heading_text"),
|
2013-03-06 04:39:21 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
hr: I18n.t("composer.hr_title") + " <hr> Ctrl+R",
|
2013-03-06 04:39:21 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
undo: I18n.t("composer.undo_title") + " - Ctrl+Z",
|
|
|
|
redo: I18n.t("composer.redo_title") + " - Ctrl+Y",
|
|
|
|
redomac: I18n.t("composer.redo_title") + " - Ctrl+Shift+Z",
|
2013-03-06 04:39:21 +08:00
|
|
|
|
2013-07-09 07:32:16 +08:00
|
|
|
help: I18n.t("composer.help")
|
2013-03-06 04:39:21 +08:00
|
|
|
}
|
2013-03-06 03:33:27 +08:00
|
|
|
};
|
|
|
|
|
2013-03-06 04:39:21 +08:00
|
|
|
return new Markdown.Editor(markdownConverter, undefined, editorOptions);
|
2013-03-06 03:33:27 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
Creates a Markdown.Converter that we we can use for formatting
|
|
|
|
|
|
|
|
@method markdownConverter
|
|
|
|
@param {Object} opts the converting options
|
|
|
|
**/
|
|
|
|
markdownConverter: function(opts) {
|
2013-03-06 04:39:21 +08:00
|
|
|
if (!opts) opts = {};
|
|
|
|
|
2013-08-09 06:14:12 +08:00
|
|
|
return {
|
|
|
|
makeHtml: function(text) {
|
|
|
|
|
|
|
|
text = Discourse.Dialect.cook(text, opts);
|
|
|
|
if (!text) return "";
|
|
|
|
|
|
|
|
if (opts.sanitize) {
|
|
|
|
if (!window.sanitizeHtml) return "";
|
|
|
|
text = window.sanitizeHtml(text);
|
2013-03-06 03:33:27 +08:00
|
|
|
}
|
2013-08-09 06:14:12 +08:00
|
|
|
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
};
|
2013-03-06 03:33:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
RSVP.EventTarget.mixin(Discourse.Markdown);
|