SeqAn3  3.2.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-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 
36 class format_html : public format_help_base<format_html>
37 {
39  using base_type = format_help_base<format_html>;
40 
42  friend base_type;
43 
44 public:
48  format_html() = default;
49  format_html(format_html const & pf) = default;
50  format_html & operator=(format_html const & pf) = default;
51  format_html(format_html &&) = default;
52  format_html & operator=(format_html &&) = default;
53  ~format_html() = default;
54 
56  format_html(std::vector<std::string> const & names, bool const advanced = false) : base_type{names, advanced} {};
58 
59 private:
61  void maybe_close_list()
62  {
63  if (is_dl)
64  {
65  std::cout << "</dl>\n";
66  is_dl = false;
67  }
68  }
69 
71  void maybe_close_paragraph()
72  {
73  if (is_p)
74  {
75  std::cout << "</p>\n";
76  is_p = false;
77  }
78  }
79 
81  void print_header()
82  {
83  // Print HTML boilerplate header.
84  std::cout << "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
85  << "http://www.w3.org/TR/html4/strict.dtd\">\n"
86  << "<html lang=\"en\">\n"
87  << "<head>\n"
88  << "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
89  << "<title>" << escape_special_xml_chars(meta.app_name) << " &mdash; "
90  << escape_special_xml_chars(meta.short_description) << "</title>\n"
91  << "</head>\n"
92  << "<body>\n";
93 
94  std::cout << "<h1>" << to_html(meta.app_name) << "</h1>\n"
95  << "<div>" << to_html(meta.short_description) << "</div>\n";
96  }
97 
101  void print_section(std::string const & title)
102  {
103  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
104  maybe_close_list();
105  maybe_close_paragraph();
106  std::cout << "<h2>" << to_html(title) << "</h2>\n";
107  }
108 
112  void print_subsection(std::string const & title)
113  {
114  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
115  maybe_close_list();
116  maybe_close_paragraph();
117  std::cout << "<h3>" << to_html(title) << "</h3>\n";
118  }
119 
125  void print_line(std::string const & text, bool line_is_paragraph)
126  {
127  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
128  maybe_close_list();
129  if (!is_p) // open parapgraph
130  {
131  std::cout << "<p>\n";
132  is_p = true;
133  }
134  std::cout << to_html(text) << "\n";
135  if (line_is_paragraph)
136  maybe_close_paragraph();
137  else
138  std::cout << "<br>\n";
139  }
140 
150  void print_list_item(std::string const & term, std::string const & desc)
151  {
152  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
153  maybe_close_paragraph();
154 
155  if (!is_dl)
156  {
157  std::cout << "<dl>\n";
158  is_dl = true;
159  }
160  std::cout << "<dt>" << to_html(term) << "</dt>\n"
161  << "<dd>" << to_html(desc) << "</dd>\n";
162  }
163 
165  void print_footer()
166  {
167  maybe_close_paragraph();
168 
169  // Print HTML boilerplate footer.
170  std::cout << "</body></html>";
171  }
172 
177  std::string to_html(std::string const & input)
178  {
179  std::string buffer = escape_special_xml_chars(input);
180  std::string result;
181  std::vector<std::string> open_tags; // acts as a stack of html tags
182 
183  for (auto it = input.begin(); it != input.end(); ++it)
184  {
185  if (*it == '\\')
186  {
187  // Handle escape sequence, we interpret only "\-", "\fI", and "\fB".
188  ++it;
189  assert(!(it == input.end()));
190  if (*it == '-')
191  {
192  result.push_back(*it);
193  }
194  else if (*it == 'f')
195  {
196  ++it;
197  assert(!(it == input.end()));
198  if (*it == 'I')
199  {
200  open_tags.push_back("em");
201  result.append("<em>");
202  }
203  else if (*it == 'B')
204  {
205  open_tags.push_back("strong");
206  result.append("<strong>");
207  }
208  else if (*it == 'P')
209  {
210  assert(!open_tags.empty());
211  result.append("</");
212  result.append(open_tags.back());
213  result.append(">");
214  open_tags.pop_back();
215  }
216  else
217  {
218  result.append("\\f");
219  result.push_back(*it);
220  }
221  }
222  else
223  {
224  result.push_back('\\');
225  result.push_back(*it);
226  }
227  }
228  else
229  {
230  result.push_back(*it);
231  }
232  }
233 
234  return result;
235  }
236 
241  std::string in_bold(std::string const & str)
242  {
243  return "<strong>" + str + "</strong>";
244  }
245 
247  bool is_dl{false};
249  bool is_p{false};
250 };
251 
252 } // namespace seqan3::detail
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:255
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.