indentation v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 07 Jan 2019 13:52:56 +0100
branchv_0
changeset 3 edbebc6163e3
parent 2 f21d6ae71bf0
child 4 abcb4c1bd9bd
indentation
include/relpipe/xmlwriter/XMLWriter.h
--- a/include/relpipe/xmlwriter/XMLWriter.h	Sun Jan 06 22:15:37 2019 +0100
+++ b/include/relpipe/xmlwriter/XMLWriter.h	Mon Jan 07 13:52:56 2019 +0100
@@ -53,6 +53,7 @@
 	ostream& output;
 	wstring_convert<codecvt_utf8<wchar_t>> convertor; // XML output will be always in UTF-8
 	vector<wstring> treePosition;
+	bool lastWasTextNode = false;
 
 	const string escapeXmlText(const wstring& value) {
 		// TODO: really bad performance → rewrite
@@ -114,19 +115,31 @@
 		}
 	}
 
+	void writeIndentation(bool resetState = true) {
+		if (lastWasTextNode) {
+			if (resetState) lastWasTextNode = false;
+		} else {
+			output << endl;
+			for (int i = 0; i < treePosition.size(); i++) {
+				output << INDENT;
+			}
+		}
+	}
+
 public:
 
 	XMLWriter(std::ostream& output) : output(output) {
-		output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+		output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
 	}
 
 	virtual ~XMLWriter() {
+		output << endl;
 		output.flush();
 	}
 
 	void writeStartElement(const wstring& name, const vector<wstring>& attributes = {}) {
-		// FIXME: indentation
 		checkName(name);
+		writeIndentation();
 		treePosition.push_back(name);
 		output << "<" << convertor.to_bytes(name);
 		writeAttributes(attributes);
@@ -134,15 +147,16 @@
 	}
 
 	void writeEndElement() {
-		// FIXME: indentation
 		if (treePosition.empty()) throw RelpipeXMLWriterException(L"unable to close element – all elements are already closed");
-		output << "</" << convertor.to_bytes(treePosition.back()) << ">";
+		wstring name = treePosition.back();
 		treePosition.pop_back();
+		writeIndentation();
+		output << "</" << convertor.to_bytes(name) << ">";
 	}
 
 	void writeEmptyElement(const wstring& name, const vector<wstring>& attributes = {}) {
-		// FIXME: indentation
 		checkName(name);
+		writeIndentation();
 		output << "<" << convertor.to_bytes(name);
 		writeAttributes(attributes);
 		output << "/>";
@@ -157,12 +171,14 @@
 
 	void writeCharacters(const wstring& text) {
 		output << escapeXmlText(text);
+		lastWasTextNode = true;
 	}
 
 	void writeComment(const wstring& text, bool addSpaces = true) {
-		output << addSpaces ? "<!-- " : "<!--";
+		writeIndentation(false);
+		output << (addSpaces ? "<!-- " : "<!--");
 		output << escapeComment(text);
-		output << addSpaces ? " -->" : "-->";
+		output << (addSpaces ? " -->" : "-->");
 	}
 
 };