Приложение B: Грамматика CSS1. Спецификация CSS1
(Это приложение является формальным)
The minimal CSS (i.e., any version of CSS) grammar that all implementations
need to support is defined in section 7. The
grammar below defines a much smaller language, a language that defines the
syntax of CSS1.
It is in some sense, however, still a superset of CSS1: there are additional
semantic constraints not expressed in this grammar. A conforming UA must
also adhere to the forward-compatible parsing rules (section 7.1), the property
and value notation (section 5) and the unit notation (section 6). In addition,
HTML imposes restrictions, e.g., on the possible values of the CLASS attribute.
The grammar below is LL(1) (but note that most UA's should not use it directly,
since it doesn't express the parsing conventions, only the CSS1 syntax).
The format of the productions is optimized for human consumption and some
shorthand notation beyond yacc [15] is used:
* : 0 or more
+ : 1 or more
? : 0 or 1
| : separates alternatives
[] : grouping
The productions are:
stylesheet
: [CDO|CDC]* [ import [CDO|CDC]* ]* [ ruleset [CDO|CDC]* ]*
;
import
: IMPORT_SYM [STRING|URL] ';' /* E.g., @import url(fun.css); */
;
unary_operator
: '-' | '+'
;
operator
: '/' | ',' | /* empty */
;
property
: IDENT
;
ruleset
: selector [ ',' selector ]*
'{' declaration [ ';' declaration ]* '}'
;
selector
: simple_selector+ [ pseudo_element | solitary_pseudo_element ]?
| solitary_pseudo_element
;
/* An "id" is an ID that is attached to an element type
** on its left, as in: P#p007
** A "solitary_id" is an ID that is not so attached,
** as in: #p007
** Analogously for classes and pseudo-classes.
*/
simple_selector
: element_name id? class? pseudo_class? /* eg: H1.subject */
| solitary_id class? pseudo_class? /* eg: #xyz33 */
| solitary_class pseudo_class? /* eg: .author */
| solitary_pseudo_class /* eg: :link */
;
element_name
: IDENT
;
pseudo_class /* as in: A:link */
: LINK_PSCLASS_AFTER_IDENT
| VISITED_PSCLASS_AFTER_IDENT
| ACTIVE_PSCLASS_AFTER_IDENT
;
solitary_pseudo_class /* as in: :link */
: LINK_PSCLASS
| VISITED_PSCLASS
| ACTIVE_PSCLASS
;
class /* as in: P.note */
: CLASS_AFTER_IDENT
;
solitary_class /* as in: .note */
: CLASS
;
pseudo_element /* as in: P:first-line */
: FIRST_LETTER_AFTER_IDENT
| FIRST_LINE_AFTER_IDENT
;
solitary_pseudo_element /* as in: :first-line */
: FIRST_LETTER
| FIRST_LINE
;
/* There is a constraint on the id and solitary_id that the
** part after the "#" must be a valid HTML ID value;
** e.g., "#x77" is OK, but "#77" is not.
*/
id
: HASH_AFTER_IDENT
;
solitary_id
: HASH
;
declaration
: property ':' expr prio?
| /* empty */ /* Prevents syntax errors... */
;
prio
: IMPORTANT_SYM /* !important */
;
expr
: term [ operator term ]*
;
term
: unary_operator?
[ NUMBER | STRING | PERCENTAGE | LENGTH | EMS | EXS
| IDENT | hexcolor | URL | RGB ]
;
/* There is a constraint on the color that it must
** have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
** after the "#"; e.g., "#000" is OK, but "#abcd" is not.
*/
hexcolor
: HASH | HASH_AFTER_IDENT
;
The following is the tokenizer, written in flex [16]
notation. Note that this assumes an 8-bit implementation of flex. The tokenizer
is case-insensitive (flex command line option -i).
unicode \\[0-9a-f]{1,4}
latin1 [¡-ÿ]
escape {unicode}|\\[ -~¡-ÿ]
stringchar {escape}|{latin1}|[ !#$%&(-~]
nmstrt [a-z]|{latin1}|{escape}
nmchar [-a-z0-9]|{latin1}|{escape}
ident {nmstrt}{nmchar}*
name {nmchar}+
d [0-9]
notnm [^-a-z0-9\\]|{latin1}
w [ \t\n]*
num {d}+|{d}*\.{d}+
string \"({stringchar}|\')*\"|\'({stringchar}|\")*\'
%x COMMENT
%s AFTER_IDENT
%%
"/*" {BEGIN(COMMENT);}
<COMMENT>"*/" {BEGIN(0);}
<COMMENT>\n {/* ignore */}
<COMMENT>. {/* ignore */}
@import {BEGIN(0); return IMPORT_SYM;}
"!"{w}important {BEGIN(0); return IMPORTANT_SYM;}
{ident} {BEGIN(AFTER_IDENT); return IDENT;}
{string} {BEGIN(0); return STRING;}
{num} {BEGIN(0); return NUMBER;}
{num}"%" {BEGIN(0); return PERCENTAGE;}
{num}pt/{notnm} {BEGIN(0); return LENGTH;}
{num}mm/{notnm} {BEGIN(0); return LENGTH;}
{num}cm/{notnm} {BEGIN(0); return LENGTH;}
{num}pc/{notnm} {BEGIN(0); return LENGTH;}
{num}in/{notnm} {BEGIN(0); return LENGTH;}
{num}px/{notnm} {BEGIN(0); return LENGTH;}
{num}em/{notnm} {BEGIN(0); return EMS;}
{num}ex/{notnm} {BEGIN(0); return EXS;}
<AFTER_IDENT>":"link {return LINK_PSCLASS_AFTER_IDENT;}
<AFTER_IDENT>":"visited {return VISITED_PSCLASS_AFTER_IDENT;}
<AFTER_IDENT>":"active {return ACTIVE_PSCLASS_AFTER_IDENT;}
<AFTER_IDENT>":"first-line {return FIRST_LINE_AFTER_IDENT;}
<AFTER_IDENT>":"first-letter {return FIRST_LETTER_AFTER_IDENT;}
<AFTER_IDENT>"#"{name} {return HASH_AFTER_IDENT;}
<AFTER_IDENT>"."{name} {return CLASS_AFTER_IDENT;}
":"link {BEGIN(AFTER_IDENT); return LINK_PSCLASS;}
":"visited {BEGIN(AFTER_IDENT); return VISITED_PSCLASS;}
":"active {BEGIN(AFTER_IDENT); return ACTIVE_PSCLASS;}
":"first-line {BEGIN(AFTER_IDENT); return FIRST_LINE;}
":"first-letter {BEGIN(AFTER_IDENT); return FIRST_LETTER;}
"#"{name} {BEGIN(AFTER_IDENT); return HASH;}
"."{name} {BEGIN(AFTER_IDENT); return CLASS;}
url\({w}{string}{w}\) |
url\({w}([^ \n\'\")]|\\\ |\\\'|\\\"|\\\))+{w}\) {BEGIN(0); return URL;}
rgb\({w}{num}%?{w}\,{w}{num}%?{w}\,{w}{num}%?{w}\) {BEGIN(0); return RGB;}
[-/+{};,#:] {BEGIN(0); return *yytext;}
[ \t]+ {BEGIN(0); /* ignore whitespace */}
\n {BEGIN(0); /* ignore whitespace */}
\<\!\-\- {BEGIN(0); return CDO;}
\-\-\> {BEGIN(0); return CDC;}
. {fprintf(stderr, "%d: Illegal character (%d)\n",
lineno, *yytext);}
(This appendix is informative, not normative)
HTML documents may contain any of the about 30,000 different characters defined
by Unicode. Many documents only need a few hundred. Many fonts also only
contain just a few hundred glyphs. In combination with
section 5.2, this appendix explains how the
characters in the document and the glyphs in a font are matched.
The content of an HTML document is a sequence of characters and
markup. To send it "over the wire", it is encoded as a sequence of bytes,
using one of several possible encodings. The HTML document has to
be decoded to find the characters. For example, in Western Europe it is customary
to use the byte 224 for an a-with-grave-accent (à), but in Hebrew,
it is more common to use 224 for an Aleph. In Japanese, the meaning of a
byte usually depends on the bytes that preceded it. In some encodings, one
character is encoded as two (or more) bytes.
The UA knows how to decode the bytes by looking at the "charset" parameter
in the HTTP header. Typical encodings (charset values) are "ASCII" (for English),
"ISO-8859-1" (for Western Europe), "ISO-8859-8" (for Hebrew), "Shift-JIS"
(for Japanese).
HTML [2],[4], allows some 30,000 different
characters, namely those defined by Unicode. Not many documents will use
that many different characters, and choosing the right encoding will usually
ensure that the document only needs one byte per character. Occasional characters
outside the encoded range can still be entered as numerical character references:
'Π' will always mean the Greek uppercase Pi, no matter what encoding
was used. Note that this entails that UAs have to be prepared for any Unicode
character, even if they only handle a few encodings.
A font doesn't contain characters, it contains pictures of characters,
known as glyphs. The glyphs, in the form of outlines or bitmaps,
constitute a particular representation of a character. Either explicitly
or implicitly, each font has a table associated with it, the font encoding
table, that tells for each glyph what character it is a representation
for. In Type 1 fonts, the table is referred to as an encoding vector.
In fact, many fonts contain several glyphs for the same character. Which
of those glyphs should be used depends either on the rules of the language,
or on the preference of the designer.
In Arabic, for example, all letters have four different shapes, depending
on whether the letter is used at the start of a word, in the middle, at the
end, or in isolation. It is the same character in all cases, and thus there
is only one character in the HTML document, but when printed, it looks
differently each time.
There are also fonts that leave it to the graphic designer to choose from
among various alternative shapes provided. Unfortunately, CSS1 doesn't yet
provide the means to select those alternatives. Currently, it is always the
default shape that is chosen from such fonts.
To deal with the problem that a single font may not be enough to display
all the characters in a document, or even a single element, CSS1 allows the
use of font sets.
A font set in CSS1 is a list of fonts, all of the same style and size, that
are tried in sequence to see if they contain a glyph for a certain character.
An element that contains English text mixed with mathematical symbols may
need a font set of two fonts, one containing letters and digits, the other
containing mathematical symbols. See section 5.2
for a detailed description of the selection mechanism for font sets.
Here is an example of a font set suitable for a text that is expected to
contain text with Latin characters, Japanese characters, and mathematical
symbols:
BODY { font-family: Baskerville, Mincho, Symbol, serif }
The characters available in the Baskerville font (a font with only Latin
characters) will be taken from that font, Japanese will be taken from Mincho,
and the mathematical symbols will come from Symbol. Any other characters
will (hopefully) come from the generic font family 'serif'. The 'serif' font
family will also be used if one or more of the other fonts is unavailable.
(This appendix is informative, not normative)
See the Gamma
Tutorial in the PNG specification [12] if you aren't
already familiar with gamma issues.
In the computation, UAs displaying on a CRT may assume an ideal CRT and ignore
any effects on apparent gamma caused by dithering. That means the minimal
handling they need to do on current platforms is:
-
PC using MS-Windows
-
none
-
Unix using X11
-
none
-
Mac using QuickDraw
-
apply gamma 1.39 [13] (ColorSync-savvy applications
may simply pass the sRGB ICC profile [14] to ColorSync
to perform correct color correction)
-
SGI using X
-
apply the gamma value from /etc/config/system.glGammaVal (the default
value being 1.70; applications running on Irix 6.2 or above may simply pass
the sRGB ICC profile to the color management system)
-
NeXT using NeXTStep
-
apply gamma 2.22
"Applying gamma" means that each of the three R, G and B must be converted
to R'=Rgamma, G'=Ggamma, G'=Bgamma, before
handing to the OS.
This may rapidly be done by building a 256-element lookup table once per
browser invocation thus:
for i := 0 to 255 do
raw := i / 255;
corr := pow (raw, gamma);
table[i] := trunc (0.5 + corr * 255.0)
end
which then avoids any need to do transcendental math per color attribute,
far less per pixel.
(This appendix is informative, not normative)
The goal of the work on CSS1 has been to create a simple style sheet mechanism
for HTML documents. The current specification is a balance between the simplicity
needed to realize style sheets on the web, and pressure from authors for
richer visual control. CSS1 offers:
CSS1 does not offer:
-
per pixel control: CSS1 values simplicity over level of control, and although
the combination of background images and styled HTML is powerful, control
to the pixel level is not possible.
-
author control: the author cannot enforce the use of a certain sheet, only
suggest
-
a layout language: CSS1 does not offer multiple columns with text-flow,
overlapping frames etc.
-
a rich query language on the parse tree: CSS1 can only look for ancestor
elements in the parse tree, while other style sheet languages (e.g. DSSSL
[6]) offers a full query language.
We expect to see extensions of CSS in several directions:
-
paper: better support for printing HTML documents
-
support for non-visual media: work is in the process to add a list of properties
and corresponding values to support speech and braille output
-
color names: the currently supported list may be extended
-
fonts: more precise font specification systems are expected to complement
existing CSS1 font properties.
-
values, properties: we expect vendors to propose extensions to the CSS1 set
of values and properties. Extending in this direction is trivial for the
specification, but interoperability between different UAs is a concern
-
layout language: support for two-dimensional layout in the tradition of desktop
publishing packages.
-
other DTDs: CSS1 has some HTML-specific parts (e.g. the special status of
the 'CLASS' and 'ID' attributes) but should easily be extended to apply to
other DTDs as well.
We do not expect CSS to evolve into: