#include <assert.h>
#include <stdlib.h>
+/*
+WIKICOMPAT: 1をセットすると,defun-wiki-commandで定義した関数の中で,motor-output, motor-output-rawで出力したテキストをWikiテキストとして解釈する。
+*/
/*DOC:
==行コマンド==
+...
+$endrepeat
}
+変数''VAR''に,数値''FROM''から''TO''までの値を1づつ加算しながら代入し,$endrepeatまでの間のブロックを繰り返し実行する。
*/
//#WIKICMD $repeat $endrepeat wc_repeat
/*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) {
+$endblock
}
+LISPセル''EXPR''が真のとき,$elseblockまたは$endblockまでのブロックを実行する。
+$elseblockに条件を書かないとき,それ以前のすべての条件が真でないときに次のブロックを実行する。
+
*/
//#WIKICMD $block $elseblock $endblock wc_block
void wc_block (WikiLine* wl, WikiFormat* wiki) {
+$eval:''EXPR''
}
+LISPセル''EXPR''を実行する。
+
*/
//#WIKICMD $eval wc_eval
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) {
}
}
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;
}
}
/* ============================================================ */
+/*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;
ustring name;
MNode* wf;
bool fx = true;
+ WikiMacro* mf;
#ifdef DEBUG
std::cerr << "(wiki):" << ustring (wl->begin0, wl->end) << "\n";
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 ("^"));