1 // ================================================================================================
3 // MediaWikiのページを解析するパーサークラスソース</summary>
5 // <copyright file="MediaWikiParser.cs" company="honeplusのメモ帳">
6 // Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
9 // ================================================================================================
11 namespace Honememo.Wptscs.Parsers
14 using System.Collections.Generic;
16 using Honememo.Parsers;
17 using Honememo.Utilities;
18 using Honememo.Wptscs.Websites;
21 /// MediaWikiのページを解析するパーサークラスです。
23 public class MediaWikiParser : XmlParser
28 /// このパーサーが対応するMediaWiki。
30 private MediaWiki website;
37 /// 指定されたMediaWikiサーバーのページを解析するためのパーサーを作成する。
39 /// <param name="site">このパーサーが対応するMediaWiki</param>
40 public MediaWikiParser(MediaWiki site)
43 this.CommentParser = new XmlCommentElementParser();
44 this.NowikiParser = new MediaWikiNowikiParser(this);
45 this.LinkParser = new MediaWikiLinkParser(this);
46 this.TemplateParser = new MediaWikiTemplateParser(this);
47 this.VariableParser = new MediaWikiVariableParser(this);
48 this.HeadingParser = new MediaWikiHeadingParser(this);
56 /// このパーサーが対応するMediaWiki。
58 /// <exception cref="ArgumentNullException"><c>null</c>が指定された場合。</exception>
59 public MediaWiki Website
68 this.website = Validate.NotNull(value);
76 // ※ 各要素のパーサーについては相互参照しているものが多々あり、
77 // 個別のクラスでnewされると危険なことから、ここで生成して公開する。
80 /// パーサー内で使用するXMLコメント要素のパーサー。
82 internal IParser CommentParser
89 /// パーサー内で使用するnowikiブロックのパーサー。
91 internal IParser NowikiParser
98 /// パーサー内で使用するMediaWiki内部リンクのパーサー。
100 internal IParser LinkParser
107 /// パーサー内で使用するMediaWikiテンプレートのパーサー。
109 internal IParser TemplateParser
116 /// パーサー内で使用するMediaWiki変数のパーサー。
118 internal IParser VariableParser
125 /// パーサー内で使用するMediaWiki変数のパーサー。
127 internal IParser HeadingParser
135 #region インタフェース実装メソッド
138 /// 渡されたMediaWikiページに対して、指定された終了条件を満たすまで解析を行う。
140 /// <param name="s">解析対象の文字列。</param>
141 /// <param name="condition">解析を終了するかの判定を行うデリゲート。</param>
142 /// <param name="result">解析結果。</param>
143 /// <returns>解析に成功した場合<c>true</c>。</returns>
144 /// <remarks>指定された終了条件を満たさない場合、最終位置まで解析を行う。</remarks>
145 public override bool TryParseToEndCondition(string s, IsEndCondition condition, out IElement result)
147 // 文字列を1文字ずつチェックし、その内容に応じた要素のリストを作成する
148 ListElement list = new ListElement();
149 StringBuilder b = new StringBuilder();
150 bool newLine = false;
151 for (int i = 0; i < s.Length; i++)
153 // 終了条件のチェック、未指定時は条件なし
154 if (condition != null && condition(s, i))
159 IElement innerElement;
163 // 改行の場合、次回に見出しの解析が必要なため記録
172 if (this.TryParseAt(s, i, out innerElement, this.HeadingParser))
174 // それまでに解析済みのテキストを吐き出し、
176 this.FlashText(ref list, ref b);
177 list.Add(innerElement);
178 i += innerElement.ToString().Length - 1;
184 if (this.TryParseAt(s, i, out innerElement, this.CommentParser))
186 // それまでに解析済みのテキストを吐き出し、
188 this.FlashText(ref list, ref b);
189 list.Add(innerElement);
190 i += innerElement.ToString().Length - 1;
192 // コメント中に改行が含まれた場合も、見出しの処理を有効化する
193 if (innerElement.ToString().Contains("\n"))
201 // それ以外のnowiki, 変数, 内部リンク, テンプレートの各要素のTryParse処理を呼び出し
209 this.TemplateParser))
211 // それまでに解析済みのテキストを吐き出し、
213 this.FlashText(ref list, ref b);
214 list.Add(innerElement);
215 i += innerElement.ToString().Length - 1;
219 // 通常の文字列はテキスト要素として積み上げる
223 // 残っていれば最後に解析済みのテキストを吐き出し
224 this.FlashText(ref list, ref b);
229 // リストが1件であれば、その要素を直に返す
232 else if (list.Count == 0)
234 // 何もなければ、空文字列だったものとして空のテキスト要素を返す
235 result = new TextElement();