Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
johnny committed Aug 20, 2011
1 parent 5ff9aca commit 7c2e68a
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 10 deletions.
121 changes: 115 additions & 6 deletions public/javascripts/modes/textile/bruteForceCompiler.js
@@ -1,22 +1,48 @@
textileCompiler = (function (){
(function (){
/**
* @name Builder
*
* The builder compiles the textile. It can also trace the common nodes between
* a start and an end point.
*
* Therefore it has two stacks: one for building and one for tracing
*/

/**
* @type Builder
*/
var builder = (function (){
var stack, tracingStack, stackPosition, traceJustStarted, traceJustEnded, popping, pointer, sP, eP, tracing, lastTrace, unsuccessfulPush = false;
definableAttributes = {
img: ['title','src'],
a: ['href']
};

function iterateOverAttributes(tag, callBack){
/**
* Iterate over the attributes of the given tag and call the callback.
* Used for comparison of the attributes of two nodes
*
* @param {String} tag
* @param {Function} callback
*/
function iterateOverAttributes(tag, callback){
var attributes = ['class'],i;
if(definableAttributes[tag]){
attributes = attributes.concat(definableAttributes[tag]);
}
for(i = attributes.length;i--;){
callBack(attributes[i]);
callback(attributes[i]);
}
}

function moveStackUp(targetNode){
/**
* Test if the tracing stack can be moved down again with the given node.
*
* @param {TraceNode} targetNode The node to test
*
* @returns {Boolean}
*/
function canMoveStackDown(targetNode){
var equalTag = true, key, equalAttributes = true, blockTag = (stackPosition == -1), stackNode, i, l;
if(blockTag){
stackNode = tracingStack[0];
Expand Down Expand Up @@ -49,11 +75,24 @@ textileCompiler = (function (){
return stackNode && (blockTag || equalAttributes);
}

/**
* Create a new TraceNode form a given node
* @constructor
*
* @param {object} node
*/
function traceNode(node){
return {tag: node.tag,
attributes: node.attributes};
}

/**
* Create a open-tag for the given node
*
* @param {object} node
*
* @return {String}
*/
function htmlOpenTag(node){
var attributeString = "";
for(attr in node.attributes){
Expand All @@ -64,6 +103,14 @@ textileCompiler = (function (){
return "<" + node.tag + attributeString + ">";
}

/**
* Warning! this supposes, that there is only one instance of any tag in
* the stack
*
* @param {String} tag
*
* @returns {Integer} The stack position of the given tag
*/
function getStackPositionOf(tag){
var i;
for(i = stack.length;i--; ){
Expand All @@ -73,6 +120,9 @@ textileCompiler = (function (){
}
}

/**
* Start the tracing
*/
function startTrace(){
var length = stack.length, i;
// console.log("################################## startTrace");
Expand All @@ -85,29 +135,50 @@ textileCompiler = (function (){
stackPosition = tracingStack.length -1;
}

/**
* End the tracing
*/
function endTrace(){
// console.log("#################################### endTrace");
// console.log(tracingStack.length);
lastTrace = false;
tracing = false;
}

/**
* @lends Builder
*/
return {
/**
* Initialize Builder for normal operation
*/
init: function(){
stack = [{content:""}];
},
/**
* Initialize Builder for tracing operation
*/
initTrace: function(startPosition, endPosition){
tracingStack = [];
tracing = undefined;
pointer = 0;
sP = startPosition;
eP = endPosition;
},
/**
* Definitly ends the trace
*/
finalizeTrace: function(){
if(tracing){
endTrace();
}
},
/**
* Advance the pointer by the given amount.
* Handles starting and ending of the trace
*
* @param {Integer} advanceAmount
*/
advancePointer: function(advanceAmount){
pointer += advanceAmount;
// console.log("pointer",pointer,"endPointer", eP);
Expand All @@ -120,6 +191,12 @@ textileCompiler = (function (){
lastTrace = true;
}
},
/**
* Push a tag to the build stack
*
* @param {String} tag
* @param {Object} attributes
*/
pushTag: function(tag, attributes){
var node = {tag: tag,
attributes: attributes || {},
Expand All @@ -133,7 +210,7 @@ textileCompiler = (function (){
stackPosition += 1;
}
else if(tracingStack[stackPosition+1]){
if(moveStackUp(node)){
if(canMoveStackDown(node)){
stackPosition += 1;
} else {
unsuccessfulPush = true;
Expand All @@ -142,6 +219,12 @@ textileCompiler = (function (){
// console.log("stackPosition " + stackPosition);
}
},
/**
* Close a tag. If a tag is given find it and close it. Otherwise the top
* tag is closed
*
* @param {String} [tag]
*/
closeTag: function(tag){
var removedNode, i;
if(tag){
Expand Down Expand Up @@ -175,6 +258,10 @@ textileCompiler = (function (){
this.pushString("</"+removedNode.tag+">");
popping = false;
},
/**
* Closes all textile markup that ends at a line break.
* For example "*" or "_"
*/
popLineEnd: function(){
var surpressLineBreak = false, partialMarkup = {b: "*", i: "_"}, node;
// If the need arises to search deeper think of the correct
Expand All @@ -190,11 +277,20 @@ textileCompiler = (function (){
}
return surpressLineBreak;
},
/**
* Closes all open tags
*/
popParagraphEnd: function(){
while(stack.length > 1){
this.closeTag();
}
},
/**
* Add a string to the given node or the top node.
*
* @param {String} string
* @param {Object} [node] defaults to the top node in the stack
*/
pushString: function(string, node){
if(!node){
node = stack[stack.length - 1];
Expand All @@ -214,13 +310,26 @@ textileCompiler = (function (){
}
}
},
/**
* Check if the given tag is open
*
* @param {String} tag
*
* @returns {Boolean}
*/
isOpen: function(tag){
// console.log("check is Open", tag, stack.length);
return typeof getStackPositionOf(tag) === 'number';
},
/**
* @returns {Object} The trace stack
*/
getTrace: function(){
return tracingStack;
},
/**
* @returns {String} The compiled html
*/
toHtml: function(){
// console.log(stack);
return stack[0].content;
Expand Down Expand Up @@ -385,7 +494,7 @@ textileCompiler = (function (){
}
}

return {
textileCompiler = {
compile: function(textToCompile){
builder.init();
text = textToCompile;
Expand Down
62 changes: 58 additions & 4 deletions public/javascripts/modes/textile/textileMode.js
Expand Up @@ -2,6 +2,13 @@ ME.addMode("textile", function() {
var text, selectionStart, startOfParagraphs, endOfParagraphs, oldExtendedSelectionLength, currentNodes = {},
$ = jQuery;

/**
* Iterate over each paragraph and call the functor on it and set the paragraphs
* CONSIDER rename or move setParagraphs out of it
*
* @param {Mode} mode The current mode
* @param {Function} functor The functor will be applied on each paragraph
*/
function eachParagraph(toolbar, functor) {
var mode = toolbar.editor.currentMode, paragraphs = mode.getParagraphs(), paragraphsLength = paragraphs.length;

Expand All @@ -11,6 +18,12 @@ ME.addMode("textile", function() {
mode.setParagraphs(paragraphs);
}

/**
* Execute align command
*
* @param {Mode} mode The current mode
* @param {String} orientation The orientation of the alignment
*/
function align(toolbar, orientation) {
eachParagraph(toolbar, function(paragraph) {
var classes, classesLength, newClasses = [];
Expand All @@ -32,6 +45,13 @@ ME.addMode("textile", function() {
});
}

/**
* Scan the textarea for the first match and set selection to it.
* This is useful e.g. for finding a link markup with a given source
*
* @param {Mode} mode The current mode
* @param {RegExp} r The regexp to search for
*/
function scanForMatch(toolbar,r){
match = r.exec(text);
if(r.lastIndex === 0){
Expand Down Expand Up @@ -217,10 +237,18 @@ ME.addMode("textile", function() {
}
}
},
/**
* Compile textile and update the preview div
*/
updatePreview: function() {
var html = textileCompiler.compile(this.textArea.val());
this.htmlDiv.html(html);
},
/**
* Convert preview div to textile
*
* @returns {String} A textile string
*/
toText: function(html) {
if(!html){
html = this.htmlDiv.html();
Expand Down Expand Up @@ -257,6 +285,11 @@ ME.addMode("textile", function() {

return html;
},
/**
* Get the states for the current selection
*
* @return {Object} An object representing the states
*/
getStates: function() {
var paragraphs = this.getExtendedSelection(),
startTrace = selectionStart - startOfParagraphs,
Expand All @@ -265,6 +298,13 @@ ME.addMode("textile", function() {

return this.buildStateObject(trace, currentNodes = {});
},
/**
* Get the paragraphs containing the current selection
*
* CONSIDER remove this? is it only needed for getParagraphs?
*
* @returns {String} The paragraphs
*/
getExtendedSelection: function(){
var paragraphIndex, searchIndex = 0, extendedSelection;
selectionStart = this.textArea[0].selectionStart;
Expand All @@ -291,9 +331,17 @@ ME.addMode("textile", function() {

return extendedSelection;
},
/**
* @returns {String[]} An array of paragraphs
*/
getParagraphs: function() {
return this.getExtendedSelection().split(/\n\n+/);
},
/**
* Set the paragraphs and move the caret
*
* @param {String[]} paragraphs An array of paragraphs
*/
setParagraphs: function(paragraphs) {
paragraphs = paragraphs.join("\n\n");

Expand All @@ -305,11 +353,17 @@ ME.addMode("textile", function() {

this.moveCaret(paragraphs.length - oldExtendedSelectionLength);
},
moveCaret: function(offset) {
console.log("Moving caret: " + offset);
/**
* Move the caret by the given distance. Positive values move the caret to
* the right, negative to the left.
*
* @param {Integer} distance The distance to move the caret
*/
moveCaret: function(distance) {
// console.log("Moving caret: " + distance);

if(Math.abs(selectionStart - startOfParagraphs) > Math.abs(offset)) {
selectionStart += offset;
if(Math.abs(selectionStart - startOfParagraphs) > Math.abs(distance)) {
selectionStart += distance;
} else {
selectionStart = startOfParagraphs;
}
Expand Down

0 comments on commit 7c2e68a

Please sign in to comment.