SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
21namespace seqan3::detail
22{
23
36class format_html : public format_help_base<format_html>
37{
39 using base_type = format_help_base<format_html>;
40
42 friend base_type;
43
44public:
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
59private:
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 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: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.