A documentation string, or "docstring" for short, encapsulates the comments and metadata, or "tags", of an object. Meta-data is expressed in the form +@tag VALUE+, where VALUE can span over multiple lines as long as they are indented. The following +@example+ tag shows how tags can be indented:
# @example My example # a = "hello world" # a.reverse # @version 1.0
Tags can be nested in a documentation string, though the {Tags::Tag} itself is responsible for parsing the inner tags.
Matches a tag at the start of a comment line @deprecated Use {DocstringParser::META_MATCH}
@note Plugin developers should make sure to reset this value
after parsing finishes. This can be done via the {Parser::SourceParser.after_parse_list} callback. This will ensure that YARD can properly parse multiple projects in the same process.
@return [Class<DocstringParser>] the parser class used to parse
text and optional meta-data from docstrings. Defaults to {DocstringParser}.
@see DocstringParser @see Parser::SourceParser.after_parse_list
@return [Range] line range in the {object}'s file where the docstring was parsed from
Creates a new docstring with the raw contents attached to an optional object. Parsing will be done by the {DocstringParser} class.
@note To properly parse directives with proper parser context within
handlers, you should not use this method to create a Docstring. Instead, use the {parser}, which takes a handler object that can pass parser state onto directives. If a Docstring is created with this method, directives do not have access to any parser state, and may not function as expected.
@example
Docstring.new("hello world\n@return Object return", someobj)
@param [String] content the raw comments to be parsed into a docstring
and associated meta-data.
@param [CodeObjects::Base] object an object to associate the docstring
with.
# File lib/yard/docstring.rb, line 99 def initialize(content = '', object = nil) @object = object @summary = nil @hash_flag = false self.all = content end
Creates a new docstring without performing any parsing through a {DocstringParser}. This method is called by DocstringParser when creating the new docstring object.
@param [String] text the textual portion of the docstring @param [Array<Tag>] tags the list of tag objects in the docstring @param [CodeObjects::Base, nil] object the object associated with the
docstring. May be nil.
@param [String] raw_data the complete docstring, including all
original formatting and any unparsed tags/directives.
# File lib/yard/docstring.rb, line 74 def self.new!(text, tags = [], object = nil, raw_data = nil) docstring = allocate docstring.replace(text, false) docstring.object = object docstring.add_tag(*tags) docstring.instance_variable_set("@all", raw_data) if raw_data docstring end
Creates a parser object using the current {default_parser}. Equivalent to:
Docstring.default_parser.new(*args)
@param args arguments are passed to the {DocstringParser}
class. See {DocstringParser#initialize} for details on arguments.
@return [DocstringParser] the parser object used to parse a
docstring.
# File lib/yard/docstring.rb, line 37 def parser(*args) default_parser.new(*args) end
Adds another {Docstring}, copying over tags.
@param [Docstring, String] other the other docstring (or string) to
add.
@return [Docstring] a new docstring with both docstrings combines
# File lib/yard/docstring.rb, line 112 def +(other) case other when Docstring Docstring.new([all, other.all].join("\n"), object) else super end end
Adds a tag or reftag object to the tag list. If you want to parse tag data based on the {Tags::DefaultFactory} tag factory, use {DocstringParser} instead.
@param [Tags::Tag, Tags::RefTag] tags list of tag objects to add @return [void]
# File lib/yard/docstring.rb, line 223 def add_tag(*tags) tags.each_with_index do |tag, i| case tag when Tags::Tag tag.object = object @tags << tag when Tags::RefTag, Tags::RefTagList @ref_tags << tag else raise ArgumentError, "expected Tag or RefTag, got #{tag.class} (at index #{i})" end end end
Returns true if the docstring has no content that is visible to a template.
@param [Boolean] only_visible_tags whether only {Tags::Library.visible_tags}
should be checked, or if all tags should be considered.
@return [Boolean] whether or not the docstring has content
# File lib/yard/docstring.rb, line 291 def blank?(only_visible_tags = true) if only_visible_tags empty? && !tags.any? {|tag| Tags::Library.visible_tags.include?(tag.tag_name.to_sym) } else empty? && @tags.empty? && @ref_tags.empty? end end
Deletes all tags where the block returns true @yieldparam [Tags::Tag] tag the tag that is being tested @yieldreturn [Boolean] true if the tag should be deleted @return [void] @since 0.7.0
# File lib/yard/docstring.rb, line 281 def delete_tag_if(&block) @tags.delete_if(&block) @ref_tags.delete_if(&block) end
Deep-copies a docstring
@note This method creates a new docstring with new tag lists, but does
not create new individual tags. Modifying the tag objects will still affect the original tags.
@return [Docstring] a new copied docstring @since 0.7.0
# File lib/yard/docstring.rb, line 138 def dup obj = super %(all summary tags ref_tags).each do |name| val = instance_variable_get("@#{name}") obj.instance_variable_set("@#{name}", val ? val.dup : nil) end obj end
Returns true if at least one tag by the name name was declared
@param [String] name the tag name to search for @return [Boolean] whether or not the tag name was declared
# File lib/yard/docstring.rb, line 264 def has_tag?(name) tags.any? {|tag| tag.tag_name.to_s == name.to_s } end
# File lib/yard/docstring.rb, line 56 def hash_flag=(v) @hash_flag = v == nil ? false : v end
@return [Fixnum] the first line of the {line_range} @return [nil] if there is no associated {line_range}
# File lib/yard/docstring.rb, line 151 def line line_range ? line_range.first : nil end
Replaces the docstring with new raw content. Called by {all=}. @param [String] content the raw comments to be parsed
# File lib/yard/docstring.rb, line 123 def replace(content, parse = true) content = content.join("\n") if content.is_a?(Array) @tags, @ref_tags = [], [] @all = content super(parse ? parse_comments(content) : content) end
Gets the first line of a docstring to the period or the first paragraph. @return [String] The first line or paragraph of the docstring; always ends with a period.
# File lib/yard/docstring.rb, line 157 def summary return @summary if @summary open_parens = ['{', '(', '['] close_parens = ['}', ')', ']'] num_parens = 0 idx = length.times do |index| case self[index, 1] when ".", "\r", "\n" next_char = self[index + 1, 1].to_s if num_parens == 0 && next_char =~ /^\s*$/ break index - 1 end when "{", "(", "[" num_parens += 1 when "}", ")", "]" num_parens -= 1 end end @summary = self[0..idx] if !@summary.empty? && @summary !~ /\A\s*\{include:.+\}\s*\Z/ @summary += '.' end @summary end
Convenience method to return the first tag object in the list of tag objects of that name
@example
doc = Docstring.new("@return zero when nil") doc.tag(:return).text # => "zero when nil"
@param [to_s] name the tag name to return data for @return [Tags::Tag] the first tag in the list of {tags}
# File lib/yard/docstring.rb, line 246 def tag(name) tags.find {|tag| tag.tag_name.to_s == name.to_s } end
Reformats and returns a raw representation of the tag data using the current tag and docstring data, not the original text.
@return [String] the updated raw formatted docstring data @since 0.7.0 @todo Add Tags::Tag#to_raw and refactor
# File lib/yard/docstring.rb, line 188 def to_raw tag_data = tags.sort_by {|t| t.tag_name }.map do |tag| case tag when Tags::OverloadTag tag_text = "@#{tag.tag_name} #{tag.signature}\n" unless tag.docstring.blank? tag_text += "\n" + tag.docstring.all.gsub(/\r?\n/, "\n ") end when Tags::OptionTag tag_text = "@#{tag.tag_name} #{tag.name}" tag_text += ' [' + tag.pair.types.join(', ') + ']' if tag.pair.types tag_text += ' ' + tag.pair.name.to_s if tag.pair.name tag_text += "\n " if tag.name && tag.text tag_text += ' (' + tag.pair.defaults.join(', ') + ')' if tag.pair.defaults tag_text += " " + tag.pair.text.strip.gsub(/\n/, "\n ") if tag.pair.text else tag_text = '@' + tag.tag_name tag_text += ' [' + tag.types.join(', ') + ']' if tag.types tag_text += ' ' + tag.name.to_s if tag.name tag_text += "\n " if tag.name && tag.text tag_text += ' ' + tag.text.strip.gsub(/\n/, "\n ") if tag.text end tag_text end [strip, tag_data.join("\n")].reject {|l| l.empty? }.compact.join("\n") end
Generated with the Darkfish Rdoc Generator 2.