Implemented markdown footnotes
This commit is contained in:
parent
56f1c3d8c4
commit
abe18e41bf
@ -419,6 +419,13 @@ div.dropdown-menu textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.footnote {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.5em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.icon-link {
|
||||
background-position: -72px -168px;
|
||||
}
|
||||
@ -642,6 +649,10 @@ div.dropdown-menu textarea {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tooltip li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* Definition list */
|
||||
dt,dd {
|
||||
margin-top: 5px;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
10
js/classes/Extension.js
Normal file
10
js/classes/Extension.js
Normal file
@ -0,0 +1,10 @@
|
||||
define(function() {
|
||||
|
||||
function Extension(extensionId, extensionName, isOptional) {
|
||||
this.extensionId = extensionId;
|
||||
this.extensionName = extensionName;
|
||||
this.isOptional = isOptional;
|
||||
}
|
||||
|
||||
return Extension;
|
||||
});
|
9
js/classes/Provider.js
Normal file
9
js/classes/Provider.js
Normal file
@ -0,0 +1,9 @@
|
||||
define(function() {
|
||||
|
||||
function Provider(providerId, providerName) {
|
||||
this.providerId = providerId;
|
||||
this.providerName = providerName;
|
||||
}
|
||||
|
||||
return Provider;
|
||||
});
|
39
js/core.js
39
js/core.js
@ -461,6 +461,28 @@ define([
|
||||
}
|
||||
});
|
||||
|
||||
// Reset inputs
|
||||
$(".action-reset-input").click(function() {
|
||||
utils.resetModalInputs();
|
||||
});
|
||||
|
||||
// Do periodic tasks
|
||||
intervalId = window.setInterval(function() {
|
||||
utils.updateCurrentTime();
|
||||
checkWindowUnique();
|
||||
if(isUserActive() === true || viewerMode === true) {
|
||||
_.each(periodicCallbacks, function(callback) {
|
||||
callback();
|
||||
});
|
||||
checkOnline();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
core.onReady(extensionMgr.onReady);
|
||||
|
||||
// After extensions onReady callbacks
|
||||
core.onReady(function() {
|
||||
|
||||
// Tooltips
|
||||
$(".tooltip-lazy-rendering").tooltip({
|
||||
container: '#modal-settings',
|
||||
@ -490,24 +512,7 @@ define([
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// Reset inputs
|
||||
$(".action-reset-input").click(function() {
|
||||
utils.resetModalInputs();
|
||||
});
|
||||
|
||||
// Do periodic tasks
|
||||
intervalId = window.setInterval(function() {
|
||||
utils.updateCurrentTime();
|
||||
checkWindowUnique();
|
||||
if(isUserActive() === true || viewerMode === true) {
|
||||
_.each(periodicCallbacks, function(callback) {
|
||||
callback();
|
||||
});
|
||||
checkOnline();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
core.onReady(extensionMgr.onReady);
|
||||
|
||||
return core;
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"settings",
|
||||
"text!html/settingsExtensionsAccordion.html",
|
||||
"extensions/googleAnalytics",
|
||||
@ -20,20 +21,21 @@ define([
|
||||
"extensions/documentTitle",
|
||||
"extensions/workingIndicator",
|
||||
"extensions/notifications",
|
||||
"extensions/markdown-extra",
|
||||
"extensions/markdownExtra",
|
||||
"extensions/markdownFootnotes",
|
||||
"extensions/toc",
|
||||
"extensions/mathJax",
|
||||
"extensions/emailConverter",
|
||||
"extensions/scrollLink",
|
||||
"libs/bootstrap",
|
||||
"libs/jquery.waitforimages"
|
||||
], function($, _, utils, settings, settingsExtensionsAccordionHTML) {
|
||||
], function($, _, utils, Extension, settings, settingsExtensionsAccordionHTML) {
|
||||
|
||||
var extensionMgr = {};
|
||||
|
||||
// Create a list of extensions
|
||||
var extensionList = _.chain(arguments).map(function(argument) {
|
||||
return _.isObject(argument) && argument.extensionId && argument;
|
||||
return argument instanceof Extension && argument;
|
||||
}).compact().value();
|
||||
|
||||
// Return every named callbacks implemented in extensions
|
||||
@ -66,7 +68,7 @@ define([
|
||||
extensionSettings = settings.extensionSettings || {};
|
||||
_.each(extensionList, function(extension) {
|
||||
extension.config = _.extend({}, extension.defaultConfig, extensionSettings[extension.extensionId]);
|
||||
extension.config.enabled = !extension.optional || extension.config.enabled === undefined || extension.config.enabled === true;
|
||||
extension.config.enabled = !extension.isOptional || extension.config.enabled === undefined || extension.config.enabled === true;
|
||||
});
|
||||
|
||||
// Load/Save extension config from/to settings
|
||||
@ -152,8 +154,8 @@ define([
|
||||
$("#accordion-extensions").append($(_.template(settingsExtensionsAccordionHTML, {
|
||||
extensionId: extension.extensionId,
|
||||
extensionName: extension.extensionName,
|
||||
optional: extension.optional,
|
||||
settingsBloc: extension.settingsBloc
|
||||
isOptional: extension.isOptional,
|
||||
settingsBlock: extension.settingsBlock
|
||||
})));
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,48 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"text!html/buttonHtmlCode.html",
|
||||
], function($, buttonHtmlCodeHTML) {
|
||||
"text!html/buttonHtmlCodeSettingsBlock.html",
|
||||
], function($, _, utils, Extension, buttonHtmlCodeHTML, buttonHtmlCodeSettingsBlockHTML) {
|
||||
|
||||
var buttonHtmlCode = {
|
||||
extensionId: "buttonHtmlCode",
|
||||
extensionName: 'Button "HTML code"',
|
||||
optional: true,
|
||||
settingsBloc: '<p>Adds a "HTML code" button over the preview.</p>'
|
||||
var buttonHtmlCode = new Extension("buttonHtmlCode", 'Button "HTML code"', true);
|
||||
buttonHtmlCode.settingsBlock = buttonHtmlCodeSettingsBlockHTML;
|
||||
buttonHtmlCode.defaultConfig = {
|
||||
template: "<%= documentHTML %>",
|
||||
};
|
||||
|
||||
buttonHtmlCode.onLoadSettings = function() {
|
||||
utils.setInputValue("#textarea-html-code-template", buttonHtmlCode.config.template);
|
||||
};
|
||||
|
||||
buttonHtmlCode.onSaveSettings = function(newConfig, event) {
|
||||
newConfig.template = utils.getInputValue("#textarea-html-code-template");
|
||||
};
|
||||
|
||||
buttonHtmlCode.onCreatePreviewButton = function() {
|
||||
return $(buttonHtmlCodeHTML);
|
||||
};
|
||||
|
||||
var selectedFileDesc = undefined;
|
||||
buttonHtmlCode.onFileSelected = function(fileDesc) {
|
||||
selectedFileDesc = fileDesc;
|
||||
};
|
||||
|
||||
buttonHtmlCode.onPreviewFinished = function() {
|
||||
$("#input-html-code").val($("#wmd-preview").html());
|
||||
try {
|
||||
var htmlCode = _.template(buttonHtmlCode.config.template, {
|
||||
documentTitle: selectedFileDesc.title,
|
||||
documentMarkdown: selectedFileDesc.content,
|
||||
documentHTML: $("#wmd-preview").html()
|
||||
});
|
||||
$("#input-html-code").val(htmlCode);
|
||||
}
|
||||
catch(e) {
|
||||
extensionMgr.onError(e);
|
||||
return e.message;
|
||||
}
|
||||
};
|
||||
|
||||
buttonHtmlCode.onReady = function() {
|
||||
|
@ -1,14 +1,11 @@
|
||||
define([
|
||||
"jquery",
|
||||
"classes/Extension",
|
||||
"text!html/buttonMarkdownSyntax.html",
|
||||
], function($, buttonMarkdownSyntaxHTML) {
|
||||
], function($, Extension, buttonMarkdownSyntaxHTML) {
|
||||
|
||||
var buttonMarkdownSyntax = {
|
||||
extensionId: "buttonMarkdownSyntax",
|
||||
extensionName: 'Button "Markdown syntax"',
|
||||
optional: true,
|
||||
settingsBloc: '<p>Adds a "Markdown syntax" button over the preview.</p>'
|
||||
};
|
||||
var buttonMarkdownSyntax = new Extension("buttonMarkdownSyntax", 'Button "Markdown syntax', true);
|
||||
buttonMarkdownSyntax.settingsBlock = '<p>Adds a "Markdown syntax" button over the preview.</p>';
|
||||
|
||||
buttonMarkdownSyntax.onCreatePreviewButton = function() {
|
||||
return $(buttonMarkdownSyntaxHTML);
|
||||
|
@ -1,14 +1,12 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
"text!html/buttonPublish.html",
|
||||
], function($, _, buttonPublishHTML) {
|
||||
], function($, _, Extension, buttonPublishHTML) {
|
||||
|
||||
var buttonPublish = {
|
||||
extensionId: "buttonPublish",
|
||||
extensionName: 'Button "Publish"',
|
||||
settingsBloc: '<p>Adds a "Publish document" button in the navigation bar.</p>'
|
||||
};
|
||||
var buttonPublish = new Extension("buttonPublish", 'Button "Publish"');
|
||||
buttonPublish.settingsBlock = '<p>Adds a "Publish document" button in the navigation bar.</p>';
|
||||
|
||||
var button = undefined;
|
||||
var currentFileDesc = undefined;
|
||||
|
@ -1,16 +1,13 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
"text!html/buttonShare.html",
|
||||
"text!html/buttonShareLocation.html",
|
||||
], function($, _, buttonShareHTML, buttonShareLocationHTML) {
|
||||
], function($, _, Extension, buttonShareHTML, buttonShareLocationHTML) {
|
||||
|
||||
var buttonShare = {
|
||||
extensionId: "buttonShare",
|
||||
extensionName: 'Button "Share"',
|
||||
optional: true,
|
||||
settingsBloc: '<p>Adds a "Share document" button in the navigation bar.</p>'
|
||||
};
|
||||
var buttonShare = new Extension("buttonShare", 'Button "Share"', true);
|
||||
buttonShare.settingsBlock = '<p>Adds a "Share document" button in the navigation bar.</p>';
|
||||
|
||||
buttonShare.onCreateButton = function() {
|
||||
return $(buttonShareHTML);
|
||||
|
@ -2,23 +2,20 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"text!html/buttonStat.html",
|
||||
"text!html/buttonStatSettingsBloc.html",
|
||||
], function($, _, utils, buttonStatHTML, buttonStatSettingsBlocHTML) {
|
||||
"text!html/buttonStatSettingsBlock.html",
|
||||
], function($, _, utils, Extension, buttonStatHTML, buttonStatSettingsBlockHTML) {
|
||||
|
||||
var buttonStat = {
|
||||
extensionId: "buttonStat",
|
||||
extensionName: 'Button "Statistics"',
|
||||
optional: true,
|
||||
defaultConfig: {
|
||||
name1: "Characters",
|
||||
value1: "\\S",
|
||||
name2: "Words",
|
||||
value2: "\\S+",
|
||||
name3: "Paragraphs",
|
||||
value3: "\\S.*",
|
||||
},
|
||||
settingsBloc: buttonStatSettingsBlocHTML
|
||||
var buttonStat = new Extension("buttonStat", 'Button "Statistics"', true);
|
||||
buttonStat.settingsBlock = buttonStatSettingsBlockHTML;
|
||||
buttonStat.defaultConfig = {
|
||||
name1: "Characters",
|
||||
value1: "\\S",
|
||||
name2: "Words",
|
||||
value2: "\\S+",
|
||||
name3: "Paragraphs",
|
||||
value3: "\\S.*",
|
||||
};
|
||||
|
||||
buttonStat.onLoadSettings = function() {
|
||||
|
@ -2,17 +2,15 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"text!html/buttonSync.html",
|
||||
"text!html/buttonSyncSettingsBloc.html",
|
||||
], function($, _, utils, buttonSyncHTML, buttonSyncSettingsBlocHTML) {
|
||||
"text!html/buttonSyncSettingsBlock.html",
|
||||
], function($, _, utils, Extension, buttonSyncHTML, buttonSyncSettingsBlockHTML) {
|
||||
|
||||
var buttonSync = {
|
||||
extensionId: "buttonSync",
|
||||
extensionName: 'Button "Synchronize"',
|
||||
defaultConfig: {
|
||||
syncPeriod: 180000
|
||||
},
|
||||
settingsBloc: buttonSyncSettingsBlocHTML
|
||||
var buttonSync = new Extension("buttonSync", 'Button "Synchronize"');
|
||||
buttonSync.settingsBlock = buttonSyncSettingsBlockHTML;
|
||||
buttonSync.defaultConfig = {
|
||||
syncPeriod: 180000
|
||||
};
|
||||
|
||||
buttonSync.onLoadSettings = function() {
|
||||
|
@ -1,14 +1,11 @@
|
||||
define([
|
||||
"jquery",
|
||||
"classes/Extension",
|
||||
"text!html/buttonViewer.html",
|
||||
], function($, buttonViewerHTML) {
|
||||
], function($, Extension, buttonViewerHTML) {
|
||||
|
||||
var buttonViewer = {
|
||||
extensionId: "buttonViewer",
|
||||
extensionName: 'Button "Viewer"',
|
||||
optional: true,
|
||||
settingsBloc: '<p>Adds a "Viewer" button over the preview.</p>'
|
||||
};
|
||||
var buttonViewer = new Extension("buttonViewer", 'Button "Viewer"', true);
|
||||
buttonViewer.settingsBlock = '<p>Adds a "Viewer" button over the preview.</p>';
|
||||
|
||||
buttonViewer.onCreatePreviewButton = function() {
|
||||
return $(buttonViewerHTML);
|
||||
|
@ -1,14 +1,12 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
"text!html/dialogAbout.html",
|
||||
], function($, _, dialogAboutHTML) {
|
||||
], function($, _, Extension, dialogAboutHTML) {
|
||||
|
||||
var dialogAbout = {
|
||||
extensionId: "dialogAbout",
|
||||
extensionName: 'Dialog "About"',
|
||||
settingsBloc: '<p>Prints the content of the "About" dialog box.</p>'
|
||||
};
|
||||
var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
|
||||
dialogAbout.settingsBlock = '<p>Prints the content of the "About" dialog box.</p>';
|
||||
|
||||
var libraries = {
|
||||
"Bootstrap": "http://twitter.github.io/bootstrap/",
|
||||
|
@ -1,14 +1,12 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
"text!html/dialogManagePublicationLocation.html",
|
||||
], function($, _, dialogManagePublicationLocationHTML) {
|
||||
], function($, _, Extension, dialogManagePublicationLocationHTML) {
|
||||
|
||||
var dialogManagePublication = {
|
||||
extensionId: "dialogManagePublication",
|
||||
extensionName: 'Dialog "Manage publication"',
|
||||
settingsBloc: '<p>Populates the "Manage publication" dialog box.</p>'
|
||||
};
|
||||
var dialogManagePublication = new Extension("dialogManagePublication", 'Dialog "Manage publication"');
|
||||
dialogManagePublication.settingsBlock = '<p>Populates the "Manage publication" dialog box.</p>';
|
||||
|
||||
var extensionMgr = undefined;
|
||||
dialogManagePublication.onExtensionMgrCreated = function(extensionMgrParameter) {
|
||||
|
@ -1,14 +1,12 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
"text!html/dialogManageSynchronizationLocation.html",
|
||||
], function($, _, dialogManageSynchronizationLocationHTML) {
|
||||
], function($, _, Extension, dialogManageSynchronizationLocationHTML) {
|
||||
|
||||
var dialogManageSynchronization = {
|
||||
extensionId: "dialogManageSynchronization",
|
||||
extensionName: 'Dialog "Manage synchronization"',
|
||||
settingsBloc: '<p>Populates the "Manage synchronization" dialog box.</p>'
|
||||
};
|
||||
var dialogManageSynchronization = new Extension("dialogManageSynchronization", 'Dialog "Manage synchronization"');
|
||||
dialogManageSynchronization.settingsBlock = '<p>Populates the "Manage synchronization" dialog box.</p>';
|
||||
|
||||
var extensionMgr = undefined;
|
||||
dialogManageSynchronization.onExtensionMgrCreated = function(extensionMgrParameter) {
|
||||
|
@ -2,15 +2,13 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"toMarkdown",
|
||||
"config",
|
||||
], function($, _, utils, toMarkdown) {
|
||||
], function($, _, utils, Extension, toMarkdown) {
|
||||
|
||||
var dialogOpenHarddrive = {
|
||||
extensionId: "dialogOpenHarddrive",
|
||||
extensionName: 'Dialog "Open from"',
|
||||
settingsBloc: '<p>Handles the "Import from hard drive" and the "Convert HTML to Markdown" dialog boxes.</p>'
|
||||
};
|
||||
var dialogOpenHarddrive = new Extension("dialogOpenHarddrive", 'Dialog "Open from"');
|
||||
dialogOpenHarddrive.settingsBlock = '<p>Handles the "Import from hard drive" and the "Convert HTML to Markdown" dialog boxes.</p>';
|
||||
|
||||
var fileMgr = undefined;
|
||||
dialogOpenHarddrive.onFileMgrCreated = function(fileMgrParameter) {
|
||||
|
@ -2,20 +2,18 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"mousetrap",
|
||||
"fileSystem",
|
||||
"text!html/documentSelectorSettingsBloc.html",
|
||||
], function($, _, utils, mousetrap, fileSystem, documentSelectorSettingsBlocHTML) {
|
||||
"text!html/documentSelectorSettingsBlock.html",
|
||||
], function($, _, utils, Extension, mousetrap, fileSystem, documentSelectorSettingsBlockHTML) {
|
||||
|
||||
var documentSelector = {
|
||||
extensionId: "documentSelector",
|
||||
extensionName: "Document Selector",
|
||||
defaultConfig: {
|
||||
orderBy: "title",
|
||||
shortcutPrevious: "Ctrl+[",
|
||||
shortcutNext: "Ctrl+]"
|
||||
},
|
||||
settingsBloc: documentSelectorSettingsBlocHTML
|
||||
var documentSelector = new Extension("documentSelector", 'Document Selector');
|
||||
documentSelector.settingsBlock = documentSelectorSettingsBlockHTML;
|
||||
documentSelector.defaultConfig = {
|
||||
orderBy: "title",
|
||||
shortcutPrevious: "Ctrl+[",
|
||||
shortcutNext: "Ctrl+]"
|
||||
};
|
||||
|
||||
documentSelector.onLoadSettings = function() {
|
||||
@ -148,7 +146,8 @@ define([
|
||||
});
|
||||
|
||||
// Handle key shortcut
|
||||
mousetrap.bind(documentSelector.config.shortcutPrevious.toLowerCase(), function() {
|
||||
var shortcutPrevious = documentSelector.config.shortcutPrevious.toLowerCase();
|
||||
mousetrap.bind(shortcutPrevious, function() {
|
||||
if(shortcutLi === undefined) {
|
||||
$("#file-selector").parent().is(".open") || $(".action-open-file").click();
|
||||
shortcutLi = liMap[selectFileDesc.fileIndex];
|
||||
@ -163,6 +162,7 @@ define([
|
||||
});
|
||||
return false;
|
||||
});
|
||||
var shortcutNext = documentSelector.config.shortcutNext.toLowerCase();
|
||||
mousetrap.bind(documentSelector.config.shortcutNext.toLowerCase(), function() {
|
||||
if(shortcutLi === undefined) {
|
||||
$("#file-selector").parent().is(".open") || $(".action-open-file").click();
|
||||
@ -175,7 +175,14 @@ define([
|
||||
});
|
||||
return false;
|
||||
});
|
||||
mousetrap.bind('ctrl', function() {
|
||||
var delimiter1 = shortcutPrevious.indexOf("+");
|
||||
var shortcutSelect1 = delimiter1 === -1 ? shortcutPrevious : shortcutPrevious.substring(0, delimiter1);
|
||||
var delimiter2 = shortcutNext.indexOf("+");
|
||||
var shortcutSelect2 = delimiter2 === -1 ? shortcutNext : shortcutNext.substring(0, delimiter2);
|
||||
mousetrap.bind([
|
||||
shortcutSelect1,
|
||||
shortcutSelect2
|
||||
], function() {
|
||||
if(shortcutLi !== undefined) {
|
||||
shortcutLi.find("a").click();
|
||||
shortcutLi = undefined;
|
||||
|
@ -1,13 +1,11 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore"
|
||||
], function($, _) {
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
], function($, _, Extension) {
|
||||
|
||||
var documentTitle = {
|
||||
extensionId: "documentTitle",
|
||||
extensionName: "Document Title",
|
||||
settingsBloc: '<p>Responsible for showing the document title in the navigation bar.</p>'
|
||||
};
|
||||
var documentTitle = new Extension("documentTitle", "Document Title");
|
||||
documentTitle.settingsBlock = '<p>Responsible for showing the document title in the navigation bar.</p>';
|
||||
|
||||
var layout = undefined;
|
||||
documentTitle.onLayoutCreated = function(layoutParameter) {
|
||||
|
@ -1,11 +1,9 @@
|
||||
define(function() {
|
||||
define([
|
||||
"classes/Extension",
|
||||
], function(Extension) {
|
||||
|
||||
var emailConverter = {
|
||||
extensionId: "emailConverter",
|
||||
extensionName: "Email Converter",
|
||||
optional: true,
|
||||
settingsBloc: '<p>Converts email adresses in the form <email@example.com> into clickable links.</p>'
|
||||
};
|
||||
var emailConverter = new Extension("emailConverter", "Markdown Email", true);
|
||||
emailConverter.settingsBlock = '<p>Converts email adresses in the form <email@example.com> into clickable links.</p>';
|
||||
|
||||
emailConverter.onEditorConfigure = function(editor) {
|
||||
editor.getConverter().hooks.chain("postConversion", function(text) {
|
||||
|
@ -2,16 +2,13 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"settings",
|
||||
"config",
|
||||
], function($, _, utils, settings) {
|
||||
], function($, _, utils, Extension, settings) {
|
||||
|
||||
var googleAnalytics = {
|
||||
extensionId: "googleAnalytics",
|
||||
extensionName: 'Google Analytics',
|
||||
optional: true,
|
||||
settingsBloc: '<p>Sends anonymous statistics about usage and errors to help improve StackEdit.</p>'
|
||||
};
|
||||
var googleAnalytics = new Extension("googleAnalytics", "Google Analytics", true);
|
||||
googleAnalytics.settingsBlock = '<p>Sends anonymous statistics about usage and errors to help improve StackEdit.</p>';
|
||||
|
||||
var isLoaded = false;
|
||||
var isOffline = false;
|
||||
|
@ -1,17 +1,14 @@
|
||||
define([
|
||||
"utils",
|
||||
"text!html/markdownExtraSettingsBloc.html",
|
||||
"classes/Extension",
|
||||
"text!html/markdownExtraSettingsBlock.html",
|
||||
"libs/Markdown.Extra",
|
||||
], function(utils, markdownExtraSettingsBlocHTML) {
|
||||
], function(utils, Extension, markdownExtraSettingsBlockHTML) {
|
||||
|
||||
var markdownExtra = {
|
||||
extensionId: "markdownExtra",
|
||||
extensionName: "Markdown Extra",
|
||||
optional: true,
|
||||
defaultConfig: {
|
||||
prettify: true
|
||||
},
|
||||
settingsBloc: markdownExtraSettingsBlocHTML
|
||||
var markdownExtra = new Extension("markdownExtra", "Markdown Extra", true);
|
||||
markdownExtra.settingsBlock = markdownExtraSettingsBlockHTML;
|
||||
markdownExtra.defaultConfig = {
|
||||
prettify: true
|
||||
};
|
||||
|
||||
markdownExtra.onLoadSettings = function() {
|
100
js/extensions/markdownFootnotes.js
Normal file
100
js/extensions/markdownFootnotes.js
Normal file
@ -0,0 +1,100 @@
|
||||
define([
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
], function(_, utils, Extension) {
|
||||
|
||||
var markdownFootnotes = new Extension("markdownFootnotes", "Markdown Footnotes", true);
|
||||
markdownFootnotes.settingsBlock = '<p>Adds support for Markdown footnotes.</p>';
|
||||
|
||||
var inlineTags = new RegExp([
|
||||
'^(<\\/?(a|abbr|acronym|applet|area|b|basefont|',
|
||||
'bdo|big|button|cite|code|del|dfn|em|figcaption|',
|
||||
'font|i|iframe|img|input|ins|kbd|label|map|',
|
||||
'mark|meter|object|param|progress|q|ruby|rp|rt|s|',
|
||||
'samp|script|select|small|span|strike|strong|',
|
||||
'sub|sup|textarea|time|tt|u|var|wbr)[^>]*>|',
|
||||
'<(br)\\s?\\/?>)$'
|
||||
].join(''), 'i');
|
||||
|
||||
var previousPostConversion = undefined;
|
||||
markdownFootnotes.onEditorConfigure = function(editor) {
|
||||
var converter = editor.getConverter();
|
||||
previousPostConversion = converter.hooks.postConversion;
|
||||
converter.hooks.chain("postNormalization", _StripFootnoteDefinitions);
|
||||
converter.hooks.chain("postBlockGamut", _DoFootnotes);
|
||||
converter.hooks.chain("postConversion", _PrintFootnotes);
|
||||
};
|
||||
|
||||
var footnotes = undefined;
|
||||
var usedFootnotes = undefined;
|
||||
function _StripFootnoteDefinitions(text) {
|
||||
footnotes = {};
|
||||
usedFootnotes = [];
|
||||
|
||||
text = text.replace(/\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?(.*?)\n{1,2}((?=\n[ ]{0,3}\S)|\Z)/g, function(wholeMatch, m1, m2) {
|
||||
m1 = utils.slugify(m1);
|
||||
m2 += "\n";
|
||||
m2 = m2.replace(/^[ ]{0,3}/gm, "");
|
||||
footnotes[m1] = m2;
|
||||
return "\n";
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
var blockGamutHookCallback = undefined;
|
||||
function _DoFootnotes(text, blockGamutHookCallbackParam) {
|
||||
blockGamutHookCallback = blockGamutHookCallbackParam;
|
||||
var footnoteCounter = 0;
|
||||
text = text.replace(/\[\^(.+?)\]/g, function(wholeMatch, m1) {
|
||||
var id = utils.slugify(m1);
|
||||
var footnote = footnotes[id];
|
||||
if(footnote === undefined) {
|
||||
return "";
|
||||
}
|
||||
footnoteCounter++;
|
||||
usedFootnotes.push(id);
|
||||
return '<a href="#fn:' + id + '" id="fnref:' + id + '" title="See footnote" class="footnote">' + footnoteCounter + '</a>';
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function _PrintFootnotes(text) {
|
||||
if(usedFootnotes.length === 0) {
|
||||
return text;
|
||||
}
|
||||
|
||||
_.each(footnotes, function(footnote, id) {
|
||||
var formattedfootnote = blockGamutHookCallback(footnote);
|
||||
formattedfootnote = unescapeSpecialChars(formattedfootnote);
|
||||
formattedfootnote = formattedfootnote.replace(/~D/g, "$$").replace(/~T/g, "~");
|
||||
formattedfootnote = previousPostConversion(formattedfootnote);
|
||||
formattedfootnote = formattedfootnote.replace(/<[^>]*>?/gi, function(tag) {
|
||||
return tag.match(inlineTags) ? tag : '';
|
||||
});
|
||||
footnotes[id] = formattedfootnote;
|
||||
});
|
||||
|
||||
text += '\n\n<div class="footnotes">\n<hr>\n<ol>\n\n';
|
||||
_.each(usedFootnotes, function(id) {
|
||||
var footnote = footnotes[id];
|
||||
text += '<li id="fn:' + id + '">' + footnote + ' <a href="#fnref:' + id + '" title="Return to article" class="reversefootnote">↩</a></li>\n\n';
|
||||
});
|
||||
text += '</ol>\n</div>';
|
||||
return text;
|
||||
}
|
||||
|
||||
// Duplicated from PageDown converter
|
||||
function unescapeSpecialChars(text) {
|
||||
// Swap back in all the special characters we've hidden.
|
||||
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
|
||||
var charCodeToReplace = parseInt(m1);
|
||||
return String.fromCharCode(charCodeToReplace);
|
||||
});
|
||||
return text;
|
||||
}
|
||||
|
||||
return markdownFootnotes;
|
||||
});
|
@ -1,22 +1,65 @@
|
||||
define([
|
||||
"libs/MathJax"
|
||||
], function() {
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"text!html/mathJaxSettingsBlock.html",
|
||||
"libs/MathJax",
|
||||
], function(utils, Extension, mathJaxSettingsBlockHTML) {
|
||||
|
||||
var mathJax = {
|
||||
extensionId: "mathJax",
|
||||
extensionName: "MathJax",
|
||||
optional: true,
|
||||
settingsBloc: '<p>Allows StackEdit to interpret LaTex mathematical expressions.</p>'
|
||||
};
|
||||
var mathJax = new Extension("mathJax", "MathJax", true);
|
||||
mathJax.settingsBlock = mathJaxSettingsBlockHTML;
|
||||
mathJax.defaultConfig = {
|
||||
tex: "{}",
|
||||
tex2jax: '{ inlineMath: [["$","$"],["\\\\(","\\\\)"]], displayMath: [["$$","$$"],["\\[","\\]"]], processEscapes: true }'
|
||||
};
|
||||
|
||||
mathJax.onLoadSettings = function() {
|
||||
utils.setInputValue("#input-mathjax-config-tex", mathJax.config.tex);
|
||||
utils.setInputValue("#input-mathjax-config-tex2jax", mathJax.config.tex2jax);
|
||||
};
|
||||
|
||||
mathJax.onSaveSettings = function(newConfig, event) {
|
||||
newConfig.tex = utils.getInputJsValue("#input-mathjax-config-tex", event);
|
||||
newConfig.tex2jax = utils.getInputJsValue("#input-mathjax-config-tex2jax", event);
|
||||
};
|
||||
|
||||
mathJax.onReady = function() {
|
||||
MathJax.Hub.Config({"HTML-CSS": {preferredFont: "TeX",availableFonts: ["STIX", "TeX"],linebreaks: {automatic: true},EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50), imageFont: null},
|
||||
tex2jax: {inlineMath: [["$", "$"], ["\\\\(", "\\\\)"]],displayMath: [["$$", "$$"], ["\\[", "\\]"]],processEscapes: true,ignoreClass: "tex2jax_ignore|dno"},
|
||||
TeX: {noUndefined: {attributes: {mathcolor: "red",mathbackground: "#FFEEEE",mathsize: "90%"}},
|
||||
Safe: {allow: {URLs: "safe",classes: "safe",cssIDs: "safe",styles: "safe",fontsize: "all"}}},
|
||||
messageStyle: "none"
|
||||
});
|
||||
};
|
||||
mathJax.onReady = function() {
|
||||
eval("var tex = " + mathJax.config.tex);
|
||||
eval("var tex2jax = " + mathJax.config.tex2jax);
|
||||
MathJax.Hub.Config({
|
||||
"HTML-CSS": {
|
||||
preferredFont: "TeX",
|
||||
availableFonts: [
|
||||
"STIX",
|
||||
"TeX"
|
||||
],
|
||||
linebreaks: {
|
||||
automatic: true
|
||||
},
|
||||
EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50),
|
||||
imageFont: null
|
||||
},
|
||||
tex2jax: tex2jax,
|
||||
TeX: $.extend({
|
||||
noUndefined: {
|
||||
attributes: {
|
||||
mathcolor: "red",
|
||||
mathbackground: "#FFEEEE",
|
||||
mathsize: "90%"
|
||||
}
|
||||
},
|
||||
Safe: {
|
||||
allow: {
|
||||
URLs: "safe",
|
||||
classes: "safe",
|
||||
cssIDs: "safe",
|
||||
styles: "safe",
|
||||
fontsize: "all"
|
||||
}
|
||||
}
|
||||
}, tex),
|
||||
messageStyle: "none"
|
||||
});
|
||||
};
|
||||
|
||||
var ready = false; // true after initial typeset is complete
|
||||
var pending = false; // true when MathJax has been requested
|
||||
|
@ -2,17 +2,15 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Extension",
|
||||
"jgrowl",
|
||||
"text!html/notificationsSettingsBloc.html",
|
||||
], function($, _, utils, jGrowl, notificationsSettingsBlocHTML) {
|
||||
"text!html/notificationsSettingsBlock.html",
|
||||
], function($, _, utils, Extension, jGrowl, notificationsSettingsBlockHTML) {
|
||||
|
||||
var notifications = {
|
||||
extensionId: "notifications",
|
||||
extensionName: "Notifications",
|
||||
defaultConfig: {
|
||||
timeout: 8000
|
||||
},
|
||||
settingsBloc: notificationsSettingsBlocHTML
|
||||
var notifications = new Extension("notifications", "Notifications");
|
||||
notifications.settingsBlock = notificationsSettingsBlockHTML;
|
||||
notifications.defaultConfig = {
|
||||
timeout: 8000
|
||||
};
|
||||
|
||||
notifications.onLoadSettings = function() {
|
||||
|
@ -1,17 +1,14 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"text!html/scrollLinkSettingsBloc.html",
|
||||
"classes/Extension",
|
||||
"text!html/scrollLinkSettingsBlock.html",
|
||||
"libs/css_browser_selector",
|
||||
"libs/jquery.mousewheel"
|
||||
], function($, _, scrollLinkSettingsBlocHTML) {
|
||||
], function($, _, Extension, scrollLinkSettingsBlockHTML) {
|
||||
|
||||
var scrollLink = {
|
||||
extensionId: "scrollLink",
|
||||
extensionName: "Scroll Link",
|
||||
optional: true,
|
||||
settingsBloc: scrollLinkSettingsBlocHTML
|
||||
};
|
||||
var scrollLink = new Extension("scrollLink", "Scroll Link", true);
|
||||
scrollLink.settingsBlock = scrollLinkSettingsBlockHTML;
|
||||
|
||||
var mdSectionList = [];
|
||||
var htmlSectionList = [];
|
||||
|
@ -2,17 +2,14 @@ define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"utils",
|
||||
"text!html/tocSettingsBloc.html",
|
||||
], function($, _, utils, tocSettingsBlocHTML) {
|
||||
"classes/Extension",
|
||||
"text!html/tocSettingsBlock.html",
|
||||
], function($, _, utils, Extension, tocSettingsBlockHTML) {
|
||||
|
||||
var toc = {
|
||||
extensionId: "toc",
|
||||
extensionName: "Table of Content",
|
||||
optional: true,
|
||||
defaultConfig: {
|
||||
marker: "\\[(TOC|toc)\\]"
|
||||
},
|
||||
settingsBloc: tocSettingsBlocHTML
|
||||
var toc = new Extension("toc", "Markdown Table of Content", true);
|
||||
toc.settingsBlock = tocSettingsBlockHTML;
|
||||
toc.defaultConfig = {
|
||||
marker: "\\[(TOC|toc)\\]"
|
||||
};
|
||||
|
||||
toc.onLoadSettings = function() {
|
||||
@ -21,7 +18,7 @@ define([
|
||||
|
||||
toc.onSaveSettings = function(newConfig, event) {
|
||||
newConfig.marker = utils.getInputRegExpValue("#input-toc-marker", event);
|
||||
};
|
||||
};
|
||||
|
||||
// TOC element description
|
||||
function TocElement(tagName, anchor, text) {
|
||||
|
@ -1,13 +1,11 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore"
|
||||
], function($, _) {
|
||||
"underscore",
|
||||
"classes/Extension",
|
||||
], function($, _, Extension) {
|
||||
|
||||
var workingIndicator = {
|
||||
extensionId: "workingIndicator",
|
||||
extensionName: "Working Indicator",
|
||||
settingsBloc: '<p>Displays an animated image when a network operation is running.</p>'
|
||||
};
|
||||
var workingIndicator = new Extension("workingIndicator", "Working Indicator");
|
||||
workingIndicator.settingsBlock = '<p>Displays an animated image when a network operation is running.</p>';
|
||||
|
||||
workingIndicator.onAsyncRunning = function(isRunning) {
|
||||
if(isRunning === false) {
|
||||
|
@ -1,8 +1,9 @@
|
||||
define([
|
||||
"jquery",
|
||||
"core",
|
||||
"settings",
|
||||
"classes/AsyncTask"
|
||||
], function($, core, AsyncTask) {
|
||||
], function($, core, settings, AsyncTask) {
|
||||
|
||||
var sshHelper = {};
|
||||
|
||||
@ -21,7 +22,7 @@ define([
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
task.onRun(function() {
|
||||
var url = SSH_PROXY_URL + "upload";
|
||||
var url = settings.sshProxy + "upload";
|
||||
var data = {
|
||||
host: host,
|
||||
port: port,
|
||||
|
11
js/html/buttonHtmlCodeSettingsBlock.html
Normal file
11
js/html/buttonHtmlCodeSettingsBlock.html
Normal file
@ -0,0 +1,11 @@
|
||||
<p>Adds a "HTML code" button over the preview.</p>
|
||||
<div class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="textarea-html-code-template">Template
|
||||
<a href="#" class="tooltip-template">(?)</a>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<textarea id="textarea-html-code-template"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -8,3 +8,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-block pull-right"><a target="_blank" href="https://github.com/jmcmanus/pagedown-extra">More info</a></span>
|
18
js/html/mathJaxSettingsBlock.html
Normal file
18
js/html/mathJaxSettingsBlock.html
Normal file
@ -0,0 +1,18 @@
|
||||
<p>Allows StackEdit to interpret LaTeX mathematical expressions.</p>
|
||||
<div class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label class="control-label"
|
||||
for="input-mathjax-config-tex">TeX configuration</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-mathjax-config-tex">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label"
|
||||
for="input-mathjax-config-tex2jax">tex2jax configuration</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-mathjax-config-tex2jax">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-block pull-right"><a target="_blank" href="http://docs.mathjax.org/en/latest/options/">More info</a></span>
|
@ -2,12 +2,12 @@
|
||||
<div class="accordion-heading">
|
||||
<label class="checkbox pull-right"> <input
|
||||
id="input-enable-extension-<%= extensionId %>" type="checkbox"<%
|
||||
if(!optional) print('disabled') %>> enabled
|
||||
if(!isOptional) print('disabled') %>> enabled
|
||||
</label> <a data-toggle="collapse"
|
||||
data-parent="#accordion-extensions" class="accordion-toggle"
|
||||
href="#collapse-<%= extensionId %>"> <%= extensionName %> </a>
|
||||
</div>
|
||||
<div id="collapse-<%= extensionId %>" class="accordion-body collapse">
|
||||
<div class="accordion-inner"><%= settingsBloc %></div>
|
||||
<div class="accordion-inner"><%= settingsBlock %></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@ Available variables:
|
||||
<li><b>documentMarkdown</b>: document in Markdown format</li>
|
||||
<li><b>documentHTML</b>: document in HTML format</li>
|
||||
<li><b>publishAttributes</b>: attributes of the publish location
|
||||
(undefined when using "Save")</li>
|
||||
(undefined if not publishing)</li>
|
||||
</ul>
|
||||
Examples:
|
||||
<br />
|
||||
@ -13,8 +13,10 @@ Examples:
|
||||
<br />
|
||||
<div><%- documentHTML %></div>
|
||||
<br />
|
||||
<% if(publishAttributes.provider == "github")
|
||||
print(documentMarkdown); %>
|
||||
<%<br />
|
||||
if(publishAttributes.provider.providerId == "github")
|
||||
print(documentMarkdown);<br />
|
||||
%>
|
||||
<br />
|
||||
<br />
|
||||
<a target="_blank" href="http://underscorejs.org/#template">More
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
// Remove one level of indentation from text. Indent is 4 spaces.
|
||||
function outdent(text) {
|
||||
return text.replace(new RegExp('^(\\t|[ ]{1,4})', 'gm'), '');
|
||||
return text.replace(new RegExp('^(\\t|[ ]{1,4})', 'gm'), '');
|
||||
}
|
||||
|
||||
function contains(str, substr) {
|
||||
@ -115,15 +115,15 @@
|
||||
function unescapeSpecialChars(text) {
|
||||
// Swap back in all the special characters we've hidden.
|
||||
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
|
||||
var charCodeToReplace = parseInt(m1);
|
||||
return String.fromCharCode(charCodeToReplace);
|
||||
});
|
||||
var charCodeToReplace = parseInt(m1);
|
||||
return String.fromCharCode(charCodeToReplace);
|
||||
});
|
||||
return text;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Markdown.Extra *
|
||||
****************************************************************************/
|
||||
* Markdown.Extra *
|
||||
****************************************************************************/
|
||||
|
||||
Markdown.Extra = function() {
|
||||
// For converting internal markdown (in tables for instance).
|
||||
@ -160,19 +160,19 @@
|
||||
options = options || {};
|
||||
options.extensions = options.extensions || ["all"];
|
||||
if (contains(options.extensions, "all")) {
|
||||
options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"];
|
||||
options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"];
|
||||
}
|
||||
if (contains(options.extensions, "attr_list")) {
|
||||
postNormalizationTransformations.push("hashFcbAttributeBlocks");
|
||||
preBlockGamutTransformations.push("hashHeaderAttributeBlocks");
|
||||
postConversionTransformations.push("applyAttributeBlocks");
|
||||
postNormalizationTransformations.push("hashFcbAttributeBlocks");
|
||||
preBlockGamutTransformations.push("hashHeaderAttributeBlocks");
|
||||
postConversionTransformations.push("applyAttributeBlocks");
|
||||
extra.attributeBlocks = true;
|
||||
}
|
||||
if (contains(options.extensions, "tables")) {
|
||||
preBlockGamutTransformations.push("tables");
|
||||
preBlockGamutTransformations.push("tables");
|
||||
}
|
||||
if (contains(options.extensions, "fenced_code_gfm")) {
|
||||
postNormalizationTransformations.push("fencedCodeBlocks");
|
||||
postNormalizationTransformations.push("fencedCodeBlocks");
|
||||
}
|
||||
if (contains(options.extensions, "def_list")) {
|
||||
preBlockGamutTransformations.push("definitionLists");
|
||||
@ -183,14 +183,14 @@
|
||||
});
|
||||
|
||||
converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) {
|
||||
// Keep a reference to the block gamut callback to run recursively
|
||||
// Keep a reference to the block gamut callback to run recursively
|
||||
extra.blockGamutHookCallback = blockGamutHookCallback;
|
||||
text = processEscapes(text);
|
||||
return extra.doTransform(preBlockGamutTransformations, text) + '\n';
|
||||
});
|
||||
|
||||
// Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks
|
||||
extra.previousPostConversion = converter.hooks.postConversion;
|
||||
extra.previousPostConversion = converter.hooks.postConversion;
|
||||
converter.hooks.chain("postConversion", function(text) {
|
||||
text = extra.doTransform(postConversionTransformations, text);
|
||||
// Clear state vars that may use unnecessary memory
|
||||
@ -215,9 +215,9 @@
|
||||
|
||||
// Do transformations
|
||||
Markdown.Extra.prototype.doTransform = function(transformations, text) {
|
||||
for(var i = 0; i < transformations.length; i++)
|
||||
text = this[transformations[i]](text);
|
||||
return text;
|
||||
for(var i = 0; i < transformations.length; i++)
|
||||
text = this[transformations[i]](text);
|
||||
return text;
|
||||
};
|
||||
|
||||
// Return a placeholder containing a key, which is the block's index in the
|
||||
@ -253,21 +253,21 @@
|
||||
// Extract headers attribute blocks, move them above the element they will be
|
||||
// applied to, and hash them for later.
|
||||
Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) {
|
||||
// TODO: use sentinels. Should we just add/remove them in doConversion?
|
||||
// TODO: better matches for id / class attributes
|
||||
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
||||
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
|
||||
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
|
||||
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
|
||||
|
||||
var self = this;
|
||||
function attributeCallback(wholeMatch, pre, attr) {
|
||||
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
|
||||
}
|
||||
// TODO: use sentinels. Should we just add/remove them in doConversion?
|
||||
// TODO: better matches for id / class attributes
|
||||
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
||||
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
|
||||
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
|
||||
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
|
||||
|
||||
var self = this;
|
||||
function attributeCallback(wholeMatch, pre, attr) {
|
||||
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
|
||||
}
|
||||
|
||||
text = text.replace(hdrAttributesA, attributeCallback); // ## headers
|
||||
text = text.replace(hdrAttributesB, attributeCallback); // underline headers
|
||||
return text;
|
||||
text = text.replace(hdrAttributesA, attributeCallback); // ## headers
|
||||
text = text.replace(hdrAttributesB, attributeCallback); // underline headers
|
||||
return text;
|
||||
};
|
||||
|
||||
// Extract FCB attribute blocks, move them above the element they will be
|
||||
@ -275,14 +275,14 @@
|
||||
Markdown.Extra.prototype.hashFcbAttributeBlocks = function(text) {
|
||||
// TODO: use sentinels. Should we just add/remove them in doConversion?
|
||||
// TODO: better matches for id / class attributes
|
||||
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
||||
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
||||
var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
|
||||
"(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm");
|
||||
|
||||
var self = this;
|
||||
function attributeCallback(wholeMatch, pre, attr) {
|
||||
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
|
||||
}
|
||||
var self = this;
|
||||
function attributeCallback(wholeMatch, pre, attr) {
|
||||
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
|
||||
}
|
||||
|
||||
return text.replace(fcbAttributes, attributeCallback);
|
||||
};
|
||||
|
@ -1,15 +1,16 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"classes/Provider",
|
||||
"core",
|
||||
"providers/gplusProvider"
|
||||
], function($, _, core) {
|
||||
], function($, _, Provider, core) {
|
||||
|
||||
var mediaImporter = {};
|
||||
|
||||
// Create a map with providerId: providerModule
|
||||
var providerMap = _.chain(arguments).map(function(argument) {
|
||||
return argument && argument.providerId && [
|
||||
return argument instanceof Provider && [
|
||||
argument.providerId,
|
||||
argument
|
||||
];
|
||||
|
@ -1,19 +1,15 @@
|
||||
define([
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"helpers/googleHelper"
|
||||
], function(_, utils, googleHelper) {
|
||||
], function(_, utils, Provider, googleHelper) {
|
||||
|
||||
var PROVIDER_BLOGGER = "blogger";
|
||||
|
||||
var bloggerProvider = {
|
||||
providerId: PROVIDER_BLOGGER,
|
||||
providerName: "Blogger",
|
||||
defaultPublishFormat: "html",
|
||||
publishPreferencesInputIds: [
|
||||
"blogger-url"
|
||||
]
|
||||
};
|
||||
var bloggerProvider = new Provider("blogger", "Blogger");
|
||||
bloggerProvider.defaultPublishFormat = "html";
|
||||
bloggerProvider.publishPreferencesInputIds = [
|
||||
"blogger-url"
|
||||
];
|
||||
|
||||
bloggerProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
googleHelper.uploadBlogger(publishAttributes.blogUrl, publishAttributes.blogId, publishAttributes.postId, publishAttributes.labelList, title, content, function(error, blogId, postId) {
|
||||
|
@ -1,17 +1,14 @@
|
||||
define([
|
||||
"jquery",
|
||||
"core",
|
||||
"classes/Provider",
|
||||
"classes/AsyncTask"
|
||||
], function($, core, AsyncTask) {
|
||||
], function($, core, Provider, AsyncTask) {
|
||||
|
||||
var PROVIDER_DOWNLOAD = "download";
|
||||
|
||||
var downloadProvider = {
|
||||
providerId: PROVIDER_DOWNLOAD,
|
||||
sharingAttributes: [
|
||||
"url"
|
||||
]
|
||||
};
|
||||
var downloadProvider = new Provider("download");
|
||||
downloadProvider.sharingAttributes = [
|
||||
"url"
|
||||
];
|
||||
|
||||
downloadProvider.importPublic = function(importParameters, callback) {
|
||||
var title = undefined;
|
||||
|
@ -1,18 +1,16 @@
|
||||
define([
|
||||
"underscore",
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"extensionMgr",
|
||||
"fileMgr",
|
||||
"helpers/dropboxHelper"
|
||||
], function(_, utils, extensionMgr, fileMgr, dropboxHelper) {
|
||||
], function(_, utils, Provider, extensionMgr, fileMgr, dropboxHelper) {
|
||||
|
||||
var PROVIDER_DROPBOX = "dropbox";
|
||||
|
||||
var dropboxProvider = {
|
||||
providerId: PROVIDER_DROPBOX,
|
||||
providerName: "Dropbox",
|
||||
defaultPublishFormat: "template"
|
||||
};
|
||||
var dropboxProvider = new Provider(PROVIDER_DROPBOX, "Dropbox");
|
||||
dropboxProvider.defaultPublishFormat = "template";
|
||||
|
||||
function checkPath(path) {
|
||||
if(path === undefined) {
|
||||
|
@ -2,22 +2,20 @@ define([
|
||||
"underscore",
|
||||
"core",
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"settings",
|
||||
"extensionMgr",
|
||||
"fileMgr",
|
||||
"helpers/googleHelper"
|
||||
], function(_, core, utils, settings, extensionMgr, fileMgr, googleHelper) {
|
||||
], function(_, core, utils, Provider, settings, extensionMgr, fileMgr, googleHelper) {
|
||||
|
||||
var PROVIDER_GDRIVE = "gdrive";
|
||||
|
||||
var gdriveProvider = {
|
||||
providerId: PROVIDER_GDRIVE,
|
||||
providerName: "Google Drive",
|
||||
defaultPublishFormat: "template",
|
||||
exportPreferencesInputIds: [
|
||||
"gdrive-parentid"
|
||||
]
|
||||
};
|
||||
var gdriveProvider = new Provider(PROVIDER_GDRIVE, "Google Drive");
|
||||
gdriveProvider.defaultPublishFormat = "template";
|
||||
gdriveProvider.exportPreferencesInputIds = [
|
||||
"gdrive-parentid"
|
||||
];
|
||||
|
||||
function createSyncIndex(id) {
|
||||
return "sync." + PROVIDER_GDRIVE + "." + id;
|
||||
|
@ -1,18 +1,14 @@
|
||||
define([
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"helpers/githubHelper"
|
||||
], function(utils, githubHelper) {
|
||||
], function(utils, Provider, githubHelper) {
|
||||
|
||||
var PROVIDER_GIST = "gist";
|
||||
|
||||
var gistProvider = {
|
||||
providerId: PROVIDER_GIST,
|
||||
providerName: "Gist",
|
||||
sharingAttributes: [
|
||||
"gistId",
|
||||
"filename"
|
||||
]
|
||||
};
|
||||
var gistProvider = new Provider("gist", "Gist");
|
||||
gistProvider.sharingAttributes = [
|
||||
"gistId",
|
||||
"filename"
|
||||
];
|
||||
|
||||
gistProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
githubHelper.uploadGist(publishAttributes.gistId, publishAttributes.filename, publishAttributes.isPublic, title, content, function(error, gistId) {
|
||||
|
@ -1,19 +1,15 @@
|
||||
define([
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"settings",
|
||||
"helpers/githubHelper"
|
||||
], function(utils, settings, githubHelper) {
|
||||
], function(utils, Provider, settings, githubHelper) {
|
||||
|
||||
var PROVIDER_GITHUB = "github";
|
||||
|
||||
var githubProvider = {
|
||||
providerId: PROVIDER_GITHUB,
|
||||
providerName: "GitHub",
|
||||
publishPreferencesInputIds: [
|
||||
"github-reponame",
|
||||
"github-branch"
|
||||
]
|
||||
};
|
||||
var githubProvider = new Provider("github", "GitHub");
|
||||
githubProvider.publishPreferencesInputIds = [
|
||||
"github-reponame",
|
||||
"github-branch"
|
||||
];
|
||||
|
||||
githubProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
var commitMsg = settings.commitMsg;
|
||||
|
@ -2,16 +2,14 @@ define([
|
||||
"underscore",
|
||||
"core",
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"extensionMgr",
|
||||
"helpers/googleHelper"
|
||||
], function(_, core, utils, extensionMgr, googleHelper) {
|
||||
], function(_, core, utils, Provider, extensionMgr, googleHelper) {
|
||||
|
||||
var PROVIDER_GPLUS = "gplus";
|
||||
|
||||
var gplusProvider = {
|
||||
providerId: PROVIDER_GPLUS,
|
||||
providerName: "Google+"
|
||||
};
|
||||
var gplusProvider = new Provider(PROVIDER_GPLUS, "Google+");
|
||||
|
||||
function getThumbnailUrl(doc, size) {
|
||||
var result = undefined;
|
||||
|
@ -1,20 +1,16 @@
|
||||
define([
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"helpers/sshHelper"
|
||||
], function(utils, sshHelper) {
|
||||
], function(utils, Provider, sshHelper) {
|
||||
|
||||
var PROVIDER_SSH = "ssh";
|
||||
|
||||
var sshProvider = {
|
||||
providerId: PROVIDER_SSH,
|
||||
providerName: "SSH server",
|
||||
publishPreferencesInputIds: [
|
||||
"ssh-host",
|
||||
"ssh-port",
|
||||
"ssh-username",
|
||||
"ssh-password"
|
||||
]
|
||||
};
|
||||
var sshProvider = new Provider("ssh", "SSH server");
|
||||
sshProvider.publishPreferencesInputIds = [
|
||||
"ssh-host",
|
||||
"ssh-port",
|
||||
"ssh-username",
|
||||
"ssh-password"
|
||||
];
|
||||
|
||||
sshProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
sshHelper.upload(publishAttributes.host, publishAttributes.port, publishAttributes.username, publishAttributes.password, publishAttributes.path, title, content, callback);
|
||||
|
@ -1,17 +1,13 @@
|
||||
define([
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"helpers/tumblrHelper"
|
||||
], function(utils, tumblrHelper) {
|
||||
], function(utils, Provider, tumblrHelper) {
|
||||
|
||||
var PROVIDER_TUMBLR = "tumblr";
|
||||
|
||||
var tumblrProvider = {
|
||||
providerId: PROVIDER_TUMBLR,
|
||||
providerName: "Tumblr",
|
||||
publishPreferencesInputIds: [
|
||||
"tumblr-hostname"
|
||||
]
|
||||
};
|
||||
var tumblrProvider = new Provider("tumblr", "Tumblr");
|
||||
tumblrProvider.publishPreferencesInputIds = [
|
||||
"tumblr-hostname"
|
||||
];
|
||||
|
||||
tumblrProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
tumblrHelper.upload(publishAttributes.blogHostname, publishAttributes.postId, publishAttributes.tags, publishAttributes.format == "markdown" ? "markdown" : "html", title, content, function(error, postId) {
|
||||
|
@ -1,18 +1,14 @@
|
||||
define([
|
||||
"utils",
|
||||
"classes/Provider",
|
||||
"helpers/wordpressHelper"
|
||||
], function(utils, wordpressHelper) {
|
||||
], function(utils, Provider, wordpressHelper) {
|
||||
|
||||
var PROVIDER_WORDPRESS = "wordpress";
|
||||
|
||||
var wordpressProvider = {
|
||||
providerId: PROVIDER_WORDPRESS,
|
||||
providerName: "WordPress",
|
||||
defaultPublishFormat: "html",
|
||||
publishPreferencesInputIds: [
|
||||
"wordpress-site"
|
||||
]
|
||||
};
|
||||
var wordpressProvider = new Provider("wordpress", "WordPress");
|
||||
wordpressProvider.defaultPublishFormat = "html";
|
||||
wordpressProvider.publishPreferencesInputIds = [
|
||||
"wordpress-site"
|
||||
];
|
||||
|
||||
wordpressProvider.publish = function(publishAttributes, title, content, callback) {
|
||||
wordpressHelper.upload(publishAttributes.site, publishAttributes.postId, publishAttributes.tags, title, content, function(error, postId) {
|
||||
|
@ -8,6 +8,7 @@ define([
|
||||
"fileSystem",
|
||||
"fileMgr",
|
||||
"sharing",
|
||||
"classes/Provider",
|
||||
"providers/bloggerProvider",
|
||||
"providers/dropboxProvider",
|
||||
"providers/gistProvider",
|
||||
@ -16,13 +17,13 @@ define([
|
||||
"providers/sshProvider",
|
||||
"providers/tumblrProvider",
|
||||
"providers/wordpressProvider"
|
||||
], function($, _, core, utils, settings, extensionMgr, fileSystem, fileMgr, sharing) {
|
||||
], function($, _, core, utils, settings, extensionMgr, fileSystem, fileMgr, sharing, Provider) {
|
||||
|
||||
var publisher = {};
|
||||
|
||||
// Create a map with providerId: providerModule
|
||||
var providerMap = _.chain(arguments).map(function(argument) {
|
||||
return argument && argument.providerId && [
|
||||
return argument instanceof Provider && [
|
||||
argument.providerId,
|
||||
argument
|
||||
];
|
||||
|
@ -6,15 +6,16 @@ define([
|
||||
"extensionMgr",
|
||||
"fileMgr",
|
||||
"classes/AsyncTask",
|
||||
"classes/Provider",
|
||||
"providers/downloadProvider",
|
||||
"providers/gistProvider"
|
||||
], function($, _, core, utils, extensionMgr, fileMgr, AsyncTask) {
|
||||
], function($, _, core, utils, extensionMgr, fileMgr, AsyncTask, Provider) {
|
||||
|
||||
var sharing = {};
|
||||
|
||||
// Create a map with providerId: providerModule
|
||||
var providerMap = _.chain(arguments).map(function(argument) {
|
||||
return argument && argument.providerId && [
|
||||
return argument instanceof Provider && [
|
||||
argument.providerId,
|
||||
argument
|
||||
];
|
||||
|
@ -6,15 +6,16 @@ define([
|
||||
"extensionMgr",
|
||||
"fileSystem",
|
||||
"fileMgr",
|
||||
"classes/Provider",
|
||||
"providers/dropboxProvider",
|
||||
"providers/gdriveProvider"
|
||||
], function($, _, core, utils, extensionMgr, fileSystem, fileMgr) {
|
||||
], function($, _, core, utils, extensionMgr, fileSystem, fileMgr, Provider) {
|
||||
|
||||
var synchronizer = {};
|
||||
|
||||
// Create a map with providerId: providerModule
|
||||
var providerMap = _.chain(arguments).map(function(argument) {
|
||||
return argument && argument.providerId && [
|
||||
return argument instanceof Provider && [
|
||||
argument.providerId,
|
||||
argument
|
||||
];
|
||||
|
17
js/utils.js
17
js/utils.js
@ -95,6 +95,23 @@ define([
|
||||
return value;
|
||||
};
|
||||
|
||||
// Return input value and check that it's a valid JavaScript object
|
||||
utils.getInputJsValue = function(element, event) {
|
||||
element = jqElt(element);
|
||||
var value = utils.getInputTextValue(element, event);
|
||||
if(value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
eval("var test=" + value);
|
||||
}
|
||||
catch(e) {
|
||||
inputError(element, event);
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
// Return checkbox boolean value
|
||||
utils.getInputChecked = function(element) {
|
||||
element = jqElt(element);
|
||||
|
Loading…
Reference in New Issue
Block a user