2 * Copyright (C) 2009 by Aiwota Programmer
3 * aiwotaprog@tetteke.tk
5 * This file is part of Dialektos.
7 * Dialektos is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * Dialektos is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef DAT_PARSER_HXX
22 #define DAT_PARSER_HXX
27 #include <boost/range.hpp>
28 #include <boost/algorithm/string.hpp>
34 /*! @brief DAT parser.
36 Supply text representing one 'res'.
37 Once parsing the 'res', the object must not be re-used.
38 You should prepare new object for next 'res'.
39 Template argument 'BufferBuilderT' must have interfaces
41 class BufferBuilderT {
43 void add_text(range, bold, href);
44 void add_id(range, bold, id);
45 void add_res_num(res_num, bold);
46 void new_line(left_margin);
49 here 'range' is Boost.Range concepts.
50 DriverT is HTML parser driver template and
51 FunctionT is HTML parser functions template.
53 template <typename BufferBuilderT,
54 template <typename> class HtmlParserDriverT,
55 template <typename> class HtmlParserFunctionT>
57 public HtmlParserDriverT<HtmlParserFunctionT<
58 DatParser<BufferBuilderT, HtmlParserDriverT, HtmlParserFunctionT> > > {
60 typedef DatParser<BufferBuilderT,
61 HtmlParserDriverT, HtmlParserFunctionT> ThisClass;
62 typedef HtmlParserDriverT<HtmlParserFunctionT<ThisClass> > SuperClass;
63 using SuperClass::parse_html;
65 BufferBuilderT& buffer_builder_;
73 /*! @brief constructor. */
74 explicit DatParser(BufferBuilderT& view, int res_num):
75 buffer_builder_(view), res_num_(res_num), left_margin_(1), bold_(false),
79 /*! @brief Supply text representing one 'res'. */
80 template<typename RangeT>
81 void operator()(const RangeT& range) {
82 drive_res_line(range);
86 /*! @brief implementing FunctionT::on_data */
87 template <typename RangeT>
88 void on_data(const RangeT& range) {
89 buffer_ += std::string(boost::begin(range), boost::end(range));
92 /*! @brief implementing FunctionT::on_start_tag */
93 template <typename RangeT, typename MapT>
94 void on_start_tag(const RangeT& range,
96 using boost::algorithm::equals;
100 if (equals(range, "br")) {
102 } else if (equals(range, "b")) {
104 } else if (equals(range, "a")) {
105 typedef typename MapT::key_type KeyType;
106 typename MapT::const_iterator h = attrs.find(KeyType("href"));
107 if (h != attrs.end()) href_ = (*h).second;
111 /*! @brief implementing FunctionT::on_end_tag */
112 template <typename RangeT>
113 void on_end_tag(const RangeT& range) {
114 using boost::algorithm::equals;
118 if (equals(range, "b")) {
120 } else if (equals(range, "a")) {
126 /*! @brief BufferBuilderT must implement add_text(range, bold, href)*/
127 template <typename RangeT, typename RangeT2>
128 void add_text(const RangeT& range, bool bold, const RangeT2& href) {
129 buffer_builder_.add_text(range, bold, href);
132 /*! @brief BufferBuilderT must implement add_id(range, bold, id) */
133 template <typename RangeT, typename RangeT2>
134 void add_id(const RangeT& range, bool bold, const RangeT2& id) {
135 buffer_builder_.add_id(range, bold, id);
138 /*! @brief BufferBuilderT must implement add_res_num(res_num, bold) */
139 void add_res_num(int res_num, bool bold) {
140 buffer_builder_.add_res_num(res_num, bold);
143 /*! @brief BufferBuilderT must implement new_line(left_margin) */
144 void new_line(int left_margin) {
145 buffer_builder_.new_line(left_margin);
153 add_res_num(res_num_, bold_);
156 template <typename RangeT, typename RangeT2>
157 void on_id(const RangeT& range, const RangeT2& id) {
161 //buffer_builder_.add_text(range, bold_, id);
162 add_id(range, bold_, id);
167 new_line(left_margin_);
171 if (!buffer_.empty()) {
172 add_text(buffer_, bold_, href_);
177 template <typename RangeT>
178 void drive_res_line(const RangeT& range) {
179 typedef typename boost::range_const_iterator<RangeT>::type Iterator;
180 typedef typename boost::iterator_range<Iterator> IterRange;
182 if (boost::empty(range)) return;
184 boost::iterator_range<Iterator> name;
185 boost::iterator_range<Iterator> mail;
186 boost::iterator_range<Iterator> date;
187 boost::iterator_range<Iterator> msg;
190 HogeName, HogeMail, HogeDate, HogeMsg, HogeEnd
192 Hogehoge state = HogeName;
194 for (Iterator it = boost::begin(range); it != boost::end(range);) {
196 boost::iterator_range<Iterator> rdlm(it, boost::end(range));
197 rdlm = boost::find_first(rdlm, "<>");
200 Iterator dlm = boost::begin(rdlm);
202 it = skip_white_space(std::make_pair(it, dlm));
208 name = std::make_pair(it, dlm);
212 mail = std::make_pair(it, dlm);
216 date = std::make_pair(it, dlm);
220 msg = std::make_pair(it, dlm);
225 it = boost::end(rdlm);
231 on_data(std::string(" "));
233 if (state != HogeEnd) {
234 // failure parsing the res line.
248 template <typename RangeT>
249 void parse_name(const RangeT& range) {
250 parse_html(std::string("<b>"));
252 parse_html(std::string("</b>"));
255 template <typename RangeT>
256 void parse_mail(const RangeT& range) {
257 on_data(std::string("["));
259 on_data(std::string("]"));
262 template <typename RangeT>
263 void parse_date(const RangeT& range) {
264 typedef typename boost::range_const_iterator<RangeT>::type Iterator;
265 typedef typename boost::iterator_range<Iterator> IterRange;
267 IterRange id = range;
268 id = boost::find_first(range, "ID:");
270 on_data(std::make_pair(boost::begin(range), boost::begin(id)));
271 Iterator id_end = std::find(boost::end(id), boost::end(range), ' ');
273 on_id(id, std::make_pair(boost::end(id), id_end));
274 on_data(std::make_pair(boost::end(id), boost::end(range)));
280 template <typename RangeT>
281 void parse_msg(const RangeT& range) {
288 /*! @brief helper function for running DatParser. */
290 template <typename> class HtmlParserDriverT,
291 template <typename> class HtmlParserFunctionT,
292 typename BufferBuilderT,
294 void run_parser(BufferBuilderT& view, const RangeT& range, int res_num) {
295 DatParser<BufferBuilderT, HtmlParserDriverT, HtmlParserFunctionT>
296 parser(view, res_num);
300 } // namespace dialektos