1 #include "wikiformat.h"
8 #include "motorconst.h"
10 #include "motoroutput.h"
11 #include "util_const.h"
12 #include "util_check.h"
13 #include "util_string.h"
16 #include <boost/ptr_container/ptr_vector.hpp>
22 #define kWikiPRE2 '\t'
27 #define kWikiTABLE '|'
28 #define kWikiQUOTE '>'
29 #define kWikiQUOTE_e '<'
31 #define kWikiDIV_e '}'
43 #define uH1e "</h1>\n"
44 #define uH2e "</h2>\n"
45 #define uH3e "</h3>\n"
46 #define uH4e "</h4>\n"
47 #define uH5e "</h5>\n"
48 #define uH6e "</h6>\n"
49 #define uHR "<hr />\n"
50 //#define unbsp " "
52 ustring uWiki (CharConst ("wiki_"));
58 /* ============================================================ */
59 void WikiMlEnv::setVar (const ustring& name, MNode* val) {
62 parent->setVar (na, val);
65 void WikiMlEnv::setAry (const ustring& name, size_t i, MNode* val) {
68 parent->setAry (na, i, val);
71 void WikiMlEnv::setArySize (const ustring& name, size_t n) {
74 parent->setArySize (na, n);
77 void WikiMlEnv::setAry (const ustring& name, MNode* list) {
80 parent->setAry (na, list);
83 MNode* WikiMlEnv::getVar (const ustring& name) {
86 return parent->getVar (na);
89 MNode* WikiMlEnv::getAry (const ustring& name, size_t i) {
92 return parent->getAry (na, i);
95 size_t WikiMlEnv::getArySize (const ustring& name) {
98 return parent->getArySize (na);
101 /* ============================================================ */
103 bool WikiTableSplitter::next () {
110 while (u != e && usearch (u, e, m, *re)) {
113 if (m[5].matched) { // [[...:
115 } else if (m[6].matched) { // ]]
118 } else if (m[7].matched) { // |
129 /* ============================================================ */
130 void WikiBlockComplex::outputBlock (MotorOutput* out) {
131 for (int i = 0; i < block.size (); i ++) {
132 block[i].output (out);
136 /* ============================================================ */
139 マークアップ文字以外の文字で書き出すと,段落になる。
140 ^行頭が他のマークアップ文字になるときは,行頭に^を書く。
145 bool WikiBlockParagraph::nextLine (uiterator b, uiterator e) {
154 void WikiBlockParagraph::addLine (uiterator b, uiterator e) {
162 if (html.size () == 0) {
165 n = html.end () - it;
169 if (n == 3 && it - b == 3) {
177 html.append (wiki->wikiMotor (b, e));
180 void WikiBlockParagraph::addHtml (const ustring& ht) {
184 void WikiBlockParagraph::output (MotorOutput* out) {
185 out->out_raw (CharConst (uP))->out_toText (html)->out_raw (CharConst (uPe));
188 /* ============================================================ */
195 行頭に=を書くと,タイトルになる。行末の=は,省略可。
199 bool WikiBlockH::nextLine (uiterator b, uiterator e) {
203 void WikiBlockH::addLine (uiterator b, uiterator e) {
207 static uregex re ("(=+)#([a-zA-Z0-9_-]+)$");
209 cn = wiki->countWikiH (b, e);
210 level = cn + wiki->headbase;
213 level0 = wiki->hlevel;
215 for (; b < e && *b == ' '; b ++) {}
216 if (usearch (b, e, m, re)) {
218 n = m[1].second - m[1].first - cn;
222 for (; b < u && u[-1] == ' '; u --) {}
223 title = wiki->wikiMotor (b, u);
224 anchor = ustring (m[2].first, m[2].second);
227 for (n = cn; n > 0 && b < u && u[-1] == '='; u --, n --) {}
228 for (; b < u && u[-1] == ' '; u --) {}
229 title = wiki->wikiMotor (b, u);
231 wiki->hlevel = level;
234 WikiBlock::closeType WikiBlockH::closeLine (uiterator b, uiterator e) {
235 if (e - b == 1 && *b == kWikiDIV_e) {
237 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
238 switch (wiki->bstack[i]->type) {
241 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
243 switch (wiki->bstack[i]->type) {
255 } else if (b != e && *b == kWikiH) {
256 int l = wiki->countWikiH (b, e) + wiki->headbase;
261 for (i = wiki->bstack.size () - 1; i >= 0; i --) {
262 if (wiki->bstack[i]->type == BlockH) {
263 obj = (WikiBlockH*)wiki->bstack[i];
264 if (obj->level >= l) {
282 void WikiBlockH::close () {
283 wiki->hlevel = level0;
286 void WikiBlockH::output (MotorOutput* out) {
289 assert (0 < level && level <= 6);
290 for (i = level0 + 1; i <= level; i ++) {
291 outputBeginDiv (i, out);
294 case 1: out->out_raw (CharConst (uH1)); break;
295 case 2: out->out_raw (CharConst (uH2)); break;
296 case 3: out->out_raw (CharConst (uH3)); break;
297 case 4: out->out_raw (CharConst (uH4)); break;
298 case 5: out->out_raw (CharConst (uH5)); break;
299 case 6: out->out_raw (CharConst (uH6)); break;
301 if (anchor.size () > 0) {
302 out->out_raw (CharConst ("<a name=\""))->out_toHTML_noCtrl (anchor)->out_raw (CharConst ("\">"))->out_toText (title)->out_raw (CharConst ("</a>"));
304 out->out_noCtrl (title);
307 case 1: out->out_raw (CharConst (uH1e)); break;
308 case 2: out->out_raw (CharConst (uH2e)); break;
309 case 3: out->out_raw (CharConst (uH3e)); break;
310 case 4: out->out_raw (CharConst (uH4e)); break;
311 case 5: out->out_raw (CharConst (uH5e)); break;
312 case 6: out->out_raw (CharConst (uH6e)); break;
315 for (i = level; i > level0; i --) {
317 out->out_raw (CharConst ("</div><!-- hh"))->out_raw (to_ustring (i))->out_raw (CharConst (" -->\n"));
324 void WikiBlockH::outputBeginDiv (int lv, MotorOutput* out) {
326 case 1: out->out_raw (CharConst ("<div class=\"hh1\">\n")); break;
327 case 2: out->out_raw (CharConst ("<div class=\"hh2\">\n")); break;
328 case 3: out->out_raw (CharConst ("<div class=\"hh3\">\n")); break;
329 case 4: out->out_raw (CharConst ("<div class=\"hh4\">\n")); break;
330 case 5: out->out_raw (CharConst ("<div class=\"hh5\">\n")); break;
331 case 6: out->out_raw (CharConst ("<div class=\"hh6\">\n")); break;
335 void WikiBlockH::outputEndDiv (MotorOutput* out) {
336 out->out_raw (CharConst ("</div>\n"));
339 /* ============================================================ */
341 ===フォーマット済みテキストブロック===
342 行頭に空白文字を書くと,<pre>〜</pre>タグで囲まれます。
345 bool WikiBlockPreformat::nextLine (uiterator b, uiterator e) {
354 void WikiBlockPreformat::addLine (uiterator b, uiterator e) {
357 // html.append (wiki->wikiMotor (b + 1, e));
358 text.append (b + 1, e);
360 // html.append (wiki->wikiMotor (b, e));
363 // html.append (uLF);
367 void WikiBlockPreformat::output (MotorOutput* out) {
368 // out->out_raw (CharConst ("<pre>"))->out_toText (html)->out_raw (CharConst ("</pre>\n"));
369 out->out_raw (CharConst ("<pre>"))->out_toHTML (text)->out_raw (CharConst ("</pre>\n"));
372 /* ============================================================ */
373 bool WikiBlockItemText::nextLine (uiterator b, uiterator e) {
377 void WikiBlockItemText::addLine (uiterator b, uiterator e) {
378 html.append (wiki->wikiMotor (b, e));
381 bool WikiBlockItemText::checkAddLine (uiterator b, uiterator e) {
387 html.append (wiki->wikiMotor (b, e));
390 if (block.size () > 0) {
391 obj = &block.back ();
396 wbi = (WikiBlockItem*)obj;
409 void WikiBlockItemText::output (MotorOutput* out) {
413 out->out_raw (CharConst ("<li>"));
414 out->out_toText (html);
416 out->out_raw (CharConst ("</li>\n"));
420 /* ============================================================ */
431 bool WikiBlockItem::nextLine (uiterator b, uiterator e) {
440 void WikiBlockItem::setChar (char c) {
445 void WikiBlockItem::addLine (uiterator b, uiterator e) {
448 WikiBlockItemText* wbt;
453 assert (b != e && b[0] == ch);
456 wbt = new WikiBlockItemText (wiki);
457 block.push_back (wbt);
461 if (block.size () > 0 && block.back ().checkAddLine (b, e)) {
465 wbi = new WikiBlockItem (WikiBlock::BlockItemUL, wiki);
468 wbi = new WikiBlockItem (WikiBlock::BlockItemOL, wiki);
471 wbi = new WikiBlockItem (WikiBlock::BlockItemNL, wiki);
477 if (block.size () > 0) {
478 wbt = &block.back ();
480 wbt->block.push_back (wbi);
482 wbt = new WikiBlockItemText (wiki);
483 block.push_back (wbt);
485 wbt->block.push_back (wbi);
486 wbt->indentHack = true;
489 wbt = new WikiBlockItemText (wiki);
490 block.push_back (wbt);
497 void WikiBlockItem::output (MotorOutput* out) {
502 out->out_raw (CharConst ("<ul>\n"));
504 out->out_raw (CharConst ("</ul>\n"));
507 out->out_raw (CharConst ("<ol>\n"));
509 out->out_raw (CharConst ("</ol>\n"));
512 out->out_raw (CharConst ("<ul class=\"nobull\">\n"));
514 out->out_raw (CharConst ("</ul>\n"));
517 std::cerr << "type:" << type << uLF;
522 void WikiBlockItem::outputBlock (MotorOutput* out) {
523 for (int i = 0; i < block.size (); i ++) {
524 block[i].output (out);
528 /* ============================================================ */
534 bool WikiBlockItemDL::nextLine (uiterator b, uiterator e) {
543 void WikiBlockItemDL::addLine (uiterator b, uiterator e) {
544 WikiMotor motor (b + 1, e, wiki);
545 WikiMotorObjVec objs;
548 motor.compile (objs);
549 objs.splitChar (wiki, ':', def, desc);
550 html1.push_back (def);
551 html2.push_back (desc);
554 void WikiBlockItemDL::output (MotorOutput* out) {
557 out->out_raw (CharConst ("<dl>\n"));
558 for (i = 0; i < html1.size (); i ++) {
559 out->out_raw (CharConst ("<dt>"))->out_toText (html1[i])->out_raw (CharConst ("</dt>\n"));
560 out->out_raw (CharConst ("<dd>"))->out_toText (html2[i])->out_raw (CharConst ("</dd>\n"));
562 out->out_raw (CharConst ("</dl>\n"));
565 /* ============================================================ */
568 |table:w=100%|head:right:||right:|
576 |noborder|nb|border="0"を出力する。|
577 |cellspacing=''integer''|spc=|cellspacing属性を出力する。|
578 |cellpadding=''integer''||cellpadding属性を出力する。|
579 |padding|pad|テーブルの最大のカラム数よりカラムが少ない行に,空のカラムを追加する。|
580 |expanding|expand|テーブルの最大のカラム数よりカラムが少ない行の最後のカラムを引き延ばす。|
581 |center|c|テーブルをセンタリングする。|
583 |right|r|テーブルを右寄せする。|
584 |id=''name''||id属性を出力する。|
585 |class=''name''||class属性を出力する。|
586 |width=''number'', width=''number''%|w=|width属性を出力する。|
587 |bgcolor=#''color''|bg=|bgcolor属性を出力する。|
589 |turn||セルの並びの横方向と縦方向を交換する。|
594 |header|h|ヘッダタグ(<th>)を出力する。|
597 |center|c|横方向で中央あわせする。|
599 |middle|m|縦方向で中央あわせする。|
601 |nowrap|nw|セル内での折り返しを禁止する。|
602 |*||これ以前にtable:行などで指定したセルオプションを破棄する。|
603 |id=''name''||セルタグにid属性を付加する。|
604 |class=''name''||セルタグにclass属性を付加する。|
605 |width=''number''&|;''number''%||セルタグにwidth属性を付加する。|
606 |height=''number''&|;''number''%||セルタグにheight属性を付加する。|
607 |bgcolor=#''hex''|bg=|セルタグにbg属性を付加する。|
611 |&<;''text''|左のセルと内容が一致するとき,結合する。|
612 |&<;^''text''|左のセルと内容が一致し,左のセルが上のセルと結合しているとき,結合する。|
614 |&^;''text''|上のセルと内容が一致するとき,結合する。|
615 |&^;<''text''|上のセルと内容が一致し,上のセルが左のセルと結合しているとき,結合する。|
618 void WikiBlockTable::TableCell::init () {
623 while (! classlist.empty ())
624 classlist.pop_back ();
631 void WikiBlockTable::TableCell::copyFrom (WikiBlockTable::TableCell& b) {
638 for (i = 0; i < b.classlist.size (); i ++)
639 classlist.push_back (b.classlist[i]);
646 void WikiBlockTable::TableCell::cellAttrib (WikiFormat* wiki, WikiMotor* motor, WikiMotorObjVec* in, WikiMotorObjVec& out, bool inHeader) {
647 WikiMotorObjVec::const_iterator b = in->begin ();
648 WikiMotorObjVec::const_iterator e = in->end ();
649 WikiMotorObj* t = NULL;
651 WikiMotorObjVecPtr v1;
652 WikiMotorObjVecPtr v2;
654 v1 = WikiMotorObjVecPtr (new WikiMotorObjVec);
655 for (; b < e; b ++) {
658 while (v1->size () > 0) {
659 WikiMotorObjVec cell;
661 WikiMotorObjVec vval;
662 v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
663 if (v1->splitChar (':', cell, *v2) || inHeader) {
664 if (cell.splitChar_keyword ('=', key, vval)) {
665 if (wiki->paramID (key, vval, id, ferr)) {
666 } else if (wiki->paramClass (key, vval, classlist, ferr)) {
667 } else if (wiki->paramWidth (key, vval, width, ferr)) {
668 } else if (wiki->paramHeight (key, vval, height, ferr)) {
669 } else if (match (key, CharConst ("bgcolor"), CharConst ("bg"))) {
670 wiki->paramColor (vval.textOut (wiki), bgcolor, key);
675 if (match (key, CharConst ("header"), CharConst ("h"))) {
677 } else if (match (key, CharConst ("left"), CharConst ("l"))) {
679 } else if (match (key, CharConst ("right"), CharConst ("r"))) {
680 halign = HAlignRight;
681 } else if (match (key, CharConst ("center"), CharConst ("c"))) {
682 halign = HAlignCenter;
683 } else if (match (key, CharConst ("top"), CharConst ("t"))) {
685 } else if (match (key, CharConst ("middle"), CharConst ("m"))) {
686 valign = VAlignMiddle;
687 } else if (match (key, CharConst ("bottom"), CharConst ("b"))) {
688 valign = VAlignBottom;
689 } else if (match (key, CharConst ("nowrap"), CharConst ("nw"))) {
691 } else if (match (key, CharConst ("*"))) {
705 for (; b < e; b ++) {
710 void WikiBlockTable::TableCell::cellBody (WikiMotorObjVec* vtext, WikiBlockTable* table, int idx) {
714 if (vtext->size () > 0 && (*vtext)[0].get ()->type == WikiMotorObj::wiki_text) {
715 WikiMotorObjText* w = WikiMotorObjText_type ((*vtext)[0].get ());
716 uiterator b = w->text.begin ();
717 uiterator e = w->text.end ();
719 if (b < e && *b == '<') {
722 if (b < e && *b == '^') {
726 } else if (b < e && *b == '^') {
729 if (b < e && *b == '<') {
734 (*vtext)[0].reset (new WikiMotorObjText (b, e));
737 html = vtext->htmlOut (table->wiki);
739 if (! spanmatch || table->ary.size () <= 1 || table->ary[table->ary.size () - 2][idx].colspan == 0) {
740 col = &table->ary.back ();
741 for (i = idx - 1; i >= 0; i --) {
742 if ((*col)[i].colspan > 0) {
743 if (html.length () == 0 || (*col)[i].html == html) {
745 (*col)[i].colspan ++;
753 if (! spanmatch || idx == 0 || table->ary.back ()[idx - 1].rowspan == 0) {
754 for (i = table->ary.size () - 2; i >= 0; i --) {
755 col = &table->ary[i];
756 if (idx < col->size () && (*col)[idx].rowspan > 0) {
757 if (html.length () == 0 || (*col)[idx].html == html) {
759 (*col)[idx].rowspan ++;
768 void WikiBlockTable::TableCell::outputTD (WikiFormat* wiki, MotorOutput* out, bool fturn) {
772 out->out_raw (CharConst ("<th"));
774 out->out_raw (CharConst ("<td"));
778 out->out_raw (CharConst (" align=\"left\""));
781 out->out_raw (CharConst (" align=\"center\""));
784 out->out_raw (CharConst (" align=\"right\""));
789 out->out_raw (CharConst (" valign=\"top\""));
792 out->out_raw (CharConst (" valign=\"middle\""));
795 out->out_raw (CharConst (" valign=\"bottom\""));
798 wiki->outputID (out, id);
799 wiki->outputClass (out, classlist);
800 wiki->outputName (out, CharConst ("width"), width);
801 wiki->outputName (out, CharConst ("height"), height);
802 wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
803 wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
806 wiki->outputName (out, CharConst ("rowspan"), colspan, false);
808 wiki->outputName (out, CharConst ("colspan"), rowspan, false);
811 wiki->outputName (out, CharConst ("colspan"), colspan, false);
813 wiki->outputName (out, CharConst ("rowspan"), rowspan, false);
815 out->out_raw (CharConst (">"));
818 void WikiBlockTable::TableCell::outputTDe (MotorOutput* out) {
820 out->out_raw (CharConst ("</th>\n"));
822 out->out_raw (CharConst ("</td>\n"));
825 /* ============================================================ */
826 bool WikiBlockTable::nextLine (uiterator b, uiterator e) {
827 if (*b == kWikiTABLE) {
835 void WikiBlockTable::addLine (uiterator b, uiterator e) {
836 assert (b[0] == '|');
838 if (n == 0 && matchSkip (b, e, CharConst ("table:"))) {
846 WikiBlock::closeType WikiBlockTable::closeLine (uiterator b, uiterator e) {
847 static uregex re ("^\\}\\}(($)|(\\|)|((!([1-9][0-9]*))?\\\\$))");
850 if (usearch (b, e, m, re)) {
851 if (m[2].matched) { // }}
854 } else if (m[3].matched) { // }}|...
856 if (wiki->cur && wiki->cur->type == BlockTable) {
857 WikiBlockTable* obj = (WikiBlockTable*)wiki->cur;
859 addLine_body (m[3].second, e);
864 } else if (m[4].matched) { // }}\ .
866 if (wiki->cur && wiki->cur->type == BlockTable) {
867 WikiBlockTable* obj = (WikiBlockTable*)wiki->cur;
869 addLine_body (m[4].first, e);
879 void WikiBlockTable::output (MotorOutput* out) {
881 outputTableTag (out);
883 out->out_raw (CharConst ("</table>\n"));
886 void WikiBlockTable::addLine_head (uiterator b, uiterator e) {
887 WikiMotor motor (b, e, wiki);
888 WikiMotorObjVec objv;
889 WikiMotorObjVecVec objvv;
893 motor.compile (objv);
894 objv.splitCharA ('|', objvv);
895 if (objvv.size () > 0 && objvv.back ()->size () == 0)
897 addLine_head_table (&motor, objvv[0].get ());
898 for (i = 1; i < objvv.size (); i ++) {
899 WikiMotorObjVec texts;
900 cell = newCell (defaultList.size ());
901 cell->cellAttrib (wiki, &motor, objvv[i].get (), texts, true);
902 defaultList.push_back (cell);
906 void WikiBlockTable::addLine_head_table (WikiMotor* motor, WikiMotorObjVec* objs) {
908 WikiMotorObjVecVec params;
909 WikiMotorObjVec* param;
912 objs->splitCharA (':', params);
913 for (i = 0; i < params.size (); i ++) {
914 param = params[i].get ();
915 if (param->size () > 0) {
917 WikiMotorObjVec vvalue;
918 if (params[i].get ()->splitChar_keyword ('=', name, vvalue)) {
919 if (match (name, CharConst ("cellspacing"), CharConst ("spc"))) {
920 wiki->paramUNum (vvalue.textOut (wiki), cellspacing, name);
921 } else if (match (name, CharConst ("cellpadding"))) {
922 wiki->paramUNum (vvalue.textOut (wiki), cellpadding, name);
923 } else if (match (name, CharConst ("bgcolor"), CharConst ("bg"))) {
924 wiki->paramColor (vvalue.textOut (wiki), bgcolor, name);
925 } else if (wiki->paramID (name, vvalue, id, ferr)) {
926 } else if (wiki->paramClass (name, vvalue, classlist, ferr)) {
927 } else if (wiki->paramWidth (name, vvalue, width, ferr)) {
929 wiki->errorMsg.append (name).append (uEq).append (vvalue.dump ()).append (CharConst (": error.\n"));
932 if (match (name, CharConst ("noborder"), CharConst ("nb"))) {
934 } else if (match (name, CharConst ("padding"), CharConst ("pad"))) {
936 } else if (match (name, CharConst ("expanding"), CharConst ("expand"))) {
938 } else if (match (name, CharConst ("center"), CharConst ("c"))) {
939 halign = HAlignCenter;
940 } else if (match (name, CharConst ("left"), CharConst ("l"))) {
942 } else if (match (name, CharConst ("right"), CharConst ("r"))) {
943 halign = HAlignRight;
944 } else if (match (name, CharConst ("nowhite"), CharConst ("nw"))) {
946 } else if (match (name, CharConst ("turn"))) {
949 wiki->errorMsg.append (name).append (CharConst (": error.\n"));
956 void WikiBlockTable::addLine_body (uiterator b, uiterator e) {
958 bool fmorecell = false;
960 static uregex re ("(!([1-9][0-9]*))?\\\\$");
966 cols = new CellList_t;
967 ary.push_back (cols);
970 if (usearch (b, e, m, re)) { //
972 if (m[2].matched) { // ...!NUM\ .
973 int v = strtoul (m[2].first);
984 if (b < e && e[-1] == '|') { // ...|\ .
992 WikiMotor motor (b, e, wiki);
993 WikiMotorObjVec objv;
994 WikiMotorObjVecVec objvv;
995 WikiMotorObjVec* vcell;
999 static const ustring brabra (CharConst ("{{"));
1001 motor.compile (objv);
1002 objv.splitCharA ('|', objvv);
1003 if (objvv.size () > 0 && objvv.back ()->size () == 0) {
1009 n = objvv.size () - 1;
1010 for (i = 0; i <= n; i ++) {
1011 WikiMotorObjVec texts;
1013 vcell = objvv[i].get ();
1014 cell = newCell (cols->size ());
1015 cell->cellAttrib (wiki, &motor, vcell, texts);
1016 if (i == n && fop && texts.match (brabra)) {
1017 cols->push_back (cell);
1018 wiki->push_block (&cell->block);
1021 cell->cellBody (&texts, this, cols->size ());
1022 cols->push_back (cell);
1026 cell = newCell (cols->size ());
1027 cols->push_back (cell);
1032 WikiBlockTable::TableCell* WikiBlockTable::newCell (int idx) {
1033 TableCell* ans = new TableCell;
1035 if (idx < defaultList.size ())
1036 ans->copyFrom (defaultList[idx]);
1040 void WikiBlockTable::normalize () {
1046 for (i = 0; i < ary.size (); i ++) {
1048 if (col->size () > maxcol)
1049 maxcol = col->size ();
1052 for (i = 0; i < ary.size (); i ++) {
1054 if (col->size () < maxcol) {
1055 cell = newCell (col->size ());
1056 cell->colspan = maxcol - col->size ();
1057 col->push_back (cell);
1058 while (col->size () < maxcol) {
1059 cell = newCell (col->size ());
1061 col->push_back (cell);
1066 for (i = 0; i < ary.size (); i ++) {
1068 for (j = col->size () - 1; j >= 0; j --) {
1070 if (cell->colspan > 0) {
1071 cell->colspan += maxcol - col->size ();
1072 while (col->size () < maxcol) {
1073 cell = newCell (col->size ());
1075 col->push_back (cell);
1084 void WikiBlockTable::outputTableTag (MotorOutput* out) {
1087 if (cellspacing < 0)
1089 if (cellpadding < 0)
1091 out->out_raw (CharConst ("<table"));
1092 wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
1093 wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
1094 wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
1097 out->out_raw (CharConst (" align=\"left\""));
1100 out->out_raw (CharConst (" align=\"center\""));
1103 out->out_raw (CharConst (" align=\"right\""));
1106 wiki->outputID (out, id);
1107 wiki->outputClass (out, classlist);
1108 wiki->outputName (out, CharConst ("width"), width);
1109 wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
1110 out->out_raw (CharConst (">\n"));
1113 void WikiBlockTable::outputTBody (MotorOutput* out) {
1119 if (ary.size () > 0) {
1121 for (j = 0; j < n; j ++) {
1122 out->out_raw (CharConst ("<tr>\n"));
1123 for (i = 0; i < ary.size (); i ++) {
1126 outputTBodyCell (wiki, out, cell);
1128 out->out_raw (CharConst ("</tr>\n"));
1132 for (i = 0; i < ary.size (); i ++) {
1134 out->out_raw (CharConst ("<tr>\n"));
1135 for (j = 0; j < col->size (); j ++) {
1137 outputTBodyCell (wiki, out, cell);
1139 out->out_raw (CharConst ("</tr>\n"));
1144 void WikiBlockTable::outputTBodyCell (WikiFormat* wiki, MotorOutput* out, TableCell* cell) {
1145 if (cell->colspan > 0 && cell->rowspan > 0) {
1146 cell->outputTD (wiki, out, fturn);
1147 if (cell->block.size () > 0) {
1148 wiki->output (cell->block);
1150 if (cell->html.size () > 0) {
1151 out->out_toText (cell->html);
1154 out->out_raw (uNbsp);
1157 cell->outputTDe (out);
1161 /* ============================================================ */
1164 |select:NAME:function:default:size=NUM:multiple|
1166 |LABEL|VALUE|selected|
1169 bool WikiBlockSelect::nextLine (uiterator b, uiterator e) {
1170 if (*b == kWikiTABLE) {
1179 void WikiBlockSelect::addLine (uiterator b, uiterator e) {
1180 assert (b[0] == '|');
1182 if (n == 0 && matchSkip (b, e, CharConst ("select:"))) {
1183 addLine_head (b, e);
1185 addLine_body (b, e);
1190 void WikiBlockSelect::addLine_head (uiterator b, uiterator e) {
1191 WikiMotor motor (b, e, wiki);
1192 WikiMotorObjVec objv;
1193 WikiMotorObjVecVec objvv;
1194 WikiMotorObjVec* vcell;
1197 motor.compile (objv);
1198 objv.splitCharA ('|', objvv);
1199 if (objvv.size () > 0 && objvv.back ()->size () == 0)
1201 if (objvv.size () > 0) {
1202 vcell = objvv[0].get ();
1203 vcell->splitCharA (':', args);
1204 if (args.size () > 0) {
1205 name = args[0].get ()->textOut (wiki);
1206 args.erase (args.begin ());
1207 while (args.size () > 0) {
1209 WikiMotorObjVec vvalue;
1210 if (args[0].get ()->splitChar_keyword ('=', key, vvalue)) {
1211 if (match (key, CharConst ("size"))) {
1212 ustring v = vvalue.textOut (wiki);
1213 if (match (v, CharConst ("*"))) {
1215 } else if (checkNum (v)) {
1216 elsize = to_int32 (v);
1217 if (elsize < 0 || elsize > 999) {
1223 args.erase (args.begin ());
1224 } else if (wiki->paramID (key, vvalue, id, ferr)) {
1225 } else if (wiki->paramClass (key, vvalue, classlist, ferr)) {
1230 if (match (key, CharConst ("default"))) {
1232 args.erase (args.begin ());
1233 } else if (match (key, CharConst ("multiple"))) {
1235 args.erase (args.begin ());
1243 if (fmultiple && elsize == 0) {
1248 void WikiBlockSelect::addLine_body (uiterator b, uiterator e) {
1249 WikiMotor motor (b, e, wiki);
1250 WikiMotorObjVec objv;
1251 WikiMotorObjVecVec objvv;
1254 motor.compile (objv);
1255 objv.splitCharA ('|', objvv);
1256 if (objvv.size () > 0 && objvv.back ()->size () == 0)
1258 if (objvv.size () > 0) {
1259 v.label = omitCtrl (objvv[0].get ()->textOut (wiki));
1263 if (objvv.size () > 1) {
1264 v.value = omitCtrl (objvv[1].get ()->textOut (wiki));
1271 if (objvv.size () > 2) {
1272 if (objvv[2].get ()->match (CharConst ("selected"), CharConst ("sel"))) {
1279 void WikiBlockSelect::close () {
1282 assert (wiki->cur->type == BlockParagraph);
1284 MotorOutputString out;
1286 wiki->cur->addHtml (out.ans);
1290 void WikiBlockSelect::output (MotorOutput* out) {
1293 WikiMotorObjVecVec::const_iterator b = args.begin ();
1294 WikiMotorObjVecVec::const_iterator e = args.end ();
1296 out->out_raw (CharConst ("<select"));
1297 wiki->outputName (out, CharConst ("name"), name, false);
1299 wiki->outputName (out, CharConst ("size"), item.size (), false);
1301 wiki->outputName (out, CharConst ("size"), elsize);
1303 wiki->outputFlag (out, CharConst ("multiple"), fmultiple);
1304 wiki->outputID (out, id);
1305 wiki->outputClass (out, classlist);
1307 if (wiki->outputLinkScript (b, e, u))
1308 wiki->outputName (out, CharConst ("onChange"), u);
1310 out->out_raw (CharConst (">\n"));
1313 u = wiki->getVar (name);
1315 std::cerr << "u:" << u << uLF;
1318 for (i = 0; i < item.size (); i ++) {
1319 SelectItem* v = &item[i];
1320 out->out_raw (CharConst ("<option"));
1322 wiki->outputName (out, CharConst ("value"), v->value, false);
1324 std::cerr << "u:" << u << " v:" << v->value << " ::" << (u == v->value) << uLF;
1326 wiki->outputName (out, CharConst ("selected"), (v->fselect || (fdefault && u == v->value)));
1328 wiki->outputName (out, CharConst ("selected"), (v->fselect || (fdefault && u == v->label)));
1330 out->out_raw (CharConst (">"));
1331 out->out_toHTML (v->label)->out_raw (CharConst ("</option>\n"));
1333 out->out_raw (CharConst ("</select>\n"));
1336 /* ============================================================ */
1344 bool WikiBlockQuote::nextLine (uiterator b, uiterator e) {
1348 WikiBlock::closeType WikiBlockQuote::closeLine (uiterator b, uiterator e) {
1349 if (e - b == 1 && *b == kWikiQUOTE_e) {
1358 void WikiBlockQuote::addLine (uiterator b, uiterator e) {
1362 void WikiBlockQuote::output (MotorOutput* out) {
1363 out->out_raw (CharConst ("<blockquote>\n"));
1365 out->out_raw (CharConst ("</blockquote>\n"));
1368 /* ============================================================ */
1374 {div:id=Name:SideMenu
1379 bool WikiBlockDiv::nextLine (uiterator b, uiterator e) {
1383 void WikiBlockDiv::addLine (uiterator b, uiterator e) {
1384 WikiMotor motor (b, e, wiki);
1385 WikiMotorObjVec objv;
1386 WikiMotorObjVecVec args;
1390 motor.compile (objv);
1391 objv.splitCharA (':', args);
1392 args.erase (args.begin ()); // "div"
1393 if (args.size () > 0 && args.back ()->size () == 0)
1395 for (i = 0; i < args.size (); i ++) {
1397 WikiMotorObjVec vval;
1398 if (args[i].get ()->splitChar_keyword ('=', key, vval)) {
1399 if (wiki->paramID (key, vval, id, ferr)) {
1400 } else if (wiki->paramClass (key, vval, classlist, ferr)) {
1402 wiki->errorMsg.append (key).append (uEq).append (vval.dump ()).append (CharConst (": error.\n"));
1405 wiki->paramClassValue (*args[i].get (), classlist, ferr);
1410 WikiBlock::closeType WikiBlockDiv::closeLine (uiterator b, uiterator e) {
1411 if (e - b == 1 && *b == kWikiDIV_e) {
1420 void WikiBlockDiv::output (MotorOutput* out) {
1423 out->out_raw (CharConst ("<div"));
1424 wiki->outputID (out, id);
1425 wiki->outputClass (out, classlist);
1426 out->out_raw (CharConst (">\n"));
1428 out->out_raw (CharConst ("</div>\n"));
1431 /* ============================================================ */
1437 // {form:POST:id=form1:class=formclass:post.hgh
1438 // {form:POST:post.hgh:id=form1:class=formclass
1439 {form:POST:id=form1:class=formclass:post.hgh:target_window
1444 bool WikiBlockForm::nextLine (uiterator b, uiterator e) {
1448 void WikiBlockForm::addLine (uiterator b, uiterator e) {
1449 WikiMotor motor (b, e, wiki);
1450 WikiMotorObjVec objv;
1451 WikiMotorObjVecVec args;
1453 WikiMotorObjVecVec::const_iterator ab, ae;
1455 motor.compile (objv);
1456 objv.splitCharA (':', args);
1457 args.erase (args.begin ()); // "form"
1458 if (args.size () > 0 && args.back ()->size () == 0)
1463 if ((*ab)->match (CharConst ("get"), CharConst ("GET"))) {
1466 } else if ((*ab)->match (CharConst ("post"), CharConst ("POST"))) {
1473 WikiMotorObjVec vval;
1474 if ((*ab)->splitChar_keyword ('=', key, vval)) {
1475 if (wiki->paramID (key, vval, id, ferr)) {
1477 } else if (wiki->paramClass (key, vval, classlist, ferr)) {
1486 wiki->wikiURLParam (ab, ae, fscript, url, target);
1489 WikiBlock::closeType WikiBlockForm::closeLine (uiterator b, uiterator e) {
1490 if (e - b == 1 && *b == kWikiDIV_e) {
1493 wiki->curform = NULL;
1500 void WikiBlockForm::output (MotorOutput* out) {
1501 out->out_raw (CharConst ("<form"));
1504 out->out_raw (CharConst (" method=\"get\""));
1508 out->out_raw (CharConst (" method=\"post\""));
1513 // if (wiki->outputLinkScript (b, e, url)) {
1515 wiki->outputName (out, CharConst ("action"), ustring (CharConst ("#")), false);
1516 wiki->outputName (out, CharConst ("onSubmit"), url);
1518 wiki->outputName (out, CharConst ("action"), url, false);
1521 out->out_raw (CharConst (" enctype=\"multipart/form-data\""));
1522 wiki->outputName (out, CharConst ("target"), target);
1523 wiki->outputID (out, id);
1524 wiki->outputClass (out, classlist);
1525 out->out_raw (CharConst (">\n"));
1527 out->out_raw (CharConst ("</form>\n"));
1530 /* ============================================================ */
1536 bool WikiBlockHR::nextLine (uiterator b, uiterator e) {
1540 void WikiBlockHR::addLine (uiterator b, uiterator e) {
1544 void WikiBlockHR::output (MotorOutput* out) {
1545 out->out_raw (CharConst (uHR));
1548 /* ============================================================ */
1549 void WikiFormat::pass1 (const ustring& text, WikiLine::linevec* block, bool fsuper) {
1550 Splitter sp (text, re_nl);
1552 pass1_1 (sp, NULL, NULL, block, NULL, NULL, NULL, fsuper);
1555 int WikiFormat::pass1_1 (Splitter& sp, ustring* elseword, ustring* endword, WikiLine::linevec* block, uiterator* elsebegin0, uiterator* elsebegin, uiterator* elseend, bool fsuper) {
1556 uiterator b, e, t, u, v;
1559 while (sp.next ()) {
1562 while (b < e && b[0] == '\t')
1564 if (matchSkip (b, e, CharConst (kComment))) {
1566 } else if (b != e && b[0] == kWikiCmd) {
1567 if (usearch (b, e, m, re_wikicmdsep)) {
1576 if (endword && match (t, u, *endword)) {
1577 return 2; // endword
1578 } else if (elseword && match (t, u, *elseword)) {
1585 return 1; // elseword
1586 } else if (pass1_2 (sp, b, e, t, u, v, block, fsuper)) {
1589 block->push_back (wl = new WikiLine (b, e, fsuper));
1590 wl->fn = wc_call_defun;
1593 block->push_back (new WikiLine (b, e, fsuper));
1596 return 0; // end of line
1599 bool WikiFormat::pass1_2 (Splitter& sp, uiterator& b, uiterator& e, uiterator& t, uiterator& u, uiterator& v, WikiLine::linevec* block, bool fsuper) {
1600 WikiCmdTable::iterator it;
1601 ustring elseword, endword;
1606 if ((it = GWikiCmdTable.find (ustring (t, u))) != GWikiCmdTable.end ()) {
1607 block->push_back (wl = new WikiLine (b, v, e, fsuper));
1608 wl->fn = it->second->fn;
1609 if (it->second->endname) {
1610 endword.assign (it->second->endname, it->second->endnamelen);
1611 if (it->second->elsename) {
1612 elseword.assign (it->second->elsename, it->second->elsenamelen);
1613 // if-then-else block
1614 wl->block = new WikiLine::linevec;
1615 rc = pass1_1 (sp, &elseword, &endword, wl->block, &b, &v, &e, fsuper);
1619 if (endword.length () > 0) {
1620 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1625 wl2 = new WikiLine (b, v, e, fsuper);
1629 wl->block = new WikiLine::linevec;
1630 rc = pass1_1 (sp, &elseword, &endword, wl->block, &b, &v, &e, fsuper);
1633 if (endword.length () > 0) {
1634 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1646 wl->block = new WikiLine::linevec;
1647 rc = pass1_1 (sp, NULL, &endword, wl->block, NULL, NULL, NULL, fsuper);
1649 // no end line error
1650 if (endword.length () > 0) {
1651 errorMsg.append (CharConst ("no matcing \"")).append (endword).append (CharConst ("\".\n"));
1665 static void dump (WikiLine::linevec* block, int indent = 0) {
1668 for (j = 0; j < indent; j ++) std::cerr << " ";
1669 std::cerr << "(NULL)\n";
1672 for (i = 0; i < block->size (); i ++) {
1673 WikiLine* wl = &(*block)[i];
1674 for (j = 0; j < indent; j ++) std::cerr << " ";
1676 std::cerr << (void*)wl->fn << ":";
1677 std::cerr << ustring (wl->begin, wl->end) << uLF;
1680 dump (wl->block, indent + 1);
1684 for (j = 0; j < indent; j ++) std::cerr << " ";
1685 std::cerr << "else:" << (void*)wl->fn << ":" << ustring (wl->begin, wl->end) << uLF;
1686 // dump (wl->block, indent + 1);
1695 void WikiFormat::compile (const ustring& text, bool fsuper) {
1697 WikiLine::linevec block;
1698 pass1 (text, &block, fsuper);
1704 WikiLineScanner scanner (&block);
1705 compileLines (scanner);
1710 if (bstack.size () > 0)
1717 } catch (ustring& msg) {
1718 logLispFunctionError (msg, uEmpty);
1722 void WikiFormat::output (boost::ptr_vector<WikiBlock>& ary) {
1725 for (i = 0; i < ary.size (); i ++) {
1726 ary[i].output (env->output);
1731 void WikiFormat::errorOutput () {
1732 if (errorMsg.size () > 0) {
1733 env->output->out_raw (CharConst (uP));
1734 env->output->out_toHTML_br (errorMsg);
1735 env->output->out_raw (CharConst (uPe));
1736 errorMsg.resize (0);
1740 bool WikiFormat::checkClose (uiterator b, uiterator e) {
1741 int n = bstack.size ();
1742 WikiBlock::closeType rc;
1746 rc = bstack[n]->closeLine (b, e);
1748 case WikiBlock::CloseTrue:
1750 case WikiBlock::CloseFalse:
1757 void WikiFormat::compileLine (WikiLineScanner& scanner) {
1758 WikiLine* wl = scanner.cur ();
1762 uiterator b = wl->begin;
1763 uiterator e = wl->end;
1768 if (b == e) { // empty line
1773 } else if (matchSkip (b, e, CharConst ("//"))) { // comment
1774 } else if (checkClose (b, e)) {
1775 } else if (cur && cur->nextLine (b, e)) {
1776 } else if (b[0] == kWikiP) { // ^
1779 cur = new WikiBlockParagraph (this);
1780 blockp->push_back (cur);
1781 cur->addLine (b, e);
1782 } else if (b[0] == kWikiH) { // =
1786 cur = obj = new WikiBlockH (this);
1787 blockp->push_back (cur);
1788 cur->addLine (b, e);
1789 push_block (&obj->block);
1790 } else if (b[0] == kWikiPRE // SPC
1791 || b[0] == kWikiPRE2) { // TAB
1794 cur = new WikiBlockPreformat (this);
1795 blockp->push_back (cur);
1796 cur->addLine (b, e);
1797 } else if (b[0] == kWikiUL) { // *
1801 cur = obj = new WikiBlockItem (WikiBlock::BlockItemUL, this);
1802 blockp->push_back (cur);
1803 obj->addLine (b, e);
1804 } else if (b[0] == kWikiOL) { // #
1808 cur = obj = new WikiBlockItem (WikiBlock::BlockItemOL, this);
1809 blockp->push_back (cur);
1810 obj->addLine (b, e);
1811 } else if (b[0] == kWikiNL) { // ]
1815 cur = obj = new WikiBlockItem (WikiBlock::BlockItemNL, this);
1816 blockp->push_back (cur);
1817 obj->addLine (b, e);
1818 } else if (b[0] == kWikiDL) { // ;
1821 cur = new WikiBlockItemDL (this);
1822 blockp->push_back (cur);
1823 cur->addLine (b, e);
1824 } else if (matchHead (b, e, CharConst ("|select:"))) { // |select:
1825 if (cur && cur->type == WikiBlock::BlockParagraph) {
1829 cur = new WikiBlockParagraph (this);
1830 blockp->push_back (cur);
1833 cur = new WikiBlockSelect (this);
1834 cur->addLine (b, e);
1835 } else if (b[0] == kWikiTABLE) { // |
1836 WikiBlockTable* obj;
1839 cur = obj = new WikiBlockTable (this);
1840 blockp->push_back (cur);
1841 cur->addLine (b, e);
1842 } else if (b[0] == kWikiQUOTE && e - b == 1) { // >
1843 WikiBlockQuote* obj;
1846 cur = obj = new WikiBlockQuote (this);
1847 blockp->push_back (cur);
1848 push_block (&obj->block);
1849 } else if (matchHead (b, e, CharConst ("{div:"))) {
1850 WikiBlockComplex* obj;
1853 cur = obj = new WikiBlockDiv (this);
1854 blockp->push_back (cur);
1855 cur->addLine (b, e);
1856 push_block (&obj->block);
1857 } else if (curform == NULL && matchHead (b, e, CharConst ("{form:"))) {
1858 WikiBlockComplex* obj;
1861 cur = obj = curform = new WikiBlockForm (this);
1862 blockp->push_back (cur);
1863 cur->addLine (b, e);
1864 push_block (&obj->block);
1865 } else if (matchHead (b, e, CharConst ("----"))) { // ----
1868 cur = new WikiBlockHR (this);
1869 blockp->push_back (cur);
1870 cur->addLine (b, e);
1873 if (cur && cur->type != WikiBlock::BlockParagraph) {
1878 cur = new WikiBlockParagraph (this);
1879 blockp->push_back (cur);
1881 cur->addLine (b, e);
1886 void WikiFormat::compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& spp, WikiLineScanner& scanner, WikiFormat* wiki, void* par), void* par) {
1889 while (wl = scanner.next ()) {
1890 if (fn && fn (*scanner.cur (), scanner, this, par)) {
1893 compileLine (scanner);
1898 int WikiFormat::countWikiH (uiterator& b, uiterator e) {
1901 while (b != e && *b == kWikiH) {
1910 bool WikiFormat::wikiURLParam (WikiMotorObjVecVec::const_iterator& b, WikiMotorObjVecVec::const_iterator e, bool& fscript, ustring& url) {
1913 if (outputLinkScript (b, e, url)) {
1917 if ((*b)->match (CharConst ("http"), CharConst ("https"))) {
1918 ustring proto = (*b)->dump ();
1924 if (! (*b)->splitURL_2 (this, proto, url)) {
1929 if (b < e && (*b)->splitURL_3 (this, url, url))
1931 } else if ((*b)->splitURLPath (this, url)) {
1943 bool WikiFormat::wikiURLParam (WikiMotorObjVecVec::const_iterator& b, WikiMotorObjVecVec::const_iterator e, bool& fscript, ustring& url, ustring& target) {
1944 if (wikiURLParam (b, e, fscript, url)) {
1945 if (! paramTarget (b, e, target))
1953 bool WikiFormat::outputLinkScript (WikiMotorObjVecVec::const_iterator& b, WikiMotorObjVecVec::const_iterator e, ustring& ans) {
1961 if ((*b)->size () == 1 && (*(*b))[0]->type == WikiMotorObj::wiki_text) {
1962 WikiMotorObjText* t = WikiMotorObjText_type ((*(*b))[0].get ());
1963 ustring* u = &t->text;
1964 if (wf = env->wikienv->wikiLink.getVar (*u)) {
1966 MotorOutputString out2;
1967 MotorOutput* back = env->output;
1969 vargs = buildArgs (b, e);
1970 env->output = &out2;
1972 node = execDefun (env->mlenv, wf, vargs ());
1973 } catch (ustring& msg) {
1974 logLispFunctionError (msg, *u);
1978 // ans = omitCtrl (out2.ans);
1985 bool WikiFormat::paramID (const ustring& key, WikiMotorObjVec& vval, ustring& var_id, bool& ferr) {
1986 if (match (key, CharConst ("id"))) {
1987 ustring value (vval.textOut (this));
1988 if (checkWikiID (value)) {
1992 errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad id\n"));
2001 bool WikiFormat::paramClass (const ustring& key, WikiMotorObjVec& vval, std::vector<ustring>& classes, bool& ferr) {
2002 if (match (key, CharConst ("class"))) {
2003 paramClassValue (vval, classes, ferr);
2010 void WikiFormat::paramClassValue (WikiMotorObjVec& vval, std::vector<ustring>& classes, bool& ferr) {
2011 WikiMotorObjVecVec args;
2013 vval.splitCharA (',', args);
2014 for (int i = 0; i < args.size (); i ++) {
2015 ustring value (args[i]->textOut (this));
2016 if (checkWikiID (value)) {
2017 classes.push_back (value);
2019 errorMsg.append (value).append (CharConst (": bad class name\n"));
2025 bool WikiFormat::paramWidth (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
2026 if (match (key, CharConst ("width"), CharConst ("w"))) {
2027 ustring value (vval.textOut (this));
2028 if (checkWidth (value)) {
2040 bool WikiFormat::paramHeight (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
2041 if (match (key, CharConst ("height"), CharConst ("h"))) {
2042 ustring value (vval.textOut (this));
2043 if (checkWidth (value)) {
2047 errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
2056 bool WikiFormat::paramSize (const char* name, size_t namelen, const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
2057 if (match (key, name, namelen)) {
2058 ustring value (vval.textOut (this));
2059 if (checkNum (value)) {
2070 void WikiFormat::paramUNum (const ustring& value, int& var, const ustring& name) {
2071 if (checkNum (value)) {
2072 var = strtoul (value);
2074 errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
2078 void WikiFormat::paramColor (const ustring& value, ustring& var, const ustring& name) {
2079 if (checkColor (value)) {
2082 errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
2086 bool WikiFormat::paramTarget (WikiMotorObjVecVec::const_iterator& b, WikiMotorObjVecVec::const_iterator e, ustring& target) {
2088 target = (*b)->textOut (this); // no LF
2089 if (! checkWikiID (target)) {
2090 errorMsg.append (target).append (CharConst (": bad target name.\n"));
2095 return true; // no error
2098 void WikiFormat::outputName (MotorOutput* out, const char* name, size_t len, const ustring& val, bool cond) {
2099 if (! cond || val.length () > 0)
2100 out->out_raw (uSPC)->out_raw (name, len)->out_raw (CharConst ("=\""))->out_toHTML_noCtrl (val)->out_raw (uQ2);
2103 void WikiFormat::outputName (MotorOutput* out, const char* name, size_t len, long val, bool cond) {
2104 if (! cond || val > 0)
2105 out->out_raw (uSPC)->out_raw (name, len)->out_raw (CharConst ("=\""))->out_raw (to_ustring (val))->out_raw (uQ2);
2108 void WikiFormat::outputFlag (MotorOutput* out, const char* name, size_t len, bool flag) {
2110 out->out_raw (uSPC)->out_raw (name, len)->out_raw (CharConst ("=\""))->out_raw (name, len)->out_raw (uQ2);
2113 void WikiFormat::outputID (MotorOutput* out, const ustring& id) {
2114 if (id.length () > 0)
2115 out->out_raw (CharConst (" id=\""))->out_toHTML_noCtrl (id)->out_raw (uQ2);
2118 void WikiFormat::outputClass (MotorOutput* out, std::vector<ustring>& classes) {
2119 if (classes.size () > 0) {
2120 out->out_raw (CharConst (" class=\""));
2121 for (int i = 0; i < classes.size (); i ++) {
2123 out->out_raw (uSPC);
2124 out->out_toHTML_noCtrl (classes[i]);
2130 void WikiFormat::wikiMotor (uiterator b, uiterator e, WikiMotorObjVec& ans) {
2131 WikiMotor motor (b, e, this);
2133 motor.compile (ans, WikiMotor::TMATCH_NONE);
2136 ustring WikiFormat::wikiMotor (uiterator b, uiterator e) {
2137 WikiMotorObjVec objv;
2139 wikiMotor (b, e, objv);
2140 return objv.htmlOut (this);
2143 MNode* WikiFormat::buildArgs (WikiMotorObjVecVec::const_iterator& b, WikiMotorObjVecVec::const_iterator e) {
2148 ans = a = new MNode;
2149 a->set_car (newMNode_str (new ustring ((*b)->textOut (this))));
2150 for (b ++; b < e; b ++) {
2152 a->set_car (newMNode_str (new ustring ((*b)->textOut (this))));
2158 void WikiFormat::logLispFunctionError (const ustring& msg, const ustring& cmd) {
2159 if (cmd.length () > 0)
2160 errorMsg.append (cmd).append (CharConst (": "));
2161 errorMsg.append (CharConst ("lisp function error.\n"));
2162 if (mlenv->env->mlenv->currentCell ()) {
2163 if (mlenv->env->log)
2164 *mlenv->env->log << mlenv->env->mlenv->currentCell ()->dump_string_short () << ": ";
2165 *mlenv->env->log << msg << uLF;
2169 /* ============================================================ */