OSDN Git Service

fix defun-wiki-command output.
authorvisor <visor@users.sourceforge.jp>
Mon, 15 Nov 2010 15:38:50 +0000 (00:38 +0900)
committervisor <visor@users.sourceforge.jp>
Mon, 15 Nov 2010 15:38:50 +0000 (00:38 +0900)
modules/ml-motor.cc
wiki/wikicmd.cc
wiki/wikicmd.h
wiki/wikienv.cc
wiki/wikienv.h
wiki/wikiformat.cc
wiki/wikiformat.h
wiki/wikimotor.h

index 60db047..a1b918a 100644 (file)
@@ -160,7 +160,7 @@ MNode*  ml_motor_item (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===motor-output===
  (motor-output TEXT...) -> NIL
-Text output via HTMLMotor.
+Text output via HTMLMotor as HTML template.
 
 */
 //#AFUNC       motor-output    ml_motor_output
@@ -216,6 +216,7 @@ MNode*  ml_motor_output_html (MNode* cell, MlEnv* mlenv) {
 /*DOC:
 ===motor-output-raw===
  (motor-output-raw TEXT...) -> NIL
+Text output asis.
 
 */
 //#AFUNC       motor-output-raw        ml_motor_output_raw
index c0b3311..c89da51 100644 (file)
@@ -15,6 +15,9 @@
 #include <assert.h>
 #include <stdlib.h>
 
+/*
+WIKICOMPAT: 1をセットすると,defun-wiki-commandで定義した関数の中で,motor-output, motor-output-rawで出力したテキストをWikiテキストとして解釈する。
+*/
 /*DOC:
 ==行コマンド==
 
@@ -35,6 +38,7 @@ static void  do_linevec (WikiLine::linevec* block, WikiFormat* wiki) {
 +...
 +$endrepeat
 }
+変数''VAR''に,数値''FROM''から''TO''までの値を1づつ加算しながら代入し,$endrepeatまでの間のブロックを繰り返し実行する。
 
 */
 //#WIKICMD     $repeat $endrepeat      wc_repeat
@@ -94,11 +98,16 @@ void  wc_repeat (WikiLine* wl, WikiFormat* wiki) {
 /*DOC:
 ===$doarray===
 {div:pre
-+$doarray:''VAR'',''VAR'',...:''INDEX_VAR''
++$doarray:''VAR1'',''VAR2'',...[:''INDEX_VAR'']
 +...
 +$enddoarray
 }
 
+配列''VAR1'', ''VAR2'', ...の各要素をそれぞれ変数''VAR1'', ''VAR2'', ...に代入しながら,$enddoarrayまでのブロックを繰り返し実行する。
+ブロックの中で変数''VAR1'', ...に代入した値は,配列に書き戻される。
+配列の長さが異なる場合は,配列''VAR1''の長さに揃えられる。
+''INDEX_VAR''を指定すると,配列のインデックス番号を変数''INDEX_VAR''に代入して,ブロックを実行する。
+
 */
 //#WIKICMD     $doarray        $enddoarray     wc_doarray
 void  wc_doarray (WikiLine* wl, WikiFormat* wiki) {
@@ -168,6 +177,9 @@ void  wc_doarray (WikiLine* wl, WikiFormat* wiki) {
 +$endblock
 }
 
+LISPセル''EXPR''が真のとき,$elseblockまたは$endblockまでのブロックを実行する。
+$elseblockに条件を書かないとき,それ以前のすべての条件が真でないときに次のブロックを実行する。
+
 */
 //#WIKICMD     $block  $elseblock      $endblock       wc_block
 void  wc_block (WikiLine* wl, WikiFormat* wiki) {
@@ -285,6 +297,8 @@ void  wc_setvar (WikiLine* wl, WikiFormat* wiki) {
 +$eval:''EXPR''
 }
 
+LISPセル''EXPR''を実行する。
+
 */
 //#WIKICMD     $eval   wc_eval
 void  wc_eval (WikiLine* wl, WikiFormat* wiki) {
@@ -330,6 +344,10 @@ void  wc_eval (WikiLine* wl, WikiFormat* wiki) {
 +$insert:VARIABLE:superuser:==
 }
 
+変数''VARIABLE''に格納されたWikiテキストを挿入する。
+オプションの「=」を追加すると,「=」の数だけ挿入されるWikiテキストのタイトルの深さが下げられる。
+superuserオプションをつけると,
+
 */
 //#WIKICMD     $insert wc_insert
 void  wc_insert (WikiLine* wl, WikiFormat* wiki) {
@@ -368,10 +386,12 @@ void  wc_insert (WikiLine* wl, WikiFormat* wiki) {
        }
     }
     if (args.size () >= 1) {
+       AutoInclCount  autoIncl (wiki->mlenv);
        ustring  text = wiki->getVar (args[0]);
        WikiLine::linevec  bl;
        wiki->headbase += hn;
        wiki->pass1 (text, &bl, super);
+       autoIncl.inc ();
        do_linevec (&bl, wiki);
        wiki->headbase -= hn;
     }
@@ -495,6 +515,143 @@ void  wc_local (WikiLine* wl, WikiFormat* wiki) {
 }
 
 /* ============================================================ */
+/*DOC:
+===$macro===
+{div:pre
++$macro:''NAME'':''VARIABLE'',...
++...
++$endmacro
++
+$NAME:PARAM,...
+}
+マクロは組み込みコマンドをオーバーライドできない。
+
+*/
+//#WIKICMD     $macro  $endmacro       wc_macro
+void  wc_macro (WikiLine* wl, WikiFormat* wiki) {
+    WikiMotor  motor (wl->begin, wl->end, wiki);
+    WikiMotorObjVec  objv;
+    WikiMotorObjVecVec  args;
+    ustring  name;
+//    std::vector<ustring>  vars;
+    MNodeList  vars;
+    int  i, n;
+
+    assert (0); // メモリ管理問題
+
+    if (wiki->protectMode && ! wl->fsuper) {
+#ifdef DEBUG
+       std::cerr << "(wiki):(protected)\n";
+#endif /* DEBUG */
+       return;
+    }
+
+#ifdef DEBUG
+    std::cerr << "(wiki):" << ustring (wl->begin0, wl->end) << "\n";
+#endif /* DEBUG */
+
+    motor.compile (objv);
+    objv.splitCharA (':', args);
+    if (args.size () >= 1) {
+       name = clipWhite (args[0]->textOut (wiki));
+    } else {
+       wiki->errorMsg.append (CharConst ("$macro: wrong number of parameters.\n"));
+       return;
+    }
+    if (args.size () == 2) {
+       WikiMotorObjVecVec  v;
+       args[1]->splitCharA (',', v);
+       for (i = 0; i < v.size (); i ++) {
+//         vars.push_back (clipWhite (v[i]->textOut (wiki)));
+           vars.append (newMNode_str (new ustring (clipWhite (v[i]->textOut (wiki)))));
+       }
+    } else if (args.size () > 2) {
+       wiki->errorMsg.append (CharConst ("$macro: wrong number of parameters.\n"));
+    }
+
+    if (wl->block) {
+       wiki->env->wikienv->wikiMacro.setVar (name, vars.release (), wl->block);
+       wl->block = NULL;
+    }
+
+#ifdef DEBUG
+//    std::cerr << "(wiki):$endmacro\n";
+#endif /* DEBUG */
+}
+
+/* ============================================================ */
+static void  call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
+    WikiMotorObjVecVec  argsv;
+    MNodePtr  vargs;
+
+    objv2.splitCharA (':', argsv);
+    vargs = wiki->buildArgs (argsv.begin (), argsv.end ());
+    {
+       MotorOutputString  out;
+       MotorOutput*  back = wiki->env->output;
+       WikiMotorOutputString*  wikiback = wiki->env->wikioutput;
+       WikiMotorOutputString  wikiout (wiki);
+       MNodePtr  node;
+       MNodePtr  bcell;
+
+       wiki->env->wikioutput = &wikiout;
+       wiki->env->output = &out;
+       bcell = wiki->env->mlenv->currentCell;
+       wiki->env->mlenv->currentCell = NULL;
+       try {
+           node = execDefun (wiki->env->mlenv, wf, vargs (), name);
+       } catch (ustring& msg) {
+           wiki->logLispFunctionError (msg, ustring (wl->begin, wl->end));
+       }
+       wiki->env->mlenv->currentCell = bcell;
+       if (wikiout.ans.length () > 0) {
+           WikiLine::linevec  bl;
+           wiki->pass1 (wikiout.ans, &bl, wl->fsuper);
+           do_linevec (&bl, wiki);
+       }
+       wiki->env->wikioutput = wikiback;
+       if (out.ans.length () > 0) {
+#ifdef WIKICOMPAT
+           WikiLine::linevec  bl;
+           wiki->pass1 (out.ans, &bl, wl->fsuper);
+           do_linevec (&bl, wiki);
+#else
+           wiki->pushBlockRaw (out.ans.begin (), out.ans.end ());
+#endif
+       }
+       wiki->env->output = back;
+    }
+}
+
+static void  call_defun_macro (ustring& name, WikiMacro* mf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
+    WikiMotorObjVecVec  argsv;
+//    MNodePtr  vargs;
+
+    objv2.splitCharA (':', argsv);
+//    vargs = wiki->buildArgs (argsv.begin (), argsv.end ());
+//    mf->mars;
+    {
+       AutoLocalVariable  autoLocal (wiki->mlenv);
+       MNode*  p = mf->vars ();
+       MNode*  t;
+       MNode*  v;
+       int  i, n;
+       n = argsv.size ();
+       i = 0;
+       while (p && (t = p->car ())) {
+           if (i < n) {
+               v = newMNode_str (new ustring (argsv[i]->textOut (wiki)));
+               i ++;
+           } else {
+               v = NULL;
+           }
+           wiki->mlenv->setLocalVar (to_string (t), v);
+           p = p->cdr ();
+       }
+       do_linevec (mf->wl, wiki);
+    }
+}
+
 void  wc_call_defun (WikiLine* wl, WikiFormat* wiki) {
     WikiMotor  motor (wl->begin + 1, wl->end, wiki);
     WikiMotorObjVec  objv;
@@ -502,6 +659,7 @@ void  wc_call_defun (WikiLine* wl, WikiFormat* wiki) {
     ustring  name;
     MNode*  wf;
     bool  fx = true;
+    WikiMacro*  mf;
 
 #ifdef DEBUG
     std::cerr << "(wiki):" << ustring (wl->begin0, wl->end) << "\n";
@@ -511,50 +669,12 @@ void  wc_call_defun (WikiLine* wl, WikiFormat* wiki) {
     if (wiki->protectMode && ! wl->fsuper && ! wiki->env->wikienv->wikiGuestFunc.get (name))
        fx = false;
 
-    if (fx && (wf = wiki->env->wikienv->wikiCmd.getVar (name))) {
-       WikiMotorObjVecVec  argsv;
-       MNodePtr  vargs;
-
-       objv2.splitCharA (':', argsv);
-       vargs = wiki->buildArgs (argsv.begin (), argsv.end ());
-       {
-#ifdef WIKICOMPAT
-           MotorOutputString  out;
-           MotorOutput*  back = wiki->env->output;
-#endif
-           WikiMotorOutputString*  wikiback = wiki->env->wikioutput;
-           WikiMotorOutputString  wikiout (wiki);
-           MNodePtr  node;
-           MNodePtr  bcell;
-
-           wiki->env->wikioutput = &wikiout;
-#ifdef WIKICOMPAT
-           wiki->env->output = &out;
-#endif
-           bcell = wiki->env->mlenv->currentCell;
-           wiki->env->mlenv->currentCell = NULL;
-           try {
-               node = execDefun (wiki->env->mlenv, wf, vargs (), name);
-           } catch (ustring& msg) {
-               wiki->logLispFunctionError (msg, ustring (wl->begin, wl->end));
-           }
-           wiki->env->mlenv->currentCell = bcell;
-           if (wikiout.ans.length () > 0) {
-               WikiLine::linevec  bl;
-               wiki->pass1 (wikiout.ans, &bl, wl->fsuper);
-               do_linevec (&bl, wiki);
-           }
-           wiki->env->wikioutput = wikiback;
-#ifdef WIKICOMPAT
-           if (out.ans.length () > 0) {
-               WikiLine::linevec  bl;
-               wiki->pass1 (out.ans, &bl, wl->fsuper);
-               do_linevec (&bl, wiki);
-           }
-           wiki->env->output = back;
-#endif
-       }
-    } else {
+    if (fx && (wf = wiki->env->wikienv->wikiCmd.getVar (name))) { // Wiki Command
+       call_defun_wikicmd (name, wf, objv2, wl, wiki);
+    } else if (mf = wiki->env->wikienv->wikiMacro.getVar (name)) { // Wiki Macro. macroは誰でも実行できる。
+//     std::cerr << "macro:" << name << "\n";
+       call_defun_macro (name, mf, objv2, wl, wiki);
+    } else {                   // 処理なし
        WikiLine::linevec  bl;
        WikiLine*  wl2;
        ustring  u (CharConst ("^"));
index ddeae60..c5c3648 100644 (file)
@@ -15,6 +15,7 @@ void  wc_eval (WikiLine* wl, WikiFormat* wiki);
 void  wc_insert (WikiLine* wl, WikiFormat* wiki);
 void  wc_data (WikiLine* wl, WikiFormat* wiki);
 void  wc_local (WikiLine* wl, WikiFormat* wiki);
+void  wc_macro (WikiLine* wl, WikiFormat* wiki);
 void  wc_call_defun (WikiLine* wl, WikiFormat* wiki);
 void  wikiOutput (const ustring& text, bool fsuper, WikiFormat* wiki);
 
index b6c72cc..74756db 100644 (file)
@@ -4,3 +4,26 @@
 #include "ustring.h"
 
 uregex  re_wikicmdsep ("(:)|([ \t]+$)");
+
+void  MacroVar::setVar (const ustring& name, MNode* var, WikiLine::linevec* wl) {
+    std::pair<MacroVar::iterator, bool>  x;
+    erase (name);
+    x = insert (value_type (name, WikiMacro ()));
+    x.first->second.vars = var;
+    x.first->second.wl = wl;
+}
+
+WikiMacro*  MacroVar::getVar (const ustring& name) {
+    iterator  it = find (name);
+    if (it == end ()) {
+       return NULL;
+    } else {
+       return &it->second;
+    }
+}
+
+bool  MacroVar::defined (const ustring& name) {
+    iterator  it = find (name);
+    return (it != end ());
+}
+
index be2e60c..0dbbbac 100644 (file)
@@ -2,14 +2,25 @@
 #define WIKIENV_H
 
 #include "motorvar.h"
+#include "wikiformat.h"
 #include "ustring.h"
 
+class  MacroVar: public boost::unordered_map<ustring, WikiMacro> {
+ public:
+    MacroVar () {};
+    virtual  ~MacroVar () {};
+    virtual void  setVar (const ustring& name, MNode* var, WikiLine::linevec* wl);
+    virtual WikiMacro*  getVar (const ustring& name);
+    virtual bool  defined (const ustring& name);
+};
+
 class  WikiEnv {
  public:
     MotorVar  wikiFunc2;
     MotorVar  wikiFunc;
     MotorVar  wikiLink;
     MotorVar  wikiCmd;
+    MacroVar  wikiMacro;
     MotorSet  wikiGuestFunc;
 
     WikiEnv () {};
index 29357b4..6628c01 100644 (file)
@@ -1846,6 +1846,19 @@ void  WikiBlockHR::output (MotorOutput* out) {
 }
 
 /* ============================================================ */
+bool  WikiBlockRaw::nextLine (uiterator b, uiterator e) {
+    return false;
+}
+
+void  WikiBlockRaw::addLine (uiterator b, uiterator e) {
+    text.assign (b, e);
+}
+
+void  WikiBlockRaw::output (MotorOutput* out) {
+    out->out_toText (text);
+}
+
+/* ============================================================ */
 void  WikiFormat::pass1 (const ustring& text, WikiLine::linevec* block, bool fsuper) {
     Splitter  sp (text, re_nl);
 
@@ -2208,6 +2221,14 @@ void  WikiFormat::compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& s
     }
 }
 
+void  WikiFormat::pushBlockRaw (uiterator b, uiterator e) {
+    WikiBlockRaw*  obj;
+
+    obj = new WikiBlockRaw (this);
+    blockp->push_back (obj);
+    obj->addLine (b, e);
+}
+
 int  WikiFormat::countWikiH (uiterator& b, uiterator e) {
     int  ans = 0;
 
index 4b909c5..e48405d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef WIKIFORMAT_H
 #define WIKIFORMAT_H
 
-#include "wikienv.h"
+//#include "wikienv.h"
 #include "wikimotor.h"
 #include "wikitable.h"
 #include "motoroutput.h"
@@ -81,6 +81,28 @@ class  WikiLine {
     
 };
 
+class  WikiMacro {
+ public:
+    MNodePtr  vars;
+    WikiLine::linevec*  wl;
+
+#if 0
+    WikiMacro (MNode* _vars, WikiLine::linevec* _wl) {
+       vars = _vars;
+       wl = _wl;
+    };
+#endif
+    WikiMacro () {
+       wl = NULL;
+    };
+    virtual  ~WikiMacro () {
+//     delete vars;
+//     vars = NULL;
+       delete wl;
+       wl = NULL;
+    };
+};
+
 class  WikiLineScanner {
  public:
     WikiLine::linevec*  wlv;
@@ -292,6 +314,7 @@ class  WikiBlock {
        BlockDiv,
        BlockForm,
        BlockHR,
+       BlockRaw,
     }  blockType;
     typedef enum {
        CloseNA,
@@ -586,6 +609,18 @@ class  WikiBlockHR: public WikiBlock {
     virtual void  output (MotorOutput* out);
 };
 
+class  WikiBlockRaw: public WikiBlock {
+ public:
+    ustring  text;
+
+    WikiBlockRaw(WikiFormat* w): WikiBlock (BlockRaw, w) {};
+    virtual  ~WikiBlockRaw () {};
+
+    virtual bool  nextLine (uiterator b, uiterator e);
+    virtual void  addLine (uiterator b, uiterator e);
+    virtual void  output (MotorOutput* out);
+};
+
 class  WikiFormat {
  public:
     typedef  enum {
@@ -644,6 +679,7 @@ class  WikiFormat {
     virtual bool  checkClose (uiterator b, uiterator e);
     virtual void  compileLine (WikiLineScanner& scanner);
     virtual void  compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& spp, WikiLineScanner& scanner, WikiFormat* wiki, void* par) = false, void* par = false);
+    virtual void  pushBlockRaw (uiterator b, uiterator e);
     virtual void  push_block (boost::ptr_vector<WikiBlock>* b) {
        bstack.push_back (cur);
        cur = NULL;
index a4ec4a4..7f7d46f 100644 (file)
@@ -2,7 +2,7 @@
 #define WIKIMOTOR_H
 
 #include "wikitable.h"
-#include "wikienv.h"
+//#include "wikienv.h"
 #include "motor.h"
 #include "ml.h"
 #include "util_splitter.h"