/*
WIKIMOTORPRE: セットすると,フォーマット済みテキストブロックの中でインライン要素の解釈を行う。
UTF8JP: セットすると,条件によりパラグラフ内の改行を空白に置き換えない。
- TABLECOMPATFLAG: セットすると,旧形式の表の継続記号もゆるす。
+ WIKITABLECOMPATFLAG: セットすると,旧形式の表の継続記号もゆるす。
*/
#define kComment "//"
#define kWikiQUOTE '>'
#define kWikiQUOTE_e '<'
#define kWikiDIV '{'
+#define uWikiDIV "{div:"
+#define uWikiFORM "{form:"
+#define uWikiELEMENT "{element:"
#define kWikiDIV_e '}'
#define kWikiHR '-'
#define kWikiCmd '$'
+#define uWikiCmd "$"
#define uP "<p>"
#define uPe "</p>\n"
ustring uAWiki (CharConst ("@wiki_"));
/*DOC:
+$premode:1
==テキストの整形ルール==
*/
^行頭が他のマークアップ文字になるときは,行頭に^を書く。
空行は,段落を分ける。
+
+
+ 段落と段落の間に空行を2行以上入れると、「<div class="pggap"></div>」を出力する。
+
+{div:greenbox
+マークアップ文字以外の文字で書き出すと,段落になる。
+^行頭が他のマークアップ文字になるときは,行頭に^を書く。
+
+空行は,段落を分ける。
+
+
+段落と段落の間に空行を2行以上入れると、「<div class="pggap"></div>」を出力する。
+}
*/
bool WikiBlockParagraph::nextLine (uiterator b, uiterator e) {
/* ============================================================ */
/*DOC:
===タイトル===
+行頭に=を書くと,タイトルになる。行末の=は,省略可。
+
=タイトル1=
==タイトル2==
===タイトル3===#anchor1
-
-行頭に=を書くと,タイトルになる。行末の=は,省略可。
+{div:greenbox
+=タイトル1=
+==タイトル2==
+===タイトル3===#anchor1
+}
*/
wiki->cur->close ();
wiki->cur = NULL;
return CloseTrue;
+ default:;
}
}
+ default:;
}
}
// no opening point.
if (checkEmpty ())
return;
-// for (i = level0 + 1; i <= level; i ++) {
-// outputBeginDiv (i, out);
-// }
outputBeginDiv (level, out);
switch (level) {
case 1: out->out_raw (CharConst (uH1)); break;
case 6: out->out_raw (CharConst (uH6e)); break;
}
outputBlock (out);
-// for (i = level; i > level0; i --) {
-// outputEndDiv (i, out);
-// }
outputEndDiv (level, out);
}
===フォーマット済みテキストブロック===
行頭に空白文字を書くと,<pre>〜</pre>タグで囲まれます。
インライン要素の解釈は行われない。
+{div:greenbox
+ 行頭に空白文字を書くと,<pre>〜</pre>タグで囲まれます。
+}
*/
bool WikiBlockPreformatRaw::nextLine (uiterator b, uiterator e) {
void WikiBlockPreformatRaw::addLine (uiterator b, uiterator e) {
markup = *b;
-#ifdef WIKIMOTORPRE
- if (markup == ' ') {
- text.append (wiki->wikiMotor (b + 1, e));
- } else {
+
+ if (markup == ' ')
+ b ++;
+ if (wiki->motorPre) {
text.append (wiki->wikiMotor (b, e));
- }
- text.append (uLF);
-#else
- if (markup == ' ') {
- text.append (b + 1, e);
} else {
- text.append (b, e);
+ MotorOutputString o;
+ o.out_toHTML (ustring (b, e));
+ text.append (o.ans);
}
text.append (uLF);
-#endif
}
void WikiBlockPreformatRaw::output (MotorOutput* out) {
-#ifdef WIKIMOTORPRE
out->out_raw (CharConst ("<pre>"))->out_toText (text)->out_raw (CharConst ("</pre>\n"));
-#else
- out->out_raw (CharConst ("<pre>"))->out_toHTML (text)->out_raw (CharConst ("</pre>\n"));
-#endif
}
/* ============================================================ */
if (indentHack) {
outputBlock (out);
} else {
- out->out_raw (CharConst ("<li"));
- attrib.output (out);
- out->out_raw (CharConst (">"));
- out->out_toText (html);
- outputBlock (out);
- out->out_raw (CharConst ("</li>\n"));
+ if (html.length () > 0) {
+ out->out_raw (CharConst ("<li"));
+ attrib.output (out);
+ out->out_raw (CharConst (">"));
+ out->out_toText (html);
+ outputBlock (out);
+ out->out_raw (CharConst ("</li>\n"));
+ } else {
+ outputBlock (out);
+ }
}
}
/* ============================================================ */
/*DOC:
===箇条書き===
-{div:pre
-+&*;項目1
-+&*;*項目1-1
-+&#;ナンバリング1
-+&#;#ナンバリング1-2
-+&+;インデント1
-+&+;+インデント1-1
-+&*;''[OPTION1:OPTION2:...:]''TEXT
-}
+ *項目1
+ **項目1-1
+ #ナンバリング1
+ ##ナンバリング1-2
+ +インデント1
+ ++インデント1-1
+ *''[OPTION1:OPTION2:...:]''TEXT
+ *id=item1:class=style1:onclick=[[ignore:]]:TEXT
+
行頭に「*」を書くと,<UL>タグによるリスト,「#」を書くと<NL>タグによる番号付きリスト,「+」を書くとnobullクラス指定の<UL>タグによるリスト。
-|h:オプション|
-|id=''ID''|
-|class=''CLASS,...''|
-|onclick=''LINK-FUNCTION:PARAM1:...::''|
+オプションパラメータ
+|table:w=100%|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|'''start='''''Number''||start属性。OLのみ。|
+
+{div:greenbox
+*項目1
+**項目1-1
+#ナンバリング1
+##ナンバリング1-2
++インデント1
+++インデント1-1
+*id=item1:class=style1:onclick=[[ignore:]]:TEXT
+}
*/
bool WikiBlockItem::nextLine (uiterator b, uiterator e) {
assert (b != e && b[0] == ch);
b ++;
if (b == e) {
- wbt = new WikiBlockItemText (wiki);
+ wbt = new WikiBlockItemText (wiki, this);
block.push_back (wbt);
wbt->addLine (b, e);
} else {
case kWikiOL: // #
wbi = new WikiBlockItem (WikiBlock::BlockItemOL, wiki);
break;
- case kWikiNL: // ]
+ case kWikiNL: // +
wbi = new WikiBlockItem (WikiBlock::BlockItemNL, wiki);
break;
default:
wbi->addLine (b, e);
wbt->block.push_back (wbi);
} else {
- wbt = new WikiBlockItemText (wiki);
+ wbt = new WikiBlockItemText (wiki, this);
block.push_back (wbt);
wbi->addLine (b, e);
wbt->block.push_back (wbi);
wbt->indentHack = true;
}
} else {
- wbt = new WikiBlockItemText (wiki);
+ wbt = new WikiBlockItemText (wiki, this);
block.push_back (wbt);
wbt->addLine (b, e);
}
switch (type) {
case BlockItemUL:
- out->out_raw (CharConst ("<ul>\n"));
+ out->out_raw (CharConst ("<ul"));
+ attrib.output (out);
+ out->out_raw (CharConst (">\n"));
outputBlock (out);
out->out_raw (CharConst ("</ul>\n"));
break;
case BlockItemOL:
- out->out_raw (CharConst ("<ol>\n"));
+ out->out_raw (CharConst ("<ol"));
+ attrib.output (out);
+ out->out_raw (CharConst (">\n"));
outputBlock (out);
out->out_raw (CharConst ("</ol>\n"));
break;
case BlockItemNL:
- out->out_raw (CharConst ("<ul class=\"nobull\">\n"));
+ out->out_raw (CharConst ("<ul"));
+ attrib.classlist.push_back (ustring (CharConst ("nobull")));
+ attrib.output (out);
+ attrib.classlist.pop_back ();
+ out->out_raw (CharConst (">\n"));
outputBlock (out);
out->out_raw (CharConst ("</ul>\n"));
break;
===定義リスト===
;見出し:説明文
+{div:greenbox
+;見出し:説明文
+}
+
*/
bool WikiBlockItemDL::nextLine (uiterator b, uiterator e) {
if (*b == kWikiDL) {
表定義の最初の行の最初のカラムに「table:」を書くと,この行はテーブルオプション指定行になる。属性指定の後にテキストを書くと,表のキャプションになる。
2番目以降のカラムは,デフォルトのカラムオプション指定になる。
-|table:||c:||
-|h:名前|h:省略形|h:意味|
-|noborder|nb|border="0"を出力する。|
-|cellspacing=''integer''|spc=|cellspacing属性を出力する。|
-|cellpadding=''integer''||cellpadding属性を出力する。|
-|padding|pad|テーブルの最大のカラム数よりカラムが少ない行に,空のカラムを追加する。|
-|expanding|expand|テーブルの最大のカラム数よりカラムが少ない行の最後のカラムを引き延ばす。|
-|center|c|テーブルをセンタリングする。|
-|left|l|テーブルを左寄せする。|
-|right|r|テーブルを右寄せする。|
-|id=''name''||id属性を出力する。|
-|class=''name,name,...''||class属性を出力する。|
-|width=''number'', width=''number''%|w=|width属性を出力する。|
-|bgcolor=#''color''|bg=|bgcolor属性を出力する。|
-|onclick=''fn(arg1,arg2,...)''||onClick属性を出力する。''name''はdefun-wiki-linkで定義したもの。|
-|nowhite|nw||
-|turn||セルの並びの横方向と縦方向を交換する。|
-|toptitle|tt|class=toptitleと同じ。|
-|bottomtitle|bt|class=bottomtitleと同じ。|
+|table:w=100%:テーブルオプション|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|'''width='''''Size''|'''w='''|width属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
+//|'''height='''''Size''|'''h='''|height属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
+|'''bgcolor='''''Color''|'''bg='''|bgcolor属性。|
+|'''cellspacing='''''Integer''|'''spc='''|cellspacing属性。*コンパイル時設定による。|
+|'''cellpadding='''''Integer''||cellpadding属性。*コンパイル時設定による。|
+|'''left'''|'''l'''|align="left"属性。|
+|'''right'''|'''r'''|align="right"属性。|
+|'''center'''|'''c'''|align="center"属性。|
+|'''noborder'''|''nb''|border="0"属性。|
+|'''padding'''|'''pad'''|行のカラム定義が最大カラム数に満たない時,空のカラムを追加する。|
+|'''expanding'''|'''expand'''|行のカラム定義が最大カラム数に満たない時,最終カラムを伸ばす。|
+|'''nowhite'''|'''nw'''|空セルにnbspを出力する。|
+|'''turn'''||表の行と列を入れ替える。|
+・行オプション
|row:bgcolor=#ff0|&[;&[;Name]]|&[;&[;Value]]|
行オプションで指定できる属性はセルオプションと同じものである。
+・セルオプション
- |header:名前|class=big:東武|
- |header:
-|table:||c:||
-|h:名前|h:省略形|h:意味|
-|header|h|ヘッダタグ(<th>)を出力する。|
-|left|l|セル内で左寄せする。|
-|right|r|右寄せする。|
-|center|c|横方向で中央あわせする。|
-|top|t|セル内で上寄せする。|
-|middle|m|縦方向で中央あわせする。|
-|bottom|b|下寄せする。|
-|nowrap|nw|セル内での折り返しを禁止する。|
-|*||デフォルトのセルオプションを含め,全てのセルオプションを破棄する。|
-|id=''name''||セルタグにid属性を付加する。|
-|class=''name,name,...''||セルタグにclass属性を付加する。|
-|width=''number''&|;''number''%||セルタグにwidth属性を付加する。|
-|height=''number''&|;''number''%||セルタグにheight属性を付加する。|
-|bgcolor=#''hex''|bg=|セルタグにbg属性を付加する。|
-|onclick=''fn(arg1,arg2,...)''||onClick属性を出力する。''name''はdefun-wiki-linkで定義したもの。|
+// |header:名前|class=big:東武|
+// |header:
+
+|table:w=100%:行オプション,セルオプション|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|'''width='''''Size''|'''w='''|width属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
+|'''height='''''Size''|'''h='''|height属性。単位はpx, pt, in, mm, cm, em, ex。または%。|
+|'''bgcolor='''''Color''|'''bg='''|bgcolor属性。|
+|'''header'''|'''h'''|thタグを出力する。|
+|'''left'''|'''l'''|align="left"属性。|
+|'''right'''|'''r'''|align="right"属性。|
+|'''center'''|'''c'''|align="center"属性。|
+|'''top'''|'''t'''|valign="top"属性。|
+|'''middle'''|'''m'''|valign="middle"属性。|
+|'''bottom'''|'''b'''|valign="bottom"属性。|
+|'''nowrap'''|'''nw'''|nowrap属性。|
+|'''*'''||オプションのクリア。|
|h:結合記号|h:意味|
|&<;|左のセルと結合する。|
out->out_raw (CharConst ("<th"));
else
out->out_raw (CharConst ("<td"));
- cellattrib.output (out);
+ bool foutputwidth = (! fturn && colspan == 1) || (fturn && rowspan == 1);
+ cellattrib.outputCell (out, foutputwidth);
if (fturn) {
if (colspan > 1)
wiki->outputName (out, CharConst ("rowspan"), colspan, false);
}
WikiBlock::closeType WikiBlockTable::closeLine (uiterator b, uiterator e) {
-#ifdef TABLECOMPATFLAG
+#ifdef WIKITABLECOMPATFLAG
static uregex re ("^\\}\\}(($)|(\\|)|((!([1-9][0-9]*))?(\\\\|&)$))");
#else
static uregex re ("^\\}\\}(($)|(\\|)|((!([1-9][0-9]*))?(&)$))");
CellList_t* cols;
bool fmorecell = false;
umatch m;
-#ifdef TABLECOMPATFLAG
+#ifdef WIKITABLECOMPATFLAG
static uregex re ("(!([1-9][0-9]*))?(\\\\|&)$");
#else
static uregex re ("(!([1-9][0-9]*))?(&)$");
void WikiBlockTable::outputTableTag (MotorOutput* out) {
int i;
+#ifdef WIKITABLEATTRIB
if (attrib.cellspacing < 0)
attrib.cellspacing = 0;
if (attrib.cellpadding < 0)
attrib.cellpadding = 0;
+#endif
out->out_raw (CharConst ("<table"));
attrib.output (out);
out->out_raw (CharConst (">\n"));
|VALUE|
|LABEL|VALUE|selected|
+オプションパラメータ
+|table:w=100%|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|'''size='''''Integer''||size属性。|
+|'''multiple'''||multiple属性。|
+
*/
bool WikiBlockSelect::nextLine (uiterator b, uiterator e) {
if (*b == kWikiTABLE) {
out->out_raw (CharConst (">\n"));
if (attrib.fdefault)
- u = wiki->getVar (name);
+ u = wiki->getVar_string (name);
#ifdef DEBUG2
std::cerr << "u:" << u << uLF;
#endif /* DEBUG */
/* ============================================================ */
/*DOC:
===DIVタグ===
- {div:SideMenu
+ {div:''ClassName''
...
}
- {div:id=Name:SideMenu:onclick=fn()
+ {div:id=''ID'':''ClassName'':onclick=''LinkFunction''
...
}
+オプションパラメータ
+|table:w=100%|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|''ClassList''||class=は省略できる。|
+|'''#nop'''||divタグを出力しない。pタグを抑制する。|
+
*/
bool WikiBlockDiv::nextLine (uiterator b, uiterator e) {
return false;
}
void WikiBlockDiv::addLine (uiterator b, uiterator e) {
- bool rc = matchSkip (b, e, CharConst ("{div:"));
+ bool rc = matchSkip (b, e, CharConst (uWikiDIV)); // {div:
assert (rc);
WikiMotor motor (b, e, wiki);
WikiMotorObjVecPtr vec (new WikiMotorObjVec);
motor.compile (*vec);
attrib.shiftAttrib (vec);
+ {
+ std::vector<ustring>::const_iterator b = attrib.directlist.begin ();
+ std::vector<ustring>::const_iterator e = attrib.directlist.end ();
+ for (; b < e; ++ b) {
+ if (match (*b, CharConst ("#nop"))) {
+ nopflag = true;
+ } else {
+ wiki->errorMsg.append (*b).append (CharConst (": bad attribute.\n"));
+ }
+ }
+ }
}
WikiBlock::closeType WikiBlockDiv::closeLine (uiterator b, uiterator e) {
void WikiBlockDiv::output (MotorOutput* out) {
bool nonl = false;
- if (block.size () == 1 && block[0].type == BlockParagraph) {
- WikiBlockParagraph* b = WikiBlockParagraph_type (&block[0]);
- if (! b->pflag) {
- b->singleTag = true;
- nonl = true;
+ if (nopflag) {
+ boost::ptr_vector<WikiBlock>::iterator b = block.begin ();
+ boost::ptr_vector<WikiBlock>::iterator e = block.end ();
+ for (; b < e; ++ b) {
+ if (b->type == BlockParagraph) {
+ WikiBlockParagraph* p = WikiBlockParagraph_type (&(*b));
+ if (! p->pflag) {
+ p->singleTag = true;
+ nonl = true;
+ }
+ }
}
+ } else {
+ if (block.size () == 1 && block[0].type == BlockParagraph) {
+ WikiBlockParagraph* b = WikiBlockParagraph_type (&block[0]);
+ if (! b->pflag) {
+ b->singleTag = true;
+ nonl = true;
+ }
+ }
+ out->out_raw (CharConst ("<div"));
+ attrib.output (out);
+ if (nonl)
+ out->out_raw (CharConst (">"));
+ else
+ out->out_raw (CharConst (">\n"));
}
- out->out_raw (CharConst ("<div"));
- attrib.output (out);
- if (nonl)
- out->out_raw (CharConst (">"));
- else
- out->out_raw (CharConst (">\n"));
outputBlock (out);
- out->out_raw (CharConst ("</div>\n"));
+ if (! nopflag) {
+ out->out_raw (CharConst ("</div>\n"));
+ } else {
+ out->out_raw (uLF);
+ }
}
/* ============================================================ */
/*DOC:
===FORMタグ===
- {form:POST:post.hml
+ {form:POST:''URL''
...
}
-// {form:POST:id=form1:class=formclass:post.hml
-// {form:POST:post.hml:id=form1:class=formclass
- {form:POST:post.hml:target=target_window:id=form1:class=formclass
+ {form:POST:''URL'':target=''TargetWindow'':id=''ID'':class=''ClassName''
...
}
+オプションパラメータ
+|table:w=100%|t:w=20%|c:w=10%|t:|
+|h:オプション|h:省略形|h:説明|
+|'''id='''''ID''||id属性。|
+|'''class='''''ClassList''||class属性。複数のクラスを指定する場合はコンマ区切りで連ねる。|
+//|'''data-'''''name'''''='''''ID''||Bootstrap用属性。|
+|'''onclick='''''Link''||onclick属性。Javascriptリンク。|
+|'''onfocus='''''Link''||onfocus属性。Javascriptリンク。|
+|'''onblur='''''Link''||onblur属性。Javascriptリンク。|
+|'''onchange='''''Link''||onchange属性。Javascriptリンク。|
+|'''target='''''Window''||target属性。|
+
*/
bool WikiBlockForm::nextLine (uiterator b, uiterator e) {
return false;
}
void WikiBlockForm::addLine (uiterator b, uiterator e) {
- bool rc = matchSkip (b, e, CharConst ("{form:"));
+// bool rc = matchSkip (b, e, CharConst ("{form:"));
+ bool rc = matchSkip (b, e, CharConst (uWikiFORM));
assert (rc);
-
WikiMotor motor (b, e, wiki);
WikiMotorObjVecPtr vec (new WikiMotorObjVec);
ustring key;
/* ============================================================ */
/*DOC:
+===Elementブロック===
+ {element:''Name''
+ ...
+ }
+
+Wikiテキストの名前付きブロック。
+
+*/
+bool WikiBlockElement::nextLine (uiterator b, uiterator e) {
+ return false;
+}
+
+void WikiBlockElement::addLine (uiterator b, uiterator e) {
+ bool rc = matchSkip (b, e, CharConst (uWikiELEMENT));
+ assert (rc);
+ WikiMotor motor (b, e, wiki);
+ WikiMotorObjVecPtr vec (new WikiMotorObjVec);
+ WikiMotorObjVecPtr v2 (new WikiMotorObjVec);
+
+ motor.compile (*vec);
+ vec->splitChar_keyword (':', name, *v2);
+ if (name.size () == 0) {
+ wiki->errorMsg.append (CharConst ("missing name in the element block."));
+ }
+ if (v2->size () > 0) {
+ wiki->errorMsg.append (v2->dump ()).append (CharConst (": bad attribute.\n"));
+ }
+ if (name.size () > 0) {
+ wiki->elementMap.put (name, this);
+ }
+}
+
+WikiBlock::closeType WikiBlockElement::closeLine (uiterator b, uiterator e) {
+ if (e - b == 1 && *b == kWikiDIV_e) {
+ wiki->pop_block ();
+ wiki->cur = NULL;
+ return CloseTrue;
+ } else {
+ return CloseFalse;
+ }
+}
+
+void WikiBlockElement::output (MotorOutput* out) {
+//*** outputBlock (out);
+}
+
+/* ============================================================ */
+/*DOC:
===水平線===
----
}
/* ============================================================ */
+bool WikiBlockBlank::nextLine (uiterator b, uiterator e) {
+ if (b == e) {
+ count ++;
+ return true;
+ } else {
+ switch (*b) { // paragraph以外の全て
+ case kWikiH:
+ case kWikiPRE:
+ case kWikiPRE2:
+ case kWikiUL:
+ case kWikiOL:
+ case kWikiNL:
+ case kWikiDL:
+ case kWikiTABLE:
+ count = 0;
+ break;
+ default:
+ if ((*b == kWikiQUOTE && e - b == 1) ||
+ matchHead (b, e, CharConst (uWikiDIV)) ||
+ (wiki->curform == NULL && matchHead (b, e, CharConst (uWikiFORM))) ||
+ (wiki->curform == NULL && matchHead (b, e, CharConst (uWikiELEMENT))) ||
+ matchHead (b, e, CharConst ("----"))) {
+ count = 0;
+ } else {
+ if (count >= 2)
+ enable = true;
+ }
+ }
+ return false;
+ }
+}
+
+void WikiBlockBlank::addLine (uiterator b, uiterator e) {
+ count ++;
+}
+
+void WikiBlockBlank::output (MotorOutput* out) {
+ if (enable) {
+ out->out_raw (CharConst ("<div class=\"pggap\"></div>\n"));
+ }
+}
+
+/* ============================================================ */
void WikiFormat::pass1 (const ustring& text, WikiLine::linevec* block, bool fsuper) {
- Splitter sp (text, re_nl);
+ SplitterNL sp (text);
pass1_1 (sp, NULL, NULL, block, NULL, NULL, NULL, fsuper);
}
+static bool findCmdSep (uiterator& b, uiterator e, uiterator& u) {
+ int c;
+ uiterator p = b;
+ for (; p < e; ++ p) {
+ c = *p;
+ if (c == ':') {
+ b = p;
+ u = b + 1;
+ return true;
+ } else if (c == ' ' || c == '\t') {
+ b = p;
+ u = b;
+ do {
+ ++ u;
+ } while (u < e && ((c = *u) == ' ' || c == '\t'));
+ return true;
+ }
+ }
+ b = p;
+ u = e;
+ return true;
+}
+
int WikiFormat::pass1_1 (Splitter& sp, ustring* elseword, ustring* endword, WikiLine::linevec* block, uiterator* elsebegin0, uiterator* elsebegin, uiterator* elseend, bool fsuper) {
uiterator b, e, t, u, v;
- umatch m;
while (sp.next ()) {
b = sp.begin ();
e = sp.end ();
- while (b < e && b[0] == '\t')
+ while (b < e && b[0] == '\t') // TABを無視
b ++;
if (matchSkip (b, e, CharConst (kComment))) {
// comment
} else if (b != e && b[0] == kWikiCmd) {
- if (usearch (b, e, m, re_wikicmdsep)) {
- t = b;
- u = m[0].first;
- v = m[0].second;
+ t = b;
+ u = b;
+ if (findCmdSep (u, e, v)) {
} else {
- t = b;
u = e;
v = e;
}
// 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;
}
}
+void WikiFormat::outputElement (const ustring& elementName) {
+ WikiBlockElement* b;
+
+ b = elementMap.get (elementName);
+ if (b) {
+ output (b->block);
+ }
+}
+
void WikiFormat::output (boost::ptr_vector<WikiBlock>& ary) {
int i;
return true;
case WikiBlock::CloseFalse:
return false;
+ default:;
}
}
return false;
WikiLine* wl = scanner.cur ();
if (! wl)
return;
-
- uiterator b = wl->begin;
- uiterator e = wl->end;
-
if (wl->fn) {
wl->fn (wl, this);
} else {
+ uiterator b = wl->begin;
+ uiterator e = wl->end;
+
if (b == e) { // empty line
if (cur) {
- cur->close ();
- cur = NULL;
+ switch (cur->type) {
+ case WikiBlock::BlockParagraph:
+ cur->close ();
+ cur = new WikiBlockBlank (this);
+ blockp->push_back (cur);
+ cur->addLine (b, e);
+ break;
+ case WikiBlock::BlockBlank:
+ cur->addLine (b, e);
+ break;
+ default:
+ cur->close ();
+ cur = NULL;
+ }
}
} else if (matchSkip (b, e, CharConst ("//"))) { // comment
} else if (checkClose (b, e)) {
cur = obj = new WikiBlockItem (WikiBlock::BlockItemOL, this);
blockp->push_back (cur);
obj->addLine (b, e);
- } else if (b[0] == kWikiNL) { // ]
+ } else if (b[0] == kWikiNL) { // +
WikiBlockItem* obj;
if (cur)
cur->close ();
cur = new WikiBlockParagraph (this);
blockp->push_back (cur);
}
- push_block (NULL);
+ push_block (blockp);
cur = new WikiBlockSelect (this);
cur->addLine (b, e);
} else if (b[0] == kWikiTABLE) { // |
cur = obj = new WikiBlockQuote (this);
blockp->push_back (cur);
push_block (&obj->block);
- } else if (matchHead (b, e, CharConst ("{div:"))) {
+// } else if (matchHead (b, e, CharConst ("{div:"))) {
+ } else if (matchHead (b, e, CharConst (uWikiDIV))) {
WikiBlockComplex* obj;
if (cur)
cur->close ();
blockp->push_back (cur);
cur->addLine (b, e);
push_block (&obj->block);
- } else if (curform == NULL && matchHead (b, e, CharConst ("{form:"))) {
+ } else if (curform == NULL && matchHead (b, e, CharConst (uWikiFORM))) {
WikiBlockComplex* obj;
if (cur)
cur->close ();
blockp->push_back (cur);
cur->addLine (b, e);
push_block (&obj->block);
+ } else if (curform == NULL && matchHead (b, e, CharConst (uWikiELEMENT))) {
+ WikiBlockComplex* obj;
+ if (cur)
+ cur->close ();
+ cur = obj = new WikiBlockElement (this);
+ blockp->push_back (cur);
+ cur->addLine (b, e);
+ push_block (&obj->block);
} else if (matchHead (b, e, CharConst ("----"))) { // ----
if (cur)
cur->close ();
void WikiFormat::compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& spp, WikiLineScanner& scanner, WikiFormat* wiki, void* par), void* par) {
WikiLine* wl;
- while (wl = scanner.next ()) {
+ while ((wl = scanner.next ())) {
if (fn && fn (*scanner.cur (), scanner, this, par)) {
break;
} else {
return ans;
}
-bool WikiFormat::paramID (const ustring& key, WikiMotorObjVec& vval, ustring& var_id, bool& ferr) {
- if (match (key, CharConst ("id"))) {
- ustring value (vval.textOut (this));
- if (value.length () > 0) {
- if (checkWikiID (value)) {
- var_id = value;
- ferr = false;
- } else {
- errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad id\n"));
- ferr = true;
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool WikiFormat::paramClass (const ustring& key, WikiMotorObjVec& vval, std::vector<ustring>& classes, bool& ferr) {
- if (match (key, CharConst ("class"))) {
- paramClassValue (vval, classes, ferr);
- return true;
- } else {
- return false;
- }
-}
-
-void WikiFormat::paramClassValue (WikiMotorObjVec& vval, std::vector<ustring>& classes, bool& ferr) {
- WikiMotorObjVecVec args;
- ferr = false;
- vval.splitCharA (',', args);
- for (int i = 0; i < args.size (); i ++) {
- ustring value (args[i]->textOut (this));
- if (value.length () > 0) {
- if (checkWikiID (value)) {
- classes.push_back (value);
- } else {
- errorMsg.append (value).append (CharConst (": bad class name\n"));
- ferr = true;
- }
- }
- }
-}
-
-bool WikiFormat::paramName (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
- if (match (key, CharConst ("name"))) {
- ustring value (vval.textOut (this));
- if (checkWikiID (value)) {
- var = value;
- ferr = false;
- } else {
- ferr = true;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool WikiFormat::paramWidth (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
- if (match (key, CharConst ("width"), CharConst ("w"))) {
- ustring value (vval.textOut (this));
- if (checkWidth (value)) {
- var = value;
-// if (checkNum (value))
-// var.append (CharConst ("px"));
- ferr = false;
- } else {
- ferr = true;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool WikiFormat::paramHeight (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
- if (match (key, CharConst ("height"), CharConst ("h"))) {
- ustring value (vval.textOut (this));
- if (checkWidth (value)) {
- var = value;
- ferr = false;
- } else {
- errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
- ferr = true;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool WikiFormat::paramSize (const char* name, size_t namelen, const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
- if (match (key, name, namelen)) {
- ustring value (vval.textOut (this));
- if (checkNum (value)) {
- var = value;
- ferr = false;
- } else {
- ferr = true;
- }
- return true;
- }
- return false;
-}
-
-void WikiFormat::paramUNum (const ustring& value, int& var, const ustring& name) {
- if (checkNum (value)) {
- var = strtoul (value);
- } else {
- errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
- }
-}
-
-void WikiFormat::paramColor (const ustring& value, ustring& var, const ustring& name) {
- if (checkColor (value)) {
- var = value;
- } else {
- errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
- }
-}
-
-bool WikiFormat::paramTargetCheck (const ustring& key) {
- return match (key, CharConst ("target"));
-}
-
-void WikiFormat::paramTargetBody (const ustring& key, const ustring& value, ustring& var, bool& ferr) {
- if (value.length () == 0 || checkWikiID (value)) {
- var = value;
- } else {
- if (key.length () > 0)
- errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad target name.\n"));
- else
- errorMsg.append (value).append (CharConst (": bad target name.\n"));
- ferr = true;
- }
-}
-
-bool WikiFormat::paramOnClickCheck (const ustring& name) {
- return match (name, CharConst ("onclick"));
-}
-
-bool WikiFormat::paramOnFocusCheck (const ustring& name) {
- return match (name, CharConst ("onfocus"));
-}
-
-bool WikiFormat::paramOnBlurCheck (const ustring& name) {
- return match (name, CharConst ("onblur"));
-}
-
-bool WikiFormat::paramOnChangeCheck (const ustring& name) {
- return match (name, CharConst ("onchange"));
-}
-
void WikiFormat::outputName (MotorOutput* out, const char* name, size_t len, const ustring& val, bool cond) {
if (! cond || val.length () > 0)
out->out_raw (uSPC)
}
}
+void WikiFormat::outputNum (MotorOutput* out, const char* name, size_t len, int val) {
+ out->out_raw (uSPC)
+ ->out_raw (name, len)
+ ->out_raw (CharConst ("="))
+ ->out_raw (to_ustring (val));
+}
+
+MNode* WikiFormat::arrayToTexp (const ustring& name) {
+ size_t i, n;
+ MNodeList e;
+
+ n = mlenv->getArySize (name);
+ for (i = 1; i <= n; i ++) {
+ e.append (mlenv->getAry (name, i));
+ }
+ return mlenv->retval = e ();
+}
+
+MNode* WikiFormat::evalVar (const ustring& name) {
+ // @NAME → getarray
+ // NAME → getvar
+ ustring sym;
+ if (checkAry (name, sym)) {
+ return arrayToTexp (sym);
+ } else {
+ return mlenv->getVar (name);
+ }
+}
+
void WikiFormat::wikiMotor (uiterator b, uiterator e, WikiMotorObjVec& ans) {
WikiMotor motor (b, e, this);
AutoInclCount autoIncl (env->mlenv);
objv.eval (ans, this);
}
-#if 0
-void WikiFormat::wikiMotorEval (uiterator b, uiterator e, WikiMotorObjVec& ans) {
- ans.push_back (WikiMotorObjPtr (new WikiMotorObjHtml (wikiMotor (b, e))));
-}
-#endif
-
-MNode* WikiFormat::buildArgs (WikiMotorObjVecVec::const_iterator b, WikiMotorObjVecVec::const_iterator e, bool dumpmode) {
+MNode* WikiFormat::buildArgs (WikiMotorObjVecVec::const_iterator b, WikiMotorObjVecVec::const_iterator e) {
MNodeList ans;
- if (dumpmode) {
- for (; b < e; b ++) {
- ans.append (newMNode_str (new ustring ((*b)->dump ())));
- }
- } else {
- for (; b < e; b ++) {
- ans.append (newMNode_str (new ustring ((*b)->textOut (this))));
- }
+ for (; b < e; b ++) {
+ ans.append ((*b)->toMNode (this));
}
return ans.release ();
}
}
+/*DOC:
+$premode:
+*/
/* ============================================================ */