summaryrefslogtreecommitdiff
path: root/src/smlrenderervt100.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/smlrenderervt100.cpp')
-rw-r--r--src/smlrenderervt100.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/smlrenderervt100.cpp b/src/smlrenderervt100.cpp
new file mode 100644
index 0000000..2b59d5f
--- /dev/null
+++ b/src/smlrenderervt100.cpp
@@ -0,0 +1,229 @@
1#include "smlrenderervt100.h"
2#include "smlnode.h"
3
4SmlRendererVt100::SmlRendererVt100()
5{
6}
7
8SmlRendererVt100::~SmlRendererVt100()
9{
10}
11
12void SmlRendererVt100::appendToken( Bu::Formatter &f, Bu::String &sCurLine,
13 Bu::String &sNextToken, int &iLineLen, int &iNextLen )
14{
15 if( iLineLen + iNextLen + 1 >= 78 )
16 {
17 f << sCurLine << f.nl;
18 iLineLen = 0;
19 sCurLine = sNextToken;
20 }
21 else
22 {
23 sCurLine += sNextToken;
24 }
25 iLineLen += iNextLen + 1;
26 sCurLine += " ";
27 iNextLen = 0;
28 sNextToken.clear();
29}
30
31Bu::String SmlRendererVt100::getStyle( const StyleStack &sStyle )
32{
33#ifdef WIN32
34 // Windows...we don't do colors for windows...
35 return "";
36#endif
37
38 if( sStyle.isEmpty() )
39 {
40 return "\x1B[0m";
41 }
42
43 int sCurStyle = 0;
44 for( StyleStack::const_iterator i = sStyle.begin(); i; i++ )
45 {
46// f << "Merging in: " << Fmt::hex() << *i << f.nl;
47 if( ((sCurStyle&stTypeMask) & ((*i)&stTypeMask)) == 0 )
48 {
49 sCurStyle |= *i;
50// f << " -> curStyle = " << Fmt::hex() << *i << f.nl;
51 }
52 }
53
54 Bu::String sRet;
55
56// f << "Color: " << Fmt::hex() << sCurStyle << f.nl;
57 switch( sCurStyle&stColor )
58 {
59 case stRed:
60 sRet += "\x1B[1;31m";
61 break;
62
63 case stGreen:
64 sRet += "\x1B[1;32m";
65 break;
66 }
67
68 return sRet;
69}
70
71void SmlRendererVt100::render( Bu::Formatter &f, const SmlNode *pNode )
72{
73 Bu::String sCurLine;
74 Bu::String sNextToken;
75 int iLineLen = 0;
76 int iNextLen = 0;
77 int iState = 0;
78 typedef Bu::List<SmlNode::SmlNodeList::const_iterator> NodeStack;
79 NodeStack sNode;
80
81 StyleStack sStyle;
82
83 sNode.push( pNode->getChildren().begin() );
84
85 for(;;)
86 {
87 if( !sNode.peek() )
88 {
89 sNode.pop();
90 if( sNode.isEmpty() )
91 break;
92 if( sNode.peek() )
93 {
94 // f << "Pop'd: " << (*sNode.peek())->getText() << f.nl;
95 Bu::String sTag = (*sNode.peek())->getText();
96 if( sTag == "green" || sTag == "red" )
97 {
98 sStyle.pop();
99 sNextToken += getStyle( sStyle );
100 }
101 sNode.peek()++;
102 continue;
103 }
104 }
105 if( sNode.isEmpty() )
106 {
107 break;
108 }
109 const SmlNode *pNode = (*sNode.peek());
110 switch( pNode->getType() )
111 {
112 case SmlNode::typeRoot:
113 throw Bu::ExceptionBase("Invalid root.");
114
115 case SmlNode::typeText:
116 {
117 // f << "Process text node: " << pNode->getText() <<
118 // f.nl;
119 Bu::String::const_iterator iBgn = pNode->getText().begin();
120 Bu::String::const_iterator iEnd = iBgn;
121 int iTmpLen = 0;
122 for(;iBgn;)
123 {
124 switch( iState )
125 {
126 case 0: // begining of paragraph
127 if( iBgn && ( *iBgn == ' ' || *iBgn == '\n' ||
128 *iBgn == '\r' || *iBgn == '\t' ) )
129 {
130 iBgn++;
131 }
132 else
133 {
134 // Here is where you would indent paragraphs
135 iNextLen += 4;
136 sNextToken += " ";
137 iEnd = iBgn;
138 iState = 1;
139 }
140 break;
141
142 case 1: // non-whitespace
143 if( !iEnd )
144 {
145 sNextToken.append( iBgn, iEnd );
146 iBgn = iEnd;
147 iNextLen += iTmpLen;
148 iTmpLen = 0;
149 }
150 else if( *iEnd == ' ' || *iEnd == '\n' ||
151 *iEnd == '\r' || *iEnd == '\t' )
152 {
153 sNextToken.append( iBgn, iEnd );
154 iNextLen += iTmpLen;
155 iTmpLen = 0;
156 iState = 2;
157 iBgn = iEnd;
158 }
159 else
160 {
161 iEnd++;
162 iTmpLen++;
163 }
164 break;
165
166 case 2: // Whitespace
167 if( iBgn && (*iBgn == ' ' || *iBgn == '\n' ||
168 *iBgn == '\r' || *iBgn == '\t') )
169 {
170 iBgn++;
171 }
172 else
173 {
174 iEnd = iBgn;
175 iState = 1;
176 appendToken( f, sCurLine, sNextToken,
177 iLineLen, iNextLen );
178 }
179 break;
180 }
181 }
182 }
183 break;
184
185 case SmlNode::typeTag:
186 if( pNode->getChildren().isEmpty() )
187 {
188 if( pNode->getText() == "break" )
189 {
190 appendToken( f, sCurLine, sNextToken, iLineLen, iNextLen );
191 if( !sCurLine.isEmpty() )
192 f << sCurLine << f.nl;
193 sCurLine.clear();
194 iLineLen = 0;
195 iState = 0;
196 }
197 }
198 else
199 {
200// f << "Push'd: " << pNode->getText() << f.nl;
201 Bu::String sTag = pNode->getText();
202 if( sTag == "green" )
203 {
204 sStyle.push( stGreen );
205 }
206 else if( sTag == "red" )
207 {
208 sStyle.push( stRed );
209 }
210 sNextToken += getStyle( sStyle );
211 sNode.push( pNode->getChildren().begin() );
212 continue;
213/* for( SmlNode::SmlNodeList::const_iterator i =
214 pNode->getChildren().begin(); i; i++ )
215 {
216 s
217 smlToConsole( *i, sCurLine, sNextToken, iLineLen, iState );
218 }
219*/
220 }
221 break;
222 }
223 sNode.peek()++;
224 }
225 if( !sNextToken.isEmpty() )
226 appendToken( f, sCurLine, sNextToken, iLineLen, iNextLen );
227 f << sCurLine << f.nl;
228}
229