define([ "jquery", "underscore", "utils", "classes/Extension", "fileSystem", "settings", "text!html/userCustomSettingsBlock.html", ], function($, _, utils, Extension, fileSystem, settings, userCustomSettingsBlockHTML) { var userCustom = new Extension("userCustom", "UserCustom extension", true); userCustom.settingsBlock = userCustomSettingsBlockHTML; userCustom.defaultConfig = { code: "", }; var fileMgr; userCustom.onFileMgrCreated = function(fileMgrParameter) { fileMgr = fileMgrParameter; }; var synchronizer; userCustom.onSynchronizerCreated = function(synchronizerParameter) { synchronizer = synchronizerParameter; }; var publisher; userCustom.onPublisherCreated = function(publisherParameter) { publisher = publisherParameter; }; var eventMgr; userCustom.onEventMgrCreated = function(eventMgrParameter) { eventMgr = eventMgrParameter; }; userCustom.onLoadSettings = function() { utils.setInputValue("#textarea-usercustom-code", userCustom.config.code); }; userCustom.onSaveSettings = function(newConfig, event) { newConfig.code = utils.getInputValue("#textarea-usercustom-code"); try { /*jshint evil: true */ eval(newConfig.code); } catch(e) { eventMgr.onError(e); // Mark the textarea as error utils.getInputTextValue("#textarea-usercustom-code", event, /^$/); } }; userCustom.onInit = function() { try { /*jshint evil: true */ eval(userCustom.config.code); } catch(e) { console.error(e); } }; userCustom.onPagedownConfigure = function (editor) { var thmCounter = { num: 0 }; var excsCounter = { num: 0 }; var environmentMap = { thm: { title: "Theorem" ,counter: thmCounter }, lem: { title: "Lemma" ,counter: thmCounter }, cor: { title: "Corollary" ,counter: thmCounter }, prop: { title: "Property" ,counter: thmCounter }, defn: { title: "Definition" ,counter: thmCounter }, rem: { title: "Remark" ,counter: thmCounter }, prob: { title: "Problem" ,counter: excsCounter }, excs: { title: "Exercise" ,counter: excsCounter }, examp: { title: "Example" ,counter: excsCounter }, proof: { title: "Proof" } }; var converter = editor.getConverter(); // Save the preConversion callbacks stack var preConversion = converter.hooks.preConversion; converter.hooks.preConversion = function (text) { // Change \begin...\end to /begin.../end to avoid MathJax processing text = text.replace(/\\begin{(\w+)}([\s\S]*?)\\end{\1}/g, function (wholeMatch, m1, m2) { if(!environmentMap[m1]) return wholeMatch; // At this stage we need to keep the same number of characters for accurate section parsing return '/begin{' + m1 + '}' + m2 + '/end{' + m1 + '}'; }); // Transform \title and \section into markdown title to take benefit of partial rendering text = text.replace(/\\(\w+){([^\r\n}]+)}/g, function (wholeMatch, m1, m2) { // At this stage we need to keep the same number of characters for accurate section parsing if (m1 == 'section') { // \section{} has to be replaced by 10 chars return '\n### ' + m2 + '\n'; } if (m1 == 'subsection') { // \subsection{} has to be replaced by 13 chars return '\n#### ' + m2 + '\n'; } if (m1 == 'subsubsection') { // \subsubsection{} has to be replaced by 16 chars return '\n##### ' + m2 + '\n'; } if (m1 == 'title') { // \title{} has to be replaced by 8 chars return '\n## ' + m2 + '\n'; } return wholeMatch; }); // We are replacing the preConversion stack, call the other preConversion callbacks from the old stack return preConversion(text); }; converter.hooks.chain("preBlockGamut", function (text, blockGamutHookCallback) { text = text.replace(/\\ref{(\w+):(\d+)}/g, function (wholeMatch, m1, m2) { if(!environmentMap[m1]) return wholeMatch; return '' + environmentMap[m1].title + ' ' + m2 + ''; }); text = text.replace(/\\(author|date){([\s\S]*?)}/g, '