26 #include <boost/tokenizer.hpp>
29 currentDepth(0), currentLine(0),
30 doc(doc), currentParent(doc), previousNode(nullptr),
41 parseLine(getNextLine());
44 std::string OTMLParser::getNextLine()
48 std::getline(in, line);
52 int OTMLParser::getLineDepth(
const std::string& line,
bool multilining)
55 std::size_t spaces = 0;
56 while(line[spaces] ==
' ')
60 int depth = spaces / 2;
62 if(!multilining || depth <= currentDepth) {
64 if(line[spaces] ==
'\t')
65 throw OTMLException(doc,
"indentation with tabs are not allowed", currentLine);
69 throw OTMLException(doc,
"must indent every 2 spaces", currentLine);
75 void OTMLParser::parseLine(std::string line)
77 int depth = getLineDepth(line);
94 if(depth == currentDepth+1) {
95 currentParent = previousNode;
97 }
else if(depth < currentDepth) {
98 for(
int i=0;i<currentDepth-depth;++i)
99 currentParent = parentMap[currentParent];
101 }
else if(depth != currentDepth)
102 throw OTMLException(doc,
"invalid indentation depth, are you indenting correctly?", currentLine);
105 currentDepth = depth;
112 void OTMLParser::parseNode(
const std::string& data)
116 std::size_t dotsPos = data.find_first_of(
':');
117 int nodeLine = currentLine;
120 if(!data.empty() && data[0] ==
'-') {
121 value = data.substr(1);
124 }
else if(dotsPos != std::string::npos) {
125 tag = data.substr(0, dotsPos);
126 if(data.size() > dotsPos+1)
127 value = data.substr(dotsPos+1);
137 if(value ==
"|" || value ==
"|-" || value ==
"|+") {
139 std::string multiLineData;
141 size_t lastPos = in.tellg();
142 std::string line = getNextLine();
143 int depth = getLineDepth(line,
true);
146 if(depth > currentDepth) {
147 multiLineData += line.substr((currentDepth+1)*2);
154 in.seekg(lastPos, std::ios::beg);
159 multiLineData +=
"\n";
167 if(value ==
"|" || value ==
"|-") {
169 int lastPos = multiLineData.length();
170 while(multiLineData[--lastPos] ==
'\n')
171 multiLineData.erase(lastPos, 1);
174 multiLineData.append(
"\n");
177 value = multiLineData;
183 node->
setUnique(dotsPos != std::string::npos);
185 node->
setSource(doc->
source() +
":" + stdext::unsafe_cast<std::string>(nodeLine));
192 std::string tmp = value.substr(1, value.length()-2);
193 boost::tokenizer<boost::escaped_list_separator<char>> tokens(tmp);
194 for(std::string v : tokens) {
203 parentMap[node] = currentParent;