-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInstantMarkupCpp.cpp
133 lines (125 loc) · 3.14 KB
/
InstantMarkupCpp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// InstantMarkupCpp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Handler.h"
#include "Rule.h"
#include "deelx.h"
#include "HTMLRenderer.h"
#include "stdio.h"
class CParser
{
public:
CParser(){}
CParser(CHandler* handler){
m_handler = handler;
}
~CParser(){
for(iter_filter iter = m_filters.begin(); iter != m_filters.end(); iter++){
pFilter p = *iter;
delete p;
p = NULL;
}
for(rule_iter riter = m_rules.begin(); riter != m_rules.end(); riter++){
CRule *rule = *riter;
delete rule;
rule = NULL;
}
}
void add_filter(const string& pattern, const string& name){
pFilter p = new filter(pattern, name);
m_filters.push_back(p);
}
void add_rule(CRule* rule){
m_rules.push_back(rule);
}
void parse(istream& in){
m_handler->start("document");
std::string line;
std::string block;
typedef vector<string> _BLOCK;
typedef vector<string>::iterator block_iter;
_BLOCK blocks;
while(std::getline(in, line)){
//line = trim(line);
if(!line.empty()){
block.empty() ? (block += line) : (block += " " + line);
}else if(!block.empty()){
blocks.push_back(block);
block = "";
}
}
if(!block.empty()){ // last line
blocks.push_back(block);
block = "";
}
for(block_iter biter = blocks.begin(); biter != blocks.end(); biter++){
block = *biter;
for(iter_filter fiter = m_filters.begin(); fiter != m_filters.end(); fiter++){
pFilter p = *fiter;
block = filtering(block, p->_pattern, p->_name, m_handler);
}
for(rule_iter riter = m_rules.begin(); riter != m_rules.end(); riter++){
CRule *rule = *riter;
if(rule->condition(block))
if(rule->action(block, m_handler))
break;
}
}
m_handler->end("document");
}
protected:
string filtering(const string& block, const string& pattern,
const string& sub_name, CHandler* handler){
static CRegexpT <char> regexp;
regexp.Compile(pattern.c_str());
MatchResult result = regexp.Match(block.c_str());
if(result.IsMatched()){
char* content = regexp.Replace(block.c_str(),
handler->sub(sub_name).c_str());
string new_block(content);
regexp.ReleaseString(content);
return new_block;
}
return block;
}
protected:
CHandler* m_handler;
vector<CRule*> m_rules;
typedef vector<CRule*>::iterator rule_iter;
typedef struct _filter
{
string _pattern;
string _name;
_filter(const string& pattern, const string& name){
_pattern = pattern;
_name = name;
}
}filter, *pFilter;
vector<pFilter> m_filters;
typedef vector<pFilter>::iterator iter_filter;
};
class CBasicTextParser : public CParser
{
public:
CBasicTextParser(CHandler* handler){
m_handler = handler;
add_rule(new CListRule());
add_rule(new CListItemRule());
add_rule(new CTitleRule());
add_rule(new CHeadingRule());
add_rule(new CParagraphRule());
add_filter("\\*(.+?)\\*", "emphasis");
add_filter("(http://[\\.a-zA-Z/]+)", "url");
add_filter("([\\.a-zA-Z]+@[\\.a-zA-Z]+[a-zA-Z]+)", "mail");
}
virtual ~CBasicTextParser(){}
private:
CBasicTextParser(){}
};
int main(int argc, char** argv)
{
CHTMLRenderer handler;
CBasicTextParser parser(&handler);
parser.parse(cin);
return 0;
}