1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#ifndef NEWSBOAT_HTMLRENDERER_H_
#define NEWSBOAT_HTMLRENDERER_H_
#include <istream>
#include <map>
#include <string>
#include <vector>
#include "textformatter.h"
#include "links.h"
namespace newsboat {
class TagSoupPullParser;
enum class HtmlTag {
A = 1,
EMBED,
IFRAME,
BR,
PRE,
ITUNESHACK,
IMG,
BLOCKQUOTE,
H1,
H2,
H3,
H4,
H5,
H6,
P,
DIV,
OL,
UL,
LI,
DT,
DD,
DL,
SUP,
SUB,
HR,
STRONG,
UNDERLINE,
QUOTATION,
SCRIPT,
STYLE,
TABLE,
TH,
TR,
TD,
VIDEO,
AUDIO,
SOURCE
};
class HtmlRenderer {
public:
explicit HtmlRenderer(bool raw = false);
void render(const std::string& source,
std::vector<std::pair<LineType, std::string>>& lines,
Links& links,
const std::string& url);
void render(std::istream& input,
std::vector<std::pair<LineType, std::string>>& lines,
Links& links,
const std::string& url);
static std::string render_hr(const unsigned int width);
// only public for unit testing purposes:
std::string format_ol_count(unsigned int count, char type);
struct TableCell {
explicit TableCell(size_t s)
: span(s)
{
}
size_t span;
std::vector<std::string> text; // multiline cell text
};
struct TableRow {
TableRow()
: inside(false)
{
}
void add_text(const std::string& str);
void start_cell(size_t span);
void complete_cell();
bool inside; // inside a cell
std::vector<TableCell> cells;
};
struct Table {
explicit Table(bool b)
: inside(false)
, has_border(b)
{
}
void add_text(const std::string& str);
void start_row();
void complete_row();
void start_cell(size_t span);
void complete_cell();
bool inside; // inside a row
bool has_border;
std::vector<TableRow> rows;
};
private:
void prepare_new_line(std::string& line, int indent_level);
bool line_is_nonempty(const std::string& line);
std::string absolute_url(const std::string& url,
const std::string& link);
std::string type2str(LinkType type);
std::map<std::string, HtmlTag> tags;
void render_table(const Table& table,
std::vector<std::pair<LineType, std::string>>& lines);
void add_nonempty_line(const std::string& curline,
std::vector<Table>& tables,
std::vector<std::pair<LineType, std::string>>& lines);
void add_line(const std::string& curline,
std::vector<Table>& tables,
std::vector<std::pair<LineType, std::string>>& lines);
void add_line_softwrappable(const std::string& line,
std::vector<std::pair<LineType, std::string>>& lines);
void add_line_nonwrappable(const std::string& line,
std::vector<std::pair<LineType, std::string>>& lines);
void add_hr(std::vector<std::pair<LineType, std::string>>& lines);
std::string get_char_numbering(unsigned int count);
std::string get_roman_numbering(unsigned int count);
void add_media_link(std::string& line, Links& links,
const std::string& url, const std::string& media_url,
const std::string& media_title, unsigned int media_count,
LinkType type);
HtmlTag extract_tag(TagSoupPullParser& parser);
bool raw_;
};
} // namespace newsboat
#endif /* NEWSBOAT_HTMLRENDERER_H_ */
|