SeqAn3  3.1.0-rc.1
The Modern C++ library for sequence analysis.
format_html.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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_paragraph();
167 
168  // Print HTML boilerplate footer.
169  std::cout << "</body></html>";
170  }
171 
176  std::string to_html(std::string const & input)
177  {
178  std::string buffer = escape_special_xml_chars(input);
179  std::string result;
180  std::vector<std::string> open_tags; // acts as a stack of html tags
181 
182  for (auto it = input.begin(); it != input.end(); ++it)
183  {
184  if (*it == '\\')
185  {
186  // Handle escape sequence, we interpret only "\-", "\fI", and "\fB".
187  ++it;
188  assert(!(it == input.end()));
189  if (*it == '-')
190  {
191  result.push_back(*it);
192  }
193  else if (*it == 'f')
194  {
195  ++it;
196  assert(!(it == input.end()));
197  if (*it == 'I')
198  {
199  open_tags.push_back("em");
200  result.append("<em>");
201  }
202  else if (*it == 'B')
203  {
204  open_tags.push_back("strong");
205  result.append("<strong>");
206  }
207  else if (*it == 'P')
208  {
209  assert(!open_tags.empty());
210  result.append("</");
211  result.append(open_tags.back());
212  result.append(">");
213  open_tags.pop_back();
214  }
215  else
216  {
217  result.append("\\f");
218  result.push_back(*it);
219  }
220  }
221  else
222  {
223  result.push_back('\\');
224  result.push_back(*it);
225  }
226  }
227  else
228  {
229  result.push_back(*it);
230  }
231  }
232 
233  return result;
234  }
235 
240  std::string in_bold(std::string const & str)
241  {
242  return "<strong>" + str + "</strong>";
243  }
244 
246  bool is_dl{false};
248  bool is_p{false};
249 };
250 
251 } // namespace seqan3
T append(T... args)
T back(T... args)
T begin(T... args)
T empty(T... args)
T end(T... args)
Provides the format_base struct containing all helper functions that are needed in all formats.
@ advanced
Definition: auxiliary.hpp:245
T pop_back(T... args)
T push_back(T... args)
Checks if program is run interactively and retrieves dimensions of terminal (Transferred from seqan2)...
Provides SeqAn version macros and global variables.