#ifndef HTML_PARSER_H
#define HTML_PARSER_H
/*
A small html parser with no dependencies and doesn't dynamically allocate any memory
and can parse and repair broken html (just like web browsers)
*/
#include
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const char *data;
size_t size;
} HtmlStringView;
typedef struct HtmlParser HtmlParser;
typedef enum{
HTML_PARSE_TAG_START,
HTML_PARSE_TAG_END,
HTML_PARSE_ATTRIBUTE,
HTML_PARSE_TEXT,
HTML_PARSE_JAVASCRIPT_CODE
} HtmlParseType;
/* Return 0 to continue */
typedef int (*HtmlParseCallback)(HtmlParser *html_parser, HtmlParseType parse_type, void *userdata);
#define UNCLOSED_TAGS_SIZE 2048
struct HtmlParser {
const char *source;
size_t source_len;
size_t offset;
HtmlParseCallback parse_callback;
void *callback_userdata;
/* The name of the current enclosing tag */
HtmlStringView tag_name;
HtmlStringView attribute_key;
HtmlStringView attribute_value;
HtmlStringView text;
HtmlStringView text_stripped;
HtmlStringView tag_before_void_tag;
int is_tag_void;
int inside_script_tag;
size_t unclosed_tags_offset;
HtmlStringView unclosed_tags[UNCLOSED_TAGS_SIZE];
};
/*
Returns the value returned from |parse_callback|. 0 meaning success.
Note: HTML_PARSE_TAG_START is guaranteed to be called for a tag before HTML_PARSE_TAG_END.
Note: HTML_PARSE_TEXT may be called multiple times for a tag. For example if a tag has multiple text items split between child tags
like this: hello
text
world
.
In this case, HTML_PARSE_TEXT will be called twice for the div tag. First with "hello" and then with "world".
*/
int html_parser_parse(const char *html_source, size_t len, HtmlParseCallback parse_callback, void *userdata);
#ifdef __cplusplus
}
#endif
#endif /* HTML_PARSER_H */