SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
format_html.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <iostream>
16 
19 #include <seqan3/version.hpp>
20 
21 namespace seqan3::detail
22 {
23 
34 class format_html : public format_help_base<format_html>
35 {
37  using base_type = format_help_base<format_html>;
38 
40  friend base_type;
41 
42 public:
46  format_html() = default;
47  format_html(format_html const & pf) = default;
48  format_html & operator=(format_html const & pf) = default;
49  format_html(format_html &&) = default;
50  format_html & operator=(format_html &&) = default;
51  ~format_html() = default;
52 
54  format_html(std::vector<std::string> const & names, bool const advanced = false) : base_type{names, advanced}
55  {};
57 
58 private:
60  void maybe_close_list()
61  {
62  if (is_dl)
63  {
64  std::cout << "</dl>\n";
65  is_dl = false;
66  }
67  }
68 
70  void maybe_close_paragraph()
71  {
72  if (is_p)
73  {
74  std::cout << "</p>\n";
75  is_p = false;
76  }
77  }
78 
80  void print_header()
81  {
82  // Print HTML boilerplate header.
83  std::cout << "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
84  << "http://www.w3.org/TR/html4/strict.dtd\">\n"
85  << "<html lang=\"en\">\n"
86  << "<head>\n"
87  << "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
88  << "<title>" << escape_special_xml_chars(meta.app_name) << " &mdash; "
89  << escape_special_xml_chars(meta.short_description) << "</title>\n"
90  << "</head>\n"
91  << "<body>\n";
92 
93  std::cout << "<h1>" << to_html(meta.app_name) << "</h1>\n"
94  << "<div>" << to_html(meta.short_description) << "</div>\n";
95  }
96 
100  void print_section(std::string const & title)
101  {
102  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
103  maybe_close_list();
104  maybe_close_paragraph();
105  std::cout << "<h2>" << to_html(title) << "</h2>\n";
106  }
107 
111  void print_subsection(std::string const & title)
112  {
113  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
114  maybe_close_list();
115  maybe_close_paragraph();
116  std::cout << "<h3>" << to_html(title) << "</h3>\n";
117  }
118 
124  void print_line(std::string const & text, bool line_is_paragraph)
125  {
126  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
127  maybe_close_list();
128  if (!is_p) // open parapgraph
129  {
130  std::cout << "<p>\n";
131  is_p = true;
132  }
133  std::cout << to_html(text) << "\n";
134  if (line_is_paragraph)
135  maybe_close_paragraph();
136  else
137  std::cout << "<br />\n";
138  }
139 
149  void print_list_item(std::string const & term, std::string const & desc)
150  {
151  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
152  maybe_close_paragraph();
153 
154  if (!is_dl)
155  {
156  std::cout << "<dl>\n";
157  is_dl = true;
158  }
159  std::cout << "<dt>" << to_html(term) << "</dt>\n"
160  << "<dd>" << to_html(desc) << "</dd>\n";
161  }
162 
164  void print_footer()
165  {
166  maybe_close_list();
167 
168  // Print version, date and url.
169  std::cout << "<h2>Version</h2>\n"
170  << "<strong>Last update:</strong> " << to_html(meta.date) << "<br>\n<strong>"
171  << meta.app_name << " version:</strong> " << meta.version << "<br>\n"
172  << "<strong>SeqAn version:</strong> " << SEQAN3_VERSION_MAJOR << '.' << SEQAN3_VERSION_MINOR << '.'
173  << SEQAN3_VERSION_PATCH << "<br>\n";
174 
175  if (!meta.url.empty())
176  {
177  std::cout << "<h2>Url</h2>\n"
178  << meta.url << "<br>\n";
179  }
180  std::cout << "<br>\n";
181 
182  // Print legal stuff
183  if ((!meta.short_copyright.empty()) || (!meta.long_copyright.empty()) || (!meta.citation.empty()))
184  {
185  std::cout << "<h2>Legal</h2>\n<strong>";
186 
187  if (!meta.short_copyright.empty())
188  std::cout << meta.app_name << " Copyright: </strong>"
189  << meta.short_copyright << "<br>\n<strong>";
190 
191  std::cout << "SeqAn Copyright:</strong> 2006-2019 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.<br>\n<strong>";
192 
193  if (!meta.citation.empty())
194  std::cout << "In your academic works please cite:</strong> " << meta.citation << "<br>\n";
195  else
196  std::cout << "</strong>";
197 
198  if (!meta.long_copyright.empty())
199  std::cout << "For full copyright and/or warranty information see <tt>--copyright</tt>.\n";
200  }
201 
202  // Print HTML boilerplate footer.
203  std::cout << "</body></html>";
204  }
205 
210  std::string to_html(std::string const & input)
211  {
212  std::string buffer = escape_special_xml_chars(input);
213  std::string result;
214  std::vector<std::string> open_tags; // acts as a stack of html tags
215 
216  for (auto it = input.begin(); it != input.end(); ++it)
217  {
218  if (*it == '\\')
219  {
220  // Handle escape sequence, we interpret only "\-", "\fI", and "\fB".
221  ++it;
222  assert(!(it == input.end()));
223  if (*it == '-')
224  {
225  result.push_back(*it);
226  }
227  else if (*it == 'f')
228  {
229  ++it;
230  assert(!(it == input.end()));
231  if (*it == 'I')
232  {
233  open_tags.push_back("em");
234  result.append("<em>");
235  }
236  else if (*it == 'B')
237  {
238  open_tags.push_back("strong");
239  result.append("<strong>");
240  }
241  else if (*it == 'P')
242  {
243  assert(!open_tags.empty());
244  result.append("</");
245  result.append(open_tags.back());
246  result.append(">");
247  open_tags.pop_back();
248  }
249  else
250  {
251  result.append("\\f");
252  result.push_back(*it);
253  }
254  }
255  else
256  {
257  result.push_back('\\');
258  result.push_back(*it);
259  }
260  }
261  else
262  {
263  result.push_back(*it);
264  }
265  }
266 
267  return result;
268  }
269 
271  bool is_dl{false};
273  bool is_p{false};
274 };
275 
276 } // namespace seqan3
std::string
std::vector< std::string >
SEQAN3_VERSION_MINOR
#define SEQAN3_VERSION_MINOR
The minor version as MACRO.
Definition: version.hpp:22
std::vector::back
T back(T... args)
version.hpp
Provides SeqAn version macros and global variables.
iostream
terminal.hpp
Checks if program is run interactively and retrieves dimensions of terminal (Transferred from seqan2)...
std::vector::push_back
T push_back(T... args)
std::cout
std::vector::pop_back
T pop_back(T... args)
format_base.hpp
Provides the format_base struct containing all helper functions that are needed in all formats.
SEQAN3_VERSION_MAJOR
#define SEQAN3_VERSION_MAJOR
The major version as MACRO.
Definition: version.hpp:20
std::string::begin
T begin(T... args)
std::vector::empty
T empty(T... args)
SEQAN3_VERSION_PATCH
#define SEQAN3_VERSION_PATCH
The patch version as MACRO.
Definition: version.hpp:24
std::string::end
T end(T... args)