A library for working with phylogenetic and population genetic data.
v0.27.0
utils/formats/xml/writer.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2020 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
39 
40 #include <cassert>
41 #include <stdexcept>
42 
43 namespace genesis {
44 namespace utils {
45 
46 // =================================================================================================
47 // Printing
48 // =================================================================================================
49 
50 void XmlWriter::write( XmlDocument const& document, std::shared_ptr<utils::BaseOutputTarget> target ) const
51 {
52  auto& os = target->ostream();
53 
54  if( !document.xml_tag.empty() || !document.declarations.empty() ) {
55  os << "<?" << document.xml_tag << print_attributes_list_(document.declarations) << "?>\n";
56  }
57  print_element_( &document, 0, os );
58  os << "\n";
59 }
60 
61 // =================================================================================================
62 // Internal
63 // =================================================================================================
64 
68 void XmlWriter::print_comment_( XmlComment const* value, std::ostream& os ) const
69 {
70  os << xml_comment( value->content );
71 }
72 
76 void XmlWriter::print_markup_( XmlMarkup const* value, std::ostream& os ) const
77 {
78  os << xml_escape(value->content);
79 }
80 
84 void XmlWriter::print_element_( XmlElement const* value, const int indent_level, std::ostream& os ) const
85 {
86  // Prepare indention and opening tag.
87  std::string in0 (indent_level * indent, ' ');
88  os << in0 << "<" << value->tag << print_attributes_list_(value->attributes);
89 
90  // If it's an empty element, close it, and we are done.
91  if (value->content.size() == 0) {
92  os << " />";
93  return;
94  }
95 
96  // If the element only contains a single markup, don't add new lines. However, if it contains
97  // more data, put each element in a new line.
98  os << ">";
99  if (value->content.size() == 1 && value->content[0]->is_markup()) {
100  print_markup_( xml_value_to_markup(value->content[0].get()), os );
101  } else {
102  std::string in1 ((indent_level + 1) * indent, ' ');
103  os << "\n";
104 
105  for (auto& v : value->content) {
106  if (v->is_comment()) {
107  os << in1;
108  print_comment_( xml_value_to_comment(v.get()), os );
109  } else if (v->is_markup()) {
110  os << in1;
111  print_markup_( xml_value_to_markup(v.get()), os );
112  } else if (v->is_element()) {
113  print_element_( xml_value_to_element(v.get()), indent_level + 1, os );
114  } else {
115  // there are no other cases
116  assert(0);
117  }
118  os << "\n";
119  }
120  os << in0;
121  }
122 
123  os << "</" << value->tag << ">";
124 }
125 
129 std::string XmlWriter::print_attributes_list_ (StringMapType attr) const
130 {
131  std::string xml;
132  for (auto pair : attr) {
133  xml += xml_attribute( pair.first, pair.second );
134  // xml += " " + pair.first + "=\"" + pair.second + "\"";
135  }
136  return xml;
137 }
138 
139 } // namespace utils
140 } // namespace genesis
helper.hpp
fs.hpp
Provides functions for accessing the file system.
genesis::utils::XmlWriter::print_element_
void print_element_(XmlElement const *value, const int indent_level, std::ostream &os) const
Print an XML element.
Definition: utils/formats/xml/writer.cpp:84
writer.hpp
genesis::utils::xml_value_to_element
const XmlElement * xml_value_to_element(const XmlValue *v)
Converts a pointer to an XmlValue to XmlElement if appropriate.
Definition: xml/document.cpp:77
genesis::utils::XmlDocument::declarations
StringMapType declarations
Definition: xml/document.hpp:235
genesis::utils::XmlWriter::write
void write(XmlDocument const &document, std::shared_ptr< utils::BaseOutputTarget > target) const
Definition: utils/formats/xml/writer.cpp:50
output_stream.hpp
genesis::utils::XmlElement
Definition: xml/document.hpp:149
genesis::utils::XmlDocument::xml_tag
std::string xml_tag
Definition: xml/document.hpp:234
genesis::utils::xml_value_to_comment
const XmlComment * xml_value_to_comment(const XmlValue *v)
Converts a pointer to an XmlValue to XmlComment if appropriate.
Definition: xml/document.cpp:47
genesis::utils::XmlComment
Definition: xml/document.hpp:117
genesis::utils::XmlWriter::indent
int indent
Indent used for printing the XML elements.
Definition: utils/formats/xml/writer.hpp:91
string.hpp
Provides some commonly used string utility functions.
genesis::utils::XmlComment::content
std::string content
Definition: xml/document.hpp:123
genesis::utils::XmlMarkup
Definition: xml/document.hpp:133
logging.hpp
Provides easy and fast logging functionality.
genesis::utils::XmlElement::content
std::vector< std::unique_ptr< XmlValue > > content
Definition: xml/document.hpp:209
genesis::utils::XmlWriter::print_comment_
void print_comment_(XmlComment const *value, std::ostream &os) const
Print an XML comment.
Definition: utils/formats/xml/writer.cpp:68
genesis::utils::xml_escape
std::string xml_escape(std::string const &txt)
Escape special XML characters.
Definition: utils/formats/xml/helper.cpp:45
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::XmlElement::attributes
StringMapType attributes
Definition: xml/document.hpp:208
genesis::utils::XmlWriter::print_attributes_list_
std::string print_attributes_list_(StringMapType attr) const
Print a list of XML attributes.
Definition: utils/formats/xml/writer.cpp:129
genesis::utils::xml_comment
std::string xml_comment(std::string const &content)
Definition: utils/formats/xml/helper.cpp:70
genesis::utils::xml_attribute
std::string xml_attribute(std::string const &name, T const &value)
Definition: utils/formats/xml/helper.hpp:52
genesis::utils::xml_value_to_markup
const XmlMarkup * xml_value_to_markup(const XmlValue *v)
Converts a pointer to an XmlValue to XmlMarkup if appropriate.
Definition: xml/document.cpp:62
document.hpp
A collection of classes for working with XML documents. See XmlDocument for more.
genesis::utils::XmlElement::tag
std::string tag
Definition: xml/document.hpp:207
genesis::utils::XmlWriter::print_markup_
void print_markup_(XmlMarkup const *value, std::ostream &os) const
Print an XML markup (simple text).
Definition: utils/formats/xml/writer.cpp:76
genesis::utils::XmlDocument
Definition: xml/document.hpp:219
genesis::utils::XmlMarkup::content
std::string content
Definition: xml/document.hpp:139