8 #ifndef INCLUDED_ORCUS_CSS_PARSER_HPP
9 #define INCLUDED_ORCUS_CSS_PARSER_HPP
11 #define ORCUS_DEBUG_CSS 0
13 #include "orcus/parser_global.hpp"
14 #include "orcus/css_parser_base.hpp"
15 #include "orcus/global.hpp"
34 void at_rule_name(
const char* p,
size_t n)
39 void simple_selector_type(
const char* p,
size_t n)
44 void simple_selector_class(
const char* p,
size_t n)
49 void simple_selector_pseudo_element(orcus::css::pseudo_element_t pe)
54 void simple_selector_pseudo_class(orcus::css::pseudo_class_t pc)
59 void simple_selector_id(
const char* p,
size_t n)
64 void end_simple_selector() {}
66 void end_selector() {}
68 void combinator(orcus::css::combinator_t combinator)
90 void value(
const char* p,
size_t n)
102 void rgb(uint8_t red, uint8_t green, uint8_t blue)
104 (void)red; (void)green; (void)blue;
116 void rgba(uint8_t red, uint8_t green, uint8_t blue,
double alpha)
118 (void)red; (void)green; (void)blue; (void)alpha;
128 void hsl(uint8_t hue, uint8_t sat, uint8_t light)
130 (void)hue; (void)sat; (void)light;
142 void hsla(uint8_t hue, uint8_t sat, uint8_t light,
double alpha)
144 (void)hue; (void)sat; (void)light; (void)alpha;
153 void url(
const char* p,
size_t n)
191 template<
typename _Handler>
195 typedef _Handler handler_type;
197 css_parser(
const char* p,
size_t n, handler_type& hdl);
207 void simple_selector_name();
208 void property_name();
210 void quoted_value(
char c);
212 void function_value(
const char* p,
size_t len);
213 void function_rgb(
bool alpha);
214 void function_hsl(
bool alpha);
220 handler_type& m_handler;
223 template<
typename _Handler>
227 template<
typename _Handler>
228 void css_parser<_Handler>::parse()
233 std::cout <<
"compressed: '";
234 const char* p = mp_char;
235 for (; p != mp_end; ++p)
237 std::cout <<
"'" << std::endl;
239 m_handler.begin_parse();
242 m_handler.end_parse();
245 template<
typename _Handler>
246 void css_parser<_Handler>::rule()
257 simple_selector_name();
264 set_combinator(c, css::combinator_t::direct_child);
267 set_combinator(c, css::combinator_t::next_sibling);
272 simple_selector_name();
278 reset_before_block();
282 css::parse_error::throw_with(
"rule: failed to parse '", c,
"'");
287 template<
typename _Handler>
288 void css_parser<_Handler>::at_rule_name()
291 assert(cur_char() ==
'@');
295 throw css::parse_error(
"at_rule_name: first character of an at-rule name must be an alphabet.");
302 m_handler.at_rule_name(p, len);
304 std::string foo(p, len);
305 std::cout <<
"at-rule name: " << foo.c_str() << std::endl;
309 template<
typename _Handler>
310 void css_parser<_Handler>::simple_selector_name()
321 if (m_simple_selector_count)
324 cout <<
"combinator: " << m_combinator << endl;
326 m_handler.combinator(m_combinator);
327 m_combinator = css::combinator_t::descendant;
329 assert(is_alpha(c) || c ==
'.' || c ==
'#');
331 const char* p =
nullptr;
335 cout <<
"simple_selector_name: (" << m_simple_selector_count <<
")";
338 if (c !=
'.' && c !=
'#')
343 cout <<
" type=" << s;
345 m_handler.simple_selector_type(p, n);
349 while (in_loop && has_char())
357 m_handler.simple_selector_class(p, n);
360 std::cout <<
" class=" << s;
368 m_handler.simple_selector_id(p, n);
371 std::cout <<
" id=" << s;
379 if (cur_char() ==
':')
384 css::pseudo_element_t elem = css::to_pseudo_element(p, n);
386 css::parse_error::throw_with(
387 "selector_name: unknown pseudo element '", p, n,
"'");
389 m_handler.simple_selector_pseudo_element(elem);
395 css::pseudo_class_t pc = css::to_pseudo_class(p, n);
397 css::parse_error::throw_with(
398 "selector_name: unknown pseudo class '", p, n,
"'");
400 m_handler.simple_selector_pseudo_class(pc);
409 m_handler.end_simple_selector();
410 skip_comments_and_blanks();
412 ++m_simple_selector_count;
415 std::cout << std::endl;
419 template<
typename _Handler>
420 void css_parser<_Handler>::property_name()
426 if (!is_alpha(c) && c !=
'.')
427 css::parse_error::throw_with(
428 "property_name: first character of a name must be an alphabet or a dot, but found '", c,
"'");
433 skip_comments_and_blanks();
435 m_handler.property_name(p, len);
437 std::string foo(p, len);
438 std::cout <<
"property name: " << foo.c_str() << std::endl;
442 template<
typename _Handler>
443 void css_parser<_Handler>::property()
447 m_handler.begin_property();
449 if (cur_char() !=
':')
450 throw css::parse_error(
"property: ':' expected.");
452 skip_comments_and_blanks();
455 while (in_loop && has_char())
465 skip_comments_and_blanks();
477 skip_comments_and_blanks();
478 m_handler.end_property();
481 template<
typename _Handler>
482 void css_parser<_Handler>::quoted_value(
char c)
485 const char* p =
nullptr;
491 m_handler.value(p, len);
493 std::string foo(p, len);
494 std::cout <<
"quoted value: " << foo.c_str() << std::endl;
498 template<
typename _Handler>
499 void css_parser<_Handler>::value()
503 if (c ==
'"' || c ==
'\'')
509 if (!is_alpha(c) && !is_numeric(c) && !is_in(c, ORCUS_ASCII(
"-+.#")))
510 css::parse_error::throw_with(
"value:: illegal first character of a value '", c,
"'");
512 const char* p =
nullptr;
514 identifier(p, len, ORCUS_ASCII(
".%"));
515 if (cur_char() ==
'(')
517 function_value(p, len);
521 m_handler.value(p, len);
523 skip_comments_and_blanks();
526 std::string foo(p, len);
527 std::cout <<
"value: " << foo.c_str() << std::endl;
531 template<
typename _Handler>
532 void css_parser<_Handler>::function_value(
const char* p,
size_t len)
534 assert(cur_char() ==
'(');
535 css::property_function_t func = css::to_property_function(p, len);
536 if (func == css::property_function_t::unknown)
537 css::parse_error::throw_with(
"function_value: unknown function '", p, len,
"'");
541 skip_comments_and_blanks();
545 case css::property_function_t::rgb:
548 case css::property_function_t::rgba:
551 case css::property_function_t::hsl:
554 case css::property_function_t::hsla:
557 case css::property_function_t::url:
561 css::parse_error::throw_with(
"function_value: unhandled function '", p, len,
"'");
566 css::parse_error::throw_with(
"function_value: ')' expected but '", c,
"' found.");
569 skip_comments_and_blanks();
572 template<
typename _Handler>
573 void css_parser<_Handler>::function_rgb(
bool alpha)
579 const uint8_t* plast = p + 2;
586 skip_comments_and_blanks();
594 css::parse_error::throw_with(
"function_rgb: ',' expected but '", c,
"' found.");
597 skip_comments_and_blanks();
604 css::parse_error::throw_with(
"function_rgb: ',' expected but '", c,
"' found.");
607 skip_comments_and_blanks();
609 double alpha_val = parse_double_or_throw();
611 alpha_val = clip(alpha_val, 0.0, 1.0);
612 m_handler.rgba(vals[0], vals[1], vals[2], alpha_val);
615 m_handler.rgb(vals[0], vals[1], vals[2]);
623 const uint8_t* pend = plast + 1;
624 for (; p != pend; ++p)
625 std::cout <<
' ' << (
int)*p;
626 std::cout <<
" )" << std::endl;
630 template<
typename _Handler>
631 void css_parser<_Handler>::function_hsl(
bool alpha)
635 double hue = parse_double_or_throw();
636 hue = clip(hue, 0.0, 360.0);
637 skip_comments_and_blanks();
641 css::parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.");
644 skip_comments_and_blanks();
646 double sat = parse_percent();
647 sat = clip(sat, 0.0, 100.0);
648 skip_comments_and_blanks();
652 css::parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.");
655 skip_comments_and_blanks();
657 double light = parse_percent();
658 light = clip(light, 0.0, 100.0);
659 skip_comments_and_blanks();
663 m_handler.hsl(hue, sat, light);
669 css::parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.");
672 skip_comments_and_blanks();
674 double alpha_val = parse_double_or_throw();
675 alpha_val = clip(alpha_val, 0.0, 1.0);
676 skip_comments_and_blanks();
677 m_handler.hsla(hue, sat, light, alpha_val);
680 template<
typename _Handler>
681 void css_parser<_Handler>::function_url()
685 if (c ==
'"' || c ==
'\'')
692 skip_comments_and_blanks();
693 m_handler.url(p, len);
695 std::cout <<
"url(" << std::string(p, len) <<
")" << std::endl;
703 skip_to_or_blank(p, len, ORCUS_ASCII(
")"));
704 skip_comments_and_blanks();
705 m_handler.url(p, len);
707 std::cout <<
"url(" << std::string(p, len) <<
")" << std::endl;
711 template<
typename _Handler>
712 void css_parser<_Handler>::name_sep()
714 assert(cur_char() ==
',');
716 std::cout <<
"," << std::endl;
720 m_handler.end_selector();
723 template<
typename _Handler>
724 void css_parser<_Handler>::property_sep()
727 std::cout <<
";" << std::endl;
730 skip_comments_and_blanks();
733 template<
typename _Handler>
734 void css_parser<_Handler>::block()
738 assert(cur_char() ==
'{');
740 std::cout <<
"{" << std::endl;
742 m_handler.end_selector();
743 m_handler.begin_block();
746 skip_comments_and_blanks();
752 if (cur_char() !=
';')
755 if (cur_char() ==
'}')
760 if (cur_char() !=
'}')
761 throw css::parse_error(
"block: '}' expected.");
763 m_handler.end_block();
766 skip_comments_and_blanks();
769 std::cout <<
"}" << std::endl;
Definition: css_parser_base.hpp:31
Definition: css_parser.hpp:32
void end_parse()
Definition: css_parser.hpp:166
void end_block()
Definition: css_parser.hpp:178
void hsl(uint8_t hue, uint8_t sat, uint8_t light)
Definition: css_parser.hpp:128
void value(const char *p, size_t n)
Definition: css_parser.hpp:90
void end_property()
Definition: css_parser.hpp:188
void begin_parse()
Definition: css_parser.hpp:161
void begin_block()
Definition: css_parser.hpp:172
void url(const char *p, size_t n)
Definition: css_parser.hpp:153
void rgba(uint8_t red, uint8_t green, uint8_t blue, double alpha)
Definition: css_parser.hpp:116
void property_name(const char *p, size_t n)
Definition: css_parser.hpp:79
void rgb(uint8_t red, uint8_t green, uint8_t blue)
Definition: css_parser.hpp:102
void begin_property()
Definition: css_parser.hpp:183
void hsla(uint8_t hue, uint8_t sat, uint8_t light, double alpha)
Definition: css_parser.hpp:142
Definition: css_parser.hpp:193
Definition: parser_base.hpp:41