1 #include "wikiformat.h"
9 #include "motorconst.h"
11 #include "motoroutput.h"
12 #include "util_const.h"
13 #include "util_check.h"
14 #include "util_string.h"
17 #include <boost/ptr_container/ptr_vector.hpp>
20 WIKIMOTORPRE: セットすると,フォーマット済みテキストブロックの中でインライン要素の解釈を行う。
21 UTF8JP: セットすると,条件によりパラグラフ内の改行を空白に置き換えない。
22 WIKITABLECOMPATFLAG: セットすると,旧形式の表の継続記号もゆるす。
29 #define kWikiPRE2 '\t'
35 #define kWikiTABLE '|'
36 #define kWikiQUOTE '>'
37 #define kWikiQUOTE_e '<'
39 #define kWikiDIV_e '}'
51 #define uH1e "</h1>\n"
52 #define uH2e "</h2>\n"
53 #define uH3e "</h3>\n"
54 #define uH4e "</h4>\n"
55 #define uH5e "</h5>\n"
56 #define uH6e "</h6>\n"
57 #define uHR "<hr />\n"
58 //#define unbsp " "
60 ustring uWiki (CharConst ("wiki_"));
61 ustring uAWiki (CharConst ("@wiki_"));
68 /* ============================================================ */
69 void WikiMlEnv::setVar (const ustring& name, MNode* val) {
70 MlEnv::setVar (wikiVarName (name), val);
73 void WikiMlEnv::setAry (const ustring& name, size_t i, MNode* val) {
74 MlEnv::setAry (wikiVarName (name), i, val);
77 void WikiMlEnv::setArySize (const ustring& name, size_t n) {
78 MlEnv::setArySize (wikiVarName (name), n);
81 void WikiMlEnv::setAry (const ustring& name, MNode* list) {
82 MlEnv::setAry (wikiVarName (name), list);
85 MNode* WikiMlEnv::getVar (const ustring& name) {
86 return MlEnv::getVar (wikiVarName (name));
89 MNode* WikiMlEnv::getAry (const ustring& name, size_t i) {
90 return MlEnv::getAry (wikiVarName (name), i);
93 size_t WikiMlEnv::getArySize (const ustring& name) {
94 return MlEnv::getArySize (wikiVarName (name));
97 void WikiMlEnv::setLocalVar (const ustring& name, MNode* val) {
98 MlEnv::setLocalVar (wikiVarName (name), val);
101 void WikiMlEnv::defineLocalVar (const ustring& name) {
102 MlEnv::defineLocalVar (wikiVarName (name));
105 ustring WikiMlEnv::wikiVarName (const ustring& name) {
111 /* ============================================================ */
112 void WikiMotorOutputString::flush (bool fsuper) {
113 wikiOutput (ans, fsuper, wiki);
117 /* ============================================================ */
118 void WikiBlockComplex::outputBlock (MotorOutput* out) {
119 for (int i = 0; i < block.size (); i ++) {
120 block[i].output (out);
124 /* ============================================================ */
127 マークアップ文字以外の文字で書き出すと,段落になる。
128 ^行頭が他のマークアップ文字になるときは,行頭に^を書く。
133 bool WikiBlockParagraph::nextLine (uiterator b, uiterator e) {
142 void WikiBlockParagraph::addLine (uiterator b, uiterator e) {
143 if (b[0] == kWikiP) {
151 WikiMotorObjVec::iterator ob;
152 WikiMotorObjVec::iterator oe;
153 wiki->wikiMotorInline (b, e, o);
154 if (objv.size () > 0 && o.size () > 0) {
157 WikiMotorObjText* t1;
158 WikiMotorObjText* t2;
162 if (v->type == WikiMotorObj::wiki_text) {
163 t1 = WikiMotorObjText_type (v);
165 if (v->type == WikiMotorObj::wiki_text) {
166 t2 = WikiMotorObjText_type (v);
167 if (t1->text.length () > 0 && t2->text.length () > 0) {
168 lastChar (t1->text, i1);
169 n = t1->text.end () - i1;
170 i2 = t2->text.begin ();
171 nextChar (i2, t2->text.end ());
172 if (n == 3 && i2 - t2->text.begin () == 3) {
174 objv.push_back (WikiMotorObjPtr (new WikiMotorObjText (uSPC)));
177 objv.push_back (WikiMotorObjPtr (new WikiMotorObjText (uSPC)));
180 objv.push_back (WikiMotorObjPtr (new WikiMotorObjText (uSPC)));
183 objv.push_back (WikiMotorObjPtr (new WikiMotorObjText (uSPC)));
186 objv.push_back (WikiMotorObjPtr (new WikiMotorObjText (uSPC)));
191 for (; ob < oe; ob ++) {
192 objv.push_back (*ob);
197 void WikiBlockParagraph::addHtml (const ustring& ht) {
198 objv.push_back (WikiMotorObjPtr (new WikiMotorObjHtml (ht)));
201 void WikiBlockParagraph::output (MotorOutput* out) {
203 out->out_toText (objv.htmlOut (wiki));
205 out->out_raw (CharConst (uP));
206 out->out_toText (objv.htmlOut (wiki));
207 out->out_raw (CharConst (uPe));
211 /* ============================================================ */
218 行頭に=を書くと,タイトルになる。行末の=は,省略可。
222 bool WikiBlockH::nextLine (uiterator b, uiterator e) {
226 void WikiBlockH::addLine (uiterator b, uiterator e) {
230 static uregex re ("(=+)#([a-zA-Z0-9_-]+)$");
232 cn = wiki->countWikiH (b, e);
233 level = cn + wiki->headbase;
236 level0 = wiki->hlevel;
238 for (; b < e && *b == ' '; b ++) {}
239 if (usearch (b, e, m, re)) {
241 n = m[1].second - m[1].first - cn;
245 for (; b < u && u[-1] == ' '; u --) {}
246 title = wiki->wikiMotor (b, u);
247 anchor = ustring (m[2].first, m[2].second);
250 for (n = cn; n > 0 && b < u && u[-1] == '='; u --, n --) {}
251 for (; b < u && u[-1] == ' '; u --) {}
252 title = wiki->wikiMotor (b, u);
254 wiki->hlevel = level;
257 WikiBlock::closeType WikiBlockH::closeLine (uiterator b, uiterator e) {
258 if (e - b == 1 && *b == kWikiDIV_e) {
259 // closing point of the div
261 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
262 switch (wiki->bstack[i]->type) {
266 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
268 switch (wiki->bstack[i]->type) {
281 } else if (b != e && *b == kWikiH) {
282 int l = wiki->countWikiH (b, e) + wiki->headbase;
287 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
288 if (wiki->bstack[i]->type == BlockH) {
289 obj = (WikiBlockH*)wiki->bstack[i];
290 if (obj->level >= l) {
308 void WikiBlockH::close () {
309 wiki->hlevel = level0;
312 void WikiBlockH::output (MotorOutput* out) {
315 assert (0 < level && level <= 6);
319 outputBeginDiv (level, out);
321 case 1: out->out_raw (CharConst (uH1)); break;
322 case 2: out->out_raw (CharConst (uH2)); break;
323 case 3: out->out_raw (CharConst (uH3)); break;
324 case 4: out->out_raw (CharConst (uH4)); break;
325 case 5: out->out_raw (CharConst (uH5)); break;
326 case 6: out->out_raw (CharConst (uH6)); break;
328 if (anchor.size () > 0) {
329 out->out_raw (CharConst ("<a name=\""))->out_toHTML_noCtrl (anchor)->out_raw (CharConst ("\">"))->out_toText (title)->out_raw (CharConst ("</a>"));
331 out->out_noCtrl (title);
334 case 1: out->out_raw (CharConst (uH1e)); break;
335 case 2: out->out_raw (CharConst (uH2e)); break;
336 case 3: out->out_raw (CharConst (uH3e)); break;
337 case 4: out->out_raw (CharConst (uH4e)); break;
338 case 5: out->out_raw (CharConst (uH5e)); break;
339 case 6: out->out_raw (CharConst (uH6e)); break;
342 outputEndDiv (level, out);
345 void WikiBlockH::outputBeginDiv (int lv, MotorOutput* out) {
347 case 1: out->out_raw (CharConst ("<div class=\"hh1\">\n")); break;
348 case 2: out->out_raw (CharConst ("<div class=\"hh2\">\n")); break;
349 case 3: out->out_raw (CharConst ("<div class=\"hh3\">\n")); break;
350 case 4: out->out_raw (CharConst ("<div class=\"hh4\">\n")); break;
351 case 5: out->out_raw (CharConst ("<div class=\"hh5\">\n")); break;
352 case 6: out->out_raw (CharConst ("<div class=\"hh6\">\n")); break;
356 void WikiBlockH::outputEndDiv (int lv, MotorOutput* out) {
358 out->out_raw (CharConst ("</div><!-- hh"))->out_raw (to_ustring (lv))->out_raw (CharConst (" -->\n"));
360 out->out_raw (CharConst ("</div>\n"));
364 bool WikiBlockH::checkEmpty () {
365 return title.empty ();
368 /* ============================================================ */
370 ===フォーマット済みテキストブロック===
371 行頭に空白文字を書くと,<pre>〜</pre>タグで囲まれます。
375 bool WikiBlockPreformatRaw::nextLine (uiterator b, uiterator e) {
384 void WikiBlockPreformatRaw::addLine (uiterator b, uiterator e) {
389 if (wiki->motorPre) {
390 text.append (wiki->wikiMotor (b, e));
393 o.out_toHTML (ustring (b, e));
399 void WikiBlockPreformatRaw::output (MotorOutput* out) {
400 out->out_raw (CharConst ("<pre>"))->out_toText (text)->out_raw (CharConst ("</pre>\n"));
403 /* ============================================================ */
404 bool WikiBlockItemText::nextLine (uiterator b, uiterator e) {
408 void WikiBlockItemText::addLine (uiterator b, uiterator e) {
409 WikiMotor motor (b, e, wiki);
410 WikiMotorObjVecPtr v1 (new WikiMotorObjVec);
413 if (! attrib.shiftAttrib (v1))
415 html.append (v1->htmlOut (wiki));
418 bool WikiBlockItemText::checkAddLine (uiterator b, uiterator e) {
426 if (block.size () > 0) {
427 obj = &block.back ();
432 wbi = (WikiBlockItem*)obj;
445 void WikiBlockItemText::output (MotorOutput* out) {
449 out->out_raw (CharConst ("<li"));
451 out->out_raw (CharConst (">"));
452 out->out_toText (html);
454 out->out_raw (CharConst ("</li>\n"));
458 /* ============================================================ */
467 *''[OPTION1:OPTION2:...:]''TEXT
468 行頭に「*」を書くと,<UL>タグによるリスト,「#」を書くと<NL>タグによる番号付きリスト,「+」を書くとnobullクラス指定の<UL>タグによるリスト。
471 |table:w=100%|t:w=20%|c:w=10%|t:|
473 |'''id='''''ID''||id属性。|
474 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
475 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
476 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
477 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
478 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
479 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
480 |'''start='''''Number''||start属性。OLのみ。|
483 bool WikiBlockItem::nextLine (uiterator b, uiterator e) {
492 void WikiBlockItem::setChar (char c) {
497 void WikiBlockItem::addLine (uiterator b, uiterator e) {
500 WikiBlockItemText* wbt;
505 assert (b != e && b[0] == ch);
508 wbt = new WikiBlockItemText (wiki, this);
509 block.push_back (wbt);
513 if (block.size () > 0 && block.back ().checkAddLine (b, e)) {
517 wbi = new WikiBlockItem (WikiBlock::BlockItemUL, wiki);
520 wbi = new WikiBlockItem (WikiBlock::BlockItemOL, wiki);
523 wbi = new WikiBlockItem (WikiBlock::BlockItemNL, wiki);
529 if (block.size () > 0) {
530 wbt = &block.back ();
532 wbt->block.push_back (wbi);
534 wbt = new WikiBlockItemText (wiki, this);
535 block.push_back (wbt);
537 wbt->block.push_back (wbi);
538 wbt->indentHack = true;
541 wbt = new WikiBlockItemText (wiki, this);
542 block.push_back (wbt);
549 void WikiBlockItem::output (MotorOutput* out) {
554 out->out_raw (CharConst ("<ul"));
556 out->out_raw (CharConst (">\n"));
558 out->out_raw (CharConst ("</ul>\n"));
561 out->out_raw (CharConst ("<ol"));
563 out->out_raw (CharConst (">\n"));
565 out->out_raw (CharConst ("</ol>\n"));
568 out->out_raw (CharConst ("<ul"));
569 attrib.classlist.push_back (ustring (CharConst ("nobull")));
571 attrib.classlist.pop_back ();
572 out->out_raw (CharConst (">\n"));
574 out->out_raw (CharConst ("</ul>\n"));
577 std::cerr << "type:" << type << uLF;
582 void WikiBlockItem::outputBlock (MotorOutput* out) {
583 for (int i = 0; i < block.size (); i ++) {
584 block[i].output (out);
588 /* ============================================================ */
594 bool WikiBlockItemDL::nextLine (uiterator b, uiterator e) {
603 void WikiBlockItemDL::addLine (uiterator b, uiterator e) {
604 WikiMotorObjVec objs;
605 WikiMotorObjVec* def;
606 WikiMotorObjVec* desc;
608 wiki->wikiMotorInline (b + 1, e, objs);
609 def = new WikiMotorObjVec;
610 desc = new WikiMotorObjVec;
611 objv1.push_back (def);
612 objv2.push_back (desc);
613 objs.splitChar (':', *def, *desc);
616 void WikiBlockItemDL::output (MotorOutput* out) {
619 out->out_raw (CharConst ("<dl>\n"));
620 for (i = 0; i < objv1.size (); i ++) {
621 out->out_raw (CharConst ("<dt>"))->out_toText (objv1[i].htmlOut (wiki))->out_raw (CharConst ("</dt>\n"));
622 out->out_raw (CharConst ("<dd>"))->out_toText (objv2[i].htmlOut (wiki))->out_raw (CharConst ("</dd>\n"));
624 out->out_raw (CharConst ("</dl>\n"));
627 /* ============================================================ */
630 |table:w=100%:数量リスト|head:right:||right:|
636 表定義の最初の行の最初のカラムに「table:」を書くと,この行はテーブルオプション指定行になる。属性指定の後にテキストを書くと,表のキャプションになる。
637 2番目以降のカラムは,デフォルトのカラムオプション指定になる。
639 |table:w=100%:テーブルオプション|t:w=20%|c:w=10%|t:|
641 |'''id='''''ID''||id属性。|
642 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
643 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
644 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
645 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
646 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
647 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
648 |'''width='''''Size''|'''w='''|width属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
649 //|'''height='''''Size''|'''h='''|height属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
650 |'''bgcolor='''''Color''|'''bg='''|bgcolor属性。|
651 |'''cellspacing='''''Integer''|'''spc='''|cellspacing属性。*コンパイル時設定による。|
652 |'''cellpadding='''''Integer''||cellpadding属性。*コンパイル時設定による。|
653 |'''left'''|'''l'''|align="left"属性。|
654 |'''right'''|'''r'''|align="right"属性。|
655 |'''center'''|'''c'''|align="center"属性。|
656 |'''noborder'''|''nb''|border="0"属性。|
657 |'''padding'''|'''pad'''|行のカラム定義が最大カラム数に満たない時,空のカラムを追加する。|
658 |'''expanding'''|'''expand'''|行のカラム定義が最大カラム数に満たない時,最終カラムを伸ばす。|
659 |'''nowhite'''|'''nw'''|空セルにnbspを出力する。|
660 |'''turn'''||表の行と列を入れ替える。|
663 |row:bgcolor=#ff0|&[;&[;Name]]|&[;&[;Value]]|
664 表の行の最初のカラムに「row:」を書くと,このカラムは行オプション指定になる。行オプション指定のカラムは,表には出力されず,この後のカラムが表のカラムとなる。
665 行オプションで指定できる属性はセルオプションと同じものである。
668 |header:名前|class=big:東武|
671 |table:w=100%:行オプション,セルオプション|t:w=20%|c:w=10%|t:|
673 |'''id='''''ID''||id属性。|
674 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
675 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
676 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
677 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
678 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
679 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
680 |'''width='''''Size''|'''w='''|width属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
681 |'''height='''''Size''|'''h='''|height属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
682 |'''bgcolor='''''Color''|'''bg='''|bgcolor属性。|
683 |'''header'''|'''h'''|thタグを出力する。|
684 |'''left'''|'''l'''|align="left"属性。|
685 |'''right'''|'''r'''|align="right"属性。|
686 |'''center'''|'''c'''|align="center"属性。|
687 |'''top'''|'''t'''|valign="top"属性。|
688 |'''middle'''|'''m'''|valign="middle"属性。|
689 |'''bottom'''|'''b'''|valign="bottom"属性。|
690 |'''nowrap'''|'''nw'''|nowrap属性。|
691 |'''*'''||オプションのクリア。|
695 |&<;''text''|左のセルと内容が一致するとき,結合する。|
696 |&<;^''text''|左のセルと内容が一致し,左のセルが上のセルと結合しているとき,結合する。|
698 |&^;''text''|上のセルと内容が一致するとき,結合する。|
699 |&^;<''text''|上のセルと内容が一致し,上のセルが左のセルと結合しているとき,結合する。|
702 行末に「&」を指定すると,次のテーブル記述を1行として継続する。数値指定を付加し「!''NUM''&」と指定するとカラム数が''NUM''に達したところで継続をやめる。
705 void WikiBlockTable::TableCell::cellBody (WikiMotorObjVec* vtext, WikiBlockTable* table, int idx) {
709 if (vtext->size () > 0 && (*vtext)[0].get ()->type == WikiMotorObj::wiki_text) {
710 WikiMotorObjText* w = WikiMotorObjText_type ((*vtext)[0].get ());
711 uiterator b = w->text.begin ();
712 uiterator e = w->text.end ();
714 if (b < e && *b == '<') {
717 if (b < e && *b == '^') {
721 } else if (b < e && *b == '^') {
724 if (b < e && *b == '<') {
729 (*vtext)[0].reset (new WikiMotorObjText (b, e));
732 html = vtext->htmlOut (table->wiki);
734 if (! spanmatch || table->ary.size () <= 1 || table->ary[table->ary.size () - 2][idx].colspan == 0) {
735 col = &table->ary.back ();
736 for (i = idx - 1; i >= 0; i --) {
737 if ((*col)[i].colspan > 0) {
738 if (html.length () == 0 || (*col)[i].html == html) {
740 (*col)[i].colspan ++;
748 if (! spanmatch || idx == 0 || table->ary.back ()[idx - 1].rowspan == 0) {
749 for (i = table->ary.size () - 2; i >= 0; i --) {
750 col = &table->ary[i];
751 if (idx < col->size () && (*col)[idx].rowspan > 0) {
752 if (html.length () == 0 || (*col)[idx].html == html) {
754 (*col)[idx].rowspan ++;
763 void WikiBlockTable::TableCell::outputTD (WikiFormat* wiki, MotorOutput* out, bool fturn) {
766 if (cellattrib.fheader)
767 out->out_raw (CharConst ("<th"));
769 out->out_raw (CharConst ("<td"));
770 cellattrib.output (out);
773 wiki->outputName (out, CharConst ("rowspan"), colspan, false);
775 wiki->outputName (out, CharConst ("colspan"), rowspan, false);
778 wiki->outputName (out, CharConst ("colspan"), colspan, false);
780 wiki->outputName (out, CharConst ("rowspan"), rowspan, false);
782 out->out_raw (CharConst (">"));
785 void WikiBlockTable::TableCell::outputTDe (MotorOutput* out) {
786 if (cellattrib.fheader)
787 out->out_raw (CharConst ("</th>\n"));
789 out->out_raw (CharConst ("</td>\n"));
792 /* ============================================================ */
793 bool WikiBlockTable::nextLine (uiterator b, uiterator e) {
794 if (*b == kWikiTABLE) {
802 void WikiBlockTable::addLine (uiterator b, uiterator e) {
803 assert (b[0] == '|');
805 if (n == 0 && matchSkip (b, e, CharConst ("table:"))) {
813 WikiBlock::closeType WikiBlockTable::closeLine (uiterator b, uiterator e) {
814 #ifdef WIKITABLECOMPATFLAG
815 static uregex re ("^\\}\\}(($)|(\\|)|((!([1-9][0-9]*))?(\\\\|&)$))");
817 static uregex re ("^\\}\\}(($)|(\\|)|((!([1-9][0-9]*))?(&)$))");
821 if (usearch (b, e, m, re)) {
822 if (m[2].matched) { // }}
825 } else if (m[3].matched) { // }}|...
827 if (wiki->cur && wiki->cur->type == BlockTable) {
828 WikiBlockTable* obj = (WikiBlockTable*)wiki->cur;
830 addLine_body (m[3].second, e);
835 } else if (m[4].matched) { // }}\ .
837 if (wiki->cur && wiki->cur->type == BlockTable) {
838 WikiBlockTable* obj = (WikiBlockTable*)wiki->cur;
840 addLine_body (m[4].first, e);
850 void WikiBlockTable::output (MotorOutput* out) {
852 outputTableTag (out);
854 out->out_raw (CharConst ("</table>\n"));
857 void WikiBlockTable::addLine_head (uiterator b, uiterator e) {
858 WikiMotor motor (b, e, wiki);
859 WikiMotorObjVec objv;
860 WikiMotorObjVecVec objvv;
864 motor.compile (objv);
865 objv.splitCharA ('|', objvv);
866 if (objvv.size () > 0 && objvv.back ()->size () == 0)
868 if (objvv.size () > 0)
869 attrib.shiftAttrib (objvv[0]);
871 cell = new TableCell (wiki, WikiAttrib1::M_NORMAL);
872 if (objvv.size () > 0)
873 cell->cellBody (objvv[0].get (), this, 0);
874 captionHtml = cell->html;
877 for (i = 1; i < objvv.size (); i ++) {
878 cell = new TableCell (wiki, WikiAttrib1::M_ATTRIB);
879 cell->cellattrib.shiftAttrib (objvv[i]);
880 defaultList.push_back (cell);
884 void WikiBlockTable::addLine_body (uiterator b, uiterator e) {
886 bool fmorecell = false;
888 #ifdef WIKITABLECOMPATFLAG
889 static uregex re ("(!([1-9][0-9]*))?(\\\\|&)$");
891 static uregex re ("(!([1-9][0-9]*))?(&)$");
898 cols = new CellList_t (wiki);
899 ary.push_back (cols);
902 if (usearch (b, e, m, re)) { //
904 if (m[2].matched) { // ...!NUM\ .
905 int v = strtoul (m[2].first);
916 if (b < e && e[-1] == '|') { // ...|\ .
924 WikiMotor motor (b, e, wiki);
925 WikiMotorObjVec objv;
926 WikiMotorObjVecVec objvv;
930 static const ustring brabra (CharConst ("{{"));
932 motor.compile (objv);
933 objv.splitCharA ('|', objvv);
934 if (objvv.size () > 0 && objvv.back ()->size () == 0) {
940 n = objvv.size () - 1;
942 if (i <= n && cols->size () == 0
943 && objvv[i]->matchHead (CharConst ("row:"))) {
944 cols->rowattrib.skipAttrib (objvv[i]);
945 cols->rowattrib.shiftAttrib (objvv[i]);
948 for (; i <= n; i ++) {
950 cell = newCell (cols->rowattrib);
952 cell = newCell (cols->size ());
953 if (! cell->cellattrib.shiftAttrib (objvv[i])) {
957 if (i == n && fop && objvv[i]->match (brabra)) {
958 cols->push_back (cell);
959 wiki->push_block (&cell->block);
962 cell->cellBody (objvv[i].get (), this, cols->size ());
963 cols->push_back (cell);
968 cell = newCell (cols->rowattrib);
970 cell = newCell (cols->size ());
971 cols->push_back (cell);
976 WikiBlockTable::TableCell* WikiBlockTable::newCell (int idx) {
977 TableCell* ans = new TableCell (wiki, WikiAttrib1::M_NORMAL);
979 if (idx < defaultList.size ())
980 ans->cellattrib.copyFrom (defaultList[idx].cellattrib);
984 WikiBlockTable::TableCell* WikiBlockTable::newCell (WikiAttribTable& rowattrib) {
985 TableCell* ans = new TableCell (wiki, WikiAttrib1::M_NORMAL);
987 ans->cellattrib.copyFrom (rowattrib);
991 void WikiBlockTable::normalize () {
997 for (i = 0; i < ary.size (); i ++) {
999 if (col->size () > maxcol)
1000 maxcol = col->size ();
1002 if (attrib.fpadding) {
1003 for (i = 0; i < ary.size (); i ++) {
1005 if (col->size () < maxcol) {
1007 cell = newCell (col->rowattrib);
1009 cell = newCell (col->size ());
1010 cell->colspan = maxcol - col->size ();
1011 col->push_back (cell);
1012 while (col->size () < maxcol) {
1014 cell = newCell (col->rowattrib);
1016 cell = newCell (col->size ());
1018 col->push_back (cell);
1023 for (i = 0; i < ary.size (); i ++) {
1025 for (j = col->size () - 1; j >= 0; j --) {
1027 if (cell->colspan > 0) {
1028 cell->colspan += maxcol - col->size ();
1029 while (col->size () < maxcol) {
1031 cell = newCell (col->rowattrib);
1033 cell = newCell (col->size ());
1035 col->push_back (cell);
1044 void WikiBlockTable::outputTableTag (MotorOutput* out) {
1047 #ifdef WIKITABLEATTRIB
1048 if (attrib.cellspacing < 0)
1049 attrib.cellspacing = 0;
1050 if (attrib.cellpadding < 0)
1051 attrib.cellpadding = 0;
1053 out->out_raw (CharConst ("<table"));
1054 attrib.output (out);
1055 out->out_raw (CharConst (">\n"));
1056 if (captionHtml.length () > 0) {
1057 out->out_raw (CharConst ("<caption>"))->out_toText (captionHtml)->out_raw (CharConst ("</caption>\n"));
1061 void WikiBlockTable::outputTBody (MotorOutput* out) {
1067 if (ary.size () > 0) {
1069 for (j = 0; j < n; j ++) {
1070 out->out_raw (CharConst ("<tr"));
1071 if (defaultList.size () > j) {
1072 defaultList[j].cellattrib.output (out);
1074 out->out_raw (CharConst (">\n"));
1075 for (i = 0; i < ary.size (); i ++) {
1078 outputTBodyCell (wiki, out, cell);
1080 out->out_raw (CharConst ("</tr>\n"));
1084 for (i = 0; i < ary.size (); i ++) {
1086 out->out_raw (CharConst ("<tr"));
1087 col->rowattrib.output (out);
1088 out->out_raw (CharConst (">\n"));
1089 for (j = 0; j < col->size (); j ++) {
1091 outputTBodyCell (wiki, out, cell);
1093 out->out_raw (CharConst ("</tr>\n"));
1098 void WikiBlockTable::outputTBodyCell (WikiFormat* wiki, MotorOutput* out, TableCell* cell) {
1099 if (cell->colspan > 0 && cell->rowspan > 0) {
1100 cell->outputTD (wiki, out, attrib.fturn);
1101 if (cell->block.size () > 0) {
1102 if (cell->block.size () == 1 && cell->block[0].type == BlockParagraph) {
1103 WikiBlockParagraph* b = WikiBlockParagraph_type (&cell->block[0]);
1105 b->singleTag = true;
1108 wiki->output (cell->block);
1110 if (cell->html.size () > 0) {
1111 out->out_toText (cell->html);
1113 if (! attrib.fnowhite)
1114 out->out_raw (uNbsp);
1117 cell->outputTDe (out);
1121 /* ============================================================ */
1124 |select:NAME:function:default:size=NUM:multiple|
1126 |LABEL|VALUE|selected|
1129 |table:w=100%|t:w=20%|c:w=10%|t:|
1130 |h:オプション|h:省略形|h:説明|
1131 |'''id='''''ID''||id属性。|
1132 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
1133 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
1134 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
1135 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
1136 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
1137 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
1138 |'''size='''''Integer''||size属性。|
1139 |'''multiple'''||multiple属性。|
1142 bool WikiBlockSelect::nextLine (uiterator b, uiterator e) {
1143 if (*b == kWikiTABLE) {
1152 void WikiBlockSelect::addLine (uiterator b, uiterator e) {
1153 assert (b[0] == '|');
1155 if (n == 0 && matchSkip (b, e, CharConst ("select:"))) {
1156 addLine_head (b, e);
1158 addLine_body (b, e);
1163 void WikiBlockSelect::addLine_head (uiterator b, uiterator e) {
1164 WikiMotor motor (b, e, wiki);
1165 WikiMotorObjVec objv;
1166 WikiMotorObjVecVec objvv;
1167 WikiMotorObjVec* vcell;
1170 motor.compile (objv);
1171 objv.splitCharA ('|', objvv);
1172 if (objvv.size () > 0 && objvv.back ()->size () == 0)
1174 if (objvv.size () > 0)
1175 attrib.shiftName (objvv[0], name);
1176 if (objvv.size () > 0) {
1177 attrib.shiftAttrib (objvv[0]);
1179 if (attrib.fmultiple && attrib.elsize == 0) {
1184 void WikiBlockSelect::addLine_body (uiterator b, uiterator e) {
1185 WikiMotor motor (b, e, wiki);
1186 WikiMotorObjVec objv;
1187 WikiMotorObjVecVec objvv;
1190 motor.compile (objv);
1191 objv.splitCharA ('|', objvv);
1192 if (objvv.size () > 0 && objvv.back ()->size () == 0)
1194 if (objvv.size () > 0) {
1195 v.label = omitCtrl (objvv[0].get ()->textOut (wiki));
1199 if (objvv.size () > 1) {
1200 v.value = omitCtrl (objvv[1].get ()->textOut (wiki));
1207 if (objvv.size () > 2) {
1208 if (objvv[2].get ()->match (CharConst ("selected"), CharConst ("sel"))) {
1215 void WikiBlockSelect::close () {
1218 assert (wiki->cur->type == BlockParagraph);
1220 MotorOutputString out;
1222 wiki->cur->addHtml (out.ans);
1226 void WikiBlockSelect::output (MotorOutput* out) {
1230 if (attrib.elsize == 1)
1231 attrib.elsize = item.size ();
1232 out->out_raw (CharConst ("<select"));
1233 wiki->outputName (out, CharConst ("name"), name, false);
1234 attrib.output (out);
1235 if (attrib.script.length () > 0)
1236 wiki->outputName (out, CharConst ("onChange"), attrib.script);
1237 out->out_raw (CharConst (">\n"));
1239 if (attrib.fdefault)
1240 u = wiki->getVar (name);
1242 std::cerr << "u:" << u << uLF;
1245 for (i = 0; i < item.size (); i ++) {
1246 SelectItem* v = &item[i];
1247 out->out_raw (CharConst ("<option"));
1249 wiki->outputName (out, CharConst ("value"), v->value, false);
1250 if (v->fselect || (attrib.fdefault && u == v->value))
1251 out->out_raw (CharConst (" selected=\"selected\""));
1253 if (v->fselect || (attrib.fdefault && u == v->label))
1254 out->out_raw (CharConst (" selected=\"selected\""));
1256 out->out_raw (CharConst (">"));
1257 out->out_toHTML (v->label)->out_raw (CharConst ("</option>\n"));
1259 out->out_raw (CharConst ("</select>\n"));
1262 /* ============================================================ */
1270 bool WikiBlockQuote::nextLine (uiterator b, uiterator e) {
1274 WikiBlock::closeType WikiBlockQuote::closeLine (uiterator b, uiterator e) {
1275 if (e - b == 1 && *b == kWikiQUOTE_e) {
1284 void WikiBlockQuote::addLine (uiterator b, uiterator e) {
1288 void WikiBlockQuote::output (MotorOutput* out) {
1289 out->out_raw (CharConst ("<blockquote>\n"));
1291 out->out_raw (CharConst ("</blockquote>\n"));
1294 /* ============================================================ */
1300 {div:id=''ID'':''ClassName'':onclick=''LinkFunction''
1305 |table:w=100%|t:w=20%|c:w=10%|t:|
1306 |h:オプション|h:省略形|h:説明|
1307 |'''id='''''ID''||id属性。|
1308 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
1309 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
1310 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
1311 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
1312 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
1313 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
1314 |'''ClassList'''||class=は省略できる。|
1317 bool WikiBlockDiv::nextLine (uiterator b, uiterator e) {
1321 void WikiBlockDiv::addLine (uiterator b, uiterator e) {
1322 bool rc = matchSkip (b, e, CharConst ("{div:"));
1324 WikiMotor motor (b, e, wiki);
1325 WikiMotorObjVecPtr vec (new WikiMotorObjVec);
1327 motor.compile (*vec);
1328 attrib.shiftAttrib (vec);
1331 WikiBlock::closeType WikiBlockDiv::closeLine (uiterator b, uiterator e) {
1332 if (e - b == 1 && *b == kWikiDIV_e) {
1341 void WikiBlockDiv::output (MotorOutput* out) {
1344 if (block.size () == 1 && block[0].type == BlockParagraph) {
1345 WikiBlockParagraph* b = WikiBlockParagraph_type (&block[0]);
1347 b->singleTag = true;
1351 out->out_raw (CharConst ("<div"));
1352 attrib.output (out);
1354 out->out_raw (CharConst (">"));
1356 out->out_raw (CharConst (">\n"));
1358 out->out_raw (CharConst ("</div>\n"));
1361 /* ============================================================ */
1367 // {form:POST:id=form1:class=formclass:post.hml
1368 // {form:POST:post.hml:id=form1:class=formclass
1369 {form:POST:''URL'':target=''TargetWindow'':id=''ID'':class=''ClassName''
1374 |table:w=100%|t:w=20%|c:w=10%|t:|
1375 |h:オプション|h:省略形|h:説明|
1376 |'''id='''''ID''||id属性。|
1377 |'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
1378 //|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
1379 |'''onclick='''''Link''||onclick属性。Javascriptリンク。|
1380 |'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
1381 |'''onblur='''''Link''||onblur属性。Javascriptリンク。|
1382 |'''onchange='''''Link''||onchange属性。Javascriptリンク。|
1383 |'''target='''''Window''||target属性。|
1386 bool WikiBlockForm::nextLine (uiterator b, uiterator e) {
1390 void WikiBlockForm::addLine (uiterator b, uiterator e) {
1391 bool rc = matchSkip (b, e, CharConst ("{form:"));
1394 WikiMotor motor (b, e, wiki);
1395 WikiMotorObjVecPtr vec (new WikiMotorObjVec);
1397 WikiMotorObjVecPtr v2 (new WikiMotorObjVec);
1399 motor.compile (*vec);
1400 vec->splitChar_keyword (':', key, *v2);
1401 if (match (key, CharConst ("get"), CharConst ("GET"))) {
1404 } else if (match (key, CharConst ("post"), CharConst ("POST"))) {
1408 if (vec->size () > 0) {
1409 attrib.shiftLink (vec, url, fscript);
1411 attrib.shiftAttrib (vec);
1414 WikiBlock::closeType WikiBlockForm::closeLine (uiterator b, uiterator e) {
1415 if (e - b == 1 && *b == kWikiDIV_e) {
1418 wiki->curform = NULL;
1425 void WikiBlockForm::output (MotorOutput* out) {
1426 out->out_raw (CharConst ("<form"));
1429 out->out_raw (CharConst (" method=\"get\""));
1433 out->out_raw (CharConst (" method=\"post\""));
1439 wiki->outputName (out, CharConst ("action"), ustring (CharConst ("#")), false);
1440 wiki->outputSubmitScript (out, CharConst ("onsubmit"), url, true);
1442 wiki->outputName (out, CharConst ("action"), url, false);
1445 out->out_raw (CharConst (" enctype=\"multipart/form-data\""));
1446 attrib.output (out);
1447 out->out_raw (CharConst (">\n"));
1449 out->out_raw (CharConst ("</form>\n"));
1452 /* ============================================================ */
1458 bool WikiBlockHR::nextLine (uiterator b, uiterator e) {
1462 void WikiBlockHR::addLine (uiterator b, uiterator e) {
1466 void WikiBlockHR::output (MotorOutput* out) {
1467 out->out_raw (CharConst (uHR));
1470 /* ============================================================ */
1471 bool WikiBlockRaw::nextLine (uiterator b, uiterator e) {
1475 void WikiBlockRaw::addLine (uiterator b, uiterator e) {
1479 void WikiBlockRaw::output (MotorOutput* out) {
1480 out->out_toText (text);
1483 /* ============================================================ */
1484 void WikiFormat::pass1 (const ustring& text, WikiLine::linevec* block, bool fsuper) {
1485 Splitter sp (text, re_nl);
1487 pass1_1 (sp, NULL, NULL, block, NULL, NULL, NULL, fsuper);
1490 int WikiFormat::pass1_1 (Splitter& sp, ustring* elseword, ustring* endword, WikiLine::linevec* block, uiterator* elsebegin0, uiterator* elsebegin, uiterator* elseend, bool fsuper) {
1491 uiterator b, e, t, u, v;
1494 while (sp.next ()) {
1497 while (b < e && b[0] == '\t')
1499 if (matchSkip (b, e, CharConst (kComment))) {
1501 } else if (b != e && b[0] == kWikiCmd) {
1502 if (usearch (b, e, m, re_wikicmdsep)) {
1511 if (endword && match (t, u, *endword)) {
1512 return 2; // endword
1513 } else if (elseword && match (t, u, *elseword)) {
1520 return 1; // elseword
1521 } else if (pass1_2 (sp, b, e, t, u, v, block, fsuper)) {
1524 block->push_back (wl = new WikiLine (b, e, fsuper));
1525 wl->fn = wc_call_defun;
1528 block->push_back (new WikiLine (b, e, fsuper));
1531 return 0; // end of line
1534 bool WikiFormat::pass1_2 (Splitter& sp, uiterator& b, uiterator& e, uiterator& t, uiterator& u, uiterator& v, WikiLine::linevec* block, bool fsuper) {
1535 WikiCmdTable::iterator it;
1536 ustring elseword, endword;
1541 if ((it = GWikiCmdTable.find (ustring (t, u))) != GWikiCmdTable.end ()) {
1542 block->push_back (wl = new WikiLine (b, v, e, fsuper));
1543 wl->fn = it->second->fn;
1544 if (it->second->endname) {
1545 endword.assign (it->second->endname, it->second->endnamelen);
1546 if (it->second->elsename) {
1547 elseword.assign (it->second->elsename, it->second->elsenamelen);
1548 // if-then-else block
1549 wl->block = new WikiLine::linevec;
1550 rc = pass1_1 (sp, &elseword, &endword, wl->block, &b, &v, &e, fsuper);
1554 if (endword.length () > 0) {
1555 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1560 wl2 = new WikiLine (b, v, e, fsuper);
1564 wl->block = new WikiLine::linevec;
1565 rc = pass1_1 (sp, &elseword, &endword, wl->block, &b, &v, &e, fsuper);
1568 if (endword.length () > 0) {
1569 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1571 } else if (rc == 2) {
1572 assert (wl->block2 == NULL);
1573 wl->block2 = new WikiLine (sp.begin (), sp.end (), false);
1578 assert (wl->block2 == NULL);
1579 wl->block2 = new WikiLine (sp.begin (), sp.end (), false);
1586 wl->block = new WikiLine::linevec;
1587 rc = pass1_1 (sp, NULL, &endword, wl->block, NULL, NULL, NULL, fsuper);
1589 // no end line error
1590 if (endword.length () > 0) {
1591 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1593 } else if (rc == 2) {
1594 assert (wl->block2 == NULL);
1595 wl->block2 = new WikiLine (sp.begin (), sp.end (), false);
1608 static void dump (WikiLine::linevec* block, int indent = 0) {
1611 for (j = 0; j < indent; j ++) std::cerr << " ";
1612 std::cerr << "(NULL)\n";
1615 for (i = 0; i < block->size (); i ++) {
1616 WikiLine* wl = &(*block)[i];
1617 for (j = 0; j < indent; j ++) std::cerr << " ";
1619 std::cerr << (void*)wl->fn << ":";
1620 std::cerr << ustring (wl->begin, wl->end) << uLF;
1623 dump (wl->block, indent + 1);
1627 for (j = 0; j < indent; j ++) std::cerr << " ";
1628 std::cerr << "else:" << (void*)wl->fn << ":" << ustring (wl->begin, wl->end) << uLF;
1629 // dump (wl->block, indent + 1);
1638 void WikiFormat::compile (const ustring& text, bool fsuper) {
1640 WikiLine::linevec block;
1641 pass1 (text, &block, fsuper);
1647 WikiLineScanner scanner (&block);
1648 compileLines (scanner);
1653 if (bstack.size () > 0)
1660 } catch (ustring& msg) {
1661 logLispFunctionError (msg, uEmpty);
1665 void WikiFormat::output (boost::ptr_vector<WikiBlock>& ary) {
1668 for (i = 0; i < ary.size (); i ++) {
1669 ary[i].output (env->output);
1674 void WikiFormat::errorOutput () {
1675 if (errorMsg.size () > 0) {
1676 env->output->out_raw (CharConst (uP));
1677 env->output->out_toHTML_br (errorMsg);
1678 env->output->out_raw (CharConst (uPe));
1679 errorMsg.resize (0);
1683 bool WikiFormat::checkClose (uiterator b, uiterator e) {
1684 int n = bstack.size ();
1685 WikiBlock::closeType rc;
1689 rc = bstack[n]->closeLine (b, e);
1691 case WikiBlock::CloseTrue:
1693 case WikiBlock::CloseFalse:
1700 void WikiFormat::compileLine (WikiLineScanner& scanner) {
1701 WikiLine* wl = scanner.cur ();
1705 uiterator b = wl->begin;
1706 uiterator e = wl->end;
1711 if (b == e) { // empty line
1716 } else if (matchSkip (b, e, CharConst ("//"))) { // comment
1717 } else if (checkClose (b, e)) {
1718 } else if (cur && cur->nextLine (b, e)) {
1719 } else if (b[0] == kWikiP) { // ^
1722 cur = new WikiBlockParagraph (this);
1723 blockp->push_back (cur);
1724 cur->addLine (b, e);
1725 } else if (b[0] == kWikiH) { // =
1729 cur = obj = new WikiBlockH (this);
1730 blockp->push_back (cur);
1731 cur->addLine (b, e);
1732 if (obj->checkEmpty ()) {
1736 push_block (&obj->block);
1738 } else if (b[0] == kWikiPRE // SPC
1739 || b[0] == kWikiPRE2) { // TAB
1742 cur = new WikiBlockPreformatRaw (this);
1743 blockp->push_back (cur);
1744 cur->addLine (b, e);
1745 } else if (b[0] == kWikiUL) { // *
1749 cur = obj = new WikiBlockItem (WikiBlock::BlockItemUL, this);
1750 blockp->push_back (cur);
1751 obj->addLine (b, e);
1752 } else if (b[0] == kWikiOL) { // #
1756 cur = obj = new WikiBlockItem (WikiBlock::BlockItemOL, this);
1757 blockp->push_back (cur);
1758 obj->addLine (b, e);
1759 } else if (b[0] == kWikiNL) { // +
1763 cur = obj = new WikiBlockItem (WikiBlock::BlockItemNL, this);
1764 blockp->push_back (cur);
1765 obj->addLine (b, e);
1766 } else if (b[0] == kWikiDL) { // ;
1769 cur = new WikiBlockItemDL (this);
1770 blockp->push_back (cur);
1771 cur->addLine (b, e);
1772 } else if (matchHead (b, e, CharConst ("|select:"))) { // |select:
1773 if (cur && cur->type == WikiBlock::BlockParagraph) {
1777 cur = new WikiBlockParagraph (this);
1778 blockp->push_back (cur);
1781 cur = new WikiBlockSelect (this);
1782 cur->addLine (b, e);
1783 } else if (b[0] == kWikiTABLE) { // |
1784 WikiBlockTable* obj;
1787 cur = obj = new WikiBlockTable (this);
1788 blockp->push_back (cur);
1789 cur->addLine (b, e);
1790 } else if (b[0] == kWikiQUOTE && e - b == 1) { // >
1791 WikiBlockQuote* obj;
1794 cur = obj = new WikiBlockQuote (this);
1795 blockp->push_back (cur);
1796 push_block (&obj->block);
1797 } else if (matchHead (b, e, CharConst ("{div:"))) {
1798 WikiBlockComplex* obj;
1801 cur = obj = new WikiBlockDiv (this);
1802 blockp->push_back (cur);
1803 cur->addLine (b, e);
1804 push_block (&obj->block);
1805 } else if (curform == NULL && matchHead (b, e, CharConst ("{form:"))) {
1806 WikiBlockComplex* obj;
1809 cur = obj = curform = new WikiBlockForm (this);
1810 blockp->push_back (cur);
1811 cur->addLine (b, e);
1812 push_block (&obj->block);
1813 } else if (matchHead (b, e, CharConst ("----"))) { // ----
1816 cur = new WikiBlockHR (this);
1817 blockp->push_back (cur);
1818 cur->addLine (b, e);
1821 if (cur && cur->type != WikiBlock::BlockParagraph) {
1826 cur = new WikiBlockParagraph (this);
1827 blockp->push_back (cur);
1829 cur->addLine (b, e);
1834 void WikiFormat::compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& spp, WikiLineScanner& scanner, WikiFormat* wiki, void* par), void* par) {
1837 while (wl = scanner.next ()) {
1838 if (fn && fn (*scanner.cur (), scanner, this, par)) {
1841 compileLine (scanner);
1846 void WikiFormat::pushBlockRaw (uiterator b, uiterator e) {
1849 obj = new WikiBlockRaw (this);
1850 blockp->push_back (obj);
1851 obj->addLine (b, e);
1854 int WikiFormat::countWikiH (uiterator& b, uiterator e) {
1857 while (b != e && *b == kWikiH) {
1866 void WikiFormat::outputName (MotorOutput* out, const char* name, size_t len, const ustring& val, bool cond) {
1867 if (! cond || val.length () > 0)
1869 ->out_raw (name, len)
1870 ->out_raw (CharConst ("=\""))
1871 ->out_toHTML_noCtrl (val)
1875 void WikiFormat::outputName (MotorOutput* out, const char* name, size_t len, long val, bool cond) {
1876 if (! cond || val > 0)
1878 ->out_raw (name, len)
1879 ->out_raw (CharConst ("=\""))
1880 ->out_raw (to_ustring (val))
1884 void WikiFormat::outputFlag (MotorOutput* out, const char* name, size_t len, bool flag) {
1887 ->out_raw (name, len)
1888 ->out_raw (CharConst ("=\""))
1889 ->out_raw (name, len)
1893 void WikiFormat::outputID (MotorOutput* out, const ustring& id) {
1894 if (id.length () > 0)
1895 out->out_raw (CharConst (" id=\""))
1896 ->out_toHTML_noCtrl (id)
1900 void WikiFormat::outputClass (MotorOutput* out, std::vector<ustring>& classes) {
1901 if (classes.size () > 0) {
1902 out->out_raw (CharConst (" class=\""));
1903 for (int i = 0; i < classes.size (); i ++) {
1905 out->out_raw (uSPC);
1906 out->out_toHTML_noCtrl (classes[i]);
1912 void WikiFormat::outputSubmitScript (MotorOutput* out, const char* name, size_t len, const ustring& onclick, bool scriptcut) {
1913 if (onclick.length () > 0) {
1915 ->out_raw (name, len)
1916 ->out_raw (CharConst ("=\""))
1917 ->out_toHTML_noCtrl (onclick);
1919 out->out_raw (CharConst ("return false;\""));
1921 out->out_raw (CharConst ("\""));
1925 void WikiFormat::outputNum (MotorOutput* out, const char* name, size_t len, int val) {
1927 ->out_raw (name, len)
1928 ->out_raw (CharConst ("="))
1929 ->out_raw (to_ustring (val));
1932 MNode* WikiFormat::arrayToSexp (const ustring& name) {
1936 n = mlenv->getArySize (name);
1937 for (i = 1; i <= n; i ++) {
1938 e.append (mlenv->getAry (name, i));
1943 MNode* WikiFormat::evalVar (const ustring& name) {
1947 if (checkAry (name, sym)) {
1948 return arrayToSexp (sym);
1950 return mlenv->getVar (name);
1954 void WikiFormat::wikiMotor (uiterator b, uiterator e, WikiMotorObjVec& ans) {
1955 WikiMotor motor (b, e, this);
1956 AutoInclCount autoIncl (env->mlenv);
1958 if (! autoIncl.inc_test ())
1959 throw (uErrorInclNest);
1960 motor.compile (ans, WikiMotor::TMATCH_NONE);
1963 ustring WikiFormat::wikiMotor (uiterator b, uiterator e) {
1964 WikiMotorObjVec objv;
1966 wikiMotor (b, e, objv);
1967 return objv.htmlOut (this);
1970 void WikiFormat::wikiMotorInline (uiterator b, uiterator e, WikiMotorObjVec& ans) {
1971 WikiMotorObjVec objv;
1972 WikiMotor motor (b, e, this);
1974 motor.compile (objv, WikiMotor::TMATCH_NONE);
1975 objv.eval (ans, this);
1978 //MNode* WikiFormat::buildArgs (WikiMotorObjVecVec::const_iterator b, WikiMotorObjVecVec::const_iterator e, bool dumpmode) {
1979 MNode* WikiFormat::buildArgs (WikiMotorObjVecVec::const_iterator b, WikiMotorObjVecVec::const_iterator e) {
1983 // for (; b < e; b ++) {
1984 // ans.append (newMNode_str (new ustring ((*b)->dump ())));
1987 for (; b < e; b ++) {
1988 // ans.append (newMNode_str (new ustring ((*b)->textOut (this))));
1989 ans.append ((*b)->toMNode (this));
1993 return ans.release ();
1996 void WikiFormat::logLispFunctionError (const ustring& msg, const ustring& cmd) {
1997 if (cmd.length () > 0)
1998 errorMsg.append (cmd).append (CharConst (": "));
1999 errorMsg.append (CharConst ("lisp function error.\n"));
2000 if (mlenv->env->mlenv->currentCell ()) {
2001 if (mlenv->env->log)
2002 *mlenv->env->log << mlenv->env->mlenv->currentCell ()->dump_string_short () << ": ";
2003 *mlenv->env->log << msg << uLF;
2010 /* ============================================================ */