Skip to content
This repository

Syntax consistency for attribute references #92

Closed
springmeyer opened this Issue August 19, 2011 · 9 comments

5 participants

Dane Springmeyer Tom MacWright Konstantin Käfer Colin Rundel Robert Coup
Dane Springmeyer
Owner

Carto and the Carto C++ versions should get in sync in terms of syntax for referring to attributes in data.

Because we may need to break something in carto or mapnik and because I assume there may be more syntax issues, I'll provide extra detail here.

Why now

Now is a good time to review this because:

  • Colin's GSOC project wraps up this week on the (C++ carto parser)[https://github.com/rundel/carto-parser]
  • TileMill is becoming stable so a re-focus on carto is timely (and at this point TileMill is the only user of carto)
  • Mapnik2 will be released soon to specifically allow the C++ Carto work to be merged into trunk to kick on Mapnik 3.x (and tilemill will likely leverage Mapnik3 rapidly).
  • @kkaefer is starting to look at extending mapnik expressions to enable #9.

Goal

Now, the goal here should be to come up with a generic syntax that is not specific to mapnik.

Specifically should carto require [] be used in all places mapnik requires then, or offer special handle of this to allow the current syntax to remain valid?

Mapnik internals

But, first some background on Mapnik so we know what we are dealing with:

Mapnik internally uses [] to denote attribute lookups. In other words, in C++ code [ATTR] triggers a runtime evaluation of expressions based on attribute values.

Expressions are new in trunk (actually not in a released version of mapnik if you can believe) and currently only plugged in for a few things: TextSymbolizers 'name' property, Filters, and paths lookup for filesystem symbols.

  • Filters in mapnik2 became expressions, because Filters were already basically expressions but just returned booleans. Expressions now can evaluate to any type.
  • TextSymbolizer's 'name' property became an expression so that you could do things like name="'This is my: [name]'" and therefore the basic syntax in mapnik changed from name='ATTR' to name=[ATTR]. NOTE: Carto does not enforce this and #foo{ text-name:"ATTR" } is currently acceptable only because of a backwards compatibility shim in mapnik that will be removed in Mapnik 2.1

So, our problem at hand is that a syntax like:

#foo [ATTR=1] { .}

or:

#foo {
  ...
  text-name:"ATTR";
  ...
}

are both currently valid in TileMill, but will break when the compatibility shim is removed in Mapnik 2.1 and is not technically valid. This would be the proper way I think:

#foo [[ATTR]=1] { .}

or:

#foo {
  ...
  text-name:"[ATTR]";
  ...
}
Dane Springmeyer
Owner

/cc @rundel, @rcoup - how is this for capturing the issue in its glory? @rundel - I have yet to build the carto generator or parser this week to see how you are handling these things. Please comment on other issues you see or clarifications needed of the decision to make.

Konstantin Käfer
Owner

To make this less awkward in carto, we could just drop the [] around attribute selectors. Of course, that'd deviate carto from CSS' syntax:

#foo [ATTR]=1 {  }
Konstantin Käfer
Owner

I guess that doesn't work for compound filters like [ATTR]>2 && [ATTR]<10

Dane Springmeyer
Owner

sticking close to CSS itself seems crucial. Of note: MapCSS supports lots of expressions and manages to avoid using [] to refer to attributes: http://wiki.openstreetmap.org/wiki/MapCSS/0.2#Selectors_-_tests

Colin Rundel

Thank you Dane for writing up a clear description of the issue. Currently my preference is to use the uglier double square brackets for the sake of consistency. In particular I think we need to keep

#foo [[ATTR]=1] { }

for the sake of consistency with

#foo {
  ...
  text-name:"[ATTR]";
  ...
}

since we need the brackets in the latter to distinguish the attributes from other text. There are possible work arounds but it makes the parser way more complex. In working on the C++ parser I've rewritten the expression parser for filters which accepts attributes both with and without brackets so both can easily be handled for the time being, but it can get away with this mostly because it assumes that attributes will always be on the left hand side of relational operators.

Robert Coup

i'm +1 on:

#foo {
  ...
  text-name:"[ATTR]";
  ...
}

I think if we start magically interpreting some strings as attributes and others as plain text, I think we'll end up in a mess.

But at the same time I'd much prefer the following:

#foo [ATTR=1] { }

@rundel, what cases fall apart if we do that?

I could imagine:

#foo [ATTR1=ATTR2] { }
#foo [ATTR1="foo/[ATTR2]"] { }
#foo [something(ATTR)=1] { }
#foo [something("foo/[ATTR]")=1] { }

but they don't seem particularly condradictory - use [ATTR] within literal strings, use ATTR in filters. Escape in literal strings via \[ATTR\].

Tom MacWright
Owner

Right now we support #foo [[ATTR1]=ATTR2] { …} as well as #foo [ATTR1=2] { …} for backwards compatibility.

Dane Springmeyer
Owner

supporting both seems to be working, shall we close this then?

Tom MacWright tmcw closed this December 19, 2012
Tom MacWright
Owner

Yep, I think so - there are definitely next-actions here like filters that compare fields, but most of this is figured out and consistified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.