allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject [2/6] allura git commit: [#7955] WIP: cleanup to support fenced block boundary detection logic
Date Fri, 11 Sep 2015 19:34:14 GMT
[#7955] WIP: cleanup to support fenced block boundary detection logic


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/59d8ff95
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/59d8ff95
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/59d8ff95

Branch: refs/heads/db/7955
Commit: 59d8ff9589c48f903dc3dacc191739679858ff8d
Parents: 4b1cbcc
Author: Dave Brondsema <dbrondsema@slashdotmedia.com>
Authored: Thu Sep 10 19:28:09 2015 +0000
Committer: Dave Brondsema <dbrondsema@slashdotmedia.com>
Committed: Thu Sep 10 19:28:09 2015 +0000

----------------------------------------------------------------------
 .../lib/widgets/resources/js/sf_markitup.js     | 244 +++++++++++--------
 1 file changed, 143 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/59d8ff95/Allura/allura/lib/widgets/resources/js/sf_markitup.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/sf_markitup.js b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
index 5513742..027a9c0 100644
--- a/Allura/allura/lib/widgets/resources/js/sf_markitup.js
+++ b/Allura/allura/lib/widgets/resources/js/sf_markitup.js
@@ -32,7 +32,7 @@ $(window).load(function() {
               "bold", "italic", "heading", "|",
               {
                 name: 'code',
-                action: toggleCodeBlockTildes,
+                action: toggleCodeBlockTildes, // TODO: highlight button when active
                 className: 'fa fa-code',
                 title: 'Code Block'
               },
@@ -68,7 +68,7 @@ $(window).load(function() {
                 highlightFormatting: true,
                 allowAtxHeaderWithoutSpace: true,
                 strikethrough: false,
-                taskLists: false,
+                taskLists: false
               }
             });
             editor.render();
@@ -98,6 +98,34 @@ $(window).load(function() {
             }
 
             function toggleCodeBlockTildes(editor) {
+              // NOTE: this requires highlightFormatting:true in the mode config
+
+              function code_type(cm, line_num, line, firstTok, lastTok) {
+                /*
+                 * Return 'single', 'indented', 'fenced' or false
+                 *
+                 * cm and line_num are required.  Others are optional for efficiency
+                 *   To check in the middle of a line, pass in firstTok yourself.
+                 */
+                line = line || cm.getLineHandle(line_num);
+                firstTok = firstTok || cm.getTokenAt({line: line_num, ch: 1});
+                lastTok = lastTok || (!!line.text && cm.getTokenAt({line: line_num,
ch: line.text.length-1}));
+                var types = firstTok.type ? firstTok.type.split(' ') : [];
+                if (lastTok && lastTok.state.base.indentedCode) {
+                  // have to check last char, since first chars of first line aren't marked
as indented
+                  return 'indented';
+                } else if (types.indexOf('comment') === -1) {
+                  // has to be after 'indented' check, since first chars of first indented
line aren't marked as such
+                  return false;
+                } else if (firstTok.state.base.code &&
+                           (!line.styles || line.styles.length <= 2 || line.styles[2].indexOf('formatting-code-block')
=== -1)) {
+                  // have to look for the formatting-code-block style, since opening ```
has state.base.code set unlike all other fenced lines
+                  return 'single';
+                } else {
+                  return 'fenced';
+                }
+              }
+
               var cm = editor.codemirror,
                 cur_start = cm.getCursor('start'),
                 cur_end = cm.getCursor('end'),
@@ -105,113 +133,128 @@ $(window).load(function() {
                 types = tok.type ? tok.type.split(' ') : [],
                 line = cm.getLineHandle(cur_start.line),
                 lastTok = !!line.text && cm.getTokenAt({line: cur_start.line, ch:
line.text.length-1}),
-                is_code_block_indented = lastTok && lastTok.state.base.indentedCode,
// have to check last char, since first chars of first line aren't marked as indented
-                is_code = types.indexOf('comment') !== -1 || is_code_block_indented, // have
to also check for indented, since first chars of first indented line aren't marked
-                is_code_single_line = tok.state.base.code, // FIXME false-positive for ```
line, check for formatting-code-block
-                is_code_block_fenced = !is_code_block_indented && !is_code_single_line;
+                is_code = code_type(cm, cur_start.line, line, tok, lastTok);
+              var block_start, block_end, lineCount;
 
-              console.log(lastTok);
-              console.log('code:', is_code, 'indented', is_code_block_indented, 'fenced',
is_code_block_fenced, 'single', is_code_single_line);
-              //console.log(cm.getLineTokens(start.line));
+              console.log(line);
+              console.log('code:', is_code);
 
-              if (is_code) {
-                if (is_code_single_line) {
-                  // similar to some SimpleMDE _toggleBlock logic
-                  var start = line.text.slice(0, cur_start.ch).replace('`',''),
-                    end = line.text.slice(cur_start.ch).replace('`', '');
-                  cm.replaceRange(start + end, {
-                    line: cur_start.line,
-                    ch: 0
-                  }, {
-                    line: cur_start.line,
-                    ch: 99999999999999
-                  });
-                  cur_start.ch--;
-                  cur_end.ch--;
-                  cm.setSelection(cur_start, cur_end);
-                  cm.focus();
-                } else if (is_code_block_fenced) {
-                  /*
-                  DEBUG
-                  */
-                  for (var i = 0; i < cm.lineCount(); i++) {
-                    tok0 = cm.getTokenAt({line: i, ch: 0});
-                    tok1 = cm.getTokenAt({line: i, ch: 1});
-                    //types0 = cm.getTokenTypeAt({line: i, ch:0});
-                    //types1 = cm.getTokenTypeAt({line: i, ch:1});
-                    line = cm.getLineHandle(i);
-                    //lineToks = cm.getLineTokens(i);
-                    //lastTok = lineToks.length && lineToks[lineToks.length-1]
-                    lastTok = line.text && cm.getTokenAt({line: i, ch: line.text.length-1});
-                    console.log('line', i,
-                      tok0.type, ',', tok1.type, ',',
-                      //tok0.state.base.indentedCode, tok1.state.base.indentedCode,
-                      'last tok indented:', lastTok && lastTok.state.base.indentedCode,
-                      'first tok indented:', tok1.state.base.indentedCode,
-                      'last tok inline code:', lastTok && lastTok.state.base.code,
-                      'first tok inline code:', tok1.state.base.code,
-                      'last tok type:', lastTok && lastTok.type,
-                      'styles:', line && line.styles, line && line.text);
-                    //console.log(cm.getLineTokens(i));
-                  }
-                  return;
+              if (is_code === 'single') {
+                // similar to some SimpleMDE _toggleBlock logic
+                var start = line.text.slice(0, cur_start.ch).replace('`',''),
+                  end = line.text.slice(cur_start.ch).replace('`', '');
+                cm.replaceRange(start + end, {
+                  line: cur_start.line,
+                  ch: 0
+                }, {
+                  line: cur_start.line,
+                  ch: 99999999999999
+                });
+                cur_start.ch--;
+                cur_end.ch--;
+                cm.setSelection(cur_start, cur_end);
+                cm.focus();
+              } else if (is_code === 'fenced') {
+                /*
+                DEBUG
+                */
+                for (var i = 0; i < cm.lineCount(); i++) {
+                  tok0 = cm.getTokenAt({line: i, ch: 0});
+                  tok1 = cm.getTokenAt({line: i, ch: 1});
+                  //types0 = cm.getTokenTypeAt({line: i, ch:0});
+                  //types1 = cm.getTokenTypeAt({line: i, ch:1});
+                  line = cm.getLineHandle(i);
+                  //lineToks = cm.getLineTokens(i);
+                  //lastTok = lineToks.length && lineToks[lineToks.length-1]
+                  lastTok = line.text && cm.getTokenAt({line: i, ch: line.text.length-1});
+                  console.log('line', i,
+                    tok0.type, ',', tok1.type, ',',
+                    //tok0.state.base.indentedCode, tok1.state.base.indentedCode,
+                    'last tok indented:', lastTok && lastTok.state.base.indentedCode,
+                    'first tok indented:', tok1.state.base.indentedCode,
+                    'last tok inline code:', lastTok && lastTok.state.base.code,
+                    'first tok inline code:', tok1.state.base.code,
+                    'last tok type:', lastTok && lastTok.type,
+                    'styles:', line && line.styles, line && line.text);
+                  //console.log(cm.getLineTokens(i));
+                }
+                //return;
 
-                  // look for formatting-code-block with highlightFormatting turned on  :(
-                  // or look for whole line being "comment" and not tok.state.base.code (which
means inline)
-                  // FIXME what about selection?
-                  cm.replaceRange('', {line: block_start-1, ch:0}, {line: block_start, ch:0});
-                  cm.replaceRange('', {line: block_end, ch:0}, {line: block_end+1, ch:0});
-                } else if (is_code_block_indented) {
-                  var block_start, block_end;
-                  if (cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
-                    // use selection
-                    block_start = cur_start.line;
-                    block_end = cur_end.line;
-                    if (cur_end.ch === 0) {
-                      block_end--;
-                    }
-                  } else {
-                    // no selection, search for ends of this indented block
-                    for (block_start = cur_start.line; block_start >= 0; block_start--)
{
-                      line = cm.getLineHandle(block_start);
-                      if (line.text.match(/^\s*$/)) {
-                        // empty or all whitespace - keep going
-                        continue;
-                      } else {
-                        lastTok = cm.getTokenAt({line: block_start, ch: line.text.length-1});
-                        if (!lastTok.state.base.indentedCode) {
-                          block_start += 1;
-                          break;
-                        }
+                // FIXME what about selection?
+
+                // no selection, search for ends of this fenced block
+
+                console.log('current line is', code_type(cm, cur_start.line));
+
+                for (block_start = cur_start.line; block_start >= 0; block_start--) {
+                  line = cm.getLineHandle(block_start);
+                  if (line.styles && line.styles.length > 2 && line.styles[2].indexOf('formatting-code-block')
!== -1) {
+                    break;
+                  }
+                }
+                lineCount = cm.lineCount();
+                for (block_end = cur_start.line; block_end < lineCount; block_end++) {
+                  line = cm.getLineHandle(block_end);
+                  if (line.styles && line.styles.length > 2 && line.styles[2].indexOf('formatting-code-block')
!== -1) {
+                    break;
+                  }
+                }
+                cm.operation(function() {
+                  cm.replaceRange('', {line: block_start, ch:0}, {line: block_start+1, ch:0});
+                  cm.replaceRange('', {line: block_end-1, ch:0}, {line: block_end, ch:0});
+                });
+                cm.focus();
+              } else if (is_code === 'indented') {
+                if (cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
+                  // use selection
+                  block_start = cur_start.line;
+                  block_end = cur_end.line;
+                  if (cur_end.ch === 0) {
+                    block_end--;
+                  }
+                } else {
+                  // no selection, search for ends of this indented block
+                  for (block_start = cur_start.line; block_start >= 0; block_start--)
{
+                    line = cm.getLineHandle(block_start);
+                    if (line.text.match(/^\s*$/)) {
+                      // empty or all whitespace - keep going
+                      continue;
+                    } else {
+                      //lastTok = cm.getTokenAt({line: block_start, ch: line.text.length-1});
+                      //if (!lastTok.state.base.indentedCode) {
+                      if (code_type(cm, block_start, line) !== 'indented') {
+                        block_start += 1;
+                        break;
                       }
                     }
-                    lineCount = cm.lineCount();
-                    for (block_end = cur_start.line; block_end < lineCount; block_end++)
{
-                      line = cm.getLineHandle(block_end);
-                      if (line.text.match(/^\s*$/)) {
-                        // empty or all whitespace - keep going
-                        continue;
-                      } else {
-                        lastTok = cm.getTokenAt({line: block_end, ch: line.text.length-1});
-                        if (!lastTok.state.base.indentedCode) {
-                          block_end -= 1;
-                          break;
-                        }
+                  }
+                  lineCount = cm.lineCount();
+                  for (block_end = cur_start.line; block_end < lineCount; block_end++)
{
+                    line = cm.getLineHandle(block_end);
+                    if (line.text.match(/^\s*$/)) {
+                      // empty or all whitespace - keep going
+                      continue;
+                    } else {
+                      if (code_type(cm, block_end, line) !== 'indented') {
+                      //lastTok = cm.getTokenAt({line: block_end, ch: line.text.length-1});
+                      //if (!lastTok.state.base.indentedCode) {
+                        block_end -= 1;
+                        break;
                       }
                     }
                   }
-                  // if we are going to un-indent based on a selected set of lines, and the
next line is indented too, we need to
-                  // insert a blank line so that the next line(s) continue to be indented
code
-                  var next_line = cm.getLineHandle(block_end+1),
-                    next_line_last_tok = next_line && cm.getTokenAt({line: block_end+1,
ch: next_line.text.length-1}),
-                    next_line_indented = next_line_last_tok && next_line_last_tok.state.base.indentedCode;
-                  if (next_line_indented) {
-                    cm.replaceRange('\n', {line: block_end+1, ch:0});
-                  }
+                }
+                // if we are going to un-indent based on a selected set of lines, and the
next line is indented too, we need to
+                // insert a blank line so that the next line(s) continue to be indented code
+                var next_line = cm.getLineHandle(block_end+1),
+                  next_line_last_tok = next_line && cm.getTokenAt({line: block_end+1,
ch: next_line.text.length-1}),
+                  next_line_indented = next_line_last_tok && next_line_last_tok.state.base.indentedCode;
+                if (next_line_indented) {
+                  cm.replaceRange('\n', {line: block_end+1, ch:0});
+                }
 
-                  for (var i = block_start; i <= block_end; i++) {
-                    cm.indentLine(i, 'subtract'); // TODO: this doesn't get tracked in the
history, so can't be undone :(
-                  }
+                for (var i = block_start; i <= block_end; i++) {
+                  cm.indentLine(i, 'subtract'); // TODO: this doesn't get tracked in the
history, so can't be undone :(
                 }
               } else {
                 // insert code formatting
@@ -242,7 +285,6 @@ $(window).load(function() {
                 } else {
                   _replaceSelection(cm, false, '`', '`');
                 }
-
               }
             }
 


Mime
View raw message