SeqAn3  3.1.0
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 
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}
57  {};
59 
60 private:
62  void maybe_close_list()
63  {
64  if (is_dl)
65  {
66  std::cout << "</dl>\n";
67  is_dl = false;
68  }
69  }
70 
72  void maybe_close_paragraph()
73  {
74  if (is_p)
75  {
76  std::cout << "</p>\n";
77  is_p = false;
78  }
79  }
80 
82  void print_header()
83  {
84  // Print HTML boilerplate header.
85  std::cout << "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
86  << "http://www.w3.org/TR/html4/strict.dtd\">\n"
87  << "<html lang=\"en\">\n"
88  << "<head>\n"
89  << "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n"
90  << "<title>" << escape_special_xml_chars(meta.app_name) << " &mdash; "
91  << escape_special_xml_chars(meta.short_description) << "</title>\n"
92  << "</head>\n"
93  << "<body>\n";
94 
95  std::cout << "<h1>" << to_html(meta.app_name) << "</h1>\n"
96  << "<div>" << to_html(meta.short_description) << "</div>\n";
97  }
98 
102  void print_section(std::string const & title)
103  {
104  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
105  maybe_close_list();
106  maybe_close_paragraph();
107  std::cout << "<h2>" << to_html(title) << "</h2>\n";
108  }
109 
113  void print_subsection(std::string const & title)
114  {
115  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
116  maybe_close_list();
117  maybe_close_paragraph();
118  std::cout << "<h3>" << to_html(title) << "</h3>\n";
119  }
120 
126  void print_line(std::string const & text, bool line_is_paragraph)
127  {
128  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
129  maybe_close_list();
130  if (!is_p) // open parapgraph
131  {
132  std::cout << "<p>\n";
133  is_p = true;
134  }
135  std::cout << to_html(text) << "\n";
136  if (line_is_paragraph)
137  maybe_close_paragraph();
138  else
139  std::cout << "<br>\n";
140  }
141 
151  void print_list_item(std::string const & term, std::string const & desc)
152  {
153  // SEQAN_ASSERT_NOT_MSG(isDl && isP, "Current <dl> and <p> are mutually exclusive.");
154  maybe_close_paragraph();
155 
156  if (!is_dl)
157  {
158  std::cout << "<dl>\n";
159  is_dl = true;
160  }
161  std::cout << "<dt>" << to_html(term) << "</dt>\n"
162  << "<dd>" << to_html(desc) << "</dd>\n";
163  }
164 
166  void print_footer()
167  {
168  maybe_close_paragraph();
169 
170  // Print HTML boilerplate footer.
171  std::cout << "</body></html>";
172  }
173 
178  std::string to_html(std::string const & input)
179  {
180  std::string buffer = escape_special_xml_chars(input);
181  std::string result;
182  std::vector<std::string> open_tags; // acts as a stack of html tags
183 
184  for (auto it = input.begin(); it != input.end(); ++it)
185  {
186  if (*it == '\\')
187  {
188  // Handle escape sequence, we interpret only "\-", "\fI", and "\fB".
189  ++it;
190  assert(!(it == input.end()));
191  if (*it == '-')
192  {
193  result.push_back(*it);
194  }
195  else if (*it == 'f')
196  {
197  ++it;
198  assert(!(it == input.end()));
199  if (*it == 'I')
200  {
201  open_tags.push_back("em");
202  result.append("<em>");
203  }
204  else if (*it == 'B')
205  {
206  open_tags.push_back("strong");
207  result.append("<strong>");
208  }
209  else if (*it == 'P')
210  {
211  assert(!open_tags.empty());
212  result.append("</");
213  result.append(open_tags.back());
214  result.append(">");
215  open_tags.pop_back();
216  }
217  else
218  {
219  result.append("\\f");
220  result.push_back(*it);
221  }
222  }
223  else
224  {
225  result.push_back('\\');
226  result.push_back(*it);
227  }
228  }
229  else
230  {
231  result.push_back(*it);
232  }
233  }
234 
235  return result;
236  }
237 
242  std::string in_bold(std::string const & str)
243  {
244  return "<strong>" + str + "</strong>";
245  }
246 
248  bool is_dl{false};
250  bool is_p{false};
251 };
252 
253 } // 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:256
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.