1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libe-book project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "FictionBook2Collector.h"
11 #include "FictionBook2TextContext.h"
12 #include "FictionBook2Token.h"
13 
14 namespace libebook
15 {
16 
FictionBook2ParaContextBase(FictionBook2ParserContext * parentContext,const FictionBook2BlockFormat & format)17 FictionBook2ParaContextBase::FictionBook2ParaContextBase(FictionBook2ParserContext *parentContext, const FictionBook2BlockFormat &format)
18   : FictionBook2StyleContextBase(parentContext, FictionBook2Style(format))
19 {
20 }
21 
startOfElement()22 void FictionBook2ParaContextBase::startOfElement()
23 {
24   getCollector()->openParagraph(getStyle().getBlockFormat());
25 }
26 
endOfElement()27 void FictionBook2ParaContextBase::endOfElement()
28 {
29   getCollector()->closeParagraph();
30 }
31 
attribute(const FictionBook2TokenData & name,const FictionBook2TokenData * ns,const char * value)32 void FictionBook2ParaContextBase::attribute(const FictionBook2TokenData &name, const FictionBook2TokenData *ns, const char *value)
33 {
34   FictionBook2StyleContextBase::attribute(name, ns, value);
35 
36   if (FictionBook2_NO_NAMESPACE(ns))
37   {
38     switch (getFictionBook2TokenID(name))
39     {
40     case FictionBook2Token::id :
41       getCollector()->defineID(value);
42       break;
43     case FictionBook2Token::style :
44       // ignore
45       break;
46     default :
47       break;
48     }
49   }
50 }
51 
FictionBook2AContext(FictionBook2ParserContext * parentContext,const FictionBook2Style & style)52 FictionBook2AContext::FictionBook2AContext(FictionBook2ParserContext *parentContext, const FictionBook2Style &style)
53   : FictionBook2StyleContextBase(parentContext, style)
54   , m_href()
55   , m_valid(true)
56   , m_note(false)
57 {
58 }
59 
element(const FictionBook2TokenData & name,const FictionBook2TokenData & ns)60 FictionBook2XMLParserContext *FictionBook2AContext::element(const FictionBook2TokenData &name, const FictionBook2TokenData &ns)
61 {
62   if (m_note)
63     return new FictionBook2SkipElementContext(this);
64   else
65     return FictionBook2StyleContextBase::element(name, ns);
66 }
67 
startOfElement()68 void FictionBook2AContext::startOfElement()
69 {
70 }
71 
endOfElement()72 void FictionBook2AContext::endOfElement()
73 {
74   if (m_note)
75     getCollector()->insertFootnote(m_href.c_str());
76 }
77 
endOfAttributes()78 void FictionBook2AContext::endOfAttributes()
79 {
80   if (!m_valid)
81     m_note = false;
82 
83   if (m_note)
84   {
85     if ('#' == m_href[0])
86       m_href = m_href.substr(1);
87     else
88       m_note = false;
89   }
90 }
91 
attribute(const FictionBook2TokenData & name,const FictionBook2TokenData * ns,const char * value)92 void FictionBook2AContext::attribute(const FictionBook2TokenData &name, const FictionBook2TokenData *ns, const char *value)
93 {
94   if (FictionBook2Token::NS_XLINK == getFictionBook2TokenID(ns))
95   {
96     switch (getFictionBook2TokenID(name))
97     {
98     case FictionBook2Token::href :
99       m_href = value;
100       break;
101     case FictionBook2Token::type :
102       m_valid = FictionBook2Token::simple == getFictionBook2TokenID(value);
103       break;
104     default :
105       break;
106     }
107   }
108   else if (FictionBook2_NO_NAMESPACE(ns) && (FictionBook2Token::type == getFictionBook2TokenID(name)))
109     m_note = FictionBook2Token::note == getFictionBook2TokenID(value);
110 }
111 
text(const char * value)112 void FictionBook2AContext::text(const char *value)
113 {
114   if (!m_note)
115   {
116     getCollector()->openSpan(getStyle());
117     getCollector()->insertText(value);
118     getCollector()->closeSpan();
119   }
120 }
121 
FictionBook2CodeContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)122 FictionBook2CodeContext::FictionBook2CodeContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
123   : FictionBook2StyleContextBase(parentContext, style)
124 {
125 }
126 
startOfElement()127 void FictionBook2CodeContext::startOfElement()
128 {
129   getTextFormat().code = true;
130 }
131 
FictionBook2EmphasisContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)132 FictionBook2EmphasisContext::FictionBook2EmphasisContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
133   : FictionBook2StyleContextBase(parentContext, style)
134 {
135 }
136 
startOfElement()137 void FictionBook2EmphasisContext::startOfElement()
138 {
139   getTextFormat().emphasis = true;
140 }
141 
FictionBook2InlineImageContext(FictionBook2ParserContext * parentContext,const FictionBook2Style & style)142 FictionBook2InlineImageContext::FictionBook2InlineImageContext(FictionBook2ParserContext *parentContext, const FictionBook2Style &style)
143   : FictionBook2DataContextBase(parentContext)
144   , m_style(style)
145   , m_href()
146   , m_altText()
147   , m_valid(true)
148 {
149 }
150 
startOfElement()151 void FictionBook2InlineImageContext::startOfElement()
152 {
153 }
154 
endOfElement()155 void FictionBook2InlineImageContext::endOfElement()
156 {
157   if (m_valid && ('#' != m_href[0]))
158     m_valid = false;
159 
160   if (m_valid)
161     getCollector()->insertBitmap(m_href.substr(1).c_str());
162   else
163   {
164     getCollector()->openSpan(m_style);
165     const std::string altText("[Image: " + m_altText + "]");
166     getCollector()->insertText(altText.c_str());
167     getCollector()->closeSpan();
168   }
169 }
170 
endOfAttributes()171 void FictionBook2InlineImageContext::endOfAttributes()
172 {
173 }
174 
attribute(const FictionBook2TokenData & name,const FictionBook2TokenData * ns,const char * value)175 void FictionBook2InlineImageContext::attribute(const FictionBook2TokenData &name, const FictionBook2TokenData *ns, const char *value)
176 {
177   if (FictionBook2_NO_NAMESPACE(ns) && (FictionBook2Token::alt == getFictionBook2TokenID(name)))
178     m_altText = value;
179   else if (FictionBook2Token::NS_XLINK == getFictionBook2TokenID(ns))
180   {
181     switch (getFictionBook2TokenID(name))
182     {
183     case FictionBook2Token::href :
184       m_href = value;
185       break;
186     case FictionBook2Token::type :
187       m_valid = FictionBook2Token::simple == getFictionBook2TokenID(value);
188       break;
189     default :
190       break;
191     }
192   }
193 }
194 
FictionBook2PContext(FictionBook2ParserContext * const parentContext,const FictionBook2BlockFormat & format)195 FictionBook2PContext::FictionBook2PContext(FictionBook2ParserContext *const parentContext, const FictionBook2BlockFormat &format)
196   : FictionBook2ParaContextBase(parentContext, makeBlockFormat(format))
197 {
198 }
199 
makeBlockFormat(const FictionBook2BlockFormat & format)200 FictionBook2BlockFormat FictionBook2PContext::makeBlockFormat(const FictionBook2BlockFormat &format)
201 {
202   FictionBook2BlockFormat outFormat(format);
203   outFormat.p = true;
204   return outFormat;
205 }
206 
FictionBook2StrikethroughContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)207 FictionBook2StrikethroughContext::FictionBook2StrikethroughContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
208   : FictionBook2StyleContextBase(parentContext, style)
209 {
210 }
211 
startOfElement()212 void FictionBook2StrikethroughContext::startOfElement()
213 {
214   getTextFormat().strikethrough = true;
215 }
216 
FictionBook2StrongContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)217 FictionBook2StrongContext::FictionBook2StrongContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
218   : FictionBook2StyleContextBase(parentContext, style)
219 {
220 }
221 
startOfElement()222 void FictionBook2StrongContext::startOfElement()
223 {
224   getTextFormat().strong = true;
225 }
226 
FictionBook2StyleContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)227 FictionBook2StyleContext::FictionBook2StyleContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
228   : FictionBook2StyleContextBase(parentContext, style)
229 {
230 }
231 
startOfElement()232 void FictionBook2StyleContext::startOfElement()
233 {
234   // TODO: implement me
235 }
236 
FictionBook2SubContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)237 FictionBook2SubContext::FictionBook2SubContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
238   : FictionBook2StyleContextBase(parentContext, style)
239 {
240 }
241 
startOfElement()242 void FictionBook2SubContext::startOfElement()
243 {
244   getTextFormat().sub = true;
245 }
246 
FictionBook2SubtitleContext(FictionBook2ParserContext * parentContext,const FictionBook2BlockFormat & format)247 FictionBook2SubtitleContext::FictionBook2SubtitleContext(FictionBook2ParserContext *parentContext, const FictionBook2BlockFormat &format)
248   : FictionBook2ParaContextBase(parentContext, makeBlockFormat(format))
249 {
250 }
251 
makeBlockFormat(const FictionBook2BlockFormat & format)252 FictionBook2BlockFormat FictionBook2SubtitleContext::makeBlockFormat(const FictionBook2BlockFormat &format)
253 {
254   FictionBook2BlockFormat outFormat(format);
255   outFormat.subtitle = true;
256   return outFormat;
257 }
258 
FictionBook2SupContext(FictionBook2ParserContext * parentContext,FictionBook2Style & style)259 FictionBook2SupContext::FictionBook2SupContext(FictionBook2ParserContext *parentContext, FictionBook2Style &style)
260   : FictionBook2StyleContextBase(parentContext, style)
261 {
262 }
263 
startOfElement()264 void FictionBook2SupContext::startOfElement()
265 {
266   getTextFormat().sup = true;
267 }
268 
FictionBook2TextAuthorContext(FictionBook2ParserContext * parentContext,const FictionBook2BlockFormat & format)269 FictionBook2TextAuthorContext::FictionBook2TextAuthorContext(FictionBook2ParserContext *parentContext, const FictionBook2BlockFormat &format)
270   : FictionBook2PContext(parentContext, makeBlockFormat(format))
271 {
272 }
273 
makeBlockFormat(const FictionBook2BlockFormat & format)274 FictionBook2BlockFormat FictionBook2TextAuthorContext::makeBlockFormat(const FictionBook2BlockFormat &format)
275 {
276   FictionBook2BlockFormat outFormat(format);
277   outFormat.textAuthor = true;
278   return outFormat;
279 }
280 
FictionBook2VContext(FictionBook2ParserContext * parentContext,const FictionBook2BlockFormat & format)281 FictionBook2VContext::FictionBook2VContext(FictionBook2ParserContext *parentContext, const FictionBook2BlockFormat &format)
282   : FictionBook2ParaContextBase(parentContext, makeBlockFormat(format))
283 {
284 }
285 
makeBlockFormat(const FictionBook2BlockFormat & format)286 FictionBook2BlockFormat FictionBook2VContext::makeBlockFormat(const FictionBook2BlockFormat &format)
287 {
288   FictionBook2BlockFormat outFormat(format);
289   outFormat.v = true;
290   return outFormat;
291 }
292 
293 }
294 
295 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
296