Parsers, whoa.

main
Shoofle 11 years ago
parent 2462baebaf
commit b28faf3ea5
  1. 28
      articles/text_editors_with_contenteditable.article.html
  2. 58
      static/text_editor.html

@ -1,4 +1,30 @@
<article>
<p>I've been playing with an exciting feature of HTML5 that I hadn't heard of: the <code class="language-html">contentEditable</code> attribute. It's magical! It just makes anything suddenly be editable in-browser! It also finally provides me with the thing I've been wanting ever since growing dissatisfied with text editors: A way to build a <em>new</em> text editor, <em>without</em> having to actually code up the guts of text movement, manipulation, and entry. Oh, happy day!</p>
<p>More on this as the situation progresses.</p>
</article>
/*
* This is my parser.
* It's not much, but it's mine.
*/
blocks = code:(if_block / lines)* { return code; }
if_block =
"if" ws "(" cond:string ")" ws "{" result:lines "}"
{ return {type: "if", condition: cond, body: result }; }
/*
while_block = "while" ws "(" cond:string ")" ws "{" result:lines "}"
{ return {type: "while", condition: cond, body: result }; }
*/
lines = lines:line+ ws?
{ return lines; }
line = ws? contents:string ";"
{ return contents; }
ws = (" " / "\n")+ { return ""; }
string = characters:([A-Za-z]+ [A-Za-z ]*) { return characters.join(""); }
</article>

@ -94,17 +94,17 @@ When I see the text "if (something)", then I should make a new if block.
<script type="text/javascript">
var finds_if_regex = /(?:^|\s+)(if\s*\([^)]+\)\s*)(\{[^}]*\})/
var finds_if_regex = /(?:\s*)(if\s*\([^)]+\)\s*)(\{[^}]*\})/;
function make_new_if(c1, c2) {
var thingeroo;
if (c1 == undefined) { thingeroo = $(this); }
if (c2 == undefined) { thingeroo = $(c1); }
else { thingeroo = $(c2); }
if (!thingeroo.is('.block.base')) {
thingeroo.find('.block.base').each(make_new_if);
} else if (finds_if_regex.exec(thingeroo.html())) {
var contents = thingeroo.html();
var target;
if (c1 == undefined) { target = $(this); }
if (c2 == undefined) { target = $(c1); }
else { target = $(c2); }
if (!target.is('.block.base')) {
target.find('.block.base').each(make_new_if);
} else if (finds_if_regex.exec(target.html())) {
var contents = target.html();
var split_up = contents.split(finds_if_regex);
var new_blocks = [];
new_blocks.push($('<div></div>').append(split_up[0]).addClass('block base'));
@ -123,30 +123,48 @@ function make_new_if(c1, c2) {
new_blocks.push(post_if);
}
}
thingeroo.after(new_blocks);
target.after(new_blocks);
console.log(new_blocks);
thingeroo.remove();
target.remove();
}
}
function make_new_else(container) {
var finds_else_regex = /(?:[^\S])\s*else\s*(\{[^}]*\})/;
function make_new_else(c1, c2) {
var target;
if (c1 == undefined) { target = $(this); }
if (c2 == undefined) { target = $(c1); }
else { target = $(c2); }
if (!target.is('.block.base')) {
target.find('.block.base')
}
}
var collapsible_block_selector = '.block.base';
var empty_text_regex = /\S/
var cbs = collapsible_block_selector;
function collapse_neighbors(container) {
container = $(container);
container.find('.block.base + .block.base').each(function () {
function collapse_blocks(c1, c2) {
var target;
if (c1 == undefined) { target = $(this); }
if (c2 == undefined) { target = $(c1); }
else { target = $(c2); }
target.find('.block.base').filter(function() { return !empty_text_regex.exec($(this).text()); }).remove();
target.find('.block.base + .block.base').each(function () {
var base = $(this).prev('.block.base');
var target = $(this);
var new_base_contents = base.html() + '<br>' + target.html();
var new_base_contents = base.html() + '<br>' + $(this).html();
base.html(new_base_contents);
target.remove();
$(this).remove();
});
target.children().each(collapse_blocks);
}
$(document).ready(function () {
$('#editor').on('input', function() { make_new_if($(this)); });
$('#editor').on('input', function() { collapse_neighbors($(this)); });
$('#editor').on('input', function() { collapse_blocks($(this)); });
});
</script>
</body>
</html>

Loading…
Cancel
Save