evil-qemacs/libqhtml/css.h
2017-03-25 18:04:51 +00:00

680 lines
22 KiB
C

/*
* CSS core for qemacs.
*
* Copyright (c) 2000-2002 Fabrice Bellard.
* Copyright (c) 2007-2017 Charlie Gordon.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CSS_H
#define CSS_H
struct CSSBox;
typedef struct CSSBox CSSBox;
/* display property */
enum CSSDisplay {
CSS_DISPLAY_INLINE,
CSS_DISPLAY_BLOCK,
CSS_DISPLAY_TABLE,
CSS_DISPLAY_TABLE_ROW,
CSS_DISPLAY_TABLE_ROW_GROUP,
CSS_DISPLAY_TABLE_HEADER_GROUP,
CSS_DISPLAY_TABLE_FOOTER_GROUP,
CSS_DISPLAY_TABLE_COLUMN,
CSS_DISPLAY_TABLE_COLUMN_GROUP,
CSS_DISPLAY_TABLE_CELL,
CSS_DISPLAY_TABLE_CAPTION,
CSS_DISPLAY_LIST_ITEM,
CSS_DISPLAY_MARKER,
CSS_DISPLAY_INLINE_BLOCK, /* qemacs extension (CSS3 ?) */
CSS_DISPLAY_INLINE_TABLE,
CSS_DISPLAY_NONE,
};
enum CSSProperties {
CSS_display,
CSS_color,
CSS_background_color,
CSS_white_space,
#define CSS_WHITE_SPACE_NORMAL 0
#define CSS_WHITE_SPACE_PRE 1
#define CSS_WHITE_SPACE_NOWRAP 2
#define CSS_WHITE_SPACE_PREWRAP 3 /* qemacs extension for editing
(XXX: use CSS3)*/
CSS_direction,
#define CSS_DIRECTION_LTR 0
#define CSS_DIRECTION_RTL 1
CSS_float,
#define CSS_FLOAT_NONE 0
#define CSS_FLOAT_LEFT 1
#define CSS_FLOAT_RIGHT 2
CSS_font_family,
CSS_font_style,
#define CSS_FONT_STYLE_NORMAL 0
#define CSS_FONT_STYLE_ITALIC 1
CSS_font_weight,
#define CSS_FONT_WEIGHT_NORMAL 0
#define CSS_FONT_WEIGHT_BOLD 1
#define CSS_FONT_WEIGHT_BOLDER 2
#define CSS_FONT_WEIGHT_LIGHTER 3
CSS_font_size,
CSS_text_decoration,
#define CSS_TEXT_DECORATION_NONE 0
#define CSS_TEXT_DECORATION_UNDERLINE 1
#define CSS_TEXT_DECORATION_LINE_THROUGH 2
CSS_text_align,
#define CSS_TEXT_ALIGN_LEFT 0
#define CSS_TEXT_ALIGN_RIGHT 1
#define CSS_TEXT_ALIGN_CENTER 2
CSS_width,
CSS_height,
CSS_unicode_bidi,
#define CSS_UNICODE_BIDI_NORMAL 0
#define CSS_UNICODE_BIDI_EMBED 1
#define CSS_UNICODE_BIDI_OVERRIDE 2
CSS_border_width,
CSS_border_left_width,
CSS_border_top_width,
CSS_border_right_width,
CSS_border_bottom_width,
CSS_border_color,
CSS_border_left_color,
CSS_border_top_color,
CSS_border_right_color,
CSS_border_bottom_color,
CSS_border_style,
CSS_border_left_style,
CSS_border_top_style,
CSS_border_right_style,
CSS_border_bottom_style,
#define CSS_BORDER_STYLE_NONE 0
#define CSS_BORDER_STYLE_HIDDEN 1
#define CSS_BORDER_STYLE_DOTTED 2
#define CSS_BORDER_STYLE_DASHED 3
#define CSS_BORDER_STYLE_SOLID 4
#define CSS_BORDER_STYLE_DOUBLE 5
#define CSS_BORDER_STYLE_GROOVE 6
#define CSS_BORDER_STYLE_RIDGE 7
#define CSS_BORDER_STYLE_INSET 8
#define CSS_BORDER_STYLE_OUTSET 9
CSS_border,
CSS_border_left,
CSS_border_top,
CSS_border_right,
CSS_border_bottom,
CSS_padding,
CSS_padding_left,
CSS_padding_top,
CSS_padding_right,
CSS_padding_bottom,
CSS_margin,
CSS_margin_left,
CSS_margin_top,
CSS_margin_right,
CSS_margin_bottom,
CSS_clear,
#define CSS_CLEAR_NONE 0
#define CSS_CLEAR_LEFT 1
#define CSS_CLEAR_RIGHT 2
#define CSS_CLEAR_BOTH 3
CSS_overflow,
#define CSS_OVERFLOW_VISIBLE 0
#define CSS_OVERFLOW_HIDDEN 1
CSS_visibility,
#define CSS_VISIBILITY_VISIBLE 0
#define CSS_VISIBILITY_HIDDEN 1
CSS_table_layout,
#define CSS_TABLE_LAYOUT_AUTO 0
#define CSS_TABLE_LAYOUT_FIXED 1
CSS_vertical_align,
#define CSS_VERTICAL_ALIGN_BASELINE 0
#define CSS_VERTICAL_ALIGN_SUB 1
#define CSS_VERTICAL_ALIGN_SUPER 2
#define CSS_VERTICAL_ALIGN_TOP 3
#define CSS_VERTICAL_ALIGN_TEXT_TOP 4
#define CSS_VERTICAL_ALIGN_MIDDLE 5
#define CSS_VERTICAL_ALIGN_BOTTOM 6
#define CSS_VERTICAL_ALIGN_TEXT_BOTTOM 7
CSS_border_collapse,
#define CSS_BORDER_COLLAPSE_COLLAPSE 0
#define CSS_BORDER_COLLAPSE_SEPARATE 1
CSS_border_spacing,
CSS_border_spacing_horizontal,
CSS_border_spacing_vertical,
CSS_line_height,
CSS_position,
#define CSS_POSITION_STATIC 0
#define CSS_POSITION_RELATIVE 1
#define CSS_POSITION_ABSOLUTE 2
#define CSS_POSITION_FIXED 3
CSS_content,
CSS_caption_side,
#define CSS_CAPTION_SIDE_TOP 0
#define CSS_CAPTION_SIDE_BOTTOM 1
#define CSS_CAPTION_SIDE_LEFT 2
#define CSS_CAPTION_SIDE_RIGHT 3
CSS_marker_offset,
CSS_list_style_type,
#define CSS_LIST_STYLE_TYPE_DISC 0
#define CSS_LIST_STYLE_TYPE_CIRCLE 1
#define CSS_LIST_STYLE_TYPE_SQUARE 2
#define CSS_LIST_STYLE_TYPE_DECIMAL 3
#define CSS_LIST_STYLE_TYPE_LOWER_ALPHA 4
#define CSS_LIST_STYLE_TYPE_UPPER_ALPHA 5
#define CSS_LIST_STYLE_TYPE_LOWER_ROMAN 6
#define CSS_LIST_STYLE_TYPE_UPPER_ROMAN 7
#define CSS_LIST_STYLE_TYPE_NONE 8
CSS_column_span, /* qemacs extension */
CSS_row_span, /* qemacs extension */
CSS_content_alt, /* qemacs extension */
CSS_list_style_position,
#define CSS_LIST_STYLE_POSITION_OUTSIDE 0
#define CSS_LIST_STYLE_POSITION_INSIDE 1
CSS_counter_reset,
CSS_counter_increment,
CSS_bidi_mode, /* qemacs extension */
#define CSS_BIDI_MODE_NORMAL 0
#define CSS_BIDI_MODE_TEST 1
CSS_left,
CSS_top,
CSS_right,
CSS_bottom,
NB_PROPERTIES,
};
#define CSS_AUTO ((int)0x80000000)
#define CSS_INHERIT ((int)0x80000001)
typedef unsigned int CSSColor;
typedef struct CSSPropertyDef {
const char *name;
unsigned short struct_offset; /* in CSSState */
unsigned char storage;
#define CSS_STORAGE_INT 0
#define CSS_STORAGE_PTR 1
unsigned int type;
#define CSS_TYPE_AUTO 0x80000000
#define CSS_TYPE_NOINHERIT 0x40000000
/* the four next properties will be set according to the CSS rules for
margin, borders and padding */
#define CSS_TYPE_FOUR 0x20000000
#define CSS_TYPE_TWO 0x10000000 /* the same with two args */
#define CSS_TYPE_SPECIAL 0x08000000 /* XXX: special storage needed */
#define CSS_TYPE_INHERITED 0x04000000 /* property is inherited */
#define CSS_TYPE_ARGS 0x02000000 /* no limit on number of args */
/* types can be ored */
#define CSS_TYPE_LENGTH 0x00000001
#define CSS_TYPE_COLOR 0x00000002
#define CSS_TYPE_ENUM 0x00000004
#define CSS_TYPE_BORDER_STYLE 0x00000008
#define CSS_TYPE_FONT_FAMILY 0x00000010
#define CSS_TYPE_BORDER_ENUM 0x00000020
#define CSS_TYPE_STRING 0x00000040
#define CSS_TYPE_INTEGER 0x00000080
#define CSS_TYPE_ATTR 0x00000100 /* attr(x) */
#define CSS_TYPE_COUNTER 0x00000200 /* counter(x[,type]) */
#define CSS_TYPE_LIST_STYLE 0x00000400
#define CSS_TYPE_IDENT 0x00000800
} CSSPropertyDef;
typedef union CSSPropertyStorage {
int val; /* CSS_STORAGE_INT */
struct CSSProperty *ptr; /* CSS_STORAGE_PTR */
} CSSPropertyStorage;
#define CSSPropertyStoragePtr(s, off) ((CSSPropertyStorage*)(void*)((char*)(s) + (off)))
extern const CSSPropertyDef css_properties[NB_PROPERTIES];
/* CSS parsing */
/* length are normalized to this value, except pixel units */
#define CSS_LENGTH_FRAC_BITS 8
#define CSS_LENGTH_FRAC_BASE (1 << CSS_LENGTH_FRAC_BITS)
/* number of pixels for one px */
#define CSS_SCREEN_PX_SIZE 1
/* resolution */
#define CSS_SCREEN_DPI 72
#define CSS_TTY_PX_SIZE (1.0/8.0)
#define CSS_TTY_DPI 9
/* currently, we define ex as a scaling of the font size */
#define CSS_EX_SCALE ((int)(0.8 * CSS_LENGTH_FRAC_BASE))
#define CSS_UNIT_NONE 0
#define CSS_UNIT_PIXEL 1
#define CSS_UNIT_PERCENT 2
#define CSS_UNIT_EX 3
#define CSS_UNIT_EM 4
#define CSS_UNIT_IN 6
/* the following units are never used except in parsing */
#define CSS_UNIT_MM 5
#define CSS_UNIT_CM 7
#define CSS_UNIT_PT 8
#define CSS_UNIT_PC 9
/* additional values */
#define CSS_VALUE_STRING 11
#define CSS_VALUE_COUNTER 12
#define CSS_VALUE_ATTR 13
#define CSS_VALUE_COLOR 14
#define CSS_VALUE_IDENT 15
#define CSS_VALUE_INTEGER 16
/* CSS identifier handling */
typedef enum CSSIdent {
CSS_ID_NIL = 0,
CSS_ID_ALL = 1, /* '*' ident */
#define CSSID(id) CSS_ID_ ## id,
#define CSSIDSTR(id, str) CSS_ID_ ## id,
#include "cssid.h"
#undef CSSID
#undef CSSIDSTR
} CSSIdent;
typedef struct CSSIdentEntry {
CSSIdent id;
struct CSSIdentEntry *hash_next;
char str[1];
} CSSIdentEntry;
const char *css_ident_str(CSSIdent id);
CSSIdent css_new_ident(const char *str);
static inline unsigned int css_hash_ident(CSSIdent id, unsigned int hash_size)
{
return (unsigned int)id % hash_size;
}
/* property handling */
typedef struct CSSPropertyValue {
int type; /* see CSS_UNIT_xxx or CSS_VALUE_xxx */
union {
int val;
char *str;
CSSIdent attr_id;
struct {
CSSIdent counter_id;
int type;
} counter;
} u;
} CSSPropertyValue;
typedef struct CSSProperty {
unsigned short property;
unsigned short nb_values;
struct CSSProperty *next; /* may change: use array ? */
CSSPropertyValue value; /* in fact an array, but need
to change all the types */
} CSSProperty;
/* tag attribute handling */
typedef struct CSSAttribute {
CSSIdent attr;
struct CSSAttribute *next;
char value[1];
} CSSAttribute;
/* css box definition (most important data structure) */
struct CSSBox {
CSSIdent tag; /* tag name of the box, may be CSS_ID_NIL
for anonymous box */
CSSAttribute *attrs; /* attributes (may be NULL) */
CSSProperty *properties; /* explicit properties */
struct CSSState *props; /* computed properties for this box */
struct CSSBox *next; /* next box at same level */
/* bounding box of the draw primitives of the box and all its
childs */
CSSRect bbox;
/* layout info */
int x, y; /* absolute content position. XXX: currently also
relative to parent in the layout */
int width, height; /* content width & height */
/* inline specific layout. Not useful in fact XXX: use an union,
or merge with padding_xx */
unsigned short padding_top;
unsigned short padding_bottom;
unsigned short ascent; /* cannot use font ascent in case of
fallback XXX: find a way to suppress this field */
unsigned char embedding_level; /* from layout: bidir embedding level */
unsigned char content_type;
#define CSS_CONTENT_TYPE_CHILDS 0
#define CSS_CONTENT_TYPE_BUFFER 1
#define CSS_CONTENT_TYPE_STRING 2
#define CSS_CONTENT_TYPE_IMAGE 3
/* true if the content ends with eol. (used in
CSS_CONTENT_TYPE_BUFFER to display the cursor */
unsigned char content_eol:1;
unsigned char absolute_pos:1; /* true if absolute position (only
meaningful during layout */
unsigned char split:1; /* true if this box is a splitted box
(no need to free its content) */
/* true if there was a space in the previous box (useful in inline
formatting context) */
unsigned char last_space;
/* next inline box in an inline formatting context. Only used
during bidi pass, so we could put this field in another field
to save space */
struct CSSBox *next_inline;
/* parent box */
struct CSSBox *parent;
/* holds a pointer to the relevant data depending on content_type:
* - CSS_CONTENT_TYPE_BUFFER: points the the edit buffer
* - CSS_CONTENT_TYPE_STRING: points the an allocated string
* - CSS_CONTENT_TYPE_IMAGE: should point to alternate content
*/
void *content_data;
union {
struct {
struct CSSBox *last; /* used only when building the tree */
struct CSSBox *first; /* first box under this box, if any */
} child;
struct {
int start; /* start of text in buffer or string */
int end; /* end of text in buffer or string */
} buffer;
struct {
char *content_alt; /* alternate content */
} image;
} u;
};
/* horrible, but simple: we store EOL content (\A) as this value. Need
to find a better unicode value and to store it in UTF8 */
#define CSS_CONTENT_EOL 0x01
typedef struct CSSState {
int display;
CSSColor color;
CSSColor bgcolor;
CSSColor border_colors[4];
CSSRect padding;
CSSRect border;
CSSRect margin;
int border_styles[4];
int white_space;
int direction;
int block_float;
int font_family;
int font_style;
int text_decoration;
int font_weight;
int font_size;
int text_align;
int width;
int height;
int unicode_bidi;
int clear;
int overflow;
int visibility; /* XXX: initial value should be inherit */
int table_layout;
int vertical_align;
int border_collapse;
int border_spacing_horizontal;
int border_spacing_vertical;
int line_height;
int position;
int caption_side;
int marker_offset;
int list_style_type;
int column_span;
int row_span;
int list_style_position;
int bidi_mode;
int left;
int top;
int right;
int bottom;
/* after hash_next, no hashing or bulk comparisons are done */
struct CSSState *hash_next;
/* set of complex properties which are handled once after the
cascade is done */
struct CSSProperty *content;
struct CSSProperty *content_alt;
struct CSSProperty *counter_reset;
struct CSSProperty *counter_increment;
} CSSState;
/* style sheet handling */
typedef struct CSSStyleSheetAttributeEntry {
struct CSSStyleSheetAttributeEntry *next;
CSSIdent attr; /* attribute */
unsigned char op;
#define CSS_ATTR_OP_SET 0
#define CSS_ATTR_OP_EQUAL 1
#define CSS_ATTR_OP_IN_LIST 2
#define CSS_ATTR_OP_IN_HLIST 3
char value[1];
} CSSStyleSheetAttributeEntry;
/* simple selector */
typedef struct CSSSimpleSelector {
/* relation between next and current simple selector */
unsigned char tree_op;
#define CSS_TREE_OP_NONE 0 /* no next simple selector */
#define CSS_TREE_OP_DESCENDANT 1
#define CSS_TREE_OP_CHILD 2
#define CSS_TREE_OP_PRECEEDED 3
unsigned short pclasses; /* pseudo classes & elements */
#define CSS_PCLASS_FIRST_CHILD 0x0001
#define CSS_PCLASS_LINK 0x0002
#define CSS_PCLASS_VISITED 0x0004
#define CSS_PCLASS_ACTIVE 0x0008
#define CSS_PCLASS_HOVER 0x0010
#define CSS_PCLASS_FOCUS 0x0020
/* pseudo elements */
#define CSS_PCLASS_FIRST_LINE 0x0040
#define CSS_PCLASS_FIRST_LETTER 0x0080
#define CSS_PCLASS_BEFORE 0x0100
#define CSS_PCLASS_AFTER 0x0200
CSSIdent tag; /* selection tag, CSS_ID_ALL means all */
CSSIdent tag_id; /* id */
CSSStyleSheetAttributeEntry *attrs; /* attribute list */
struct CSSSimpleSelector *next; /* next selector operation */
} CSSSimpleSelector;
typedef struct CSSStyleSheetEntry {
CSSSimpleSelector sel; /* main selector */
int media; /* CSS2 media mask */
CSSProperty *props; /* associated properties */
struct CSSStyleSheetEntry *hash_next; /* hash table for next matching tag */
struct CSSStyleSheetEntry *next; /* next entry in style sheet */
} CSSStyleSheetEntry;
#define CSS_TAG_HASH_SIZE 521
typedef struct CSSStyleSheet {
CSSStyleSheetEntry *first_entry, **plast_entry;
CSSStyleSheetEntry *tag_hash[CSS_TAG_HASH_SIZE];
} CSSStyleSheet;
typedef struct {
const char *ptr;
int line_num;
const char *filename;
int ignore_case; /* true if case must be ignored (convert to lower case) */
} CSSParseState;
CSSStyleSheet *css_new_style_sheet(void);
void css_parse_style_sheet_str(CSSStyleSheet *s, const char *buffer, int flags);
void css_parse_style_sheet(CSSStyleSheet *s, CSSParseState *b);
void css_free_style_sheet(CSSStyleSheet **sp);
void css_dump_style_sheet(CSSStyleSheet *s);
void css_merge_style_sheet(CSSStyleSheet *s, CSSStyleSheet *a);
CSSProperty *css_parse_properties(CSSParseState *b, const char *props_str);
void css_add_prop_values(CSSProperty ***last_prop,
int property_index,
int nb_values, CSSPropertyValue *val_ptr);
void css_add_prop(CSSProperty ***last_prop,
int property_index, CSSPropertyValue *val_ptr);
void css_add_prop_unit(CSSProperty ***last_prop,
int property_index, int type, int val);
void css_add_prop_int(CSSProperty ***last_prop,
int property_index, int val);
CSSStyleSheetEntry *add_style_entry(CSSStyleSheet *s,
CSSSimpleSelector *ss,
int media);
void add_attribute(CSSStyleSheetAttributeEntry ***last_attr,
CSSIdent attr, int op, const char *value);
int get_font_size(int i);
/* CSS creating, layout and display */
struct CSSContext;
#define PROPS_HASH_SIZE 521
#define PROPS_SIZE offsetof(CSSState, hash_next)
typedef struct CSSCounterValue {
CSSIdent counter_id;
int value;
struct CSSCounterValue *prev;
} CSSCounterValue;
typedef struct CSSContext {
CSSStyleSheet *style_sheet;
QEditScreen *screen;
/* various default settings */
/* XXX: use style sheet ? */
int selection_bgcolor;
int selection_fgcolor;
int default_bgcolor;
/* edit buffer */
EditBuffer *b;
/* selection handling */
int selection_start, selection_end;
/* private content */
int media; /* initialized when creating CSSContext */
int px_size; /* px unit size, in displayed pixels (CSS_LENGTH_FRAC_BASE) */
int dots_per_inch; /* convert from inch to displayed pixels */
int bg_drawn; /* temporary for css_display */
CSSRect bg_rect; /* temporary for css_display */
CSSAbortFunc *abort_func;
void *abort_opaque;
int nb_props; /* statistics */
/* only used during css_compute() */
CSSCounterValue *counter_stack_ptr;
CSSCounterValue *counter_stack_base;
/* css attributes for the boxes are shared here */
CSSState *hash_props[PROPS_HASH_SIZE];
} CSSContext;
/* document managing */
void css_init(void);
CSSContext *css_new_document(QEditScreen *screen,
EditBuffer *b);
void css_delete_document(CSSContext **sp);
int css_compute(CSSContext *s, CSSBox *box);
int css_layout(CSSContext *s, CSSBox *box, int width,
CSSAbortFunc *abort_func, void *abort_opaque);
void css_display(CSSContext *s, CSSBox *box,
CSSRect *clip_box, int dx, int dy);
/* cursor/edition handling */
int box_get_text(CSSContext *s,
unsigned int *line_buf, int max_size,
int *offsets, CSSBox *box);
int css_get_cursor_pos(CSSContext *s, CSSBox *box,
CSSBox **box_ptr, int *x0_ptr, int *y0_ptr,
CSSRect *cursor_ptr, int *dir_ptr,
int offset);
int css_get_offset_pos(CSSContext *s, CSSBox *box, int xc, int dir);
typedef int (*CSSIterateFunc)(void *opaque, CSSBox *box, int x0, int y0);
int css_box_iterate(CSSContext *s, CSSBox *box, void *opaque,
CSSIterateFunc iterate_func);
/* box tree handling */
CSSBox *css_new_box(CSSIdent tag, CSSAttribute *attrs);
CSSBox *css_add_box(CSSBox *parent_box, CSSBox *box);
void css_delete_box(CSSBox **boxp);
void css_set_text_buffer(CSSBox *box, EditBuffer *b,
int offset1, int offset2, int eol);
void css_set_text_string(CSSBox *box, const char *string);
void css_make_child_box(CSSBox *box);
void css_set_child_box(CSSBox *parent_box, CSSBox *box);
/* box tree display (debug) */
void css_dump_box(CSSBox *box, int level);
void css_dump(CSSBox *box);
/* XML parser */
struct XMLState;
typedef struct XMLState XMLState;
#define XML_HTML 0x0001 /* enable html tag interpretation which cannot
be specified in a stylesheet */
#define XML_IGNORE_CASE 0x0002 /* ignore case for both xml/css tag parsing */
#define XML_DOCBOOK 0x0004 /* programlisting is handled as PRE */
#define XML_HTML_SYNTAX 0x0008 /* modify xml parser to accept HTML syntax */
XMLState *xml_begin(CSSStyleSheet *style_sheet, int flags,
CSSAbortFunc *abort_func, void *abort_opaque,
const char *filename, QECharset *charset);
int xml_parse(XMLState *s, char *buf, int buf_len);
CSSBox *xml_end(XMLState **sp);
CSSBox *xml_parse_buffer(EditBuffer *b, int offset_start, int offset_end,
CSSStyleSheet *style_sheet, int flags,
CSSAbortFunc *abort_func, void *abort_opaque);
int find_entity(const char *str);
const char *find_entity_str(int code);
#endif
/* The following functions must be provided by the user */
/* error reporting during parsing */
void html_error(int line_num, const char *fmt, va_list ap);
void css_error(const char *filename, int line_num, const char *msg);
/* file handling (for external scripts/css) */
struct CSSFile;
typedef struct CSSFile CSSFile;
CSSFile *css_open(CSSContext *s, const char *filename);
int css_filesize(CSSFile *f);
int css_read(CSSFile *f, char *buf, int size);
void css_close(CSSFile *f);
extern char const docbook_style[];
extern char const html_style[];