OSDN Git Service

define-wiki-command2, wiki-eval function.
authorvisor <visor@users.sourceforge.jp>
Tue, 16 Feb 2016 12:17:26 +0000 (21:17 +0900)
committervisor <visor@users.sourceforge.jp>
Tue, 16 Feb 2016 12:17:26 +0000 (21:17 +0900)
modules/ml-wiki.cc
modules/ml-wiki.h
wiki/wikicmd.cc
wiki/wikienv.h
wiki/wikiformat.cc

index 4c7c35c..ee5478d 100644 (file)
@@ -101,6 +101,26 @@ MNode*  ml_wiki_string (MNode* cell, MlEnv* mlenv) {
     return newMNode_str (new ustring (out.ans));
 }
 
+/*DOC:
+===wiki-eval===
+ (wiki-eval ANY) -> ANY
+
+*/
+//#AFUNC       wiki-eval       ml_wiki_eval
+MNode*  ml_wiki_eval (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    MNodePtr  h;
+    std::vector<MNode*>  params;
+
+    setParams (arg, 1, &params, NULL, NULL, NULL);
+    h = eval (params[0], mlenv);
+    {
+       WikiFormat  w (mlenv->env, false);
+       h = eval (h (), w.mlenv);
+    }
+    return mlenv->retval = h ();
+}
+
 static ustring*  wikivar (const ustring& name) {
     ustring*  ans = new ustring;
 
@@ -279,8 +299,13 @@ MNode*  ml_defun_wiki_link (MNode* cell, MlEnv* mlenv) {
  (defun-wiki-command FNAME (ARGS...) BLOCK...) -> NIL
  $FNAME:ARGS:...
 
+===defun-wiki-command2===
+ (defun-wiki-command FNAME (ARGS...) BLOCK...) -> NIL
+ $FNAME:ARGS:...
+
 */
 //#AFUNC       defun-wiki-command      ml_defun_wiki_command
+//#AFUNC       defun-wiki-command2     ml_defun_wiki_command2
 MNode*  ml_defun_wiki_command (MNode* cell, MlEnv* mlenv) {
     ustring  name;
     MNode*  sexp = NULL;
@@ -291,6 +316,16 @@ MNode*  ml_defun_wiki_command (MNode* cell, MlEnv* mlenv) {
     return NULL;
 }
 
+MNode*  ml_defun_wiki_command2 (MNode* cell, MlEnv* mlenv) {
+    ustring  name;
+    MNode*  sexp = NULL;
+
+    checkDefun (cell->cdr (), name, sexp);
+    mlenv->env->wikienv->wikiCmd2.setVar (name, newLambda (sexp));
+
+    return NULL;
+}
+
 /*DOC:
 ===get-wiki-command===
  (get-wiki-command NAME) -> LAMBDA
index 1719eb8..f1047cd 100644 (file)
@@ -6,6 +6,7 @@ class  MlEnv;
 
 MNode*  ml_wiki (MNode* cell, MlEnv* mlenv);
 MNode*  ml_wiki_string (MNode* cell, MlEnv* mlenv);
+MNode*  ml_wiki_eval (MNode* cell, MlEnv* mlenv);
 MNode*  ml_wikivar (MNode* cell, MlEnv* mlenv);
 MNode*  ml_wikivar_ary (MNode* cell, MlEnv* mlenv);
 MNode*  ml_set_wikivar (MNode* cell, MlEnv* mlenv);
@@ -13,6 +14,7 @@ MNode*  ml_defun_wiki_inline (MNode* cell, MlEnv* mlenv);
 MNode*  ml_defun_wiki_inline2 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_defun_wiki_link (MNode* cell, MlEnv* mlenv);
 MNode*  ml_defun_wiki_command (MNode* cell, MlEnv* mlenv);
+MNode*  ml_defun_wiki_command2 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_get_wiki_command (MNode* cell, MlEnv* mlenv);
 MNode*  ml_wiki_guestuser_function (MNode* cell, MlEnv* mlenv);
 MNode*  ml_guestuser_function (MNode* cell, MlEnv* mlenv);
index 5c930b1..8c656fb 100644 (file)
@@ -930,7 +930,7 @@ void  wc_premode (WikiLine* wl, WikiFormat* wiki) {
 }
 
 /* ============================================================ */
-static void  call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
+static void  op_call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki, int version) {
     WikiMotorObjVecVec  argsv;
     MNodePtr  vargs;
 
@@ -948,6 +948,12 @@ static void  call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv
        wiki->env->output = &out;
        bcell = wiki->env->mlenv->currentCell;
        wiki->env->mlenv->currentCell = NULL;
+       if (version == 2) {
+           ustring  data;
+           if (wl->block)
+               wldump (data, wl->block);
+           vargs = newMNode_cons (newMNode_str (new ustring (data)), vargs ());
+       }
        try {
            node = execDefun (wiki->env->mlenv, wf, vargs (), name);
        } catch (ustring& msg) {
@@ -973,6 +979,14 @@ static void  call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv
     }
 }
 
+static void  call_defun_wikicmd (ustring& name, MNode* wf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
+    op_call_defun_wikicmd (name, wf, objv2, wl, wiki, 1);
+}
+
+static void  call_defun_wikicmd2 (ustring& name, MNode* wf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
+    op_call_defun_wikicmd (name, wf, objv2, wl, wiki, 2);
+}
+
 static void  call_defun_macro (ustring& name, WikiMacro* mf, WikiMotorObjVec& objv2, WikiLine* wl, WikiFormat* wiki) {
     WikiMotorObjVecVec  argsv;
 
@@ -1015,9 +1029,10 @@ void  wc_call_defun (WikiLine* wl, WikiFormat* wiki) {
     objv.splitChar_keyword (':', name, objv2);
     if (wiki->protectMode && ! wl->fsuper && ! wiki->env->wikienv->wikiGuestFunc.get (name))
        fx = false;
-
     if (fx && (wf = wiki->env->wikienv->wikiCmd.getVar (name))) { // Wiki Command
        call_defun_wikicmd (name, wf, objv2, wl, wiki);
+    } else if (fx && (wf = wiki->env->wikienv->wikiCmd2.getVar (name))) { // Wiki Command2
+       call_defun_wikicmd2 (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);
index cf95822..e931cc2 100644 (file)
@@ -16,10 +16,11 @@ class  MacroVar: public boost::unordered_map<ustring, WikiMacro> {
 
 class  WikiEnv {
  public:
-    MotorVar  wikiFunc2;
-    MotorVar  wikiFunc;
-    MotorVar  wikiLink;
-    MotorVar  wikiCmd;
+    MotorVar  wikiFunc2;       // inline2 function
+    MotorVar  wikiFunc;                // inline function
+    MotorVar  wikiLink;                // link command
+    MotorVar  wikiCmd;         // wiki command
+    MotorVar  wikiCmd2;                // wiki command2
     MacroVar  wikiMacro;
     MotorSet  wikiGuestFunc;
 
index 0b0a2e4..fd3ec90 100644 (file)
@@ -42,6 +42,7 @@
 #define  kWikiDIV_e    '}'
 #define  kWikiHR       '-'
 #define  kWikiCmd      '$'
+#define  uWikiCmd      "$"
 
 #define  uP    "<p>"
 #define  uPe   "</p>\n"
@@ -1671,6 +1672,30 @@ bool  WikiFormat::pass1_2 (Splitter& sp, uiterator& b, uiterator& e, uiterator&
            // nonblock
        }
        return true;
+    } else if (t < u && *t == kWikiCmd) {
+       bool  fx = true;
+       MNode*  wf;
+       ustring  name (t + 1, u);                       // '$'を取り除く
+       if (protectMode && ! fsuper && ! env->wikienv->wikiGuestFunc.get (name))
+           fx = false;
+       if (fx && (wf = env->wikienv->wikiCmd2.getVar (name))) { // Wiki Command
+           ustring  endword;
+           endword.assign (CharConst (uWikiCmd "end")).append (name);  // $end...
+           block->push_back (wl = new WikiLine (b, e, fsuper));
+           wl->fn = wc_call_defun;
+           wl->block = new WikiLine::linevec;
+           rc = pass1_1 (sp, NULL, &endword, wl->block, NULL, NULL, NULL, fsuper);
+           if (rc == 0) {
+               // no end line error
+               if (endword.length () > 0) {
+                   errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
+               }
+           } else if (rc == 2) {
+               assert (wl->block2 == NULL);
+               wl->block2 = new WikiLine (sp.begin (), sp.end (), false);
+           }
+           return true;
+       }
     }
 
     return false;