8 #ifndef INCLUDED_ORCUS_CSS_PARSER_HPP
9 #define INCLUDED_ORCUS_CSS_PARSER_HPP
11 #define ORCUS_DEBUG_CSS 0
13 #include "parser_global.hpp"
14 #include "css_parser_base.hpp"
199 void rgb(uint8_t red, uint8_t green, uint8_t blue)
201 (void)red; (void)green; (void)blue;
213 void rgba(uint8_t red, uint8_t green, uint8_t blue,
double alpha)
215 (void)red; (void)green; (void)blue; (void)alpha;
225 void hsl(uint8_t hue, uint8_t sat, uint8_t light)
227 (void)hue; (void)sat; (void)light;
239 void hsla(uint8_t hue, uint8_t sat, uint8_t light,
double alpha)
241 (void)hue; (void)sat; (void)light; (void)alpha;
300 template<
typename HandlerT>
304 typedef HandlerT handler_type;
306 css_parser(std::string_view content, handler_type& hdl);
316 void simple_selector_name();
317 void property_name();
319 void quoted_value(
char c);
321 void function_value(std::string_view v);
322 void function_rgb(
bool alpha);
323 void function_hsl(
bool alpha);
329 handler_type& m_handler;
332 template<
typename _Handler>
336 template<
typename _Handler>
337 void css_parser<_Handler>::parse()
342 std::cout <<
"compressed: '";
343 const char* p = mp_char;
344 for (; p != mp_end; ++p)
346 std::cout <<
"'" << std::endl;
348 m_handler.begin_parse();
351 m_handler.end_parse();
354 template<
typename _Handler>
355 void css_parser<_Handler>::rule()
366 simple_selector_name();
373 set_combinator(c, css::combinator_t::direct_child);
376 set_combinator(c, css::combinator_t::next_sibling);
381 simple_selector_name();
387 reset_before_block();
391 parse_error::throw_with(
"rule: failed to parse '", c,
"'", offset());
396 template<
typename _Handler>
397 void css_parser<_Handler>::at_rule_name()
400 assert(cur_char() ==
'@');
404 throw parse_error(
"at_rule_name: first character of an at-rule name must be an alphabet.", offset());
411 m_handler.at_rule_name({p, len});
413 std::string foo(p, len);
414 std::cout <<
"at-rule name: " << foo.c_str() << std::endl;
418 template<
typename _Handler>
419 void css_parser<_Handler>::simple_selector_name()
430 if (m_simple_selector_count)
433 cout <<
"combinator: " << m_combinator << endl;
435 m_handler.combinator(m_combinator);
436 m_combinator = css::combinator_t::descendant;
438 assert(is_alpha(c) || c ==
'.' || c ==
'#');
440 const char* p =
nullptr;
444 cout <<
"simple_selector_name: (" << m_simple_selector_count <<
")";
447 if (c !=
'.' && c !=
'#')
452 cout <<
" type=" << s;
454 m_handler.simple_selector_type({p, n});
458 while (in_loop && has_char())
466 m_handler.simple_selector_class({p, n});
469 std::cout <<
" class=" << s;
477 m_handler.simple_selector_id({p, n});
480 std::cout <<
" id=" << s;
488 if (cur_char() ==
':')
493 css::pseudo_element_t elem = css::to_pseudo_element({p, n});
495 parse_error::throw_with(
496 "selector_name: unknown pseudo element '", {p, n},
"'", offset());
498 m_handler.simple_selector_pseudo_element(elem);
504 css::pseudo_class_t pc = css::to_pseudo_class({p, n});
506 parse_error::throw_with(
507 "selector_name: unknown pseudo class '", {p, n},
"'", offset());
509 m_handler.simple_selector_pseudo_class(pc);
518 m_handler.end_simple_selector();
519 skip_comments_and_blanks();
521 ++m_simple_selector_count;
524 std::cout << std::endl;
528 template<
typename _Handler>
529 void css_parser<_Handler>::property_name()
535 if (!is_alpha(c) && c !=
'.')
536 parse_error::throw_with(
537 "property_name: first character of a name must be an alphabet or a dot, but found '", c,
"'", offset());
542 skip_comments_and_blanks();
544 m_handler.property_name({p, len});
546 std::string foo(p, len);
547 std::cout <<
"property name: " << foo.c_str() << std::endl;
551 template<
typename _Handler>
552 void css_parser<_Handler>::property()
556 m_handler.begin_property();
558 if (cur_char() !=
':')
559 throw parse_error(
"property: ':' expected.", offset());
561 skip_comments_and_blanks();
564 while (in_loop && has_char())
574 skip_comments_and_blanks();
586 skip_comments_and_blanks();
587 m_handler.end_property();
590 template<
typename _Handler>
591 void css_parser<_Handler>::quoted_value(
char c)
594 const char* p =
nullptr;
600 m_handler.value({p, len});
602 std::string foo(p, len);
603 std::cout <<
"quoted value: " << foo.c_str() << std::endl;
607 template<
typename _Handler>
608 void css_parser<_Handler>::value()
612 if (c ==
'"' || c ==
'\'')
618 std::string_view v = parse_value();
622 if (cur_char() ==
'(')
630 skip_comments_and_blanks();
633 std::cout <<
"value: " << v << std::endl;
637 template<
typename _Handler>
638 void css_parser<_Handler>::function_value(std::string_view v)
640 assert(cur_char() ==
'(');
641 css::property_function_t func = css::to_property_function(v);
642 if (func == css::property_function_t::unknown)
643 parse_error::throw_with(
"function_value: unknown function '", v,
"'", offset());
647 skip_comments_and_blanks();
651 case css::property_function_t::rgb:
654 case css::property_function_t::rgba:
657 case css::property_function_t::hsl:
660 case css::property_function_t::hsla:
663 case css::property_function_t::url:
667 parse_error::throw_with(
"function_value: unhandled function '", v,
"'", offset());
672 parse_error::throw_with(
"function_value: ')' expected but '", c,
"' found.", offset());
675 skip_comments_and_blanks();
678 template<
typename _Handler>
679 void css_parser<_Handler>::function_rgb(
bool alpha)
685 const uint8_t* plast = p + 2;
692 skip_comments_and_blanks();
700 parse_error::throw_with(
"function_rgb: ',' expected but '", c,
"' found.", offset());
703 skip_comments_and_blanks();
710 parse_error::throw_with(
"function_rgb: ',' expected but '", c,
"' found.", offset());
713 skip_comments_and_blanks();
715 double alpha_val = parse_double_or_throw();
717 alpha_val = std::clamp(alpha_val, 0.0, 1.0);
718 m_handler.rgba(vals[0], vals[1], vals[2], alpha_val);
721 m_handler.rgb(vals[0], vals[1], vals[2]);
729 const uint8_t* pend = plast + 1;
730 for (; p != pend; ++p)
731 std::cout <<
' ' << (
int)*p;
732 std::cout <<
" )" << std::endl;
736 template<
typename _Handler>
737 void css_parser<_Handler>::function_hsl(
bool alpha)
741 double hue = parse_double_or_throw();
742 hue = std::clamp(hue, 0.0, 360.0);
743 skip_comments_and_blanks();
747 parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.", offset());
750 skip_comments_and_blanks();
752 double sat = parse_percent();
753 sat = std::clamp(sat, 0.0, 100.0);
754 skip_comments_and_blanks();
758 parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.", offset());
761 skip_comments_and_blanks();
763 double light = parse_percent();
764 light = std::clamp(light, 0.0, 100.0);
765 skip_comments_and_blanks();
769 m_handler.hsl(hue, sat, light);
775 parse_error::throw_with(
"function_hsl: ',' expected but '", c,
"' found.", offset());
778 skip_comments_and_blanks();
780 double alpha_val = parse_double_or_throw();
781 alpha_val = std::clamp(alpha_val, 0.0, 1.0);
782 skip_comments_and_blanks();
783 m_handler.hsla(hue, sat, light, alpha_val);
786 template<
typename _Handler>
787 void css_parser<_Handler>::function_url()
791 if (c ==
'"' || c ==
'\'')
798 skip_comments_and_blanks();
799 m_handler.url({p, len});
801 std::cout <<
"url(" << std::string(p, len) <<
")" << std::endl;
809 skip_to_or_blank(p, len,
")");
810 skip_comments_and_blanks();
811 m_handler.url({p, len});
813 std::cout <<
"url(" << std::string(p, len) <<
")" << std::endl;
817 template<
typename _Handler>
818 void css_parser<_Handler>::name_sep()
820 assert(cur_char() ==
',');
822 std::cout <<
"," << std::endl;
826 m_handler.end_selector();
829 template<
typename _Handler>
830 void css_parser<_Handler>::property_sep()
833 std::cout <<
";" << std::endl;
836 skip_comments_and_blanks();
839 template<
typename _Handler>
840 void css_parser<_Handler>::block()
844 assert(cur_char() ==
'{');
846 std::cout <<
"{" << std::endl;
848 m_handler.end_selector();
849 m_handler.begin_block();
852 skip_comments_and_blanks();
858 if (cur_char() !=
';')
861 if (cur_char() ==
'}')
866 if (cur_char() !=
'}')
867 throw parse_error(
"block: '}' expected.", offset());
869 m_handler.end_block();
872 skip_comments_and_blanks();
875 std::cout <<
"}" << std::endl;
Definition: css_parser_base.hpp:22
Definition: css_parser.hpp:32
void url(std::string_view url)
Definition: css_parser.hpp:249
void end_parse()
Definition: css_parser.hpp:262
void end_block()
Definition: css_parser.hpp:274
void property_name(std::string_view name)
Definition: css_parser.hpp:177
void at_rule_name(std::string_view name)
Definition: css_parser.hpp:39
void hsl(uint8_t hue, uint8_t sat, uint8_t light)
Definition: css_parser.hpp:225
void end_property()
Definition: css_parser.hpp:291
void begin_parse()
Definition: css_parser.hpp:257
void end_selector()
Definition: css_parser.hpp:151
void begin_block()
Definition: css_parser.hpp:268
void simple_selector_pseudo_element(orcus::css::pseudo_element_t pe)
Definition: css_parser.hpp:95
void simple_selector_class(std::string_view cls)
Definition: css_parser.hpp:75
void rgba(uint8_t red, uint8_t green, uint8_t blue, double alpha)
Definition: css_parser.hpp:213
void rgb(uint8_t red, uint8_t green, uint8_t blue)
Definition: css_parser.hpp:199
void begin_property()
Definition: css_parser.hpp:286
void simple_selector_pseudo_class(orcus::css::pseudo_class_t pc)
Definition: css_parser.hpp:114
void hsla(uint8_t hue, uint8_t sat, uint8_t light, double alpha)
Definition: css_parser.hpp:239
void simple_selector_id(std::string_view id)
Definition: css_parser.hpp:132
void combinator(orcus::css::combinator_t combinator)
Definition: css_parser.hpp:167
void simple_selector_type(std::string_view type)
Definition: css_parser.hpp:57
void value(std::string_view value)
Definition: css_parser.hpp:187
void end_simple_selector()
Definition: css_parser.hpp:143
Definition: css_parser.hpp:302
Definition: parser_base.hpp:23