diff --git a/src/document/css/apply.c b/src/document/css/apply.c index 563cf596..92c894a9 100644 --- a/src/document/css/apply.c +++ b/src/document/css/apply.c @@ -95,6 +95,38 @@ css_apply_font_attribute(struct html_context *html_context, element->attr.style.attr &= ~prop->value.font_attribute.rem; } +static void +css_apply_list_style(struct html_context *html_context, + struct html_element *element, struct css_property *prop) +{ + assert(prop->value_type == CSS_VT_LIST_STYLE); + + element->parattr.list_number = (prop->value.list_style > CSS_LIST_ORDINAL); + switch (prop->value.list_style) { + case CSS_LIST_NONE: element->parattr.flags = P_NO_BULLET; break; + case CSS_LIST_DISC: element->parattr.flags = P_O; break; + case CSS_LIST_CIRCLE: element->parattr.flags = P_O; break; + case CSS_LIST_SQUARE: element->parattr.flags = P_PLUS; break; + case CSS_LIST_DECIMAL: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_DECIMAL_LEADING_ZERO: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_LOWER_ROMAN: element->parattr.flags = P_roman; break; + case CSS_LIST_UPPER_ROMAN: element->parattr.flags = P_ROMAN; break; + case CSS_LIST_LOWER_ALPHA: element->parattr.flags = P_alpha; break; + case CSS_LIST_UPPER_ALPHA: element->parattr.flags = P_ALPHA; break; + case CSS_LIST_LOWER_GREEK: element->parattr.flags = P_roman; break; + case CSS_LIST_LOWER_LATIN: element->parattr.flags = P_alpha; break; + case CSS_LIST_UPPER_LATIN: element->parattr.flags = P_ALPHA; break; + case CSS_LIST_HEBREW: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_ARMENIAN: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_GEORGIAN: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_CJK_IDEOGRAPHIC: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_HIRAGANA: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_KATAKANA: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_HIRAGANA_IROHA: element->parattr.flags = P_NUMBER; break; + case CSS_LIST_KATAKANA_IROHA: element->parattr.flags = P_NUMBER; break; + } +} + /** @bug FIXME: Because the current CSS doesn't provide reasonable * defaults for each HTML element this applier will cause bad * rendering of @
tags. */ @@ -115,6 +147,7 @@ static const css_applier_T css_appliers[CSS_PT_LAST] = { /* CSS_PT_DISPLAY */ css_apply_display, /* CSS_PT_FONT_STYLE */ css_apply_font_attribute, /* CSS_PT_FONT_WEIGHT */ css_apply_font_attribute, + /* CSS_PT_LIST_STYLE */ css_apply_list_style, /* CSS_PT_TEXT_ALIGN */ css_apply_text_align, /* CSS_PT_TEXT_DECORATION */ css_apply_font_attribute, /* CSS_PT_WHITE_SPACE */ css_apply_font_attribute, diff --git a/src/document/css/property.c b/src/document/css/property.c index 553bbcfd..3914fd1c 100644 --- a/src/document/css/property.c +++ b/src/document/css/property.c @@ -22,6 +22,7 @@ struct css_property_info css_property_info[CSS_PT_LAST] = { { "display", CSS_PT_DISPLAY, CSS_VT_DISPLAY, css_parse_display_value }, { "font-style", CSS_PT_FONT_STYLE, CSS_VT_FONT_ATTRIBUTE, css_parse_font_style_value }, { "font-weight", CSS_PT_FONT_WEIGHT, CSS_VT_FONT_ATTRIBUTE, css_parse_font_weight_value }, + { "list-style", CSS_PT_LIST_STYLE, CSS_VT_LIST_STYLE, css_parse_list_style_value }, { "text-align", CSS_PT_TEXT_ALIGN, CSS_VT_TEXT_ALIGN, css_parse_text_align_value }, { "text-decoration", CSS_PT_TEXT_DECORATION, CSS_VT_FONT_ATTRIBUTE, css_parse_text_decoration_value }, { "white-space", CSS_PT_WHITE_SPACE, CSS_VT_FONT_ATTRIBUTE, css_parse_white_space_value }, diff --git a/src/document/css/property.h b/src/document/css/property.h index 995f460e..3d96e66d 100644 --- a/src/document/css/property.h +++ b/src/document/css/property.h @@ -3,6 +3,7 @@ #define EL__DOCUMENT_CSS_PROPERTY_H #include "document/format.h" +#include "document/html/parser.h" #include "util/align.h" #include "util/color.h" #include "util/lists.h" @@ -23,6 +24,7 @@ struct css_property { CSS_PT_DISPLAY, CSS_PT_FONT_STYLE, CSS_PT_FONT_WEIGHT, + CSS_PT_LIST_STYLE, CSS_PT_TEXT_ALIGN, CSS_PT_TEXT_DECORATION, CSS_PT_WHITE_SPACE, @@ -35,6 +37,7 @@ struct css_property { CSS_VT_COLOR, CSS_VT_DISPLAY, CSS_VT_FONT_ATTRIBUTE, + CSS_VT_LIST_STYLE, CSS_VT_TEXT_ALIGN, CSS_VT_LAST, } value_type; @@ -53,6 +56,30 @@ struct css_property { enum text_style_format add, rem; } font_attribute; enum format_align text_align; + enum css_list_style { + CSS_LIST_NONE, + CSS_LIST_DISC, + CSS_LIST_CIRCLE, + CSS_LIST_SQUARE, + CSS_LIST_ORDINAL, /* Marker value */ + CSS_LIST_DECIMAL, + CSS_LIST_DECIMAL_LEADING_ZERO, + CSS_LIST_LOWER_ROMAN, + CSS_LIST_UPPER_ROMAN, + CSS_LIST_LOWER_ALPHA, + CSS_LIST_UPPER_ALPHA, + CSS_LIST_LOWER_GREEK, + CSS_LIST_LOWER_LATIN, + CSS_LIST_UPPER_LATIN, + CSS_LIST_HEBREW, + CSS_LIST_ARMENIAN, + CSS_LIST_GEORGIAN, + CSS_LIST_CJK_IDEOGRAPHIC, + CSS_LIST_HIRAGANA, + CSS_LIST_KATAKANA, + CSS_LIST_HIRAGANA_IROHA, + CSS_LIST_KATAKANA_IROHA, + } list_style; /* TODO: * Generic numbers * Percentages diff --git a/src/document/css/value.c b/src/document/css/value.c index a58f0521..3d96285e 100644 --- a/src/document/css/value.c +++ b/src/document/css/value.c @@ -197,6 +197,88 @@ css_parse_font_weight_value(struct css_property_info *propinfo, } +int +css_parse_list_style_value(struct css_property_info *propinfo, + union css_property_value *value, + struct scanner *scanner) +{ + struct scanner_token *token = get_scanner_token(scanner); + + assert(propinfo->value_type == CSS_VT_LIST_STYLE); + + if (token->type != CSS_TOKEN_IDENT) return 0; + + if (scanner_token_contains(token, "none")) { + value->list_style = CSS_LIST_NONE; + + } else if (scanner_token_contains(token, "disc")) { + value->list_style = CSS_LIST_DISC; + + } else if (scanner_token_contains(token, "circle")) { + value->list_style = CSS_LIST_CIRCLE; + + } else if (scanner_token_contains(token, "square")) { + value->list_style = CSS_LIST_SQUARE; + + } else if (scanner_token_contains(token, "decimal")) { + value->list_style = CSS_LIST_DECIMAL; + + } else if (scanner_token_contains(token, "decimal-leading-zero")) { + value->list_style = CSS_LIST_DECIMAL_LEADING_ZERO; + + } else if (scanner_token_contains(token, "lower-roman")) { + value->list_style = CSS_LIST_LOWER_ROMAN; + + } else if (scanner_token_contains(token, "upper-roman")) { + value->list_style = CSS_LIST_UPPER_ROMAN; + + } else if (scanner_token_contains(token, "lower-alpha")) { + value->list_style = CSS_LIST_LOWER_ALPHA; + + } else if (scanner_token_contains(token, "upper-alpha")) { + value->list_style = CSS_LIST_UPPER_ALPHA; + + } else if (scanner_token_contains(token, "lower-greek")) { + value->list_style = CSS_LIST_LOWER_GREEK; + + } else if (scanner_token_contains(token, "lower-latin")) { + value->list_style = CSS_LIST_LOWER_LATIN; + + } else if (scanner_token_contains(token, "upper-latin")) { + value->list_style = CSS_LIST_UPPER_LATIN; + + } else if (scanner_token_contains(token, "hebrew")) { + value->list_style = CSS_LIST_HEBREW; + + } else if (scanner_token_contains(token, "armenian")) { + value->list_style = CSS_LIST_ARMENIAN; + + } else if (scanner_token_contains(token, "georgian")) { + value->list_style = CSS_LIST_GEORGIAN; + + } else if (scanner_token_contains(token, "cjk-ideographic")) { + value->list_style = CSS_LIST_CJK_IDEOGRAPHIC; + + } else if (scanner_token_contains(token, "hiragana")) { + value->list_style = CSS_LIST_HIRAGANA; + + } else if (scanner_token_contains(token, "katakana")) { + value->list_style = CSS_LIST_KATAKANA; + + } else if (scanner_token_contains(token, "hiragana-iroha")) { + value->list_style = CSS_LIST_HIRAGANA_IROHA; + + } else if (scanner_token_contains(token, "katakana-iroha")) { + value->list_style = CSS_LIST_KATAKANA_IROHA; + + } else { + return 0; + } + + skip_css_tokens(scanner, CSS_TOKEN_IDENT); + return 1; +} + int css_parse_text_align_value(struct css_property_info *propinfo, union css_property_value *value, diff --git a/src/document/css/value.h b/src/document/css/value.h index 25730170..96ab9b5e 100644 --- a/src/document/css/value.h +++ b/src/document/css/value.h @@ -51,6 +51,10 @@ int css_parse_font_style_value(struct css_property_info *propinfo, int css_parse_font_weight_value(struct css_property_info *propinfo, union css_property_value *value, struct scanner *scanner); +/*! Takes no parser_data. */ +int css_parse_list_style_value(struct css_property_info *propinfo, + union css_property_value *value, + struct scanner *scanner); /*! Takes no parser_data. */ int css_parse_text_align_value(struct css_property_info *propinfo, diff --git a/src/document/dom/util.c b/src/document/dom/util.c index b33cc2a7..fe03df78 100644 --- a/src/document/dom/util.c +++ b/src/document/dom/util.c @@ -62,6 +62,7 @@ init_template_by_style(struct screen_char *template, struct document_options *op break; case CSS_PT_DISPLAY: case CSS_PT_NONE: + case CSS_PT_LIST_STYLE: case CSS_PT_TEXT_ALIGN: case CSS_PT_WHITE_SPACE: case CSS_PT_LAST: diff --git a/src/document/html/parser.h b/src/document/html/parser.h index f989f7a0..b14ad402 100644 --- a/src/document/html/parser.h +++ b/src/document/html/parser.h @@ -80,6 +80,7 @@ enum format_list_flag { P_ALPHA = 3, P_roman = 4, P_ROMAN = 5, + P_NO_BULLET = 6, P_STAR = 1, P_O = 2, diff --git a/src/document/html/parser/general.c b/src/document/html/parser/general.c index 7e8de820..1bcef8a9 100644 --- a/src/document/html/parser/general.c +++ b/src/document/html/parser/general.c @@ -852,6 +852,8 @@ void html_li(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5) { + int t = par_format.flags & P_LISTMASK; + /* When handling the code
+ list-style:none +
+ list-style:disc +
+ list-style:circle +
+ list-style:square +
+ list-style:decimal +
+ list-style:decimal-leading-zero +
+ list-style:lower-roman +
+ list-style:upper-roman +
+ list-style:lower-alpha +
+ list-style:upper-alpha +
+ list-style:lower-greek +
+ list-style:lower-latin +
+ list-style:upper-latin +
+ list-style:hebrew +
+ list-style:armenian +
+ list-style:georgian +
+ list-style:cjk-ideograph +
+ list-style:hiragana +
+ list-style:katakana +
+ list-style:hiragana-iroha +
+ list-style:katakana-iroha +