From 490b51c6fd1a5b5bd073faea564d09fc75e4928d Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 2 Feb 2011 16:24:20 -0500 Subject: [PATCH] Adding make doc command, making renderer docs better for docco, writing some docs. --- Makefile | 3 + lib/mess/parser.js | 22 +++-- lib/mess/renderer.js | 187 +++++++++++++++++++++++-------------------- 3 files changed, 113 insertions(+), 99 deletions(-) diff --git a/Makefile b/Makefile index d5db06e..7ce1e89 100644 --- a/Makefile +++ b/Makefile @@ -10,4 +10,7 @@ test: bin/expresso -I lib test/${only}.test.js endif +doc: + docco lib/mess/*.js + .PHONY: test diff --git a/lib/mess/parser.js b/lib/mess/parser.js index df871cd..73af6f1 100644 --- a/lib/mess/parser.js +++ b/lib/mess/parser.js @@ -311,10 +311,8 @@ mess.Parser = function Parser(env) { } } - /** - * Get an array of Ruleset objects, flattened - * and sorted according to specificitySort - */ + // Get an array of Ruleset objects, flattened + // and sorted according to specificitySort root.toList = (function() { var line, lines, column, _ = require('underscore')._; return function(env) { @@ -336,15 +334,13 @@ mess.Parser = function Parser(env) { }; })(); - /** - * Sort rules by specificity: this function expects selectors to be - * split already. - * - * Written to be used as a .sort(Function); - * argument. - * - * [1, 0, 0, 467] > [0, 0, 1, 520] - */ + // Sort rules by specificity: this function expects selectors to be + // split already. + // + // Written to be used as a .sort(Function); + // argument. + // + // [1, 0, 0, 467] > [0, 0, 1, 520] var specificitySort = function(a, b) { var as = a.selector.specificity(); var bs = b.selector.specificity(); diff --git a/lib/mess/renderer.js b/lib/mess/renderer.js index f32f942..b8ca3c2 100644 --- a/lib/mess/renderer.js +++ b/lib/mess/renderer.js @@ -9,12 +9,8 @@ var path = require('path'), require.paths.unshift(path.join(__dirname, '..', 'lib')); -/** - * Rendering circuitry for JSON map manifests. - * - * This is node-only for the time being. - */ - +// Rendering circuitry for JSON map manifests. +// This is node-only for the time being. mess.Renderer = function Renderer(env) { env = _.extend({}, env); if (!env.debug) env.debug = false; @@ -23,19 +19,15 @@ mess.Renderer = function Renderer(env) { if (!env.validation_data) env.validation_data = false; return { - /** - * Keep a copy of passed-in environment variables - */ + // Keep a copy of passed-in environment variables env: env, - /** - * Ensure that map layers have a populated SRS value and attempt to - * autodetect SRS if missing. Requires that node-srs is available and - * that any remote datasources have been localized. - * - * @param {Object} m map object. - * @param {Function} callback - */ + // Ensure that map layers have a populated SRS value and attempt to + // autodetect SRS if missing. Requires that node-srs is available and + // that any remote datasources have been localized. + // + // - @param {Object} m map object. + // - @param {Function} callback ensureSRS: function(m, callback) { Step( function autodetectSRS() { @@ -48,6 +40,8 @@ mess.Renderer = function Renderer(env) { fs.readdir(path.dirname(l.Datasource.file), this); }, function(err, files) { + // Confirm that layers have .prj files + // in line with the .shp and .dbf, etc files. var prj = _.detect(files, function(f) { return path.extname(f).toLowerCase() == '.prj'; }); @@ -78,15 +72,13 @@ mess.Renderer = function Renderer(env) { ); }, - /** - * Download any file-based remote datsources. - * - * Usable as an entry point: does not expect any modification to - * the map object beyond JSON parsing. - * - * @param {Object} m map object. - * @param {Function} callback - */ + // Download any file-based remote datsources. + // + // Usable as an entry point: does not expect any modification to + // the map object beyond JSON parsing. + // + // - @param {Object} m map object. + // - @param {Function} callback localizeExternals: function(m, callback) { var that = this; if (env.only_validate === true) { @@ -130,12 +122,10 @@ mess.Renderer = function Renderer(env) { ); }, - /** - * Download any remote stylesheets - * - * @param {Object} m map object. - * @param {Function} callback - */ + // Download any remote stylesheets + // + // - @param {Object} m map object. + // - @param {Function} callback localizeStyle: function(m, callback) { var that = this; Step( @@ -144,6 +134,8 @@ mess.Renderer = function Renderer(env) { m.Stylesheet.forEach(function(s, k) { if (!s.id) { var next = group(); + // TODO: handle stylesheet externals + // that fail. new External(that.env, s) .on('complete', function(external) { m.Stylesheet[k] = external.path(); @@ -159,16 +151,14 @@ mess.Renderer = function Renderer(env) { ); }, - /** - * Compile (already downloaded) styles with mess.js, - * calling callback with an array of [map object, [stylesheet objects]] - * - * Called with the results of localizeStyle or localizeExternals: - * expects not to handle downloading. - * - * @param {Object} m map object. - * @param {Function} callback - */ + // Compile (already downloaded) styles with mess.js, + // calling callback with an array of [map object, [stylesheet objects]] + // + // Called with the results of localizeStyle or localizeExternals: + // expects not to handle downloading. + // + // - @param {Object} m map object. + // - @param {Function} callback style: function(m, callback) { var that = this; Step( @@ -176,8 +166,13 @@ mess.Renderer = function Renderer(env) { var group = this.group(); m.Stylesheet.forEach(function(s) { var next = group(); + // If a stylesheet is an object with an id + // property, it will have a .data property + // as well which can be parsed directly if (s.id) { next(null, [s.id, s.data]); + // Otherwise the value is assumed to be a + // string and is read from the filesystem } else { fs.readFile(s, 'utf-8', function(err, data) { next(err, [s, data]); @@ -191,6 +186,9 @@ mess.Renderer = function Renderer(env) { results.forEach(function(result) { var next = group(); var parsingTime = +new Date; + // Maintain a parsing environment from + // stylesheet to stylesheet, so that frames + // and effects are maintained. var parse_env = _.extend( _.extend( that.env, @@ -219,17 +217,18 @@ mess.Renderer = function Renderer(env) { ); }, - /** - * Split definitions into sub-lists of definitions - * containing rules pertaining to only one - * symbolizer each - */ + // Split definitions into sub-lists of definitions + // containing rules pertaining to only one + // symbolizer each splitSymbolizers: function(definitions) { var splitTime = +new Date; var bySymbolizer = {}; for (var i = 0; i < definitions.length; i++) { definitions[i].symbolizers().forEach(function(sym) { - var index = sym + (definitions[i].selector.attachment ? '/' + definitions[i].selector.attachment : ''); + // Maintain attachments + var index = sym + (definitions[i].selector.attachment ? + '/' + definitions[i].selector.attachment : + ''); if(!bySymbolizer[index]) { bySymbolizer[index] = []; } @@ -237,15 +236,14 @@ mess.Renderer = function Renderer(env) { definitions[i].filterSymbolizer(sym)); }); } - if (env.debug) console.warn('Splitting symbolizers: ' + ((new Date - splitTime)) + 'ms'); + if (env.debug) console.warn('Splitting symbolizers: ' + + ((new Date - splitTime)) + 'ms'); return bySymbolizer; }, - /** - * Pick the 'winners' - all elements that select - * properly. Apply inherited styles from their - * ancestors to them. - */ + // Pick the 'winners' - all elements that select + // properly. Apply inherited styles from their + // ancestors to them. processChain: function(definitions) { var processTime = +new Date(); // definitions are ordered in specificity, @@ -261,8 +259,8 @@ mess.Renderer = function Renderer(env) { } } - if (env.debug) console.warn('Processing time: ' + ((new Date - processTime)) + 'ms'); - + if (env.debug) console.warn('Processing time: ' + + ((new Date - processTime)) + 'ms'); return definitions; }, @@ -294,9 +292,14 @@ mess.Renderer = function Renderer(env) { var filters; for (var id1 in byFilter) { for (var id2 in byFilter) { + // If selectors are identical, they can't be merged. if (id1 === id2) continue; + // If selectors don't cover the exact same zoom range, + // they can't be merged. if (byFilter[id1].zoom != byFilter[id2].zoom) continue; - if (filters = tree.Filter.mergable(byFilter[id1].filters, byFilter[id2].filters)) { + if (filters = tree.Filter.mergable( + byFilter[id1].filters, + byFilter[id2].filters)) { byFilter[id1].filters = filters; delete byFilter[id2]; } @@ -310,6 +313,10 @@ mess.Renderer = function Renderer(env) { return result; }, + // Resolve conditions: with the current state of Mapnik + // and the goal of CSS-like behavior, it is necessary to + // ensure that only one Rule, and thus only one Filter, + // is applied out of a Style. resolveConditions: function(definitions) { var renderer = this; var resolvingTime = +new Date; @@ -364,20 +371,18 @@ mess.Renderer = function Renderer(env) { input = next; } - if (env.debug) console.warn('Resolving time: ' + ((new Date - resolvingTime)) + 'ms'); - // process.exit(); + if (env.debug) console.warn('Resolving time: ' + + ((new Date - resolvingTime)) + 'ms'); return rules; }, - /** - * Find a rule like Map { background-color: #fff; }, - * if any, and return a list of properties to be inserted - * into the