Sun, 01 Sep 2013 16:18:24 +0100
[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><a></code> elements that are children of a <code><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 & 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 — |
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><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><link></code> element or <code><?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">'</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 ' \ 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">'</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 " ' ( ) \ 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"><!--</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">--></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 <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 (') |
jackalmage@5473 | 692 | <dd> |
simon@8830 | 693 | <a>Consume a string token</a> with the ending <a>code point</a> U+0027 APOSTROPHE (') |
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 (<) |
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 ('), |
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 (') |
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 */
<!-- |
jackalmage@8116 | 2240 | -->even /* same */
<!-- |
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 */
<!-- |
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 */
<!-- |
jackalmage@8116 | 2285 | -->n+0 /* same */
<!-- |
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 */
<!-- |
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
<!-- |
jackalmage@8116 | 2308 | -->+3n - 2
<!-- |
jackalmage@8116 | 2309 | -->-n+ 6
<!-- |
jackalmage@8116 | 2310 | -->+6</pre> |
jackalmage@8116 | 2311 | <p>Invalid Examples with white space: |
jackalmage@8116 | 2312 | <pre><!-- |
jackalmage@8116 | 2313 | -->3 n
<!-- |
jackalmage@8116 | 2314 | -->+ 2n
<!-- |
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><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><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><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 & Units spec</a>) |
jackalmage@8572 | 2330 | as: |
jackalmage@8116 | 2331 | |
jackalmage@8116 | 2332 | <pre class='prod'> |
jackalmage@8572 | 2333 | <dfn id="anb-production"><an+b></dfn> = |
jackalmage@8572 | 2334 | odd | even | |
jackalmage@8572 | 2335 | <var><integer></var> | |
jackalmage@8572 | 2336 | |
jackalmage@8572 | 2337 | <var><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><ndashdigit-dimension></var> | |
jackalmage@8572 | 2342 | '+'?<sup><a href="#anb-plus">†</a></sup> <var><ndashdigit-ident></var> | |
jackalmage@8572 | 2343 | <var><dashndashdigit-ident></var> | |
jackalmage@8572 | 2344 | |
jackalmage@8572 | 2345 | <var><n-dimension></var> <var><signed-integer></var> | |
jackalmage@8572 | 2346 | '+'?<sup><a href="#anb-plus">†</a></sup> n <var><signed-integer></var> | |
jackalmage@8572 | 2347 | -n <var><signed-integer></var> | |
jackalmage@8572 | 2348 | |
simon@8799 | 2349 | <var><ndash-dimension></var> <var><signless-integer></var> | |
simon@8799 | 2350 | '+'?<sup><a href="#anb-plus">†</a></sup> n- <var><signless-integer></var> | |
simon@8799 | 2351 | -n- <var><signless-integer></var> | |
simon@8799 | 2352 | |
jackalmage@8572 | 2353 | <var><n-dimension></var> ['+' | '-'] <var><signless-integer></var> |
jackalmage@8572 | 2354 | '+'?<sup><a href="#anb-plus">†</a></sup> n ['+' | '-'] <var><signless-integer></var> | |
jackalmage@8572 | 2355 | -n ['+' | '-'] <var><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><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><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><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><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><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><integer></code></dfn> is a <<<number>>> with its type flag set to "integer" |
jackalmage@8819 | 2367 | <li><dfn><code><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><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><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><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><ndashdigit-dimension></var></code> |
jackalmage@8143 | 2399 | <dt><code>'+'? <var><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><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><n-dimension></var> <var><signed-integer></var></code> |
jackalmage@8143 | 2413 | <dt><code>'+'? n <var><signed-integer></var></code> |
jackalmage@8143 | 2414 | <dt><code>-n <var><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><ndash-dimension></var> <var><signless-integer></var></code> |
simon@8799 | 2420 | <dt><code>'+'? n- <var><signless-integer></var></code> |
simon@8799 | 2421 | <dt><code>-n- <var><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><n-dimension></var> ['+' | '-'] <var><signless-integer></var></code> |
jackalmage@8143 | 2427 | <dt><code>'+'? n ['+' | '-'] <var><signless-integer></var></code> |
jackalmage@8143 | 2428 | <dt><code>-n ['+' | '-'] <var><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><foo></code> refers to the "foo" grammar term, |
jackalmage@8572 | 2445 | assumed to be defined elsewhere. |
jackalmage@8572 | 2446 | Substituting the <code><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><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><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><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><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 "-", "+", ".", "<", ">", 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><an+b></var></h3> |
jackalmage@8572 | 2725 | |
jackalmage@8572 | 2726 | To serialize an <var><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. |