Skip to content
Rene Saarsoo edited this page Jun 4, 2013 · 5 revisions

Often we want to create a tag that uses syntax like this:

@mytag {String/Number} [varname="Hello world"]

We call this a standard tag and there's a simple builtin way for parsing these: the scanner.standard_tag method:

def parse_doc(scanner, position)
  scanner.standard_tag({
    :tagname => :mytag,
    :type => true,
    :name => true,
    :default => true,
    :optional => true,
  })
end

The :tagname field is simply returned as is, the rest are flags specifying what to parse and return.

  • :type - parses the type definition in curly brackets.
  • :name - parses the member name.
  • :default - parses the default value after member name.
  • :optional - parses the square brackets around the name and default, returning true when they're present and false when not.

In the case of our example scanner.standard_tag will return the following hash:

{
  :tagname => :mytag,
  :type => "String/Number",
  :name => "varname",
  :default => "Hello world",
  :optional => true,
}

Example

Let's define a @constant tag which will work just like a @property, but with the semantic difference of documenting unchangeable values. For example:

/**
 * @constant {Number} GRAVITY=9.80665
 * Acceleration of objects in Earth's gravitational field.
 */

Here's our implementation:

require "jsduck/tag/tag"
require "cgi"

class Constant < JsDuck::Tag::MemberTag
  def initialize
    @tagname = :constant
    @pattern = "constant"
    @member_type = {
      :title => "Constants",
      :position => MEMBER_POS_CFG - 0.1,
      :icon => File.dirname(__FILE__) + "/constant.png",
    }
  end

  def parse_doc(scanner, position)
    scanner.standard_tag({
      :tagname => :constant,
      :type => true,
      :name => true,
      :default => true,
    })
  end

  def process_doc(context, tags, pos)
    t = tags[0]
    context[:name] = t[:name]
    context[:type] = t[:type]
    context[:default] = t[:default]
  end

  def to_html(member, cls)
    member_link(member) + " : " + CGI.escapeHTML(member[:default] || "")
  end
end

The initialize should be obvious.

In parse_doc we leave out the :optional flag of scanner.standard_tag (constants must always have a value). So when parsing our example code, our parse_doc will return the following hash:

{
  :tagname => :constant,
  :type => "Number",
  :name => "GRAVITY",
  :default => "9.80665"
}

Later in process_doc we assign those values separately to the context hash and JSDuck will already know how to treat them.

Finally in to_html we print out the name of our constant and it's value (which we also escape with Ruby's standard HTML escaping routine), so the result looks like this:

Screenshot of custom constant member type