docs: function exportFilter(feed,filter,filterName) {
  
  	var optionCount = 0;
  
  	var s = '/**\n';
  	s += '* '+filter.title+'\n';
  	if (filter.href) {
  		if (!checkHref(filter.href,filter.name)) {
  			console.log('! filter '+filterName+'('+filter.name+') does not appear in');
  			console.log('  '+filter.href);
  		}
  		s += '* '+filter.href+'\n';
  	}
  	if (filter.type) {
  		s += '* type = '+filter.type+'\n';
  	}
  	if (filter.default) {
  		s += '* default = '+filter.default+'\n';
  	}
  	if (filter.multiple_values) {
  		s += '* multiple_values = '+filter.multiple_values+'\n';
  	}
  	if (filter.min_value) {
  		s += '* min_value = '+filter.min_value+'\n';
  	}
  	if (filter.max_value) {
  		s += '* max_value = '+filter.max_value+'\n';
  	}
  	if (filter.depends_on) {
  		s += '* depends_on = '+filter.depends_on+'\n';
  	}
  	if (filter.prefer) {
  		s += '* prefer = '+filter.prefer+'\n';
  	}
  	if (filter.prohibits) {
  		s += prohibits(filter.prohibits);
  	}
  	if (filter.affected_by) {
  		if (filter.affected_by.filter) {
  			for (var i=0;i<filter.affected_by.filter.length;i++) {
  				s += '* is affected by filter '+filter.affected_by.filter[i].name+' ('+filter.affected_by.filter[i].description+')\n';
  			}
  		}
  	}
  
  	if (filter.option) {
  		filter.option = toArray(filter.option);
  		for (var i in filter.option) {
  			var option = filter.option[i];
  			if (option.title) {
  				s += '* option: '+option.value+', '+option.title+'\n';
  				s += '*/\n';
  				var optionName = filterName+('-'+option.value).toCamelCase();
  				cache.push(optionName+' : '+optionName +',\n');
  				fs.appendFileSync(apijs, s+'const '+optionName+" = '"+filter.name+'='+encodeURIComponent(option.value)+"';\n", 'utf8');
  				s = '/**\n';
  				seen.push(optionName);
  				//optionCount++;
  			}
  			if (option.href) {
  				s += '* '+option.href+'\n';
  				if (!checkHref(option.href,option.value)) {
  					console.log('! option '+filterName+'('+option.value+') does not exist in');
  					console.log('  '+option.href);
  				}
  			}
  
  			var param = {};
  			for (var p in params) {
  				if (params[p].name == filter.name) {
  					param = params[p];
  				}
  			}
  			if (!param.name) {
  				param.name = filter.name;
  				param.in = 'query';
  				param.description = filter.title;
  				param.schema = {};
  				param.schema.type = 'array';
  				//param.collectionFormat = 'multi';
  				param.schema.items = {};
  				param.schema.items.type = 'string';
  				param.required = false;
  				param.schema.items.enum = [];
  				params.push(param);
  			}
  			param.schema.items.enum.push(option.value);
  
  			// TODO unstable filters
  
  		}
  	}
  	s += '*/\n';
  	fs.appendFileSync(apijs, s+'const '+filterName+" = '"+filter.name+"';\n", 'utf8');
  	cache.push(filterName + ' : '+filterName +',\n');
  
  	if (optionCount<1) {
  		var param = {};
  		for (var p in params) {
  			if (params[p].name == filter.name) {
  				param = params[p];
  			}
  		}
  		if (!param.name) {
  			param.name = filter.name;
  			param.in = 'query';
  			param.description = filter.title;
  			param.schema = {};
  			param.schema.type = filter.type;
  			if (filter.type == 'PID') {
  				param.schema.type = 'string';
  				param.schema.minLength = 8;
  				param.schema.pattern = "^([0-9,a-d,f-h,j-n,p-t,v-z]){8,}$";
  			}
  			if (filter.type == 'ID') {
  				param.schema.type = 'string';
  			}
  			if (filter.type == 'datetime') {
  				param.schema.type = 'string';
  				param.schema.format = 'date-time';
  			}
  			if (filter.type == 'date') {
  				param.schema.type = 'string';
  				param.schema.format = 'date';
  			}
  			if (filter.type == 'character') {
  				param.schema.type = 'string';
  				param.schema.minLength = 1;
  				param.schema.maxLength = 1;
  			}
  			if (filter.default) {
  				param.schema.default = filter.default;
  				if (param.schema.type == 'integer') {
  					param.schema.default = parseInt(filter.default,10);
  				}
  			}
  			if (filter.min_value) {
  				param.schema.minimum = filter.min_value;
  			}
  			if (filter.max_value) {
  				param.schema.maximum = filter.max_value;
  			}
  			if (filter.multiple_values === true) {
  				param.schema.items = {};
  				param.schema.items.type = param.schema.type;
  				param.schema.type = 'array';
  				//param.collectionFormat = 'multi';
  				if (param.schema.default) {
  					param.schema.items.default = param.schema.default;
  					delete param.schema.default;
  				}
  				if (param.schema.pattern) {
  					param.schema.items.pattern = param.schema.pattern;
  					delete param.schema.pattern;
  				}
  				if (param.schema.minLength) {
  					param.schema.items.minLength = param.schema.minLength;
  					delete param.schema.minLength;
  				}
  				if (param.schema.maxLength) {
  					param.schema.items.maxLength = param.schema.maxLength;
  					delete param.schema.maxLength;
  				}
  			}
  			param.required = false;
  			if (filter.release_status == 'deprecated') {
  				param.deprecated = true;
  			}
  			params.push(param);
  		}
  	}
  
  	return optionCount;
  }