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
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}
57 {};
59
60private:
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.