1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "otmlemitter.h"
24#include "otmldocument.h"
25
26std::string OTMLEmitter::emitNode(const OTMLNodePtr& node, int currentDepth)
27{
28 std::stringstream ss;
29
30 // emit nodes
31 if(currentDepth >= 0) {
32 // fill spaces for current depth
33 for(int i=0;i<currentDepth;++i)
34 ss << " ";
35
36 // emit node tag
37 if(node->hasTag()) {
38 ss << node->tag();
39
40 // add ':' to if the node is unique or has value
41 if(node->hasValue() || node->isUnique() || node->isNull())
42 ss << ":";
43 } else
44 ss << "-";
45
46 // emit node value
47 if(node->isNull())
48 ss << " ~";
49 else if(node->hasValue()) {
50 ss << " ";
51
52 std::string value = node->value();
53
54 // emit multiline values
55 if(value.find("\n") != std::string::npos) {
56 if(value[value.length()-1] == '\n' && value[value.length()-2] == '\n')
57 ss << "|+";
58 else if(value[value.length()-1] == '\n')
59 ss << "|";
60 else
61 ss << "|-";
62
63 // multilines
64 for(std::size_t pos = 0; pos < value.length(); ++pos) {
65 ss << "\n";
66
67 // fill spaces for multiline depth
68 for(int i=0;i<currentDepth+1;++i)
69 ss << " ";
70
71 // fill until a new line
72 while(pos < value.length()) {
73 if(value[pos] == '\n')
74 break;
75 ss << value[pos++];
76 }
77 }
78 // emit inline values
79 } else
80 ss << value;
81 }
82 }
83
84 // emit children
85 int i = 0;
86 for(auto& child : node->children()) {
87 if(currentDepth >= 0 || i != 0)
88 ss << "\n";
89 ss << emitNode(child, currentDepth+1);
90 i += 1;
91 }
92
93 return ss.str();
94}
95