2 * Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include "MarkupParser.h"
12 #include <utf8_functions.h>
15 MarkupParser::MarkupParser()
24 fHeadingParagraphStyle(),
27 fCurrentCharacterStyle(&fNormalStyle
),
28 fCurrentParagraphStyle(&fParagraphStyle
),
35 MarkupParser::MarkupParser(const CharacterStyle
& characterStyle
,
36 const ParagraphStyle
& paragraphStyle
)
38 fNormalStyle(characterStyle
),
44 fParagraphStyle(paragraphStyle
),
45 fHeadingParagraphStyle(),
48 fCurrentCharacterStyle(&fNormalStyle
),
49 fCurrentParagraphStyle(&fParagraphStyle
),
57 MarkupParser::SetStyles(const CharacterStyle
& characterStyle
,
58 const ParagraphStyle
& paragraphStyle
)
60 fNormalStyle
= characterStyle
;
61 fParagraphStyle
= paragraphStyle
;
67 MarkupParser::CreateDocumentFromMarkup(const BString
& text
)
69 TextDocumentRef
document(new(std::nothrow
) TextDocument(), true);
70 if (document
.Get() == NULL
)
73 AppendMarkup(document
, text
);
80 MarkupParser::AppendMarkup(const TextDocumentRef
& document
, const BString
& text
)
82 fTextDocument
.SetTo(document
);
84 fCurrentCharacterStyle
= &fNormalStyle
;
85 fCurrentParagraphStyle
= &fParagraphStyle
;
87 fCurrentParagraph
= Paragraph(*fCurrentParagraphStyle
);
92 fTextDocument
.Unset();
96 // #pragma mark - private
100 MarkupParser::_InitStyles()
102 fBoldStyle
= fNormalStyle
;
103 fBoldStyle
.SetBold(true);
105 fItalicStyle
= fNormalStyle
;
106 fItalicStyle
.SetItalic(true);
108 fBoldItalicStyle
= fNormalStyle
;
109 fBoldItalicStyle
.SetBold(true);
110 fBoldItalicStyle
.SetItalic(true);
112 float fontSize
= fNormalStyle
.Font().Size();
114 fHeadingStyle
= fNormalStyle
;
115 fHeadingStyle
.SetFontSize(ceilf(fontSize
* 1.15f
));
116 fHeadingStyle
.SetBold(true);
118 fHeadingParagraphStyle
= fParagraphStyle
;
119 fHeadingParagraphStyle
.SetSpacingTop(ceilf(fontSize
* 0.8f
));
120 fHeadingParagraphStyle
.SetSpacingBottom(ceilf(fontSize
* 0.5f
));
121 fHeadingParagraphStyle
.SetJustify(false);
123 fBulletStyle
= fParagraphStyle
;
124 fBulletStyle
.SetBullet(Bullet("•", fontSize
));
125 fBulletStyle
.SetLineInset(ceilf(fontSize
* 0.8f
));
130 MarkupParser::_ParseText(const BString
& text
)
135 int32 charCount
= text
.CountChars();
136 const char* c
= text
.String();
138 while (offset
<= charCount
) {
139 uint32 nextChar
= UTF8ToCharCode(&c
);
142 // Requires two line-breaks to start a new paragraph, unles the current
143 // paragraph is already considered a bullet list item. Doesn't work well
144 // with current set of packages.
146 // _CopySpan(text, start, offset);
147 // if (offset + 1 < charCount && c[0] == '\n') {
148 // _FinishParagraph();
151 // } else if (fCurrentParagraph.Style() == fBulletStyle) {
152 // _FinishParagraph();
154 // start = offset + 1;
158 _CopySpan(text
, start
, offset
);
159 if (offset
> 0 && c
[-1] != ' ')
160 _FinishParagraph(offset
>= charCount
);
165 _CopySpan(text
, start
, offset
);
166 _FinishParagraph(true);
171 if (offset
+ 2 < charCount
&& c
[0] == '\'') {
176 // Copy previous span using current style, excluding the
178 _CopySpan(text
, start
, offset
);
181 _ToggleStyle(fItalicStyle
);
182 else if (tickCount
== 3)
183 _ToggleStyle(fBoldStyle
);
185 // Don't include the ticks in the next span.
186 offset
+= tickCount
- 1;
195 && fCurrentParagraph
.IsEmpty()
196 && offset
+ 2 < charCount
197 && c
[0] == '=' && c
[1] == ' ') {
199 fCurrentParagraph
.SetStyle(fHeadingParagraphStyle
);
200 fCurrentCharacterStyle
= &fHeadingStyle
;
206 } else if (offset
> start
207 && offset
+ 2 < charCount
208 && c
[0] == '=' && c
[1] == '\n') {
210 _CopySpan(text
, start
, offset
- 1);
215 _FinishParagraph(offset
>= charCount
);
222 // Detect bullets at line starts (preceeding space)
224 && fCurrentParagraph
.IsEmpty()
225 && offset
+ 2 < charCount
226 && (c
[0] == '*' || c
[0] == '-') && c
[1] == ' ') {
228 fCurrentParagraph
.SetStyle(fBulletStyle
);
239 // Detect bullets at line starts (no preceeding space)
241 && fCurrentParagraph
.IsEmpty()
242 && offset
+ 1 < charCount
245 fCurrentParagraph
.SetStyle(fBulletStyle
);
264 MarkupParser::_CopySpan(const BString
& text
, int32
& start
, int32 end
)
270 text
.CopyCharsInto(subString
, start
, end
- start
);
271 fCurrentParagraph
.Append(TextSpan(subString
, *fCurrentCharacterStyle
));
278 MarkupParser::_ToggleStyle(const CharacterStyle
& style
)
280 if (fCurrentCharacterStyle
== &style
)
281 fCurrentCharacterStyle
= &fNormalStyle
;
283 fCurrentCharacterStyle
= &style
;
288 MarkupParser::_FinishParagraph(bool isLast
)
291 fCurrentParagraph
.Append(TextSpan("\n", *fCurrentCharacterStyle
));
293 if (fCurrentParagraph
.IsEmpty()) {
295 fCurrentParagraph
.Append(TextSpan("", fNormalStyle
));
298 fTextDocument
->Append(fCurrentParagraph
);
299 fCurrentParagraph
.Clear();
300 fCurrentParagraph
.SetStyle(fParagraphStyle
);
301 fCurrentCharacterStyle
= &fNormalStyle
;