css-syntax/Overview.src.html

Sun, 01 Sep 2013 16:18:24 +0100

author
Simon Sapin <simon.sapin@exyr.org>
date
Sun, 01 Sep 2013 16:18:24 +0100
changeset 8996
dec8752a6390
parent 8952
aa1b58939f73
child 8997
bed44c340b52
permissions
-rw-r--r--

[css-syntax] Revert <unicode-range> changes from CSS 2.1

jackalmage@8571 1 <h1>CSS Syntax Module Level 3</h1>
jackalmage@8571 2
jackalmage@8571 3 <pre class='metadata'>
jackalmage@8571 4 Status: ED
jackalmage@8571 5 ED: http://dev.w3.org/csswg/css-syntax
simon@8845 6 Previous Version: http://www.w3.org/TR/2003/WD-css3-syntax-20030813/
jackalmage@8571 7 Shortname: css-syntax
jackalmage@8571 8 Level: 3
jackalmage@8571 9 Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/
jackalmage@8571 10 Editor: Simon Sapin, Mozilla, http://exyr.org/about/
jackalmage@8571 11 Abstract: This module describes, in general terms, the basic structure and syntax of CSS stylesheets. It defines, in detail, the syntax and parsing of CSS - how to turn a stream of bytes into a meaningful stylesheet.
jackalmage@8816 12 Ignored Terms: <keyframes-name>, <keyframe-rule>, <keyframe-selector>, <translation-value>, <media-query-list>
jackalmage@8571 13 </pre>
dbaron@330 14
jackalmage@8589 15 <link href="railroad-diagrams.css" rel="stylesheet" type="text/css">
jackalmage@8589 16
jackalmage@5473 17 <h2 id="intro">
jackalmage@5473 18 Introduction</h2>
dbaron@270 19
jackalmage@8572 20 <em>This section is not normative.</em>
jackalmage@8572 21
jackalmage@8572 22 This module defines the abstract syntax and parsing of CSS stylesheets
jackalmage@8572 23 and other things which use CSS syntax
jackalmage@8572 24 (such as the HTML <code>style</code> attribute).
jackalmage@8572 25
simon@8830 26 It defines algorithms for converting a stream of Unicode <a>code points</a>
jackalmage@8572 27 (in other words, text)
jackalmage@8572 28 into a stream of CSS tokens,
jackalmage@8572 29 and then further into CSS objects
jackalmage@8572 30 such as stylesheets, rules, and declarations.
dbaron@270 31
jackalmage@5473 32 <h3 id="placement">
jackalmage@5473 33 Module interactions</h3>
dbaron@270 34
jackalmage@8572 35 This module defines the syntax and parsing of CSS stylesheets.
jackalmage@8572 36 It supersedes the lexical scanner and grammar defined in CSS 2.1.
dbaron@270 37
jackalmage@5473 38 <h2 id='syntax-description'>
jackalmage@5473 39 Description of CSS's Syntax</h2>
dbaron@270 40
jackalmage@8572 41 <em>This section is not normative.</em>
jackalmage@8572 42
jackalmage@8572 43 A CSS document is a series of <a>qualified rules</a>,
jackalmage@8572 44 which are usually style rules that apply CSS properties to elements,
jackalmage@8572 45 and <a>at-rules</a>,
jackalmage@8572 46 which define special processing rules or values for the CSS document.
jackalmage@8572 47
jackalmage@8572 48 A qualified rule starts with a prelude
jackalmage@8572 49 then has a {}-wrapped block containing a sequence of declarations.
jackalmage@8598 50 The meaning of the prelude varies based on the context that the rule appears in -
jackalmage@8572 51 for style rules, it's a selector which specifies what elements the declarations will apply to.
jackalmage@8572 52 Each declaration has a name,
jackalmage@8572 53 followed by a colon and the declaration value.
jackalmage@8572 54 Declarations are separated by semicolons.
jackalmage@5549 55
jackalmage@5549 56 <div class='example'>
jackalmage@8572 57
jackalmage@8572 58 A typical rule might look something like this:
jackalmage@5549 59
jackalmage@5549 60 <pre>
jackalmage@8572 61 p > a {
jackalmage@8572 62 color: blue;
jackalmage@8572 63 text-decoration: underline;
jackalmage@8572 64 }
jackalmage@8572 65 </pre>
jackalmage@8572 66
jackalmage@8572 67 In the above rule, "<code>p > a</code>" is the selector,
jackalmage@8572 68 which, if the source document is HTML,
jackalmage@8572 69 selects any <code>&lt;a></code> elements that are children of a <code>&lt;p></code> element.
jackalmage@8572 70
jackalmage@8572 71 "<code>color: blue;</code>" is a declaration specifying that,
jackalmage@8572 72 for the elements that match the selector,
jackalmage@8572 73 their 'color' property should have the value ''blue''.
jackalmage@8572 74 Similiarly, their 'text-decoration' property should have the value ''underline''.
jackalmage@5549 75 </div>
jackalmage@5549 76
jackalmage@8572 77 At-rules are all different, but they have a basic structure in common.
simon@8830 78 They start with an "@" <a>code point</a> followed by their name.
jackalmage@8572 79 Some <a>at-rules</a> are simple statements,
jackalmage@8572 80 with their name followed by more CSS values to specify their behavior,
jackalmage@8572 81 and finally ended by a semicolon.
jackalmage@8572 82 Others are blocks;
jackalmage@8572 83 they can have CSS values following their name,
jackalmage@8572 84 but they end with a {}-wrapped block,
jackalmage@8572 85 similar to a <a>qualified rule</a>.
jackalmage@8572 86 Even the contents of these blocks are specific to the given <a>at-rule</a>:
jackalmage@8572 87 sometimes they contain a sequence of declarations, like a <a>qualified rule</a>;
jackalmage@8572 88 other times, they may contain additional blocks, or at-rules, or other structures altogether.
jackalmage@5549 89
jackalmage@5549 90 <div class='example'>
jackalmage@8572 91
jackalmage@8572 92 Here are several examples of <a>at-rules</a> that illustrate the varied syntax they may contain.
jackalmage@5549 93
jackalmage@5549 94 <pre>@import "my-styles.css";</pre>
jackalmage@5549 95
jackalmage@8572 96 The ''@import'' <a>at-rule</a> is a simple statement.
jackalmage@8572 97 After its name, it takes a single string or ''url()'' function to indicate the stylesheet that it should import.
jackalmage@5549 98
jackalmage@5549 99 <pre>
jackalmage@8572 100 @page :left {
jackalmage@8572 101 margin-left: 4cm;
jackalmage@8572 102 margin-right: 3cm;
jackalmage@8572 103 }
jackalmage@8572 104 </pre>
jackalmage@8572 105
jackalmage@8572 106 The ''@page'' <a>at-rule</a> consists of an optional page selector (the '':left'' pseudoclass),
jackalmage@8572 107 followed by a block of properties that apply to the page when printed.
jackalmage@8572 108 In this way, it's very similar to a normal style rule,
jackalmage@8572 109 except that its properties don't apply to any "element",
jackalmage@8572 110 but rather the page itself.
jackalmage@5549 111
jackalmage@5549 112 <pre>
jackalmage@8572 113 @media print {
jackalmage@8572 114 body { font-size: 10pt }
jackalmage@8572 115 }
jackalmage@8572 116 </pre>
jackalmage@8572 117
jackalmage@8572 118 The ''@media'' <a>at-rule</a> begins with a media type
jackalmage@8572 119 and a list of optional media queries.
jackalmage@8572 120 Its block contains entire rules,
jackalmage@8572 121 which are only applied when the ''@media''s conditions are fulfilled.
jackalmage@5549 122 </div>
jackalmage@5549 123
jackalmage@8572 124 Property names and <a>at-rule</a> names are always <b>identifiers</b>,
jackalmage@8572 125 which have to start with a letter or a hyphen followed by a letter,
jackalmage@8572 126 and then can contain letters, numbers, hyphens, or underscores.
simon@8830 127 You can include any <a>code point</a> at all,
jackalmage@8572 128 even ones that CSS uses in its syntax,
simon@8751 129 by <a>escaping</a> it.
jackalmage@8572 130
jackalmage@8572 131 The syntax of selectors is defined in the <a href="http://www.w3.org/TR/selectors/">Selectors spec</a>.
jackalmage@8572 132 Similarly, the syntax of the wide variety of CSS values is defined in the <a href="http://www.w3.org/TR/css3-values/">Values &amp; Units spec</a>.
jackalmage@8572 133 The special syntaxes of individual <a>at-rules</a> can be found in the specs that define them.
simon@7402 134
simon@8751 135 <h3>
simon@8751 136 Escaping</h3>
simon@8751 137
simon@8751 138 <em>This section is not normative.</em>
simon@8751 139
simon@8830 140 Any Unicode <a>code point</a> can be included in an identifier or quoted string
simon@8751 141 by <dfn>escaping</dfn> it.
simon@8751 142 CSS escape sequences start with a backslash (\), and continue with:
simon@8751 143
simon@8751 144 <ul>
simon@8751 145 <li>
simon@8830 146 Any Unicode <a>code point</a> that is not a <a>hex digits</a> or a <a>newline</a>.
simon@8830 147 The escape sequence is replaced by that <a>code point</a>.
simon@8751 148 <li>
simon@8751 149 Or one to six <a>hex digits</a>, followed by an optional <a>whitespace</a>.
simon@8830 150 The escape sequence is replaced by the Unicode <a>code point</a>
simon@8830 151 whose value is given by the hexadecimal digits.
simon@8751 152 This optional whitespace allow hexadecimal escape sequences
simon@8751 153 to be followed by "real" hex digits.
simon@8751 154
simon@8751 155 <p class=example>
simon@8751 156 An identifier with the value "&B"
simon@8751 157 could be written as ''\26 B'' or ''\000026B''.
simon@8751 158
simon@8751 159 <p class=note>
simon@8751 160 A "real" space after the escape sequence must be doubled.
simon@8751 161 </ul>
jackalmage@7550 162
jackalmage@7550 163 <h3>
jackalmage@7550 164 Error Handling</h3>
jackalmage@7550 165
jackalmage@8572 166 <em>This section is not normative.</em>
jackalmage@8572 167
jackalmage@8572 168 When errors occur in CSS,
jackalmage@8572 169 the parser attempts to recover gracefully,
jackalmage@8572 170 throwing away only the minimum amount of content
jackalmage@8572 171 before returning to parsing as normal.
jackalmage@8598 172 This is because errors aren't always mistakes -
jackalmage@8572 173 new syntax looks like an error to an old parser,
jackalmage@8572 174 and it's useful to be able to add new syntax to the language
jackalmage@8572 175 without worrying about stylesheets that include it being completely broken in older UAs.
jackalmage@8572 176
jackalmage@8572 177 The precise error-recovery behavior is detailed in the parser itself,
jackalmage@8572 178 but it's simple enough that a short description is fairly accurate:
jackalmage@7550 179
jackalmage@7550 180 <ul>
jackalmage@7550 181 <li>
jackalmage@8125 182 At the "top level" of a stylesheet,
jackalmage@8819 183 an <<<at-keyword>>> starts an at-rule.
jackalmage@8125 184 Anything else starts a qualified rule,
jackalmage@8125 185 and is included in the rule's prelude.
jackalmage@8125 186 This may produce an invalid selector,
jackalmage@8125 187 but that's not the concern of the CSS parser &mdash;
jackalmage@8125 188 at worst, it means the selector will match nothing.
jackalmage@7550 189
jackalmage@7550 190 <li>
jackalmage@8125 191 Once an at-rule starts,
jackalmage@8125 192 nothing is invalid from the parser's standpoint;
jackalmage@8125 193 it's all part of the at-rule's prelude.
jackalmage@8819 194 Encountering a <<<semicolon>>> ends the at-rule immediately,
jackalmage@8819 195 while encountering an opening curly-brace <<<{>>> starts the at-rule's body.
jackalmage@8125 196 The at-rule seeks forward, matching blocks (content surrounded by (), {}, or [])
jackalmage@8819 197 until it finds a closing curly-brace <<<}>>> that isn't matched by anything else
jackalmage@8125 198 or inside of another block.
jackalmage@8125 199 The contents of the at-rule are then interpreted according to the at-rule's own grammar.
jackalmage@7550 200
jackalmage@7550 201 <li>
jackalmage@8598 202 Qualified rules work similarly,
jackalmage@8125 203 except that semicolons don't end them;
jackalmage@8125 204 instead, they are just taken in as part of the rule's prelude.
jackalmage@8125 205 When the first {} block is found,
jackalmage@8125 206 the contents are always interpreted as a list of declarations.
jackalmage@8125 207
jackalmage@8125 208 <li>
jackalmage@8125 209 When interpreting a list of declarations,
jackalmage@8125 210 unknown syntax at any point causes the parser to throw away whatever declaration it's currently building,
jackalmage@8125 211 and seek forward until it finds a semicolon (or the end of the block).
jackalmage@8125 212 It then starts fresh, trying to parse a declaration again.
jackalmage@7550 213
jackalmage@7550 214 <li>
jackalmage@7550 215 If the stylesheet ends while any rule, declaration, function, string, etc. are still open,
jackalmage@7550 216 everything is automatically closed.
jackalmage@7550 217 This doesn't make them invalid,
jackalmage@7550 218 though they may be incomplete
jackalmage@7550 219 and thus thrown away when they are verified against their grammar.
jackalmage@7550 220 </ul>
jackalmage@7550 221
jackalmage@5473 222 <h2>
jackalmage@6563 223 Tokenizing and Parsing CSS</h2>
dbaron@270 224
jackalmage@8572 225 User agents must use the parsing rules described in this specification
jackalmage@8572 226 to generate the CSSOM trees from text/css resources.
jackalmage@8572 227 Together, these rules define what is referred to as the CSS parser.
jackalmage@8572 228
jackalmage@8572 229 This specification defines the parsing rules for CSS documents,
jackalmage@8572 230 whether they are syntactically correct or not.
jackalmage@8572 231 Certain points in the parsing algorithm are said to be a <dfn title="parse error">parse errors</dfn>.
jackalmage@8572 232 The error handling for parse errors is well-defined:
jackalmage@8572 233 user agents must either act as described below when encountering such problems,
jackalmage@8572 234 or must abort processing at the first error that they encounter for which they do not wish to apply the rules described below.
jackalmage@8572 235
jackalmage@8572 236 Conformance checkers must report at least one parse error condition to the user
jackalmage@8572 237 if one or more parse error conditions exist in the document
jackalmage@8572 238 and must not report parse error conditions
jackalmage@8572 239 if none exist in the document.
jackalmage@8572 240 Conformance checkers may report more than one parse error condition if more than one parse error condition exists in the document.
jackalmage@8572 241 Conformance checkers are not required to recover from parse errors,
jackalmage@8572 242 but if they do,
jackalmage@8572 243 they must recover in the same way as user agents.
dbaron@270 244
jackalmage@5473 245 <h3>
jackalmage@5473 246 Overview of the Parsing Model</h3>
dbaron@273 247
simon@8830 248 The input to the CSS parsing process consists of a stream of Unicode <a>code points</a>,
jackalmage@8572 249 which is passed through a tokenization stage followed by a tree construction stage.
jackalmage@8572 250 The output is a CSSStyleSheet object.
jackalmage@8572 251
jackalmage@8572 252 Note: Implementations that do not support scripting do not have to actually create a CSSOM CSSStyleSheet object,
jackalmage@8572 253 but the CSSOM tree in such cases is still used as the model for the rest of the specification.
dbaron@273 254
jackalmage@5473 255 <h3>
jackalmage@5473 256 The input byte stream</h3>
dbaron@273 257
jackalmage@8572 258 When parsing a stylesheet,
simon@8830 259 the stream of Unicode <a>code points</a> that comprises the input to the tokenization stage
simon@8830 260 may be initially seen by the user agent as a stream of bytes
jackalmage@8572 261 (typically coming over the network or from the local file system).
simon@8830 262 The bytes encode the <a>code points</a> according to a particular character encoding,
simon@8830 263 which the user agent must use to decode the bytes into <a>code points</a>.
simon@8830 264
simon@8830 265 To decode the stream of bytes into a stream of <a>code points</a>,
jackalmage@8572 266 UAs must follow these steps.
jackalmage@8572 267
jackalmage@8572 268 The algorithms to <a href="http://encoding.spec.whatwg.org/#concept-encoding-get"><dfn>get an encoding</dfn></a>
jackalmage@8572 269 and <a href="http://encoding.spec.whatwg.org/#decode"><dfn>decode</dfn></a>
jackalmage@8572 270 are defined in the <a href="http://encoding.spec.whatwg.org/">Encoding Standard</a>.
jackalmage@8572 271
jackalmage@8744 272 First, <dfn>determine the fallback encoding</dfn>:
jackalmage@7465 273
jackalmage@6922 274 <ol>
jackalmage@6922 275 <li>
simon@7402 276 If HTTP or equivalent protocol defines an encoding (e.g. via the charset parameter of the Content-Type header),
jackalmage@8572 277 <a>get an encoding</a> for the specified value.
jackalmage@6944 278 If that does not return failure,
jackalmage@7465 279 use the return value as the fallback encoding.
jackalmage@6922 280
jackalmage@6922 281 <li>
jackalmage@7465 282 Otherwise, check the byte stream. If the first several bytes match the hex sequence
jackalmage@7465 283
jackalmage@7465 284 <pre>40 63 68 61 72 73 65 74 20 22 (not 22)* 22 3B</pre>
jackalmage@7465 285
jackalmage@8572 286 then <a>get an encoding</a> for the sequence of <code>(not 22)*</code> bytes,
jackalmage@7465 287 decoded per <code>windows-1252</code>.
jackalmage@6922 288
jackalmage@8572 289 Note: Anything ASCII-compatible will do, so using <code>windows-1252</code> is fine.
jackalmage@8572 290
jackalmage@8572 291
jackalmage@8572 292 Note: The byte sequence above,
jackalmage@8572 293 when decoded as ASCII,
jackalmage@8572 294 is the string "<code>@charset "…";</code>",
jackalmage@8572 295 where the "…" is the sequence of bytes corresponding to the encoding's name.
jackalmage@8572 296
jackalmage@8572 297 If the return value was <code>utf-16</code> or <code>utf-16be</code>,
jackalmage@8572 298 use <code>utf-8</code> as the fallback encoding;
jackalmage@8572 299 if it was anything else except failure,
jackalmage@8572 300 use the return value as the fallback encoding.
jackalmage@8572 301
jackalmage@8572 302 Note: This mimics HTML <code>&lt;meta></code> behavior.
jackalmage@6944 303
jackalmage@6922 304 <li>
jackalmage@8572 305 Otherwise, <a>get an encoding</a> for the value of the <code>charset</code> attribute on the <code>&lt;link></code> element or <code>&lt;?xml-stylesheet?></code> processing instruction that caused the style sheet to be included, if any.
jackalmage@6944 306 If that does not return failure,
jackalmage@7465 307 use the return value as the fallback encoding.
jackalmage@6922 308
jackalmage@6922 309 <li>
jackalmage@7465 310 Otherwise, if the referring style sheet or document has an encoding,
jackalmage@7465 311 use that as the fallback encoding.
jackalmage@6922 312
jackalmage@6922 313 <li>
jackalmage@7465 314 Otherwise, use <code>utf-8</code> as the fallback encoding.
jackalmage@6922 315 </ol>
simon@7474 316
jackalmage@8572 317 Then, <a>decode</a> the byte stream using the fallback encoding.
jackalmage@8572 318
jackalmage@8572 319 Note: the <a>decode</a> algorithm lets the byte order mark (BOM) take precedence,
jackalmage@8572 320 hence the usage of the term "fallback" above.
jackalmage@6922 321
jackalmage@6944 322 <p class='issue'>
simon@7479 323 Anne says that steps 3/4 should be an input to this algorithm from the specs that define importing stylesheet,
jackalmage@6944 324 to make the algorithm as a whole cleaner.
jackalmage@6944 325 Perhaps abstract it into the concept of an "environment charset" or something?
jackalmage@6944 326
jackalmage@8110 327 <p class='issue'>
jackalmage@8110 328 Should we only take the charset from the referring document if it's same-origin?
jackalmage@8110 329
dbaron@273 330
jackalmage@8273 331 <h3>
jackalmage@8273 332 Preprocessing the input stream</h3>
dbaron@273 333
simon@8830 334 The input stream consists of the <a>code points</a>
jackalmage@8572 335 pushed into it as the input byte stream is decoded.
jackalmage@8572 336
jackalmage@8572 337 Before sending the input stream to the tokenizer,
simon@8830 338 implementations must make the following <a>code point</a> substitutions:
jackalmage@6923 339
jackalmage@6923 340 <ul>
jackalmage@6923 341 <li>
simon@8830 342 Replace any U+000D CARRIAGE RETURN (CR) <a>code point</a>,
simon@8830 343 U+000C FORM FEED (FF) <a>code point</a>,
simon@7402 344 or pairs of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF)
simon@8830 345 by a single U+000A LINE FEED (LF) <a>code point</a>.
jackalmage@6923 346
jackalmage@6923 347 <li>
simon@8830 348 Replace any U+0000 NULL <a>code point</a> with U+FFFD REPLACEMENT CHARACTER (�).
jackalmage@6923 349 </ul>
dbaron@273 350
dbaron@291 351
jackalmage@7224 352 <h2>
jackalmage@7224 353 Tokenization</h2>
dbaron@291 354
jackalmage@8572 355 Implementations must act as if they used the following algorithms to tokenize CSS.
simon@8830 356 To transform a stream of <a>code points</a> into a stream of tokens,
jackalmage@8572 357 repeatedly <a>consume a token</a>
jackalmage@8819 358 until an <<<EOF>>> is reached,
jackalmage@8572 359 collecting the returned tokens into a stream.
jackalmage@8572 360 Each call to the <a>consume a token</a> algorithm
jackalmage@8572 361 returns a single token,
simon@8830 362 so it can also be used "on-demand" to tokenize a stream of <a>code points</a> <em>during</em> parsing,
jackalmage@8572 363 if so desired.
jackalmage@8572 364
jackalmage@8572 365 The output of the tokenization step is a stream of zero or more of the following tokens:
jackalmage@8819 366 <dfn>〈ident〉</dfn>,
jackalmage@8819 367 <dfn>〈function〉</dfn>,
jackalmage@8819 368 <dfn>〈at-keyword〉</dfn>,
jackalmage@8819 369 <dfn>〈hash〉</dfn>,
jackalmage@8819 370 <dfn>〈string〉</dfn>,
jackalmage@8819 371 <dfn>〈bad-string〉</dfn>,
jackalmage@8819 372 <dfn>〈url〉</dfn>,
jackalmage@8819 373 <dfn>〈bad-url〉</dfn>,
jackalmage@8819 374 <dfn>〈delim〉</dfn>,
jackalmage@8819 375 <dfn>〈number〉</dfn>,
jackalmage@8819 376 <dfn>〈percentage〉</dfn>,
jackalmage@8819 377 <dfn>〈dimension〉</dfn>,
jackalmage@8819 378 <dfn>〈unicode-range〉</dfn>,
jackalmage@8819 379 <dfn>〈include-match〉</dfn>,
jackalmage@8819 380 <dfn>〈dash-match〉</dfn>,
jackalmage@8819 381 <dfn>〈prefix-match〉</dfn>,
jackalmage@8819 382 <dfn>〈suffix-match〉</dfn>,
jackalmage@8819 383 <dfn>〈substring-match〉</dfn>,
jackalmage@8819 384 <dfn>〈column〉</dfn>,
jackalmage@8819 385 <dfn>〈whitespace〉</dfn>,
jackalmage@8819 386 <dfn>〈CDO〉</dfn>,
jackalmage@8819 387 <dfn>〈CDC〉</dfn>,
jackalmage@8819 388 <dfn>〈colon〉</dfn>,
jackalmage@8819 389 <dfn>〈semicolon〉</dfn>,
jackalmage@8819 390 <dfn>〈comma〉</dfn>,
jackalmage@8819 391 <dfn id="tokendef-open-square">〈[〉</dfn>,
jackalmage@8819 392 <dfn id="tokendef-close-square">〈]〉</dfn>,
jackalmage@8819 393 <dfn id="tokendef-open-paren">〈(〉</dfn>,
jackalmage@8819 394 <dfn id="tokendef-close-paren">〈)〉</dfn>,
jackalmage@8819 395 <dfn id="tokendef-open-curly">〈{〉</dfn>,
jackalmage@8819 396 and <dfn id="tokendef-close-curly">〈}〉</dfn>.
dbaron@270 397
jackalmage@8308 398 <ul>
jackalmage@8308 399 <li>
simon@8830 400 <<<ident>>>, <<<function>>>, <<<at-keyword>>>, <<<hash>>>, <<<string>>>, and <<<url>>> tokens have a value composed of zero or more <a>code points</a>.
jackalmage@8308 401 Additionally, hash tokens have a type flag set to either "id" or "unrestricted". The type flag defaults to "unrestricted" if not otherwise set.
jackalmage@8572 402
jackalmage@8308 403 <li>
simon@8830 404 <<<delim>>> tokens have a value composed of a single <a>code point</a>.
jackalmage@8308 405
jackalmage@8308 406 <li>
simon@8830 407 <<<number>>>, <<<percentage>>>, and <<<dimension>>> tokens have a representation composed of one or more <a>code points</a>, and a numeric value.
jackalmage@8819 408 <<<number>>> and <<<dimension>>> tokens additionally have a type flag set to either "integer" or "number". The type flag defaults to "integer" if not otherwise set.
simon@8830 409 <<<dimension>>> tokens additionally have a unit composed of one or more <a>code points</a>.
jackalmage@8308 410
jackalmage@8308 411 <li>
simon@8996 412 <<<unicode-range>>> tokens have
simon@8996 413 a <dfn id=unicode-range-start title=unicode-range-start>start</dfn> made of one to six <a>hex digits</a> or U+003F QUESTION MARK (?) code points,
simon@8996 414 and and optional <dfn id=unicode-range-end title=unicode-range-end>end</dfn> made of one to six <a>hex digits</a>.
jackalmage@8308 415 </ul>
dbaron@279 416
jackalmage@8572 417 Note: The type flag of hash tokens is used in the Selectors syntax [[SELECT]].
jackalmage@8572 418 Only hash tokens with the "id" type are valid <a href="http://www.w3.org/TR/selectors/#id-selectors">ID selectors</a>.
jackalmage@8572 419
simon@8996 420 Note: The syntax of <<<unicode-range>>> tokens defined in this specification
simon@8996 421 is a super-set of the <<urange>> value accepted by ''@font-face''’s 'unicode-range' descriptor. [[CSS3-FONTS]]
simon@8996 422 For example, ''U+4??6'' and ''U+1??-300'' are valid <<<unicode-range>>> tokens
simon@8996 423 but not valid <<urange>> values.
simon@8996 424
jackalmage@8572 425 Note: As a technical note,
simon@8830 426 the tokenizer defined here requires only three <a>code points</a> of look-ahead.
jackalmage@8572 427 The tokens it produces are designed to allow Selectors to be parsed with one token of look-ahead,
jackalmage@8572 428 and additional tokens may be added in the future to maintain this invariant.
jackalmage@8309 429
dbaron@270 430
jackalmage@7224 431 <h3 id='token-diagrams'>
jackalmage@7224 432 Token Railroad Diagrams</h3>
jackalmage@6819 433
jackalmage@8572 434 <em>This section is non-normative.</em>
jackalmage@8572 435
jackalmage@8572 436 This section presents an informative view of the tokenizer,
jackalmage@8572 437 in the form of railroad diagrams.
jackalmage@8572 438 Railroad diagrams are more compact than an explicit parser,
jackalmage@8572 439 but often easier to read than an regular expression.
jackalmage@8572 440
jackalmage@8572 441 These diagrams are <em>informative</em> and <em>incomplete</em>;
jackalmage@8572 442 they describe the grammar of "correct" tokens,
jackalmage@8572 443 but do not describe error-handling at all.
jackalmage@8572 444 They are provided solely to make it easier to get an intuitive grasp of the syntax of each token.
jackalmage@8572 445
jackalmage@8819 446 Diagrams with names between <<<>>> brackets represent tokens.
jackalmage@8572 447 The rest are productions referred to by other diagrams.
simon@7926 448
simon@7048 449 <!--
simon@7048 450 The "source" of these diagrams is in ./Diagrams.src.html
simon@7048 451 The generated SVG is copied here so that JavaScript is not required
simon@7048 452 to view the spec.
simon@7048 453 -->
jackalmage@6819 454 <dl>
simon@7476 455 <dt id="comment-diagram">comment</dt>
simon@7476 456 <dd><svg class="railroad-diagram" width="497" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M86 41h0"></path><rect x="50" y="30" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="45">/*</text></g><path d="M86 41h10"></path><g><path d="M96 41h0"></path><path d="M400 41h0"></path><path d="M96 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M116 21h264"></path></g><path d="M380 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M96 41h20"></path><g><path d="M116 41h0"></path><path d="M380 41h0"></path><path d="M116 41h10"></path><g><path d="M126 41h0"></path><path d="M370 41h0"></path><rect x="126" y="30" width="244" height="22"></rect><text x="248" y="45">anything but * followed by /</text></g><path d="M370 41h10"></path><path d="M126 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M126 61h244"></path></g><path d="M370 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M380 41h20"></path></g><path d="M400 41h10"></path><g><path d="M410 41h0"></path><path d="M446 41h0"></path><rect x="410" y="30" width="36" height="22" rx="10" ry="10"></rect><text x="428" y="45">*/</text></g><path d="M446 41h10"></path><path d="M 456 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 457
simon@7476 458 <dt id="newline-diagram">newline</dt>
simon@7476 459 <dd><svg class="railroad-diagram" width="173" height="152"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 31h0"></path><path d="M132 31h0"></path><path d="M40 31h20"></path><g><path d="M60 31h8"></path><path d="M104 31h8"></path><rect x="68" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="86" y="35">\n</text></g><path d="M112 31h20"></path><path d="M40 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M60 61h0"></path><path d="M112 61h0"></path><rect x="60" y="50" width="52" height="22" rx="10" ry="10"></rect><text x="86" y="65">\r\n</text></g><path d="M112 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><g><path d="M60 91h8"></path><path d="M104 91h8"></path><rect x="68" y="80" width="36" height="22" rx="10" ry="10"></rect><text x="86" y="95">\r</text></g><path d="M112 91a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v70a10 10 0 0 0 10 10"></path><g><path d="M60 121h8"></path><path d="M104 121h8"></path><rect x="68" y="110" width="36" height="22" rx="10" ry="10"></rect><text x="86" y="125">\f</text></g><path d="M112 121a10 10 0 0 0 10 -10v-70a10 10 0 0 1 10 -10"></path></g><path d="M 132 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 460
simon@8830 461 <dt id="whitespace-diagram">whitespace</dt>
simon@7476 462 <dd><svg class="railroad-diagram" width="197" height="122"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 31h0"></path><path d="M156 31h0"></path><path d="M40 31h20"></path><g><path d="M60 31h8"></path><path d="M128 31h8"></path><rect x="68" y="20" width="60" height="22" rx="10" ry="10"></rect><text x="98" y="35">space</text></g><path d="M136 31h20"></path><path d="M40 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M60 61h20"></path><path d="M116 61h20"></path><rect x="80" y="50" width="36" height="22" rx="10" ry="10"></rect><text x="98" y="65">\t</text></g><path d="M136 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><g><path d="M60 91h0"></path><path d="M136 91h0"></path><rect x="60" y="80" width="76" height="22"></rect><text x="98" y="95">newline</text></g><path d="M136 91a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path></g><path d="M 156 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 463
simon@8996 464 <dt id="hex-digit-diagram">hex digit</dt>
simon@8996 465 <dd><svg class="railroad-diagram" width="233" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M182 31h0"></path><rect x="50" y="20" width="132" height="22"></rect><text x="116" y="35">0-9 a-f or A-F</text></g><path d="M182 31h10"></path><path d="M 192 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8996 466
simon@7048 467 <dt id="escape-diagram">escape</dt>
simon@8830 468 <dd><svg class="railroad-diagram" width="441" height="122"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M78 31h0"></path><rect x="50" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="35">\</text></g><path d="M78 31h10"></path><g><path d="M88 31h0"></path><path d="M400 31h0"></path><path d="M88 31h20"></path><g><path d="M108 31h30"></path><path d="M350 31h30"></path><rect x="138" y="20" width="212" height="22"></rect><text x="244" y="35">not newline or hex digit</text></g><path d="M380 31h20"></path><path d="M88 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M108 61h0"></path><path d="M380 61h0"></path><path d="M108 61h10"></path><g><path d="M118 61h0"></path><path d="M230 61h0"></path><path d="M118 61h10"></path><g><path d="M128 61h0"></path><path d="M220 61h0"></path><rect x="128" y="50" width="92" height="22"></rect><text x="174" y="65">hex digit</text></g><path d="M220 61h10"></path><path d="M128 61a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path><g><path d="M128 91h9.5"></path><path d="M210.5 91h9.5"></path><text x="174" y="96" class="comment">1-6 times</text></g><path d="M220 91a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path></g><path d="M230 61h10"></path><g><path d="M240 61h0"></path><path d="M380 61h0"></path><path d="M240 61h20"></path><g><path d="M260 61h100"></path></g><path d="M360 61h20"></path><path d="M240 61a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M260 81h0"></path><path d="M360 81h0"></path><rect x="260" y="70" width="100" height="22"></rect><text x="310" y="85">whitespace</text></g><path d="M360 81a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g></g><path d="M380 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M 400 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 469
simon@8830 470 <dt id="〈whitespace〉-diagram">〈whitespace〉</dt>
simon@8830 471 <dd><svg class="railroad-diagram" width="221" height="71"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M170 31h0"></path><path d="M50 31h10"></path><g><path d="M60 31h0"></path><path d="M160 31h0"></path><rect x="60" y="20" width="100" height="22"></rect><text x="110" y="35">whitespace</text></g><path d="M160 31h10"></path><path d="M60 31a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M60 51h100"></path></g><path d="M160 51a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M170 31h10"></path><path d="M 180 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 472
simon@8830 473 <dt id="〈ident〉-diagram">〈ident〉</dt>
simon@7048 474 <dd><svg class="railroad-diagram" width="729" height="110"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 41h0"></path><path d="M108 41h0"></path><path d="M40 41h20"></path><g><path d="M60 41h28"></path></g><path d="M88 41h20"></path><path d="M40 41a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M60 61h0"></path><path d="M88 61h0"></path><rect x="60" y="50" width="28" height="22" rx="10" ry="10"></rect><text x="74" y="65">-</text></g><path d="M88 61a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g><g><path d="M108 41h0"></path><path d="M344 41h0"></path><path d="M108 41h20"></path><g><path d="M128 41h0"></path><path d="M324 41h0"></path><rect x="128" y="30" width="196" height="22"></rect><text x="226" y="45">a-z A-Z _ or non-ASCII</text></g><path d="M324 41h20"></path><path d="M108 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M128 71h64"></path><path d="M260 71h64"></path><rect x="192" y="60" width="68" height="22"></rect><text x="226" y="75">escape</text></g><path d="M324 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g><path d="M344 41h0"></path><path d="M688 41h0"></path><path d="M344 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M364 21h304"></path></g><path d="M668 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M344 41h20"></path><g><path d="M364 41h0"></path><path d="M668 41h0"></path><path d="M364 41h10"></path><g><path d="M374 41h0"></path><path d="M658 41h0"></path><path d="M374 41h20"></path><g><path d="M394 41h0"></path><path d="M638 41h0"></path><rect x="394" y="30" width="244" height="22"></rect><text x="516" y="45">a-z A-Z 0-9 _ - or non-ASCII</text></g><path d="M638 41h20"></path><path d="M374 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M394 71h88"></path><path d="M550 71h88"></path><rect x="482" y="60" width="68" height="22"></rect><text x="516" y="75">escape</text></g><path d="M638 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M658 41h10"></path><path d="M374 41a10 10 0 0 0 -10 10v29a10 10 0 0 0 10 10"></path><g><path d="M374 90h284"></path></g><path d="M658 90a10 10 0 0 0 10 -10v-29a10 10 0 0 0 -10 -10"></path></g><path d="M668 41h20"></path></g><path d="M 688 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 475
simon@8830 476 <dt id="〈function〉-diagram">〈function〉</dt>
simon@8830 477 <dd><svg class="railroad-diagram" width="225" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M126 31h0"></path><rect x="50" y="20" width="76" height="22"></rect><text x="88" y="35">〈ident〉</text></g><path d="M126 31h10"></path><path d="M136 31h10"></path><g><path d="M146 31h0"></path><path d="M174 31h0"></path><rect x="146" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="160" y="35">(</text></g><path d="M174 31h10"></path><path d="M 184 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 478
simon@8830 479 <dt id="〈at-keyword〉-diagram">〈at-keyword〉</dt>
simon@8830 480 <dd><svg class="railroad-diagram" width="225" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M78 31h0"></path><rect x="50" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="35">@</text></g><path d="M78 31h10"></path><path d="M88 31h10"></path><g><path d="M98 31h0"></path><path d="M174 31h0"></path><rect x="98" y="20" width="76" height="22"></rect><text x="136" y="35">〈ident〉</text></g><path d="M174 31h10"></path><path d="M 184 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 481
simon@8830 482 <dt id="〈hash〉-diagram">〈hash〉</dt>
simon@7048 483 <dd><svg class="railroad-diagram" width="453" height="100"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M78 31h0"></path><rect x="50" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="35">#</text></g><path d="M78 31h10"></path><path d="M88 31h10"></path><g><path d="M98 31h0"></path><path d="M402 31h0"></path><path d="M98 31h10"></path><g><path d="M108 31h0"></path><path d="M392 31h0"></path><path d="M108 31h20"></path><g><path d="M128 31h0"></path><path d="M372 31h0"></path><rect x="128" y="20" width="244" height="22"></rect><text x="250" y="35">a-z A-Z 0-9 _ - or non-ASCII</text></g><path d="M372 31h20"></path><path d="M108 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M128 61h88"></path><path d="M284 61h88"></path><rect x="216" y="50" width="68" height="22"></rect><text x="250" y="65">escape</text></g><path d="M372 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M392 31h10"></path><path d="M108 31a10 10 0 0 0 -10 10v29a10 10 0 0 0 10 10"></path><g><path d="M108 80h284"></path></g><path d="M392 80a10 10 0 0 0 10 -10v-29a10 10 0 0 0 -10 -10"></path></g><path d="M402 31h10"></path><path d="M 412 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 484
simon@8830 485 <dt id="〈string〉-diagram">〈string〉</dt>
simon@7476 486 <dd><svg class="railroad-diagram" width="481" height="248"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 41h0"></path><path d="M440 41h0"></path><path d="M40 41h20"></path><g><path d="M60 41h0"></path><path d="M420 41h0"></path><path d="M60 41h10"></path><g><path d="M70 41h0"></path><path d="M98 41h0"></path><rect x="70" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="84" y="45">"</text></g><path d="M98 41h10"></path><g><path d="M108 41h0"></path><path d="M372 41h0"></path><path d="M108 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M128 21h224"></path></g><path d="M352 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M108 41h20"></path><g><path d="M128 41h0"></path><path d="M352 41h0"></path><path d="M128 41h10"></path><g><path d="M138 41h0"></path><path d="M342 41h0"></path><path d="M138 41h20"></path><g><path d="M158 41h0"></path><path d="M322 41h0"></path><rect x="158" y="30" width="164" height="22"></rect><text x="240" y="45">not " \ or newline</text></g><path d="M322 41h20"></path><path d="M138 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M158 71h48"></path><path d="M274 71h48"></path><rect x="206" y="60" width="68" height="22"></rect><text x="240" y="75">escape</text></g><path d="M322 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><path d="M138 41a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><g><path d="M158 101h10"></path><path d="M312 101h10"></path><path d="M168 101h10"></path><g><path d="M178 101h0"></path><path d="M206 101h0"></path><rect x="178" y="90" width="28" height="22" rx="10" ry="10"></rect><text x="192" y="105">\</text></g><path d="M206 101h10"></path><path d="M216 101h10"></path><g><path d="M226 101h0"></path><path d="M302 101h0"></path><rect x="226" y="90" width="76" height="22"></rect><text x="264" y="105">newline</text></g><path d="M302 101h10"></path></g><path d="M322 101a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path></g><path d="M342 41h10"></path><path d="M138 41a10 10 0 0 0 -10 10v59a10 10 0 0 0 10 10"></path><g><path d="M138 120h204"></path></g><path d="M342 120a10 10 0 0 0 10 -10v-59a10 10 0 0 0 -10 -10"></path></g><path d="M352 41h20"></path></g><path d="M372 41h10"></path><g><path d="M382 41h0"></path><path d="M410 41h0"></path><rect x="382" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="396" y="45">"</text></g><path d="M410 41h10"></path></g><path d="M420 41h20"></path><path d="M40 41a10 10 0 0 1 10 10v88a10 10 0 0 0 10 10"></path><g><path d="M60 149h0"></path><path d="M420 149h0"></path><path d="M60 149h10"></path><g><path d="M70 149h0"></path><path d="M98 149h0"></path><rect x="70" y="138" width="28" height="22" rx="10" ry="10"></rect><text x="84" y="153">&apos;</text></g><path d="M98 149h10"></path><g><path d="M108 149h0"></path><path d="M372 149h0"></path><path d="M108 149a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M128 129h224"></path></g><path d="M352 129a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M108 149h20"></path><g><path d="M128 149h0"></path><path d="M352 149h0"></path><path d="M128 149h10"></path><g><path d="M138 149h0"></path><path d="M342 149h0"></path><path d="M138 149h20"></path><g><path d="M158 149h0"></path><path d="M322 149h0"></path><rect x="158" y="138" width="164" height="22"></rect><text x="240" y="153">not &apos; \ or newline</text></g><path d="M322 149h20"></path><path d="M138 149a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M158 179h48"></path><path d="M274 179h48"></path><rect x="206" y="168" width="68" height="22"></rect><text x="240" y="183">escape</text></g><path d="M322 179a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><path d="M138 149a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><g><path d="M158 209h10"></path><path d="M312 209h10"></path><path d="M168 209h10"></path><g><path d="M178 209h0"></path><path d="M206 209h0"></path><rect x="178" y="198" width="28" height="22" rx="10" ry="10"></rect><text x="192" y="213">\</text></g><path d="M206 209h10"></path><path d="M216 209h10"></path><g><path d="M226 209h0"></path><path d="M302 209h0"></path><rect x="226" y="198" width="76" height="22"></rect><text x="264" y="213">newline</text></g><path d="M302 209h10"></path></g><path d="M322 209a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path></g><path d="M342 149h10"></path><path d="M138 149a10 10 0 0 0 -10 10v59a10 10 0 0 0 10 10"></path><g><path d="M138 228h204"></path></g><path d="M342 228a10 10 0 0 0 10 -10v-59a10 10 0 0 0 -10 -10"></path></g><path d="M352 149h20"></path></g><path d="M372 149h10"></path><g><path d="M382 149h0"></path><path d="M410 149h0"></path><rect x="382" y="138" width="28" height="22" rx="10" ry="10"></rect><text x="396" y="153">&apos;</text></g><path d="M410 149h10"></path></g><path d="M420 149a10 10 0 0 0 10 -10v-88a10 10 0 0 1 10 -10"></path></g><path d="M 440 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 487
simon@8830 488 <dt id="〈url〉-diagram">〈url〉</dt>
simon@8830 489 <dd><svg class="railroad-diagram" width="829" height="102"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M174 41h0"></path><rect x="50" y="30" width="124" height="22"></rect><text x="112" y="45">〈ident "url"〉</text></g><path d="M174 41h10"></path><path d="M184 41h10"></path><g><path d="M194 41h0"></path><path d="M222 41h0"></path><rect x="194" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="208" y="45">(</text></g><path d="M222 41h10"></path><g><path d="M232 41h0"></path><path d="M388 41h0"></path><path d="M232 41h20"></path><g><path d="M252 41h116"></path></g><path d="M368 41h20"></path><path d="M232 41a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M252 61h0"></path><path d="M368 61h0"></path><rect x="252" y="50" width="116" height="22"></rect><text x="310" y="65">〈whitespace〉</text></g><path d="M368 61a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g><g><path d="M388 41h0"></path><path d="M740 41h0"></path><path d="M388 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M408 21h312"></path></g><path d="M720 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M388 41h20"></path><g><path d="M408 41h0"></path><path d="M720 41h0"></path><g><path d="M408 41h0"></path><path d="M564 41h0"></path><path d="M408 41h20"></path><g><path d="M428 41h0"></path><path d="M544 41h0"></path><rect x="428" y="30" width="116" height="22"></rect><text x="486" y="45">url-unquoted</text></g><path d="M544 41h20"></path><path d="M408 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M428 71h24"></path><path d="M520 71h24"></path><rect x="452" y="60" width="68" height="22"></rect><text x="486" y="75">STRING</text></g><path d="M544 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g><path d="M564 41h0"></path><path d="M720 41h0"></path><path d="M564 41h20"></path><g><path d="M584 41h116"></path></g><path d="M700 41h20"></path><path d="M564 41a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M584 61h0"></path><path d="M700 61h0"></path><rect x="584" y="50" width="116" height="22"></rect><text x="642" y="65">〈whitespace〉</text></g><path d="M700 61a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g></g><path d="M720 41h20"></path></g><path d="M740 41h10"></path><g><path d="M750 41h0"></path><path d="M778 41h0"></path><rect x="750" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="764" y="45">)</text></g><path d="M778 41h10"></path><path d="M 788 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 490
simon@7476 491 <dt id="url-unquoted-diagram">url-unquoted</dt>
simon@7476 492 <dd><svg class="railroad-diagram" width="509" height="100"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M458 31h0"></path><path d="M50 31h10"></path><g><path d="M60 31h0"></path><path d="M448 31h0"></path><path d="M60 31h20"></path><g><path d="M80 31h0"></path><path d="M428 31h0"></path><rect x="80" y="20" width="348" height="22"></rect><text x="254" y="35">not " &apos; ( ) \ whitespace or non-printable</text></g><path d="M428 31h20"></path><path d="M60 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M80 61h140"></path><path d="M288 61h140"></path><rect x="220" y="50" width="68" height="22"></rect><text x="254" y="65">escape</text></g><path d="M428 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M448 31h10"></path><path d="M60 31a10 10 0 0 0 -10 10v29a10 10 0 0 0 10 10"></path><g><path d="M60 80h388"></path></g><path d="M448 80a10 10 0 0 0 10 -10v-29a10 10 0 0 0 -10 -10"></path></g><path d="M458 31h10"></path><path d="M 468 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 493
simon@8830 494 <dt id="〈number〉-diagram">〈number〉</dt>
jackalmage@8081 495 <dd><svg class="railroad-diagram" width="713" height="179"><g transform="translate(.5 .5)"><path d="M 20 50 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 60h0"></path><path d="M108 60h0"></path><path d="M40 60a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M60 40h0"></path><path d="M88 40h0"></path><rect x="60" y="29" width="28" height="22" rx="10" ry="10"></rect><text x="74" y="44">+</text></g><path d="M88 40a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M40 60h20"></path><g><path d="M60 60h28"></path></g><path d="M88 60h20"></path><path d="M40 60a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M60 80h0"></path><path d="M88 80h0"></path><rect x="60" y="69" width="28" height="22" rx="10" ry="10"></rect><text x="74" y="84">-</text></g><path d="M88 80a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g><g><path d="M108 60h0"></path><path d="M396 60h0"></path><path d="M108 60h20"></path><g><path d="M128 60h0"></path><path d="M376 60h0"></path><path d="M128 60h10"></path><g><path d="M138 60h0"></path><path d="M218 60h0"></path><path d="M138 60h10"></path><g><path d="M148 60h0"></path><path d="M208 60h0"></path><rect x="148" y="49" width="60" height="22"></rect><text x="178" y="64">digit</text></g><path d="M208 60h10"></path><path d="M148 60a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M148 80h60"></path></g><path d="M208 80a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M218 60h10"></path><path d="M228 60h10"></path><g><path d="M238 60h0"></path><path d="M266 60h0"></path><rect x="238" y="49" width="28" height="22" rx="10" ry="10"></rect><text x="252" y="64">.</text></g><path d="M266 60h10"></path><path d="M276 60h10"></path><g><path d="M286 60h0"></path><path d="M366 60h0"></path><path d="M286 60h10"></path><g><path d="M296 60h0"></path><path d="M356 60h0"></path><rect x="296" y="49" width="60" height="22"></rect><text x="326" y="64">digit</text></g><path d="M356 60h10"></path><path d="M296 60a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M296 80h60"></path></g><path d="M356 80a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M366 60h10"></path></g><path d="M376 60h20"></path><path d="M108 60a10 10 0 0 1 10 10v19a10 10 0 0 0 10 10"></path><g><path d="M128 99h84"></path><path d="M292 99h84"></path><path d="M212 99h10"></path><g><path d="M222 99h0"></path><path d="M282 99h0"></path><rect x="222" y="88" width="60" height="22"></rect><text x="252" y="103">digit</text></g><path d="M282 99h10"></path><path d="M222 99a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M222 119h60"></path></g><path d="M282 119a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M376 99a10 10 0 0 0 10 -10v-19a10 10 0 0 1 10 -10"></path><path d="M108 60a10 10 0 0 1 10 10v58a10 10 0 0 0 10 10"></path><g><path d="M128 138h50"></path><path d="M326 138h50"></path><path d="M178 138h10"></path><g><path d="M188 138h0"></path><path d="M216 138h0"></path><rect x="188" y="127" width="28" height="22" rx="10" ry="10"></rect><text x="202" y="142">.</text></g><path d="M216 138h10"></path><path d="M226 138h10"></path><g><path d="M236 138h0"></path><path d="M316 138h0"></path><path d="M236 138h10"></path><g><path d="M246 138h0"></path><path d="M306 138h0"></path><rect x="246" y="127" width="60" height="22"></rect><text x="276" y="142">digit</text></g><path d="M306 138h10"></path><path d="M246 138a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M246 158h60"></path></g><path d="M306 158a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M316 138h10"></path></g><path d="M376 138a10 10 0 0 0 10 -10v-58a10 10 0 0 1 10 -10"></path></g><g><path d="M396 60h0"></path><path d="M672 60h0"></path><path d="M396 60h20"></path><g><path d="M416 60h236"></path></g><path d="M652 60h20"></path><path d="M396 60a10 10 0 0 1 10 10v28a10 10 0 0 0 10 10"></path><g><path d="M416 108h0"></path><path d="M652 108h0"></path><g><path d="M416 108h0"></path><path d="M484 108h0"></path><path d="M416 108h20"></path><g><path d="M436 108h0"></path><path d="M464 108h0"></path><rect x="436" y="97" width="28" height="22" rx="10" ry="10"></rect><text x="450" y="112">e</text></g><path d="M464 108h20"></path><path d="M416 108a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M436 138h0"></path><path d="M464 138h0"></path><rect x="436" y="127" width="28" height="22" rx="10" ry="10"></rect><text x="450" y="142">E</text></g><path d="M464 138a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g><path d="M484 108h0"></path><path d="M552 108h0"></path><path d="M484 108a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M504 88h0"></path><path d="M532 88h0"></path><rect x="504" y="77" width="28" height="22" rx="10" ry="10"></rect><text x="518" y="92">+</text></g><path d="M532 88a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M484 108h20"></path><g><path d="M504 108h28"></path></g><path d="M532 108h20"></path><path d="M484 108a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g><path d="M504 128h0"></path><path d="M532 128h0"></path><rect x="504" y="117" width="28" height="22" rx="10" ry="10"></rect><text x="518" y="132">-</text></g><path d="M532 128a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path></g><path d="M552 108h10"></path><g><path d="M562 108h0"></path><path d="M642 108h0"></path><path d="M562 108h10"></path><g><path d="M572 108h0"></path><path d="M632 108h0"></path><rect x="572" y="97" width="60" height="22"></rect><text x="602" y="112">digit</text></g><path d="M632 108h10"></path><path d="M572 108a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M572 128h60"></path></g><path d="M632 128a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M642 108h10"></path></g><path d="M652 108a10 10 0 0 0 10 -10v-28a10 10 0 0 1 10 -10"></path></g><path d="M 672 60 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 496
simon@8830 497 <dt id="〈dimension〉-diagram">〈dimension〉</dt>
simon@8830 498 <dd><svg class="railroad-diagram" width="281" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M134 31h0"></path><rect x="50" y="20" width="84" height="22"></rect><text x="92" y="35">〈number〉</text></g><path d="M134 31h10"></path><path d="M144 31h10"></path><g><path d="M154 31h0"></path><path d="M230 31h0"></path><rect x="154" y="20" width="76" height="22"></rect><text x="192" y="35">〈ident〉</text></g><path d="M230 31h10"></path><path d="M 240 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 499
simon@8830 500 <dt id="〈percentage〉-diagram">〈percentage〉</dt>
simon@8830 501 <dd><svg class="railroad-diagram" width="233" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M134 31h0"></path><rect x="50" y="20" width="84" height="22"></rect><text x="92" y="35">〈number〉</text></g><path d="M134 31h10"></path><path d="M144 31h10"></path><g><path d="M154 31h0"></path><path d="M182 31h0"></path><rect x="154" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="168" y="35">%</text></g><path d="M182 31h10"></path><path d="M 192 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8830 502
simon@8830 503 <dt id="〈unicode-range〉-diagram">〈unicode-range〉</dt>
simon@8996 504 <dd><svg class="railroad-diagram" width="589" height="132"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 41h0"></path><path d="M108 41h0"></path><path d="M40 41h20"></path><g><path d="M60 41h0"></path><path d="M88 41h0"></path><rect x="60" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="74" y="45">U</text></g><path d="M88 41h20"></path><path d="M40 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M60 71h0"></path><path d="M88 71h0"></path><rect x="60" y="60" width="28" height="22" rx="10" ry="10"></rect><text x="74" y="75">u</text></g><path d="M88 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M108 41h10"></path><g><path d="M118 41h0"></path><path d="M146 41h0"></path><rect x="118" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="132" y="45">+</text></g><path d="M146 41h10"></path><g><path d="M156 41h0"></path><path d="M328 41h0"></path><path d="M156 41h10"></path><g><path d="M166 41h0"></path><path d="M318 41h0"></path><path d="M166 41h10"></path><g><path d="M176 41h0"></path><path d="M308 41h0"></path><path d="M176 41h20"></path><g><path d="M196 41h0"></path><path d="M288 41h0"></path><rect x="196" y="30" width="92" height="22"></rect><text x="242" y="45">hex digit</text></g><path d="M288 41h20"></path><path d="M176 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M196 71h32"></path><path d="M256 71h32"></path><rect x="228" y="60" width="28" height="22" rx="10" ry="10"></rect><text x="242" y="75">?</text></g><path d="M288 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M308 41h10"></path><path d="M176 41a10 10 0 0 0 -10 10v40a10 10 0 0 0 10 10"></path><g><path d="M176 101h29.5"></path><path d="M278.5 101h29.5"></path><text x="242" y="106" class="comment">1-6 times</text></g><path d="M308 101a10 10 0 0 0 10 -10v-40a10 10 0 0 0 -10 -10"></path></g><path d="M318 41h10"></path></g><g><path d="M328 41h0"></path><path d="M548 41h0"></path><path d="M328 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M348 21h180"></path></g><path d="M528 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M328 41h20"></path><g><path d="M348 41h0"></path><path d="M528 41h0"></path><path d="M348 41h10"></path><g><path d="M358 41h0"></path><path d="M386 41h0"></path><rect x="358" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="372" y="45">-</text></g><path d="M386 41h10"></path><path d="M396 41h10"></path><g><path d="M406 41h0"></path><path d="M518 41h0"></path><path d="M406 41h10"></path><g><path d="M416 41h0"></path><path d="M508 41h0"></path><rect x="416" y="30" width="92" height="22"></rect><text x="462" y="45">hex digit</text></g><path d="M508 41h10"></path><path d="M416 41a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path><g><path d="M416 71h9.5"></path><path d="M498.5 71h9.5"></path><text x="462" y="76" class="comment">1-6 times</text></g><path d="M508 71a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path></g><path d="M518 41h10"></path></g><path d="M528 41h20"></path></g><path d="M 548 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 505
simon@8830 506 <dt id="〈include-match〉-diagram">〈include-match〉</dt>
simon@7476 507 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">~=</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 508
simon@8830 509 <dt id="〈dash-match〉-diagram">〈dash-match〉</dt>
simon@7476 510 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">|=</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 511
simon@8830 512 <dt id="〈prefix-match〉-diagram">〈prefix-match〉</dt>
simon@7476 513 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">^=</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 514
simon@8830 515 <dt id="〈suffix-match〉-diagram">〈suffix-match〉</dt>
simon@7476 516 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">$=</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7476 517
simon@8830 518 <dt id="〈substring-match〉-diagram">〈substring-match〉</dt>
simon@7476 519 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">*=</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 520
simon@8830 521 <dt id="〈column〉-diagram">〈column〉</dt>
jackalmage@7895 522 <dd><svg class="railroad-diagram" width="137" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M86 31h0"></path><rect x="50" y="20" width="36" height="22" rx="10" ry="10"></rect><text x="68" y="35">||</text></g><path d="M86 31h10"></path><path d="M 96 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
jackalmage@7895 523
simon@8830 524 <dt id="〈cdo〉-diagram">〈CDO〉</dt>
simon@7048 525 <dd><svg class="railroad-diagram" width="153" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M102 31h0"></path><rect x="50" y="20" width="52" height="22" rx="10" ry="10"></rect><text x="76" y="35">&lt;!--</text></g><path d="M102 31h10"></path><path d="M 112 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 526
simon@8830 527 <dt id="〈cdc〉-diagram">〈CDC〉</dt>
simon@7048 528 <dd><svg class="railroad-diagram" width="145" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M94 31h0"></path><rect x="50" y="20" width="44" height="22" rx="10" ry="10"></rect><text x="72" y="35">--&gt;</text></g><path d="M94 31h10"></path><path d="M 104 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7048 529
jackalmage@6819 530 </dl>
jackalmage@6819 531
jackalmage@7224 532 <h3>
jackalmage@7224 533 Definitions</h3>
dbaron@280 534
jackalmage@8572 535 This section defines several terms used during the tokenization phase.
dbaron@280 536
jackalmage@5473 537 <dl>
simon@8830 538 <dt><dfn>code point</dfn>
jackalmage@7490 539 <dd>
simon@8830 540 A <a href="http://unicode.org/glossary/#code_point">Unicode code point</a>.
simon@8830 541 Any value in the Unicode codespace; that is, the range of integers from 0 to (hexadecimal) 10FFFF.
simon@8830 542
simon@8830 543 <dt><dfn>next input code point</dfn>
jackalmage@7490 544 <dd>
simon@8830 545 The first <a>code point</a> in the input stream that has not yet been consumed.
simon@8830 546
simon@8830 547 <dt><dfn>current input code point</dfn>
jackalmage@7565 548 <dd>
simon@8830 549 The last <a>code point</a> to have been consumed.
simon@8830 550
simon@8830 551 <dt><dfn>reconsume the current input code point</dfn>
jackalmage@7490 552 <dd>
simon@8830 553 Push the <a>current input code point</a> back onto the front of the input stream,
simon@8830 554 so that the next time you are instructed to consume the <a>next input code point</a>,
simon@8830 555 it will instead reconsume the <a>current input code point</a>.
simon@8830 556
simon@8830 557 <dt><dfn>EOF code point</dfn>
simon@8830 558 <dd>
simon@8830 559 A conceptual <a>code point</a> representing the end of the input stream.
simon@7492 560 Whenever the input stream is empty,
simon@8830 561 the <a>next input code point</a> is always an EOF code point.
jackalmage@7490 562
jackalmage@5473 563 <dt><dfn>digit</dfn>
jackalmage@5473 564 <dd>
simon@8830 565 A <a>code point</a> between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
dbaron@280 566
jackalmage@5473 567 <dt><dfn>hex digit</dfn>
jackalmage@5473 568 <dd>
jackalmage@8572 569 A <a>digit</a>,
simon@8830 570 or a <a>code point</a> between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
simon@8830 571 or a <a>code point</a> between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
dbaron@280 572
jackalmage@5473 573 <dt><dfn>uppercase letter</dfn>
jackalmage@5473 574 <dd>
simon@8830 575 A <a>code point</a> between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
dbaron@280 576
jackalmage@5473 577 <dt><dfn>lowercase letter</dfn>
jackalmage@5473 578 <dd>
simon@8830 579 A <a>code point</a> between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
dbaron@280 580
jackalmage@5473 581 <dt><dfn>letter</dfn>
jackalmage@5473 582 <dd>
jackalmage@8572 583 An <a>uppercase letter</a>
jackalmage@8572 584 or a <a>lowercase letter</a>.
dbaron@280 585
simon@8830 586 <dt><dfn>non-ASCII code point</dfn>
jackalmage@5473 587 <dd>
simon@8830 588 A <a>code point</a> with a value equal to or greater than U+0080 &lt;control>.
simon@8830 589
simon@8830 590 <dt><dfn>name-start code point</dfn>
jackalmage@5473 591 <dd>
jackalmage@8572 592 A <a>letter</a>,
simon@8830 593 a <a>non-ASCII code point</a>,
jackalmage@5473 594 or U+005F LOW LINE (_).
dbaron@280 595
simon@8830 596 <dt><dfn>name code point</dfn>
jackalmage@5473 597 <dd>
simon@8830 598 A <a>name-start code point</a>,
jackalmage@8572 599 A <a>digit</a>,
jackalmage@5473 600 or U+002D HYPHEN-MINUS (-).
dbaron@280 601
simon@8830 602 <dt><dfn>non-printable code point</dfn>
jackalmage@5473 603 <dd>
simon@8830 604 A <a>code point</a> between U+0000 NULL and U+0008 BACKSPACE,
jackalmage@8273 605 or U+000B LINE TABULATION,
simon@8830 606 or a <a>code point</a> between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE,
jackalmage@8273 607 or U+007F DELETE.
dbaron@270 608
jackalmage@5473 609 <dt><dfn>newline</dfn>
jackalmage@5473 610 <dd>
jackalmage@8190 611 U+000A LINE FEED.
jackalmage@5473 612 <span class='note'>
jackalmage@8190 613 Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
jackalmage@8273 614 as they are converted to U+000A LINE FEED during <a href="#preprocessing-the-input-stream">preprocessing</a>.
jackalmage@5473 615 </span>
dbaron@279 616
jackalmage@5473 617 <dt><dfn>whitespace</dfn>
jackalmage@8572 618 <dd>A <a>newline</a>, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
dbaron@270 619
simon@8831 620 <dt><dfn>surrogate code point</dfn>
simon@8831 621 <dd>
simon@8831 622 A <a>code point</a> between U+D800 and U+DFFF inclusive.
simon@8831 623
simon@8830 624 <dt><dfn>maximum allowed code point</dfn>
simon@8830 625 <dd>The greatest <a>code point</a> defined by Unicode. This is currently U+10FFFF.
jackalmage@5548 626
jackalmage@5473 627 </dl>
dbaron@270 628
jackalmage@7224 629 <h3>
jackalmage@8308 630 Tokenizer Algorithms</h3>
jackalmage@8308 631
simon@8830 632 The algorithms defined in this section transform a stream of <a>code points</a> into a stream of tokens.
jackalmage@7224 633
jackalmage@5473 634 <h4>
jackalmage@8308 635 <dfn>Consume a token</dfn></h4>
jackalmage@8308 636
simon@8830 637 This section describes how to <a>consume a token</a> from a stream of <a>code points</a>.
jackalmage@8572 638 It will return a single token of any type.
jackalmage@8572 639
simon@8830 640 Consume the <a>next input code point</a>.
dbaron@279 641
jackalmage@5473 642 <dl>
jackalmage@8572 643 <dt><a>whitespace</a>
jackalmage@5473 644 <dd>
jackalmage@8572 645 Consume as much <a>whitespace</a> as possible.
jackalmage@8819 646 Return a <<<whitespace>>>.
dbaron@270 647
jackalmage@5473 648 <dt>U+0022 QUOTATION MARK (")
jackalmage@5473 649 <dd>
simon@8830 650 <a>Consume a string token</a> with the ending <a>code point</a> U+0022 QUOTATION MARK (")
jackalmage@8308 651 and return it.
dbaron@275 652
jackalmage@5473 653 <dt>U+0023 NUMBER SIGN (#)
jackalmage@5473 654 <dd>
simon@8830 655 If the <a>next input code point</a> is a <a>name code point</a>
simon@8830 656 or the <a title="next input code point">next two input code points</a>
jackalmage@8572 657 <a>are a valid escape</a>,
jackalmage@8318 658 then:
jackalmage@8318 659
jackalmage@8318 660 <ol>
jackalmage@8318 661 <li>
jackalmage@8819 662 Create a <<<hash>>>.
jackalmage@8318 663
jackalmage@8318 664 <li>
simon@8830 665 If the <a title="next input code point">next 3 input code points</a> <a>would start an identifier</a>,
jackalmage@8819 666 set the <<<hash>>>’s type flag to "id".
jackalmage@8318 667
jackalmage@8318 668 <li>
jackalmage@8572 669 <a>Consume a name</a>,
jackalmage@8819 670 and set the <<<hash>>>’s value to the returned string.
jackalmage@8318 671
jackalmage@8318 672 <li>
jackalmage@8819 673 Return the <<<hash>>>.
jackalmage@8318 674 </ol>
dbaron@275 675
jackalmage@8572 676 Otherwise,
jackalmage@8819 677 return a <<<delim>>>
simon@8830 678 with its value set to the <a>current input code point</a>.
jackalmage@8065 679
jackalmage@7370 680 <dt>U+0024 DOLLAR SIGN ($)
jackalmage@7370 681 <dd>
simon@8830 682 If the <a>next input code point</a> is
jackalmage@7370 683 U+003D EQUALS SIGN (=),
jackalmage@7370 684 consume it
jackalmage@8819 685 and return a <<<suffix-match>>>.
jackalmage@7370 686
jackalmage@8572 687 Otherwise,
jackalmage@8819 688 emit a <<<delim>>>
simon@8830 689 with its value set to the <a>current input code point</a>.
jackalmage@7370 690
jackalmage@5547 691 <dt>U+0027 APOSTROPHE (&apos;)
jackalmage@5473 692 <dd>
simon@8830 693 <a>Consume a string token</a> with the ending <a>code point</a> U+0027 APOSTROPHE (&apos;)
jackalmage@8308 694 and return it.
dbaron@270 695
jackalmage@5473 696 <dt>U+0028 LEFT PARENTHESIS (()
jackalmage@5473 697 <dd>
jackalmage@8819 698 Return a <<<(>>>.
dbaron@270 699
jackalmage@5473 700 <dt>U+0029 RIGHT PARENTHESIS ())
jackalmage@5473 701 <dd>
jackalmage@8819 702 Return a <<<)>>>.
dbaron@270 703
jackalmage@7370 704 <dt>U+002A ASTERISK (*)
jackalmage@7370 705 <dd>
simon@8830 706 If the <a>next input code point</a> is
jackalmage@7370 707 U+003D EQUALS SIGN (=),
jackalmage@7370 708 consume it
jackalmage@8819 709 and return a <<<substring-match>>>.
jackalmage@7370 710
jackalmage@8572 711 Otherwise,
jackalmage@8819 712 return a <<<delim>>>
simon@8830 713 with its value set to the <a>current input code point</a>.
jackalmage@7370 714
jackalmage@5473 715 <dt>U+002B PLUS SIGN (+)
jackalmage@5473 716 <dd>
jackalmage@8572 717 If the input stream <a>starts with a number</a>,
simon@8830 718 <a>reconsume the current input code point</a>,
jackalmage@8572 719 <a>consume a numeric token</a>
jackalmage@8308 720 and return it.
dbaron@270 721
jackalmage@8572 722 Otherwise,
jackalmage@8819 723 return a <<<delim>>>
simon@8830 724 with its value set to the <a>current input code point</a>.
dbaron@280 725
jackalmage@7445 726 <dt>U+002C COMMA (,)
jackalmage@7445 727 <dd>
jackalmage@8819 728 Return a <<<comma>>>.
jackalmage@7445 729
jackalmage@5473 730 <dt>U+002D HYPHEN-MINUS (-)
jackalmage@5473 731 <dd>
jackalmage@8572 732 If the input stream <a>starts with a number</a>,
simon@8830 733 <a>reconsume the current input code point</a>,
jackalmage@8572 734 <a>consume a numeric token</a>,
jackalmage@8308 735 and return it.
dbaron@270 736
jackalmage@8572 737 Otherwise,
jackalmage@8572 738 if the input stream <a>starts with an identifier</a>,
simon@8830 739 <a>reconsume the current input code point</a>,
jackalmage@8572 740 <a>consume an ident-like token</a>,
jackalmage@8572 741 and return it.
jackalmage@8572 742
jackalmage@8572 743 Otherwise,
simon@8830 744 if the <a title="next input code point">next 2 input code points</a> are
jackalmage@8572 745 U+002D HYPHEN-MINUS
jackalmage@8572 746 U+003E GREATER-THAN SIGN
jackalmage@8572 747 (->),
jackalmage@8572 748 consume them
jackalmage@8819 749 and return a <<<CDC>>>.
jackalmage@8572 750
jackalmage@8572 751 Otherwise,
jackalmage@8819 752 return a <<<delim>>>
simon@8830 753 with its value set to the <a>current input code point</a>.
jackalmage@7563 754
jackalmage@7563 755 <dt>U+002E FULL STOP (.)
jackalmage@7563 756 <dd>
jackalmage@8572 757 If the input stream <a>starts with a number</a>,
simon@8830 758 <a>reconsume the current input code point</a>,
jackalmage@8572 759 <a>consume a numeric token</a>,
jackalmage@8308 760 and return it.
jackalmage@7563 761
jackalmage@8572 762 Otherwise,
jackalmage@8819 763 return a <<<delim>>>
simon@8830 764 with its value set to the <a>current input code point</a>.
dbaron@282 765
jackalmage@5473 766 <dt>U+002F SOLIDUS (/)
jackalmage@5473 767 <dd>
simon@8830 768 If the <a>next input code point</a> is U+002A ASTERISK (*),
jackalmage@5473 769 consume it
simon@8830 770 and all following <a>code points</a> up to and including
jackalmage@8308 771 the first U+002A ASTERISK (*) followed by a U+002F SOLIDUS (/),
simon@8830 772 or up to an EOF code point.
jackalmage@8572 773 Then <a>consume a token</a>
jackalmage@8308 774 and return it.
dbaron@279 775
jackalmage@8572 776 Otherwise,
jackalmage@8819 777 return a <<<delim>>>
simon@8830 778 with its value set to the <a>current input code point</a>.
dbaron@279 779
jackalmage@5473 780 <dt>U+003A COLON (:)
jackalmage@5473 781 <dd>
jackalmage@8819 782 Return a <<<colon>>>.
dbaron@279 783
jackalmage@5473 784 <dt>U+003B SEMICOLON (;)
jackalmage@5473 785 <dd>
jackalmage@8819 786 Return a <<<semicolon>>>.
dbaron@279 787
jackalmage@5473 788 <dt>U+003C LESS-THAN SIGN (&lt;)
jackalmage@5473 789 <dd>
simon@8830 790 If the <a title="next input code point">next 3 input code points</a> are
jackalmage@5473 791 U+0021 EXCLAMATION MARK
jackalmage@5473 792 U+002D HYPHEN-MINUS
jackalmage@5473 793 U+002D HYPHEN-MINUS
jackalmage@5473 794 (!--),
jackalmage@5473 795 consume them
jackalmage@8819 796 and return a <<<CDO>>>.
dbaron@300 797
jackalmage@8572 798 Otherwise,
jackalmage@8819 799 return a <<<delim>>>
simon@8830 800 with its value set to the <a>current input code point</a>.
dbaron@270 801
jackalmage@5473 802 <dt>U+0040 COMMERCIAL AT (@)
jackalmage@5473 803 <dd>
simon@8830 804 If the <a title="next input code point">next 3 input code points</a>
jackalmage@8572 805 <a>would start an identifier</a>,
jackalmage@8572 806 <a>consume a name</a>,
jackalmage@8819 807 create an <<<at-keyword>>> with its value set to the returned value,
jackalmage@8308 808 and return it.
dbaron@270 809
jackalmage@8572 810 Otherwise,
jackalmage@8819 811 return a <<<delim>>>
simon@8830 812 with its value set to the <a>current input code point</a>.
jackalmage@8063 813
jackalmage@5473 814 <dt>U+005B LEFT SQUARE BRACKET ([)
jackalmage@5473 815 <dd>
jackalmage@8819 816 Return a <<<[>>>.
dbaron@276 817
jackalmage@5473 818 <dt>U+005C REVERSE SOLIDUS (\)
jackalmage@5473 819 <dd>
jackalmage@8572 820 If the input stream <a>starts with a valid escape</a>,
simon@8830 821 <a>reconsume the current input code point</a>,
jackalmage@8572 822 <a>consume an ident-like token</a>,
jackalmage@8308 823 and return it.
dbaron@270 824
jackalmage@8572 825 Otherwise,
jackalmage@8572 826 this is a <a>parse error</a>.
jackalmage@8819 827 Return a <<<delim>>>
simon@8830 828 with its value set to the <a>current input code point</a>.
dbaron@270 829
jackalmage@5473 830 <dt>U+005D RIGHT SQUARE BRACKET (])
jackalmage@5473 831 <dd>
jackalmage@8819 832 Return a <<<]>>>.
dbaron@270 833
jackalmage@7370 834 <dt>U+005E CIRCUMFLEX ACCENT (^)
jackalmage@7370 835 <dd>
simon@8830 836 If the <a>next input code point</a> is
jackalmage@7370 837 U+003D EQUALS SIGN (=),
jackalmage@7370 838 consume it
jackalmage@8819 839 and return a <<<prefix-match>>>.
jackalmage@7370 840
jackalmage@8572 841 Otherwise,
jackalmage@8819 842 return a <<<delim>>>
simon@8830 843 with its value set to the <a>current input code point</a>.
jackalmage@7370 844
jackalmage@5473 845 <dt>U+007B LEFT CURLY BRACKET ({)
jackalmage@5473 846 <dd>
jackalmage@8819 847 Return a <<<{>>>.
dbaron@270 848
jackalmage@5473 849 <dt>U+007D RIGHT CURLY BRACKET (})
jackalmage@5473 850 <dd>
jackalmage@8819 851 Return a <<<}>>>.
dbaron@270 852
jackalmage@8572 853 <dt><a>digit</a>
jackalmage@5473 854 <dd>
jackalmage@8572 855 <a>Consume a numeric token</a>,
jackalmage@8308 856 and return it.
dbaron@270 857
jackalmage@5473 858 <dt>U+0055 LATIN CAPITAL LETTER U (U)
jackalmage@5473 859 <dt>U+0075 LATIN SMALL LETTER U (u)
jackalmage@5473 860 <dd>
simon@8830 861 If the <a title="next input code point">next 2 input code points</a> are
jackalmage@5473 862 U+002B PLUS SIGN (+)
jackalmage@8572 863 followed by a <a>hex digit</a>
jackalmage@7340 864 or U+003F QUESTION MARK (?),
simon@8830 865 consume the <a>next input code point</a>.
jackalmage@5473 866 <span class='note'>Note: don't consume both of them.</span>
jackalmage@8572 867 <a>Consume a unicode-range token</a>
jackalmage@8308 868 and return it.
jackalmage@8308 869
jackalmage@8572 870 Otherwise,
simon@8830 871 <a>reconsume the current input code point</a>,
jackalmage@8572 872 <a>consume an ident-like token</a>,
jackalmage@8572 873 and return it.
jackalmage@8572 874
simon@8830 875 <dt><a>name-start code point</a>
jackalmage@5473 876 <dd>
simon@8830 877 <a>Reconsume the current input code point</a>,
jackalmage@8572 878 <a>consume an ident-like token</a>,
jackalmage@8308 879 and return it.
dbaron@270 880
jackalmage@7370 881 <dt>U+007C VERTICAL LINE (|)
jackalmage@7370 882 <dd>
simon@8830 883 If the <a>next input code point</a> is
jackalmage@7370 884 U+003D EQUALS SIGN (=),
jackalmage@7370 885 consume it
jackalmage@8819 886 and return a <<<dash-match>>>.
jackalmage@7370 887
jackalmage@8572 888 Otherwise,
simon@8830 889 if the <a>next input code point</a> is
jackalmage@8572 890 U+0073 VERTICAL LINE (|),
jackalmage@8572 891 consume it
jackalmage@8819 892 and return a <<<column>>>.
jackalmage@8572 893
jackalmage@8572 894 Otherwise,
jackalmage@8819 895 return a <<<delim>>>
simon@8830 896 with its value set to the <a>current input code point</a>.
jackalmage@7370 897
jackalmage@7370 898 <dt>U+007E TILDE (~)
jackalmage@7370 899 <dd>
simon@8830 900 If the <a>next input code point</a> is
jackalmage@7370 901 U+003D EQUALS SIGN (=),
jackalmage@7370 902 consume it
jackalmage@8819 903 and return an <<<include-match>>>.
jackalmage@7370 904
jackalmage@8572 905 Otherwise,
jackalmage@8819 906 return a <<<delim>>>
simon@8830 907 with its value set to the <a>current input code point</a>.
jackalmage@7370 908
jackalmage@5473 909 <dt>EOF
jackalmage@5473 910 <dd>
jackalmage@8819 911 Return an <<<EOF>>> token.
dbaron@270 912
jackalmage@5473 913 <dt>anything else
jackalmage@5473 914 <dd>
jackalmage@8819 915 Return a <<<delim>>>
simon@8830 916 with its value set to the <a>current input code point</a>.
jackalmage@5473 917 </dl>
dbaron@270 918
jackalmage@8308 919
jackalmage@8308 920
jackalmage@8308 921
jackalmage@5473 922 <h4>
jackalmage@8308 923 <dfn>Consume a numeric token</dfn></h4>
dbaron@270 924
simon@8830 925 This section describes how to <a>consume a numeric token</a> from a stream of <a>code points</a>.
jackalmage@8819 926 It returns either a <<<number>>>, <<<percentage>>>, or <<<dimension>>>.
jackalmage@8572 927
jackalmage@8572 928 <a>Consume a number</a>.
jackalmage@8572 929
simon@8830 930 If the <a title="next input code point">next 3 input code points</a> <a>would start an identifier</a>,
jackalmage@8572 931 then:
jackalmage@8572 932
jackalmage@8572 933 <ol>
jackalmage@8819 934 <li>Create a <<<dimension>>> with the same representation, value, and type flag as the returned number,
jackalmage@8572 935 and a unit set initially to the empty string.
jackalmage@8572 936
jackalmage@8572 937 <li><a>Consume a name</a>.
jackalmage@8819 938 Set the <<<dimension>>>’s unit to the returned value.
jackalmage@8819 939
jackalmage@8819 940 <li>Return the <<<dimension>>>.
jackalmage@8572 941 </ol>
jackalmage@8572 942
jackalmage@8572 943 Otherwise,
simon@8830 944 if the <a>next input code point</a> is U+0025 PERCENTAGE SIGN (%),
jackalmage@8572 945 consume it.
jackalmage@8819 946 Create a <<<percentage>>> with the same representation and value as the returned number,
jackalmage@8572 947 and return it.
jackalmage@8572 948
jackalmage@8572 949 Otherwise,
jackalmage@8819 950 create a <<<number>>> with the same representation, value, and type flag as the returned number,
jackalmage@8572 951 and return it.
jackalmage@8308 952
jackalmage@8308 953
jackalmage@8308 954 <h4>
jackalmage@8319 955 <dfn>Consume an ident-like token</dfn></h4>
jackalmage@8319 956
simon@8830 957 This section describes how to <a>consume an ident-like token</a> from a stream of <a>code points</a>.
jackalmage@8819 958 It returns an <<<ident>>>, <<<function>>>, <<<url>>>, or <<<bad-url>>>.
jackalmage@8572 959
jackalmage@8572 960 <a>Consume a name</a>.
jackalmage@8572 961
jackalmage@8572 962 If the returned string's value is an <a>ASCII case-insensitive</a> match for "url",
simon@8830 963 and the <a>next input code point</a> is U+0028 LEFT PARENTHESIS ((),
jackalmage@8572 964 consume it.
jackalmage@8572 965 <a>Consume a url token</a>,
jackalmage@8572 966 and return it.
jackalmage@8572 967
jackalmage@8572 968 Otherwise,
simon@8830 969 if the <a>next input code point</a> is U+0028 LEFT PARENTHESIS ((),
jackalmage@8572 970 consume it.
jackalmage@8819 971 Create a <<<function>>> token
jackalmage@8572 972 with its value set to the returned string
jackalmage@8572 973 and return it.
jackalmage@8572 974
jackalmage@8572 975 Otherwise,
jackalmage@8819 976 create an <<<ident>>> token
jackalmage@8572 977 with its value set to the returned string
jackalmage@8572 978 and return it.
jackalmage@8319 979
jackalmage@8319 980
jackalmage@8319 981 <h4>
jackalmage@8308 982 <dfn>Consume a string token</dfn></h4>
jackalmage@8308 983
simon@8830 984 This section describes how to <a>consume a string token</a> from a stream of <a>code points</a>.
jackalmage@8819 985 It returns either a <<<string>>> or <<<bad-string>>>.
jackalmage@8572 986
simon@8830 987 This algorithm must be called with an <var>ending code point</var>,
simon@8830 988 which denotes the <a>code point</a> that ends the string.
jackalmage@8572 989
jackalmage@8819 990 Initially create a <<<string>>> with its value set to the empty string.
jackalmage@8572 991
simon@8830 992 Repeatedly consume the <a>next input code point</a> from the stream:
dbaron@270 993
jackalmage@5473 994 <dl>
simon@8830 995 <dt><var>ending code point</var>
jackalmage@7514 996 <dt>EOF
jackalmage@5473 997 <dd>
jackalmage@8819 998 Return the <<<string>>>.
dbaron@270 999
jackalmage@8572 1000 <dt><a>newline</a>
jackalmage@5473 1001 <dd>
jackalmage@8572 1002 This is a <a>parse error</a>.
simon@8830 1003 <a>Reconsume the current input code point</a>,
jackalmage@8819 1004 create a <<<bad-string>>>, and return it.
dbaron@270 1005
jackalmage@5473 1006 <dt>U+005C REVERSE SOLIDUS (\)
jackalmage@5473 1007 <dd>
simon@8830 1008 If the <a>next input code point</a> is EOF,
simon@8362 1009 do nothing.
dbaron@347 1010
jackalmage@8572 1011 Otherwise,
simon@8830 1012 if the <a>next input code point</a> is a newline,
jackalmage@8572 1013 consume it.
jackalmage@8572 1014
jackalmage@8572 1015 Otherwise,
jackalmage@8572 1016 if the stream <a>starts with a valid escape</a>,
simon@8830 1017 <a>consume an escaped code point</a>
simon@8830 1018 and append the returned <a>code point</a> to the <<<string>>>’s value.
dbaron@270 1019
jackalmage@5473 1020 <dt>anything else
jackalmage@5473 1021 <dd>
simon@8830 1022 Append the <a>current input code point</a> to the <<<string>>>’s value.
jackalmage@5473 1023 </dl>
dbaron@270 1024
jackalmage@8308 1025
jackalmage@5473 1026 <h4>
jackalmage@8447 1027 <dfn>Consume a url token</dfn></h4>
dbaron@270 1028
simon@8830 1029 This section describes how to <a>consume a url token</a> from a stream of <a>code points</a>.
jackalmage@8819 1030 It returns either a <<<url>>> or a <<<bad-url>>>.
jackalmage@8572 1031
jackalmage@8572 1032 Note: This algorithm assumes that the initial "url(" has already been consumed.
jackalmage@8572 1033
jackalmage@8572 1034 Execute the following steps in order:
jackalmage@8308 1035
jackalmage@8308 1036 <ol>
jackalmage@8308 1037 <li>
jackalmage@8819 1038 Initially create a <<<url>>> with its value set to the empty string.
jackalmage@8308 1039
jackalmage@8308 1040 <li>
jackalmage@8572 1041 Consume as much <a>whitespace</a> as possible.
jackalmage@8308 1042
jackalmage@8308 1043 <li>
simon@8830 1044 If the <a>next input code point</a> is EOF,
jackalmage@8819 1045 return the <<<url>>>.
jackalmage@8308 1046
jackalmage@8308 1047 <li>
simon@8830 1048 If the <a>next input code point</a> is a U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE (&apos;),
jackalmage@8308 1049 then:
jackalmage@8308 1050
jackalmage@8308 1051 <ol>
jackalmage@8308 1052 <li>
simon@8830 1053 <a>Consume a string token</a> with the <a>current input code point</a> as the ending code point.
jackalmage@8308 1054
jackalmage@8308 1055 <li>
jackalmage@8819 1056 If a <<<bad-string>>> was returned,
jackalmage@8572 1057 <a>consume the remnants of a bad url</a>,
jackalmage@8819 1058 create a <<<bad-url>>>,
jackalmage@8308 1059 and return it.
jackalmage@8308 1060
jackalmage@8308 1061 <li>
jackalmage@8819 1062 Set the <<<url>>>’s value to the returned <<<string>>>’s value.
jackalmage@8308 1063
jackalmage@8308 1064 <li>
jackalmage@8572 1065 Consume as much <a>whitespace</a> as possible.
jackalmage@8308 1066
jackalmage@8308 1067 <li>
simon@8830 1068 If the <a>next input code point</a> is U+0029 RIGHT PARENTHESIS ()) or EOF,
jackalmage@8819 1069 consume it and return the <<<url>>>;
jackalmage@8308 1070 otherwise,
jackalmage@8572 1071 <a>consume the remnants of a bad url</a>,
jackalmage@8819 1072 create a <<<bad-url>>>,
jackalmage@8308 1073 and return it.
jackalmage@8308 1074 </ol>
jackalmage@8308 1075
jackalmage@8308 1076 <li>
simon@8830 1077 Repeatedly consume the <a>next input code point</a> from the stream:
jackalmage@8308 1078
jackalmage@8308 1079 <dl>
jackalmage@8308 1080 <dt>U+0029 RIGHT PARENTHESIS ())
jackalmage@8308 1081 <dt>EOF
jackalmage@8308 1082 <dd>
jackalmage@8819 1083 Return the <<<url>>>.
jackalmage@8308 1084
jackalmage@8572 1085 <dt><a>whitespace</a>
jackalmage@8308 1086 <dd>
jackalmage@8572 1087 Consume as much <a>whitespace</a> as possible.
simon@8830 1088 If the <a>next input code point</a> is U+0029 RIGHT PARENTHESIS ()) or EOF,
jackalmage@8819 1089 consume it and return the <<<url>>>;
jackalmage@8308 1090 otherwise,
jackalmage@8572 1091 <a>consume the remnants of a bad url</a>,
jackalmage@8819 1092 create a <<<bad-url>>>,
jackalmage@8308 1093 and return it.
jackalmage@8308 1094
jackalmage@8308 1095 <dt>U+0022 QUOTATION MARK (")
jackalmage@8308 1096 <dt>U+0027 APOSTROPHE (&apos;)
jackalmage@8308 1097 <dt>U+0028 LEFT PARENTHESIS (()
simon@8830 1098 <dt><a>non-printable code point</a>
jackalmage@8308 1099 <dd>
jackalmage@8572 1100 This is a <a>parse error</a>.
jackalmage@8572 1101 <a>Consume the remnants of a bad url</a>,
jackalmage@8819 1102 create a <<<bad-url>>>,
jackalmage@8308 1103 and return it.
jackalmage@8308 1104
jackalmage@8308 1105 <dt>U+005C REVERSE SOLIDUS
jackalmage@8308 1106 <dd>
jackalmage@8572 1107 If the stream <a>starts with a valid escape</a>,
simon@8830 1108 <a>consume an escaped code point</a>
simon@8830 1109 and append the returned <a>code point</a> to the <<<url>>>’s value.
jackalmage@8308 1110
jackalmage@8572 1111 Otherwise,
jackalmage@8572 1112 this is a <a>parse error</a>.
jackalmage@8572 1113 <a>Consume the remnants of a bad url</a>,
jackalmage@8819 1114 create a <<<bad-url>>>,
jackalmage@8572 1115 and return it.
jackalmage@8308 1116
jackalmage@8308 1117 <dt>anything else
jackalmage@8308 1118 <dd>
simon@8830 1119 Append the <a>current input code point</a>
jackalmage@8819 1120 to the <<<url>>>’s value.
jackalmage@8308 1121 </dl>
jackalmage@8572 1122 </ol>
jackalmage@8308 1123
jackalmage@8308 1124
jackalmage@8308 1125 <h4>
jackalmage@8308 1126 <dfn>Consume a unicode-range token</dfn></h4>
jackalmage@8308 1127
jackalmage@8572 1128 This section describes how to <a>consume a unicode-range token</a>.
jackalmage@8819 1129 It returns a <<<unicode-range>>> token.
jackalmage@8572 1130
jackalmage@8572 1131 Note: This algorithm assumes that the initial "u+" has been consumed,
simon@8830 1132 and the next <a>code point</a> verified to be a <a>hex digit</a> or a "?".
jackalmage@8572 1133
jackalmage@8572 1134 Execute the following steps in order:
jackalmage@8308 1135
jackalmage@8308 1136 <ol>
jackalmage@8308 1137 <li>
simon@8996 1138 Consume as many <a>hex digits</a> or U+003F QUESTION MARK (?) as possible,
simon@8996 1139 but no more than 6.
simon@8996 1140
simon@8996 1141 <li>
jackalmage@8819 1142 Create a new <<<unicode-range>>>
simon@8996 1143 with its <a title=unicode-range-start>start</a> set to the result of the previous step,
simon@8996 1144 and with its <a title=unicode-range-end>end</a> initially unset.
jackalmage@8308 1145
jackalmage@8308 1146 <li>
simon@8830 1147 If the <a title="next input code point">next 2 input code point</a> are
jackalmage@8572 1148 U+002D HYPHEN-MINUS (-) followed by a <a>hex digit</a>,
jackalmage@8308 1149 then:
jackalmage@8308 1150
jackalmage@8308 1151 <ol>
simon@8996 1152 <li>
simon@8996 1153 Consume the <a>next input code point</a>.
jackalmage@8308 1154
jackalmage@8308 1155 <li>
jackalmage@8572 1156 Consume as many <a>hex digits</a> as possible, but no more than 6.
simon@8996 1157 Set the <a title=unicode-range-end>unicode-range’s end</a> to the result.
jackalmage@8308 1158 </ol>
jackalmage@8308 1159
jackalmage@8308 1160 <li>
simon@8996 1161 Return the token.
jackalmage@8572 1162 </ol>
jackalmage@8308 1163
jackalmage@8115 1164
jackalmage@8115 1165 <h4>
jackalmage@8832 1166 <dfn>Consume an escaped code point</dfn></h4>
simon@8830 1167
simon@8830 1168 This section describes how to <a>consume an escaped code point</a>.
jackalmage@8572 1169 It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed
simon@8830 1170 and that the next input code point has already been verified
jackalmage@8572 1171 to not be a <a>newline</a> or EOF.
simon@8830 1172 It will return a <a>code point</a>.
simon@8830 1173
simon@8830 1174 Consume the <a>next input code point</a>.
dbaron@270 1175
jackalmage@5473 1176 <dl>
jackalmage@8572 1177 <dt><a>hex digit</a>
jackalmage@5473 1178 <dd>
jackalmage@8572 1179 Consume as many <a>hex digits</a> as possible, but no more than 5.
jackalmage@5473 1180 <span class='note'>Note that this means 1-6 hex digits have been consumed in total.</span>
simon@8830 1181 If the <a>next input code point</a> is
jackalmage@8572 1182 <a>whitespace</a>,
jackalmage@5473 1183 consume it as well.
jackalmage@8572 1184 Interpret the <a>hex digits</a> as a hexadecimal number.
jackalmage@6924 1185 If this number is zero,
simon@8831 1186 or is for a <a>surrogate code point</a>,
simon@8830 1187 or is greater than the <a>maximum allowed code point</a>,
jackalmage@6924 1188 return U+FFFD REPLACEMENT CHARACTER (�).
simon@8830 1189 Otherwise, return the <a>code point</a> with that value.
dbaron@276 1190
simon@8830 1191 <dt>EOF code point
simon@8362 1192 <dd>
simon@8362 1193 Return U+FFFD REPLACEMENT CHARACTER (�).
simon@8362 1194
jackalmage@5473 1195 <dt>anything else
jackalmage@5473 1196 <dd>
simon@8830 1197 Return the <a>current input code point</a>.
jackalmage@5473 1198 </dl>
dbaron@291 1199
jackalmage@8308 1200
jackalmage@8308 1201 <h4>
simon@8830 1202 <dfn title="check if two code points are a valid escape|are a valid escape|starts with a valid escape">Check if two code points are a valid escape</dfn></h4>
simon@8830 1203
simon@8830 1204 This section describes how to <a>check if two code points are a valid escape</a>.
simon@8830 1205 The algorithm described here can be called explicitly with two <a>code points</a>,
jackalmage@8572 1206 or can be called with the input stream itself.
simon@8830 1207 In the latter case, the two <a>code points</a> in question are
simon@8830 1208 the <a>current input code point</a>
simon@8830 1209 and the <a>next input code point</a>,
jackalmage@8572 1210 in that order.
jackalmage@8572 1211
simon@8830 1212 Note: This algorithm will not consume any additional <a>code point</a>.
simon@8830 1213
simon@8830 1214 If the first <a>code point</a> is not U+005D REVERSE SOLIDUS (\),
jackalmage@8572 1215 return false.
jackalmage@8572 1216
jackalmage@8572 1217 Otherwise,
simon@8830 1218 if the second <a>code point</a> is a <a>newline</a>,
jackalmage@8572 1219 return false.
jackalmage@8572 1220
jackalmage@8572 1221 Otherwise, return true.
jackalmage@8308 1222
jackalmage@8308 1223
jackalmage@8308 1224 <h4>
simon@8830 1225 <dfn title="check if three code points would start an identifier|starts with an identifier|start with an identifier|would start an identifier">Check if three code points would start an identifier</dfn></h4>
simon@8830 1226
simon@8830 1227 This section describes how to <a>check if three code points would start an identifier</a>.
simon@8830 1228 The algorithm described here can be called explicitly with three <a>code points</a>,
jackalmage@8572 1229 or can be called with the input stream itself.
simon@8830 1230 In the latter case, the three <a>code points</a> in question are
simon@8830 1231 the <a>current input code point</a>
simon@8830 1232 and the <a title="next input code point">next two input code points</a>,
jackalmage@8572 1233 in that order.
jackalmage@8572 1234
simon@8830 1235 Note: This algorithm will not consume any additional <a>code point</a>.
simon@8830 1236
simon@8830 1237 Look at the first <a>code point</a>:
jackalmage@8308 1238
jackalmage@8308 1239 <dl>
jackalmage@8308 1240 <dt>U+002D HYPHEN-MINUS
jackalmage@8308 1241 <dd>
simon@8830 1242 If the second <a>code point</a> is a <a>name-start code point</a>
simon@8830 1243 or the second and third <a>code points</a> <a>are a valid escape</a>,
jackalmage@8308 1244 return true.
jackalmage@8308 1245 Otherwise, return false.
jackalmage@8308 1246
simon@8830 1247 <dt><a>name-start code point</a>
jackalmage@8308 1248 <dd>
jackalmage@8308 1249 Return true.
jackalmage@8308 1250
jackalmage@8308 1251 <dt>U+005C REVERSE SOLIDUS (\)
jackalmage@8308 1252 <dd>
simon@8830 1253 If the first and second <a>code points</a> <a>are a valid escape</a>,
jackalmage@8308 1254 return true.
jackalmage@8308 1255 Otherwise, return false.
jackalmage@8308 1256 </dl>
jackalmage@8308 1257
jackalmage@8308 1258 <h4>
simon@8830 1259 <dfn title="check if three code points would start a number|starts with a number|start with a number|would start a number">Check if three code points would start a number</dfn></h4>
simon@8830 1260
simon@8830 1261 This section describes how to <a>check if three code points would start a number</a>.
simon@8830 1262 The algorithm described here can be called explicitly with three <a>code points</a>,
jackalmage@8572 1263 or can be called with the input stream itself.
simon@8830 1264 In the latter case, the three <a>code points</a> in question are
simon@8830 1265 the <a>current input code point</a>
simon@8830 1266 and the <a title="next input code point">next two input code points</a>,
jackalmage@8572 1267 in that order.
jackalmage@8572 1268
simon@8830 1269 Note: This algorithm will not consume any additional <a>code points</a>.
simon@8830 1270
simon@8830 1271 Look at the first <a>code point</a>:
jackalmage@8308 1272
jackalmage@8308 1273 <dl>
jackalmage@8308 1274 <dt>U+002B PLUS SIGN (+)
jackalmage@8308 1275 <dt>U+002D HYPHEN-MINUS (-)
jackalmage@8308 1276 <dd>
simon@8830 1277 If the second <a>code point</a>
jackalmage@8572 1278 is a <a>digit</a>,
jackalmage@8308 1279 return true.
jackalmage@8308 1280
jackalmage@8572 1281 Otherwise,
simon@8830 1282 if the second <a>code point</a>
jackalmage@8572 1283 is a U+002E FULL STOP (.)
simon@8830 1284 and the third <a>code point</a>
jackalmage@8572 1285 is a <a>digit</a>,
jackalmage@8572 1286 return true.
jackalmage@8572 1287
jackalmage@8572 1288 Otherwise, return false.
jackalmage@8308 1289
jackalmage@8308 1290 <dt>U+002E FULL STOP (.)
jackalmage@8308 1291 <dd>
simon@8830 1292 If the second <a>code point</a>
jackalmage@8572 1293 is a <a>digit</a>,
jackalmage@8308 1294 return true.
jackalmage@8308 1295 Otherwise, return false.
jackalmage@8308 1296
jackalmage@8572 1297 <dt><a>digit</a>
jackalmage@8308 1298 <dd>
jackalmage@8308 1299 Return true.
jackalmage@8308 1300
jackalmage@8308 1301 <dt>anything else
jackalmage@8308 1302 <dd>
jackalmage@8308 1303 Return false.
jackalmage@8308 1304 </dl>
jackalmage@8308 1305
jackalmage@8308 1306
jackalmage@8308 1307 <h4>
jackalmage@8308 1308 <dfn>Consume a name</dfn></h4>
jackalmage@8308 1309
simon@8830 1310 This section describes how to <a>consume a name</a> from a stream of <a>code points</a>.
jackalmage@8572 1311 It returns a string containing
simon@8830 1312 the largest name that can be formed from adjacent <a>code points</a> in the stream, starting from the first.
simon@8830 1313
simon@8830 1314 Note: This algorithm does not do the verification of the first few <a>code points</a>
simon@8830 1315 that are necessary to ensure the returned <a>code points</a> would constitute an <<<ident>>>.
jackalmage@8572 1316 If that is the intended use,
jackalmage@8572 1317 ensure that the stream <a>starts with an identifier</a>
jackalmage@8572 1318 before calling this algorithm.
jackalmage@8572 1319
jackalmage@8572 1320 Let <var>result</var> initially be an empty string.
jackalmage@8572 1321
simon@8830 1322 Repeatedly consume the <a>next input code point</a> from the stream:
jackalmage@8308 1323
jackalmage@8308 1324 <dl>
simon@8830 1325 <dt><a>name code point</a>
jackalmage@8308 1326 <dd>
simon@8830 1327 Append the <a>code point</a> to <var>result</var>.
jackalmage@8308 1328
jackalmage@8572 1329 <dt>the stream <a>starts with a valid escape</a>
jackalmage@8308 1330 <dd>
simon@8830 1331 <a>consume an escaped code point</a>.
simon@8830 1332 Append the returned <a>code point</a> to <var>result</var>.
jackalmage@8308 1333
jackalmage@8308 1334 <dt>anything else
jackalmage@8308 1335 <dd>
jackalmage@8308 1336 Return <var>result</var>.
jackalmage@8308 1337 </dl>
jackalmage@8308 1338
jackalmage@8308 1339
jackalmage@8308 1340 <h4>
jackalmage@8308 1341 <dfn>Consume a number</dfn></h4>
jackalmage@8308 1342
simon@8830 1343 This section describes how to <a>consume a number</a> from a stream of <a>code points</a>.
jackalmage@8572 1344 It returns a 3-tuple of
jackalmage@8572 1345 a string representation,
jackalmage@8572 1346 a numeric value,
jackalmage@8572 1347 and a type flag which is either "integer" or "number".
jackalmage@8572 1348
simon@8830 1349 Note: This algorithm does not do the verification of the first few <a>code points</a>
jackalmage@8572 1350 that are necessary to ensure a number can be obtained from the stream.
jackalmage@8572 1351 Ensure that the stream <a>starts with a number</a>
jackalmage@8572 1352 before calling this algorithm.
jackalmage@8572 1353
jackalmage@8572 1354 Execute the following steps in order:
jackalmage@8308 1355
jackalmage@8308 1356 <ol>
jackalmage@8308 1357 <li>
jackalmage@8308 1358 Initially set <var>repr</var> to the empty string
jackalmage@8308 1359 and <var>type</var> to "integer".
jackalmage@8308 1360
jackalmage@8308 1361 <li>
simon@8830 1362 If the <a>next input code point</a> is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
jackalmage@8308 1363 consume it and append it to <var>repr</var>.
jackalmage@8308 1364
jackalmage@8308 1365 <li>
simon@8830 1366 While the <a>next input code point</a> is a <a>digit</a>,
jackalmage@8308 1367 consume it and append it to <var>repr</var>.
jackalmage@8308 1368
jackalmage@8308 1369 <li>
simon@8830 1370 If the <a title="next input code point">next 2 input code points</a> are
jackalmage@8572 1371 U+002E FULL STOP (.) followed by a <a>digit</a>,
jackalmage@8308 1372 then:
jackalmage@8308 1373
jackalmage@8308 1374 <ol>
jackalmage@8308 1375 <li>Consume them.
jackalmage@8308 1376 <li>Append them to <var>repr</var>.
jackalmage@8308 1377 <li>Set <var>type</var> to "number".
simon@8830 1378 <li>While the <a>next input code point</a> is a <a>digit</a>, consume it and append it to <var>repr</var>.
jackalmage@8308 1379 </ol>
jackalmage@8308 1380
jackalmage@8308 1381 <li>
simon@8830 1382 If the <a title="next input code point">next 2 or 3 input code points</a> are
simon@8602 1383 U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e),
simon@8602 1384 optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+),
jackalmage@8572 1385 followed by a <a>digit</a>,
jackalmage@8308 1386 then:
jackalmage@8308 1387
jackalmage@8308 1388 <ol>
jackalmage@8308 1389 <li>Consume them.
jackalmage@8308 1390 <li>Append them to <var>repr</var>.
jackalmage@8308 1391 <li>Set <var>type</var> to "number".
simon@8830 1392 <li>While the <a>next input code point</a> is a <a>digit</a>, consume it and append it to <var>repr</var>.
jackalmage@8308 1393 </ol>
jackalmage@8308 1394
jackalmage@8308 1395 <li>
jackalmage@8572 1396 <a title="convert a string to a number">Convert <var>repr</var> to a number</a>,
jackalmage@8308 1397 and set the <var>value</var> to the returned value.
jackalmage@8308 1398
jackalmage@8308 1399 <li>
jackalmage@8308 1400 Return a 3-tuple of <var>repr</var>, <var>value</var>, and <var>type</var>.
jackalmage@8308 1401 </ol>
jackalmage@8308 1402
jackalmage@8308 1403
jackalmage@8308 1404 <h4>
jackalmage@8308 1405 <dfn>Convert a string to a number</dfn></h4>
jackalmage@8308 1406
jackalmage@8572 1407 This section describes how to <a>convert a string to a number</a>.
jackalmage@8572 1408 It returns a number.
jackalmage@8572 1409
jackalmage@8572 1410 Note: This algorithm does not do any verification to ensure that the string contains only a number.
jackalmage@8572 1411 Ensure that the string contains only a valid CSS number
jackalmage@8572 1412 before calling this algorithm.
jackalmage@8572 1413
jackalmage@8572 1414 Divide the string into seven components,
jackalmage@8572 1415 in order from left to right:
jackalmage@8308 1416
jackalmage@8308 1417 <ol>
jackalmage@8598 1418 <li>A <b>sign</b>:
jackalmage@8308 1419 a single U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
jackalmage@8308 1420 or the empty string.
jackalmage@8308 1421 Let <var>s</var> be the number -1 if the sign is U+002D HYPHEN-MINUS (-);
jackalmage@8308 1422 otherwise, let <var>s</var> be the number 1.
jackalmage@8308 1423
jackalmage@8308 1424 <li>An <b>integer part</b>:
jackalmage@8572 1425 zero or more <a>digits</a>.
jackalmage@8308 1426 If there is at least one digit,
jackalmage@8308 1427 let <var>i</var> be the number formed by interpreting the digits as a base-10 integer;
jackalmage@8308 1428 otherwise, let <var>i</var> be the number 0.
jackalmage@8308 1429
jackalmage@8308 1430 <li>A <b>decimal point</b>:
jackalmage@8308 1431 a single U+002E FULL STOP (.),
jackalmage@8308 1432 or the empty string.
jackalmage@8308 1433
jackalmage@8308 1434 <li>A <b>fractional part</b>:
jackalmage@8572 1435 zero or more <a>digits</a>.
jackalmage@8308 1436 If there is at least one digit,
jackalmage@8308 1437 let <var>f</var> be the number formed by interpreting the digits as a base-10 integer
jackalmage@8308 1438 and <var>d</var> be the number of digits;
jackalmage@8308 1439 otherwise, let <var>f</var> and <var>d</var> be the number 0.
jackalmage@8308 1440
jackalmage@8308 1441 <li>An <b>exponent indicator</b>:
jackalmage@8308 1442 a single U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e),
jackalmage@8308 1443 or the empty string.
jackalmage@8308 1444
jackalmage@8308 1445 <li>An <b>exponent sign</b>:
jackalmage@8308 1446 a single U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
jackalmage@8308 1447 or the empty string.
jackalmage@8308 1448 Let <var>t</var> be the number -1 if the sign is U+002D HYPHEN-MINUS (-);
jackalmage@8308 1449 otherwise, let <var>t</var> be the number 1.
jackalmage@8308 1450
jackalmage@8308 1451 <li>An <b>exponent</b>:
jackalmage@8572 1452 zero or more <a>digits</a>.
jackalmage@8308 1453 If there is at least one digit,
simon@8603 1454 let <var>e</var> be the number formed by interpreting the digits as a base-10 integer;
simon@8603 1455 otherwise, let <var>e</var> be the number 0.
jackalmage@8308 1456 </ol>
jackalmage@8308 1457
jackalmage@8572 1458 Return the number <code>s·(i + f·10<sup>-d</sup>)·10<sup>te</sup></code>.
jackalmage@8308 1459
jackalmage@8308 1460
jackalmage@8308 1461 <h4>
jackalmage@8308 1462 <dfn>Consume the remnants of a bad url</dfn></h4>
jackalmage@8308 1463
simon@8830 1464 This section describes how to <a>consume the remnants of a bad url</a> from a stream of <a>code points</a>,
jackalmage@8819 1465 "cleaning up" after the tokenizer realizes that it's in the middle of a <<<bad-url>>> rather than a <<<url>>>.
jackalmage@8572 1466 It returns nothing;
jackalmage@8572 1467 its sole use is to consume enough of the input stream to reach a recovery point
jackalmage@8572 1468 where normal tokenizing can resume.
jackalmage@8572 1469
simon@8830 1470 Repeatedly consume the <a>next input code point</a> from the stream:
jackalmage@8308 1471
jackalmage@8308 1472 <dl>
jackalmage@8308 1473 <dt>U+0029 RIGHT PARENTHESIS ())
jackalmage@8308 1474 <dt>EOF
jackalmage@8308 1475 <dd>
jackalmage@8308 1476 Return.
jackalmage@8308 1477
jackalmage@8572 1478 <dt>the input stream <a>starts with a valid escape</a>
jackalmage@8308 1479 <dd>
simon@8830 1480 <a>consume an escaped code point</a>.
jackalmage@8819 1481 <span class='note'>This allows an escaped right parenthesis ("\)") to be encountered without ending the <<<bad-url>>>.
jackalmage@8320 1482 This is otherwise identical to the "anything else" clause.</span>
jackalmage@8308 1483
jackalmage@8308 1484 <dt>anything else
jackalmage@8308 1485 <dd>
jackalmage@8308 1486 Do nothing.
jackalmage@8308 1487 </dl>
jackalmage@8308 1488
jackalmage@7537 1489
jackalmage@5486 1490 <!--
simon@7402 1491 PPPPPPPPPPPPPPPPP AAA RRRRRRRRRRRRRRRRR SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEERRRRRRRRRRRRRRRRR
simon@7402 1492 P::::::::::::::::P A:::A R::::::::::::::::R SS:::::::::::::::SE::::::::::::::::::::ER::::::::::::::::R
simon@7402 1493 P::::::PPPPPP:::::P A:::::A R::::::RRRRRR:::::R S:::::SSSSSS::::::SE::::::::::::::::::::ER::::::RRRRRR:::::R
jackalmage@5486 1494 PP:::::P P:::::P A:::::::A RR:::::R R:::::RS:::::S SSSSSSSEE::::::EEEEEEEEE::::ERR:::::R R:::::R
jackalmage@8116 1495 P::::P P:::::P A:::::::::A R::::R R:::::RS:::::S E:::::E EEEEEE R::::R R:::::R
jackalmage@8116 1496 P::::P P:::::PA:::::A:::::A R::::R R:::::RS:::::S E:::::E R::::R R:::::R
jackalmage@8116 1497 P::::PPPPPP:::::PA:::::A A:::::A R::::RRRRRR:::::R S::::SSSS E::::::EEEEEEEEEE R::::RRRRRR:::::R
jackalmage@8116 1498 P:::::::::::::PPA:::::A A:::::A R:::::::::::::RR SS::::::SSSSS E:::::::::::::::E R:::::::::::::RR
jackalmage@8116 1499 P::::PPPPPPPPP A:::::A A:::::A R::::RRRRRR:::::R SSS::::::::SS E:::::::::::::::E R::::RRRRRR:::::R
jackalmage@8116 1500 P::::P A:::::AAAAAAAAA:::::A R::::R R:::::R SSSSSS::::S E::::::EEEEEEEEEE R::::R R:::::R
jackalmage@8116 1501 P::::P A:::::::::::::::::::::A R::::R R:::::R S:::::S E:::::E R::::R R:::::R
jackalmage@8116 1502 P::::P A:::::AAAAAAAAAAAAA:::::A R::::R R:::::R S:::::S E:::::E EEEEEE R::::R R:::::R
jackalmage@5486 1503 PP::::::PP A:::::A A:::::A RR:::::R R:::::RSSSSSSS S:::::SEE::::::EEEEEEEE:::::ERR:::::R R:::::R
jackalmage@5486 1504 P::::::::P A:::::A A:::::A R::::::R R:::::RS::::::SSSSSS:::::SE::::::::::::::::::::ER::::::R R:::::R
jackalmage@5486 1505 P::::::::P A:::::A A:::::A R::::::R R:::::RS:::::::::::::::SS E::::::::::::::::::::ER::::::R R:::::R
jackalmage@5486 1506 PPPPPPPPPPAAAAAAA AAAAAAARRRRRRRR RRRRRRR SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEERRRRRRRR RRRRRRR
jackalmage@5486 1507 -->
jackalmage@5486 1508
jackalmage@7224 1509 <h2>
jackalmage@7224 1510 Parsing</h2>
jackalmage@5486 1511
jackalmage@8572 1512 The input to the parsing stage is a stream or list of tokens from the tokenization stage.
jackalmage@8572 1513 The output depends on how the parser is invoked,
jackalmage@8572 1514 as defined by the entry points listed later in this section.
jackalmage@8572 1515 The parser output can consist of at-rules,
jackalmage@8572 1516 qualified rules,
jackalmage@8572 1517 and/or declarations.
jackalmage@8572 1518
jackalmage@8572 1519 The parser's output is constructed according to the fundamental syntax of CSS,
jackalmage@8572 1520 without regards for the validity of any specific item.
jackalmage@8572 1521 Implementations may check the validity of items as they are returned by the various parser algorithms
jackalmage@8572 1522 and treat the algorithm as returning nothing if the item was invalid according to the implementation's own grammar knowledge,
jackalmage@8572 1523 or may construct a full tree as specified
jackalmage@8572 1524 and "clean up" afterwards by removing any invalid items.
jackalmage@8572 1525
jackalmage@8572 1526 The items that can appear in the tree are:
jackalmage@6022 1527
jackalmage@6022 1528 <dl>
jackalmage@7233 1529 <dt><dfn>at-rule</dfn>
jackalmage@6022 1530 <dd>
jackalmage@6022 1531 An at-rule has a name,
jackalmage@7264 1532 a prelude consisting of a list of component values,
jackalmage@8273 1533 and an optional block consisting of a simple {} block.
jackalmage@6235 1534
jackalmage@8572 1535 Note: This specification places no limits on what an at-rule's block may contain.
jackalmage@8572 1536 Individual at-rules must define whether they accept a block,
jackalmage@8572 1537 and if so,
jackalmage@8572 1538 how to parse it
jackalmage@8572 1539 (preferably using one of the parser algorithms or entry points defined in this specification).
jackalmage@7571 1540
jackalmage@7444 1541 <dt><dfn>qualified rule</dfn>
jackalmage@6022 1542 <dd>
jackalmage@7444 1543 A qualified rule has
jackalmage@7444 1544 a prelude consisting of a list of component values,
simon@8584 1545 and a block consisting of a simple {} block.
jackalmage@6030 1546
jackalmage@8572 1547 Note: Most qualified rules will be style rules,
simon@8584 1548 where the prelude is a selector [[SELECT]]
simon@8584 1549 and the block a <i title="parse a list of declarations">list of declarations</i>.
jackalmage@7467 1550
jackalmage@7233 1551 <dt><dfn>declaration</dfn>
jackalmage@6030 1552 <dd>
jackalmage@7130 1553 A declaration has a name,
jackalmage@7264 1554 a value consisting of a list of component values,
jackalmage@7130 1555 and an <var>important</var> flag which is initially unset.
jackalmage@6022 1556
jackalmage@8194 1557 <p class='issue'>
jackalmage@8194 1558 Should we go ahead and generalize the important flag to be a list of bang values?
jackalmage@8194 1559 Suggested by Zack Weinburg.
jackalmage@8572 1560
jackalmage@8572 1561 Declarations are further categorized as "properties" or "descriptors",
jackalmage@8572 1562 with the former typically appearing in <a>qualified rules</a>
jackalmage@8572 1563 and the latter appearing in <a>at-rules</a>.
jackalmage@8572 1564 (This categorization does not occur at the Syntax level;
jackalmage@8572 1565 instead, it is a product of where the declaration appears,
jackalmage@8572 1566 and is defined by the respective specifications defining the given rule.)
jackalmage@8194 1567
jackalmage@7264 1568 <dt><dfn>component value</dfn>
jackalmage@6022 1569 <dd>
jackalmage@7264 1570 A component value is one of the preserved tokens,
jackalmage@6022 1571 a function,
jackalmage@6022 1572 or a simple block.
jackalmage@6022 1573
jackalmage@7233 1574 <dt><dfn>preserved tokens</dfn>
jackalmage@6022 1575 <dd>
jackalmage@7444 1576 Any token produced by the tokenizer
jackalmage@8819 1577 except for <<<function>>>s,
jackalmage@8819 1578 <<<{>>>s,
jackalmage@8819 1579 <<<(>>>s,
jackalmage@8819 1580 and <<<[>>>s.
jackalmage@6022 1581
jackalmage@8572 1582 Note: The non-preserved tokens listed above are always consumed into higher-level objects,
jackalmage@8572 1583 either functions or simple blocks,
jackalmage@8572 1584 and so never appear in any parser output themselves.
jackalmage@8572 1585
jackalmage@8819 1586 Note: The tokens <<<}>>>s, <<<)>>>s, <<<]>>>, <<<bad-string>>>, and <<<bad-url>>> are always parse errors,
jackalmage@8572 1587 but they are preserved in the token stream by this specification to allow other specs,
jackalmage@8572 1588 such as Media Queries,
jackalmage@8572 1589 to define more fine-grainted error-handling
jackalmage@8572 1590 than just dropping an entire declaration or block.
jackalmage@8273 1591
jackalmage@7233 1592 <dt><dfn>function</dfn>
jackalmage@6022 1593 <dd>
jackalmage@7444 1594 A function has a name
jackalmage@8060 1595 and a value consisting of a list of component values.
jackalmage@6022 1596
jackalmage@7233 1597 <dt><dfn>simple block</dfn>
jackalmage@6022 1598 <dd>
jackalmage@8819 1599 A simple block has an associated token (either a <<<[>>>, <<<(>>>, or <<<{>>>)
jackalmage@7264 1600 and a value consisting of a list of component values.
jackalmage@6022 1601 </dl>
jackalmage@5498 1602
simon@7477 1603 <h3 id='parser-diagrams'>
simon@7477 1604 Parser Railroad Diagrams</h3>
simon@7477 1605
jackalmage@8572 1606 <em>This section is non-normative.</em>
jackalmage@8572 1607
jackalmage@8572 1608 This section presents an informative view of the parser,
jackalmage@8572 1609 in the form of railroad diagrams.
jackalmage@8572 1610 Railroad diagrams are more compact than a state-machine,
jackalmage@8572 1611 but often easier to read than a regular expression.
jackalmage@8572 1612
jackalmage@8572 1613 These diagrams are <em>informative</em> and <em>incomplete</em>;
jackalmage@8572 1614 they describe the grammar of "correct" stylesheets,
jackalmage@8572 1615 but do not describe error-handling at all.
jackalmage@8572 1616 They are provided solely to make it easier to get an intuitive grasp of the syntax.
simon@7477 1617
simon@7477 1618 <!--
simon@7477 1619 The "source" of these diagrams is in ./Diagrams.src.html
simon@7477 1620 The generated SVG is copied here so that JavaScript is not required
simon@7477 1621 to view the spec.
simon@7477 1622 -->
simon@7477 1623
simon@7477 1624 <dl>
simon@7477 1625 <dt id="stylesheet-diagram">Stylesheet</dt>
jackalmage@8851 1626 <dd><svg class="railroad-diagram" width="313" height="200"><g transform="translate(.5 .5)"><path d="M 20 121 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 131h0"></path><path d="M272 131h0"></path><path d="M40 131a10 10 0 0 0 10 -10v-89a10 10 0 0 1 10 -10"></path><g><path d="M60 22h192"></path></g><path d="M252 22a10 10 0 0 1 10 10v89a10 10 0 0 0 10 10"></path><path d="M40 131h20"></path><g><path d="M60 131h0"></path><path d="M252 131h0"></path><path d="M60 131h10"></path><g><path d="M70 131h0"></path><path d="M242 131h0"></path><path d="M70 131a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><g><path d="M90 101h8"></path><path d="M214 101h8"></path><rect x="98" y="90" width="116" height="22"></rect><text x="156" y="105">〈whitespace〉</text></g><path d="M222 101a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><path d="M70 131a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path><g><path d="M90 71h36"></path><path d="M186 71h36"></path><rect x="126" y="60" width="60" height="22"></rect><text x="156" y="75">〈CDC〉</text></g><path d="M222 71a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><path d="M70 131a10 10 0 0 0 10 -10v-70a10 10 0 0 1 10 -10"></path><g><path d="M90 41h36"></path><path d="M186 41h36"></path><rect x="126" y="30" width="60" height="22"></rect><text x="156" y="45">〈CDO〉</text></g><path d="M222 41a10 10 0 0 1 10 10v70a10 10 0 0 0 10 10"></path><path d="M70 131h20"></path><g><path d="M90 131h0"></path><path d="M222 131h0"></path><rect x="90" y="120" width="132" height="22"></rect><text x="156" y="135">Qualified rule</text></g><path d="M222 131h20"></path><path d="M70 131a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M90 161h28"></path><path d="M194 161h28"></path><rect x="118" y="150" width="76" height="22"></rect><text x="156" y="165">At-rule</text></g><path d="M222 161a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M242 131h10"></path><path d="M70 131a10 10 0 0 0 -10 10v29a10 10 0 0 0 10 10"></path><g><path d="M70 180h172"></path></g><path d="M242 180a10 10 0 0 0 10 -10v-29a10 10 0 0 0 -10 -10"></path></g><path d="M252 131h20"></path></g><path d="M 272 131 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8252 1627
simon@8252 1628 <dt id="rule-list-diagram">Rule list</dt>
jackalmage@8851 1629 <dd><svg class="railroad-diagram" width="313" height="140"><g transform="translate(.5 .5)"><path d="M 20 61 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 71h0"></path><path d="M272 71h0"></path><path d="M40 71a10 10 0 0 0 10 -10v-29a10 10 0 0 1 10 -10"></path><g><path d="M60 22h192"></path></g><path d="M252 22a10 10 0 0 1 10 10v29a10 10 0 0 0 10 10"></path><path d="M40 71h20"></path><g><path d="M60 71h0"></path><path d="M252 71h0"></path><path d="M60 71h10"></path><g><path d="M70 71h0"></path><path d="M242 71h0"></path><path d="M70 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><g><path d="M90 41h8"></path><path d="M214 41h8"></path><rect x="98" y="30" width="116" height="22"></rect><text x="156" y="45">〈whitespace〉</text></g><path d="M222 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><path d="M70 71h20"></path><g><path d="M90 71h0"></path><path d="M222 71h0"></path><rect x="90" y="60" width="132" height="22"></rect><text x="156" y="75">Qualified rule</text></g><path d="M222 71h20"></path><path d="M70 71a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M90 101h28"></path><path d="M194 101h28"></path><rect x="118" y="90" width="76" height="22"></rect><text x="156" y="105">At-rule</text></g><path d="M222 101a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M242 71h10"></path><path d="M70 71a10 10 0 0 0 -10 10v29a10 10 0 0 0 10 10"></path><g><path d="M70 120h172"></path></g><path d="M242 120a10 10 0 0 0 10 -10v-29a10 10 0 0 0 -10 -10"></path></g><path d="M252 71h20"></path></g><path d="M 272 71 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1630
simon@7477 1631 <dt id="at-rule-diagram">At-rule</dt>
jackalmage@8851 1632 <dd><svg class="railroad-diagram" width="541" height="102"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M166 41h0"></path><rect x="50" y="30" width="116" height="22"></rect><text x="108" y="45">〈at-keyword〉</text></g><path d="M166 41h10"></path><g><path d="M176 41h0"></path><path d="M376 41h0"></path><path d="M176 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M196 21h160"></path></g><path d="M356 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M176 41h20"></path><g><path d="M196 41h0"></path><path d="M356 41h0"></path><path d="M196 41h10"></path><g><path d="M206 41h0"></path><path d="M346 41h0"></path><rect x="206" y="30" width="140" height="22"></rect><text x="276" y="45">Component value</text></g><path d="M346 41h10"></path><path d="M206 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M206 61h140"></path></g><path d="M346 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M356 41h20"></path></g><g><path d="M376 41h0"></path><path d="M500 41h0"></path><path d="M376 41h20"></path><g><path d="M396 41h0"></path><path d="M480 41h0"></path><rect x="396" y="30" width="84" height="22"></rect><text x="438" y="45">{} block</text></g><path d="M480 41h20"></path><path d="M376 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M396 71h28"></path><path d="M452 71h28"></path><rect x="424" y="60" width="28" height="22" rx="10" ry="10"></rect><text x="438" y="75">;</text></g><path d="M480 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M 500 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1633
simon@7477 1634 <dt id="qualified-rule-diagram">Qualified rule</dt>
simon@8722 1635 <dd><svg class="railroad-diagram" width="385" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 41h0"></path><path d="M240 41h0"></path><path d="M40 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M60 21h160"></path></g><path d="M220 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M40 41h20"></path><g><path d="M60 41h0"></path><path d="M220 41h0"></path><path d="M60 41h10"></path><g><path d="M70 41h0"></path><path d="M210 41h0"></path><rect x="70" y="30" width="140" height="22"></rect><text x="140" y="45">Component value</text></g><path d="M210 41h10"></path><path d="M70 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M70 61h140"></path></g><path d="M210 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M220 41h20"></path></g><path d="M240 41h10"></path><g><path d="M250 41h0"></path><path d="M334 41h0"></path><rect x="250" y="30" width="84" height="22"></rect><text x="292" y="45">{} block</text></g><path d="M334 41h10"></path><path d="M 344 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@8252 1636
simon@8252 1637 <dt id="declaration-list-diagram">Declaration list</dt>
simon@8252 1638 <dd><svg class="railroad-diagram" width="589" height="102"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M94 41h0"></path><rect x="50" y="30" width="44" height="22"></rect><text x="72" y="45">ws*</text></g><path d="M94 41h10"></path><g><path d="M104 41h0"></path><path d="M548 41h0"></path><path d="M104 41h20"></path><g><path d="M124 41h0"></path><path d="M528 41h0"></path><g><path d="M124 41h0"></path><path d="M272 41h0"></path><path d="M124 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M144 21h108"></path></g><path d="M252 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M124 41h20"></path><g><path d="M144 41h0"></path><path d="M252 41h0"></path><rect x="144" y="30" width="108" height="22"></rect><text x="198" y="45">Declaration</text></g><path d="M252 41h20"></path></g><g><path d="M272 41h0"></path><path d="M528 41h0"></path><path d="M272 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M292 21h216"></path></g><path d="M508 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M272 41h20"></path><g><path d="M292 41h0"></path><path d="M508 41h0"></path><path d="M292 41h10"></path><g><path d="M302 41h0"></path><path d="M330 41h0"></path><rect x="302" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="316" y="45">;</text></g><path d="M330 41h10"></path><path d="M340 41h10"></path><g><path d="M350 41h0"></path><path d="M498 41h0"></path><rect x="350" y="30" width="148" height="22"></rect><text x="424" y="45">Declaration list</text></g><path d="M498 41h10"></path></g><path d="M508 41h20"></path></g></g><path d="M528 41h20"></path><path d="M104 41a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M124 71h70"></path><path d="M458 71h70"></path><path d="M194 71h10"></path><g><path d="M204 71h0"></path><path d="M280 71h0"></path><rect x="204" y="60" width="76" height="22"></rect><text x="242" y="75">At-rule</text></g><path d="M280 71h10"></path><path d="M290 71h10"></path><g><path d="M300 71h0"></path><path d="M448 71h0"></path><rect x="300" y="60" width="148" height="22"></rect><text x="374" y="75">Declaration list</text></g><path d="M448 71h10"></path></g><path d="M528 71a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M 548 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1639
simon@7477 1640 <dt id="declaration-diagram">Declaration</dt>
jackalmage@8851 1641 <dd><svg class="railroad-diagram" width="629" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M126 41h0"></path><rect x="50" y="30" width="76" height="22"></rect><text x="88" y="45">〈ident〉</text></g><path d="M126 41h10"></path><path d="M136 41h10"></path><g><path d="M146 41h0"></path><path d="M190 41h0"></path><rect x="146" y="30" width="44" height="22"></rect><text x="168" y="45">ws*</text></g><path d="M190 41h10"></path><path d="M200 41h10"></path><g><path d="M210 41h0"></path><path d="M238 41h0"></path><rect x="210" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="224" y="45">:</text></g><path d="M238 41h10"></path><g><path d="M248 41h0"></path><path d="M448 41h0"></path><path d="M248 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M268 21h160"></path></g><path d="M428 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M248 41h20"></path><g><path d="M268 41h0"></path><path d="M428 41h0"></path><path d="M268 41h10"></path><g><path d="M278 41h0"></path><path d="M418 41h0"></path><rect x="278" y="30" width="140" height="22"></rect><text x="348" y="45">Component value</text></g><path d="M418 41h10"></path><path d="M278 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M278 61h140"></path></g><path d="M418 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M428 41h20"></path></g><g><path d="M448 41h0"></path><path d="M588 41h0"></path><path d="M448 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M468 21h100"></path></g><path d="M568 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M448 41h20"></path><g><path d="M468 41h0"></path><path d="M568 41h0"></path><rect x="468" y="30" width="100" height="22"></rect><text x="518" y="45">!important</text></g><path d="M568 41h20"></path></g><path d="M 588 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1642
simon@7477 1643 <dt id="important-diagram">!important</dt>
jackalmage@8851 1644 <dd><svg class="railroad-diagram" width="449" height="62"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 31h10"></path><g><path d="M50 31h0"></path><path d="M78 31h0"></path><rect x="50" y="20" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="35">!</text></g><path d="M78 31h10"></path><path d="M88 31h10"></path><g><path d="M98 31h0"></path><path d="M142 31h0"></path><rect x="98" y="20" width="44" height="22"></rect><text x="120" y="35">ws*</text></g><path d="M142 31h10"></path><path d="M152 31h10"></path><g><path d="M162 31h0"></path><path d="M334 31h0"></path><rect x="162" y="20" width="172" height="22"></rect><text x="248" y="35">〈ident "important"〉</text></g><path d="M334 31h10"></path><path d="M344 31h10"></path><g><path d="M354 31h0"></path><path d="M398 31h0"></path><rect x="354" y="20" width="44" height="22"></rect><text x="376" y="35">ws*</text></g><path d="M398 31h10"></path><path d="M 408 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1645
simon@7477 1646 <dt id="ws-diagram">ws*</dt>
jackalmage@8851 1647 <dd><svg class="railroad-diagram" width="257" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 41h0"></path><path d="M216 41h0"></path><path d="M40 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M60 21h136"></path></g><path d="M196 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M40 41h20"></path><g><path d="M60 41h0"></path><path d="M196 41h0"></path><path d="M60 41h10"></path><g><path d="M70 41h0"></path><path d="M186 41h0"></path><rect x="70" y="30" width="116" height="22"></rect><text x="128" y="45">〈whitespace〉</text></g><path d="M186 41h10"></path><path d="M70 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M70 61h116"></path></g><path d="M186 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M196 41h20"></path></g><path d="M 216 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1648
simon@7477 1649 <dt id="component-value-diagram">Component value</dt>
simon@8252 1650 <dd><svg class="railroad-diagram" width="261" height="182"><g transform="translate(.5 .5)"><path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><g><path d="M40 31h0"></path><path d="M220 31h0"></path><path d="M40 31h20"></path><g><path d="M60 31h0"></path><path d="M200 31h0"></path><rect x="60" y="20" width="140" height="22"></rect><text x="130" y="35">Preserved token</text></g><path d="M200 31h20"></path><path d="M40 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g><path d="M60 61h28"></path><path d="M172 61h28"></path><rect x="88" y="50" width="84" height="22"></rect><text x="130" y="65">{} block</text></g><path d="M200 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path><g><path d="M60 91h28"></path><path d="M172 91h28"></path><rect x="88" y="80" width="84" height="22"></rect><text x="130" y="95">() block</text></g><path d="M200 91a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v70a10 10 0 0 0 10 10"></path><g><path d="M60 121h28"></path><path d="M172 121h28"></path><rect x="88" y="110" width="84" height="22"></rect><text x="130" y="125">[] block</text></g><path d="M200 121a10 10 0 0 0 10 -10v-70a10 10 0 0 1 10 -10"></path><path d="M40 31a10 10 0 0 1 10 10v100a10 10 0 0 0 10 10"></path><g><path d="M60 151h4"></path><path d="M196 151h4"></path><rect x="64" y="140" width="132" height="22"></rect><text x="130" y="155">Function block</text></g><path d="M200 151a10 10 0 0 0 10 -10v-100a10 10 0 0 1 10 -10"></path></g><path d="M 220 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1651
simon@7477 1652 <dt id="{}-block-diagram">{} block</dt>
simon@8252 1653 <dd><svg class="railroad-diagram" width="377" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M78 41h0"></path><rect x="50" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="45">{</text></g><path d="M78 41h10"></path><g><path d="M88 41h0"></path><path d="M288 41h0"></path><path d="M88 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M108 21h160"></path></g><path d="M268 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M88 41h20"></path><g><path d="M108 41h0"></path><path d="M268 41h0"></path><path d="M108 41h10"></path><g><path d="M118 41h0"></path><path d="M258 41h0"></path><rect x="118" y="30" width="140" height="22"></rect><text x="188" y="45">Component value</text></g><path d="M258 41h10"></path><path d="M118 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M118 61h140"></path></g><path d="M258 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M268 41h20"></path></g><path d="M288 41h10"></path><g><path d="M298 41h0"></path><path d="M326 41h0"></path><rect x="298" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="312" y="45">}</text></g><path d="M326 41h10"></path><path d="M 336 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1654
simon@7477 1655 <dt id="()-block-diagram">() block</dt>
simon@8252 1656 <dd><svg class="railroad-diagram" width="377" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M78 41h0"></path><rect x="50" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="45">(</text></g><path d="M78 41h10"></path><g><path d="M88 41h0"></path><path d="M288 41h0"></path><path d="M88 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M108 21h160"></path></g><path d="M268 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M88 41h20"></path><g><path d="M108 41h0"></path><path d="M268 41h0"></path><path d="M108 41h10"></path><g><path d="M118 41h0"></path><path d="M258 41h0"></path><rect x="118" y="30" width="140" height="22"></rect><text x="188" y="45">Component value</text></g><path d="M258 41h10"></path><path d="M118 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M118 61h140"></path></g><path d="M258 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M268 41h20"></path></g><path d="M288 41h10"></path><g><path d="M298 41h0"></path><path d="M326 41h0"></path><rect x="298" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="312" y="45">)</text></g><path d="M326 41h10"></path><path d="M 336 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1657
simon@7477 1658 <dt id="[]-block-diagram">[] block</dt>
simon@8252 1659 <dd><svg class="railroad-diagram" width="377" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M78 41h0"></path><rect x="50" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="64" y="45">[</text></g><path d="M78 41h10"></path><g><path d="M88 41h0"></path><path d="M288 41h0"></path><path d="M88 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M108 21h160"></path></g><path d="M268 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M88 41h20"></path><g><path d="M108 41h0"></path><path d="M268 41h0"></path><path d="M108 41h10"></path><g><path d="M118 41h0"></path><path d="M258 41h0"></path><rect x="118" y="30" width="140" height="22"></rect><text x="188" y="45">Component value</text></g><path d="M258 41h10"></path><path d="M118 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M118 61h140"></path></g><path d="M258 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M268 41h20"></path></g><path d="M288 41h10"></path><g><path d="M298 41h0"></path><path d="M326 41h0"></path><rect x="298" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="312" y="45">]</text></g><path d="M326 41h10"></path><path d="M 336 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1660
simon@7477 1661 <dt id="function-block-diagram">Function block</dt>
jackalmage@8851 1662 <dd><svg class="railroad-diagram" width="449" height="81"><g transform="translate(.5 .5)"><path d="M 20 31 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path><path d="M40 41h10"></path><g><path d="M50 41h0"></path><path d="M150 41h0"></path><rect x="50" y="30" width="100" height="22"></rect><text x="100" y="45">〈function〉</text></g><path d="M150 41h10"></path><g><path d="M160 41h0"></path><path d="M360 41h0"></path><path d="M160 41a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g><path d="M180 21h160"></path></g><path d="M340 21a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M160 41h20"></path><g><path d="M180 41h0"></path><path d="M340 41h0"></path><path d="M180 41h10"></path><g><path d="M190 41h0"></path><path d="M330 41h0"></path><rect x="190" y="30" width="140" height="22"></rect><text x="260" y="45">Component value</text></g><path d="M330 41h10"></path><path d="M190 41a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g><path d="M190 61h140"></path></g><path d="M330 61a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g><path d="M340 41h20"></path></g><path d="M360 41h10"></path><g><path d="M370 41h0"></path><path d="M398 41h0"></path><rect x="370" y="30" width="28" height="22" rx="10" ry="10"></rect><text x="384" y="45">)</text></g><path d="M398 41h10"></path><path d="M 408 41 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg></dd>
simon@7477 1663
simon@7477 1664 </dl>
simon@7477 1665
jackalmage@7224 1666 <h3>
jackalmage@7224 1667 Definitions</h3>
jackalmage@5498 1668
jackalmage@5498 1669 <dl>
jackalmage@6014 1670 <dt><dfn>current input token</dfn>
jackalmage@6014 1671 <dd>
jackalmage@8572 1672 The token or <a>component value</a> currently being operated on, from the list of tokens produced by the tokenizer.
jackalmage@6015 1673
jackalmage@5964 1674 <dt><dfn>next input token</dfn>
jackalmage@5498 1675 <dd>
jackalmage@8572 1676 The token or <a>component value</a> following the <a>current input token</a> in the list of tokens produced by the tokenizer.
jackalmage@8572 1677 If there isn't a token following the <a>current input token</a>,
jackalmage@8819 1678 the <a>next input token</a> is an <<<EOF>>>.
jackalmage@8819 1679
jackalmage@8819 1680 <dt><dfn><<<EOF>>></dfn>
jackalmage@7490 1681 <dd>
jackalmage@7490 1682 A conceptual token representing the end of the list of tokens.
simon@7492 1683 Whenever the list of tokens is empty,
jackalmage@8819 1684 the <a>next input token</a> is always an <<<EOF>>>.
jackalmage@7490 1685
jackalmage@8573 1686 <dt><dfn>consume the next input token</dfn>
jackalmage@8573 1687 <dd>
jackalmage@8573 1688 Let the <a>current input token</a> be the current <a>next input token</a>,
jackalmage@8573 1689 adjusting the <a>next input token</a> accordingly.
jackalmage@8573 1690
jackalmage@6678 1691 <dt><dfn>reconsume the current input token</dfn>
jackalmage@6678 1692 <dd>
jackalmage@8573 1693 The next time an algorithm instructs you to <a>consume the next input token</a>,
jackalmage@8573 1694 instead do nothing
jackalmage@8573 1695 (retain the <a>current input token</a> unchanged).
jackalmage@6678 1696
jackalmage@7128 1697 <dt><dfn>ASCII case-insensitive</dfn>
jackalmage@7128 1698 <dd>
jackalmage@7128 1699 When two strings are to be matched ASCII case-insensitively,
jackalmage@7128 1700 temporarily convert both of them to ASCII lower-case form
simon@8830 1701 by adding 32 (0x20) to the value of each <a>code point</a> between
jackalmage@7128 1702 U+0041 LATIN CAPITAL LETTER A (A)
jackalmage@7128 1703 and U+005A LATIN CAPITAL LETTER Z (Z),
jackalmage@7128 1704 inclusive,
simon@8830 1705 and check if this results in identical sequences of <a>code point</a>.
jackalmage@5498 1706 </dl>
jackalmage@5498 1707
jackalmage@7444 1708
jackalmage@7444 1709
jackalmage@7224 1710 <h3>
jackalmage@7444 1711 Parser Entry Points</h3>
jackalmage@7444 1712
jackalmage@8572 1713 The algorithms defined in this section produce high-level CSS objects
jackalmage@8572 1714 from lower-level objects.
jackalmage@8572 1715 They assume that they are invoked on a token stream,
jackalmage@8572 1716 but they may also be invoked on a string;
jackalmage@8572 1717 if so,
jackalmage@8572 1718 first perform <a href="#preprocessing-the-input-stream">input preprocessing</a>
simon@8830 1719 to produce a <a>code point</a> stream,
jackalmage@8572 1720 then perform <a href="#tokenization">tokenization</a>
jackalmage@8572 1721 to produce a token stream.
jackalmage@8572 1722
jackalmage@8572 1723 "<a>Parse a stylesheet</a>" can also be invoked on a byte stream,
jackalmage@8572 1724 in which case <a href="#the-input-byte-stream">The input byte stream</a>
jackalmage@8572 1725 defines how to decode it into Unicode.
jackalmage@8572 1726
jackalmage@8572 1727 Note: This specification does not define how a byte stream is decoded for other entry points.
jackalmage@8572 1728
jackalmage@8572 1729 Note: Other specs can define additional entry points for their own purposes.
jackalmage@7551 1730
jackalmage@7444 1731 <div class='issue'>
jackalmage@8572 1732 The following notes should probably be translated into normative text in the relevant specs,
jackalmage@8572 1733 hooking this spec's terms:
jackalmage@7444 1734
jackalmage@7444 1735 <ul>
jackalmage@7444 1736 <li>
jackalmage@8572 1737 "<a>Parse a stylesheet</a>" is intended to be the normal parser entry point,
jackalmage@7444 1738 for parsing stylesheets.
jackalmage@7444 1739
jackalmage@7444 1740 <li>
jackalmage@8572 1741 "<a>Parse a list of rules</a>" is intended for the content of at-rules such as ''@media''.
jackalmage@8819 1742 It differs from "<a>Parse a stylesheet</a>" in the handling of <<<CDO>>> and <<<CDC>>>.
simon@8477 1743
simon@8477 1744 <li>
jackalmage@8572 1745 "<a>Parse a rule</a>" is intended for use by the <code>CSSStyleSheet#insertRule</code> method,
jackalmage@7444 1746 and similar functions which might exist,
jackalmage@7444 1747 which parse text into a single rule.
jackalmage@7444 1748
jackalmage@7444 1749 <li>
jackalmage@8572 1750 "<a>Parse a declaration</a>" is used in ''@supports'' conditions. [[CSS3-CONDITIONAL]]
simon@8477 1751
simon@8477 1752 <li>
jackalmage@8572 1753 "<a>Parse a list of declarations</a>" is for the contents of a <code>style</code> attribute,
jackalmage@7444 1754 which parses text into the contents of a single style rule.
jackalmage@7444 1755
jackalmage@7444 1756 <li>
jackalmage@8572 1757 "<a>Parse a component value</a>" is for things that need to consume a single value,
jackalmage@8273 1758 like the parsing rules for ''attr()''.
jackalmage@7444 1759
jackalmage@7444 1760 <li>
jackalmage@8572 1761 "<a>Parse a list of component values</a>" is for the contents of presentational attributes,
simon@8477 1762 which parse text into a single declaration's value,
simon@8477 1763 or for parsing a stand-alone selector [[SELECT]] or list of Media Queries [[MEDIAQ]],
simon@8477 1764 as in <a href="http://www.w3.org/TR/selectors-api/">Selectors API</a>
simon@8477 1765 or the <code>media</code> HTML attribute.
jackalmage@7444 1766 </ul>
jackalmage@7444 1767 </div>
jackalmage@7444 1768
jackalmage@8572 1769 All of the algorithms defined in this spec may be called with either a list of tokens or of component values.
jackalmage@8572 1770 Either way produces an identical result.
jackalmage@7463 1771
jackalmage@7224 1772
jackalmage@5498 1773 <h4>
jackalmage@7444 1774 <dfn>Parse a stylesheet</dfn></h4>
jackalmage@5498 1775
jackalmage@8572 1776 To <a>parse a stylesheet</a> from a stream of tokens:
jackalmage@7444 1777
jackalmage@7444 1778 <ol>
jackalmage@7444 1779 <li>
jackalmage@7444 1780 Create a new stylesheet.
jackalmage@7444 1781
jackalmage@7444 1782 <li>
jackalmage@8572 1783 <a>Consume a list of rules</a> from the stream of tokens, with the <var>top-level flag</var> set.
jackalmage@7444 1784
jackalmage@7444 1785 <li>
jackalmage@7444 1786 Assign the returned value to the stylesheet's value.
jackalmage@7444 1787
jackalmage@7444 1788 <li>
jackalmage@7444 1789 Return the stylesheet.
jackalmage@7444 1790 </ol>
jackalmage@7444 1791
jackalmage@7444 1792 <h4>
simon@8477 1793 <dfn>Parse a list of rules</dfn></h4>
simon@8477 1794
jackalmage@8572 1795 To <a>parse a list of rules</a> from a stream of tokens:
simon@8477 1796
simon@8477 1797 <ol>
simon@8477 1798 <li>
jackalmage@8573 1799 <a>Consume a list of rules</a> from the stream of tokens, with the <var>top-level flag</var> unset.
jackalmage@8573 1800
jackalmage@8573 1801 <li>
jackalmage@8573 1802 Return the returned list.
simon@8477 1803 </ol>
simon@8477 1804
simon@8477 1805 <h4>
jackalmage@7444 1806 <dfn>Parse a rule</dfn></h4>
jackalmage@7444 1807
jackalmage@8572 1808 To <a>parse a rule</a> from a stream of tokens:
jackalmage@7444 1809
jackalmage@7444 1810 <ol>
jackalmage@7444 1811 <li>
jackalmage@8575 1812 <a>Consume the next input token</a>.
jackalmage@7444 1813
jackalmage@7444 1814 <li>
jackalmage@8819 1815 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8575 1816 <a>consume the next input token</a>.
jackalmage@8573 1817
jackalmage@8573 1818 <li>
jackalmage@8819 1819 If the <a>current input token</a> is an <<<EOF>>>,
jackalmage@7444 1820 return a syntax error.
jackalmage@7444 1821
jackalmage@8572 1822 Otherwise,
jackalmage@8819 1823 if the <a>current input token</a> is an <<<at-keyword>>>,
jackalmage@8572 1824 <a>consume an at-rule</a>.
jackalmage@8572 1825
jackalmage@8572 1826 Otherwise,
jackalmage@8572 1827 <a>consume a qualified rule</a>.
jackalmage@8572 1828 If nothing was returned,
jackalmage@8572 1829 return a syntax error.
jackalmage@7444 1830
jackalmage@7444 1831 <li>
jackalmage@8819 1832 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8575 1833 <a>consume the next input token</a>.
jackalmage@7444 1834
jackalmage@7444 1835 <li>
jackalmage@8819 1836 If the <a>current input token</a> is an <<<EOF>>>,
jackalmage@7444 1837 return the rule obtained in step 2.
jackalmage@7444 1838 Otherwise, return a syntax error.
jackalmage@7444 1839 </ol>
jackalmage@7444 1840
jackalmage@7444 1841 <h4>
simon@8477 1842 <dfn>Parse a declaration</dfn></h4>
simon@8477 1843
jackalmage@8572 1844 Note: Unlike "<a>Parse a list of declarations</a>",
jackalmage@8572 1845 this parses only a declaration and not an at-rule.
jackalmage@8572 1846
jackalmage@8572 1847 To <a>parse a declaration</a>:
simon@8477 1848
simon@8477 1849 <ol>
simon@8477 1850 <li>
jackalmage@8573 1851 <a>Consume the next input token</a>.
jackalmage@8573 1852
jackalmage@8573 1853 <li>
jackalmage@8819 1854 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8575 1855 <a>consume the next input token</a>.
simon@8554 1856
simon@8554 1857 <li>
jackalmage@8572 1858 <a>Consume a declaration</a>.
simon@8477 1859 If anything was returned, return it.
simon@8477 1860 Otherwise, return a syntax error.
simon@8477 1861 </ol>
simon@8477 1862
simon@8477 1863 <h4>
jackalmage@7444 1864 <dfn>Parse a list of declarations</dfn></h4>
jackalmage@7444 1865
jackalmage@8572 1866 Note: Despite the name,
jackalmage@8572 1867 this actually parses a mixed list of declarations and at-rules,
jackalmage@8572 1868 as CSS 2.1 does for <a href=http://www.w3.org/TR/CSS21/page.html#page-box>''@page''</a>.
jackalmage@8572 1869 Unexpected at-rules (which could be all of them, in a given context)
jackalmage@8572 1870 are invalid and should be ignored by the consumer.
jackalmage@8572 1871
jackalmage@8572 1872 To <a>parse a list of declarations</a>:
jackalmage@7444 1873
jackalmage@7444 1874 <ol>
jackalmage@7444 1875 <li>
jackalmage@8573 1876 <a>Consume a list of declarations</a>.
jackalmage@8573 1877
jackalmage@8573 1878 <li>
jackalmage@8573 1879 Return the returned list.
jackalmage@7444 1880 </ol>
jackalmage@7444 1881
jackalmage@7444 1882 <h4>
jackalmage@7444 1883 <dfn>Parse a component value</dfn></h4>
jackalmage@7444 1884
jackalmage@8572 1885 To <a>parse a component value</a>:
jackalmage@7444 1886
jackalmage@7444 1887 <ol>
jackalmage@7444 1888 <li>
jackalmage@8575 1889 <a>Consume the next input token</a>.
jackalmage@8573 1890
jackalmage@8573 1891 <li>
jackalmage@8819 1892 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8575 1893 <a>consume the next input token</a>.
jackalmage@8573 1894
jackalmage@8573 1895 <li>
jackalmage@8819 1896 If the <a>current input token</a> is an <<<EOF>>>,
jackalmage@7444 1897 return a syntax error.
jackalmage@7444 1898
jackalmage@7444 1899 <li>
jackalmage@8575 1900 <a>Reconsume the current input token</a>.
jackalmage@8572 1901 <a>Consume a component value</a>.
jackalmage@7444 1902 If nothing is returned,
jackalmage@7444 1903 return a syntax error.
jackalmage@7444 1904
jackalmage@7444 1905 <li>
jackalmage@8819 1906 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8573 1907 <a>consume the next input token</a>.
jackalmage@8573 1908
jackalmage@8573 1909 <li>
jackalmage@8819 1910 If the <a>current input token</a> is an <<<EOF>>>,
jackalmage@8573 1911 return the <a>component value</a> returned in step 3.
jackalmage@7444 1912 Otherwise,
jackalmage@7444 1913 return a syntax error.
jackalmage@7444 1914 </ol>
jackalmage@7444 1915
jackalmage@7444 1916 <h4>
jackalmage@7444 1917 <dfn>Parse a list of component values</dfn></h4>
jackalmage@7444 1918
jackalmage@8572 1919 To <a>parse a list of component values</a>:
jackalmage@7444 1920
jackalmage@7444 1921 <ol>
jackalmage@7444 1922 <li>
jackalmage@8819 1923 Repeatedly <a>consume a component value</a> until an <<<EOF>>> is returned,
jackalmage@8819 1924 appending the returned values (except the final <<<EOF>>>) into a list.
jackalmage@7444 1925 Return the list.
jackalmage@7444 1926 </ol>
jackalmage@7444 1927
jackalmage@7444 1928 <h3>
jackalmage@7444 1929 Parser Algorithms</h3>
jackalmage@7444 1930
jackalmage@8572 1931 The following algorithms comprise the parser.
jackalmage@8572 1932 They are called by the parser entry points above.
jackalmage@8572 1933
jackalmage@8572 1934 These algorithms may be called with a list of either tokens or of component values.
jackalmage@8572 1935 (The difference being that some tokens are replaced by <a>functions</a> and <a>simple blocks</a> in a list of component values.)
simon@8830 1936 Similar to how the input stream returned EOF code points to represent when it was empty during the tokenization stage,
jackalmage@8819 1937 the lists in this stage must return an <<<EOF>>> when the next token is requested but they are empty.
jackalmage@8572 1938
jackalmage@8572 1939 An algorithm may be invoked with a specific list,
jackalmage@8572 1940 in which case it consumes only that list
jackalmage@8572 1941 (and when that list is exhausted,
jackalmage@8819 1942 it begins returning <<<EOF>>>s).
jackalmage@8572 1943 Otherwise,
jackalmage@8572 1944 it is implicitly invoked with the same list as the invoking algorithm.
jackalmage@7462 1945
jackalmage@7462 1946
jackalmage@7444 1947 <h4>
jackalmage@7444 1948 <dfn>Consume a list of rules</dfn></h4>
jackalmage@7444 1949
jackalmage@8572 1950 Create an initially empty list of rules.
jackalmage@8572 1951
jackalmage@8572 1952 Repeatedly consume the <a>next input token</a>:
jackalmage@5498 1953
jackalmage@5498 1954 <dl>
jackalmage@8819 1955 <dt><<<whitespace>>>
jackalmage@5498 1956 <dd>
jackalmage@5498 1957 Do nothing.
jackalmage@7444 1958
jackalmage@8819 1959 <dt><<<EOF>>>
jackalmage@7444 1960 <dd>
jackalmage@7444 1961 Return the list of rules.
jackalmage@5498 1962
jackalmage@8819 1963 <dt><<<CDO>>>
jackalmage@8819 1964 <dt><<<CDC>>>
jackalmage@8112 1965 <dd>
simon@8477 1966 If the <dfn><var>top-level flag</var></dfn> is set,
jackalmage@8112 1967 do nothing.
jackalmage@8112 1968
jackalmage@8572 1969 Otherwise,
jackalmage@8572 1970 <a>reconsume the current input token</a>.
jackalmage@8572 1971 <a>Consume a qualified rule</a>.
jackalmage@8572 1972 If anything is returned,
jackalmage@8572 1973 append it to the list of rules.
jackalmage@8112 1974
jackalmage@8819 1975 <dt><<<at-keyword>>>
jackalmage@5498 1976 <dd>
jackalmage@8572 1977 <a>Reconsume the current input token</a>.
jackalmage@8572 1978 <a>Consume an at-rule</a>.
jackalmage@7561 1979 If anything is returned,
jackalmage@7561 1980 append it to the list of rules.
jackalmage@7444 1981
jackalmage@7444 1982 <dt>anything else
jackalmage@7444 1983 <dd>
jackalmage@8572 1984 <a>Reconsume the current input token</a>.
jackalmage@8572 1985 <a>Consume a qualified rule</a>.
jackalmage@7444 1986 If anything is returned,
jackalmage@8111 1987 append it to the list of rules.
jackalmage@7444 1988 </dl>
jackalmage@7444 1989
jackalmage@7444 1990
jackalmage@7444 1991 <h4>
jackalmage@7444 1992 <dfn>Consume an at-rule</dfn></h4>
jackalmage@7444 1993
jackalmage@8572 1994 Create a new at-rule
jackalmage@8572 1995 with its name set to the value of the <a>current input token</a>,
jackalmage@8572 1996 its prelude initially set to an empty list,
jackalmage@8572 1997 and its value initially set to nothing.
jackalmage@8572 1998
jackalmage@8572 1999 Repeatedly consume the <a>next input token</a>:
jackalmage@7444 2000
jackalmage@7444 2001 <dl>
jackalmage@8819 2002 <dt><<<semicolon>>>
jackalmage@8819 2003 <dt><<<EOF>>>
jackalmage@6239 2004 <dd>
jackalmage@7444 2005 Return the at-rule.
jackalmage@6239 2006
jackalmage@8819 2007 <dt><<<{>>>
jackalmage@7561 2008 <dd>
jackalmage@8572 2009 <a>Consume a simple block</a>
jackalmage@8273 2010 and assign it to the at-rule's block.
jackalmage@7561 2011 Return the at-rule.
jackalmage@7561 2012
jackalmage@8819 2013 <dt><a>simple block</a> with an associated token of <<<{>>>
jackalmage@7561 2014 <dd>
jackalmage@8273 2015 Assign the block to the at-rule's block.
jackalmage@7561 2016 Return the at-rule.
jackalmage@7561 2017
jackalmage@6016 2018 <dt>anything else
jackalmage@6016 2019 <dd>
jackalmage@8575 2020 <a>Reconsume the current input token</a>.
jackalmage@8572 2021 <a>Consume a component value</a>.
jackalmage@7444 2022 Append the returned value to the at-rule's prelude.
jackalmage@5964 2023 </dl>
jackalmage@5964 2024
jackalmage@5964 2025
jackalmage@5964 2026 <h4>
jackalmage@7444 2027 <dfn>Consume a qualified rule</dfn></h4>
jackalmage@5964 2028
jackalmage@8572 2029 Create a new qualified rule
jackalmage@8572 2030 with its prelude initially set to an empty list,
jackalmage@8572 2031 and its value initially set to nothing.
jackalmage@8572 2032
jackalmage@8572 2033 Repeatedly consume the <a>next input token</a>:
jackalmage@5964 2034
jackalmage@5964 2035 <dl>
jackalmage@8819 2036 <dt><<<EOF>>>
jackalmage@6239 2037 <dd>
jackalmage@8572 2038 This is a <a>parse error</a>.
jackalmage@7444 2039 Return nothing.
jackalmage@7444 2040
jackalmage@8819 2041 <dt><<<{>>>
jackalmage@7444 2042 <dd>
simon@8584 2043 <a>Consume a simple block</a>
simon@8584 2044 and assign it to the qualified rule's block.
jackalmage@7444 2045 Return the qualified rule.
jackalmage@6239 2046
jackalmage@8819 2047 <dt><a>simple block</a> with an associated token of <<<{>>>
jackalmage@7462 2048 <dd>
simon@8584 2049 Assign the block to the qualified rule's block.
jackalmage@7462 2050 Return the qualified rule.
jackalmage@7462 2051
jackalmage@5964 2052 <dt>anything else
jackalmage@5964 2053 <dd>
jackalmage@8575 2054 <a>Reconsume the current input token</a>.
jackalmage@8572 2055 <a>Consume a component value</a>.
jackalmage@7444 2056 Append the returned value to the qualified rule's prelude.
jackalmage@5964 2057 </dl>
jackalmage@5964 2058
jackalmage@5964 2059
jackalmage@5964 2060 <h4>
jackalmage@7444 2061 <dfn>Consume a list of declarations</dfn></h4>
jackalmage@5964 2062
jackalmage@8572 2063 Create an initially empty list of declarations.
jackalmage@8572 2064
jackalmage@8572 2065 Repeatedly consume the <a>next input token</a>:
jackalmage@5964 2066
jackalmage@5964 2067 <dl>
jackalmage@8819 2068 <dt><<<whitespace>>>
jackalmage@8819 2069 <dt><<<semicolon>>>
jackalmage@5964 2070 <dd>
jackalmage@5964 2071 Do nothing.
jackalmage@7444 2072
jackalmage@8819 2073 <dt><<<EOF>>>
jackalmage@5978 2074 <dd>
jackalmage@7444 2075 Return the list of declarations.
jackalmage@5978 2076
jackalmage@8819 2077 <dt><<<at-keyword>>>
jackalmage@6016 2078 <dd>
jackalmage@8572 2079 <a>Consume an at-rule</a>.
jackalmage@8195 2080 Append the returned rule to the list of declarations.
jackalmage@6016 2081
jackalmage@8819 2082 <dt><<<ident>>>
jackalmage@5964 2083 <dd>
jackalmage@8572 2084 Initialize a temporary list initially filled with the <a>current input token</a>.
jackalmage@8575 2085 <a>Consume the next input token</a>.
jackalmage@8819 2086 While the <a>current input token</a> is anything other than a <<<semicolon>>> or <<<EOF>>>,
jackalmage@8574 2087 append it to the temporary list
jackalmage@8575 2088 and <a>consume the next input token</a>.
jackalmage@8572 2089 <a>Consume a declaration</a> from the temporary list.
jackalmage@7444 2090 If anything was returned,
jackalmage@7444 2091 append it to the list of declarations.
jackalmage@7444 2092
jackalmage@7444 2093 <dt>anything else</dd>
jackalmage@5498 2094 <dd>
jackalmage@8572 2095 This is a <a>parse error</a>.
jackalmage@8574 2096 Repeatedly <a>consume a component value</a>
jackalmage@8819 2097 until it is a <<<semicolon>>> or <<<EOF>>>.
jackalmage@5964 2098 </dl>
jackalmage@5964 2099
jackalmage@5964 2100
jackalmage@5964 2101 <h4>
jackalmage@7444 2102 <dfn>Consume a declaration</dfn></h4>
jackalmage@5964 2103
jackalmage@8572 2104 Create a new declaration
jackalmage@8573 2105 with its name set to the value of the <a>current input token</a>
jackalmage@8573 2106 and its value initially set to the empty list.
jackalmage@8573 2107
jackalmage@8573 2108 <ol>
jackalmage@8573 2109 <li>
jackalmage@8575 2110 <a>Consume the next input token</a>.
jackalmage@8573 2111
jackalmage@8573 2112 <li>
jackalmage@8819 2113 While the <a>current input token</a> is a <<<whitespace>>>,
jackalmage@8575 2114 <a>consume the next input token</a>.
jackalmage@8573 2115
jackalmage@8573 2116 <li>
jackalmage@8819 2117 If the <a>current input token</a> is anything other than a <<<colon>>>,
jackalmage@8575 2118 this is a <a>parse error</a>.
jackalmage@8573 2119 Return nothing.
jackalmage@8573 2120
jackalmage@8575 2121 Otherwise, <a>consume the next input token</a>.
jackalmage@8573 2122
jackalmage@8573 2123 <li>
jackalmage@8819 2124 While the <a>current input token</a> is anything other than an <<<EOF>>>,
jackalmage@8573 2125 append it to the declaration's value
jackalmage@8575 2126 and <a>consume the next input token</a>.
jackalmage@8573 2127
jackalmage@8573 2128 <li>
jackalmage@8819 2129 If the last two non-<<<whitespace>>>s in the declaration's value are
jackalmage@8819 2130 a <<<delim>>> with the value "!"
jackalmage@8819 2131 followed by an <<<ident>>> with a value that is an <a>ASCII case-insensitive</a> match for "important",
jackalmage@8573 2132 remove them from the declaration's value
jackalmage@8573 2133 and set the declaration's <var>important</var> flag to true.
jackalmage@8573 2134
jackalmage@8573 2135 <li>
jackalmage@8573 2136 Return the declaration.
jackalmage@8573 2137 </ol>
jackalmage@5498 2138
jackalmage@5491 2139
jackalmage@5964 2140 <h4>
jackalmage@7444 2141 <dfn>Consume a component value</dfn></h4>
jackalmage@6236 2142
jackalmage@8572 2143 This section describes how to <a>consume a component value</a>.
jackalmage@8572 2144
jackalmage@8575 2145 <a>Consume the next input token</a>.
jackalmage@8574 2146
jackalmage@8572 2147 If the <a>current input token</a>
jackalmage@8819 2148 is a <<<{>>>, <<<[>>>, or <<<(>>>,
jackalmage@8572 2149 <a>consume a simple block</a>
jackalmage@8572 2150 and return it.
jackalmage@8572 2151
jackalmage@8572 2152 Otherwise, if the <a>current input token</a>
jackalmage@8819 2153 is a <<<function>>>,
jackalmage@8572 2154 <a>consume a function</a>
jackalmage@8572 2155 and return it.
jackalmage@8572 2156
jackalmage@8572 2157 Otherwise, return the <a>current input token</a>.
jackalmage@6236 2158
jackalmage@6236 2159
jackalmage@7444 2160 <h4>
jackalmage@7444 2161 <dfn>Consume a simple block</dfn></h4>
jackalmage@5964 2162
jackalmage@8572 2163 This section describes how to <a>consume a simple block</a>.
jackalmage@8572 2164
jackalmage@8572 2165 The <dfn>ending token</dfn> is the mirror variant of the <a>current input token</a>.
jackalmage@8819 2166 (E.g. if it was called with <<<[>>>, the <a>ending token</a> is <<<]>>>.)
jackalmage@8572 2167
jackalmage@8573 2168 Create a <a>simple block</a> with its associated token set to the <a>current input token</a>
jackalmage@8573 2169 and with a value with is initially an empty list.
jackalmage@8572 2170
jackalmage@8572 2171 Repeatedly consume the <a>next input token</a> and process it as follows:
jackalmage@5964 2172
jackalmage@5964 2173 <dl>
jackalmage@8819 2174 <dt><<<EOF>>>
jackalmage@8572 2175 <dt><a>ending token</a>
jackalmage@5964 2176 <dd>
jackalmage@7444 2177 Return the block.
jackalmage@5964 2178
jackalmage@5964 2179 <dt>anything else
jackalmage@5964 2180 <dd>
jackalmage@8575 2181 <a>Reconsume the current input token</a>.
jackalmage@8572 2182 <a>Consume a component value</a>
jackalmage@7444 2183 and append it to the value of the block.
jackalmage@5964 2184 </dl>
jackalmage@5964 2185
jackalmage@5964 2186
jackalmage@7444 2187 <h4>
jackalmage@7444 2188 <dfn>Consume a function</dfn></h4>
jackalmage@6020 2189
jackalmage@8572 2190 This section describes how to <a>consume a function</a>.
jackalmage@8572 2191
jackalmage@8572 2192 Create a function with a name equal to the value of the <a>current input token</a>,
jackalmage@8572 2193 and with a value which is initially an empty list.
jackalmage@8572 2194
jackalmage@8572 2195 Repeatedly consume the <a>next input token</a> and process it as follows:
jackalmage@6020 2196
jackalmage@6020 2197 <dl>
jackalmage@8819 2198 <dt><<<EOF>>>
jackalmage@8819 2199 <dt><<<)>>>
jackalmage@6020 2200 <dd>
jackalmage@6020 2201 Return the function.
jackalmage@6020 2202
jackalmage@6020 2203 <dt>anything else
jackalmage@6020 2204 <dd>
jackalmage@8575 2205 <a>Reconsume the current input token</a>.
jackalmage@8572 2206 <a>Consume a component value</a>
jackalmage@7444 2207 and append the returned value
jackalmage@8209 2208 to the function's value.
jackalmage@6020 2209 </dl>
jackalmage@6020 2210
jackalmage@6020 2211
jackalmage@6239 2212
jackalmage@8116 2213 <h2 id="anb">
jackalmage@8116 2214 The <var>An+B</var> microsyntax</h2>
jackalmage@8116 2215
jackalmage@8598 2216 Several things in CSS,
jackalmage@8572 2217 such as the '':nth-child()'' pseudoclass,
jackalmage@8572 2218 need to indicate indexes in a list.
jackalmage@8572 2219 The <var>An+B</var> microsyntax is useful for this,
jackalmage@8572 2220 allowing an author to easily indicate single elements
jackalmage@8572 2221 or all elements at regularly-spaced intervals in a list.
jackalmage@8572 2222
jackalmage@8572 2223 The <dfn>An+B</dfn> notation defines an integer step (<dfn>A</dfn>) and offset (<dfn>B</dfn>),
jackalmage@8572 2224 and represents the <var>An+B</var>th elements in a list,
jackalmage@8572 2225 for every positive integer or zero value of <var>n</var>,
jackalmage@8572 2226 with the first element in the list having index 1 (not 0).
jackalmage@8572 2227
jackalmage@8572 2228 For values of <var>A</var> and <var>B</var> greater than 0,
jackalmage@8572 2229 this effectively divides the list into groups of <var>A</var> elements
jackalmage@8572 2230 (the last group taking the remainder),
jackalmage@8572 2231 and selecting the <var>B</var>th element of each group.
jackalmage@8572 2232
jackalmage@8572 2233 The <var>An+B</var> notation also accepts the ''even'' and ''odd'' keywords,
jackalmage@8572 2234 which have the same meaning as ''2n'' and ''2n+1'', respectively.
jackalmage@8572 2235
jackalmage@8116 2236 <div class="example">
jackalmage@8116 2237 <p>Examples:
jackalmage@8116 2238 <pre><!--
jackalmage@8116 2239 -->2n+0 /* represents all of the even elements in the list */&#xa;<!--
jackalmage@8116 2240 -->even /* same */&#xa;<!--
jackalmage@8116 2241 -->4n+1 /* represents the 1st, 5th, 9th, 13th, etc. elements in the list */</pre>
jackalmage@8116 2242 </div>
jackalmage@8116 2243
jackalmage@8572 2244 The values of <var>A</var> and <var>B</var> can be negative,
jackalmage@8572 2245 but only the positive results of <var>An+B</var>,
jackalmage@8572 2246 for <var>n</var> ≥ 0,
jackalmage@8572 2247 are used.
jackalmage@8116 2248
jackalmage@8116 2249 <div class="example">
jackalmage@8116 2250 <p>Example:
jackalmage@8116 2251 <pre>-n+6 /* represents the first 6 elements of the list */</pre>
jackalmage@8116 2252 </div>
jackalmage@8116 2253
jackalmage@8572 2254 If both <var>A</var> and <var>B</var> are 0,
jackalmage@8572 2255 the pseudo-class represents no element in the list.
jackalmage@8116 2256
jackalmage@8116 2257 <h3 id='anb-syntax'>
jackalmage@8116 2258 Informal Syntax Description</h3>
jackalmage@8116 2259
jackalmage@8572 2260 <em>This section is non-normative.</em>
jackalmage@8572 2261
jackalmage@8572 2262 When <var>A</var> is 0, the <var>An</var> part may be omitted
jackalmage@8572 2263 (unless the <var>B</var> part is already omitted).
jackalmage@8572 2264 When <var>An</var> is not included
jackalmage@8572 2265 and <var>B</var> is non-negative,
jackalmage@8572 2266 the ''+'' sign before <var>B</var> (when allowed)
jackalmage@8572 2267 may also be omitted.
jackalmage@8572 2268 In this case the syntax simplifies to just <var>B</var>.
jackalmage@8116 2269
jackalmage@8116 2270 <div class="example">
jackalmage@8116 2271 <p>Examples:
jackalmage@8116 2272 <pre><!--
jackalmage@8116 2273 -->0n+5 /* represents the 5th element in the list */&#xa;<!--
jackalmage@8116 2274 -->5 /* same */</pre>
jackalmage@8116 2275 </div>
jackalmage@8116 2276
jackalmage@8572 2277 When <var>A</var> is 1 or -1,
jackalmage@8572 2278 the <code>1</code> may be omitted from the rule.
jackalmage@8116 2279
jackalmage@8116 2280 <div class="example">
jackalmage@8116 2281 <p>Examples:
jackalmage@8116 2282 <p>The following notations are therefore equivalent:
jackalmage@8116 2283 <pre><!--
jackalmage@8116 2284 -->1n+0 /* represents all elements in the list */&#xa;<!--
jackalmage@8116 2285 -->n+0 /* same */&#xa;<!--
jackalmage@8116 2286 -->n /* same */</pre>
jackalmage@8116 2287 </div>
jackalmage@8116 2288
jackalmage@8572 2289 If <var>B</var> is 0, then every <var>A</var>th element is picked.
jackalmage@8572 2290 In such a case,
jackalmage@8572 2291 the <var>+B</var> (or <var>-B</var>) part may be omitted
jackalmage@8572 2292 unless the <var>A</var> part is already omitted.
jackalmage@8116 2293
jackalmage@8116 2294 <div class="example">
jackalmage@8116 2295 <p>Examples:
jackalmage@8116 2296 <pre><!--
jackalmage@8116 2297 -->2n+0 /* represents every even element in the list */&#xa;<!--
jackalmage@8116 2298 -->2n /* same */</pre>
jackalmage@8116 2299 </div>
jackalmage@8116 2300
jackalmage@8572 2301 Whitespace is permitted on either side of the ''+'' or ''-''
jackalmage@8572 2302 that separates the <var>An</var> and <var>B</var> parts when both are present.
jackalmage@8116 2303
jackalmage@8116 2304 <div class="example">
jackalmage@8116 2305 <p>Valid Examples with white space:
jackalmage@8116 2306 <pre><!--
jackalmage@8116 2307 -->3n + 1&#xa;<!--
jackalmage@8116 2308 -->+3n - 2&#xa;<!--
jackalmage@8116 2309 -->-n+ 6&#xa;<!--
jackalmage@8116 2310 -->+6</pre>
jackalmage@8116 2311 <p>Invalid Examples with white space:
jackalmage@8116 2312 <pre><!--
jackalmage@8116 2313 -->3 n&#xa;<!--
jackalmage@8116 2314 -->+ 2n&#xa;<!--
jackalmage@8116 2315 -->+ 2</pre>
jackalmage@8116 2316 </div>
jackalmage@8116 2317
jackalmage@8116 2318
jackalmage@8116 2319 <h3 id="the-anb-type">
jackalmage@8116 2320 The <code>&lt;an+b></code> type</h3>
jackalmage@8116 2321
jackalmage@8572 2322 The <var>An+B</var> notation was originally defined using a slightly different tokenizer than the rest of CSS,
jackalmage@8572 2323 resulting in a somewhat odd definition when expressed in terms of CSS tokens.
jackalmage@8572 2324 This section describes how to recognize the <var>An+B</var> notation in terms of CSS tokens
jackalmage@8572 2325 (thus defining the <var>&lt;an+b></var> type for CSS grammar purposes),
jackalmage@8572 2326 and how to interpret the CSS tokens to obtain values for <var>A</var> and <var>B</var>.
jackalmage@8572 2327
jackalmage@8598 2328 The <var>&lt;an+b></var> type is defined
jackalmage@8598 2329 (using the <a href="http://www.w3.org/TR/css3-values/#value-defs">Value Definition Syntax in the Values &amp; Units spec</a>)
jackalmage@8572 2330 as:
jackalmage@8116 2331
jackalmage@8116 2332 <pre class='prod'>
jackalmage@8572 2333 <dfn id="anb-production">&lt;an+b></dfn> =
jackalmage@8572 2334 odd | even |
jackalmage@8572 2335 <var>&lt;integer></var> |
jackalmage@8572 2336
jackalmage@8572 2337 <var>&lt;n-dimension></var> |
jackalmage@8572 2338 '+'?<sup><a href="#anb-plus">†</a></sup> n |
jackalmage@8572 2339 -n |
jackalmage@8572 2340
jackalmage@8572 2341 <var>&lt;ndashdigit-dimension></var> |
jackalmage@8572 2342 '+'?<sup><a href="#anb-plus">†</a></sup> <var>&lt;ndashdigit-ident></var> |
jackalmage@8572 2343 <var>&lt;dashndashdigit-ident></var> |
jackalmage@8572 2344
jackalmage@8572 2345 <var>&lt;n-dimension></var> <var>&lt;signed-integer></var> |
jackalmage@8572 2346 '+'?<sup><a href="#anb-plus">†</a></sup> n <var>&lt;signed-integer></var> |
jackalmage@8572 2347 -n <var>&lt;signed-integer></var> |
jackalmage@8572 2348
simon@8799 2349 <var>&lt;ndash-dimension></var> <var>&lt;signless-integer></var> |
simon@8799 2350 '+'?<sup><a href="#anb-plus">†</a></sup> n- <var>&lt;signless-integer></var> |
simon@8799 2351 -n- <var>&lt;signless-integer></var> |
simon@8799 2352
jackalmage@8572 2353 <var>&lt;n-dimension></var> ['+' | '-'] <var>&lt;signless-integer></var>
jackalmage@8572 2354 '+'?<sup><a href="#anb-plus">†</a></sup> n ['+' | '-'] <var>&lt;signless-integer></var> |
jackalmage@8572 2355 -n ['+' | '-'] <var>&lt;signless-integer></var>
jackalmage@8572 2356 </pre>
jackalmage@8572 2357
jackalmage@8572 2358 where:
jackalmage@8116 2359
jackalmage@8116 2360 <ul>
jackalmage@8819 2361 <li><dfn><code>&lt;n-dimension></code></dfn> is a <<<dimension>>> with its type flag set to "integer", and a unit that is an <a>ASCII case-insensitive</a> match for "n"
jackalmage@8819 2362 <li><dfn><code>&lt;ndash-dimension></code></dfn> is a <<<dimension>>> with its type flag set to "integer", and a unit that is an <a>ASCII case-insensitive</a> match for "n-"
jackalmage@8819 2363 <li><dfn><code>&lt;ndashdigit-dimension></code></dfn> is a <<<dimension>>> with its type flag set to "integer", and a unit that is an <a>ASCII case-insensitive</a> match for "n-*", where "*" is a series of one or more <a>digits</a>
jackalmage@8819 2364 <li><dfn><code>&lt;ndashdigit-ident></code></dfn> is an <<<ident>>> whose value is an <a>ASCII case-insensitive</a> match for "n-*", where "*" is a series of one or more <a>digits</a>
jackalmage@8819 2365 <li><dfn><code>&lt;dashndashdigit-ident></code></dfn> is an <<<ident>>> whose value is an <a>ASCII case-insensitive</a> match for "-n-*", where "*" is a series of one or more <a>digits</a>
jackalmage@8819 2366 <li><dfn><code>&lt;integer></code></dfn> is a <<<number>>> with its type flag set to "integer"
jackalmage@8819 2367 <li><dfn><code>&lt;signed-integer></code></dfn> is a <<<number>>> with its type flag set to "integer", and whose representation starts with "+" or "-"
jackalmage@8819 2368 <li><dfn><code>&lt;signless-integer></code></dfn> is a <<<number>>> with its type flag set to "integer", and whose representation start with a <a>digit</a>
jackalmage@8116 2369 </ul>
jackalmage@8116 2370
jackalmage@8572 2371 <p id="anb-plus">
jackalmage@8572 2372 <sup>†</sup>: When a plus sign (+) precedes an ident starting with "n", as in the cases marked above,
jackalmage@8571 2373 there must be no whitespace between the two tokens,
jackalmage@8571 2374 or else the tokens do not match the above grammar.
jackalmage@8571 2375
jackalmage@8572 2376 The clauses of the production are interpreted as follows:
jackalmage@8116 2377
jackalmage@8116 2378 <dl>
jackalmage@8116 2379 <dt>''odd''
jackalmage@8116 2380 <dd>
jackalmage@8116 2381 <var>A</var> is 2, <var>B</var> is 1.
jackalmage@8116 2382
jackalmage@8116 2383 <dt>''even''
jackalmage@8116 2384 <dd>
jackalmage@8116 2385 <var>A</var> is 2, <var>B</var> is 0.
jackalmage@8116 2386
jackalmage@8143 2387 <dt><code><var>&lt;integer></var></code>
jackalmage@8116 2388 <dd>
simon@8475 2389 <var>A</var> is 0, <var>B</var> is the integer’s value.
jackalmage@8116 2390
jackalmage@8143 2391 <dt><code><var>&lt;n-dimension></var></code>
jackalmage@8143 2392 <dt><code>'+'? n</code>
jackalmage@8143 2393 <dt><code>-n</code>
jackalmage@8116 2394 <dd>
simon@8475 2395 <var>A</var> is the dimension's value, 1, or -1, respectively.
simon@8475 2396 <var>B</var> is 0.
jackalmage@8143 2397
jackalmage@8143 2398 <dt><code><var>&lt;ndashdigit-dimension></var></code>
jackalmage@8143 2399 <dt><code>'+'? <var>&lt;ndashdigit-ident></var></code>
simon@8475 2400 <dd>
simon@8475 2401 <var>A</var> is the dimension's value or 1, respectively.
simon@8475 2402 <var>B</var> is the dimension's unit or ident's value, respectively,
simon@8830 2403 with the first <a>code point</a> removed and the remainder interpreted as a base-10 number.
simon@8475 2404 <span class=note>B is negative.</span>
simon@8475 2405
jackalmage@8143 2406 <dt><code><var>&lt;dashndashdigit-ident></var></code>
jackalmage@8116 2407 <dd>
simon@8475 2408 <var>A</var> is -1.
simon@8830 2409 <var>B</var> is the ident's value, with the first two <a>code points</a> removed and the remainder interpreted as a base-10 number.
simon@8475 2410 <span class=note>B is negative.</span>
jackalmage@8143 2411
jackalmage@8143 2412 <dt><code><var>&lt;n-dimension></var> <var>&lt;signed-integer></var></code>
jackalmage@8143 2413 <dt><code>'+'? n <var>&lt;signed-integer></var></code>
jackalmage@8143 2414 <dt><code>-n <var>&lt;signed-integer></var></code>
jackalmage@8116 2415 <dd>
simon@8475 2416 <var>A</var> is the dimension's value, 1, or -1, respectively.
simon@8475 2417 <var>B</var> is the integer’s value.
jackalmage@8143 2418
simon@8799 2419 <dt><code><var>&lt;ndash-dimension></var> <var>&lt;signless-integer></var></code>
simon@8799 2420 <dt><code>'+'? n- <var>&lt;signless-integer></var></code>
simon@8799 2421 <dt><code>-n- <var>&lt;signless-integer></var></code>
simon@8799 2422 <dd>
simon@8799 2423 <var>A</var> is the dimension's value, 1, or -1, respectively.
simon@8799 2424 <var>B</var> is the negation of the integer’s value.
simon@8799 2425
jackalmage@8143 2426 <dt><code><var>&lt;n-dimension></var> ['+' | '-'] <var>&lt;signless-integer></var></code>
jackalmage@8143 2427 <dt><code>'+'? n ['+' | '-'] <var>&lt;signless-integer></var></code>
jackalmage@8143 2428 <dt><code>-n ['+' | '-'] <var>&lt;signless-integer></var></code>
jackalmage@8116 2429 <dd>
simon@8475 2430 <var>A</var> is the dimension's value, 1, or -1, respectively.
simon@8475 2431 <var>B</var> is the integer’s value.
simon@8475 2432 If a '-' was provided between the two, <var>B</var> is instead the negation of the integer’s value.
jackalmage@8116 2433 </dl>
jackalmage@8116 2434
jackalmage@8116 2435
jackalmage@8116 2436
jackalmage@8273 2437 <h2 id='rule-defs'>
jackalmage@8210 2438 Defining Grammars for Rules and Other Values</h2>
jackalmage@8210 2439
jackalmage@8572 2440 The <a href="http://www.w3.org/TR/css3-values/">Values</a> spec defines how to specify a grammar for properties.
jackalmage@8572 2441 This section does the same, but for rules.
jackalmage@8572 2442
jackalmage@8572 2443 Just like in property grammars,
jackalmage@8572 2444 the notation <code>&lt;foo></code> refers to the "foo" grammar term,
jackalmage@8572 2445 assumed to be defined elsewhere.
jackalmage@8572 2446 Substituting the <code>&lt;foo></code> for its definition results in a semantically identical grammar.
jackalmage@8572 2447
jackalmage@8572 2448 Several types of tokens are written literally, without quotes:
jackalmage@8210 2449
jackalmage@8210 2450 <ul>
jackalmage@8819 2451 <li><<<ident>>>s (such as ''auto'', ''disc'', etc), which are simply written as their value.
jackalmage@8819 2452 <li><<<at-keyword>>>s, which are written as an @ character followed by the token's value, like "@media".
jackalmage@8819 2453 <li><<<function>>>s, which are written as the function name followed by a ( character, like "translate(".
jackalmage@8819 2454 <li>The <<<colon>>> (written as <code>:</code>), <<<comma>>> (written as <code>,</code>), <<<semicolon>>> (written as <code>;</code>), <<<(>>>, <<<)>>>, <<<{>>>, and <<<}>>>s.
jackalmage@8210 2455 </ul>
jackalmage@8210 2456
simon@8752 2457 Tokens match if their value is an <a>ASCII case-insensitive</a> match
simon@8752 2458 for the value defined in the grammar.
simon@8752 2459
simon@8752 2460 <p class=note>
simon@8752 2461 Although it is possible, with <a>escaping</a>,
jackalmage@8819 2462 to construct an <<<ident>>> whose value starts with <code>@</code> or ends with <code>(</code>,
jackalmage@8819 2463 such a tokens is not an <<<at-keyword>>> or a <<<function>>>
simon@8752 2464 and does not match corresponding grammar definitions.
simon@8752 2465
jackalmage@8819 2466 <<<delim>>>s are written with their value enclosed in single quotes.
simon@8830 2467 For example, a <<<delim>>> containing the "+" <a>code point</a> is written as <code>'+'</code>.
jackalmage@8819 2468 Similarly, the <<<[>>> and <<<]>>>s must be written in single quotes,
jackalmage@8572 2469 as they're used by the syntax of the grammar itself to group clauses.
jackalmage@8819 2470 <<<whitespace>>> is never indicated in the grammar;
jackalmage@8819 2471 <<<whitespace>>>s are allowed before, after, and between any two tokens,
jackalmage@8572 2472 unless explicitly specified otherwise in prose definitions.
jackalmage@8572 2473 (For example, if the prelude of a rule is a selector,
jackalmage@8572 2474 whitespace is significant.)
jackalmage@8572 2475
jackalmage@8572 2476 When defining a function or a block,
jackalmage@8572 2477 the ending token must be specified in the grammar,
jackalmage@8572 2478 but if it's not present in the eventual token stream,
jackalmage@8572 2479 it still matches.
jackalmage@8210 2480
jackalmage@8210 2481 <div class='example'>
jackalmage@8210 2482 For example, the syntax of the ''translateX()'' function is:
jackalmage@8210 2483
jackalmage@8743 2484 <pre>translateX( <<translation-value>> )</pre>
jackalmage@8210 2485
jackalmage@8572 2486 However, the stylesheet may end with the function unclosed, like:
jackalmage@8210 2487
jackalmage@8210 2488 <pre>.foo { transform: translate(50px</pre>
jackalmage@8210 2489
jackalmage@8572 2490 The CSS parser parses this as a style rule containing one declaration,
jackalmage@8572 2491 whose value is a function named "translate".
jackalmage@8572 2492 This matches the above grammar,
jackalmage@8572 2493 even though the ending token didn't appear in the token stream,
jackalmage@8572 2494 because by the time the parser is finished,
jackalmage@8572 2495 the presence of the ending token is no longer possible to determine;
jackalmage@8572 2496 all you have is the fact that there's a block and a function.
jackalmage@8210 2497 </div>
jackalmage@8210 2498
jackalmage@8210 2499 <h3 id='declaration-rule-list'>
jackalmage@8743 2500 Defining Block Contents: the <<declaration-list>>, <<rule-list>>, and <<stylesheet>> productions</h3>
jackalmage@8210 2501
jackalmage@8572 2502 The CSS parser is agnostic as to the contents of blocks,
jackalmage@8572 2503 such as those that come at the end of some at-rules.
jackalmage@8572 2504 Defining the generic grammar of the blocks in terms of tokens is non-trivial,
jackalmage@8572 2505 but there are dedicated and unambiguous algorithms defined for parsing this.
jackalmage@8572 2506
jackalmage@8743 2507 The <dfn>&lt;declaration-list></dfn> production represents a list of declarations.
jackalmage@8572 2508 It may only be used in grammars as the sole value in a block,
jackalmage@8572 2509 and represents that the contents of the block must be parsed using the <a>consume a list of declarations</a> algorithm.
jackalmage@8572 2510
jackalmage@8743 2511 Similarly, the <dfn>&lt;rule-list></dfn> production represents a list of rules,
jackalmage@8572 2512 and may only be used in grammars as the sole value in a block.
jackalmage@8572 2513 It represents that the contents of the block must be parsed using the <a>consume a list of rules</a> algorithm.
jackalmage@8572 2514
jackalmage@8743 2515 Finally, the <dfn>&lt;stylesheet></dfn> production represents a list of rules.
jackalmage@8743 2516 It is identical to <<rule-list>>,
jackalmage@8572 2517 except that blocks using it default to accepting all rules
jackalmage@8572 2518 that aren't otherwise limited to a particular context.
jackalmage@8210 2519
jackalmage@8210 2520 <div class='example'>
jackalmage@8598 2521 For example, the ''@font-face'' rule is defined to have an empty prelude,
jackalmage@8210 2522 and to contain a list of declarations.
jackalmage@8210 2523 This is expressed with the following grammar:
jackalmage@8210 2524
jackalmage@8743 2525 <pre>@font-face { <<declaration-list>> }</pre>
jackalmage@8210 2526
jackalmage@8572 2527 This is a complete and sufficient definition of the rule's grammar.
jackalmage@8572 2528
jackalmage@8572 2529 For another example,
jackalmage@8572 2530 ''@keyframes'' rules are more complex,
jackalmage@8572 2531 interpreting their prelude as a name and containing keyframes rules in their block
jackalmage@8572 2532 Their grammar is:
jackalmage@8210 2533
jackalmage@8743 2534 <pre>@keyframes <<keyframes-name>> { <<rule-list>> }</pre>
jackalmage@8210 2535 </div>
jackalmage@8210 2536
jackalmage@8743 2537 For rules that use <<declaration-list>>,
jackalmage@8572 2538 the spec for the rule must define which properties, descriptors, and/or at-rules are valid inside the rule;
jackalmage@8572 2539 this may be as simple as saying "The @foo rule accepts the properties/descriptors defined in this specification/section.",
jackalmage@8572 2540 and extension specs may simply say "The @foo rule additionally accepts the following properties/descriptors.".
jackalmage@8572 2541 Any declarations or at-rules found inside the block that are not defined as valid
jackalmage@8572 2542 must be removed from the rule's value.
jackalmage@8572 2543
jackalmage@8743 2544 Within a <<declaration-list>>,
jackalmage@8572 2545 <code>!important</code> is automatically invalid on any descriptors.
jackalmage@8572 2546 If the rule accepts properties,
jackalmage@8572 2547 the spec for the rule must define whether the properties interact with the cascade,
jackalmage@8572 2548 and with what specificity.
jackalmage@8598 2549 If they don't interact with the cascade,
jackalmage@8572 2550 properties containing <code>!important</code> are automatically invalid;
jackalmage@8572 2551 otherwise using <code>!important</code> is valid and has its usual effect on the cascade origin of the property.
jackalmage@8210 2552
jackalmage@8211 2553 <div class='example'>
jackalmage@8211 2554 For example, the grammar for ''@font-face'' in the previous example must,
jackalmage@8211 2555 in addition to what is written there,
jackalmage@8211 2556 define that the allowed declarations are the descriptors defined in the Fonts spec.
jackalmage@8211 2557 </div>
jackalmage@8211 2558
jackalmage@8743 2559 For rules that use <<rule-list>>,
jackalmage@8572 2560 the spec for the rule must define what types of rules are valid inside the rule,
jackalmage@8743 2561 same as <<declaration-list>>,
jackalmage@8572 2562 and unrecognized rules must similarly be removed from the rule's value.
jackalmage@8210 2563
jackalmage@8210 2564 <div class='example'>
jackalmage@8211 2565 For example, the grammar for ''@keyframes'' in the previous example must,
jackalmage@8210 2566 in addition to what is written there,
jackalmage@8743 2567 define that the only allowed rules are <<keyframe-rule>>s,
jackalmage@8210 2568 which are defined as:
jackalmage@8210 2569
jackalmage@8743 2570 <pre><<keyframe-rule>> = <<keyframe-selector>> { <<declaration-list>> }</pre>
jackalmage@8210 2571
jackalmage@8572 2572 Keyframe rules, then,
jackalmage@8572 2573 must further define that they accept as declarations all animatable CSS properties,
jackalmage@8572 2574 plus the 'animation-timing-function' property,
jackalmage@8572 2575 but that they do not interact with the cascade.
jackalmage@8210 2576 </div>
jackalmage@8210 2577
jackalmage@8743 2578 For rules that use <<stylesheet>>,
jackalmage@8572 2579 all rules are allowed by default,
jackalmage@8572 2580 but the spec for the rule may define what types of rules are <em>invalid</em> inside the rule.
jackalmage@8210 2581
jackalmage@8210 2582 <div class='example'>
jackalmage@8210 2583 For example, the ''@media'' rule accepts anything that can be placed in a stylesheet,
jackalmage@8210 2584 except more ''@media'' rules.
jackalmage@8210 2585 As such, its grammar is:
jackalmage@8210 2586
jackalmage@8743 2587 <pre>@media <<media-query-list>> { <<stylesheet>> }</pre>
jackalmage@8743 2588
jackalmage@8743 2589 It additionally defines a restriction that the <<stylesheet>> can not contain ''@media'' rules,
jackalmage@8572 2590 which causes them to be dropped from the outer rule's value if they appear.
jackalmage@8210 2591 </div>
jackalmage@8116 2592
jackalmage@8116 2593
jackalmage@8743 2594 <h2>
jackalmage@8743 2595 CSS stylesheets</h2>
simon@8741 2596
jackalmage@8744 2597 To parse a CSS stylesheet,
jackalmage@8744 2598 first <i>parse a stylesheet</i>.
jackalmage@8744 2599 Interpret all of the resulting top-level <i>qualified rules</i> as <i>style rules</i>, defined below.
jackalmage@8744 2600
jackalmage@8744 2601 If any style rule is invalid,
jackalmage@8744 2602 or any at-rule is not recognized or is invalid according to its grammar or context,
jackalmage@8744 2603 it's a <i>parse error</i>.
jackalmage@8744 2604 Discard that rule.
simon@8741 2605
jackalmage@8743 2606 <h3>
jackalmage@8743 2607 Style rules</h3>
simon@8741 2608
jackalmage@8744 2609 A <dfn>style rule</dfn> is a <i>qualified rule</i>
jackalmage@8744 2610 that associates a <a href="http://dev.w3.org/csswg/selectors4/#selector-list">selector list</a> [[!SELECT]]
jackalmage@8744 2611 with a list of property declarations.
jackalmage@8744 2612 They are also called
jackalmage@8744 2613 <a href="http://www.w3.org/TR/CSS21/syndata.html#rule-sets">rule sets</a> in [[!CSS21]].
jackalmage@8744 2614 CSS Cascading and Inheritance [[!CSS3CASCADE]] defines how the declarations inside of style rules participate in the cascade.
jackalmage@8744 2615
jackalmage@8744 2616 The prelude of the qualified rule is parsed as a
jackalmage@8744 2617 <a href="http://dev.w3.org/csswg/selectors4/#selector-list">selector list</a>.
simon@8750 2618 If this results in an <a href="http://dev.w3.org/csswg/selectors4/#invalid">invalid selector list</a>,
jackalmage@8744 2619 the entire style rule is invalid.
jackalmage@8744 2620
jackalmage@8744 2621 The content of the qualified rule’s block is parsed as a
jackalmage@8744 2622 <i title="parse a list of declarations">list of declarations</i>.
jackalmage@8744 2623 Unless defined otherwise by another specification or a future level of this specification,
jackalmage@8744 2624 at-rules in that list are invalid
jackalmage@8744 2625 and must be ignored.
jackalmage@8744 2626 Declaration for an unknown CSS property
jackalmage@8744 2627 or whose value does not match the syntax defined by the property are invalid
jackalmage@8744 2628 and must be ignored.
jackalmage@8744 2629 The validity of the style rule’s contents have no effect on the validity of the style rule itself.
jackalmage@8744 2630 Unless otherwise specified, property names are <i>ASCII case-insensitive</i>.
jackalmage@8744 2631
jackalmage@8744 2632 Note: The names of Custom Properties [[CSS-VARIABLES]] are case-sensitive.
jackalmage@8744 2633
jackalmage@8744 2634 <i>Qualified rules</i> at the top-level of a CSS stylesheet are style rules.
jackalmage@8744 2635 Qualified rules in other contexts may or may not be style rules,
jackalmage@8744 2636 as defined by the context.
jackalmage@8744 2637
jackalmage@8744 2638 <p class='example'>
jackalmage@8744 2639 For example, qualified rules inside ''@media'' rules [[CSS3-CONDITIONAL]] are style rules,
jackalmage@8744 2640 but qualified rules inside ''@keyframes'' rules are not [[CSS3-ANIMATIONS]].
simon@8741 2641
jackalmage@8743 2642 <h3>
jackalmage@8744 2643 The ''@charset'' Rule</h3>
jackalmage@8744 2644
jackalmage@8744 2645 The <dfn>''@charset''</dfn> rule is a very special <i>at-rule</i> associated with determining the character encoding of the stylesheet.
jackalmage@8744 2646 In general, its grammar is:
jackalmage@8744 2647
jackalmage@8744 2648 <pre class='prod'><dfn>&lt;at-charset-rule></dfn> = @charset <<string>>;</pre>
jackalmage@8744 2649
jackalmage@8744 2650 Additionally, an ''@charset'' rule is invalid if it is not at the top-level of a stylesheet,
simon@8750 2651 or if it is not the very first rule of a stylesheet.
jackalmage@8744 2652
jackalmage@8744 2653 ''@charset'' rules have an <dfn>encoding</dfn>,
jackalmage@8744 2654 given by the value of the <<string>>.
jackalmage@8744 2655
jackalmage@8744 2656 The ''@charset'' rule has <strong>no effect on a stylesheet</strong>.
jackalmage@8744 2657
jackalmage@8744 2658 Note: However, the algorithm to <a>determine the fallback encoding</a>
jackalmage@8744 2659 looks at the first several bytes of the stylesheet
jackalmage@8744 2660 to see if they're a match for the ASCII characters <code>@charset "XXX";</code>,
jackalmage@8744 2661 where XXX is a sequence of bytes other than 22 (ASCII for <code>"</code>).
jackalmage@8744 2662 While this resembles an ''@charset'' rule,
jackalmage@8744 2663 it's not actually the same thing.
jackalmage@8744 2664 For example, the necessary sequence of bytes will spell out something entirely different
jackalmage@8744 2665 if the stylesheet is in an encoding that's not ASCII-compatible,
jackalmage@8744 2666 such as UTF-16.
jackalmage@8744 2667
jackalmage@8116 2668
jackalmage@7285 2669
jackalmage@8743 2670 <h2>
jackalmage@8743 2671 Serialization</h2>
jackalmage@7217 2672
jackalmage@8572 2673 This specification does not define how to serialize CSS in general,
jackalmage@8572 2674 leaving that task to the CSSOM and individual feature specifications.
jackalmage@8572 2675 However, there is one important facet that must be specified here regarding comments,
jackalmage@8572 2676 to ensure accurate "round-tripping" of data from text to CSS objects and back.
jackalmage@8572 2677
jackalmage@8572 2678 The tokenizer described in this specification does not produce tokens for comments,
jackalmage@8572 2679 or otherwise preserve them in any way.
jackalmage@8572 2680 Implementations may preserve the contents of comments and their location in the token stream.
jackalmage@8572 2681 If they do, this preserved information must have no effect on the parsing step,
jackalmage@8572 2682 but must be serialized in its position as
jackalmage@8572 2683 "/*"
jackalmage@8572 2684 followed by its contents
jackalmage@8572 2685 followed by "*/".
jackalmage@8572 2686
jackalmage@8572 2687 If the implementation does not preserve comments,
jackalmage@8572 2688 it must insert the text "/**/" between the serialization of adjacent tokens
jackalmage@8572 2689 when the two tokens are of the following pairs:
jackalmage@7217 2690
jackalmage@7217 2691 <ul>
jackalmage@7217 2692 <li>
jackalmage@8819 2693 a <<<hash>>> or <<<at-keyword>>> followed by a <<<number>>>, <<<percentage>>>, <<<ident>>>, <<<dimension>>>, <<<unicode-range>>>, <<<url>>>, or a <<<function>>> token;
jackalmage@7217 2694
jackalmage@7217 2695 <li>
jackalmage@8819 2696 <<<number>>>s, <<<ident>>>s, and <<<dimension>>>s in any combination;
jackalmage@7217 2697
jackalmage@7217 2698 <li>
jackalmage@8819 2699 a <<<number>>>, <<<ident>>>, or <<<dimension>>> followed by a <<<percentage>>>, <<<unicode-range>>>, <<<url>>>, or <<<function>>>;
jackalmage@7217 2700
jackalmage@7217 2701 <li>
jackalmage@8819 2702 an <<<ident>>> followed by a <<<(>>>;
jackalmage@7219 2703
jackalmage@7219 2704 <li>
jackalmage@8819 2705 a <<<delim>>> containing "#" or "@" followed by any token except <<<whitespace>>>;
jackalmage@7219 2706
jackalmage@7219 2707 <li>
jackalmage@8819 2708 a <<<delim>>> containing "-", "+", ".", "&lt;", ">", or "!" following or followed by any token except <<<whitespace>>>;
jackalmage@7219 2709
jackalmage@7219 2710 <li>
jackalmage@8819 2711 a <<<delim>>> containing "/" following or followed by a <<<delim>>> containing "*".
jackalmage@7217 2712 </ul>
jackalmage@7217 2713
jackalmage@8572 2714 Note: The preceding pairs of tokens can only be adjacent due to comments in the original text,
jackalmage@8572 2715 so the above rule reinserts the minimum number of comments into the serialized text to ensure an accurate round-trip.
jackalmage@8819 2716 (Roughly. The <<<delim>>> rules are slightly too powerful, for simplicity.)
jackalmage@5964 2717
simon@8952 2718 Note: No comment is inserted between consecutive <<<whitespace>>>.
simon@8952 2719 As a consequence such token sequences will not "round-trip" exactly.
simon@8952 2720 This shouldn’t be an issue as CSS grammars always interpret
simon@8952 2721 any amount of whitespace as identical to a single space.
simon@8952 2722
jackalmage@8148 2723 <h3 id='serializing-anb'>
jackalmage@8148 2724 Serializing <var>&lt;an+b></var></h3>
jackalmage@8572 2725
jackalmage@8572 2726 To serialize an <var>&lt;an+b></var> value,
jackalmage@8572 2727 let <var>s</var> initially be the empty string:
jackalmage@8207 2728
jackalmage@8207 2729 <dl>
jackalmage@8207 2730 <dt><var>A</var> and <var>B</var> are both zero
jackalmage@8207 2731 <dd>
jackalmage@8207 2732 Append "0" to <var>s</var>.
jackalmage@8207 2733
jackalmage@8207 2734 <dt><var>A</var> is zero, <var>B</var> is non-zero
jackalmage@8207 2735 <dd>
jackalmage@8207 2736 Serialize <var>B</var> and append it to <var>s</var>.
jackalmage@8207 2737
jackalmage@8207 2738 <dt><var>A</var> is non-zero, <var>B</var> is zero
jackalmage@8207 2739 <dd>
jackalmage@8207 2740 Serialize <var>A</var> and append it to <var>s</var>.
jackalmage@8207 2741 Append "n" to <var>s</var>.
jackalmage@8207 2742
jackalmage@8207 2743 <dt><var>A</var> and <var>B</var> are both non-zero
jackalmage@8207 2744 <dd>
jackalmage@8207 2745 Serialize <var>A</var> and append it to <var>s</var>.
jackalmage@8207 2746 Append "n" to <var>s</var>.
jackalmage@8207 2747 If <var>B</var> is positive,
jackalmage@8209 2748 append "+" to <var>s</var>
jackalmage@8207 2749 Serialize <var>B</var> and append it to <var>s</var>.
jackalmage@8207 2750 </dl>
jackalmage@8207 2751
jackalmage@8207 2752 Return <var>s</var>.
jackalmage@8207 2753
simon@8323 2754 <h2 id="changes">Changes from CSS 2.1 and Selectors Level 3</h2>
simon@8323 2755
jackalmage@8572 2756 <em>This section is non-normative.</em>
jackalmage@8572 2757
jackalmage@8572 2758 Note: The point of this spec is to match reality;
jackalmage@8572 2759 changes from CSS2.1 are nearly always because CSS 2.1 specified something that doesn't match actual browser behavior,
jackalmage@8572 2760 or left something unspecified.
jackalmage@8572 2761 If some detail doesn't match browsers,
jackalmage@8572 2762 please let me know
jackalmage@8572 2763 as it's almost certainly unintentional.
jackalmage@8572 2764
jackalmage@8572 2765 Changes in decoding from a byte stream:
jackalmage@8572 2766
simon@8323 2767 <ul>
simon@8323 2768 <li>
simon@8323 2769 Only detect ''@charset'' rules in ASCII-compatible byte patterns.
simon@8323 2770
simon@8323 2771 <li>
simon@8323 2772 Ignore ''@charset'' rules that specify an ASCII-incompatible encoding,
simon@8323 2773 as that would cause the rule itself to not decode properly.
simon@8323 2774
simon@8323 2775 <li>
simon@8323 2776 Refer to the the <a href="http://encoding.spec.whatwg.org/">Encoding Standard</a>
simon@8323 2777 rather than the IANA registery for character encodings.
simon@8323 2778
simon@8323 2779 </ul>
simon@8323 2780
jackalmage@8572 2781 Tokenization changes:
simon@8323 2782
simon@8323 2783 <ul>
simon@8323 2784 <li>
simon@8830 2785 Any U+0000 NULL <a>code point</a> in the CSS source is replaced with U+FFFD REPLACEMENT CHARACTER.
simon@8323 2786
simon@8323 2787 <li>
simon@8323 2788 Any hexadecimal escape sequence such as ''\0'' that evaluate to zero
simon@8830 2789 produce U+FFFD REPLACEMENT r rather than U+0000 NULL.
simon@8323 2790 <!--
simon@8323 2791 This covers a security issue:
simon@8323 2792 https://bugzilla.mozilla.org/show_bug.cgi?id=228856
simon@8323 2793 -->
jackalmage@8572 2794
simon@8323 2795 <li>
simon@8830 2796 The definition of <a>non-ASCII code point</a> was changed
simon@8323 2797 to be consistent with every definition of ASCII.
simon@8830 2798 This affects <a>code points</a> U+0080 to U+009F,
simon@8830 2799 which are now <a>name code points</a> rather than <<<delim>>>s,
simon@8830 2800 like the rest of <a>non-ASCII code points</a>.
simon@8323 2801
simon@8323 2802 <li>
simon@8323 2803 Tokenization does not emit COMMENT or BAD_COMMENT tokens anymore.
simon@8323 2804 BAD_COMMENT is now considered the same as normal token (not an error.)
jackalmage@8598 2805 <a href="#serialization">Serialization</a> is responsible
simon@8323 2806 for inserting comments as necessary between tokens that need to be separated,
jackalmage@8819 2807 e.g. two consecutive <<<ident>>>s.
simon@8323 2808
simon@8323 2809 <li>
simon@8323 2810 Apply the <a href="http://www.w3.org/TR/CSS21/syndata.html#unexpected-eof">EOF error handling rule</a> in the tokenizer
jackalmage@8819 2811 and emit normal <<<string>>> and <<<url>>> tokens rather than BAD_STRING or BAD_URI
simon@8323 2812 on EOF.
simon@8323 2813
simon@8323 2814 <li>
jackalmage@8819 2815 The <<<prefix-match>>>, <<<suffix-match>>>, and <<<substring-match>>> tokens have been imported from Selectors 3.
simon@8323 2816
simon@8323 2817 <li>
jackalmage@8819 2818 The BAD_URI token (now <<<bad-url>>>) is "self-contained".
jackalmage@8819 2819 In other words, once the tokenizer realizes it's in a <<<bad-url>>> rather than a <<<url>>>,
simon@8323 2820 it just seeks forward to look for the closing ),
simon@8323 2821 ignoring everything else.
jackalmage@8819 2822 This behavior is simpler than treating it like a <<<function>>>
simon@8323 2823 and paying attention to opened blocks and such.
simon@8323 2824 Only WebKit exhibits this behavior,
simon@8323 2825 but it doesn't appear that we've gotten any compat bugs from it.
simon@8323 2826
simon@8323 2827 <li>
jackalmage@8819 2828 The <<<comma>>> has been added.
simon@8323 2829
simon@8323 2830 <li>
jackalmage@8819 2831 The <<<number>>>, <<<number>>>, and <<<dimension>>> tokens have been changed
simon@8323 2832 to include the preceding +/- sign as part of their value
jackalmage@8819 2833 (rather than as a separate <<<delim>>> that needs to be manually handled every time the token is mentioned in other specs).
simon@8323 2834 The only consequence of this is that comments can no longer be inserted between the sign and the number.
simon@8323 2835
simon@8323 2836 <li>
simon@8323 2837 Scientific notation is supported for numbers/percentages/dimensions to match SVG,
simon@8323 2838 per WG resolution.
simon@8323 2839
simon@8323 2840 <li>
jackalmage@8819 2841 <<<column>>> has been added,
simon@8323 2842 to keep Selectors parsing in single-token lookahead.
simon@8323 2843
simon@8834 2844 <li>
simon@8834 2845 Hexadecimal escape for <a>surrogate code points</a> now emit a replacement character rather than the surrogate.
simon@8834 2846 This allows implementations to safely use UTF-16 internally.
simon@8834 2847
simon@8323 2848 </ul>
simon@8323 2849
jackalmage@8572 2850 Parsing changes:
simon@8323 2851
simon@8323 2852 <ul>
simon@8323 2853 <li>
simon@8323 2854 Any list of declaration now also accepts at-rules, like ''@page'',
simon@8323 2855 per WG resolution.
jackalmage@8598 2856 This makes a difference in error handling
simon@8323 2857 even if no such at-rules are defined yet:
simon@8323 2858 an at-rule, valid or not, ends and lets the next declaration being
jackalmage@8819 2859 at a {} block without a <<<semicolon>>>.
simon@8323 2860
simon@8323 2861 <li>
simon@8323 2862 The handling of some miscellanous "special" tokens
jackalmage@8819 2863 (like an unmatched <<<}>>>)
simon@8323 2864 showing up in various places in the grammar
simon@8323 2865 has been specified with some reasonable behavior shown by at least one browser.
simon@8323 2866 Previously, stylesheets with those tokens in those places just didn't match the stylesheet grammar at all,
simon@8323 2867 so their handling was totally undefined.
simon@8323 2868 Specifically:
simon@8323 2869
simon@8323 2870 <ul>
simon@8323 2871 <li>
jackalmage@8819 2872 [] blocks, () blocks and functions can now contain {} blocks, <<<at-keyword>>>s or <<<semicolon>>>s
simon@8323 2873
simon@8323 2874 <li>
simon@8361 2875 Qualified rule preludes can now contain semicolons
simon@8323 2876
simon@8323 2877 <li>
jackalmage@8819 2878 Qualified rule and at-rule preludes can now contain <<<at-keyword>>>s
simon@8323 2879 </ul>
simon@8323 2880
simon@8323 2881 </ul>
simon@8323 2882
jackalmage@8572 2883 <var>An+B</var> changes from Selectors Level 3 [[SELECT]]:
simon@8323 2884
simon@8323 2885 <ul>
simon@8323 2886 <li>
simon@8323 2887 The <var>An+B</var> microsyntax has now been formally defined in terms of CSS tokens,
simon@8323 2888 rather than with a separate tokenizer.
simon@8323 2889 This has resulted in minor differences:
simon@8323 2890
simon@8323 2891 <ul>
simon@8323 2892 <li>
simon@8830 2893 In some cases, minus signs or digits can be escaped
jackalmage@8819 2894 (when they appear as part of the unit of a <<<dimension>>> or <<<ident>>>).
simon@8323 2895 </ul>
simon@8584 2896 </ul>
simon@8597 2897
simon@8597 2898 <h2 class=no-num id="acknowledgments">
simon@8597 2899 Acknowledgments</h2>
simon@8597 2900
simon@8597 2901 <p>
simon@8597 2902 Thanks for feedback and contributions from
simon@8597 2903 David Baron,
simon@8604 2904 呂康豪 (Kang-Hao Lu),
simon@8604 2905 and Marc O'Morain.

mercurial