diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb
index edebfa0..900985f 100644
--- a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/docstring.erb
@@ -27,23 +27,7 @@
Return:
-
-
- <% if !@class_details[:return][1].nil? %>
- (
- <% @class_details[:return][1].each do |type| %>
- <%= type %>
- <% if @class_details[:return][1].last != type %>
- ,
- <% end %>
- <% end %>
- ) —
- <% end %>
-
- <% if !@class_details[:return][0].nil? %>
-
-
<%= @class_details[:return][0] %>
-
- <% end %>
+ <%= @html_helper.generate_return_types(@class_details[:return][1], @class_details[:return][0]) %>
<% end %>
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb
index b55a473..a085ac0 100644
--- a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/html/parameter_details.erb
@@ -1,41 +1,6 @@
Parameter Summary
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/setup.rb b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/setup.rb
index adc2778..39ae076 100644
--- a/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/setup.rb
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/definedtype/setup.rb
@@ -1,7 +1,13 @@
include T('default/module')
+require File.join(File.dirname(__FILE__),'../html_helper')
+require File.join(File.dirname(__FILE__),'../template_helper')
+
def init
sections :header, :box_info, :pre_docstring, :docstring, :parameter_details
+
+ @template_helper = TemplateHelper.new
+ @html_helper = HTMLHelper.new
end
def parameter_details
@@ -12,7 +18,7 @@ def parameter_details
@param_details = []
- @param_details = extract_param_details(params, param_tags)
+ @param_details = @template_helper.extract_param_details(params, param_tags, true)
erb(:parameter_details)
end
@@ -30,63 +36,8 @@ def header
end
def docstring
- examples = Hash.new
- example_tags = object.tags.find_all { |tag| tag.tag_name == "example" }
- example_tags.each do |example|
- examples["#{example.name}"] = example.text
- end
- return_tag = object.tags.find { |tag| tag.tag_name == "return"}
- return_text = return_tag.nil? ? nil : return_tag.text
- return_types = return_tag.nil? ? nil : return_tag.types
- return_details = (return_text.nil? && return_types.nil?) ? nil : [return_text, return_types]
-
- since_tag = object.tags.find { |tag| tag.tag_name == "since"}
- since_text = since_tag.nil? ? nil : since_tag.text
-
- @class_details = {:name => object.name, :desc => object.docstring, :examples => examples, :since => since_text, :return => return_details}
+ @class_details = @template_helper.extract_tag_data(object)
erb(:docstring)
end
-
-# Given the parameter information and YARD param tags, extracts the
-# useful information and returns it as an array of hashes which can
-# be printed and formatted in the paramters_details erb file
-#
-# @param params_hash [Array] parameter details obtained programmatically
-# @param tags_hash [Array] parameter details obtained from comments
-#
-# @return [Hash] The relevant information about each parameter
-# @option opts [String] :name The name of the parameter
-# @option opts [String] :fq_name The fully qualified parameter name
-# @option opts [String] :desc The description provided in the comment
-# @options opts [Array] :types The parameter type(s) specified in the comment
-# @options opts [Boolean] :exists? True only if the parameter exists in the documented logic and not just in a comment
-def extract_param_details(params_hash, tags_hash)
- parameter_info = []
-
- # Extract the information for parameters that actually exist
- params_hash.each do |param|
- param_tag = tags_hash.find { |tag| tag.name == param[0] }
-
- description = param_tag.nil? ? nil : param_tag.text
- param_types = param_tag.nil? ? nil : param_tag.types
-
- parameter_info.push({:name => param[0], :fq_name => param[1], :desc => description, :types => param_types, :exists? => true})
- end
-
- # Check if there were any comments for parameters that do not exist
- tags_hash.each do |tag|
- param_exists = false
- parameter_info.each do |parameter|
- if parameter[:name] == tag.name
- param_exists = true
- end
- end
- if !param_exists
- parameter_info.push({:name => tag.name, :fq_name => nil, :desc => tag.text, :types => tag.types, :exists? => false})
- end
- end
-
- parameter_info
-end
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/html_helper.rb b/lib/puppetx/puppetlabs/strings/yard/templates/default/html_helper.rb
new file mode 100644
index 0000000..b9a4a58
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/html_helper.rb
@@ -0,0 +1,68 @@
+# A class containing helper methods to aid the generation of HTML
+# given formatted data
+class HTMLHelper
+
+ # Generates the HTML to format the relevant data about return values
+ def generate_return_types(types, desc = nil)
+ result = []
+
+ result << "(" << types.join(", ") << ")"
+
+ if !desc.nil?
+ result << "- "
+ end
+
+ result.join
+ end
+
+ # Generates the HTML to format the relevant data about parameters
+ def generate_parameters(params)
+ result = []
+
+ params.each do |param|
+ result << ""
+
+ # Parameters which are documented in the comments but not
+ # present in the code itself are given the strike through
+ # styling in order to show the reader that they do not actually
+ # exist
+ if !param[:exists?]
+ result << ""
+ end
+
+ result << "#{param[:name]} "
+ result << ""
+
+ if param[:types]
+ result << "(" << "" << param[:types].join(", ") << "" << ")"
+ # Don't bother with TBD since 3x functions will never have type info per parameter.
+ # However if the user does want to list a type for some reason that is still supported,
+ # we just don't want to suggest that they need to
+ elsif !param[:puppet_3_func]
+ result << "(TBD)"
+ end
+
+ result << ""
+
+ # This is only relevant for manifests, not puppet functions
+ # This is due to the fact that the scope of a parameter (as illustrated by
+ # by it's fully qualified name) is not relevant for the parameters in puppet
+ # functions, but may be for components of a manifest (i.e. classes)
+ unless param[:fq_name].nil?
+ result << " => #{param[:fq_name]}"
+ end
+
+ if param[:desc]
+ result << "- "
+ end
+
+ if !param[:exists?]
+ result << ""
+ end
+
+ result << ""
+ end
+
+ result.join
+ end
+end
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/box_info.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/box_info.erb
new file mode 100644
index 0000000..1780c32
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/box_info.erb
@@ -0,0 +1,11 @@
+
+ - Defined in:
+ -
+ <% @source_files.each do |file| %>
+ <%= file[0] %>:
+ <%= file[1] %>
+
+ <% end %>
+
+
+
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/header.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/header.erb
new file mode 100644
index 0000000..74b3dba
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/header.erb
@@ -0,0 +1,5 @@
+
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_details_list.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_details_list.erb
new file mode 100644
index 0000000..8050727
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_details_list.erb
@@ -0,0 +1,53 @@
+Function Details
+<% @class_details.each do |func| %>
+ >
+
+ <% if func[:return] %>
+ <%= @html_helper.generate_return_types(func[:return][1]) %>
+ <% end %>
+ <%= func[:name] %>
+
+
+
+
+
<%= htmlify(func[:desc]) %>
+
+
+
+<% end %>
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_summary.erb b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_summary.erb
new file mode 100644
index 0000000..11ec619
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/html/method_summary.erb
@@ -0,0 +1,20 @@
+Available Functions
+
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb
index cf37b36..054cee2 100644
--- a/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/puppetnamespace/setup.rb
@@ -1,7 +1,89 @@
include T('default/module')
+require File.join(File.dirname(__FILE__),'../html_helper')
+require File.join(File.dirname(__FILE__),'../template_helper')
+
def init
- sections :header, :box_info, :pre_docstring, T('docstring'),
+ sections :header, :box_info,
:method_summary, [:item_summary],
:method_details_list, [T('method_details')]
+
+ @methods = object.children
+ @template_helper = TemplateHelper.new
+end
+
+def header
+ # The list is expected to only contain one type of function
+ if @methods[0]['puppet_4x_function']
+ @header_text = "Puppet 4 Functions"
+ else
+ @header_text = "Puppet 3 Functions"
+ end
+
+ erb(:header)
+end
+
+def box_info
+ @source_files = []
+
+ @methods.each do |method|
+ # extract the file name and line number for each method
+ file_name = method.files[0][0]
+ line_number = method.files[0][1]
+
+ @source_files.push([method.name, "#{file_name} (#{line_number})"])
+ end
+
+ erb(:box_info)
+end
+
+def method_summary
+ @method_details = []
+ @html_helper = HTMLHelper.new
+
+ @methods.each do |method|
+ # If there are multiple sentences in the method description, only
+ # use the first one for the summary. If the author did not include
+ # any periods in their summary, include the whole thing
+ first_sentence = method.docstring.match(/^(.*?)\./)
+ brief_summary = first_sentence ? first_sentence : method.docstring
+
+ return_tag = method.tags.find { |tag| tag.tag_name == "return"}
+ return_types = return_tag.nil? ? nil : return_tag.types
+
+ @method_details.push({:name => method.name, :short_desc => brief_summary, :return_types => return_types})
+ end
+
+ erb(:method_summary)
+end
+
+def method_details_list
+ @class_details = []
+ @html_helper = HTMLHelper.new
+
+ @methods.each do |object|
+
+ method_info = @template_helper.extract_tag_data(object)
+ param_details = nil
+ param_tags = object.tags.find_all{ |tag| tag.tag_name == "param"}
+
+ if object['puppet_4x_function']
+ # Extract the source code
+ source_code = object.source
+ # Extract the parameters for the source code
+ parameters = source_code.match(/(?:def .*)\((.*?)\)/)
+ # Convert the matched string into an array of strings
+ params = parameters.nil? ? nil : parameters[1].split(/\s*,\s*/)
+
+ param_details = @template_helper.extract_param_details(params, param_tags) unless params.nil?
+ else
+ param_details = @template_helper.comment_only_param_details(param_tags)
+ end
+
+ method_info[:params] = param_details
+
+ @class_details.push(method_info)
+ end
+
+ erb(:method_details_list)
end
diff --git a/lib/puppetx/puppetlabs/strings/yard/templates/default/template_helper.rb b/lib/puppetx/puppetlabs/strings/yard/templates/default/template_helper.rb
new file mode 100644
index 0000000..40cf94e
--- /dev/null
+++ b/lib/puppetx/puppetlabs/strings/yard/templates/default/template_helper.rb
@@ -0,0 +1,107 @@
+# A class containing helper methods to aid in the extraction of relevant data
+# from comments and YARD tags
+class TemplateHelper
+
+ # Extracts data from comments which include the supported YARD tags
+ def extract_tag_data(object)
+ examples = Hash.new
+ example_tags = object.tags.find_all { |tag| tag.tag_name == "example" }
+ example_tags.each do |example|
+ examples["#{example.name}"] = example.text
+ end
+
+ return_tag = object.tags.find { |tag| tag.tag_name == "return"}
+ return_text = return_tag.nil? ? nil : return_tag.text
+ return_types = return_tag.nil? ? nil : return_tag.types
+ return_details = (return_text.nil? && return_types.nil?) ? nil : [return_text, return_types]
+
+ since_tag = object.tags.find { |tag| tag.tag_name == "since"}
+ since_text = since_tag.nil? ? nil : since_tag.text
+
+ {:name => object.name, :desc => object.docstring, :examples => examples, :since => since_text, :return => return_details}
+ end
+
+ # Given the parameter information and YARD param tags, extracts the
+ # useful information and returns it as an array of hashes which can
+ # be printed and formatted as HTML
+ #
+ # @param parameters [Array] parameter details obtained programmatically
+ # @param tags_hash [Array] parameter details obtained from comments
+ # @param fq_name [Boolean] does this parameter have a fully qualified name?
+ #
+ # @return [Hash] The relevant information about each parameter with the following keys/values:
+ # {:name => [String] The name of the parameter
+ # :fq_name => [String] The fully qualified parameter name
+ # :desc => [String] The description provided in the comment
+ # :types => [Array] The parameter type(s) specified in the comment
+ # :exists => [Boolean] True only if the parameter exists in the documented logic and not just in a comment}
+ def extract_param_details(parameters, tags_hash, fq_name = false)
+ parameter_info = []
+
+ # Extract the information for parameters that actually exist
+ # as opposed to parameters that are defined only in the comments
+ parameters.each do |param|
+
+ if fq_name
+ param_name = param[0]
+ fully_qualified_name = param[1]
+ else
+ param_name = param
+ end
+
+ param_tag = tags_hash.find { |tag| tag.name == param_name }
+
+ description = param_tag.nil? ? nil : param_tag.text
+ param_types = param_tag.nil? ? nil : param_tag.types
+
+ param_details = {:name => param_name, :desc => description, :types => param_types, :exists? => true}
+
+ if fq_name
+ param_details[:fq_name] = fully_qualified_name
+ end
+
+ parameter_info.push(param_details)
+ end
+
+ # Check if there were any comments for parameters that do not exist
+ tags_hash.each do |tag|
+ param_exists = false
+ parameter_info.each do |parameter|
+ if parameter[:name] == tag.name
+ param_exists = true
+ end
+ end
+ if !param_exists
+ parameter_info.push({:name => tag.name, :desc => tag.text, :types => tag.types, :exists? => false})
+ end
+ end
+
+ parameter_info
+ end
+
+ # Generates parameter information in situations where the information can only
+ # come from YARD tags in the comments, not from the code itself. For now the only
+ # use for this is 3x functions. In this case exists? will always be true since we
+ # cannot verify if the parameter exists in the code itself. We must trust the user
+ # to provide information in the comments that is accurate.
+ #
+ # @param param_tags [Array] parameter details obtained from comments
+ #
+ # @return [Hash] The relevant information about each parameter with the following keys/values:
+ # {:name => [String] The name of the parameter
+ # :desc => [String] The description provided in the comment
+ # :types => [Array] The parameter type(s) specified in the comment
+ # :exists => [Boolean] True only if the parameter exists in the documented logic and not just in a comment
+ # :puppet_3_func => [Boolean] Are these parameters for a puppet 3 function? (relevant in HTML generation)}
+ def comment_only_param_details(param_tags)
+ return if param_tags.empty?
+
+ parameter_info = []
+
+ param_tags.each do |tag|
+ parameter_info.push({:name => tag.name, :desc => tag.text, :types => tag.types, :exists? => true, :puppet_3_func => true})
+ end
+
+ parameter_info
+ end
+end