1 //<script type="text/javascript">
4 XObject = imports.XObject.XObject;
6 Options = imports.Options.Options;
10 * DocTag - represents a single A=b tag.
15 DocTag = XObject.define(
26 this.isOptional = false;
27 this.defaultValue = "";
29 this.optvalues = false;
30 if (typeof src != "undefined") {
48 var ret = { '*object' : 'DocTag' };
51 if (i == 'optvalues') {
52 ret[i] = this.optvalues;
56 switch (typeof(this[i])) {
64 ret[i] = this[i]; continue;
70 print("unknown type: (" + i + ")" + typeof(this[i]));
72 print(JSON.stringify(this));;
82 Populate the properties of this from the given tag src.
85 parse : function(src) {
86 if (typeof src != "string") throw "src must be a string not "+(typeof src);
89 src = this.nibbleTitle(src);
90 //if (JSDOC.PluginManager) {
91 // JSDOC.PluginManager.run("onDocTagSynonym", this);
94 src = this.nibbleType(src);
96 // only some tags are allowed to have names.
97 if (this.title == "param" || this.title == "property" || this.title == "cfg") { // @config is deprecated
98 src = this.nibbleName(src);
102 if (Options.LOG) Options.LOG.warn(e);
106 // if type == @cfg, and matches (|....|...)
109 if (this.title == "cfg" && src.match(/^\([^)]+\)/)) {
110 var m = src.match(/^\(([^)]+)\)/);
112 if (m[1].match(/\|/)) {
113 var opts = m[1].trim().split(/\s*\|\s*/);
114 this.optvalues = opts;
115 src = src.substring(m[0].length).trim();
125 this.desc = src; // whatever is left
127 // example tags need to have whitespace preserved
128 if (this.title != "example") this.desc = this.desc.trim();
130 //if (JSDOC.PluginManager) {
131 // JSDOC.PluginManager.run("onDocTag", this);
136 Automatically called when this is stringified.
138 toString : function() {
144 Find and shift off the title of a tag.
148 nibbleTitle : function(src) {
149 if (typeof src != "string") throw "src must be a string not "+(typeof src);
151 var parts = src.match(/^\s*(\S+)(?:\s([\s\S]*))?$/);
153 if (parts && parts[1]) this.title = parts[1];
154 if (parts && parts[2]) src = parts[2];
161 Find and shift off the type of a tag.
162 @requires frame/String.js
166 nibbleType : function(src)
168 if (typeof src != "string") throw "src must be a string not "+(typeof src);
170 if (src.match(/^\s*\{/)) {
171 var typeRange = this.balance(src,"{", "}");
172 if (typeRange[1] == -1) {
173 throw "Malformed comment tag ignored. Tag type requires an opening { and a closing }: "+src;
175 this.type = src.substring(typeRange[0]+1, typeRange[1]).trim();
176 this.type = this.type.replace(/\s*,\s*/g, "|"); // multiples can be separated by , or |
177 src = src.substring(typeRange[1]+1);
185 Find and shift off the name of a tag.
186 @requires frame/String.js
190 nibbleName : function(src) {
191 if (typeof src != "string") throw "src must be a string not "+(typeof src);
196 if (src.charAt(0) == "[") {
197 var nameRange = this.balance(src,"[", "]");
198 if (nameRange[1] == -1) {
199 throw "Malformed comment tag ignored. Tag optional name requires an opening [ and a closing ]: "+src;
201 this.name = src.substring(nameRange[0]+1, nameRange[1]).trim();
202 this.isOptional = true;
204 src = src.substring(nameRange[1]+1);
206 // has default value?
207 var nameAndValue = this.name.split("=");
208 if (nameAndValue.length) {
209 this.name = nameAndValue.shift().trim();
210 this.defaultValue = nameAndValue.join("=");
214 var parts = src.match(/^(\S+)(?:\s([\s\S]*))?$/);
216 if (parts[1]) this.name = parts[1];
217 if (parts[2]) src = parts[2].trim();
225 balance : function(str, open, close) {
227 while (str.charAt(i) != open) {
228 if (i == str.length) return [-1, -1];
234 while (j < str.length) {
235 if (str.charAt(j) == open) balance++;
236 if (str.charAt(j) == close) balance--;
237 if (balance == 0) break;
239 if (j == str.length) return [-1, -1];
250 DocTag.fromDump = function(t)
252 var ns = new DocTag();
254 if (typeof(ns[i]) == "undefined") {
255 println("ERR:no default for DocTag:"+ i);