Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2012 UnaMesa Association
/***
|''Name''|CMEditCommands|
|''Description''|Opens a tiddler in edit mode and starts CodeMirror editor.|
|''Version''|0.1.3|
|''Date''|2012-03-13|
|''Status''|''beta''|
|''Source''|https://github.com/pmario/tw.CodeMirrorPlugin|
|''License''|CC-BY-SA|
|''CoreVersion''|2.5|
|''Requires''|zCodeMirrorPlugin|
|''Keywords''|toolbar command code mirror codemirror edit|
!!!Description
<<<
To use this new toolbar command you have to add {{{cmEdit}}} to ToolbarCommands tiddler
eg:
{{{
|~ViewToolbar|tagSearch cmEdit +editTiddler ...
}}}
<<<
!!! History
<<<
* V 0.1.3 2012-03-13
** Added functions to make editor height persistent.
** + bug fixes introduced with V 0.1.2
* V 0.1.1
** Initial release
<<<
!!!Code
***/
//{{{
config.commands.cmEdit = {
text: "cmEdit",
tooltip: "Edit tiddler with CodeMirror editor!",
readOnlyText: "view",
readOnlyTooltip: "View the source of this tiddler using CodeMirror"
};
config.commands.cmSave = {
text: "cmSave",
tooltip: "Save tiddler, when CodeMirror editor is used!",
isEnabled: function(tiddler) {
return (!readOnly);
}
};
config.commands.cmEdit.handler = function(event,src,title)
{
// needed to get the original textarea dirty, after first time editing.
var cmOnChange = function(cmEditor) {
if (!cmEditor.dirty) {
cmEditor.dirty = true;
cmEditor.save();
}
};
// readOnly can't be set by config tidder.
// TODO onChange will need special handling. aka Hijacking if config also contains a onChange
var cmOptions = {
'readOnly': readOnly,
onChange: cmOnChange
};
// define var shortcuts
var cm = config.tools.cm;
var conf = cm.conf;
var tags = [], tl, mode;
// read CodeMirrorConfig tiddler and write to global conf var
cm.init();
var modes = CodeMirror.listModes();
// TODO post to mailing list about it ?! It makes handling the library more difficult.
var mimes = cm.listMimeNames();
// doesn't set tid if title is a shadow tiddler
var tid = store.getTiddler(title);
// set global settings
jQuery.extend(cmOptions, conf['global']);
// shadow tiddlers don't have tags, fields ...
if (tid && tid.fields) {
if (tid.fields['server.content-type'] && mimes.contains(tid.fields['server.content-type'])) {
mode = cm.getModeObject(tid.fields['server.content-type']);
jQuery.extend(cmOptions, conf[mode.name]);
jQuery.extend(cmOptions.mode, mode);
}
if (tid.fields['content-type'] && mimes.contains(tid.fields['content-type'])) {
mode = cm.getModeObject(tid.fields['content-type']);
jQuery.extend(cmOptions, conf[mode.name]);
jQuery.extend(cmOptions.mode, mode);
}
for (var i=0; i < modes.length; i += 1) {
if (conf[modes[i]] && conf[modes[i]].tags) {
tags = conf[modes[i]].tags.split(' ');
tl = tags.length;
// there is no need to know, which tag, was the one, that was found.
// it's important, that one was found.
for (var j=0; j < tid.tags.length; j += 1) {
tags.pushUnique(tid.tags[j]);
}
// if one tag is the same, pushUnique above will eliminate one or more tags.
if ((tl + tid.tags.length) != tags.length) {
jQuery.extend(cmOptions, conf[modes[i]]);
break; // modes.length loop. first found wins.
}
} // if
} // for
if (tid.fields['cm.height']) {
jQuery.extend(cmOptions, {cmHeight: tid.fields['cm.height']});
} // TODO TypeChooser and cmEdit should use the same functions. refactoring needed.
} // if tid
// if no mode was found, init with null -> text/plain
if (!cmOptions.mode) {
jQuery.extend(cmOptions, conf['null']);
}
// call the TW default editor
config.commands.editTiddler.handler.call(this,event,src,title);
// find the default editor
var textArea = jQuery(story.getTiddler(title)).find('textarea[edit=text]');
// create the cm editor
cm.startEditor(textArea, cmOptions);
return false;
};
config.commands.cmSave.handler = function(event,src,title)
{
var text = jQuery(story.getTiddler(title)).find('textarea[edit=text]');
var editor = jQuery(text[0]).data('editor');
if (editor) {editor.save();}
config.commands.saveTiddler.handler.call(this,event,src,title);
return false;
};
//}}}
! CodeMirror
See http://codemirror.net/ for more information.
|''Name''|CodeMirrorPluginInfo|
|''Description''|Documentation for [[zCodeMirrorPlugin]]|
|''Author''|PMario|
|''Source''|https://github.com/pmario/tw.CodeMirrorPlugin|
|''Documentation''|http://codemirror.tiddlyspace.com/|
|''License''|see: [[zCodeMirrorPlugin]]|
|''Keywords''|editro syntax highlighting color code|
!Documentation
!!!! Macros
<<<
The plugin contains some additional macros, to get an overview, which modes are activated.
Modes: {{{<<cmModes>>}}} ... displays the usable modes seen below.
> Modes: <<cmModes>>
MIMEs: {{{<<cmMimes>>}}} ... displays the usable mime types seen below. Same order as modes.
> Modes: <<cmMimes>>
<<<
!!!! Global Settings
<<<
* <<option chkInsertTab>>chkInsertTab option cookie ''should be disabled'' to use CM key-handling. If {{{chkInsertTab}}} is active, keyhandling is hardcoded. {{{extraKeys}}} settings in CodeMirrorConfig are ignored.
* Learn more at ExtraKeysAddOn plugin.
<<<
!!!! StyleSheet
<<<
* The plugin automatically creates a shadow StyleSheetCodeMirror tiddler, that can be adjusted to your needs.
<<<
!! Feedback / Support
Feedback is very welcome at [[TiddlyWiki group|TWGroup]]
!!Examples
<<<
Available Modes: <<cmModes>>
Available MIMEs: <<cmMimes>>
<<<
!!!! Text
<<<
{{{
{{{
This is some plain text!
}}}
}}}
{{{
This is some plain text!
}}}
<<<
!!!! CSS
<<<
{{{
/*{{{*/
.cssClass {
display: block; !important;
}
/*}}}*/
}}}
will render like:
/*{{{*/
.cssClass {
display: block; !important;
}
/*}}}*/
<<<
!!!! XML
<<<
{{{
<!--{{{-->
<html>
<div id='myId' class='dp50'>some text </div>
</html>
<!--}}}-->
}}}
will render like:
<!--{{{-->
<html>
<div id='myId' class='dp50'>some text </div>
</html>
<!--}}}-->
<<<
!!!! Plugin
<<<
{{{
//{{{
(function($) {
config.macros.highlightSyntax = {
var a = b = 0;
// your code here!
}
})(jQuery);
//}}}
}}}
will render like:
//{{{
(function($) {
config.macros.highlightSyntax = {
var a = b = 0;
// your code here!
}
})(jQuery);
//}}}
<<<
!!!! Code sample
<<<
<!--{{{-->
<code class="brush:javascript">
// comment
var a = b = 0;
a = 17;
</code>
<!--}}}-->
will render like
<code class="brush:javascript">
// comment
var a = b = 0;
a = 17;
</code>
<<<
!! Advanced Options
<<<
Guess syntax: <<option chkGuessSyntax>> .. If activated, ~TiddlyWiky <pre> blocks will be rendered according to there block braces, like described obove.
Expert mode: <<option chkExpertSyntax>> .. If activated, additional values below will be used
{{{ {{{ }}} txtShText: <<option txtShText>> eg: 'brush:text'
{{{ /*{{{*/ }}} txtShCss: <<option txtShCss>> eg: 'brush:css'
{{{ //{{{ }}} txtShPlugin: <<option txtShPlugin>> 'brush:js'
{{{ <!--{{{-->> }}} txtShXml: <<option txtShXml>> 'brush:xml'
If you want to change the default values eg for C++, add the following to a [[zzConfig]] tiddler and tag it "systemConfig"
//{{{
config.options.chkGuessSyntax = true;
config.options.chkExpertSyntax = true;
config.options.txtShPlugin = 'brush:clike';
//}}}
and use the following backets to cover your code
{{{
//{{{
cpp code comes here.
//}}}
}}}
All possible "brushes" can be found at: [[CodeMirror homepage|http://codemirror.net]]
<<<
!! You need a different mode?
* Go to [[CodeMirror compression API page| http://codemirror.net/compress.html]]
* Select your mode
* Create a minified version
* Copy paste it into a tiddler eg: clike.js
** Add the line {{{|''Requires''|codemirror.js|}}} at the top of the tiddler
*** see eg: [[css.js]]
** Tag the new tiddler ''systemConfig''
** Save and reload
* Have a look at Advanced options or use the {{{<code class="brush: ... >}}} tag described above.
!! List needed tiddlers tagged "cmtw" and "cmtwAddOn"
<<<
''If you want to roll your own version, the following tiddlers are needed.''
<<list filter [tag[cmtw]]>>
<<<
<<<
''There are usefull addOns too''
<<list filter [tag[cmtwAddOn]]>>
<<<
!!! highlightSyntax Macro
<<<
*The {{{highlightSyntax}}} macro is only needed if you have inline html blocks, like shown below.
<!--{{{-->
<html>
<pre class='brush:clike'>
// your code
</pre>
</html>
<<highlightSyntax>> .. will render the <pre> blocks shown above.
<!--}}}-->
<<<
!!!! Parameters
<<<
{{{<<highlightSyntax [tagName]>>}}}
*will render all blocks, with any defined tag name. eg: tagName = code.
*[tagName] is optional. Default is "pre".
<<<
!!! Revision History
<<<
* V 0.2.6 2012-03-13
** Added functions to make editor height persistent.
* V 0.2.5 2012-02-07
** update codemirror library to v2.21 including all "support" libraries.
** TAB key handling improved. Extra keys handling moved to ExtraKeysAddOn
** F11 toggle editor height moved to ExtraKeysAddOn.
* V 0.2.4 2012-01-31
** slightly better TAB key handling. Internal testing only
* V 0.2.3 2012-01-11
** renames everything codemirror2 -> codemirror
** Toggle max height mode implemented hardcoded key: 'F11'
* V 0.2.1 2012-01-10
** Toggle max height mode implemented hardcoded key: 'F11'
* V 0.2.0 2011-10-23
** update to codeMirror lib v2.2
** indentation / tab handling fix
* V 0.1.7 2011-10-27
** little docu fix
* V 0.1.6 2011-10-05
** several bug fixes
** improved handling, initializing ...
* V 0.1.4 2011-09-25
** resize hack changed
* V 0.1.0 2011-09-07
** inital release
<<<
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div class='toolbar' macro='typeChooser'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
/***
|''Name''|ExtraKeysAddOn|
|''Description''|This AddOn contains the extra key handling for zCodeMirrorPlugin|
|''Author''|PMario|
|''Version''|0.1.2|
|''Status''|''beta''|
|''Source''|http://codemirror-plugins.tiddlyspace.com/#RenderBuffer.js|
|''License''|[[CC by-nc-sa 3.0|http://creativecommons.org/licenses/by-nc-sa/3.0/]]|
|''CoreVersion''|2.5.0|
|''Keywords''|TAB key handling |
! Documentation
<<<
This addOn needs to be used together with [[zCodeMirrorPlugin]]. It contains:
* simpleTab
** If TAB key is pressed, it just inserts a tab.
** If some text is selected the text will be deleted and a tab will be inserted.
* smartTab
** If no text is selected it inserts a tab.
** If some text or some lines are selected the selected lines will be indented by one tab.
** If text is selected <shift><tab> will unindent the selected lines. This behaviour is preferred, for programming.
* Using {{{simpleTab}}} or {{{smartTab}}} can be configured at CodeMirrorConfig tiddler.
** Default is .. {{{ extraKeys: smartTab }}}
* <F11> key toggles the editor height.
<<<
! Important
<<<
The option {{{chkInsertTabs}}} needs to be ''unchecked'' to use {{{smartTab}}} handling.
<<option chkInsertTabs>> {{{chkInsertTabs}}} Use the tab key to insert tab characters instead of moving between fields.
<<<
! History
<<<
* V 0.1.2 2012-03-13
** Added functions to make editor height persistent.
** + bug fixes introduce with V 0.1.1
<<<
***/
//{{{
version.extensions.ExtraKeyAddOns = {
major: 0,
minor: 0,
revision: 1,
date: new Date(2012, 2, 7)
};
// Returns the specified field (input or textarea element) in a tiddler
// or null if it found no field
Story.prototype.hasTiddlerField = function(title,field)
{
var tiddlerElem = this.getTiddler(title);
var e = null;
if(tiddlerElem) {
var t,children = tiddlerElem.getElementsByTagName("*");
for(t=0; t<children.length; t++) {
var c = children[t];
if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea") {
if(c.getAttribute("edit") == field)
e = c;
}
}
}
return e;
};
if (!config.tools) config.tools = {};
if (!config.tools.cm) config.tools.cm = {};
if (!config.tools.cm.addOns) config.tools.cm.addOns = {};
(function ($) {
var me;
config.tools.cm.addOns.toggleMaxHeight = me = {
F11: function (ed) {
var oldHeight,
$scroll,
tidEl = story.findContainingTiddler(ed.getWrapperElement()),
cmHeight,
corr = 25; // TODO make configurable
$scroll = $(ed.getScrollerElement());
oH = $scroll.data('oldHeight');
if (!oH || oH == $scroll.height()) {
$scroll.data('oldHeight', $scroll.height());
$scroll.height(config.tools.cm.guessMaxHeight(corr));
window.scrollTo(0,ensureVisible(ed.getScrollerElement())+1); // +1 sucks but I want to see the border!
cmHeight = 'max';
}
else {
window.scrollTo(0,ensureVisible(ed.getScrollerElement())-1); // -1 sucks
$scroll.height(oH);
cmHeight = 'min';
}
var title = tidEl.getAttribute('tiddler');
var f = story.hasTiddlerField(title,'cm.height');
if (!f ) {
story.addCustomFields(tidEl, 'cm.height:'+cmHeight);
}
else {
f.setAttribute('value', cmHeight);
}
ed.refresh();
}
},
// smartTab
// if _no_ text is selected, it inserts a tab char
// if text is selected, it indents the selected block
config.tools.cm.addOns.smartTab = {
Tab: function (instance) {
if (instance.somethingSelected())
CodeMirror.commands.indentMore(instance);
else
CodeMirror.commands.insertTab(instance);
}
}, // end plugin
// simpleTab
// if _no_ text is selected, it inserts a tab char
// if text is selected, it _deletes_ the selected block and inserts a tab char
config.tools.cm.addOns.simpleTab = {
Tab: "insertTab"
}
})(jQuery);
//}}}
/***
|''Name:''|FieldsEditorPlugin|
|''Description:''|//create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.|
|''Version:''|1.0.2|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[FieldEditor example]]
!Installation:
*import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
*save and reload
*optionnaly : add the following css text in your StyleSheet : {{{#popup tr.fieldTableRow td {padding:1px 3px 1px 3px;}}}
!Code
***/
//{{{
config.commands.fields.handlePopup = function(popup,title) {
var tiddler = store.fetchTiddler(title);
if(!tiddler)
return;
var fields = {};
store.forEachField(tiddler,function(tiddler,fieldName,value) {fields[fieldName] = value;},true);
var items = [];
for(var t in fields) {
var editCommand = "<<untiddledCall editFieldDialog "+escape(title)+" "+escape(t)+">>";
var deleteCommand = "<<untiddledCall deleteField "+escape(title)+" "+escape(t)+">>";
var renameCommand = "<<untiddledCall renameField "+escape(title)+" "+escape(t)+">>";
items.push({field: t,value: fields[t], actions: editCommand+renameCommand+deleteCommand});
}
items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
var createNewCommand = "<<untiddledCall createField "+escape(title)+">>";
items.push({field : "", value : "", actions:createNewCommand });
if(items.length > 0)
ListView.create(popup,items,this.listViewTemplate);
else
createTiddlyElement(popup,"div",null,null,this.emptyText);
}
config.commands.fields.listViewTemplate = {
columns: [
{name: 'Field', field: 'field', title: "Field", type: 'String'},
{name: 'Actions', field: 'actions', title: "Actions", type: 'WikiText'},
{name: 'Value', field: 'value', title: "Value", type: 'WikiText'}
],
rowClasses: [
{className: 'fieldTableRow', field: 'actions'}
],
buttons: [ //can't use button for selected then delete, because click on checkbox will hide the popup
]
}
config.macros.untiddledCall = { // when called from listview, tiddler is unset, so we need to pass tiddler as parameter
handler : function(place,macroName,params,wikifier,paramString) {
var macroName = params.shift();
if (macroName) var macro = config.macros[macroName];
var title = params.shift();
if (title) var tiddler = store.getTiddler(unescape(title));
if (macro) macro.handler(place,macroName,params,wikifier,paramString,tiddler);
}
}
config.macros.deleteField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"delete", "delete "+fieldName,this.onClickDeleteField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickDeleteField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName && confirm("delete field " + fieldName+" from " + title +" tiddler ?")) {
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
return false;
}
}
config.macros.createField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly) {
var btn = createTiddlyButton(place,"create new", "create a new field",this.onClickCreateField);
btn.setAttribute("title",tiddler.title);
}
},
onClickCreateField : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
if (tiddler) {
var fieldName = prompt("Field name","");
if (store.getValue(tiddler,fieldName)) {
window.alert("This field already exists.");
}
else if (fieldName) {
var v = prompt("Field value","");
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.editFieldDialog = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"edit", "edit this field",this.onClickEditFieldDialog);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickEditFieldDialog : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
var fieldName=this.getAttribute("fieldName");
if (tiddler && fieldName) {
var value = tiddler.fields[fieldName];
value = value ? value : "";
var lines = value.match(/\n/mg);
lines = lines ? true : false;
if (!lines || confirm("This field contains more than one line. Only the first line will be kept if you edit it here. Proceed ?")) {
var v = prompt("Field value",value);
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.renameField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"rename", "rename "+fieldName,this.onClickRenameField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickRenameField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName) {
var newName = prompt("Rename " + fieldName + " as ?", fieldName);
if (newName) {
tiddler.fields[newName]=tiddler.fields[fieldName];
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.shadowTiddlers.StyleSheetFieldsEditor = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow td {padding : 1px 3px}\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow .button {border:0; padding : 0 0.2em}\n";
config.shadowTiddlers.StyleSheetFieldsEditor +="/*}}}*/";
store.addNotification("StyleSheetFieldsEditor", refreshStyles);
//}}}
! Features
* Realtime highlighting in edit mode for {{{tiddlywiki, javascript, css, html, xml, python}}} syntax.
** Other modes are possible too.
* F11 toggles editor height.
** This setting is persistent. So if the tiddler is opened again, it will be set to "max" or "min".
* smart tab handling.
** <tab> key inserts a tab character
** If some text/lines are selected it indents the block.
*** <shift><tab> unindents the block.
! Info
* This is the presentation space of the TiddlyWiki implementaion of CodeMirror Library. »The in-browser code editing library«
* @codemirror-plugin space contains all plugins needed.
* Read CodeMirrorPluginInfo to get more information about the possibilities.
* Feedback is very welcome at [[TiddlyWiki group|TWGroup]]
! ~ToolbarCommands
''Your ToolbarCommands tiddler has to contain {{{cmEdit}}} and {{{cmSave}}} commands!'' This is not automatically updated by the plugin!
! Modes
At the moment, there are 2 modes:
* view mode
** view mode mainly depends on TW code block indicators. Learn more at: CodeMirrorPluginInfo
* edit mode
** edit mode depends on: ''tags'', ''content-type'' and ''server.content-type'' fields
** tag has the highest priority and can be adjusted at: CodeMirrorConfig
** content-type can be edited in "edit mode :)". The selector button is near the toolbar commands. Have a look at the EditTemplate {{{<span macro='tagChooser excludeLists'></span>}}}
! ''Important for TiddlySpace''
* ''Include the [[codemirror-plugins]] space into your TW if you want to use it!''
* Then carefully read the documentation.
* ''Do not include this "codemirror" space'' into your space! Most TS themes don't like it, if there StyleSheet tiddler is overwritten.
! Configuration
CodeMirror has a lot of configuration options, which can be seen at [[CodeMirror manual page|http://codemirror.net/manual.html]]
This TW uses CodeMirrorConfig tiddler, to make them available.
''global'' section
<<<
The global section contains the "default" behaviour, adjusted to my needs :) They may vary for your needs. The config tiddler is a shadow tiddler. So if you mess up the configuration, just delete it, reload and start over again.
<<<
''mode'' section
<<<
The mode section overwrites the global setting.
''tags'' parameter defines the tags, that you use to identify different edit modes.
<<<
! View Mode Test Tiddlers
All tiddlers named "runMode*" are for testing the CodeMirror runMode() function. They don't have any edit mode identifier assigned. So it initially will be "text/plain".
<<list filter [tag[runMode]]>>
! Edit Mode
The following tiddlers are used to test the edit mode identification process
* [[testTag]] .. the tag defined at ~CodeMirrorPlugin define the edit mode.
* [[testContentType]] .. toolbar command: more: fields shows the content-type field
* [[testServerContentType]] .. toolbar command: more: fields shows the server.content-type field
* The tag has the highest priority.
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
bidix.core.loadRemoteFile = loadRemoteFile;
//}}}
! MIMEs
English: http://en.wikipedia.org/wiki/MIME
German: http://de.wikipedia.org/wiki/MIME
<<list filter [tag[mainMenu]]>>
Type the text for 'New Tiddler'
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|''Name''|RenderBufferPlugin|
|''Description''|Transcludes text from a tiddler, specified by line number and number of lines. |
|''Author''|PMario|
|''Version''|0.0.1|
|''Status''|@@experimental@@|
|''Source''|http://codemirror-plugins.tiddlyspace.com/#RenderBuffer.js|
|''License''|[[CC by-nc-sa 3.0|http://creativecommons.org/licenses/by-nc-sa/3.0/]]|
|''CoreVersion''|2.5.0|
|''Keywords''|render wikify buffer tiddler transclusion|
!Documentation
<<<
..
<<<
!!! Usage
<<<
{{{
<<renderBuffer text:'!!! heading
SomeText'>>
}}}
<<renderBuffer text:'!!! heading
SomeText'>>
{{{
<<renderBuffer tiddler:RenderBufferPlugin find:'!Doc' next:'!+ ?Usage'>>
}}}
<<renderBuffer tiddler:RenderBufferPlugin find:'!Doc' next:'!+ ?Usage'>>
<<<
!!! History
<<<
* V 0.0.1 - 2012.02.14
** alpha release
<<<
!!! Code
***/
//{{{
version.extensions.RenderBufferPlugin = {
major: 0,
minor: 1,
revision: 0,
date: new Date(2012, 2, 14)
};
(function ($) {
var me;
config.macros.renderBuffer = me = {
// should be done for easy localisation
locale: {
txtBtnTooltip: "Just for testing at the moment!"
},
// converts the named params into keys of an object.
// Be aware, that parmName:true will be a text "true" variable, not a boolean !!
// See: https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects
paramsToObject: function (conf, names, params, initValue) {
var tmp;
for (var i=0, im = names.length; i<im; i += 1) {
tmp = getParam( params, names[i], initValue);
// the conf.xx variable will only be set if a parameter or "initValue" is defined;
// For my examples. I don t use initValue!!
if (tmp) {
conf[names[i]] = tmp;
}
} // for
},
// Set some default values
defaults: {
start: 0,
lines: 5,
tag: 'span',
class: 'cmBuffer',
id: ''
},
handler: function (place, macroName, params, wikifier, paramString, tiddler) {
params = paramString.parseParams(null, null, true);
// console.log('params', params);
var btn; // will be the button element.
var txtTooltip; // button tooltip is a helper variable to make the code more readable
var conf = {}; // contains the named params, to work with.
// these are optional params which are used by your plugin.
// no 'place' param is allowed, it will be overwritten.
var names = ['text', 'tiddler', 'start', 'lines', 'find', 'next', 'id', 'button'];
// define the default values, if needed. See: http://api.jquery.com/jQuery.extend/
$.extend(conf, me.defaults);
// next function converts names into object keys.
// can be: me.paramsToObject(conf, names, params, initValue);
// BUT initValue will overwrite me.defaults! code line above
me.paramsToObject(conf, names, params);
conf.place = place; // place will be needed to find the containing element.
// ============================================================================
// from here on, you can work with your "conf" object, that contains the params.
// console.log('conf: ', conf);
// start default line = 1 ==> index 0
conf.start = (conf.start > 0) ? parseInt(conf.start,10)-1 : 0;
conf.lines = parseInt(conf.lines,10);
conf.tiddler = (conf.tiddler) ? conf.tiddler : null;
conf.output = createTiddlyElement(place, conf.tag, conf.id, conf.class);
$(conf.output).data('conf', conf).attr({"refresh":'macro', "macroname": macroName});
if (conf.button) {
txtTooltip = (conf.tooltip) ? conf.tooltip : me.locale.txtBtnTooltip;
// next comment line is used as a reminder for the possible/needed parameters
// createTiddlyButton(parent, text, tooltip, action, className, id, accessKey, attribs)
btn = createTiddlyButton(place, conf.button, txtTooltip, me.onClick, 'button');
// adding a jQuery data object to the button. see: http://api.jquery.com/jQuery.data/
var result = $(btn).data('data', conf.output);
// var result is just there, to be used as a console.log var in the next line.
// console.log('result:', result);
} // if
if (!conf.button) me.refresh(conf.output);
}, // handler
refresh: function (el) {
var tmp
, iMax
, regStart, regNext
, conf = $(el).data('conf');
// if tiddler is specified, text will not be used
conf.text = (conf.tiddler) ? store.getTiddlerText(conf.tiddler) : conf.text;
tmp = conf.text.split('\n');
iMax = (tmp.length >= conf.lines) ? conf.lines : tmp.length;
// console.log('tmp: ', tmp, conf.text);
if (conf.find) {
// TODO may be remove special handling and move this to documentation
// <<renderBuffer find:"!(?=[^!])" should do it as well. Is difficult for users :(
if (conf.find === '!') regStart = new RegExp('^!(?=[^!])', 'im')
else if (conf.find === '!!') regStart = new RegExp('^!!(?=[^!])', 'im')
else if (conf.find === '!!!') regStart = new RegExp('^!!!(?=[^!])', 'im')
else if (conf.find === '!!!!') regStart = new RegExp('^!!!!(?=[^!])', 'im')
else if (conf.find === '!!!!!') regStart = new RegExp('^!!!!!(?=[^!])', 'im')
else if (conf.find === '!!!!!!') regStart = new RegExp('^!!!!!!', 'im')
else regStart = new RegExp('^' + conf.find, 'im');
if (conf.next === '!') regNext = new RegExp('^!(?=[^!])', 'im')
else if (conf.next === '!!') regNext = new RegExp('^!!(?=[^!])', 'im')
else if (conf.next === '!!!') regNext = new RegExp('^!!!(?=[^!])', 'im')
else if (conf.next === '!!!!') regNext = new RegExp('^!!!!(?=[^!])', 'im')
else if (conf.next === '!!!!!') regNext = new RegExp('^!!!!!(?=[^!])', 'im')
else if (conf.next === '!!!!!!') regNext = new RegExp('^!!!!!!', 'im')
else regNext = new RegExp('^' + conf.next, 'im');
iMax = tmp.length;
for (i=0, iMax=tmp.length; i < iMax; i++ ) {
match = tmp[i].match(regStart);
if (match != null) {
conf.start = i;
// set iMax to conf.lines. It will be recalculated if conf.next exists
iMax = conf.lines;// iMax - i;
i += 1;
break;
}
} // for
if (conf.next) {
for (iMax=tmp.length; i < iMax; i++ ) {
match = tmp[i].match(regNext);
if (match != null) {
iMax = i-conf.start;
break;
}
}
} // if
} // if (conf.find)
conf.text = tmp.slice(conf.start, conf.start+iMax).join('\n');
$(conf.output).empty();
wikify(conf.text, conf.output);
},
onClick: function() {
// since the handlers context is not defined in the right way, when the button is clicked
// it needs to be loaded from the jQuery data object. http://api.jquery.com/jQuery.data/
var data = $(this).data("data");
me.refresh(data);
}
}; // end plugin
})(jQuery);
//}}}
/***
|''Name''|SimpleSearchPlugin|
|''Description''|displays search results as a simple list of matching tiddlers|
|''Authors''|FND|
|''Version''|0.4.1|
|''Status''|stable|
|''Source''|http://devpad.tiddlyspot.com/#SimpleSearchPlugin|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/SimpleSearchPlugin.js|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Keywords''|search|
!Revision History
!!v0.2.0 (2008-08-18)
* initial release
!!v0.3.0 (2008-08-19)
* added Open All button (renders Classic Search option obsolete)
* sorting by relevance (title matches before content matches)
!!v0.4.0 (2008-08-26)
* added tag matching
!To Do
* tag matching optional
* animations for container creation and removal
* when clicking on search results, do not scroll to the respective tiddler (optional)
* use template for search results
!Code
***/
//{{{
if(!version.extensions.SimpleSearchPlugin) { //# ensure that the plugin is only installed once
version.extensions.SimpleSearchPlugin = { installed: true };
if(!config.extensions) { config.extensions = {}; }
config.extensions.SimpleSearchPlugin = {
heading: "Search Results",
containerId: "searchResults",
btnCloseLabel: "close",
btnCloseTooltip: "dismiss search results",
btnCloseId: "search_close",
btnOpenLabel: "Open all",
btnOpenTooltip: "open all search results",
btnOpenId: "search_open",
displayResults: function(matches, query) {
story.refreshAllTiddlers(true); // update highlighting within story tiddlers
var el = document.getElementById(this.containerId);
query = '"""' + query + '"""'; // prevent WikiLinks
if(el) {
removeChildren(el);
} else { //# fallback: use displayArea as parent
var container = document.getElementById("displayArea");
el = document.createElement("div");
el.id = this.containerId;
el = container.insertBefore(el, container.firstChild);
}
var msg = "!" + this.heading + "\n";
if(matches.length > 0) {
msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
this.results = [];
for(var i = 0 ; i < matches.length; i++) {
this.results.push(matches[i].title);
msg += "* [[" + matches[i].title + "]]\n";
}
} else {
msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
}
createTiddlyButton(el, this.btnCloseLabel, this.btnCloseTooltip, config.extensions.SimpleSearchPlugin.closeResults, "button", this.btnCloseId);
wikify(msg, el);
if(matches.length > 0) { // XXX: redundant!?
createTiddlyButton(el, this.btnOpenLabel, this.btnOpenTooltip, config.extensions.SimpleSearchPlugin.openAll, "button", this.btnOpenId);
}
},
closeResults: function() {
var el = document.getElementById(config.extensions.SimpleSearchPlugin.containerId);
removeNode(el);
config.extensions.SimpleSearchPlugin.results = null;
highlightHack = null;
},
openAll: function(ev) {
story.displayTiddlers(null, config.extensions.SimpleSearchPlugin.results);
return false;
}
};
config.shadowTiddlers.StyleSheetSimpleSearch = "/*{{{*/\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " {\n" +
"\toverflow: auto;\n" +
"\tpadding: 5px 1em 10px;\n" +
"\tbackground-color: [[ColorPalette::TertiaryPale]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " h1 {\n" +
"\tmargin-top: 0;\n" +
"\tborder: none;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " ul {\n" +
"\tmargin: 0.5em;\n" +
"\tpadding-left: 1.5em;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button {\n" +
"\tdisplay: block;\n" +
"\tborder-color: [[ColorPalette::TertiaryDark]];\n" +
"\tpadding: 5px;\n" +
"\tbackground-color: [[ColorPalette::TertiaryLight]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button:hover {\n" +
"\tborder-color: [[ColorPalette::SecondaryMid]];\n" +
"\tbackground-color: [[ColorPalette::SecondaryLight]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.btnCloseId + " {\n" +
"\tfloat: right;\n" +
"\tmargin: -5px -1em 5px 5px;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.btnOpenId + " {\n" +
"\tfloat: left;\n" +
"\tmargin-top: 5px;\n" +
"}\n" +
"/*}}}*/";
store.addNotification("StyleSheetSimpleSearch", refreshStyles);
// override Story.search()
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(), useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack, null, "excludeSearch");
var q = useRegExp ? "/" : "'";
config.extensions.SimpleSearchPlugin.displayResults(matches, q + text + q);
};
// override TiddlyWiki.search() to sort by relevance
TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {
var candidates = this.reverseLookup("tags", excludeTag, !!match);
var primary = [];
var secondary = [];
var tertiary = [];
for(var t = 0; t < candidates.length; t++) {
if(candidates[t].title.search(searchRegExp) != -1) {
primary.push(candidates[t]);
} else if(candidates[t].tags.join(" ").search(searchRegExp) != -1) {
secondary.push(candidates[t]);
} else if(candidates[t].text.search(searchRegExp) != -1) {
tertiary.push(candidates[t]);
}
}
var results = primary.concat(secondary).concat(tertiary);
if(sortField) {
results.sort(function(a, b) {
return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
});
}
return results;
};
} //# end of "install only once"
//}}}
/*{{{*/
.CodeMirror {
font-family: Inconsolata, monospace;
}
#sidebar {
overflow: hidden;
}
/*}}}*/
Learn more and give feedback at the TW discussion group: http://groups.google.com/group/tiddlywiki
Learn more about the TiddlyWiki server side: [[TiddlySpace|http://tiddlyspace.com]]
You can visit me at: [[pmario's space|http://pmario.tiddlyspace.com]]
have fun!
TiddlyWiki is a complete wiki in a single HTML file. It contains the entire text of the wiki, and all the ~JavaScript, CSS and HTML goodness to be able to display it, and let you edit it or search it - without needing a server. Although, having said that, there are some fine ~ServerSide adaptations out there.
~TiddlyWiki is published under an ~OpenSourceLicense and maintained by a busy Community of independent developers.
Learn more at: http://tiddlywiki.com/ and have fun!
|~ViewToolbar|closeTiddler closeOthers +cmEdit > fields syncing permalink references jump <|
|~EditToolbar|cmSave cancelTiddler deleteTiddler|
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
// config.tiddlyspotSiteId = 'yourTiddlySpotNameHere';
config.tiddlyspotSiteId = 'codemirror';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 13/03/2012 20:35:38 | codemirror | [[upstream.html|file:///media/Daten/Git/tiddly/pmario/tw.CodeMirrorPlugin/upstream.html]] | [[store.cgi|http://codemirror.tiddlyspot.com/store.cgi]] | . | [[index.html | http://codemirror.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
!MIT License
http://www.opensource.org/licenses/mit-license.php
!BSD License
http://www.opensource.org/licenses/bsd-license.php
!CC License
http://creativecommons.org/licenses/
!GPL License
http://www.gnu.org/copyleft/gpl.html
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (type: <span macro='view content-type link'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
! To use CM include this space
use: http://codemirror-plugins.tiddlyspace.com
/*{{{*/
.CodeMirror {
line-height: 1em;
font-family: monospace;
}
.CodeMirror-scroll {
overflow: auto;
height: 300px;
/* This is needed to prevent an IE[67] bug where the scrolled content
is visible outside of the scrolling box. */
position: relative;
}
.CodeMirror-gutter {
position: absolute; left: 0; top: 0;
z-index: 10;
background-color: #f7f7f7;
border-right: 1px solid #eee;
min-width: 2em;
height: 100%;
}
.CodeMirror-gutter-text {
color: #aaa;
text-align: right;
padding: .4em .2em .4em .4em;
white-space: pre !important;
}
.CodeMirror-lines {
padding: .4em;
}
.CodeMirror pre {
-moz-border-radius: 0;
-webkit-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border-width: 0; margin: 0; padding: 0; background: transparent;
font-family: inherit;
font-size: inherit;
padding: 0; margin: 0;
white-space: pre;
word-wrap: normal;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
}
.CodeMirror textarea {
outline: none !important;
}
.CodeMirror pre.CodeMirror-cursor {
z-index: 10;
position: absolute;
visibility: hidden;
border-left: 1px solid black;
border-right:none;
width:0;
}
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
.CodeMirror-focused pre.CodeMirror-cursor {
visibility: visible;
}
div.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Default theme */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #cc7;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
.cm-s-default span.cm-header {color: #a0a;}
.cm-s-default span.cm-quote {color: #090;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-link {color: #00c;}
span.cm-header, span.cm-strong {font-weight: bold;}
span.cm-em {font-style: italic;}
span.cm-emstrong {font-style: italic; font-weight: bold;}
span.cm-link {text-decoration: underline;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
/*}}}*/
/***
Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
***/
//{{{
// All functions that need access to the editor's state live inside
// the CodeMirror function. Below that, at the bottom of the file,
// some utilities are defined.
// CodeMirror is the only global var we claim
var CodeMirror=function(){function a(d,e){function bT(a){return a>=0&&a<br.size}function bV(a){return v(br,a)}function bW(a,b){bI=!0;var c=b-a.height;for(var d=a;d;d=d.parent)d.height+=c}function bX(a){var b={line:0,ch:0};cl(b,{line:br.size-1,ch:bV(br.size-1).text.length},bc(a),b,b),bC=!0}function bY(a){var b=[];return br.iter(0,br.size,function(a){b.push(a.text)}),b.join("\n")}function bZ(a){function j(a){var b=dE(a,!0);if(b&&!W(b,g)){bt||cj(),g=b,cM(d,b),bC=!1;var c=cF();if(b.line>=c.to||b.line<c.from)h=setTimeout(dR(function(){j(a)}),150)}}cL(H(a,"shiftKey"));for(var b=F(a);b!=A;b=b.parentNode)if(b.parentNode==S&&b!=Z)return;for(var b=F(a);b!=A;b=b.parentNode)if(b.parentNode==bg)return f.onGutterClick&&f.onGutterClick(bU,ba(bg.childNodes,b)+bL,a),C(a);var d=dE(a);switch(G(a)){case 3:M&&!c&&dF(a);return;case 2:d&&cP(d.line,d.ch,!0);return}if(!d){F(a)==R&&C(a);return}bt||cj();var e=+(new Date);if(bx&&bx.time>e-400&&W(bx.pos,d))return C(a),setTimeout(cB,20),cY(d.line);if(bw&&bw.time>e-400&&W(bw.pos,d))return bx={time:e,pos:d},C(a),cX(d);bw={time:e,pos:d};var g=d,h;if(L&&!f.readOnly&&!W(bu.from,bu.to)&&!X(d,bu.from)&&!X(bu.to,d)){P&&(bh.draggable=!0);var i=I(s,"mouseup",dR(function(b){P&&(bh.draggable=!1),bz=!1,i(),Math.abs(a.clientX-b.clientX)+Math.abs(a.clientY-b.clientY)<10&&(C(b),cP(d.line,d.ch,!0),cB())}),!0);bz=!0;return}C(a),cP(d.line,d.ch,!0);var k=I(s,"mousemove",dR(function(a){clearTimeout(h),C(a),j(a)}),!0),i=I(s,"mouseup",dR(function(a){clearTimeout(h);var b=dE(a);b&&cM(d,b),C(a),cB(),bC=!0,k(),i()}),!0)}function b$(a){for(var b=F(a);b!=A;b=b.parentNode)if(b.parentNode==bg)return C(a);var c=dE(a);if(!c)return;bx={time:+(new Date),pos:c},C(a),cX(c)}function b_(a){a.preventDefault();var b=dE(a,!0),c=a.dataTransfer.files;if(!b||f.readOnly)return;if(c&&c.length&&window.FileReader&&window.File){function d(a,c){var d=new FileReader;d.onload=function(){g[c]=d.result,++h==e&&(b=cR(b),dR(function(){var a=cq(g.join(""),b,b);cM(b,a)})())},d.readAsText(a)}var e=c.length,g=Array(e),h=0;for(var i=0;i<e;++i)d(c[i],i)}else try{var g=a.dataTransfer.getData("Text");if(g){var j=bu.from,k=bu.to;cM(b,b),bz&&cq("",j,k),cr(g),cB()}}catch(a){}}function ca(a){var b=cu();a.dataTransfer.setData("Text",b)}function cb(a,b){if(typeof a=="string"){a=h[a];if(!a)return!1}var c=bv;try{f.readOnly&&(bB=!0),b&&(bv=null),a(bU)}catch(d){if(d!=K)throw d;return!1}finally{bv=c,bB=!1}return!0}function cc(a){var b=j(f.keyMap),c=b.auto;clearTimeout(cf),c&&!l(a)&&(cf=setTimeout(function(){j(f.keyMap)==b&&(f.keyMap=c.call?c.call(null,bU):c)},50));var d=be[H(a,"keyCode")],e=!1;return d==null||a.altGraphKey?!1:(H(a,"altKey")&&(d="Alt-"+d),H(a,"ctrlKey")&&(d="Ctrl-"+d),H(a,"metaKey")&&(d="Cmd-"+d),H(a,"shiftKey")&&(e=k("Shift-"+d,f.extraKeys,f.keyMap,function(a){return cb(a,!0)})),e||(e=k(d,f.extraKeys,f.keyMap,cb)),e&&C(a),e)}function cd(a,b){var c=k("'"+b+"'",f.extraKeys,f.keyMap,cb);return c&&C(a),c}function cg(a){bt||cj(),N&&a.keyCode==27&&(a.returnValue=!1),cv&&cz()&&(cv=!1);if(f.onKeyEvent&&f.onKeyEvent(bU,B(a)))return;var b=H(a,"keyCode");cL(b==16||H(a,"shiftKey"));var d=cc(a);window.opera&&(ce=d?b:null,!d&&b==88&&H(a,c?"metaKey":"ctrlKey")&&cr(""))}function ch(a){cv&&cz();if(f.onKeyEvent&&f.onKeyEvent(bU,B(a)))return;var b=H(a,"keyCode"),c=H(a,"charCode");if(window.opera&&b==ce){ce=null,C(a);return}if(window.opera&&!a.which&&cc(a))return;var d=String.fromCharCode(c==null?b:c);f.electricChars&&bq.electricChars&&f.smartIndent&&!f.readOnly&&bq.electricChars.indexOf(d)>-1&&setTimeout(dR(function(){c$(bu.to.line,"smart")}),75);if(cd(a,d))return;cx()}function ci(a){if(f.onKeyEvent&&f.onKeyEvent(bU,B(a)))return;H(a,"keyCode")==16&&(bv=null)}function cj(){if(f.readOnly=="nocursor")return;bt||(f.onFocus&&f.onFocus(bU),bt=!0,A.className.search(/\bCodeMirror-focused\b/)==-1&&(A.className+=" CodeMirror-focused"),bH||cA(!0)),cw(),dG()}function ck(){bt&&(f.onBlur&&f.onBlur(bU),bt=!1,bO&&dR(function(){bO&&(bO(),bO=null)})(),A.className=A.className.replace(" CodeMirror-focused","")),clearInterval(bp),setTimeout(function(){bt||(bv=null)},150)}function cl(a,b,c,d,e){if(bB)return;if(bR){var g=[];br.iter(a.line,b.line+1,function(a){g.push(a.text)}),bR.addChange(a.line,c.length,g);while(bR.done.length>f.undoDepth)bR.done.shift()}cp(a,b,c,d,e)}function cm(a,b){if(!a.length)return;var c=a.pop(),d=[];for(var e=c.length-1;e>=0;e-=1){var f=c[e],g=[],h=f.start+f.added;br.iter(f.start,h,function(a){g.push(a.text)}),d.push({start:f.start,added:f.old.length,old:g});var i=cR({line:f.start+f.old.length-1,ch:_(g[g.length-1],f.old[f.old.length-1])});cp({line:f.start,ch:0},{line:h-1,ch:bV(h-1).text.length},f.old,i,i)}bC=!0,b.push(d)}function cn(){cm(bR.done,bR.undone)}function co(){cm(bR.undone,bR.done)}function cp(a,b,c,d,e){function y(a){return a<=Math.min(b.line,b.line+s)?a:a+s}if(bB)return;var g=!1,h=bP.length;f.lineWrapping||br.iter(a.line,b.line,function(a){if(a.text.length==h)return g=!0,!0});if(a.line!=b.line||c.length>1)bI=!0;var i=b.line-a.line,j=bV(a.line),k=bV(b.line);if(a.ch==0&&b.ch==0&&c[c.length-1]==""){var l=[],m=null;a.line?(m=bV(a.line-1),m.fixMarkEnds(k)):k.fixMarkStarts();for(var n=0,o=c.length-1;n<o;++n)l.push(r.inheritMarks(c[n],m));i&&br.remove(a.line,i,bJ),l.length&&br.insert(a.line,l)}else if(j==k)if(c.length==1)j.replace(a.ch,b.ch,c[0]);else{k=j.split(b.ch,c[c.length-1]),j.replace(a.ch,null,c[0]),j.fixMarkEnds(k);var l=[];for(var n=1,o=c.length-1;n<o;++n)l.push(r.inheritMarks(c[n],j));l.push(k),br.insert(a.line+1,l)}else if(c.length==1)j.replace(a.ch,null,c[0]),k.replace(null,b.ch,""),j.append(k),br.remove(a.line+1,i,bJ);else{var l=[];j.replace(a.ch,null,c[0]),k.replace(null,b.ch,c[c.length-1]),j.fixMarkEnds(k);for(var n=1,o=c.length-1;n<o;++n)l.push(r.inheritMarks(c[n],j));i>1&&br.remove(a.line+1,i-1,bJ),br.insert(a.line+1,l)}if(f.lineWrapping){var p=R.clientWidth/dB()-3;br.iter(a.line,a.line+c.length,function(a){if(a.hidden)return;var b=Math.ceil(a.text.length/p)||1;b!=a.height&&bW(a,b)})}else br.iter(a.line,n+c.length,function(a){var b=a.text;b.length>h&&(bP=b,h=b.length,bQ=null,g=!1)}),g&&(h=0,bP="",bQ=null,br.iter(0,br.size,function(a){var b=a.text;b.length>h&&(h=b.length,bP=b)}));var q=[],s=c.length-i-1;for(var n=0,t=bs.length;n<t;++n){var u=bs[n];u<a.line?q.push(u):u>b.line&&q.push(u+s)}var v=a.line+Math.min(c.length,500);dL(a.line,v),q.push(v),bs=q,dN(100),bE.push({from:a.line,to:b.line+1,diff:s});var w={from:a,to:b,text:c};if(bF){for(var x=bF;x.next;x=x.next);x.next=w}else bF=w;cN(d,e,y(bu.from.line),y(bu.to.line)),R.clientHeight&&(S.style.height=br.height*dy()+2*dC()+"px")}function cq(a,b,c){function d(d){if(X(d,b))return d;if(!X(c,d))return e;var f=d.line+a.length-(c.line-b.line)-1,g=d.ch;return d.line==c.line&&(g+=a[a.length-1].length-(c.ch-(c.line==b.line?b.ch:0))),{line:f,ch:g}}b=cR(b),c?c=cR(c):c=b,a=bc(a);var e;return cs(a,b,c,function(a){return e=a,{from:d(bu.from),to:d(bu.to)}}),e}function cr(a,b){cs(bc(a),bu.from,bu.to,function(a){return b=="end"?{from:a,to:a}:b=="start"?{from:bu.from,to:bu.from}:{from:bu.from,to:a}})}function cs(a,b,c,d){var e=a.length==1?a[0].length+b.ch:a[a.length-1].length,f=d({line:b.line+a.length-1,ch:e});cl(b,c,a,f.from,f.to)}function ct(a,b){var c=a.line,d=b.line;if(c==d)return bV(c).text.slice(a.ch,b.ch);var e=[bV(c).text.slice(a.ch)];return br.iter(c+1,d,function(a){e.push(a.text)}),e.push(bV(d).text.slice(0,b.ch)),e.join("\n")}function cu(){return ct(bu.from,bu.to)}function cw(){if(cv)return;bn.set(f.pollInterval,function(){dO(),cz(),bt&&cw(),dP()})}function cx(){function b(){dO();var c=cz();!c&&!a?(a=!0,bn.set(60,b)):(cv=!1,cw()),dP()}var a=!1;cv=!0,bn.set(20,b)}function cz(){if(bH||!bt||bd(Q)||f.readOnly)return!1;var a=Q.value;if(a==cy)return!1;bv=null;var b=0,c=Math.min(cy.length,a.length);while(b<c&&cy[b]==a[b])++b;return b<cy.length?bu.from={line:bu.from.line,ch:bu.from.ch-(cy.length-b)}:bA&&W(bu.from,bu.to)&&(bu.to={line:bu.to.line,ch:Math.min(bV(bu.to.line).text.length,bu.to.ch+(a.length-b))}),cr(a.slice(b),"end"),cy=a,!0}function cA(a){W(bu.from,bu.to)?a&&(cy=Q.value=""):(cy="",Q.value=cu(),V(Q))}function cB(){f.readOnly!="nocursor"&&Q.focus()}function cC(){if(!bj.getBoundingClientRect)return;var a=bj.getBoundingClientRect();if(N&&a.top==a.bottom)return;var b=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(a.top<0||a.bottom>b)&&bj.scrollIntoView()}function cD(){var a=ds(bu.inverted?bu.from:bu.to),b=f.lineWrapping?Math.min(a.x,bh.offsetWidth):a.x;return cE(b,a.y,b,a.yBot)}function cE(a,b,c,d){var e=dD(),g=dC(),h=dy();b+=g,d+=g,a+=e,c+=e;var i=R.clientHeight,j=R.scrollTop,k=!1,l=!0;b<j?(R.scrollTop=Math.max(0,b-2*h),k=!0):d>j+i&&(R.scrollTop=d+h-i,k=!0);var m=R.clientWidth,n=R.scrollLeft,o=f.fixedGutter?bf.clientWidth:0;return a<n+o?(a<50&&(a=0),R.scrollLeft=Math.max(0,a-10-o),k=!0):c>m+n-3&&(R.scrollLeft=c+10-m,k=!0,c>S.clientWidth&&(l=!1)),k&&f.onScroll&&f.onScroll(bU),l}function cF(){var a=dy(),b=R.scrollTop-dC(),c=Math.max(0,Math.floor(b/a)),d=Math.ceil((b+R.clientHeight)/a);return{from:x(br,c),to:x(br,d)}}function cG(a,b){if(!R.clientWidth){bL=bM=bK=0;return}var c=cF();if(a!==!0&&a.length==0&&c.from>bL&&c.to<bM)return;var d=Math.max(c.from-100,0),e=Math.min(br.size,c.to+100);bL<d&&d-bL<20&&(d=bL),bM>e&&bM-e<20&&(e=Math.min(br.size,bM));var g=a===!0?[]:cH([{from:bL,to:bM,domStart:0}],a),h=0;for(var i=0;i<g.length;++i){var j=g[i];j.from<d&&(j.domStart+=d-j.from,j.from=d),j.to>e&&(j.to=e),j.from>=j.to?g.splice(i--,1):h+=j.to-j.from}if(h==e-d)return;g.sort(function(a,b){return a.domStart-b.domStart});var k=dy(),l=bf.style.display;bl.style.display="none",cI(d,e,g),bl.style.display=bf.style.display="";var m=d!=bL||e!=bM||bN!=R.clientHeight+k;m&&(bN=R.clientHeight+k),bL=d,bM=e,bK=y(br,d),Z.style.top=bK*k+"px",R.clientHeight&&(S.style.height=br.height*k+2*dC()+"px");if(bl.childNodes.length!=bM-bL)throw new Error("BAD PATCH! "+JSON.stringify(g)+" size="+(bM-bL)+" nodes="+bl.childNodes.length);if(f.lineWrapping){bQ=R.clientWidth;var n=bl.firstChild,o=!1;br.iter(bL,bM,function(a){if(!a.hidden){var b=Math.round(n.offsetHeight/k)||1;a.height!=b&&(bW(a,b),bI=o=!0)}n=n.nextSibling}),o&&(S.style.height=br.height*k+2*dC()+"px")}else bQ==null&&(bQ=dn(bP)),bQ>R.clientWidth?(bh.style.width=bQ+"px",S.style.width="",S.style.width=R.scrollWidth+"px"):bh.style.width=S.style.width="";return bf.style.display=l,(m||bI)&&cJ(),cK(),!b&&f.onUpdate&&f.onUpdate(bU),!0}function cH(a,b){for(var c=0,d=b.length||0;c<d;++c){var e=b[c],f=[],g=e.diff||0;for(var h=0,i=a.length;h<i;++h){var j=a[h];e.to<=j.from&&e.diff?f.push({from:j.from+g,to:j.to+g,domStart:j.domStart}):e.to<=j.from||e.from>=j.to?f.push(j):(e.from>j.from&&f.push({from:j.from,to:e.from,domStart:j.domStart}),e.to<j.to&&f.push({from:e.to+g,to:j.to+g,domStart:j.domStart+(e.to-j.from)}))}a=f}return a}function cI(a,b,c){if(!c.length)bl.innerHTML="";else{function d(a){var b=a.nextSibling;return a.parentNode.removeChild(a),b}var e=0,f=bl.firstChild,g;for(var h=0;h<c.length;++h){var i=c[h];while(i.domStart>e)f=d(f),e++;for(var j=0,k=i.to-i.from;j<k;++j)f=f.nextSibling,e++}while(f)f=d(f)}var l=c.shift(),f=bl.firstChild,j=a,m=s.createElement("div"),n;br.iter(a,b,function(a){l&&l.to==j&&(l=c.shift());if(!l||l.from>j){if(a.hidden)var b=m.innerHTML="<pre></pre>";else{var b="<pre>"+a.getHTML(dc)+"</pre>";a.className&&(b='<div style="position: relative"><pre class="'+a.className+'" style="position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2"> </pre>'+b+"</div>")}m.innerHTML=b,bl.insertBefore(m.firstChild,f)}else f=f.nextSibling;++j})}function cJ(){if(!f.gutter&&!f.lineNumbers)return;var a=Z.offsetHeight,b=R.clientHeight;bf.style.height=(a-b<2?b:a)+"px";var c=[],d=bL;br.iter(bL,Math.max(bM,bL+1),function(a){if(a.hidden)c.push("<pre></pre>");else{var b=a.gutterMarker,e=f.lineNumbers?d+f.firstLineNumber:null;b&&b.text?e=b.text.replace("%N%",e!=null?e:""):e==null&&(e="\u00a0"),c.push(b&&b.style?'<pre class="'+b.style+'">':"<pre>",e);for(var g=1;g<a.height;++g)c.push("<br/> ");c.push("</pre>")}++d}),bf.style.display="none",bg.innerHTML=c.join("");var e=String(br.size).length,g=bg.firstChild,h=U(g),i="";while(h.length+i.length<e)i+="\u00a0";i&&g.insertBefore(s.createTextNode(i),g.firstChild),bf.style.display="",bh.style.marginLeft=bf.offsetWidth+"px",bI=!1}function cK(){var a=W(bu.from,bu.to),b=ds(bu.from,!0),c=a?b:ds(bu.to,!0),d=bu.inverted?b:c,e=dy(),g=T(A),h=T(bl);D.style.top=Math.max(0,Math.min(R.offsetHeight,d.y+h.top-g.top))+"px",D.style.left=Math.max(0,Math.min(R.offsetWidth,d.x+h.left-g.left))+"px";if(a)bj.style.top=d.y+"px",bj.style.left=(f.lineWrapping?Math.min(d.x,bh.offsetWidth):d.x)+"px",bj.style.display="",bk.style.display="none";else{var i=b.y==c.y,j="";function k(a,b,c,d){j+='<div class="CodeMirror-selected" style="position: absolute; left: '+a+"px; top: "+b+"px; right: "+c+"px; height: "+d+'px"></div>'}if(bu.from.ch&&b.y>=0){var l=i?bh.clientWidth-c.x:0;k(b.x,b.y,l,e)}var m=Math.max(0,b.y+(bu.from.ch?e:0)),n=Math.min(c.y,bh.clientHeight)-m;n>.2*e&&k(0,m,0,n),(!i||!bu.from.ch)&&c.y<bh.clientHeight-.5*e&&k(0,c.y,bh.clientWidth-c.x,e),bk.innerHTML=j,bj.style.display="none",bk.style.display=""}}function cL(a){a?bv=bv||(bu.inverted?bu.to:bu.from):bv=null}function cM(a,b){var c=bv&&cR(bv);c&&(X(c,a)?a=c:X(b,c)&&(b=c)),cN(a,b),bD=!0}function cN(a,b,c,d){cV=null,c==null&&(c=bu.from.line,d=bu.to.line);if(W(bu.from,a)&&W(bu.to,b))return;if(X(b,a)){var e=b;b=a,a=e}a.line!=c&&(a=cO(a,c,bu.from.ch)),b.line!=d&&(b=cO(b,d,bu.to.ch)),W(a,b)?bu.inverted=!1:W(a,bu.to)?bu.inverted=!1:W(b,bu.from)&&(bu.inverted=!0);if(f.autoClearEmptyLines&&W(bu.from,bu.to)){var g=bu.inverted?a:b;if(g.line!=bu.from.line){var h=bV(bu.from.line);/^\s+$/.test(h.text)&&setTimeout(dR(function(){if(h.parent&&/^\s+$/.test(h.text)){var a=w(h);cq("",{line:a,ch:0},{line:a,ch:h.text.length})}},10))}}bu.from=a,bu.to=b,bG=!0}function cO(a,b,c){function d(b){var d=a.line+b,e=b==1?br.size:-1;while(d!=e){var f=bV(d);if(!f.hidden){var g=a.ch;if(g>c||g>f.text.length)g=f.text.length;return{line:d,ch:g}}d+=b}}var e=bV(a.line);return e.hidden?a.line>=b?d(1)||d(-1):d(-1)||d(1):a}function cP(a,b,c){var d=cR({line:a,ch:b||0});(c?cM:cN)(d,d)}function cQ(a){return Math.max(0,Math.min(a,br.size-1))}function cR(a){if(a.line<0)return{line:0,ch:0};if(a.line>=br.size)return{line:br.size-1,ch:bV(br.size-1).text.length};var b=a.ch,c=bV(a.line).text.length;return b==null||b>c?{line:a.line,ch:c}:b<0?{line:a.line,ch:0}:a}function cS(a,b){function g(){for(var b=d+a,c=a<0?-1:br.size;b!=c;b+=a){var e=bV(b);if(!e.hidden)return d=b,f=e,!0}}function h(b){if(e==(a<0?0:f.text.length))if(!b&&g())e=a<0?f.text.length:0;else return!1;else e+=a;return!0}var c=bu.inverted?bu.from:bu.to,d=c.line,e=c.ch,f=bV(d);if(b=="char")h();else if(b=="column")h(!0);else if(b=="word"){var i=!1;for(;;){if(a<0&&!h())break;if(bb(f.text.charAt(e)))i=!0;else if(i){a<0&&(a=1,h());break}if(a>0&&!h())break}}return{line:d,ch:e}}function cT(a,b){var c=a<0?bu.from:bu.to;if(bv||W(bu.from,bu.to))c=cS(a,b);cP(c.line,c.ch,!0)}function cU(a,b){W(bu.from,bu.to)?a<0?cq("",cS(a,b),bu.to):cq("",bu.from,cS(a,b)):cq("",bu.from,bu.to),bD=!0}function cW(a,b){var c=0,d=ds(bu.inverted?bu.from:bu.to,!0);cV!=null&&(d.x=cV),b=="page"?c=Math.min(R.clientHeight,window.innerHeight||document.documentElement.clientHeight):b=="line"&&(c=dy());var e=dt(d.x,d.y+c*a+2);cP(e.line,e.ch,!0),cV=d.x}function cX(a){var b=bV(a.line).text,c=a.ch,d=a.ch;while(c>0&&bb(b.charAt(c-1)))--c;while(d<b.length&&bb(b.charAt(d)))++d;cM({line:a.line,ch:c},{line:a.line,ch:d})}function cY(a){cM({line:a,ch:0},cR({line:a+1,ch:0}))}function cZ(a){if(W(bu.from,bu.to))return c$(bu.from.line,a);var b=bu.to.line-(bu.to.ch?0:1);for(var c=bu.from.line;c<=b;++c)c$(c,a)}function c$(a,b){b||(b="add");if(b=="smart")if(!bq.indent)b="prev";else var c=dK(a);var d=bV(a),e=d.indentation(f.tabSize),g=d.text.match(/^\s*/)[0],h;b=="prev"?a?h=bV(a-1).indentation(f.tabSize):h=0:b=="smart"?h=bq.indent(c,d.text.slice(g.length),d.text):b=="add"?h=e+f.indentUnit:b=="subtract"&&(h=e-f.indentUnit),h=Math.max(0,h);var i=h-e;if(!i){if(bu.from.line!=a&&bu.to.line!=a)return;var j=g}else{var j="",k=0;if(f.indentWithTabs)for(var l=Math.floor(h/f.tabSize);l;--l)k+=f.tabSize,j+="\t";while(k<h)++k,j+=" "}cq(j,{line:a,ch:0},{line:a,ch:g.length})}function c_(){bq=a.getMode(f,f.mode),br.iter(0,br.size,function(a){a.stateAfter=null}),bs=[0],dN()}function da(){var a=f.gutter||f.lineNumbers;bf.style.display=a?"":"none",a?bI=!0:bl.parentNode.style.marginLeft=0}function db(a,b){if(f.lineWrapping){A.className+=" CodeMirror-wrap";var c=R.clientWidth/dB()-3;br.iter(0,br.size,function(a){if(a.hidden)return;var b=Math.ceil(a.text.length/c)||1;b!=1&&bW(a,b)}),bh.style.width=S.style.width=""}else A.className=A.className.replace(" CodeMirror-wrap",""),bQ=null,bP="",br.iter(0,br.size,function(a){a.height!=1&&!a.hidden&&bW(a,1),a.text.length>bP.length&&(bP=a.text)});bE.push({from:0,to:br.size})}function dc(a){var b=f.tabSize-a%f.tabSize;for(var c='<span class="cm-tab">',d=0;d<b;++d)c+=" ";return{html:c+"</span>",width:b}}function dd(){R.className=R.className.replace(/\s*cm-s-\w+/g,"")+f.theme.replace(/(^|\s)\s*/g," cm-s-")}function de(){this.set=[]}function df(a,b,c){function e(a,b,c,e){bV(a).addMark(new p(b,c,e,d.set))}a=cR(a),b=cR(b);var d=new de;if(a.line==b.line)e(a.line,a.ch,b.ch,c);else{e(a.line,a.ch,null,c);for(var f=a.line+1,g=b.line;f<g;++f)e(f,null,null,c);e(b.line,null,b.ch,c)}return bE.push({from:a.line,to:b.line+1}),d}function dg(a){a=cR(a);var b=new q(a.ch);return bV(a.line).addMark(b),b}function dh(a,b,c){return typeof a=="number"&&(a=bV(cQ(a))),a.gutterMarker={text:b,style:c},bI=!0,a}function di(a){typeof a=="number"&&(a=bV(cQ(a))),a.gutterMarker=null,bI=!0}function dj(a,b){var c=a,d=a;typeof a=="number"?d=bV(cQ(a)):c=w(a);if(c==null)return null;if(b(d,c))bE.push({from:c,to:c+1});else return null;return d}function dk(a,b){return dj(a,function(a){if(a.className!=b)return a.className=b,!0})}function dl(a,b){return dj(a,function(a,c){if(a.hidden!=b){a.hidden=b,bW(a,b?0:1);var d=bu.from.line,e=bu.to.line;if(b&&(d==c||e==c)){var f=d==c?cO({line:d,ch:0},d,0):bu.from,g=e==c?cO({line:e,ch:0},e,0):bu.to;cN(f,g)}return bI=!0}})}function dm(a){if(typeof a=="number"){if(!bT(a))return null;var b=a;a=bV(a);if(!a)return null}else{var b=w(a);if(b==null)return null}var c=a.gutterMarker;return{line:b,handle:a,text:a.text,markerText:c&&c.text,markerClass:c&&c.style,lineClass:a.className}}function dn(a){return bi.innerHTML="<pre><span>x</span></pre>",bi.firstChild.firstChild.firstChild.nodeValue=a,bi.firstChild.firstChild.offsetWidth||10}function dp(a,b){function e(a){return bi.innerHTML="<pre><span>"+c.getHTML(dc,a)+"</span></pre>",bi.firstChild.firstChild.offsetWidth}if(b<=0)return 0;var c=bV(a),d=c.text,f=0,g=0,h=d.length,i,j=Math.min(h,Math.ceil(b/dB()));for(;;){var k=e(j);if(k<=b&&j<h)j=Math.min(h,Math.ceil(j*1.2));else{i=k,h=j;break}}if(b>i)return h;j=Math.floor(h*.8),k=e(j),k<b&&(f=j,g=k);for(;;){if(h-f<=1)return i-b>b-g?f:h;var l=Math.ceil((f+h)/2),m=e(l);m>b?(h=l,i=m):(f=l,g=m)}}function dr(a,b){if(b==0)return{top:0,left:0};var c="";if(f.lineWrapping){var d=a.text.indexOf(" ",b+2);c=$(a.text.slice(b+1,d<0?a.text.length:d+(N?5:0)))}bi.innerHTML="<pre>"+a.getHTML(dc,b)+'<span id="CodeMirror-temp-'+dq+'">'+$(a.text.charAt(b)||" ")+"</span>"+c+"</pre>";var e=document.getElementById("CodeMirror-temp-"+dq),g=e.offsetTop,h=e.offsetLeft;if(N&&g==0&&h==0){var i=document.createElement("span");i.innerHTML="x",e.parentNode.insertBefore(i,e.nextSibling),g=i.offsetTop}return{top:g,left:h}}function ds(a,b){var c,d=dy(),e=d*(y(br,a.line)-(b?bK:0));if(a.ch==0)c=0;else{var g=dr(bV(a.line),a.ch);c=g.left,f.lineWrapping&&(e+=Math.max(0,g.top))}return{x:c,y:e,yBot:e+d}}function dt(a,b){function l(a){var b=dr(h,a);if(j){var d=Math.round(b.top/c);return Math.max(0,b.left+(d-k)*R.clientWidth)}return b.left}b<0&&(b=0);var c=dy(),d=dB(),e=bK+Math.floor(b/c),g=x(br,e);if(g>=br.size)return{line:br.size-1,ch:bV(br.size-1).text.length};var h=bV(g),i=h.text,j=f.lineWrapping,k=j?e-y(br,g):0;if(a<=0&&k==0)return{line:g,ch:0};var m=0,n=0,o=i.length,p,q=Math.min(o,Math.ceil((a+k*R.clientWidth*.9)/d));for(;;){var r=l(q);if(r<=a&&q<o)q=Math.min(o,Math.ceil(q*1.2));else{p=r,o=q;break}}if(a>p)return{line:g,ch:o};q=Math.floor(o*.8),r=l(q),r<a&&(m=q,n=r);for(;;){if(o-m<=1)return{line:g,ch:p-a>a-n?m:o};var s=Math.ceil((m+o)/2),t=l(s);t>a?(o=s,p=t):(m=s,n=t)}}function du(a){var b=ds(a,!0),c=T(bh);return{x:c.left+b.x,y:c.top+b.y,yBot:c.top+b.yBot}}function dy(){if(dx==null){dx="<pre>";for(var a=0;a<49;++a)dx+="x<br/>";dx+="x</pre>"}var b=bl.clientHeight;return b==dw?dv:(dw=b,bi.innerHTML=dx,dv=bi.firstChild.offsetHeight/50||1,bi.innerHTML="",dv)}function dB(){return R.clientWidth==dA?dz:(dA=R.clientWidth,dz=dn("x"))}function dC(){return bh.offsetTop}function dD(){return bh.offsetLeft}function dE(a,b){var c=T(R,!0),d,e;try{d=a.clientX,e=a.clientY}catch(a){return null}if(!b&&(d-c.left>R.clientWidth||e-c.top>R.clientHeight))return null;var f=T(bh,!0);return dt(d-f.left,e-f.top)}function dF(a){function f(){var a=bc(Q.value).join("\n");a!=e&&dR(cr)(a,"end"),D.style.position="relative",Q.style.cssText=d,O&&(R.scrollTop=c),bH=!1,cA(!0),cw()}var b=dE(a),c=R.scrollTop;if(!b||window.opera)return;(W(bu.from,bu.to)||X(b,bu.from)||!X(b,bu.to))&&dR(cP)(b.line,b.ch);var d=Q.style.cssText;D.style.position="absolute",Q.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: white; "+"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",bH=!0;var e=Q.value=cu();cB(),V(Q);if(M){E(a);var g=I(window,"mouseup",function(){g(),setTimeout(f,20)},!0)}else setTimeout(f,50)}function dG(){clearInterval(bp);var a=!0;bj.style.visibility="",bp=setInterval(function(){bj.style.visibility=(a=!a)?"":"hidden"},650)}function dI(a){function p(a,b,c){if(!a.text)return;var d=a.styles,e=g?0:a.text.length-1,f;for(var i=g?0:d.length-2,j=g?d.length:-2;i!=j;i+=2*h){var k=d[i];if(d[i+1]!=null&&d[i+1]!=m){e+=h*k.length;continue}for(var l=g?0:k.length-1,p=g?k.length:-1;l!=p;l+=h,e+=h)if(e>=b&&e<c&&o.test(f=k.charAt(l))){var q=dH[f];if(q.charAt(1)==">"==g)n.push(f);else{if(n.pop()!=q.charAt(0))return{pos:e,match:!1};if(!n.length)return{pos:e,match:!0}}}}}var b=bu.inverted?bu.from:bu.to,c=bV(b.line),d=b.ch-1,e=d>=0&&dH[c.text.charAt(d)]||dH[c.text.charAt(++d)];if(!e)return;var f=e.charAt(0),g=e.charAt(1)==">",h=g?1:-1,i=c.styles;for(var j=d+1,k=0,l=i.length;k<l;k+=2)if((j-=i[k].length)<=0){var m=i[k+1];break}var n=[c.text.charAt(d)],o=/[(){}[\]]/;for(var k=b.line,l=g?Math.min(k+100,br.size):Math.max(-1,k-100);k!=l;k+=h){var c=bV(k),q=k==b.line,r=p(c,q&&g?d+1:0,q&&!g?d:c.text.length);if(r)break}r||(r={pos:null,match:!1});var m=r.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",s=df({line:b.line,ch:d},{line:b.line,ch:d+1},m),t=r.pos!=null&&df({line:k,ch:r.pos},{line:k,ch:r.pos+1},m),u=dR(function(){s.clear(),t&&t.clear()});a?setTimeout(u,800):bO=u}function dJ(a){var b,c;for(var d=a,e=a-40;d>e;--d){if(d==0)return 0;var g=bV(d-1);if(g.stateAfter)return d;var h=g.indentation(f.tabSize);if(c==null||b>h)c=d-1,b=h}return c}function dK(a){var b=dJ(a),c=b&&bV(b-1).stateAfter;return c?c=m(bq,c):c=n(bq),br.iter(b,a,function(a){a.highlight(bq,c,f.tabSize),a.stateAfter=m(bq,c)}),b<a&&bE.push({from:b,to:a}),a<br.size&&!bV(a).stateAfter&&bs.push(a),c}function dL(a,b){var c=dK(a);br.iter(a,b,function(a){a.highlight(bq,c,f.tabSize),a.stateAfter=m(bq,c)})}function dM(){var a=+(new Date)+f.workTime,b=bs.length;while(bs.length){if(!bV(bL).stateAfter)var c=bL;else var c=bs.pop();if(c>=br.size)continue;var d=dJ(c),e=d&&bV(d-1).stateAfter;e?e=m(bq,e):e=n(bq);var g=0,h=bq.compareStates,i=!1,j=d,k=!1;br.iter(j,br.size,function(b){var d=b.stateAfter;if(+(new Date)>a)return bs.push(j),dN(f.workDelay),i&&bE.push({from:c,to:j+1}),k=!0;var l=b.highlight(bq,e,f.tabSize);l&&(i=!0),b.stateAfter=m(bq,e);if(h){if(d&&h(d,e))return!0}else if(l!==!1||!d)g=0;else if(++g>3&&(!bq.indent||bq.indent(d,"")==bq.indent(e,"")))return!0;++j});if(k)return;i&&bE.push({from:c,to:j+1})}b&&f.onHighlightComplete&&f.onHighlightComplete(bU)}function dN(a){if(!bs.length)return;bo.set(a,dR(dM))}function dO(){bC=bD=bF=null,bE=[],bG=!1,bJ=[]}function dP(){var a=!1,b;bG&&(a=!cD()),bE.length?b=cG(bE,!0):(bG&&cK(),bI&&cJ()),a&&cD(),bG&&(cC(),dG()),bt&&!bH&&(bC===!0||bC!==!1&&bG)&&cA(bD),bG&&f.matchBrackets&&setTimeout(dR(function(){bO&&(bO(),bO=null),W(bu.from,bu.to)&&dI(!1)}),20);var c=bF,d=bJ;bG&&f.onCursorActivity&&f.onCursorActivity(bU),c&&f.onChange&&bU&&f.onChange(bU,c);for(var e=0;e<d.length;++e)d[e](bU);b&&f.onUpdate&&f.onUpdate(bU)}function dR(a){return function(){dQ++||dO();try{var b=a.apply(this,arguments)}finally{--dQ||dP()}return b}}var f={},i=a.defaults;for(var o in i)i.hasOwnProperty(o)&&(f[o]=(e&&e.hasOwnProperty(o)?e:i)[o]);var s=f.document,A=s.createElement("div");A.className="CodeMirror"+(f.lineWrapping?" CodeMirror-wrap":""),A.innerHTML='<div style="overflow: hidden; position: relative; width: 3px; height: 0px;"><textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" autocorrect="off" autocapitalize="off"></textarea></div><div class="CodeMirror-scroll" tabindex="-1"><div style="position: relative"><div style="position: relative"><div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div><div class="CodeMirror-lines"><div style="position: relative; z-index: 0"><div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden;"></div><pre class="CodeMirror-cursor"> </pre><div style="position: relative; z-index: -1"></div><div></div></div></div></div></div></div>',d.appendChild?d.appendChild(A):d(A);var D=A.firstChild,Q=D.firstChild,R=A.lastChild,S=R.firstChild,Z=S.firstChild,bf=Z.firstChild,bg=bf.firstChild,bh=bf.nextSibling.firstChild,bi=bh.firstChild,bj=bi.nextSibling,bk=bj.nextSibling,bl=bk.nextSibling;dd(),b&&(Q.style.width="0px"),P||(bh.draggable=!0),bh.style.outline="none",f.tabindex!=null&&(Q.tabIndex=f.tabindex),!f.gutter&&!f.lineNumbers&&(bf.style.display="none");try{dn("x")}catch(bm){throw bm.message.match(/runtime/i)&&(bm=new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)")),bm}var bn=new J,bo=new J,bp,bq,br=new u([new t([new r("")])]),bs,bt;c_();var bu={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},bv,bw,bx,by=0,bz,bA=!1,bB=!1,bC,bD,bE,bF,bG,bH,bI,bJ,bK=0,bL=0,bM=0,bN=0,bO,bP="",bQ;dR(function(){bX(f.value||""),bC=!1})();var bR=new z;I(R,"mousedown",dR(bZ)),I(R,"dblclick",dR(b$)),I(bh,"dragstart",ca),I(bh,"selectstart",C),M||I(R,"contextmenu",dF),I(R,"scroll",function(){by=R.scrollTop,cG([]),f.fixedGutter&&(bf.style.left=R.scrollLeft+"px"),f.onScroll&&f.onScroll(bU)}),I(window,"resize",function(){cG(!0)}),I(Q,"keyup",dR(ci)),I(Q,"input",cx),I(Q,"keydown",dR(cg)),I(Q,"keypress",dR(ch)),I(Q,"focus",cj),I(Q,"blur",ck),I(R,"dragenter",E),I(R,"dragover",E),I(R,"drop",dR(b_)),I(R,"paste",function(){cB(),cx()}),I(Q,"paste",cx),I(Q,"cut",dR(function(){f.readOnly||cr("")}));var bS;try{bS=s.activeElement==Q}catch(bm){}bS?setTimeout(cj,20):ck();var bU=A.CodeMirror={getValue:bY,setValue:dR(bX),getSelection:cu,replaceSelection:dR(cr),focus:function(){window.focus(),cB(),cj(),cx()},setOption:function(a,b){var c=f[a];f[a]=b,a=="mode"||a=="indentUnit"?c_():a=="readOnly"&&b=="nocursor"?(ck(),Q.blur()):a=="readOnly"&&!b?cA(!0):a=="theme"?dd():a=="lineWrapping"&&c!=b?dR(db)():a=="tabSize"&&cG(!0);if(a=="lineNumbers"||a=="gutter"||a=="firstLineNumber"||a=="theme")da(),cG(!0)},getOption:function(a){return f[a]},undo:dR(cn),redo:dR(co),indentLine:dR(function(a,b){typeof b!="string"&&(b==null?b=f.smartIndent?"smart":"prev":b=b?"add":"subtract"),bT(a)&&c$(a,b)}),indentSelection:dR(cZ),historySize:function(){return{undo:bR.done.length,redo:bR.undone.length}},clearHistory:function(){bR=new z},matchBrackets:dR(function(){dI(!0)}),getTokenAt:dR(function(a){return a=cR(a),bV(a.line).getTokenAt(bq,dK(a.line),a.ch)}),getStateAfter:function(a){return a=cQ(a==null?br.size-1:a),dK(a+1)},cursorCoords:function(a){return a==null&&(a=bu.inverted),du(a?bu.from:bu.to)},charCoords:function(a){return du(cR(a))},coordsChar:function(a){var b=T(bh);return dt(a.x-b.left,a.y-b.top)},markText:dR(df),setBookmark:dg,setMarker:dR(dh),clearMarker:dR(di),setLineClass:dR(dk),hideLine:dR(function(a){return dl(a,!0)}),showLine:dR(function(a){return dl(a,!1)}),onDeleteLine:function(a,b){if(typeof a=="number"){if(!bT(a))return null;a=bV(a)}return(a.handlers||(a.handlers=[])).push(b),a},lineInfo:dm,addWidget:function(a,b,c,d,e){a=ds(cR(a));var f=a.yBot,g=a.x;b.style.position="absolute",S.appendChild(b);if(d=="over")f=a.y;else if(d=="near"){var h=Math.max(R.offsetHeight,br.height*dy()),i=Math.max(S.clientWidth,bh.clientWidth)-dD();a.yBot+b.offsetHeight>h&&a.y>b.offsetHeight&&(f=a.y-b.offsetHeight),g+b.offsetWidth>i&&(g=i-b.offsetWidth)}b.style.top=f+dC()+"px",b.style.left=b.style.right="",e=="right"?(g=S.clientWidth-b.offsetWidth,b.style.right="0px"):(e=="left"?g=0:e=="middle"&&(g=(S.clientWidth-b.offsetWidth)/2),b.style.left=g+dD()+"px"),c&&cE(g,f,g+b.offsetWidth,f+b.offsetHeight)},lineCount:function(){return br.size},clipPos:cR,getCursor:function(a){return a==null&&(a=bu.inverted),Y(a?bu.from:bu.to)},somethingSelected:function(){return!W(bu.from,bu.to)},setCursor:dR(function(a,b,c){b==null&&typeof a.line=="number"?cP(a.line,a.ch,c):cP(a,b,c)}),setSelection:dR(function(a,b,c){(c?cM:cN)(cR(a),cR(b||a))}),getLine:function(a){if(bT(a))return bV(a).text},getLineHandle:function(a){if(bT(a))return bV(a)},setLine:dR(function(a,b){bT(a)&&cq(b,{line:a,ch:0},{line:a,ch:bV(a).text.length})}),removeLine:dR(function(a){bT(a)&&cq("",{line:a,ch:0},cR({line:a+1,ch:0}))}),replaceRange:dR(cq),getRange:function(a,b){return ct(cR(a),cR(b))},execCommand:function(a){return h[a](bU)},moveH:dR(cT),deleteH:dR(cU),moveV:dR(cW),toggleOverwrite:function(){bA?(bA=!1,bj.className=bj.className.replace(" CodeMirror-overwrite","")):(bA=!0,bj.className+=" CodeMirror-overwrite")},posFromIndex:function(a){var b=0,c;return br.iter(0,br.size,function(d){var e=d.text.length+1;if(e>a)return c=a,!0;a-=e,++b}),cR({line:b,ch:c})},indexFromPos:function(a){if(a.line<0||a.ch<0)return 0;var b=a.ch;return br.iter(0,a.line,function(a){b+=a.text.length+1}),b},scrollTo:function(a,b){a!=null&&(R.scrollLeft=a),b!=null&&(R.scrollTop=b),cG([])},operation:function(a){return dR(a)()},refresh:function(){cG(!0),R.scrollHeight>by&&(R.scrollTop=by)},getInputField:function(){return Q},getWrapperElement:function(){return A},getScrollerElement:function(){return R},getGutterElement:function(){return bf}},ce=null,cf,cv=!1,cy="",cV=null;de.prototype.clear=dR(function(){var a=Infinity,b=-Infinity;for(var c=0,d=this.set.length;c<d;++c){var e=this.set[c],f=e.marked;if(!f||!e.parent)continue;var g=w(e);a=Math.min(a,g),b=Math.max(b,g);for(var h=0;h<f.length;++h)f[h].set==this.set&&f.splice(h--,1)}a!=Infinity&&bE.push({from:a,to:b+1})}),de.prototype.find=function(){var a,b;for(var c=0,d=this.set.length;c<d;++c){var e=this.set[c],f=e.marked;for(var g=0;g<f.length;++g){var h=f[g];if(h.set==this.set)if(h.from!=null||h.to!=null){var i=w(e);i!=null&&(h.from!=null&&(a={line:i,ch:h.from}),h.to!=null&&(b={line:i,ch:h.to}))}}}return{from:a,to:b}};var dq=Math.floor(Math.random()*16777215).toString(16),dv,dw,dx,dz,dA=0,dH={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},dQ=0;for(var dS in g)g.propertyIsEnumerable(dS)&&!bU.propertyIsEnumerable(dS)&&(bU[dS]=g[dS]);return bU}function j(a){return typeof a=="string"?i[a]:a}function k(a,b,c,d){function e(b){b=j(b);var c=b[a];if(c!=null&&d(c))return!0;if(b.catchall)return d(b.catchall);var f=b.fallthrough;if(f==null)return!1;if(Object.prototype.toString.call(f)!="[object Array]")return e(f);for(var g=0,h=f.length;g<h;++g)if(e(f[g]))return!0;return!1}return b&&e(b)?!0:e(c)}function l(a){var b=be[H(a,"keyCode")];return b=="Ctrl"||b=="Alt"||b=="Shift"||b=="Mod"}function m(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c}function n(a,b,c){return a.startState?a.startState(b,c):!0}function o(a,b){this.pos=this.start=0,this.string=a,this.tabSize=b||8}function p(a,b,c,d){this.from=a,this.to=b,this.style=c,this.set=d}function q(a){this.from=a,this.to=a,this.line=null}function r(a,b){this.styles=b||[a,null],this.text=a,this.height=1,this.marked=this.gutterMarker=this.className=
this.handlers=null,this.stateAfter=this.parent=this.hidden=null}function s(a,b,c,d){for(var e=0,f=0,g=0;f<b;e+=2){var h=c[e],i=f+h.length;g==0?(i>a&&d.push(h.slice(a-f,Math.min(h.length,b-f)),c[e+1]),i>=a&&(g=1)):g==1&&(i>b?d.push(h.slice(0,b-f),c[e+1]):d.push(h,c[e+1])),f=i}}function t(a){this.lines=a,this.parent=null;for(var b=0,c=a.length,d=0;b<c;++b)a[b].parent=this,d+=a[b].height;this.height=d}function u(a){this.children=a;var b=0,c=0;for(var d=0,e=a.length;d<e;++d){var f=a[d];b+=f.chunkSize(),c+=f.height,f.parent=this}this.size=b,this.height=c,this.parent=null}function v(a,b){while(!a.lines)for(var c=0;;++c){var d=a.children[c],e=d.chunkSize();if(b<e){a=d;break}b-=e}return a.lines[b]}function w(a){if(a.parent==null)return null;var b=a.parent,c=ba(b.lines,a);for(var d=b.parent;d;b=d,d=d.parent)for(var e=0,f=d.children.length;;++e){if(d.children[e]==b)break;c+=d.children[e].chunkSize()}return c}function x(a,b){var c=0;a:do{for(var d=0,e=a.children.length;d<e;++d){var f=a.children[d],g=f.height;if(b<g){a=f;continue a}b-=g,c+=f.chunkSize()}return c}while(!a.lines);for(var d=0,e=a.lines.length;d<e;++d){var h=a.lines[d],i=h.height;if(b<i)break;b-=i}return c+d}function y(a,b){var c=0;a:do{for(var d=0,e=a.children.length;d<e;++d){var f=a.children[d],g=f.chunkSize();if(b<g){a=f;continue a}b-=g,c+=f.height}return c}while(!a.lines);for(var d=0;d<b;++d)c+=a.lines[d].height;return c}function z(){this.time=0,this.done=[],this.undone=[]}function A(){E(this)}function B(a){return a.stop||(a.stop=A),a}function C(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function D(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function E(a){C(a),D(a)}function F(a){return a.target||a.srcElement}function G(a){if(a.which)return a.which;if(a.button&1)return 1;if(a.button&2)return 3;if(a.button&4)return 2}function H(a,b){var c=a.override&&a.override.hasOwnProperty(b);return c?a.override[b]:a[b]}function I(a,b,c,d){if(typeof a.addEventListener=="function"){a.addEventListener(b,c,!1);if(d)return function(){a.removeEventListener(b,c,!1)}}else{var e=function(a){c(a||window.event)};a.attachEvent("on"+b,e);if(d)return function(){a.detachEvent("on"+b,e)}}}function J(){this.id=null}function R(a,b,c){b==null&&(b=a.search(/[^\s\u00a0]/),b==-1&&(b=a.length));for(var d=0,e=0;d<b;++d)a.charAt(d)=="\t"?e+=c-e%c:++e;return e}function S(a){return a.currentStyle?a.currentStyle:window.getComputedStyle(a,null)}function T(a,b){var c=a.ownerDocument.body,d=0,e=0,f=!1;for(var g=a;g;g=g.offsetParent){var h=g.offsetLeft,i=g.offsetTop;g==c?(d+=Math.abs(h),e+=Math.abs(i)):(d+=h,e+=i),b&&S(g).position=="fixed"&&(f=!0)}var j=b&&!f?null:c;for(var g=a.parentNode;g!=j;g=g.parentNode)g.scrollLeft!=null&&(d-=g.scrollLeft,e-=g.scrollTop);return{left:d,top:e}}function U(a){return a.textContent||a.innerText||a.nodeValue||""}function V(a){b?(a.selectionStart=0,a.selectionEnd=a.value.length):a.select()}function W(a,b){return a.line==b.line&&a.ch==b.ch}function X(a,b){return a.line<b.line||a.line==b.line&&a.ch<b.ch}function Y(a){return{line:a.line,ch:a.ch}}function $(a){return Z.textContent=a,Z.innerHTML}function _(a,b){if(!b)return 0;if(!a)return b.length;for(var c=a.length,d=b.length;c>=0&&d>=0;--c,--d)if(a.charAt(c)!=b.charAt(d))break;return d+1}function ba(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c<d;++c)if(a[c]==b)return c;return-1}function bb(a){return/\w/.test(a)||a.toUpperCase()!=a.toLowerCase()}a.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,smartIndent:!0,tabSize:4,keyMap:"default",extraKeys:null,electricChars:!0,autoClearEmptyLines:!1,onKeyEvent:null,lineWrapping:!1,lineNumbers:!1,gutter:!1,fixedGutter:!1,firstLineNumber:1,readOnly:!1,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onUpdate:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,pollInterval:100,undoDepth:40,tabindex:null,document:window.document};var b=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent),c=b||/Mac/.test(navigator.platform),d=/Win/.test(navigator.platform),e={},f={};a.defineMode=function(b,c){!a.defaults.mode&&b!="null"&&(a.defaults.mode=b),e[b]=c},a.defineMIME=function(a,b){f[a]=b},a.resolveMode=function(a){return typeof a=="string"&&f.hasOwnProperty(a)&&(a=f[a]),typeof a=="string"?{name:a}:a||{name:"null"}},a.getMode=function(b,c){var c=a.resolveMode(c),d=e[c.name];return d?d(b,c):(window.console&&console.warn("No mode "+c.name+" found, falling back to plain text."),a.getMode(b,"text/plain"))},a.listModes=function(){var a=[];for(var b in e)e.propertyIsEnumerable(b)&&a.push(b);return a},a.listMIMEs=function(){var a=[];for(var b in f)f.propertyIsEnumerable(b)&&a.push({mime:b,mode:f[b]});return a};var g=a.extensions={};a.defineExtension=function(a,b){g[a]=b};var h=a.commands={selectAll:function(a){a.setSelection({line:0,ch:0},{line:a.lineCount()-1})},killLine:function(a){var b=a.getCursor(!0),c=a.getCursor(!1),d=!W(b,c);!d&&a.getLine(b.line).length==b.ch?a.replaceRange("",b,{line:b.line+1,ch:0}):a.replaceRange("",b,d?c:{line:b.line})},deleteLine:function(a){var b=a.getCursor().line;a.replaceRange("",{line:b,ch:0},{line:b})},undo:function(a){a.undo()},redo:function(a){a.redo()},goDocStart:function(a){a.setCursor(0,0,!0)},goDocEnd:function(a){a.setSelection({line:a.lineCount()-1},null,!0)},goLineStart:function(a){a.setCursor(a.getCursor().line,0,!0)},goLineStartSmart:function(a){var b=a.getCursor(),c=a.getLine(b.line),d=Math.max(0,c.search(/\S/));a.setCursor(b.line,b.ch<=d&&b.ch?0:d,!0)},goLineEnd:function(a){a.setSelection({line:a.getCursor().line},null,!0)},goLineUp:function(a){a.moveV(-1,"line")},goLineDown:function(a){a.moveV(1,"line")},goPageUp:function(a){a.moveV(-1,"page")},goPageDown:function(a){a.moveV(1,"page")},goCharLeft:function(a){a.moveH(-1,"char")},goCharRight:function(a){a.moveH(1,"char")},goColumnLeft:function(a){a.moveH(-1,"column")},goColumnRight:function(a){a.moveH(1,"column")},goWordLeft:function(a){a.moveH(-1,"word")},goWordRight:function(a){a.moveH(1,"word")},delCharLeft:function(a){a.deleteH(-1,"char")},delCharRight:function(a){a.deleteH(1,"char")},delWordLeft:function(a){a.deleteH(-1,"word")},delWordRight:function(a){a.deleteH(1,"word")},indentAuto:function(a){a.indentSelection("smart")},indentMore:function(a){a.indentSelection("add")},indentLess:function(a){a.indentSelection("subtract")},insertTab:function(a){a.replaceSelection("\t","end")},transposeChars:function(a){var b=a.getCursor(),c=a.getLine(b.line);b.ch>0&&b.ch<c.length-1&&a.replaceRange(c.charAt(b.ch)+c.charAt(b.ch-1),{line:b.line,ch:b.ch-1},{line:b.line,ch:b.ch+1})},newlineAndIndent:function(a){a.replaceSelection("\n","end"),a.indentLine(a.getCursor().line)},toggleOverwrite:function(a){a.toggleOverwrite()}},i=a.keyMap={};i.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharRight",Backspace:"delCharLeft",Tab:"indentMore","Shift-Tab":"indentLess",Enter:"newlineAndIndent",Insert:"toggleOverwrite"},i.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Alt-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goWordLeft","Ctrl-Right":"goWordRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delWordLeft","Ctrl-Delete":"delWordRight","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll",fallthrough:"basic"},i.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goWordLeft","Alt-Right":"goWordRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delWordLeft","Ctrl-Alt-Backspace":"delWordRight","Alt-Delete":"delWordRight","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll",fallthrough:["basic","emacsy"]},i["default"]=c?i.macDefault:i.pcDefault,i.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageUp","Shift-Ctrl-V":"goPageDown","Ctrl-D":"delCharRight","Ctrl-H":"delCharLeft","Alt-D":"delWordRight","Alt-Backspace":"delWordLeft","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},a.fromTextArea=function(b,c){function d(){b.value=h.getValue()}c||(c={}),c.value=b.value,!c.tabindex&&b.tabindex&&(c.tabindex=b.tabindex);if(b.form){var e=I(b.form,"submit",d,!0);if(typeof b.form.submit=="function"){var f=b.form.submit;function g(){d(),b.form.submit=f,b.form.submit(),b.form.submit=g}b.form.submit=g}}b.style.display="none";var h=a(function(a){b.parentNode.insertBefore(a,b.nextSibling)},c);return h.save=d,h.getTextArea=function(){return b},h.toTextArea=function(){d(),b.parentNode.removeChild(h.getWrapperElement()),b.style.display="",b.form&&(e(),typeof b.form.submit=="function"&&(b.form.submit=f))},h},a.copyState=m,a.startState=n,o.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(a){var b=this.string.charAt(this.pos);if(typeof a=="string")var c=b==a;else var c=b&&(a.test?a.test(b):a(b));if(c)return++this.pos,b},eatWhile:function(a){var b=this.pos;while(this.eat(a));return this.pos>b},eatSpace:function(){var a=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);if(b>-1)return this.pos=b,!0},backUp:function(a){this.pos-=a},column:function(){return R(this.string,this.start,this.tabSize)},indentation:function(){return R(this.string,null,this.tabSize)},match:function(a,b,c){if(typeof a!="string"){var e=this.string.slice(this.pos).match(a);return e&&b!==!1&&(this.pos+=e[0].length),e}function d(a){return c?a.toLowerCase():a}if(d(this.string).indexOf(d(a),this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},a.StringStream=o,p.prototype={attach:function(a){this.set.push(a)},detach:function(a){var b=ba(this.set,a);b>-1&&this.set.splice(b,1)},split:function(a,b){if(this.to<=a&&this.to!=null)return null;var c=this.from<a||this.from==null?null:this.from-a+b,d=this.to==null?null:this.to-a+b;return new p(c,d,this.style,this.set)},dup:function(){return new p(null,null,this.style,this.set)},clipTo:function(a,b,c,d,e){this.from!=null&&this.from>=b&&(this.from=Math.max(d,this.from)+e),this.to!=null&&this.to>b&&(this.to=d<this.to?this.to+e:b),a&&d>this.from&&(d<this.to||this.to==null)&&(this.from=null),c&&(b<this.to||this.to==null)&&(b>this.from||this.from==null)&&(this.to=null)},isDead:function(){return this.from!=null&&this.to!=null&&this.from>=this.to},sameSet:function(a){return this.set==a.set}},q.prototype={attach:function(a){this.line=a},detach:function(a){this.line==a&&(this.line=null)},split:function(a,b){if(a<this.from)return this.from=this.to=this.from-a+b,this},isDead:function(){return this.from>this.to},clipTo:function(a,b,c,d,e){(a||b<this.from)&&(c||d>this.to)?(this.from=0,this.to=-1):this.from>b&&(this.from=this.to=Math.max(d,this.from)+e)},sameSet:function(a){return!1},find:function(){return!this.line||!this.line.parent?null:{line:w(this.line),ch:this.from}},clear:function(){if(this.line){var a=ba(this.line.marked,this);a!=-1&&this.line.marked.splice(a,1),this.line=null}}},r.inheritMarks=function(a,b){var c=new r(a),d=b&&b.marked;if(d)for(var e=0;e<d.length;++e)if(d[e].to==null&&d[e].style){var f=c.marked||(c.marked=[]),g=d[e],h=g.dup();f.push(h),h.attach(c)}return c},r.prototype={replace:function(a,b,c){var d=[],e=this.marked,f=b==null?this.text.length:b;s(0,a,this.styles,d),c&&d.push(c,null),s(f,this.text.length,this.styles,d),this.styles=d,this.text=this.text.slice(0,a)+c+this.text.slice(f),this.stateAfter=null;if(e){var g=c.length-(f-a);for(var h=0;h<e.length;++h){var i=e[h];i.clipTo(a==null,a||0,b==null,f,g),i.isDead()&&(i.detach(this),e.splice(h--,1))}}},split:function(a,b){var c=[b,null],d=this.marked;s(a,this.text.length,this.styles,c);var e=new r(b+this.text.slice(a),c);if(d)for(var f=0;f<d.length;++f){var g=d[f],h=g.split(a,b.length);h&&(e.marked||(e.marked=[]),e.marked.push(h),h.attach(e))}return e},append:function(a){var b=this.text.length,c=a.marked,d=this.marked;this.text+=a.text,s(0,a.text.length,a.styles,this.styles);if(d)for(var e=0;e<d.length;++e)d[e].to==null&&(d[e].to=b);if(c&&c.length){d||(this.marked=d=[]);a:for(var e=0;e<c.length;++e){var f=c[e];if(!f.from)for(var g=0;g<d.length;++g){var h=d[g];if(h.to==b&&h.sameSet(f)){h.to=f.to==null?null:f.to+b,h.isDead()&&(h.detach(this),c.splice(e--,1));continue a}}d.push(f),f.attach(this),f.from+=b,f.to!=null&&(f.to+=b)}}},fixMarkEnds:function(a){var b=this.marked,c=a.marked;if(!b)return;for(var d=0;d<b.length;++d){var e=b[d],f=e.to==null;if(f&&c)for(var g=0;g<c.length;++g)if(c[g].sameSet(e)){f=!1;break}f&&(e.to=this.text.length)}},fixMarkStarts:function(){var a=this.marked;if(!a)return;for(var b=0;b<a.length;++b)a[b].from==null&&(a[b].from=0)},addMark:function(a){a.attach(this),this.marked==null&&(this.marked=[]),this.marked.push(a),this.marked.sort(function(a,b){return(a.from||0)-(b.from||0)})},highlight:function(a,b,c){var d=new o(this.text,c),e=this.styles,f=0,g=!1,h=e[0],i;this.text==""&&a.blankLine&&a.blankLine(b);while(!d.eol()){var j=a.token(d,b),k=this.text.slice(d.start,d.pos);d.start=d.pos,f&&e[f-1]==j?e[f-2]+=k:k&&(!g&&(e[f+1]!=j||f&&e[f-2]!=i)&&(g=!0),e[f++]=k,e[f++]=j,i=h,h=e[f]);if(d.pos>5e3){e[f++]=this.text.slice(d.pos),e[f++]=null;break}}return e.length!=f&&(e.length=f,g=!0),f&&e[f-2]!=i&&(g=!0),g||(e.length<5&&this.text.length<10?null:!1)},getTokenAt:function(a,b,c){var d=this.text,e=new o(d);while(e.pos<c&&!e.eol()){e.start=e.pos;var f=a.token(e,b)}return{start:e.start,end:e.pos,string:e.current(),className:f||null,state:b}},indentation:function(a){return R(this.text,null,a)},getHTML:function(a,b){function f(b,f){if(!b)return;d&&N&&b.charAt(0)==" "&&(b="\u00a0"+b.slice(1)),d=!1;if(b.indexOf("\t")==-1){e+=b.length;var g=$(b)}else{var g="";for(var h=0;;){var i=b.indexOf("\t",h);if(i==-1){g+=$(b.slice(h)),e+=b.length-h;break}e+=i-h;var j=a(e);g+=$(b.slice(h,i))+j.html,e+=j.width,h=i+1}}f?c.push('<span class="',f,'">',g,"</span>"):c.push(g)}function k(a){return a?"cm-"+a.replace(/ +/g," cm-"):null}var c=[],d=!0,e=0,g=this.styles,h=this.text,i=this.marked,j=h.length;b!=null&&(j=Math.min(b,j));if(!h&&b==null)f(" ");else if(!i||!i.length)for(var l=0,m=0;m<j;l+=2){var n=g[l],o=g[l+1],p=n.length;m+p>j&&(n=n.slice(0,j-m)),m+=p,f(n,k(o))}else{var q=0,l=0,r="",o,s=0,t=i[0].from||0,u=[],v=0;function w(){var a;while(v<i.length&&((a=i[v]).from==q||a.from==null))a.style!=null&&u.push(a),++v;t=v<i.length?i[v].from:Infinity;for(var b=0;b<u.length;++b){var c=u[b].to||Infinity;c==q?u.splice(b--,1):t=Math.min(c,t)}}var x=0;while(q<j){t==q&&w();var y=Math.min(j,t);for(;;){if(r){var z=q+r.length,A=o;for(var B=0;B<u.length;++B)A=(A?A+" ":"")+u[B].style;f(z>y?r.slice(0,y-q):r,A);if(z>=y){r=r.slice(y-q),q=y;break}q=z}r=g[l++],o=k(g[l++])}}}return c.join("")},cleanUp:function(){this.parent=null;if(this.marked)for(var a=0,b=this.marked.length;a<b;++a)this.marked[a].detach(this)}},t.prototype={chunkSize:function(){return this.lines.length},remove:function(a,b,c){for(var d=a,e=a+b;d<e;++d){var f=this.lines[d];this.height-=f.height,f.cleanUp();if(f.handlers)for(var g=0;g<f.handlers.length;++g)c.push(f.handlers[g])}this.lines.splice(a,b)},collapse:function(a){a.splice.apply(a,[a.length,0].concat(this.lines))},insertHeight:function(a,b,c){this.height+=c,this.lines.splice.apply(this.lines,[a,0].concat(b));for(var d=0,e=b.length;d<e;++d)b[d].parent=this},iterN:function(a,b,c){for(var d=a+b;a<d;++a)if(c(this.lines[a]))return!0}},u.prototype={chunkSize:function(){return this.size},remove:function(a,b,c){this.size-=b;for(var d=0;d<this.children.length;++d){var e=this.children[d],f=e.chunkSize();if(a<f){var g=Math.min(b,f-a),h=e.height;e.remove(a,g,c),this.height-=h-e.height,f==g&&(this.children.splice(d--,1),e.parent=null);if((b-=g)==0)break;a=0}else a-=f}if(this.size-b<25){var i=[];this.collapse(i),this.children=[new t(i)],this.children[0].parent=this}},collapse:function(a){for(var b=0,c=this.children.length;b<c;++b)this.children[b].collapse(a)},insert:function(a,b){var c=0;for(var d=0,e=b.length;d<e;++d)c+=b[d].height;this.insertHeight(a,b,c)},insertHeight:function(a,b,c){this.size+=b.length,this.height+=c;for(var d=0,e=this.children.length;d<e;++d){var f=this.children[d],g=f.chunkSize();if(a<=g){f.insertHeight(a,b,c);if(f.lines&&f.lines.length>50){while(f.lines.length>50){var h=f.lines.splice(f.lines.length-25,25),i=new t(h);f.height-=i.height,this.children.splice(d+1,0,i),i.parent=this}this.maybeSpill()}break}a-=g}},maybeSpill:function(){if(this.children.length<=10)return;var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new u(b);if(!a.parent){var d=new u(a.children);d.parent=a,a.children=[d,c],a=d}else{a.size-=c.size,a.height-=c.height;var e=ba(a.parent.children,a);a.parent.children.splice(e+1,0,c)}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()},iter:function(a,b,c){this.iterN(a,b-a,c)},iterN:function(a,b,c){for(var d=0,e=this.children.length;d<e;++d){var f=this.children[d],g=f.chunkSize();if(a<g){var h=Math.min(b,g-a);if(f.iterN(a,h,c))return!0;if((b-=h)==0)break;a=0}else a-=g}}},z.prototype={addChange:function(a,b,c){this.undone.length=0;var d=+(new Date),e=this.done[this.done.length-1],f=e&&e[e.length-1],g=d-this.time;if(g>400||!f)this.done.push([{start:a,added:b,old:c}]);else if(f.start>a+c.length||f.start+f.added<a-f.added+f.old.length)e.push({start:a,added:b,old:c});else{var h=0;if(a<f.start){for(var i=f.start-a-1;i>=0;--i)f.old.unshift(c[i]);f.added+=f.start-a,f.start=a}else f.start<a&&(h=a-f.start,b+=h);for(var i=f.added-h,j=c.length;i<j;++i)f.old.push(c[i]);f.added<b&&(f.added=b)}this.time=d}},a.e_stop=E,a.e_preventDefault=C,a.e_stopPropagation=D,a.connect=I,J.prototype={set:function(a,b){clearTimeout(this.id),this.id=setTimeout(b,a)}};var K=a.Pass={toString:function(){return"CodeMirror.Pass"}},L=function(){if(/MSIE [1-8]\b/.test(navigator.userAgent))return!1;var a=document.createElement("div");return"draggable"in a}(),M=/gecko\/\d{7}/i.test(navigator.userAgent),N=/MSIE \d/.test(navigator.userAgent),O=/MSIE [1-8]\b/.test(navigator.userAgent),P=/WebKit\//.test(navigator.userAgent),Q="\n";(function(){var a=document.createElement("textarea");a.value="foo\nbar",a.value.indexOf("\r")>-1&&(Q="\r\n")})(),document.documentElement.getBoundingClientRect!=null&&(T=function(a,b){try{var c=a.getBoundingClientRect();c={top:c.top,left:c.left}}catch(d){c={top:0,left:0}}if(!b)if(window.pageYOffset==null){var e=document.documentElement||document.body.parentNode;e.scrollTop==null&&(e=document.body),c.top+=e.scrollTop,c.left+=e.scrollLeft}else c.top+=window.pageYOffset,c.left+=window.pageXOffset;return c});var Z=document.createElement("pre");$("a")=="\na"?$=function(a){return Z.textContent=a,Z.innerHTML.slice(1)}:$("\t")!="\t"&&($=function(a){return Z.innerHTML="",Z.appendChild(document.createTextNode(a)),Z.innerHTML}),a.htmlEscape=$;var bc="\n\nb".split(/\n/).length!=3?function(a){var b=0,c,d=[];while((c=a.indexOf("\n",b))>-1)d.push(a.slice(b,a.charAt(c-1)=="\r"?c-1:c)),b=c+1;return d.push(a.slice(b)),d}:function(a){return a.split(/\r?\n/)};a.splitLines=bc;var bd=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return!b||b.parentElement()!=a?!1:b.compareEndPoints("StartToEnd",b)!=0};a.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),a.defineMIME("text/plain","null");var be={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};return a.keyNames=be,function(){for(var a=0;a<10;a++)be[a+48]=String(a);for(var a=65;a<=90;a++)be[a]=String.fromCharCode(a);for(var a=1;a<=12;a++)be[a+111]=be[a+63235]="F"+a}(),a}();
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.defineMode("css",function(a){function d(a,b){return c=b,a}function e(a,b){var c=a.next();if(c=="@")return a.eatWhile(/[\w\\\-]/),d("meta",a.current());if(c=="/"&&a.eat("*"))return b.tokenize=f,f(a,b);if(c=="<"&&a.eat("!"))return b.tokenize=g,g(a,b);if(c=="=")d(null,"compare");else return c!="~"&&c!="|"||!a.eat("=")?c=='"'||c=="'"?(b.tokenize=h(c),b.tokenize(a,b)):c=="#"?(a.eatWhile(/[\w\\\-]/),d("atom","hash")):c=="!"?(a.match(/^\s*\w*/),d("keyword","important")):/\d/.test(c)?(a.eatWhile(/[\w.%]/),d("number","unit")):/[,.+>*\/]/.test(c)?d(null,"select-op"):/[;{}:\[\]]/.test(c)?d(null,c):(a.eatWhile(/[\w\\\-]/),d("variable","variable")):d(null,"compare")}function f(a,b){var c=!1,f;while((f=a.next())!=null){if(c&&f=="/"){b.tokenize=e;break}c=f=="*"}return d("comment","comment")}function g(a,b){var c=0,f;while((f=a.next())!=null){if(c>=2&&f==">"){b.tokenize=e;break}c=f=="-"?c+1:0}return d("comment","comment")}function h(a){return function(b,c){var f=!1,g;while((g=b.next())!=null){if(g==a&&!f)break;f=!f&&g=="\\"}return f||(c.tokenize=e),d("string","string")}}var b=a.indentUnit,c;return{startState:function(a){return{tokenize:e,baseIndent:a||0,stack:[]}},token:function(a,b){if(a.eatSpace())return null;var d=b.tokenize(a,b),e=b.stack[b.stack.length-1];if(c=="hash"&&e=="rule")d="atom";else if(d=="variable")if(e=="rule")d="number";else if(!e||e=="@media{")d="tag";return e=="rule"&&/^[\{\};]$/.test(c)&&b.stack.pop(),c=="{"?e=="@media"?b.stack[b.stack.length-1]="@media{":b.stack.push("{"):c=="}"?b.stack.pop():c=="@media"?b.stack.push("@media"):e=="{"&&c!="comment"&&b.stack.push("rule"),d},indent:function(a,c){var d=a.stack.length;return/^\}/.test(c)&&(d-=a.stack[a.stack.length-1]=="rule"?2:1),a.baseIndent+d*b},electricChars:"}"}}),CodeMirror.defineMIME("text/css","css");
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.defineMode("htmlmixed",function(a,b){function f(a,b){var f=c.token(a,b.htmlState);return f=="tag"&&a.current()==">"&&b.htmlState.context&&(/^script$/i.test(b.htmlState.context.tagName)?(b.token=h,b.localState=d.startState(c.indent(b.htmlState,"")),b.mode="javascript"):/^style$/i.test(b.htmlState.context.tagName)&&(b.token=i,b.localState=e.startState(c.indent(b.htmlState,"")),b.mode="css")),f}function g(a,b,c){var d=a.current(),e=d.search(b);return e>-1&&a.backUp(d.length-e),c}function h(a,b){return a.match(/^<\/\s*script\s*>/i,!1)?(b.token=f,b.curState=null,b.mode="html",f(a,b)):g(a,/<\/\s*script\s*>/,d.token(a,b.localState))}function i(a,b){return a.match(/^<\/\s*style\s*>/i,!1)?(b.token=f,b.localState=null,b.mode="html",f(a,b)):g(a,/<\/\s*style\s*>/,e.token(a,b.localState))}var c=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),d=CodeMirror.getMode(a,"javascript"),e=CodeMirror.getMode(a,"css");return{startState:function(){var a=c.startState();return{token:f,localState:null,mode:"html",htmlState:a}},copyState:function(a){if(a.localState)var b=CodeMirror.copyState(a.token==i?e:d,a.localState);return{token:a.token,localState:b,mode:a.mode,htmlState:CodeMirror.copyState(c,a.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return a.token==f||/^\s*<\//.test(b)?c.indent(a.htmlState,b):a.token==h?d.indent(a.localState,b):e.indent(a.localState,b)},compareStates:function(a,b){return c.compareStates(a.htmlState,b.htmlState)},electricChars:"/{}:"}}),CodeMirror.defineMIME("text/html","htmlmixed");
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.defineMode("javascript",function(a,b){function g(a,b,c){return b.tokenize=c,c(a,b)}function h(a,b){var c=!1,d;while((d=a.next())!=null){if(d==b&&!c)return!1;c=!c&&d=="\\"}return c}function k(a,b,c){return i=a,j=c,b}function l(a,b){var c=a.next();if(c=='"'||c=="'")return g(a,b,m(c));if(/[\[\]{}\(\),;\:\.]/.test(c))return k(c);if(c=="0"&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),k("number","number");if(/\d/.test(c))return a.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),k("number","number");if(c=="/")return a.eat("*")?g(a,b,n):a.eat("/")?(a.skipToEnd(),k("comment","comment")):b.reAllowed?(h(a,"/"),a.eatWhile(/[gimy]/),k("regexp","string-2")):(a.eatWhile(f),k("operator",null,a.current()));if(c=="#")return a.skipToEnd(),k("error","error");if(f.test(c))return a.eatWhile(f),k("operator",null,a.current());a.eatWhile(/[\w\$_]/);var d=a.current(),i=e.propertyIsEnumerable(d)&&e[d];return i&&b.kwAllowed?k(i.type,i.style,d):k("variable","variable",d)}function m(a){return function(b,c){return h(b,a)||(c.tokenize=l),k("string","string")}}function n(a,b){var c=!1,d;while(d=a.next()){if(d=="/"&&c){b.tokenize=l;break}c=d=="*"}return k("comment","comment")}function p(a,b,c,d,e,f){this.indented=a,this.column=b,this.type=c,this.prev=e,this.info=f,d!=null&&(this.align=d)}function q(a,b){for(var c=a.localVars;c;c=c.next)if(c.name==b)return!0}function r(a,b,c,e,f){var g=a.cc;s.state=a,s.stream=f,s.marked=null,s.cc=g,a.lexical.hasOwnProperty("align")||(a.lexical.align=!0);for(;;){var h=g.length?g.pop():d?D:C;if(h(c,e)){while(g.length&&g[g.length-1].lex)g.pop()();return s.marked?s.marked:c=="variable"&&q(a,e)?"variable-2":b}}}function t(){for(var a=arguments.length-1;a>=0;a--)s.cc.push(arguments[a])}function u(){return t.apply(null,arguments),!0}function v(a){var b=s.state;if(b.context){s.marked="def";for(var c=b.localVars;c;c=c.next)if(c.name==a)return;b.localVars={name:a,next:b.localVars}}}function x(){s.state.context||(s.state.localVars=w),s.state.context={prev:s.state.context,vars:s.state.localVars}}function y(){s.state.localVars=s.state.context.vars,s.state.context=s.state.context.prev}function z(a,b){var c=function(){var c=s.state;c.lexical=new p(c.indented,s.stream.column(),a,null,c.lexical,b)};return c.lex=!0,c}function A(){var a=s.state;a.lexical.prev&&(a.lexical.type==")"&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function B(a){return function(c){return c==a?u():a==";"?t():u(arguments.callee)}}function C(a){return a=="var"?u(z("vardef"),L,B(";"),A):a=="keyword a"?u(z("form"),D,C,A):a=="keyword b"?u(z("form"),C,A):a=="{"?u(z("}"),K,A):a==";"?u():a=="function"?u(R):a=="for"?u(z("form"),B("("),z(")"),N,B(")"),A,C,A):a=="variable"?u(z("stat"),G):a=="switch"?u(z("form"),D,z("}","switch"),B("{"),K,A,A):a=="case"?u(D,B(":")):a=="default"?u(B(":")):a=="catch"?u(z("form"),x,B("("),S,B(")"),C,A,y):t(z("stat"),D,B(";"),A)}function D(a){return o.hasOwnProperty(a)?u(F):a=="function"?u(R):a=="keyword c"?u(E):a=="("?u(z(")"),E,B(")"),A,F):a=="operator"?u(D):a=="["?u(z("]"),J(D,"]"),A,F):a=="{"?u(z("}"),J(I,"}"),A,F):u()}function E(a){return a.match(/[;\}\)\],]/)?t():t(D)}function F(a,b){if(a=="operator"&&/\+\+|--/.test(b))return u(F);if(a=="operator")return u(D);if(a==";")return;if(a=="(")return u(z(")"),J(D,")"),A,F);if(a==".")return u(H,F);if(a=="[")return u(z("]"),D,B("]"),A,F)}function G(a){return a==":"?u(A,C):t(F,B(";"),A)}function H(a){if(a=="variable")return s.marked="property",u()}function I(a){a=="variable"&&(s.marked="property");if(o.hasOwnProperty(a))return u(B(":"),D)}function J(a,b){function c(d){return d==","?u(a,c):d==b?u():u(B(b))}return function(e){return e==b?u():t(a,c)}}function K(a){return a=="}"?u():t(C,K)}function L(a,b){return a=="variable"?(v(b),u(M)):u()}function M(a,b){if(b=="=")return u(D,M);if(a==",")return u(L)}function N(a){return a=="var"?u(L,P):a==";"?t(P):a=="variable"?u(O):t(P)}function O(a,b){return b=="in"?u(D):u(F,P)}function P(a,b){return a==";"?u(Q):b=="in"?u(D):u(D,B(";"),Q)}function Q(a){a!=")"&&u(D)}function R(a,b){if(a=="variable")return v(b),u(R);if(a=="(")return u(z(")"),x,J(S,")"),A,C,y)}function S(a,b){if(a=="variable")return v(b),u()}var c=a.indentUnit,d=b.json,e=function(){function a(a){return{type:a,style:"keyword"}}var b=a("keyword a"),c=a("keyword b"),d=a("keyword c"),e=a("operator"),f={type:"atom",style:"atom"};return{"if":b,"while":b,"with":b,"else":c,"do":c,"try":c,"finally":c,"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"var":a("var"),"const":a("var"),let:a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":e,"typeof":e,"instanceof":e,"true":f,"false":f,"null":f,"undefined":f,NaN:f,Infinity:f}}(),f=/[+\-*&%=<>!?|]/,i,j,o={atom:!0,number:!0,variable:!0,string:!0,regexp:!0},s={state:null,column:null,marked:null,cc:null},w={name:"this",next:{name:"arguments"}};return A.lex=!0,{startState:function(a){return{tokenize:l,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new p((a||0)-c,0,"block",!1),localVars:null,context:null,indented:0}},token:function(a,b){a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation());if(a.eatSpace())return null;var c=b.tokenize(a,b);return i=="comment"?c:(b.reAllowed=i=="operator"||i=="keyword c"||i.match(/^[\[{}\(,;:]$/),b.kwAllowed=i!=".",r(b,c,i,j,a))},indent:function(a,b){if(a.tokenize!=l)return 0;var d=b&&b.charAt(0),e=a.lexical,f=e.type,g=d==f;return f=="vardef"?e.indented+4:f=="form"&&d=="{"?e.indented:f=="stat"||f=="form"?e.indented+c:e.info=="switch"&&!g?e.indented+(/^(?:case|default)\b/.test(b)?c:2*c):e.align?e.column+(g?0:1):e.indented+(g?0:c)},electricChars:":{}"}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0});
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true, in which case
// the styles are combined.
CodeMirror.overlayParser=function(a,b,c){return{startState:function(){return{base:CodeMirror.startState(a),overlay:CodeMirror.startState(b),basePos:0,baseCur:null,overlayPos:0,overlayCur:null}},copyState:function(c){return{base:CodeMirror.copyState(a,c.base),overlay:CodeMirror.copyState(b,c.overlay),basePos:c.basePos,baseCur:null,overlayPos:c.overlayPos,overlayCur:null}},token:function(d,e){return d.start==e.basePos&&(e.baseCur=a.token(d,e.base),e.basePos=d.pos),d.start==e.overlayPos&&(d.pos=d.start,e.overlayCur=b.token(d,e.overlay),e.overlayPos=d.pos),d.pos=Math.min(e.basePos,e.overlayPos),d.eol()&&(e.basePos=e.overlayPos=0),e.overlayCur==null?e.baseCur:e.baseCur!=null&&c?e.baseCur+" "+e.overlayCur:e.overlayCur},indent:function(b,c){return a.indent(b.base,c)},electricChars:a.electricChars}};
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.defineMode("python",function(a,b){function d(a){return new RegExp("^(("+a.join(")|(")+"))\\b")}function t(a,b){if(a.sol()){var d=b.scopes[0].offset;if(a.eatSpace()){var l=a.indentation();return l>d?s="indent":l<d&&(s="dedent"),null}d>0&&w(a,b)}if(a.eatSpace())return null;var m=a.peek();if(m==="#")return a.skipToEnd(),"comment";if(a.match(/^[0-9\.]/,!1)){var n=!1;a.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)&&(n=!0),a.match(/^\d+\.\d*/)&&(n=!0),a.match(/^\.\d+/)&&(n=!0);if(n)return a.eat(/J/i),"number";var o=!1;a.match(/^0x[0-9a-f]+/i)&&(o=!0),a.match(/^0b[01]+/i)&&(o=!0),a.match(/^0o[0-7]+/i)&&(o=!0),a.match(/^[1-9]\d*(e[\+\-]?\d+)?/)&&(a.eat(/J/i),o=!0),a.match(/^0(?![\dx])/i)&&(o=!0);if(o)return a.eat(/L/i),"number"}return a.match(p)?(b.tokenize=u(a.current()),b.tokenize(a,b)):a.match(i)||a.match(h)?null:a.match(g)||a.match(e)||a.match(k)?"operator":a.match(f)?null:a.match(q)?"keyword":a.match(r)?"builtin":a.match(j)?"variable":(a.next(),c)}function u(a){while("rub".indexOf(a.charAt(0).toLowerCase())>=0)a=a.substr(1);var d=a.length==1,e="string";return function(g,h){while(!g.eol()){g.eatWhile(/[^'"\\]/);if(g.eat("\\")){g.next();if(d&&g.eol())return e}else{if(g.match(a))return h.tokenize=t,e;g.eat(/['"]/)}}if(d){if(b.singleLineStringErrors)return c;h.tokenize=t}return e}}function v(b,c,d){d=d||"py";var e=0;if(d==="py"){if(c.scopes[0].type!=="py"){c.scopes[0].offset=b.indentation();return}for(var f=0;f<c.scopes.length;++f)if(c.scopes[f].type==="py"){e=c.scopes[f].offset+a.indentUnit;break}}else e=b.column()+b.current().length;c.scopes.unshift({offset:e,type:d})}function w(a,b,c){c=c||"py";if(b.scopes.length==1)return;if(b.scopes[0].type==="py"){var d=a.indentation(),e=-1;for(var f=0;f<b.scopes.length;++f)if(d===b.scopes[f].offset){e=f;break}if(e===-1)return!0;while(b.scopes[0].offset!==d)b.scopes.shift();return!1}return c==="py"?(b.scopes[0].offset=a.indentation(),!1):b.scopes[0].type!=c?!0:(b.scopes.shift(),!1)}function x(a,b){s=null;var d=b.tokenize(a,b),e=a.current();if(e===".")return d=b.tokenize(a,b),e=a.current(),d==="variable"||d==="builtin"?"variable":c;if(e==="@")return d=b.tokenize(a,b),e=a.current(),d==="variable"||e==="@staticmethod"||e==="@classmethod"?"meta":c;if(e==="pass"||e==="return")b.dedent+=1;(e===":"&&!b.lambda&&b.scopes[0].type=="py"||s==="indent")&&v(a,b);var f="[({".indexOf(e);return f!==-1&&v(a,b,"])}".slice(f,f+1)),s==="dedent"&&w(a,b)?c:(f="])}".indexOf(e),f!==-1&&w(a,b,e)?c:(b.dedent>0&&a.eol()&&b.scopes[0].type=="py"&&(b.scopes.length>1&&b.scopes.shift(),b.dedent-=1),d))}var c="error",e=new RegExp("^[\\+\\-\\*/%&|\\^~<>!]"),f=new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]"),g=new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"),h=new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"),i=new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"),j=new RegExp("^[_A-Za-z][_A-Za-z0-9]*"),k=d(["and","or","not","is","in"]),l=["as","assert","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","lambda","pass","raise","return","try","while","with","yield"],m=["abs","all","any","bin","bool","bytearray","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip","__import__","NotImplemented","Ellipsis","__debug__"],n={builtins:["apply","basestring","buffer","cmp","coerce","execfile","file","intern","long","raw_input","reduce","reload","unichr","unicode","xrange","False","True","None"],keywords:["exec","print"]},o={builtins:["ascii","bytes","exec","print"],keywords:["nonlocal","False","True","None"]};if(!b.version||parseInt(b.version,10)!==3){l=l.concat(n.keywords),m=m.concat(n.builtins);var p=new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))","i")}else{l=l.concat(o.keywords),m=m.concat(o.builtins);var p=new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))","i")}var q=d(l),r=d(m),s=null,y={startState:function(a){return{tokenize:t,scopes:[{offset:a||0,type:"py"}],lastToken:null,lambda:!1,dedent:0}},token:function(a,b){var c=x(a,b);return b.lastToken={style:c,content:a.current()},a.eol()&&a.lambda&&(b.lambda=!1),c},indent:function(a,b){return a.tokenize!=t?0:a.scopes[0].offset}};return y}),CodeMirror.defineMIME("text/x-python","python");
//}}}
!!!! StyleSheetColors
<<tiddler StyleSheetColors>>
//{{{
// Demo code (the actual new parser character stream implementation)
function StringStream(string) {
this.pos = 0;
this.string = string;
}
StringStream.prototype = {
done: function() {return this.pos >= this.string.length;},
peek: function() {return this.string.charAt(this.pos);},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && match.test ? match.test(ch) : match(ch);
if (ok) {this.pos++; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match));
if (this.pos > start) return this.string.slice(start, this.pos);
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.pos;},
eatSpace: function() {
var start = this.pos;
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
return this.pos - start;
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
if (consume !== false) this.pos += str.length;
return true;
}
}
else {
var match = this.string.slice(this.pos).match(pattern);
if (match && consume !== false) this.pos += match[0].length;
return match;
}
}
};
//}}}
{{{
<code class="brush:python">
some code ..
</code>
}}}
<code class="brush:python">
# Literals
1234
0.0e101
.123
0b01010011100
0o01234567
0x0987654321abcdef
7
2147483647
3L
79228162514264337593543950336L
0x100000000L
79228162514264337593543950336
0xdeadbeef
3.14j
10.j
10j
.001j
1e100j
3.14e-10j
# String Literals
'For\''
"God\""
"""so loved
the world"""
'''that he gave
his only begotten\' '''
'that whosoever believeth \
in him'
''
# Identifiers
__a__
a.b
a.b.c
# Operators
+ - * / % & | ^ ~ < >
== != <= >= <> << >> // **
and or not in is
# Delimiters
() [] {} , : ` = ; @ . # Note that @ and . require the proper context.
+= -= *= /= %= &= |= ^=
//= >>= <<= **=
# Keywords
as assert break class continue def del elif else except
finally for from global if import lambda pass raise
return try while with yield
# Python 2 Keywords (otherwise Identifiers)
exec print
# Python 3 Keywords (otherwise Identifiers)
nonlocal
# Types
bool classmethod complex dict enumerate float frozenset int list object
property reversed set slice staticmethod str super tuple type
# Python 2 Types (otherwise Identifiers)
basestring buffer file long unicode xrange
# Python 3 Types (otherwise Identifiers)
bytearray bytes filter map memoryview open range zip
# Some Example code
import os
from package import ParentClass
@nonsenseDecorator
def doesNothing():
pass
class ExampleClass(ParentClass):
@staticmethod
def example(inputStr):
a = list(inputStr)
a.reverse()
return ''.join(a)
def __init__(self, mixin = 'Hello'):
self.mixin = mixin
</code>
!!!! PageTemplate
<<tiddler PageTemplate>>
!!!! ViewTemplate
<<tiddler ViewTemplate>>
!!!! EditTemplate
<<tiddler EditTemplate>>
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.runMode=function(a,b,c,d){function p(a){var b=e.tabSize-a%e.tabSize;for(var c="",d=0;d<b;++d)c+=" ";return c}function q(a){var b,d,e,f=a.length;for(e=0;e<f;)b="",d=a.indexOf("\t",e),d==-1?(b+=a.slice(e),l=/[^\s]/im.test(b)?null:"tab-space-mixed",d=a.length):d-e>1?(b=a.slice(e,d),l=/[^\s]/im.test(b)?null:"tab-space-mixed",d-=1):(b+=p(n),l="tab"),e=d+1,n+=b.length,c(b,l,r,o.start);return""}var e=d||CodeMirror.defaults,f=CodeMirror.getMode(e,b),g=c.nodeType==1;if(g){var h=c,i=[];c=function(a,b){if(a=="")return;a=="\n"?i.push("<br>"):b?i.push('<span class="cm-'+CodeMirror.htmlEscape(b)+'">'+CodeMirror.htmlEscape(a)+"</span>"):i.push(CodeMirror.htmlEscape(a))}}var j=CodeMirror.splitLines(a),k=CodeMirror.startState(f),l,m,n,o;for(var r=0,s=j.length;r<s;++r){n=0,r&&c("\n"),o=new CodeMirror.StringStream(j[r]);while(!o.eol())l=f.token(o,k),m=o.current(),m.indexOf("\t")!=-1&&(m=q(m)),n+=m.length,c(m,l,r,o.start),o.start=o.pos}g&&(h.innerHTML=i.join(""))};
//}}}
# Some Example code
import os
from package import ParentClass
@nonsenseDecorator
def doesNothing():
pass
class ExampleClass(ParentClass):
@staticmethod
def example(inputStr):
a = list(inputStr)
a.reverse()
return ''.join(a)
def __init__(self, mixin = 'Hello'):
self.mixin = mixin
/***
! heading 1
server.content-type: <<view server.content-type>>
***/
//{{{
var a = 0;
for (var i=0; i < 10; i++) {
hallo
}
//}}}
/***
possible tags can be seen at: CodeMirrorConfig
***/
/*{{{*/
a {
text-decoration: underline
}
/*}}}*/
/*{{{*/
.cm-s-default span.cm-header {color: blue; font-weight:bold;}
.cm-s-default span.cm-code {color: #a50;}
.cm-s-default span.cm-code-inline {color: #660;}
.cm-s-default span.cm-quote {color: #555;}
.cm-s-default span.cm-list {color: #c60;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-em {font-style: italic;}
.cm-s-default span.cm-strong {font-weight: bold;}
.cm-s-default span.cm-link-external {color: blue;}
.cm-s-default span.cm-brace {color: #170; font-weight: bold;}
.cm-s-default span.cm-macro {color: #9E3825;}
.cm-s-default span.cm-table {color: blue;}
.cm-s-default span.cm-warning {color: red; font-weight: bold;}
.cm-s-default span.cm-underlined {text-decoration: underline;}
.cm-s-default span.cm-line-through {text-decoration: line-through;}
.cm-s-default span.cm-comment {color: #666;}
.cm-s-default span.cm-tab-space-mixed {background: #ccc;}
/*}}}*/
//{{{
/***
|''Name''|tiddlywiki.js|
|''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror2|
|''Author''|PMario|
|''Version''|0.1.7|
|''Status''|stable|
|''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
|''Documentation''|http://codemirror.tiddlyspace.com/|
|''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|codemirror.js|
|''Keywords''|syntax highlighting color code mirror codemirror|
! Info
CoreVersion parameter is needed for TiddlyWiki only!
***///{{{
CodeMirror.defineMode("tiddlywiki",function(a,b){function s(a,b,c){return b.tokenize=c,c(a,b)}function t(a,b){var c=!1,d;while((d=a.next())!=null){if(d==b&&!c)return!1;c=!c&&d=="\\"}return c}function w(a,b,c){return u=a,v=c,b}function x(a,b){var c=a.sol(),e,p;b.block=!1,e=a.peek();if(c&&/[<\/\*{}\-]/.test(e)){if(a.match(o))return b.block=!0,s(a,b,B);if(a.match(j))return w("quote","quote");if(a.match(h)||a.match(i))return w("code","code");if(a.match(k)||a.match(l)||a.match(m)||a.match(n))return w("code","code");if(a.match(g))return w("hr","hr")}var e=a.next();if(c&&/[\/\*!#;:>|]/.test(e)){if(e=="!")return a.skipToEnd(),w("header","header");if(e=="*")return a.eatWhile("*"),w("list","list");if(e=="#")return a.eatWhile("#"),w("list","list");if(e==";")return a.eatWhile(";"),w("list","list");if(e==":")return a.eatWhile(":"),w("list","list");if(e==">")return a.eatWhile(">"),w("quote","quote");if(e=="|")return w("table","table")}if(e=="{"&&a.match(/\{\{/))return s(a,b,B);if(/[hf]/i.test(e)&&/[ti]/i.test(a.peek())&&a.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i))return w("link-external","link-external");if(e=='"')return w("string","string");if(/[\[\]]/.test(e)&&a.peek()==e)return a.next(),w("brace","brace");if(e=="@")return a.eatWhile(f),w("link-external","link-external");if(/\d/.test(e))return a.eatWhile(/\d/),w("number","number");if(e=="/"){if(a.eat("%"))return s(a,b,z);if(a.eat("/"))return s(a,b,C)}if(e=="_"&&a.eat("_"))return s(a,b,D);if(e=="-"&&a.eat("-"))return s(a,b,E);if(e=="'"&&a.eat("'"))return s(a,b,A);if(e!="<")return w(e);if(a.eat("<"))return s(a,b,F);a.eatWhile(/[\w\$_]/);var q=a.current(),r=d.propertyIsEnumerable(q)&&d[q];return r?w(r.type,r.style,q):w("text",null,q)}function y(a){return function(b,c){return t(b,a)||(c.tokenize=x),w("string","string")}}function z(a,b){var c=!1,d;while(d=a.next()){if(d=="/"&&c){b.tokenize=x;break}c=d=="%"}return w("comment","comment")}function A(a,b){var c=!1,d;while(d=a.next()){if(d=="'"&&c){b.tokenize=x;break}c=d=="'"}return w("text","strong")}function B(a,b){var c,d=b.block;return d&&a.current()?w("code","code"):!d&&a.match(r)?(b.tokenize=x,w("code","code-inline")):d&&a.sol()&&a.match(p)?(b.tokenize=x,w("code","code")):(c=a.next(),d?w("code","code"):w("code","code-inline"))}function C(a,b){var c=!1,d;while(d=a.next()){if(d=="/"&&c){b.tokenize=x;break}c=d=="/"}return w("text","em")}function D(a,b){var c=!1,d;while(d=a.next()){if(d=="_"&&c){b.tokenize=x;break}c=d=="_"}return w("text","underlined")}function E(a,b){var c=!1,d,e;while(d=a.next()){if(d=="-"&&c){b.tokenize=x;break}c=d=="-"}return w("text","line-through")}function F(a,b){var c,d,f,g;return a.current()=="<<"?w("brace","macro"):(c=a.next(),c?c==">"&&a.peek()==">"?(a.next(),b.tokenize=x,w("brace","macro")):(a.eatWhile(/[\w\$_]/),f=a.current(),g=e.propertyIsEnumerable(f)&&e[f],g?w(g.type,g.style,f):w("macro",null,f)):(b.tokenize=x,w(c)))}var c=a.indentUnit,d=function(){function a(a){return{type:a,style:"text"}}return{}}(),e=function(){function a(a){return{type:a,style:"macro"}}return{allTags:a("allTags"),closeAll:a("closeAll"),list:a("list"),newJournal:a("newJournal"),newTiddler:a("newTiddler"),permaview:a("permaview"),saveChanges:a("saveChanges"),search:a("search"),slider:a("slider"),tabs:a("tabs"),tag:a("tag"),tagging:a("tagging"),tags:a("tags"),tiddler:a("tiddler"),timeline:a("timeline"),today:a("today"),version:a("version"),option:a("option"),"with":a("with"),filter:a("filter")}}(),f=/[\w_\-]/i,g=/^\-\-\-\-+$/,h=/^\/\*\*\*$/,i=/^\*\*\*\/$/,j=/^<<<$/,k=/^\/\/\{\{\{$/,l=/^\/\/\}\}\}$/,m=/^<!--\{\{\{-->$/,n=/^<!--\}\}\}-->$/,o=/^\{\{\{$/,p=/^\}\}\}$/,q=/\{\{\{/,r=/.*?\}\}\}/,u,v;return{startState:function(a){return{tokenize:x,indented:0,level:0}},token:function(a,b){if(a.eatSpace())return null;var c=b.tokenize(a,b);return c},electricChars:""}}),CodeMirror.defineMIME("text/x-tiddlywiki","tiddlywiki");
//}}}
/***
|''Requires''|codemirror.js|
|''License''|[[codemirror.js]]|
***/
//{{{
CodeMirror.defineMode("xml",function(a,b){function h(a,b){function c(c){return b.tokenize=c,c(a,b)}var d=a.next();if(d=="<"){if(a.eat("!"))return a.eat("[")?a.match("CDATA[")?c(k("atom","]]>")):null:a.match("--")?c(k("comment","-->")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),c(l(1))):null;if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),b.tokenize=k("meta","?>"),"meta";g=a.eat("/")?"closeTag":"openTag",a.eatSpace(),f="";var e;while(e=a.eat(/[^\s\u00a0=<>\"\'\/?]/))f+=e;return b.tokenize=i,"tag"}if(d=="&"){var h;return a.eat("#")?a.eat("x")?h=a.eatWhile(/[a-fA-F\d]/)&&a.eat(";"):h=a.eatWhile(/[\d]/)&&a.eat(";"):h=a.eatWhile(/[\w\.\-:]/)&&a.eat(";"),h?"atom":"error"}return a.eatWhile(/[^&<]/),null}function i(a,b){var c=a.next();return c==">"||c=="/"&&a.eat(">")?(b.tokenize=h,g=c==">"?"endTag":"selfcloseTag","tag"):c=="="?(g="equals",null):/[\'\"]/.test(c)?(b.tokenize=j(c),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function j(a){return function(b,c){while(!b.eol())if(b.next()==a){c.tokenize=i;break}return"string"}}function k(a,b){return function(c,d){while(!c.eol()){if(c.match(b)){d.tokenize=h;break}c.next()}return a}}function l(a){return function(b,c){var d;while((d=b.next())!=null){if(d=="<")return c.tokenize=l(a+1),c.tokenize(b,c);if(d==">"){if(a==1){c.tokenize=h;break}return c.tokenize=l(a-1),c.tokenize(b,c)}}return"meta"}}function o(){for(var a=arguments.length-1;a>=0;a--)m.cc.push(arguments[a])}function p(){return o.apply(null,arguments),!0}function q(a,b){var c=d.doNotIndent.hasOwnProperty(a)||m.context&&m.context.noIndent;m.context={prev:m.context,tagName:a,indent:m.indented,startOfLine:b,noIndent:c}}function r(){m.context&&(m.context=m.context.prev)}function s(a){if(a=="openTag")return m.tagName=f,p(v,t(m.startOfLine));if(a=="closeTag"){var b=!1;return m.context?b=m.context.tagName!=f:b=!0,b&&(n="error"),p(u(b))}return p()}function t(a){return function(b){return b=="selfcloseTag"||b=="endTag"&&d.autoSelfClosers.hasOwnProperty(m.tagName.toLowerCase())?p():b=="endTag"?(q(m.tagName,a),p()):p()}}function u(a){return function(b){return a&&(n="error"),b=="endTag"?(r(),p()):(n="error",p(arguments.callee))}}function v(a){return a=="word"?(n="attribute",p(w,v)):a=="endTag"||a=="selfcloseTag"?o():(n="error",p(v))}function w(a){return a=="equals"?p(x,v):(d.allowMissing||(n="error"),a=="endTag"||a=="selfcloseTag"?o():p())}function x(a){return a=="string"?p(y):a=="word"&&d.allowUnquoted?(n="string",p()):(n="error",a=="endTag"||a=="selfCloseTag"?o():p())}function y(a){return a=="string"?p(y):o()}var c=a.indentUnit,d=b.htmlMode?{autoSelfClosers:{br:!0,img:!0,hr:!0,link:!0,input:!0,meta:!0,col:!0,frame:!0,base:!0,area:!0},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!1}:{autoSelfClosers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1},e=b.alignCDATA,f,g,m,n;return{startState:function(){return{tokenize:h,cc:[],indented:0,startOfLine:!0,tagName:null,context:null}},token:function(a,b){a.sol()&&(b.startOfLine=!0,b.indented=a.indentation());if(a.eatSpace())return null;n=g=f=null;var c=b.tokenize(a,b);b.type=g;if((c||g)&&c!="comment"){m=b;for(;;){var d=b.cc.pop()||s;if(d(g||c))break}}return b.startOfLine=!1,n||c},indent:function(a,b,d){var f=a.context;if(a.tokenize!=i&&a.tokenize!=h||f&&f.noIndent)return d?d.match(/^(\s*)/)[0].length:0;if(e&&/<!\[CDATA\[/.test(b))return 0;f&&/^<\//.test(b)&&(f=f.prev);while(f&&!f.startOfLine)f=f.prev;return f?f.indent+c:0},compareStates:function(a,b){if(a.indented!=b.indented||a.tokenize!=b.tokenize)return!1;for(var c=a.context,d=b.context;;c=c.prev,d=d.prev){if(!c||!d)return c==d;if(c.tagName!=d.tagName)return!1}},electricChars:"/"}}),CodeMirror.defineMIME("application/xml","xml"),CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:!0});
//}}}
/***
|''Name''|zCodeMirrorPlugin|
|''Description''|Enables syntax highlighting using CodeMirror|
|''Author''|PMario|
|''Version''|0.2.7|
|''Status''|''stable''|
|''Info''|CodeMirrorPluginInfo|
|''Source''|https://github.com/pmario/tw.CodeMirrorPlugin|
|''Documentation''|http://codemirror.tiddlyspace.com/|
|''License''|[[CC-BY-NC-SA|http://creativecommons.org/licenses/by-nc-sa/3.0/]]|
|''CoreVersion''|2.5.0|
|''Requires''|codemirror.js |
|''Keywords''|syntax highlighting color code mirror codemirror|
! Documentation
* Full info, see: [[CodeMirrorPluginInfo]]
! Description
Enables syntax highlighting for <pre> and <code> blocks. Adds a new formatter for {{{<code class='???'>}}}
! Usage
!!!! StyleSheet
<<<
* The plugin automatically creates a shadow tiddler: StyleSheetCodeMirror, that can be adjusted to your needs.
<<<
!!!! Macros
Modes: {{{<<cmModes>>}}} ... displays the usable modes seen below
<<<
Modes: <<cmModes>>
<<<
MIMEs: {{{<<cmMimes>>}}} ... displays the usable mime types seen below. Same order as modes.
<<<
Modes: <<cmMimes>>
<<<
MIMEs: {{{<<cmMimeObjects>>}}} ... displays the usable mime types seen below. Same order as modes. Shows the structure as a JSON.
<<<
<<cmMimeObjects>>
<<<
!!!!Global Settings
<<<
* Have a look at: [[CodeMirrorConfig]]
<<<
!!!! ViewTemplate
<<<
* Same as macro, but will be executed automatically for every tiddler. see: [[CodeMirrorPluginInfo]]
<<<
!!!! Parameters
<<<
{{{<<highlightSyntax [tagName]>> }}}
* will render all blocks, with any defined tag name. eg: tagName = {{{code}}}.
* [tagName] is optional. Default is "pre".
<<<
!!!! Configuration options
<<<
Guess syntax: <<option chkGuessSyntax>> .. If activated, ~TiddlyWiky <pre> blocks will be rendered according to there block braces. see [[CodeMirrorInfo]]
Expert mode: <<option chkExpertSyntax>> .. If activated, additional values below will be used. see [[CodeMirrorInfo]]
{{{ {{{ }}} txtShText: <<option txtShText>> eg: 'brush:text'
{{{ / *{{{* / }}} txtShCss: <<option txtShCss>> eg: 'brush:css'
{{{ //{{{ }}} txtShPlugin: <<option txtShPlugin>> 'brush:javascript'
{{{ <!--{{{-->> }}} txtShXml: <<option txtShXml>> 'brush:xml'
Additional options
<<<
!!!! Known Issues
* Theme switching not supported yet
** Too many TODOs
!!!! Revision History
<<<
* V 0.2.7 2012-03-13
** Editor refresh fixed, TypeChooser height fixed.
* V 0.1.0 2011-09-07
** inital release
see full History at CodeMirrorPluginInfo
<<<
!!!! ToDo
<<<
<<<
!!! Code
!!!!! {{{<<cmModes>>, <<cmMimes>>, <<cmMimeObjects>>}}}
***/
//{{{
version.extensions.CodeMirrorPlugin = {major: 0, minor: 2, revision: 5, date: new Date(2012,2,7)};
(function($) {
config.macros.cmModes = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
jQuery('<span/>').text(CodeMirror.listModes().join(', ')).appendTo(place);
}
};
config.macros.cmMimes = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var cm = config.tools.cm;
jQuery('<span/>').text(cm.listMimeNames().join(', ')).appendTo(place);
}
};
config.macros.cmMimeObjects = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
jQuery('<span/>').text(JSON.stringify(CodeMirror.listMIMEs())).appendTo(place);
}
};
//}}}
/***
!!!!! Type chooser to define the MIME type
***/
//{{{
// create objects for typeChooser dropDown
config.macros.typeChooser = {};
config.views.editor.typeChooser = {};
// use this part if you need translation
merge(config.views.editor.typeChooser,{
text: "content-type",
tooltip: "Choose existing types to add to this tiddler",
popupNone: "There are no content-types defined",
typeTooltip: "Add the content-type '%0'"});
// content-type chooser
config.macros.typeChooser.onClick = function(ev)
{
var e = ev || window.event,
lingo = config.views.editor.typeChooser,
popup = Popup.create(this),
data = $(this).data('data'),
types = CodeMirror.listMIMEs();
types.push({mime: '-none-', mode: 'none'});
if(types.length === 0) {
$('<li/>').text(lingo.popupNone).appendTo(popup);
}
var t, type, mode, tooltipText;
for(t=0; t<types.length; t++) {
tooltipText = (typeof types[t].mode === 'object') ? types[t].mode.name : types[t].mode;
type = createTiddlyButton( createTiddlyElement(popup,'li'),
types[t].mime, lingo.typeTooltip.format([tooltipText]), config.macros.typeChooser.onTypeClick);
$(type).data('data', data);
type.setAttribute('type',types[t].mime);
type.setAttribute('tiddler',this.getAttribute('tiddler'));
}
Popup.show();
e.cancelBubble = true;
if(e.stopPropagation) {e.stopPropagation();}
return false;
};
config.macros.typeChooser.onTypeClick = function(ev)
{
var e = ev || window.event;
if(e.metaKey || e.ctrlKey) {stopEvent(e);} //# keep popup open on CTRL-click
var data = $(this).data('data'),
type = this.getAttribute('type'),
title = this.getAttribute('tiddler'),
conf = config.tools.cm.conf,
cm = config.tools.cm,
cmOptions = {},
mode;
// TODO doesn't seem to be right here.
// SyntaxHL change should work in read only too, for demo purpose.
if(!readOnly) {
// read actual global configuraiton
config.tools.cm.init();
// clear the input ..
$(data.input).val('');
if (type == '-none-' || type == 'content-type') {
story.setTiddlerField(title, '', '+1', data.ctfield);
}
else {
story.setTiddlerField(title, type, '+1', data.ctfield);
}
$(data.btn).text(type);
var text = $(story.getTiddler(title)).find('textarea[edit=text]');
var editor = $(text[0]).data('editor');
// save changes to textarea.
if (editor) {editor.save();}
// TODO if a tag overwrites the content-type, gray out/disable the content-type button.
if (editor) $(editor.getWrapperElement()).remove();
mode = cm.getModeObject(type);
$.extend( cmOptions, conf['global']);
$.extend( cmOptions, conf[mode.name]);
$.extend( cmOptions.mode, mode); // IMPORTANT overwrite mode, because it may be an object !!
var tid = store.getTiddler(title);
var cmField = story.hasTiddlerField(title, 'cm.height');
// if there is a cmField it will win, because there may be a new setting.
if (cmField) {
$.extend(cmOptions, {cmHeight: cmField.getAttribute('value')});
}
else if (tid && tid.fields['cm.height']) {
$.extend(cmOptions, {cmHeight: tid.fields['cm.height']});
} // TODO this code is used several times -> refactoring needed
cm.startEditor(text, cmOptions);
}
return false;
};
config.macros.typeChooser.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
var ctfield = params[0] || 'content-type';
if(tiddler instanceof Tiddler) {
var lingo = config.views.editor.typeChooser,
btnText = (tiddler.fields[ctfield]) ? tiddler.fields[ctfield] : lingo.text,
inpText = (tiddler.fields[ctfield]) ? tiddler.fields[ctfield] : '';
// createTiddlyElement(parent, element, id, className, text, attribs)
var $inp = $('<input type="text" edit="'+ctfield+'" size="20">').appendTo(place).val(inpText).hide();
var btn = createTiddlyButton(place, btnText, lingo.tooltip, this.onClick);
$(btn).data('data', {'input':$inp, 'btn':btn, 'ctfield':ctfield});
btn.setAttribute('tiddler', tiddler.title);
btn.setAttribute('exclude', params[0]);
}
};
//}}}
/***
!!!!! {{{<<highlightSyntax>>}}} macro
***/
//{{{
config.macros.highlightSyntax = {
getElementsByClass: function (searchClass,node,tag) {
var classElements = [];
if ( node === null ) {node = document;}
if ( tag === null ) {tag = '*';}
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\s)'+searchClass+'(:|\\s|$)');
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
},
// <<highlightSyntax tagName>>
// <<highlightSyntax code>> || <<highlightSyntax div>>
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
// the configured tagName can be temporarily overwritten by the macro.
var output, cStr, modeName;
var tagName = params[0] || 'pre';
var arr = this.getElementsByClass('brush', story.findContainingTiddler(place), tagName);
var src;
for (i=0; i<arr.length; i++) {
$output = $('<'+ tagName +' class="cm-s-default">'); // TODO theme handling
$src = $(arr[i]);
cStr = $src.attr('class');
cStr = cStr.parseParams(null, null, true);
modeName = getParam(cStr, 'brush', 'null');
CodeMirror.runMode($src.text(), modeName, $output[0]);
$src.replaceWith($output[0]);
}
} // handler
};
})(jQuery);
//}}}
/***
!!!!! New formatter for {{{<code class='brush:??'>}}}
***/
//{{{
config.formatters.push({
name: "highlightSyntax",
match: "^<code[\\s]+[^>]+>\\n",
element: "pre",
handler: function(w)
{
this.lookaheadRegExp = /<code[\s]+class.*=.*["'](.*)["'].*>\n((?:^[^\n]*\n)+?)(^<\/code>$\n?)/img;
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var options = lookaheadMatch[1];
var text = lookaheadMatch[2];
var cmMode;
if(config.browser.isIE) {
text = text.replace(/\n/g,"\r");
}
var element = createTiddlyElement(w.output,this.element,null,options +' cm-s-default',''); // TODO check for theme
// may be there will be additional params in the future.
cmMode = options.parseParams(null, null, true);
cmMode = getParam(cmMode, 'brush', 'null');
CodeMirror.runMode(text, cmMode, element);
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
});
//}}}
/***
!!!!! Add class attribute to pre, if defined
***/
//{{{
(function(formatters) { //# set up alias
var helper = {};
helper.enclosedTextHelper = function(w){
var attr;
var co = config.options;
var expert = (co.chkExpertSyntax !== undefined)? co.chkExpertSyntax : false;
var guess = (co.chkGuessSyntax !== undefined)? co.chkGuessSyntax : true;
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
if(config.browser.isIE) {
text = text.replace(/\n/g,'\r');
}
switch(w.matchText) {
case '{{{\n': // text
attr = (expert) ? (co.txtShText) ? (co.txtShText) : 'text/plain' : 'text/plain' ;
break;
case '/*{{{*/\n': // CSS
attr = (expert) ? (co.txtShCss) ? (co.txtShCss) : 'css' : 'css';
break;
case '//{{{\n': // plugin
attr = (expert) ? (co.txtShPlugin) ? (co.txtShPlugin) : 'javascript' : 'javascript';
break;
case '<!--{{{-->\n': //template
attr = (expert) ? (co.txtShXml) ? (co.txtShXml) : 'xml' : 'xml';
break;
}
var element = createTiddlyElement(w.output,this.element,null,' cm-s-default',''); // TODO check for theme
if (guess || expert) {
CodeMirror.runMode(text, attr, element);
}
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
};
// merge the new helper function into formatterHelpers.
merge(config.formatterHelpers, helper);
})(config.formatters); //# end of alias
//}}}
/***
!!!!! CM tools and helper functions
***/
//{{{
(function ($) {
var me;
if (!config.tools) config.tools = {};
config.tools.cm = me = {
locale: {
},
// since TW layout is very flexible, the actual hight for the editor viewport can be guessed only
// formular used: window.height - title.h * 2 - toolbar.h * 2 - correction
// Editor scrolls into position, to be maximum visible.
// TODO correction may be given by the user. eg cookie
guessMaxHeight: function (corr) {
var wh = $(window).height(),
tih = ($('.title').height()) ? $('.title').height() : 0,
toh = ($('.toolbar').height()) ? $('.toolbar').height() : 0;
return wh - (tih + toh) * 2 - ((corr) ? corr : 0);
},
// This function is used, if there is a browser resize,
// or user want's to have max size
resizeEditor : function(height) {
var $cm = $('.CodeMirror');
$cm.width($cm.closest('.editor').width());
if (height) { $cm.find('.CodeMirror-scroll').height(height)};
},
listMimeNames: function() {
return CodeMirror.listMIMEs().map(function(el){return el.mime;});
},
getModeObject: function(mime) {
var arr = CodeMirror.listMIMEs();
var mode = {"name": 'null'};
for (var i=0, iMax = arr.length; i < iMax; i += 1) {
if (arr[i].mime == mime) {
if (typeof arr[i].mode === 'object') {
return arr[i].mode;
}
else if (typeof arr[i].mode === 'string' ) {
mode.name = arr[i].mode;
return mode;
} // else if
} // if
} // for
return mode;
},
helper : {
'true': true,
'false': false,
'null': null
},
calcTextSlices: function (text) {
var a = [], slices = {};
store.slicesRE.lastIndex = 0;
var m = store.slicesRE.exec(text);
while (m) {
if (m[2]) {
if (m[3] === '') {
slices[m[2]] = '';
}
else if (isNaN(m[3])) {
if (!slices[m[2]]) {
slices[m[2]] = (m[3] in me.helper) ? me.helper[m[3]] : m[3];
}
else {
if (typeof(slices[m[2]]) != 'string') {
slices[m[2]].push((m[3] in me.helper) ? me.helper[m[3]] : m[3]);
}
else {
a[0] = slices[m[2]];
slices[m[2]] = a;
slices[m[2]].push((m[3] in me.helper) ? me.helper[m[3]] : m[3]);
}
}
}
else {
slices[m[2]] = parseFloat(m[3]);
}
}
m = store.slicesRE.exec(text);
}
// console.log('slices: ', slices);
return slices;
},
rdSettings: function (cName) {
var settings = {};
var text;
var title = cName;
var secSep = config.textPrimitives.sectionSeparator;
var section = null;
var pos = title.indexOf(secSep);
if (pos != -1) {
section = title.substr(pos + config.textPrimitives.sectionSeparator.length);
title = title.substr(0, pos);
}
cName = (title) ? cName : tiddler.title + cName;
title = (title) ? title : tiddler.title;
if (store.tiddlerExists(title) || store.isShadowTiddler(title)) {
text = store.getTiddlerText(cName);
settings = me.calcTextSlices(text);
}
// special handling for functions.
// There are only extraKeys addOns at the moment !!
var p = ['extraKeys', 'onChange', 'onCursorActivity', 'onGutterClick', 'onFocus', 'onScroll', 'onHighlightComplete', 'onKeyEvent'];
var ctca = config.tools.cm.addOns;
var x;
for (var i = 0, im = p.length; i<im; i += 1) {
x = settings[p[i]];
if (x) {
// it's possible to have arrays of addOns
if (typeof(x) == 'object') {
settings[p[i]] = {};
for (var j = 0; j < x.length; j++) {
$.extend(settings[p[i]], (ctca && ctca[x[j]]) ? ctca[x[j]] : null);
}
}
else {
settings[p[i]] = (ctca && ctca[x]) ? ctca[x] : null;
}
}
}
return settings;
},
// stores the global CM config settings
conf: {},
init: function() {
var cm = 'CodeMirrorConfig', modes;
var secSep = config.textPrimitives.sectionSeparator;
// global settings need to be read seperately
me.conf['global'] = me.rdSettings(cm + secSep + 'global');
// check CM for installed modes and get usre config if available
modes = CodeMirror.listModes();
for (var i=0; i < modes.length; i += 1) {
me.conf[modes[i]] = me.rdSettings(cm + secSep + modes[i]);
}
},
startEditor: function(textArea, cmOptions) {
// disable chkInsertTabs
var height = null;
var co = config.options;
if (co.chkInsertTabs) {
// it's better to disalbe this option. see: smartTab mode.
$.extend(cmOptions.extraKeys, {"Tab": false, "Shift-Tab": false});
}
var editor = CodeMirror.fromTextArea(textArea[0], cmOptions);
$(textArea[0]).data('editor', editor);
if (cmOptions.cmHeight == 'max') {
$(editor.getScrollerElement()).data('oldHeight', $(editor.getScrollerElement()).height());
height = config.tools.cm.guessMaxHeight(25); // TODO 25 should be an option.
}
config.tools.cm.resizeEditor(height);
editor.focus();
editor.refresh();
}
}; // end plugin
// get and init the global CM settings
// config.tools.cm.init();
// Probably not needed with TiddlySpace themes.
// Deffinitely not needed with neui-em theme. The layout deals with it.
$(window).resize(function() {
config.tools.cm.resizeEditor();
});
})(jQuery);
//}}}
/***
!!!!! TiddlySpace specific stuff
***/
//{{{
// Check, if there is the BinaryTiddlersPlugin TODO and use it.
// If not check for content-type == text/....
(function($) {
var ctfield = 'content-type';
config.extensions.cm = me = {
isTW : function(ctype) {
return ctype.indexOf('tiddlywiki') != -1;
},
isTextual : function(ctype) {
return ctype.indexOf('text/') === 0
|| this.endsWith(ctype, '+xml')
|| ctype == 'application/json'
|| ctype == 'application/javascript';
},
endsWith: function(str, suffix) {
return str.length >= suffix.length &&
str.substr(str.length - suffix.length) == suffix;
}
};
// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
paramString, tiddler) {
var el;
var ctype = tiddler.fields[ctfield];
// TODO next line matches are ugly
if(params[0] == 'text' && ctype && !tiddler.text.match('{{'+'{') && !tiddler.text.match('<code')) {
if (!me.isTW(ctype) && me.isTextual(ctype)) {
el = $('<pre class="cm-s-default">').appendTo(place); // TODO theme
CodeMirror.runMode(tiddler.text, ctype, el[0]);
}
else { _view.apply(this, arguments);}
} // if
else {_view.apply(this, arguments);}
}; // _view
})(jQuery);
//}}}
/***
!!!!! The default StyleSheetCodeMirror style sheet
***/
//{{{
config.shadowTiddlers["StyleSheetCodeMirror"]="/*{{{*/\n"+
"[[codemirror.css]]\n"+
"[[tiddlywiki.css]]\n"+
"\n"+
".CodeMirror {\n"+
" border: 1px solid [[ColorPalette::PrimaryMid]];\n"+
" background: [[ColorPalette::Background]];\n"+
"}\n"+
"/*}}}*/";
store.addNotification("StyleSheetCodeMirror",refreshStyles);
//}}}
/*{{{*/
config.options.txtBackupFolder = 'backups'
/*}}}*/