docs: function(func) {
        if (w.isString(func)) {
          return func;
        } else if (!w.isFunction(func)) {
          return w.str(func);
        }
  
        var lines = w.str(func).split(/\r?\n/);
        var i = 0, j = 0, len = lines.length;
        var startIndex, endIndex;
        var endTag, options = {};
        var dent = null;
  
        // Find the start line.
        while (i < len) {
          var start = lines[i++].match(/^[ \t]*\/\*\*?!?<<<(\w+)(?:;(.+)?)?$/);
          if (!start) {
            continue;
          }
          startIndex = i;
          endTag = start[1];
          var optionTags = (start[2] || '').split(/[ \t]*,[ \t]*/);
          for (j = 0; j < optionTags.length; ++j) {
            var tag = optionTags[j].toLowerCase().split(/-(.*)/);
            if (tag[0]) {
              options[tag[0]] = tag[1] || true;
            }
          }
          break;
        }
        if (!startIndex) {
          w.error('Format failed: start line missing');
        }
  
        // The default WS option is "OUTDENT".
        options.ws = options.ws || 'outdent';
  
        var result = [];
  
        // Find the end line.
        while (i < len) {
          var line = lines[i];
          if (line.match(new RegExp('^[ \\t]*' + endTag + '\\*\\/'))) {
            endIndex = i;
            break;
          }
          i++;
          // Count the dent here.
          if (options.ws === 'outdent') {
            var match = line.match(/^([ \t]*).*$/);
            var cur = match[1];
            if (dent === null) {
              dent = cur;
            } else {
              j = 0;
              while (j < dent.length && j < cur.length && dent[j] === cur[j]) {
                j++;
              }
              if (dent.length > j) {
                dent = dent.substring(0, j);
              }
            }
          }
          result.push(line);
        }
        if (!endIndex) {
          w.error('Format failed: end line missing');
        }
  
        var wsFunc;
        switch (options.ws) {
          case 'outdent':
            wsFunc = function(s) {
              return s.substring(dent.length);
            };
            break;
          case 'keep':
            wsFunc = w.identity;
            break;
          case 'trim':
            wsFunc = function(s) {
              return s.trim();
            };
            break;
          default:
            w.error('Format failed: Unsupported WS option');
        }
  
        for (i = 0, len = result.length; i < len; ++i) {
          result[i] = wsFunc(result[i]);
        }
  
        return result.join('\n');
      }