2 * Yara: Yet Another RSS Aggregator
3 * Copyright (C) 2007 Ronald Landheer-Cieslak
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "Private/RenderingChannelInserter.h"
23 #include "Private/RenderingItemInserter.h"
29 template < typename InfoType
, typename InserterType
>
30 void render__(std::ostream
& target
, const InfoType
& info
, const std::string
& input
, InserterType (*getter
)(const std::string
&))
32 std::string::const_iterator
begin(input
.begin());
33 std::string::const_iterator
where(input
.begin());
34 std::string::const_iterator
end(input
.end());
38 std::string::size_type
tag_start(input
.find("$$__", std::distance(begin
, where
)));
39 std::string::size_type
tag_end(input
.find("__$$", tag_start
));
40 if (tag_start
!= std::string::npos
&& tag_end
!= std::string::npos
)
42 // when we get here, we can at least push out everything
43 // between the current value of where and the start of the
45 std::copy(where
, where
+ (tag_start
- std::distance(begin
, where
)), std::ostream_iterator
< char >(target
));
46 // the tag itself is between tag_start + 4 (the size of "$$__") and tag_end
47 std::string
tag(begin
+ tag_start
+ 4/* sizeof $$__ */, begin
+ tag_end
);
48 InserterType
inserter(getter(tag
));
51 // we haven't found the tag. The policy is therefore to add it
52 // to the target stream and look again
53 std::advance(where
, tag_start
);
54 std::copy(where
, where
+ 4/* sizeof $$__ */, std::ostream_iterator
< char >(target
));
55 std::advance(where
, 4/* sizeof $$__ */);
58 { // we've found a real tag. We'll use its inserter to add it to the target
59 // stream and advance the where iterator to the end of the tag
60 inserter(target
, info
);
61 std::advance(where
, tag_end
+ 4 - std::distance(begin
, where
));
66 std::copy(where
, end
, std::ostream_iterator
< char >(target
));
75 Data(const Template
& _template
)
76 : template_(new Template(_template
))
79 std::auto_ptr
< Template
> template_
;
82 Renderer::Renderer(const Template
& _template
)
83 : data_(new Data(_template
))
91 void Renderer::render(std::ostream
& target
, const Parser
& parser
)
93 Details::ChannelInfo
channel_info(parser
.getChannelInfo());
95 render__(target
, channel_info
, data_
->template_
->getHeader(), Private::getRenderingChannelInserter
);
96 unsigned int item_count(parser
.getItemCount());
97 for (unsigned int item_index(0); item_index
< item_count
; ++item_index
)
99 Details::ItemInfo
item(parser
.getItem(item_index
));
100 render__(target
, item
, data_
->template_
->getItem(), Private::getRenderingItemInserter
);
102 render__(target
, channel_info
, data_
->template_
->getFooter(), Private::getRenderingChannelInserter
);