Rename STL -> STLText
[libsub.git] / src / stl_text_reader.cc
1 /*
2     Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
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.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "stl_text_reader.h"
21 #include "compose.hpp"
22 #include <boost/algorithm/string.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <vector>
25
26 using std::list;
27 using std::ostream;
28 using std::istream;
29 using std::string;
30 using std::vector;
31 using std::cout;
32 using boost::algorithm::trim;
33 using boost::algorithm::starts_with;
34 using boost::is_any_of;
35 using boost::optional;
36 using boost::lexical_cast;
37 using namespace sub;
38
39 STLTextReader::STLTextReader (istream& in)
40 {
41         while (in.good ()) {
42                 string line;
43                 getline (in, line);
44                 if (!in.good ()) {
45                         return;
46                 }
47
48                 trim (line);
49
50                 if (starts_with (line, "//")) {
51                         continue;
52                 }
53
54                 if (line.size() > 0 && line[0] == '$') {
55                         /* $ variables */
56                         vector<string> bits;
57                         split (bits, line, is_any_of ("="));
58                         if (bits.size() == 2) {
59                                 string name = bits[0];
60                                 trim (name);
61                                 string value = bits[1];
62                                 trim (value);
63
64                                 set (name, value);
65                         } else {
66                                 warn (String::compose ("Unrecognised line %1", line));
67                         }
68                 } else {
69                         /* "Normal" lines */
70                         size_t divider[2];
71                         divider[0] = line.find_first_of (",");
72                         if (divider[0] != string::npos) {
73                                 divider[1] = line.find_first_of (",", divider[0] + 1);
74                         }
75                         
76                         if (divider[0] == string::npos || divider[1] == string::npos || divider[0] <= 1 || divider[1] >= line.length() - 1) {
77                                 warn (String::compose ("Unrecognised line %1", line));
78                                 continue;
79                         }
80
81                         string from_string = line.substr (0, divider[0] - 1);
82                         trim (from_string);
83                         string to_string = line.substr (divider[0] + 1, divider[1] - divider[0] - 1);
84                         trim (to_string);
85
86                         optional<FrameTime> from = time (from_string);
87                         optional<FrameTime> to = time (to_string);
88
89                         if (!from || !to) {
90                                 warn (String::compose ("Unrecognised line %1", line));
91                                 continue;
92                         }
93
94                         _current.from.frame = from.get ();
95                         _current.to.frame = to.get ();
96
97                         /* Parse ^B/^I/^U */
98                         string text = line.substr (divider[1] + 1);
99                         for (size_t i = 0; i < text.length(); ++i) {
100                                 if (text[i] == '|') {
101                                         maybe_push ();
102                                         _current.line++;
103                                 } else if (text[i] == '^') {
104                                         maybe_push ();
105                                         if ((i + 1) < text.length()) {
106                                                 switch (text[i + 1]) {
107                                                 case 'B':
108                                                         _current.bold = !_current.bold;
109                                                         break;
110                                                 case 'I':
111                                                         _current.italic = !_current.italic;
112                                                         break;
113                                                 case 'U':
114                                                         _current.underline = !_current.underline;
115                                                         break;
116                                                 }
117                                         }
118                                         ++i;
119                                 } else {
120                                         _current.text += text[i];
121                                 }
122                         }
123
124                         maybe_push ();
125                         _current.line = 0;
126                 }
127         }
128 }
129
130 optional<FrameTime>
131 STLTextReader::time (string t) const
132 {
133         vector<string> b;
134         split (b, t, is_any_of (":"));
135         if (b.size() != 4) {
136                 warn (String::compose ("Unrecognised time %1", t));
137                 return optional<FrameTime> ();
138         }
139
140         return FrameTime (lexical_cast<int> (b[0]), lexical_cast<int> (b[1]), lexical_cast<int> (b[2]), lexical_cast<int> (b[3]));
141 }
142
143 void
144 STLTextReader::set (string name, string value)
145 {
146         if (name == "$FontName") {
147                 _current.font = value;
148         } else if (name == "$Bold") {
149                 _current.bold = value == "True";
150         } else if (name == "$Italic") {
151                 _current.italic = value == "True";
152         } else if (name == "$Underlined") {
153                 _current.underline = value == "True";
154         } else if (name == "$FontSize") {
155                 _current.font_size.points = lexical_cast<int> (value);
156         }
157 }
158
159 void
160 STLTextReader::maybe_push ()
161 {
162         if (!_current.text.empty ()) {
163                 _subs.push_back (_current);
164                 _current.text.clear ();
165         }
166 }
167