Skip to content
Commits on Source (12)
{
"env": {
"browser": true,
"node": true
"node": true,
"es6": true
},
"rules": {
"quotes": [2, "single"],
......@@ -10,7 +11,7 @@
"consistent-return": 0,
"new-cap": 0,
"strict": [2, "never"],
"indent": [2, 4],
"indent": [2, 4, { "SwitchCase": 1 }],
"no-shadow": 0,
"semi-spacing": 0,
"semi": [2, "always"]
......
language: node_js
node_js:
- "8"
- "6"
- "4"
git:
depth: 10
env:
- CXX=g++-4.8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
install:
- npm install
- npm run lint
- npm test
Copyright (C) 2014-2016 Yohan Boniface and contributors
This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
below or http://www.wtfpl.net/ for more details.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
......@@ -2,6 +2,7 @@
[![Join the chat at https://gitter.im/kosmtik/kosmtik](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kosmtik/kosmtik?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Dependency Status](https://david-dm.org/kosmtik/kosmtik.svg)](https://david-dm.org/kosmtik/kosmtik)
[![Build Status](https://travis-ci.org/kosmtik/kosmtik.svg?branch=master)](https://travis-ci.org/kosmtik/kosmtik)
Very lite but extendable mapping framework to create Mapnik ready maps with
OpenStreetMap data (and more).
......@@ -9,8 +10,6 @@ OpenStreetMap data (and more).
For now, only Carto based projects are supported (with .mml or .yml config),
but in the future we hope to plug in MapCSS too.
**Alpha version, installable only from source**
## Lite
......@@ -28,58 +27,69 @@ Only the core needs:
![screenshot](https://raw.github.com/kosmtik/kosmtik/master/screenshot.png "Screenshot of Kosmtik")
## Install
## Install or Update
Clone this repository with ``git clone https://github.com/kosmtik/kosmtik.git``,
go to the downloaded directory with ``cd kosmtik``, and run:
Note: Node.js versions are moving very fast, and kosmtik or its dependencies are
hardly totally up to date with latest release. Ideally, you should run the LTS
version of Node.js. You can use a Node.js version manager (like
[NVM](https://github.com/creationix/nvm)) to help.
```
npm install
```
npm -g install kosmtik
## Update
This might need root/Administrator rights. If you cannot install globally
you can also install locally with
Obtain changes from repository (e.g. `git pull`)
npm install kosmtik
rm -rf node_modules && npm install
This will create a `node_modules/kosmtik` folder. You then have to replace all occurences of `kosmtik`
below with `node node_modules/kosmtik/index.js`.
To reinstall all plugins:
node index.js plugins --reinstall
kosmtik plugins --reinstall
## Usage
To get command line help, run:
```
node index.js -h
```
kosmtik -h
To run a Carto project (or `.yml`, `.yaml`):
```
node index.js serve <path/to/your/project.mml>
```
kosmtik serve <path/to/your/project.mml>
Then open your browser at http://127.0.0.1:6789/.
You may also want to install plugins. To see the list of available ones, type:
```
node index.js plugins --available
```
kosmtik plugins --available
And then pick one and install it like this:
```
node index.js plugins --install pluginname
```
kosmtik plugins --install pluginname
For example:
```
node index.js plugins --install kosmtik-map-compare [--install kosmtik-overlay…]
```
kosmtik plugins --install kosmtik-map-compare [--install kosmtik-overlay…]
## Configuration file
By default Kosmtik places a configuration file into `$HOMEDIR/.config/kosmtik.yml`
where $HOMEDIR is your home directory. You can change that by setting the
environment variable `KOSMTIK_CONFIGPATH` to the appropriate file.
In the configuration file Kosmtik stores information about installed plugins and
you can change certain settings that should be persistent between runs.
Configurable settings are:
* autoReload (true/false)
* backendPolling (true/false)
* cacheVectorTiles (true/false)
* dataInspectorLayers (object with layer names and true/false)
* exportFormats (array of strings)
* showCrosshairs (true/false)
## Local config
......@@ -89,7 +99,7 @@ kosmtik comes with an internal plugin to manage that. You have two
options: with a json file named `localconfig.json`, or with a js module
name `localconfig.js`.
Place your localconfig.js or localconfig.json file in the same directory as your
Place your localconfig.js or localconfig.json file in the same directory as your
carto project (or `.yml`, `.yaml`).
In both cases, the behaviour is the same, you create some rules to target
......@@ -101,11 +111,11 @@ See the examples below to get it working right now.
### Example of a json file
```
```json
[
{
"where": "center",
"then": [29.9377, -3.4216, 9]
"then": [-122.25, 49.25, 10]
},
{
"where": "Layer",
......@@ -113,7 +123,7 @@ See the examples below to get it working right now.
"Datasource.type": "postgis"
},
"then": {
"Datasource.dbname": "burundi",
"Datasource.dbname": "vancouver",
"Datasource.password": "",
"Datasource.user": "ybon",
"Datasource.host": ""
......@@ -132,7 +142,7 @@ See the examples below to get it working right now.
```
### Example of a js module
```
```javascript
exports.LocalConfig = function (localizer, project) {
localizer.where('center').then([29.9377, -3.4216, 9]);
localizer.where('Layer').if({'Datasource.type': 'postgis'}).then({
......@@ -147,6 +157,13 @@ exports.LocalConfig = function (localizer, project) {
```
## Custom renderers
By default Kosmtik uses [Carto](https://github.com/mapbox/carto) to render the style. Via plugins
it is possible to use other renderers or Carto implementations. You can switch the renderer installing
the appropriate plugin and by passing the command line option `--renderer NAME`. `NAME` refers to the
renderer name (e.g. `carto` for the default renderer or `magnacarto` for the Magnacarto renderer).
## Known plugins
- [kosmtik-overpass-layer](https://github.com/kosmtik/kosmtik-overpass-layer): add Overpass Layer in your carto project
......@@ -158,5 +175,6 @@ exports.LocalConfig = function (localizer, project) {
- [kosmtik-osm-data-overlay](https://github.com/kosmtik/kosmtik-osm-data-overlay): display OSM data on top of your map
- [kosmtik-tiles-export](https://github.com/kosmtik/kosmtik-tiles-export): export a tiles tree from your project
- [kosmtik-mbtiles-export](https://github.com/kosmtik/kosmtik-mbtiles-export): export your project in MBTiles
- [kosmtik-magnacarto](https://github.com/kosmtik/kosmtik-magnacarto): Magnacarto renderer for CartoCSS
Run `node index.js plugins --available` to get an up to date list.
Run `kosmtik plugins --available` to get an up to date list.
include: https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
build:
extends: .build-unstable
reprotest:
extends: .test-reprotest
lintian:
extends: .test-lintian
autopkgtest:
extends: .test-autopkgtest
piuparts:
extends: .test-piuparts
Embedded mapnik-pool: Not available in Debian yet
Added generic-pool to d/control: Dependency of mapnik-pool
Embedded copy of carto: Need newer version than in sid (#826560)
Embedded chroma-js: Not available in Debian yet (#844229)
Added lodash to d/control: Dependency of chroma-js?
Embedded hsluv: Not available in Debian yet
Added mapnik-reference to d/control: Dependency of chroma-js?
node-kosmtik (0.0.13-1) UNRELEASED; urgency=low
node-kosmtik (0.0.17-1) UNRELEASED; urgency=low
* Initial release (Closes: #805308)
-- Ross Gammon <rosco2@ubuntu.com> Thu, 10 Nov 2016 19:14:01 +0100
-- Ross Gammon <rossgammon@debian.org> Thu, 10 Nov 2016 19:14:01 +0100
Source: node-kosmtik
Section: web
Priority: optional
Maintainer: Debian Javascript Maintainers <pkg-javascript-devel@lists.alioth.debian.org>
Uploaders: Ross Gammon <rosco2@ubuntu.com>
Maintainer: Debian GIS Project <pkg-grass-devel@lists.alioth.debian.org>
Uploaders: Ross Gammon <rossgammon@debian.org>
Build-Depends: debhelper (>= 9),
dh-buildinfo,
nodejs,
mocha,
node-semver (>= 5.0.3),
node-js-yaml (>= 3.4.2)
Standards-Version: 3.9.8
node-js-yaml (>= 3.4.2),
node-request (>= 2.64.0),
node-mapnik (>= 3.4.7),
npm,
node-nomnom (>= 1.8.1),
node-generic-pool (>= 2.2.0),
node-lodash,
mapnik-reference
Standards-Version: 4.2.1
Homepage: https://github.com/kosmtik/kosmtik#readme
Vcs-Git: https://anonscm.debian.org/git/pkg-javascript/node-kosmtik.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-javascript/node-kosmtik.git
Vcs-Browser: https://salsa.debian.org/debian-gis-team/node-kosmtik
Vcs-Git: https://salsa.debian.org/debian-gis-team/node-kosmtik.git
Package: node-kosmtik
Architecture: all
......@@ -23,7 +30,6 @@ Depends: ${misc:Depends},
node-semver (>= 5.0.3),
node-request (>= 2.64.0),
node-nomnom (>= 1.8.1),
node-carto (>= 0.15.2),
node-leaflet-hash (>= 0.2.1),
node-leaflet-formbuilder (>= 0.2.0),
node-leaflet (>= 1.0.0-beta.2),
......
package.json usr/lib/nodejs/kosmtik/
index.js usr/lib/nodejs/kosmtik/
src/* usr/lib/nodejs/kosmtik/
debian/node_modules usr/lib/nodejs/kosmtik/
usr/lib/nodejs/kosmtik/index.js usr/bin/kosmtik
# Changelog
## 1.1.0
* Update dependencies
* Update mapnik-reference to support new Mapnik API version ([#494](https://github.com/mapbox/carto/issues/494))
## 1.0.1
* Fix a error in the serialization process. ([#473](https://github.com/mapbox/carto/issues/488))
## 1.0.0
* Documentation is now available on https://cartocss.readthedocs.io. ([#473](https://github.com/mapbox/carto/issues/473))
* Warnings are emitted if properties are used that are `deprecated`, `unstable` or `experimental`.
There is a new command line / API switch (`-q / --quiet` / `quiet`) to suppress those warnings. ([#474](https://github.com/mapbox/carto/issues/474))
* Warnings are emitted if a layer has no associated styles or styles do not match a corresponding layer selector. ([#29](https://github.com/mapbox/carto/issues/29))
* New command line switch `-f / --file` to specify a file for output instead of `stdout`.
* carto now honors variable redefinition and uses the last defined value instead of the first one ([#338](https://github.com/mapbox/carto/issues/338)).
* All parameters of XML tags are now ouput in alphabetical order. This makes output more predictable.
* carto is now able to output a JSON variant of Mapnik XML. There is a new command line / API switch
(`-o / --output` / `outputFormat`) to choose the output format. Possible values are `mapnik` (default)
for Mapnik XML and `json` for the JSON variant (part of [#413](https://github.com/mapbox/carto/issues/413)).
For Mapnik XML all character data as tag content is now prefixed with CDATA.
* Expressions are allowed in filters e.g. `[height] % 50 = 0` or `[height] + 10 = 0`, fields have to be properly written within brackets
([#377](https://github.com/mapbox/carto/issues/377))
* carto now accepts custom references for validating rules (part of [#413](https://github.com/mapbox/carto/issues/413))
* The JavaScript API has been documented ([#479](https://github.com/mapbox/carto/issues/479))
* New symbolizer rules (work on the whole symbolizer) enable control of symbolizer serialization. Write e.g. `line: none` to suppress output
of the line symbolizer for this definition. Write e.g. `marker: auto` to output a markers symbolizer with default values. Symbolizer rules
are considered an advanced features and are never inherited to other definitions ([#477](https://github.com/mapbox/carto/pull/477)).
* Remove `millstone` from optional dependencies again ([#482](https://github.com/mapbox/carto/issues/482)).
### Breaking changes
#### Stylesheets
* The deprecated `name` attribute for layers is no longer supported. Use `id` instead.
* The deprecated color functions `husl` and `husla` are no longer supported. Use `hsluv` and `hsluva` instead.
* If you define a variable with the same name twice the latest defined value is now used in contrast to the first defined one as before.
* All parameters of XML tags are now ouput in alphabetical order. If you somehow depend on the order
of parameters (e.g. for tests) expect them to change.
#### API
* `carto.Renderer.render` and `carto.Renderer.renderMSS` now return an object `{ msg: Array, data: String }` instead of just a
string. `data` contains the output as before and `msg` now contains an array of error or warning objects.
In case of errors `data` is `null`.
* carto now only throws errors in case of program failures. All other style processing
related errors can be found in the `msg` property (see above).
* The constructor of `carto.Renderer` now only takes one options object
instead of a `env` and `options` parameter.
* The option `mapnik_version` and `validation_data` of `carto.Renderer` have
been renamed to `version` and `validationData` respectively.
* `carto.Renderer` now checks each option before forwarding them to the rendering
chain. Supported options are defined in the documentation. If you use a option that is
missing please open a issue.
## 0.18.2
* Remove `millstone` from optional dependencies again
## 0.18.1
* Updated `mapnik-reference` to fix an install problem for some Node.js versions
* Backported documentation updates
## 0.18.0
* Compile time performance improvement by leaving out rules that do not apply to layer minzoom and maxzoom restrictions if specified ([#469](https://github.com/mapbox/carto/issues/469))
* Confirmed that [#348](https://github.com/mapbox/carto/issues/348) does not occur (anymore)
* Updated dependencies
## 0.17.3
* Fix regression with number parsing after fixing of [#411](https://github.com/mapbox/carto/issues/411) ([#471](https://github.com/mapbox/carto/issues/471))
## 0.17.2
* Remove unintended scoping of package. It is now again `carto`. The NPM requirement is dropped.
* Variables in font definitions are now processed correctly ([#333](https://github.com/mapbox/carto/issues/333))
* Display a better error for missing fonts on font name validation ([#242](https://github.com/mapbox/carto/issues/242))
* Some properties can now be reset to their default value by using `none` ([#214](https://github.com/mapbox/carto/issues/214))
## 0.17.1
* Revert fix for [#315](https://github.com/mapbox/carto/issues/315) due to performance problems ([#466](https://github.com/mapbox/carto/issues/466))
## 0.17.0
* Carto is now a scoped package named `@mapbox/carto`. Scoped packages require NPM >= 1.5. ([#457](https://github.com/mapbox/carto/pull/457))
* Carto now runs in the browser too (part of [#413](https://github.com/mapbox/carto/issues/413))
* Carto can now load MML itself and supports absolute file paths in MML stylesheet references ([#439](https://github.com/mapbox/carto/pull/439))
* The target API default of Mapnik moved from 2.3.0 to being always the latest version (3.0.x). Take that into account if you run a Mapnik 2.x instance (see also the `-a/--api` command line option).
([#454](https://github.com/mapbox/carto/issues/454))
* `husl()` was renamed to `hsluv()`. The HuSL variant is deprecated and will be removed in 1.0.0. ([#456](https://github.com/mapbox/carto/issues/456))
* The `name` attribute for layers in the MML is deprecated and will be removed in 1.0.0. Use `id` instead. ([#165](https://github.com/mapbox/carto/issues/165))
* The `_properties` object in the MML of vector tiles projects is now supported ([#450](https://github.com/mapbox/carto/issues/450))
* Updated `mapnik-reference` to 8.6.1, which enables Browser support and support for the `transform` property of PolygonPatternSymbolizer ([#445](https://github.com/mapbox/carto/issues/445))
* Bugfixes ([#296](https://github.com/mapbox/carto/issues/296), [#121](https://github.com/mapbox/carto/issues/121), [#315](https://github.com/mapbox/carto/issues/315), [#411](https://github.com/mapbox/carto/issues/411), [#426](https://github.com/mapbox/carto/issues/426), [#273](https://github.com/mapbox/carto/issues/273))
* Documentation updates ([#269](https://github.com/mapbox/carto/issues/269), [#452](https://github.com/mapbox/carto/issues/452))
## 0.16.3
* Fixed outdated library reference for carto help screen ([#444](https://github.com/mapbox/carto/pull/443))
* Fixed a regression related to color math with non-color values being interpreted as HSL instead of RGB ([#446](https://github.com/mapbox/carto/issues/446))
## 0.16.2
* Fixed a regression related to color math ([#443](https://github.com/mapbox/carto/issues/443))
## 0.16.1
* Fixed a regression related to the color mix function ([#442](https://github.com/mapbox/carto/issues/442))
## 0.16.0
* Fixed a bug related to parsing numerical selectors ([#393](https://github.com/mapbox/carto/pull/393))
* More meaningful error messages on erroneous Stylesheet references in MML ([#438](https://github.com/mapbox/carto/pull/438))
* Added support for YAML MML files ([#419](https://github.com/mapbox/carto/pull/419))
* Added support for [HuSL](http://www.husl-colors.org) perceptual colors ([#422](https://github.com/mapbox/carto/pull/422))
* Added support for targeting Mapnik API versions in `carto` command line tool ([#433](https://github.com/mapbox/carto/pull/433))
* Added support for `minimum-/maximum-scale-denominator` ([#394](https://github.com/mapbox/carto/issues/394))
* Updated documentation, fixed its display problems and added doc for `image-filter` ([#432](https://github.com/mapbox/carto/pull/432))
* Moved from `underscore` to `lodash` dependency ([#431](https://github.com/mapbox/carto/pull/431))
* Moved from `optimist` to `yargs` dependency ([#435](https://github.com/mapbox/carto/pull/435))
* Bump `mapnik-reference` dependency to 8.5.3 (support for Mapnik 3.0.10)
* Modernized development dependencies
* Further small fixes and improvements for development.
## 0.15.3
* Support for Mapnik 3.0.6
## 0.15.2
* Support for Mapnik 3.0.5
## 0.15.1
* Support for Mapnik 3.0.4
## 0.15.0
* Support for Mapnik 3.0.3
## 0.14.1
* Support latest Mapnik 3.x
* Bump `mapnik-reference` dependency to 7.x.
## 0.14.0
* Support for Mapnik 3.x
* Bump `mapnik-reference` dependency to ~6.0.1.
## 0.13.0
* Allows optional args in transforms.
* Bump `mapnik-reference` dependency to 5.1.x.
## 0.12.0
* Drop mml2json and xml2js dependency.
## 0.11.0
* Switch API to be synchronous. All errors should be caught using try/catch now.
## 0.10.0
* Remove automatic inclusion of `maximum-extent` on Map element to allow geometries that are buffered past extent bounds (e.g. dateline).
* Bump `mapnik-reference` dependency to ~5.0.9 (with `shield-halo-rasterizer`)
## 0.9.6
* Fixed support for `text-face-name` values with `&` like `El&Font Bubble`
* Fixed support for filtering on fields containing single quotes. Now `#layer[name="it's"] { ... }` is possible.
* Fixed support for filtering on fields containing `&`. Now `#layer["Hello&Goodbye"="yes"] { ... }` is possible.
* Added support for exponential notation in filters. Now `#layer[value = 1.2e3] { ... }` is possible.
* Bump `mapnik-reference` dependency to ~5.0.8 (with support for Mapnik v2.3.0 and 3.x)
## 0.9.5
* Various speed optimizations to help address #20 (#231)
* Fixed support for fields that contain the word `zoom` in them (previous clashed with `zoom` keyword)
* Fixed support for a space in front of `zoom` keyword (#288)
* Improved error messages when color functions encounter invalid color (#309)
* The `carto` command line tool now exits cleanly when millstone is used
* The `carto` command line tool now only localized with millstone if requested (#243)
* Added man page for `carto` (#257)
* Fix repeated comments in selectors. Fixes #260
* Fixed `image-filter` duplication (#270)
* Quote all needed XML chars. See #263.
* Added higher tolerance for various characters in field names (#230)
* Bump `mapnik-reference` dependency to ~5.0.7 (with support for Mapnik v2.2.0)
* Adds compatibility with screen units.
* Fixed ability to use carto as global module (#236)
* Now using 'console' instead of `util` for `stderr` (#217)
## 0.9.4
* Fixes nesting of regex calls
## 0.9.3
* Allows `text-face-name` properties to be unquoted
* Detects inline Format XML tags in `text-name` and passes such output
straight to XML for advanced text names.
* Fixes bugs around concatenation of strings in expressions
* Fixes parsing of comments in between selectors
* Fixes parsing of whitespace in calls
* Improved error messages for unknown properties - advises user on
the property name most closely matching the incorrect input.
* Improved errors for calls, advises user on number of arguments
* Fixes instance inheritance - thanks @gravitystorm!
## 0.9.2
Tagged Sept 6, 2012
* Bump `mapnik-reference` dependency to ~5.0.0
* Better support for unsigned types in certain Mapnik styling properties
## 0.9.1
Tagged Aug 15, 2012
* Improved error handling for different target `mapnik-reference` versions (strk)
* Bump `mapnik-reference` dependency to ~4.0.3
* Fixed handling of image-filter syntax as per [Mapnik changes](https://github.com/mapnik/mapnik/issues/1384)
## 0.9.0
* Bump `mapnik-reference` dependency to ~4.0.0 to pull in new properties.
* Adapted to `comp-op` rename upstream in `mapnik-reference`.
* Adapted to `transform` rename upstream in `mapnik-reference` and Mapnik.
## 0.8.1
* Bump `mapnik-reference` dependency to ~3.1.0 to pull in new properties.
## 0.8.0
* Adds the modulus operator `%` as an option
* Adds a new field-type like `[FIELD]` instead of "[FIELD]"
* Supports function syntax for transforms, optionally with variables and arguments.
### 0.7.1
* Updated mapnik-reference to `~2.2.1`
* Added support for `status` parameter on layers.
* Command line `carto` program gained `--nosymlink` option to pass to millstone to use absolute paths instead of symlinking files.
* Removed unsupported mixin code.
### 0.7.0
* Updated mapnik-reference to `~2.1.0`
* Support an `opacity` property on any style that is a style-level property
### 0.6.0
* Bump `mapnik-reference` dependency to 1.0.0 to allow for using `buffer-size` in the
`Map` element.
### 0.5.0
* Now uses the [mapnik-reference](https://github.com/mapnik/mapnik-reference) npm module
instead of copying `reference.json` when it's updated
* Adds a second parameter to `carto.Renderer` - an object which has a key `mapnik_version`
that specifies the version of Mapnik this stylesheet should target.
### 0.4.10
* Updated reference.json
### 0.4.9
* Render TileJSON, Mapnik options to Mapnik XML parameters.
### 0.4.8
* Updated reference.json
### 0.4.7
* Removed deprecation warnings re: sys/util
* Updated reference.json
* Updated underscore dependency
### 0.4.6
* Node >=v0.6.x compatibility
* Dropped cartox
* Updated reference.json
### 0.4.5
* Fixes text-name with HTML entities
* Fixes function calls with incorrect number of arguments
* Fixes invalid code segments not having eval
### 0.4.3
* Fixes serialization bug with invalid selectors.
### 0.4.0
* Switches text-symbolizer syntax to new-style for Mapnik 2.0
### 0.3.0
* Add "name/" prefix for creating multiple instances of a symbolizer in the same
attachment
* Only output `<Layer>` tag when there's at least one style
* Sort styles by location of first rule's index
* Don't support selectors that are not either `Map`, `.` or `#`-prefixed.
### 0.2.3
* Fixes many bugs
* Supports arbitrary properties on layers with the `properties` key in MML
* Adds `min-path-length`
* Updates `reference.json`
### 0.2.2
* Update `carto` to use `millstone` if available.
### 0.2.1
* Accept valid Map properties directly from input mml object.
### 0.2.0
* Removed all external handling - see http://github.com/mapbox/millstone for localizing/caching MML objects with external references.
* All errors are now handled as Error objects.
### 0.1.14
* Optional-file datasources - allows string argument to OGR
### 0.1.9
* Variables in filters.
### 0.1.6 & 0.1.8
* Fixed bug caused by jshint testing
### 0.1.5
* Using npm devDependencies in place of ndistro
* Updated package.json format
* Fixes tests
### 0.1.4
* Fix bug in which SRS autodetection broke error handling
* Update carto
## Developing
Installing:
git clone https://github.com/mapbox/carto.git
cd carto
npm install
Test:
npm test
Running the head binary:
./bin/carto
## Releasing
- Make sure all tests are passing
- Ensure CHANGELOG.md is up to date
- Test relevant applications to ensure no regressions
- `npm publish`
- Regenerate documentation (see below)
If there's a high chance of regression, please bump to a new major version number
so that code using a semver ^ or ~ doesn't auto-upgrade anyone.
For examples of previous releases see: https://github.com/mapbox/carto/issues/440
## Documentation
This repository contains auto-generated documentation of the content of Carto
that's published on readthedocs.io. You find the relevant files in the `docs`
directory. Those files with the extension `rst` are the ones where you find
the documentation sources in reStructuredText.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright (c) 2009-2010 Alexis Sellier
# CartoCSS
[![Build Status](https://secure.travis-ci.org/mapbox/carto.svg)](http://travis-ci.org/mapbox/carto) [![Build status](https://ci.appveyor.com/api/projects/status/github/mapbox/carto?svg=true)](https://ci.appveyor.com/project/Mapbox/carto) [![Coverage Status](https://coveralls.io/repos/github/mapbox/carto/badge.svg?branch=master)](https://coveralls.io/github/mapbox/carto?branch=master) [![Package Version](https://img.shields.io/npm/v/carto.svg)](https://www.npmjs.com/package/carto) [![Dependencies](https://david-dm.org/mapbox/carto.svg)](https://david-dm.org/mapbox/carto) [![Documentation Status](https://readthedocs.org/projects/cartocss/badge/?version=latest)](http://cartocss.readthedocs.io/en/latest/?badge=latest)
CartoCSS (short: Carto) is a language for map design. It is similar in syntax to CSS, but builds upon it with specific abilities to filter map data and by providing things like variables.
It targets the [Mapnik renderer](http://mapnik.org) and is able to generate Mapnik XML and a JSON variant of Mapnik XML.
It can run from the command line or in the browser.
Carto is an evolution of the [Cascadenik](https://github.com/mapnik/Cascadenik) idea and language, with an emphasis on speed and flexibility.
## Documentation
The best place to start is to review the [CartoCSS documentation](https://cartocss.readthedocs.io).
Tutorials like the [Mapbox Getting started with CartoCSS guide](https://www.mapbox.com/guides/getting-started-cartocss/) are a great place to start to learn the basics of CartoCSS.
For more advanced topics see the [Studio style quickstart guide](https://www.mapbox.com/guides/style-quickstart/) and [Studio style manual](https://www.mapbox.com/guides/style-manual). The links below reference the Tilemill application, which preceded Mapbox Studio Classic, but still contain useful and relevant information.
- [Details on Filtering data with CartoCSS](https://www.mapbox.com/tilemill/docs/guides/selectors/)
- [How order works in rendering](https://www.mapbox.com/tilemill/docs/guides/symbol-drawing-order/)
- [How to style labels](https://www.mapbox.com/tilemill/docs/guides/styling-labels/)
- [How to style lines](https://www.mapbox.com/tilemill/docs/guides/styling-lines/)
- [How to style polygons](https://www.mapbox.com/tilemill/docs/guides/styling-polygons/)
- See also the [Styling Concepts](#styling-concepts) for explanations of advanced features.
## Installation
If you are using a map design application like Kosmtik, Mapbox Studio Classic or Tilemill you already have CartoCSS installed
and might be more interested in the language reference.
Else you can install the `carto` binary with NPM by running:
npm install -g carto
You should consider using a Node.js version manager like [NVM](https://github.com/creationix/nvm).
Optionally you may also want to install millstone which is required for resolving data in the same way as Mapbox Studio Classic does:
npm install -g millstone
Having `millstone` installed specifically enable support for localizing external resources (URLs and local files) referenced in your mml file, and detecting projections (using [node-srs](https://github.com/mapbox/node-srs))
## Usage
Now that Carto is installed you should have a `carto` command line tool available that can be run on a CartoCSS project:
carto project.mml > mapnik.xml
Available parameters:
* -a / --api VERSION - Specify Mapnik API version (e.g. --api 3.0.10) (default: latest Mapnik API version)
* -b / --benchmark - Outputs total compile time
* -f / --file - Outputs to the specified file instead of stdout
* -h / --help - Display help message
* -l / --localize - Use millstone to localize resources when loading an MML (default: off)
* -n / --nosymlink - Use absolute paths instead of symlinking files
* -o / --output - Specify output format, possible values are `mapnik` and `json` (default: `mapnik`)
* -ppi RESOLUTION - Pixels per inch used to convert m, mm, cm, in, pt, pc to pixels (default: 90.714)
* -q / --quiet - Do not output any warnings (default: off)
* -v / --version - Display version information
Alternatively, Carto can be used from JavaScript.
The `Renderer` interface is the main API for developers, and it takes an MML file as a string as input.
```javascript
// defined variables:
// - input (the name or identifier of the file being parsed)
var carto = require('carto');
try {
var data = fs.readFileSync(input, 'utf-8');
var mml = new carto.MML({});
mml.load(path.dirname(input), data, function (err, data) {
var output = {};
if (!err) {
output = new carto.Renderer({
filename: input
}).render(data);
}
if (output.msg) {
output.msg.forEach(function (v) {
if (v.type === 'error') {
console.error(carto.Util.getMessageToPrint(v));
}
else if (v.type === 'warning') {
console.warn(carto.Util.getMessageToPrint(v));
}
});
}
// output content (if no errors)
if (output.data) {
console.log(output.data);
}
});
} catch (err) {
// program failures
...
}
```
If you want to use CartoCSS within the browser you should not use MML loading via `carto.MML.load`.
Instead you should supply the JSON of the MML including the Stylesheet strings directly to `carto.Renderer.render`.
## Vim
To install, download or clone this repository, then copy the `vim-carto`
directory located at `build/vim-carto` to your `~/.vim` directory.
cp build/vim-carto/* ~/.vim -R
## Credits
CartoCSS is based on [less.js](https://github.com/cloudhead/less.js), a CSS compiler written by Alexis Sellier.
See also a [list of dependencies](https://david-dm.org/mapbox/carto#info=dependencies&view=list).
## Similar projects
* [Magnacarto](https://github.com/omniscale/magnacarto) (Go implementation of CartoCSS for Mapnik and Mapserver)
## Authors
* Tom MacWright (tmcw)
* Konstantin Käfer (kkaefer)
* AJ Ashton (ajashton)
* Dane Springmeyer (springmeyer)
* Michael Glanznig (nebulon42)
# Test against this versions of Node.js
environment:
matrix:
- nodejs_version: 10
- nodejs_version: 8
- nodejs_version: 6
# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
# install modules
- npm install
# Post-install test scripts.
test_script:
# Output useful info for debugging.
- node --version
- npm --version
# run tests
- npm test
# Don't actually build.
build: off
#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
carto = require('../lib/carto'),
url = require('url'),
_ = require('lodash'),
util = require('../lib/carto/util');
var existsSync = require('fs').existsSync || require('path').existsSync
var yargs = require('yargs')
.usage("Usage: $0 <source MML file>")
.options('h', {alias:'help', describe:'Display this help message'})
.options('v', {alias:'version', boolean:true, describe:'Display version information'})
.options('b', {alias:'benchmark', boolean:true, describe:'Outputs total compile time'})
.options('l', {alias:'localize', boolean:true, default:false, describe:'Use millstone to localize resources when loading an MML'})
.options('n', {alias:'nosymlink', boolean:true, describe:'Use absolute paths instead of symlinking files'})
.options('a', {alias:'api', describe:'Specify Mapnik API version'})
.options('f', {alias:'file', describe:'Outputs to the given file instead of stdout.'})
.options('o', {alias:'output', describe:'Specify output format (mapnik, json)', default:'mapnik'})
.options('q', {alias:'quiet', boolean:true, default:false, describe:'Do not output any warnings'})
.options('ppi', {describe:'Pixels per inch used to convert m, mm, cm, in, pt, pc to pixels', default:90.714});
var options = yargs.argv;
if (options.help) {
yargs.showHelp();
process.exit(0);
}
if (options.version) {
console.error("carto " + carto.version.join('.') + " (Carto map stylesheet compiler)");
process.exit(0);
}
var input = options._[0];
if (input && input[0] != '/') {
input = path.join(process.cwd(), input);
}
if (!input) {
console.error("carto: no input files ('carto -h or --help' for help)");
process.exit(1);
}
if (options.benchmark) {
var start = +new Date;
}
var ext = path.extname(input);
if (!ext) {
console.error("carto: please pass either a .mml file or .mss file");
process.exit(1);
}
if (!existsSync(input)) {
console.error("carto: file does not exist: '" + input + "'");
process.exit(1);
}
try {
var data = fs.readFileSync(input, 'utf-8');
} catch(err) {
console.error("carto: " + err.message.replace(/^[A-Z]+, /, ''));
process.exit(1);
}
if (ext === '.mml') {
var mml = new carto.MML(options);
mml.load(path.dirname(input), data, compile);
} else if (ext === '.mss') {
compile(null, data);
} else {
console.error("carto: please pass either a .mml file or .mss file");
}
function compile(err, data) {
if (err) {
console.error(err);
process.exit(1);
}
var renderer = new carto.Renderer({
filename: input,
benchmark: options.benchmark,
ppi: options.ppi,
quiet: options.quiet,
outputFormat: options.output,
version: options.api
});
try {
var output;
if (ext === '.mml') {
output = renderer.render(data);
} else if (ext === '.mss') {
output = renderer.renderMSS(data);
}
if (_.has(output, 'msg') && _.isArray(output.msg) &&
output.msg.length > 0) {
var hasError = false;
_.forEach(output.msg, function (v) {
if (v.type === 'error') {
console.error(util.getMessageToPrint(v));
hasError = true;
}
else if (v.type === 'warning') {
console.warn(util.getMessageToPrint(v));
}
});
if (hasError) {
process.exit(1);
}
}
} catch (e) {
if (e.stack) {
console.error(e.stack);
} else if (e.message) {
console.error(e.message);
}
else {
console.error(e);
}
process.exit(1);
}
if (!options.benchmark) {
if (!_.isNil(output.data)) {
if (options.file) {
try {
fs.writeFileSync(options.file, output.data);
}
catch (e) {
console.error(e);
console.error('Writing to given file ' + options.file + ' failed. Falling back to stdout output.');
console.log(output.data);
}
}
else {
console.log(output.data);
}
}
} else {
var duration = (+new Date) - start;
console.log('TOTAL: ' + (duration) + 'ms');
}
};
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>beforeRunningCommand</key>
<string>nop</string>
<key>command</key>
<string>#!/usr/bin/env ruby
nvmdir = File.expand_path('~/.nvm')
localdir = "/usr/local/bin/"
if File.directory?nvmdir then
cartos = Dir.glob(nvmdir + '/*/bin/mapnik-render.js')
carto = cartos.pop() if cartos
node = carto.gsub('/bin/mapnik-render.js', '/bin/node')
elsif File.exist?localdir + "mapnik-render.js"
carto = localdir + "mapnik-render.js"
node = localdir + "node"
end
if carto
`#{node} #{carto} #{ENV['TM_FILEPATH']} /tmp/test.png`
else
puts 'node and mapnik-render.js could not be found'
end
</string>
<key>input</key>
<string>none</string>
<key>keyEquivalent</key>
<string>^~@p</string>
<key>name</key>
<string>Preview</string>
<key>output</key>
<string>showAsHTML</string>
<key>scope</key>
<string>source.mml</string>
<key>uuid</key>
<string>4A0B3C2B-5F11-4D70-AFF4-EC4A4A042D66</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>comment</key>
<string>Carto</string>
<key>fileTypes</key>
<array>
<string>mss</string>
</array>
<key>foldingStartMarker</key>
<string>/\*\*(?!\*)|\{\s*($|/\*(?!.*?\*/.*\S))</string>
<key>foldingStopMarker</key>
<string>(?&lt;!\*)\*\*/|^\s*\}</string>
<key>keyEquivalent</key>
<string>^~C</string>
<key>name</key>
<string>Carto</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\b(Map)\b</string>
<key>name</key>
<string>keyword.control.carto.elements</string>
</dict>
<dict>
<key>begin</key>
<string>"</string>
<key>end</key>
<string>"</string>
<key>name</key>
<string>string.quoted.double.carto</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escaped.carto</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>'</string>
<key>end</key>
<string>'</string>
<key>name</key>
<string>string.quoted.single.carto</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escaped.carto</string>
</dict>
</array>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.carto</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.other.class.carto</string>
</dict>
</dict>
<key>match</key>
<string>(\.)([a-zA-Z0-9_-]+)</string>
<key>name</key>
<string>meta.selector.class.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.carto</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.control.id.carto</string>
</dict>
</dict>
<key>match</key>
<string>(#)([a-zA-Z0-9_-]+)</string>
<key>name</key>
<string>meta.selector.id.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.carto</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.other.attachment.carto</string>
</dict>
</dict>
<key>match</key>
<string>(::)([a-zA-Z0-9_/-]+)\b</string>
<key>name</key>
<string>meta.selector.attachment.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.carto</string>
</dict>
<key>10</key>
<dict>
<key>name</key>
<string>string.quoted.attribute-value.carto</string>
</dict>
<key>11</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.carto</string>
</dict>
<key>12</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.carto</string>
</dict>
<key>13</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.carto</string>
</dict>
<key>14</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.carto</string>
</dict>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.carto</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>meta.tag.zoomfilter.carto</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>variable.other.carto</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.carto</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.carto</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.carto</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.carto</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.separator.operator.carto</string>
</dict>
<key>9</key>
<dict>
<key>name</key>
<string>constant.numeric.carto</string>
</dict>
</dict>
<key>match</key>
<string>(\[)\s*(?:(zoom)|((")(?:[^"\\]|\\.)*(")|(')(?:[^'\\]|\\.)*(')|[a-zA-Z0-9_][a-zA-Z0-9_-]*))\s*(!?=|&gt;=?|&lt;=?)\s*(?:(\d+)|((")(?:[^"\\]|\\.)*(")|(')(?:[^'\\]|\\.)*(')|[a-zA-Z0-9_][a-zA-Z0-9_-]*))\s*(\])</string>
<key>name</key>
<string>meta.attribute-selector.carto</string>
</dict>
<dict>
<key>begin</key>
<string>url\(</string>
<key>contentName</key>
<string>variable.parameter.url</string>
<key>end</key>
<string>\)</string>
<key>name</key>
<string>support.function.any-method.builtin.carto</string>
</dict>
<dict>
<key>match</key>
<string>(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b</string>
<key>name</key>
<string>constant.other.rgb-value.carto</string>
</dict>
<dict>
<key>begin</key>
<string>/\*</string>
<key>end</key>
<string>\*/</string>
<key>name</key>
<string>comment.block.carto</string>
</dict>
<dict>
<key>match</key>
<string>(-|\+)?\s*[0-9]+(\.[0-9]+)?</string>
<key>name</key>
<string>constant.numeric.carto</string>
</dict>
<dict>
<key>match</key>
<string>(?&lt;=[\d])(px)\b|%</string>
<key>name</key>
<string>keyword.unit.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.at-rule.import.carto</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.keyword.carto</string>
</dict>
</dict>
<key>match</key>
<string>^\s*((@)import\b)</string>
<key>name</key>
<string>meta.at-rule.import.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.type.property-name.carto</string>
</dict>
</dict>
<key>match</key>
<string>\b(background-color|background-image|srs|buffer|font-directory|polygon-fill|polygon-gamma|polygon-opacity|polygon-meta-output|polygon-meta-writer|line-color|line-width|line-opacity|line-join|line-cap|line-gamma|line-dasharray|line-meta-output|line-meta-writer|marker-file|marker-opacity|marker-line-color|marker-line-width|marker-line-opacity|marker-placement|marker-type|marker-width|marker-height|marker-fill|marker-allow-overlap|marker-spacing|marker-max-error|marker-transform|marker-meta-output|marker-meta-writer|shield-name|shield-face-name|shield-size|shield-fill|shield-min-distance|shield-halo-fill|shield-halo-radius|shield-spacing|shield-character-spacing|shield-line-spacing|shield-file|shield-width|shield-height|shield-type|shield-text-dx|shield-text-dy|shield-dx|shield-dy|shield-meta-output|shield-meta-writer|shield-label-position-tolerance|line-pattern-file|line-pattern-width|line-pattern-height|line-pattern-type|line-pattern-meta-output|line-pattern-meta-writer|polygon-pattern-file|polygon-pattern-width|polygon-pattern-height|polygon-pattern-type|polygon-pattern-meta-output|polygon-pattern-meta-writer|raster-opacity|raster-comp-op|raster-scaling|point-file|point-width|point-height|point-type|point-allow-overlap|point-placement|point-meta-output|point-meta-writer|text-name|text-face-name|text-size|text-ratio|text-wrap-width|text-spacing|text-character-spacing|text-line-spacing|text-label-position-tolerance|text-max-char-angle-delta|text-fill|text-halo-fill|text-halo-radius|text-dx|text-dy|text-avoid-edges|text-min-distance|text-min-padding|text-allow-overlap|text-placement|text-placement-type|text-placements|text-transform|text-meta-output|text-meta-writer|building-fill|building-fill-opacity|building-height)\s*:</string>
</dict>
<dict>
<key>match</key>
<string>\b(miter|round|bevel|butt|round|square|point|line|arrow|ellipse|png|jpg|svg|normal|grain_merge|grain_merge2|multiply|multiply2|divide|divide2|screen|hard_light|near|bilinear|bilinear8|centroid|interior|point|line|vertex|interior|none|uppercase|lowercase)\b</string>
<key>name</key>
<string>meta.property-value.carto</string>
</dict>
<dict>
<key>comment</key>
<string>http://www.w3.org/TR/CSS21/syndata.html#value-def-color</string>
<key>match</key>
<string>\b(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|transparent)\b</string>
<key>name</key>
<string>constant.color.w3c-standard-color-name.carto</string>
</dict>
<dict>
<key>match</key>
<string>\b(saturate|desaturate|lighten|darken|grayscale)\b</string>
<key>name</key>
<string>support.function.any-method.builtin.carto</string>
</dict>
<dict>
<key>match</key>
<string>\b(rgb|rgba|hsl|hsla|url)\b</string>
<key>name</key>
<string>support.function.any-method.builtin.carto</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.carto</string>
</dict>
</dict>
<key>match</key>
<string>(\.[a-zA-Z0-9_-]+)\s*(;|\()</string>
</dict>
<dict>
<key>begin</key>
<string>//</string>
<key>end</key>
<string>$\n?</string>
<key>name</key>
<string>comment.line.double-slash.carto</string>
</dict>
<dict>
<key>match</key>
<string>@[a-zA-Z0-9_-][\w-]*</string>
<key>name</key>
<string>variable.other.carto</string>
</dict>
<dict>
<key>match</key>
<string>\$|%|&amp;|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|&lt;=|&gt;=|&lt;&lt;=|&gt;&gt;=|&gt;&gt;&gt;=|&lt;&gt;|&lt;|&gt;|!|&amp;&amp;|\|\||\?\:|\*=|(?&lt;!\()/=|%=|\+=|\-=|&amp;=|\^=|\/\b</string>
<key>name</key>
<string>keyword.operator.carto</string>
</dict>
<dict>
<key>match</key>
<string>\{|\}</string>
<key>name</key>
<string>meta.brace.curly.js</string>
</dict>
<dict>
<key>match</key>
<string>\(|\)</string>
<key>name</key>
<string>meta.brace.round.js</string>
</dict>
<dict>
<key>match</key>
<string>\[|\]</string>
<key>name</key>
<string>meta.brace.square.js</string>
</dict>
</array>
<key>scopeName</key>
<string>source.css.carto</string>
<key>uuid</key>
<string>43F4EF91-F880-4CE7-A4C8-02DA726BC5FF</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>mml</string>
</array>
<key>foldingStartMarker</key>
<string>(?x: # turn on extended mode
^ # a line beginning with
\s* # some optional space
[{\[] # the start of an object or array
(?! # but not followed by
.* # whatever
[}\]] # and the close of an object or array
,? # an optional comma
\s* # some optional space
$ # at the end of the line
)
| # ...or...
[{\[] # the start of an object or array
\s* # some optional space
$ # at the end of the line
)</string>
<key>foldingStopMarker</key>
<string>(?x: # turn on extended mode
^ # a line beginning with
\s* # some optional space
[}\]] # and the close of an object or array
)</string>
<key>keyEquivalent</key>
<string>^~M</string>
<key>name</key>
<string>Carto MML</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#value</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>array</key>
<dict>
<key>begin</key>
<string>\[</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.array.begin.json</string>
</dict>
</dict>
<key>end</key>
<string>\]</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.array.end.json</string>
</dict>
</dict>
<key>name</key>
<string>meta.structure.array.json</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#value</string>
</dict>
<dict>
<key>match</key>
<string>,</string>
<key>name</key>
<string>punctuation.separator.array.json</string>
</dict>
<dict>
<key>match</key>
<string>[^\s\]]</string>
<key>name</key>
<string>invalid.illegal.expected-array-separator.json</string>
</dict>
</array>
</dict>
<key>constant</key>
<dict>
<key>match</key>
<string>\b(?:true|false|null)\b</string>
<key>name</key>
<string>constant.language.json</string>
</dict>
<key>number</key>
<dict>
<key>comment</key>
<string>handles integer and decimal numbers</string>
<key>match</key>
<string>(?x: # turn on extended mode
-? # an optional minus
(?:
0 # a zero
| # ...or...
[1-9] # a 1-9 character
\d* # followed by zero or more digits
)
(?:
(?:
\. # a period
\d+ # followed by one or more digits
)?
(?:
[eE] # an e character
[+-]? # followed by an option +/-
\d+ # followed by one or more digits
)? # make exponent optional
)? # make decimal portion optional
)</string>
<key>name</key>
<string>constant.numeric.json</string>
</dict>
<key>object</key>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.dictionary.begin.json</string>
</dict>
</dict>
<key>comment</key>
<string>a JSON object</string>
<key>end</key>
<string>\}</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.dictionary.end.json</string>
</dict>
</dict>
<key>name</key>
<string>meta.structure.dictionary.json</string>
<key>patterns</key>
<array>
<dict>
<key>comment</key>
<string>the JSON object key</string>
<key>include</key>
<string>#string</string>
</dict>
<dict>
<key>begin</key>
<string>:</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.separator.dictionary.key-value.json</string>
</dict>
</dict>
<key>end</key>
<string>(,)|(?=\})</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.separator.dictionary.pair.json</string>
</dict>
</dict>
<key>name</key>
<string>meta.structure.dictionary.value.json</string>
<key>patterns</key>
<array>
<dict>
<key>comment</key>
<string>the JSON object value</string>
<key>include</key>
<string>#value</string>
</dict>
<dict>
<key>match</key>
<string>[^\s,]</string>
<key>name</key>
<string>invalid.illegal.expected-dictionary-separator.json</string>
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>[^\s\}]</string>
<key>name</key>
<string>invalid.illegal.expected-dictionary-separator.json</string>
</dict>
</array>
</dict>
<key>string</key>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.json</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.json</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.json</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?x: # turn on extended mode
\\ # a literal backslash
(?: # ...followed by...
["\\/bfnrt] # one of these characters
| # ...or...
u # a u
[0-9a-fA-F]{4} # and four hex digits
)
)</string>
<key>name</key>
<string>constant.character.escape.json</string>
</dict>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>invalid.illegal.unrecognized-string-escape.json</string>
</dict>
</array>
</dict>
<key>value</key>
<dict>
<key>comment</key>
<string>the 'value' diagram at http://json.org</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#constant</string>
</dict>
<dict>
<key>include</key>
<string>#number</string>
</dict>
<dict>
<key>include</key>
<string>#string</string>
</dict>
<dict>
<key>include</key>
<string>#array</string>
</dict>
<dict>
<key>include</key>
<string>#object</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>source.mml</string>
<key>uuid</key>
<string>74FEE366-FF0A-4AAA-B8C5-1C66CECA7F86</string>
</dict>
</plist>