Re: [css3-values] calc(), whitespace, and DIMENSION tokens

Andrei has hit the nail on the head. The reason for the problems with 
the grammar for nth-child and calc is due to the way in which dimension 
is specified. So either don't allow dimension in there, or redefine it.

The vendor keywords reference given by Andrei does not provide for 
vendor specific units, only vendor specific properties, and / or 
keywords. So if vendor specific units are not required then just 
disallow any non alpha characters in the unit. If vendor specific units 
are required then - must still be allowed in the unit and so it is not 
possible to redefine DIMENSION in any way to simplify the authoring / 
parsing.

A cleaner alternative is to simply disallow dimensions altogether within 
general function syntax and instead provide a special function notation 
for specifying the units, which could also be used in properties as 
well. That would be slightly more verbose but I believe would be cleaner.

e.g.
dim(3cm)-dim(2cm)
calc(dim(3em)-max(dim(1em),dim(9px)))

That would require a special production for the dim(<DIMENSION>) 
function but there is already precedent for that, e.g. not(<selector>).

Similarly, nth-child could have its own special production that allows 
the simplified mathematical expression, or the aliases, odd and even. It 
seems reasonable to restrict the expression as currently implementations 
of :nth-child() must find some non negative value of n that satisfies 
the formula "an+b = p" where p is the 1 based position of an element 
within its parent. Attempting to do that for more general expression 
could become extremely costly, not to mention difficult for authors to 
understand.

If a more general yet easier to understand expression based selector is 
required then I would suggest something more conventional along the 
lines of:
:if(p % 2 == 0) instead of :nth-child(2n)
:if(p % 2 == 1) instead of :nth-child(2n+1)
:if(p <= 4) instead of :nth-child(-n+4)
:if(p > 4) instead of :nth-child(n-4)
:if(p > 2 && p < 4) instead of :nth-child(n-2):nth-child(-n+3)
:if(p == 9) instead of :nth-child(9)
:if(p != 9) instead of :not(:nth-child(9))

:if() would require more operators than :nth-child() but I think is more 
understandable, more flexible and easier to implement.

Andrei Polushin wrote:
> 2008/3/12, fantasai wrote:
>>  I'll note that
>>    3cm-2cm
>>  will be parsed as a single DIMENSION token and
>>    3cm -2cm
>>  will be parsed as two DIMENSION tokens. Is that what we want? Is whitespace
>>  required around minus and plus signs to treat them like operators or is
>>  tokenization different inside calc() like it is inside :nth-child()?
> 
> I propose changing the grammar around the {ident} as follows:
> 
>   nmstart   [_a-z]|{nonascii}|{escape}
>   nmchar    [_a-z0-9-]|{nonascii}|{escape}
> 
>   alpha     [a-z]|{nonascii}|{escape}
>   alnum     [_a-z0-9]|{nonascii}|{escape}
> 
>   restrict  {alpha}{alnum}*
>   simple    {nmstart}{nmchar}*
>   prefixed  [_-]{restrict}[-]{simple}
>   ident     {simple}|{prefixed}
>   unit      {restrict}|{prefixed}
> 
>   %%
> 
>   {num}{unit}   {return DIMENSION;}
> 
> That is, the unit name cannot contain '-', unless that unit name
> starts with either '-' or '_', as described by
> http://www.w3.org/TR/2007/CR-CSS21-20070719/syndata.html#vendor-keywords
> 
> In addition, such grammar treats the '-' before the {ident} as a MINUS
> SIGN, unless the {ident} itself contains '-' (see the example with
> "-max()" below).
> 
> Tokenization examples:
> 
>     :nth-child(3n-1)
> 
>         => OK: ':' FUNCTION(nth-child) DIMENSION(3n) '-' NUMBER(1) ')'
> 
>     3cm-2cm
> 
>         => OK:  DIMENSION(3cm) '-' DIMENSION(2cm)
> 
>     3-x-parsec-2-x-angstrom
>         /* -x-parsec and -x-angstrom are vendor-specific unit names */
> 
>         => BAD: DIMENSION(3-x-parsec-2-x-angstrom)
> 
>     3-x-parsec -2-x-angstrom
> 
>         => OK: DIMENSION(3-x-parsec) '-' DIMENSION(2-x-angstrom)
> 
>     calc(3em-max(1em,9px))
> 
>         => OK: FUNCTION(calc) DIMENSION(3em) '-'
>                FUNCTION(max)  DIMENSION(1em) ','
>                               DIMENSION(9px) ')' ')'
> 
> Note that tokenization is *context-free*, it can be used in equally
> incontext of 'calc', or in context of 'nth-child', or out of them.
> 
> The patch for the scanner grammar is attached.
> 
> --
> Andrei Polushin

Received on Monday, 17 March 2008 17:25:07 UTC