From 7576ca834942928d8c0467dc44fc50b54a78b052 Mon Sep 17 00:00:00 2001
From: anekos
Date: Sat, 7 Feb 2009 02:08:19 +0000
Subject: バグ修正&整理
git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@29665 d0d07461-0603-4401-acd4-de1884942a52
---
pluginManager.js | 454 +++++++++++++++++++++++++++++--------------------------
1 file changed, 240 insertions(+), 214 deletions(-)
(limited to 'pluginManager.js')
diff --git a/pluginManager.js b/pluginManager.js
index b8fc05a..bb724e2 100644
--- a/pluginManager.js
+++ b/pluginManager.js
@@ -123,7 +123,7 @@ var tags = { // {{{
return info.*;
var text = fromUTF8Octets(info.*.toString());
- var xml = WikiParser(text);
+ var xml = WikiParser.parse(text);
return xml;
}
}; // }}}
@@ -330,23 +330,40 @@ Plugin.prototype = { // {{{
// WikiParser
// -----------------------------------------------------{{{
var WikiParser = (function () {
-
function cloneArray (ary)
Array.concat(ary);
- function State (lines, result) {
+ function State (lines, result, indents) {
if (!(this instanceof arguments.callee))
- return new arguments.callee(lines, result);
+ return new arguments.callee(lines, result, indents);
this.lines = lines;
this.result = result || <>>;
+ this.indents = indents || [];
}
State.prototype = {
- get end () !this.lines.length,
+ get end () !(this.lines.length && let (i = this.indents[this.indents.length - 1])
+ /^\s*$/.test(this.head) || !i || i.test(this.head)),
+ get realEnd () !this.lines.length,
get head () this.lines[0],
set head (value) this.lines[0] = value,
- get clone () State(cloneArray(this.lines), this.result),
- get next () State(this.lines.slice(1), this.result),
+ get clone () State(cloneArray(this.lines), this.result, cloneArray(this.indents)),
+ get next () {
+ let result = this.clone;
+ result.lines = this.lines.slice(1);
+ return result;
+ },
+ indent: function (indent, more) {
+ let result = this.clone;
+ let re = RegExp('^' + indent.replace(/[^\s]/g, ' ') + (more ? '\\s+' : '') + '(.*)$');
+ result.indents.push(re);
+ return result;
+ },
+ indentBack: function () {
+ let result = this.clone;
+ result.indents.pop();
+ return result;
+ },
wrap: function (name) {
let result = this.clone;
result.result = <{name}>{this.result}{name}>;
@@ -397,245 +414,254 @@ var WikiParser = (function () {
function stripAndLink (s)
link(strip(s));
+ function isEmptyLine (s)
+ /^\s*$/.test(s);
- ////////////////////////////////////////////////////////////////////////////////
- // [Parser] -> OKError Parser
- function or () {
- let as = [];
- for (let i = 0, l = arguments.length; i < l; i++)
- as.push(arguments[i]);
- return function (st) {
- let a;
- for each (let a in as) {
- let r = a(st);
- if (ok(r))
- return r;
- }
- return Error('or-end', st);
- };
- }
+ ////////////////////////////////////////////////////////////////////////////////
- function map (p) {
- return function (st) {
- let result = [];
- let cnt = 0;
- while (!st.end) {
- st = p(st);
- if (ok(st))
- result.push(st.result);
- else
- break;
- if (cnt++ > 100) {
- liberator.log('100 break: map')
- break;
+ let C = {
+ // [Parser] -> OKError Parser
+ or: function or () {
+ let as = [];
+ for (let i = 0, l = arguments.length; i < l; i++)
+ as.push(arguments[i]);
+ return function (st) {
+ let a;
+ for each (let a in as) {
+ let r = a(st);
+ if (ok(r))
+ return r;
}
- }
- return st.set(result);
- }
- }
+ return Error('or-end', st);
+ };
+ },
- function whileMap (p) {
- return function (st) {
- let result = [];
- let next;
- let cnt = 0;
- while (!st.end) {
- next = p(st);
- if (ok(next))
- result.push(next.result);
- else
- break;
- st = next;
- if (cnt++ > 100) {
- liberator.log('100 break: whileMap')
- break;
+ many: function many (p) {
+ return function (st) {
+ let result = [];
+ let cnt = 0;
+ while (!st.end) {
+ let r = p(st);
+ if (ok(r))
+ result.push(r.result);
+ else
+ break;
+ st = r;
+ if (cnt++ > 100) { liberator.log('force break: many-while'); break; }
}
+ if (ok(st))
+ return st.set(result);
+ else
+ return Error('many', st);
}
- if (result.length)
- return st.set(result);
- else
- return Error('whileMap', st);
- }
- }
+ },
- function lv_map (lv, more, p) {
- let re = RegExp('^' + lv.replace(/[^\s]/g, ' ') + (more ? '\\s+' : '') + '(.*)$');
- return function (st) {
- let result = [];
- let cnt = 0;
- while (!st.end) {
- if (!re.test(st.head))
- break;
- st = p(st);
- if (!ok(st))
- return st;
- result.push(st.result);
- if (cnt++ > 100) {
- liberator.log('100 break')
- break;
+ many1: function many1 (p) {
+ return function (st) {
+ let result = [];
+ let cnt = 0;
+ while (!st.end) {
+ let r = p(st);
+ if (ok(r))
+ result.push(r.result);
+ else
+ break;
+ st = r;
+ if (cnt++ > 100) { liberator.log('force break: many1-while'); break; }
}
- }
- return st.set(result);
- };
- }
+ if (result.length) {
+ return st.set(result);
+ } else
+ return Error('many1', st);
+ };
+ },
+ indent: function indent (p) {
+ return function (st) {
+ if (st.end)
+ return Error('EOL', 'st');
+ else
+ return p(st);
+ };
+ }
+ };
////////////////////////////////////////////////////////////////////////////////
- function wiki (st) {
- let r = wikiLines(st);
- if (ok(r)) {
- let xs = r.result;
- return r.set(xmlJoin(xs)).wrap('div');
- } else {
- return Error('wiki', st);
+ let P = (function () {
+ function hn (n) {
+ let re = RegExp('^\\s*=={' + n + '}\\s+(.*)\\s*=={' + n + '}\\s*$');
+ return function (st) {
+ let m = st.head.match(re);
+ if (m) {
+ let hn = 'h' + n;
+ return st.next.set(<{hn} style={'font-size:'+(0.75+1/n)+'em'}>{stripAndLink(m[1])}{hn}>)
+ } else {
+ return Error('not head1', st);
+ }
+ };
}
- }
-
- // St -> St XML
- function plain (st) {
- let text = st.head;
- return st.next.set(<>{stripAndLink(text)}
>);
- }
-
- // St -> St XML
- function hn (n) {
- let re = RegExp('^\\s*=={' + n + '}\\s+(.*)\\s*=={' + n + '}\\s*$');
- return function (st) {
- let m = st.head.match(re);
- if (m) {
- let hn = 'h' + n;
- return st.next.set(<{hn} style={'font-size:'+(0.75+1/n)+'em'}>{stripAndLink(m[1])}{hn}>)
- } else {
- return Error('not head1', st);
- }
- };
- }
- let h1 = hn(1);
- let h2 = hn(2);
- let h3 = hn(3);
- let h4 = hn(4);
-
- // St -> St XML
- function dl (st) {
- let r = whileMap(dtdd)(st);
- if (ok(r)) {
- let body = xmlJoin(r.result);
- return r.set(body).wrap('dl');
- } else {
- return Error('dl', st);
+ function list (name) {
+ return function (st) {
+ let lis = C.many1(self[name + 'i'])(st);
+ if (ok(lis)) {
+ return lis.set(xmlJoin(lis.result)).wrap(name);
+ } else {
+ return Error(name, st);
+ }
+ };
}
- }
- // St -> St XML
- function dtdd (st) {
- let r = dt(st);
- if (ok(r)) {
- let [lv, _dt] = r.result;
- let _dd = lv_dd(lv, wikiLine)(r);
- return _dd.set(_dt +
{result}); + } else { + return Error('pre', st); + } + }, - // St -> St XML - function ul (st) { - let lis = whileMap(li)(st); - if (ok(lis)) { - return lis.set(xmlJoin(lis.result)).wrap('ul'); - } else { - return Error('ul', st); - } - } + // St -> St XML + ul: list('ul'), - // St -> St XML - function li (st) { - let m = st.head.match(/^(\s*- )(.*)$/); - if (m) { - st.head = st.head.replace(/- /, ' '); - let r = lv_map(m[1], false, wikiLine)(st); - return r.set(xmlJoin(r.result)).wrap('li'); - } else { - return Error('li', st); - } - } + // St -> St XML + uli: listItem('-'), - // St -> St XML - function ol (st) { - let lis = whileMap(oli)(st); - if (ok(lis)) { - return lis.set(xmlJoin(lis.result)).wrap('ol'); - } else { - return Error('ol', st); - } - } + // St -> St XML + ol: list('ol'), - // St -> St XML - function oli (st) { - let m = st.head.match(/^(\s*\+ )(.*)$/); - if (m) { - st.head = st.head.replace(/\+ /, ' '); - let r = lv_map(m[1], false, wikiLine)(st); - return r.set(xmlJoin(r.result)).wrap('li'); - } else { - return Error('li', st); - } - } + // St -> St XML + oli: listItem('+'), - // St -> St XML - function pre (st) { - let m = st.head.match(/^(\s*)>\|\|\s*$/); - if (m) { - let result = ''; - let cnt = 0; - while (!st.end) { - st = st.next; - if (/^(\s*)\|\|<\s*$/.test(st.head)){ - st = st.next; - break; + // St -> St XML + dl: function dl (st) { + let r = C.many1(self.dtdd)(st); + if (ok(r)) { + let body = xmlJoin(r.result); + return r.set(body).wrap('dl'); + } else { + return Error('dl', st); } - result += st.head.replace(m[1], '') + '\n'; - if (cnt++ > 100) { - liberator.log('br') - break; + }, + + // St -> St XML + dtdd: function dtdd (st) { + let r = self.dt(st); + if (ok(r)) { + let [indent, dt] = r.result; + let dd = C.many(self.wikiLine)(r.indent(indent, true)); + return dd.indentBack().set(dt +
{result}); - } else { - return Error('pre', st); } - } - // St -> St XML - let wikiLine = or(h1, h2, h3, h4, dl, ul, ol, pre, plain); + for (let [name, p] in Iterator(self)) { + self[name] = C.indent(p); + } + + return self; + })(); - // St -> St [XML] - let wikiLines = map(wikiLine); - return liberator.plugins.PMWikiParser = function (src) { - let r = wiki(State(src.split(/\n/))); - if (ok(r)) - return r.result; - else - liberator.echoerr(r.name); + return liberator.plugins.PMWikiParser = { + parsers: P, + combs: C, + classes: { + State: State, + }, + parse: function (src) { + let r = P.wiki(State(src.split(/\n/))); + if (ok(r)) + return r.result; + else + liberator.echoerr(r.name); + } }; })(); -- cgit v1.2.3