diff --git a/lib/puppet-strings/markdown.rb b/lib/puppet-strings/markdown.rb index b9e988954..3ef2e9d89 100644 --- a/lib/puppet-strings/markdown.rb +++ b/lib/puppet-strings/markdown.rb @@ -4,30 +4,59 @@ # module for parsing Yard Registries and generating markdown module PuppetStrings::Markdown - require_relative 'markdown/puppet_classes' - require_relative 'markdown/functions' - require_relative 'markdown/defined_types' - require_relative 'markdown/data_types' - require_relative 'markdown/resource_types' - require_relative 'markdown/puppet_tasks' - require_relative 'markdown/puppet_plans' - require_relative 'markdown/table_of_contents' + require_relative 'markdown/puppet_class' + require_relative 'markdown/function' + require_relative 'markdown/defined_type' + require_relative 'markdown/data_type' + require_relative 'markdown/resource_type' + require_relative 'markdown/puppet_task' + require_relative 'markdown/puppet_plan' + + # Get classes that handle collecting and rendering each section/group. + # + # @return [Array[class]] The classes + def self.groups + [ + PuppetStrings::Markdown::PuppetClass, + PuppetStrings::Markdown::DefinedType, + PuppetStrings::Markdown::ResourceType, + PuppetStrings::Markdown::Function, + PuppetStrings::Markdown::DataType, + PuppetStrings::Markdown::PuppetTask, + PuppetStrings::Markdown::PuppetPlan, + ] + end # generates markdown documentation # @return [String] markdown doc def self.generate - final = "# Reference\n\n" - final += "\n\n" - final += PuppetStrings::Markdown::TableOfContents.render - final += PuppetStrings::Markdown::PuppetClasses.render - final += PuppetStrings::Markdown::DefinedTypes.render - final += PuppetStrings::Markdown::ResourceTypes.render - final += PuppetStrings::Markdown::Functions.render - final += PuppetStrings::Markdown::DataTypes.render - final += PuppetStrings::Markdown::PuppetTasks.render - final += PuppetStrings::Markdown::PuppetPlans.render - - final + output = [ + "# Reference\n\n", + "\n\n", + "## Table of Contents\n\n", + ] + + # Create table of contents + template = erb(File.join(__dir__, 'markdown', 'templates', 'table_of_contents.erb')) + groups.each do |group| + group_name = group.group_name + items = group.items.map { |item| item.toc_info } + has_private = items.any? { |item| item[:private] } + has_public = items.any? { |item| !item[:private] } + + output << template.result(binding) + end + + # Create actual contents + groups.each do |group| + items = group.items.reject { |item| item.private? } + unless items.empty? + output << "## #{group.group_name}\n\n" + output.append(items.map { |item| item.render }) + end + end + + output.join('') end # mimicks the behavior of the json render, although path will never be nil @@ -41,4 +70,17 @@ def self.render(path = nil) YARD::Logger.instance.debug "Wrote markdown to #{path}" end end + + # Helper function to load an ERB template. + # + # @param [String] path The full path to the template file. + # @return [ERB] Template + def self.erb(path) + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6.0') + ERB.new(File.read(path), trim_mode: '-') + else + # This outputs warnings in Ruby 2.6+. + ERB.new(File.read(path), nil, '-') + end + end end diff --git a/lib/puppet-strings/markdown/base.rb b/lib/puppet-strings/markdown/base.rb index b0e58a6d9..54110d3ad 100644 --- a/lib/puppet-strings/markdown/base.rb +++ b/lib/puppet-strings/markdown/base.rb @@ -50,6 +50,33 @@ module PuppetStrings::Markdown # ") inherits foo::bar {\n" + # "}"} class Base + # Set or return the name of the group + # + # @param [Optional[String]] Name of the group to set + # @return [String] Name of the group + def self.group_name(name = nil) + @group_name = name if name + @group_name + end + + # Set or return the types registered with YARD + # + # @param [Optional[Array[Symbol]]] Array of symbols registered with YARD to set + # @return [Array[Symbol]] Array of symbols registered with YARD + def self.yard_types(types = nil) + @yard_types = types if types + @yard_types + end + + # @return [Array] list of items + def self.items + yard_types + .flat_map { |type| YARD::Registry.all(type) } + .sort_by(&:name) + .map(&:to_hash) + .map { |i| new(i) } + end + def initialize(registry, component_type) @type = component_type @registry = registry @@ -200,17 +227,4 @@ def clean_link(input) input.tr('^a-zA-Z0-9_-', '-') end end - - # Helper function to load an ERB template. - # - # @param [String] path The full path to the template file. - # @return [ERB] Template - def self.erb(path) - if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6.0') - ERB.new(File.read(path), trim_mode: '-') - else - # This outputs warnings in Ruby 2.6+. - ERB.new(File.read(path), nil, '-') - end - end end diff --git a/lib/puppet-strings/markdown/data_type.rb b/lib/puppet-strings/markdown/data_type.rb index 61fa5debb..3f2040ab1 100644 --- a/lib/puppet-strings/markdown/data_type.rb +++ b/lib/puppet-strings/markdown/data_type.rb @@ -8,6 +8,9 @@ class DataType < Base attr_reader :alias_of attr_reader :functions + group_name 'Data types' + yard_types [:puppet_data_type, :puppet_data_type_alias] + def initialize(registry) @template = 'data_type.erb' super(registry, 'data type') diff --git a/lib/puppet-strings/markdown/data_types.rb b/lib/puppet-strings/markdown/data_types.rb deleted file mode 100644 index 15c842232..000000000 --- a/lib/puppet-strings/markdown/data_types.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require_relative 'data_type' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Data Types. - module DataTypes - # @return [Array] list of data types - def self.in_dtypes - arr = YARD::Registry.all(:puppet_data_type).map!(&:to_hash) - arr.concat(YARD::Registry.all(:puppet_data_type_alias).map!(&:to_hash)) - - arr.sort! { |a, b| a[:name] <=> b[:name] } - arr.map! { |a| PuppetStrings::Markdown::DataType.new(a) } - end - - def self.contains_private? - return if in_dtypes.nil? - in_dtypes.find { |type| type.private? }.nil? ? false : true - end - - def self.render - final = !in_dtypes.empty? ? "## Data types\n\n" : '' - in_dtypes.each do |type| - final += type.render unless type.private? - end - final - end - - def self.toc_info - final = ['Data types'] - - in_dtypes.each do |type| - final.push(type.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/defined_type.rb b/lib/puppet-strings/markdown/defined_type.rb index 4353d98b2..a1a5c084f 100644 --- a/lib/puppet-strings/markdown/defined_type.rb +++ b/lib/puppet-strings/markdown/defined_type.rb @@ -5,6 +5,9 @@ module PuppetStrings::Markdown # Generates Markdown for a Puppet Defined Type. class DefinedType < Base + group_name 'Defined types' + yard_types [:puppet_defined_type] + def initialize(registry) @template = 'classes_and_defines.erb' super(registry, 'defined type') diff --git a/lib/puppet-strings/markdown/defined_types.rb b/lib/puppet-strings/markdown/defined_types.rb deleted file mode 100644 index 1ec19cad3..000000000 --- a/lib/puppet-strings/markdown/defined_types.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'defined_type' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Defined Types. - module DefinedTypes - # @return [Array] list of defined types - def self.in_dtypes - arr = YARD::Registry.all(:puppet_defined_type).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::DefinedType.new(a) } - end - - def self.contains_private? - return if in_dtypes.nil? - in_dtypes.find { |type| type.private? }.nil? ? false : true - end - - def self.render - final = !in_dtypes.empty? ? "## Defined types\n\n" : '' - in_dtypes.each do |type| - final += type.render unless type.private? - end - final - end - - def self.toc_info - final = ['Defined types'] - - in_dtypes.each do |type| - final.push(type.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/function.rb b/lib/puppet-strings/markdown/function.rb index ba0575f7d..da7e215e5 100644 --- a/lib/puppet-strings/markdown/function.rb +++ b/lib/puppet-strings/markdown/function.rb @@ -7,6 +7,9 @@ module PuppetStrings::Markdown class Function < Base attr_reader :signatures + group_name 'Functions' + yard_types [:puppet_function] + def initialize(registry) @template = 'function.erb' super(registry, 'function') diff --git a/lib/puppet-strings/markdown/functions.rb b/lib/puppet-strings/markdown/functions.rb deleted file mode 100644 index d4361a7e9..000000000 --- a/lib/puppet-strings/markdown/functions.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'function' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Functions. - module Functions - # @return [Array] list of functions - def self.in_functions - arr = YARD::Registry.all(:puppet_function).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::Function.new(a) } - end - - def self.contains_private? - return if in_functions.nil? - in_functions.find { |func| func.private? }.nil? ? false : true - end - - def self.render - final = !in_functions.empty? ? "## Functions\n\n" : '' - in_functions.each do |func| - final += func.render unless func.private? - end - final - end - - def self.toc_info - final = ['Functions'] - - in_functions.each do |func| - final.push(func.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/puppet_class.rb b/lib/puppet-strings/markdown/puppet_class.rb index 37ea1698b..aded6739b 100644 --- a/lib/puppet-strings/markdown/puppet_class.rb +++ b/lib/puppet-strings/markdown/puppet_class.rb @@ -5,6 +5,9 @@ module PuppetStrings::Markdown # Generates Markdown for a Puppet Class. class PuppetClass < Base + group_name 'Classes' + yard_types [:puppet_class] + def initialize(registry) @template = 'classes_and_defines.erb' super(registry, 'class') diff --git a/lib/puppet-strings/markdown/puppet_classes.rb b/lib/puppet-strings/markdown/puppet_classes.rb deleted file mode 100644 index ef7b4ce8c..000000000 --- a/lib/puppet-strings/markdown/puppet_classes.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'puppet_class' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Classes. - module PuppetClasses - # @return [Array] list of classes - def self.in_classes - arr = YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::PuppetClass.new(a) } - end - - def self.contains_private? - return if in_classes.nil? - in_classes.find { |klass| klass.private? }.nil? ? false : true - end - - def self.render - final = !in_classes.empty? ? "## Classes\n\n" : '' - in_classes.each do |klass| - final += klass.render unless klass.private? - end - final - end - - def self.toc_info - final = ['Classes'] - - in_classes.each do |klass| - final.push(klass.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/puppet_plan.rb b/lib/puppet-strings/markdown/puppet_plan.rb index 310fc505a..9f55cf279 100644 --- a/lib/puppet-strings/markdown/puppet_plan.rb +++ b/lib/puppet-strings/markdown/puppet_plan.rb @@ -5,6 +5,9 @@ module PuppetStrings::Markdown # Generates Markdown for a Puppet Plan. class PuppetPlan < Base + group_name 'Plans' + yard_types [:puppet_plan] + def initialize(registry) @template = 'classes_and_defines.erb' super(registry, 'plan') diff --git a/lib/puppet-strings/markdown/puppet_plans.rb b/lib/puppet-strings/markdown/puppet_plans.rb deleted file mode 100644 index 4c9406a4b..000000000 --- a/lib/puppet-strings/markdown/puppet_plans.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'puppet_plan' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Plans. - module PuppetPlans - # @return [Array] list of classes - def self.in_plans - arr = YARD::Registry.all(:puppet_plan).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::PuppetPlan.new(a) } - end - - def self.contains_private? - return if in_plans.nil? - in_plans.find { |plan| plan.private? }.nil? ? false : true - end - - def self.render - final = !in_plans.empty? ? "## Plans\n\n" : '' - in_plans.each do |plan| - final += plan.render unless plan.private? - end - final - end - - def self.toc_info - final = ['Plans'] - - in_plans.each do |plan| - final.push(plan.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/puppet_task.rb b/lib/puppet-strings/markdown/puppet_task.rb index 7da80ed23..f2d8a2cfc 100644 --- a/lib/puppet-strings/markdown/puppet_task.rb +++ b/lib/puppet-strings/markdown/puppet_task.rb @@ -5,6 +5,9 @@ module PuppetStrings::Markdown # Generates Markdown for a Puppet Task. class PuppetTask < Base + group_name 'Tasks' + yard_types [:puppet_task] + def initialize(registry) @template = 'puppet_task.erb' @registry = registry diff --git a/lib/puppet-strings/markdown/puppet_tasks.rb b/lib/puppet-strings/markdown/puppet_tasks.rb deleted file mode 100644 index 835cb1f98..000000000 --- a/lib/puppet-strings/markdown/puppet_tasks.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require_relative 'puppet_task' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Tasks. - module PuppetTasks - # @return [Array] list of classes - def self.in_tasks - arr = YARD::Registry.all(:puppet_task).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::PuppetTask.new(a) } - end - - def self.contains_private? - false - end - - def self.render - final = !in_tasks.empty? ? "## Tasks\n\n" : '' - in_tasks.each do |task| - final += task.render unless task.private? - end - final - end - - def self.toc_info - final = ['Tasks'] - - in_tasks.each do |task| - final.push(task.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/resource_type.rb b/lib/puppet-strings/markdown/resource_type.rb index 424cb98e8..f2b9e31aa 100644 --- a/lib/puppet-strings/markdown/resource_type.rb +++ b/lib/puppet-strings/markdown/resource_type.rb @@ -5,6 +5,9 @@ module PuppetStrings::Markdown # Generates Markdown for a Puppet Resource Type. class ResourceType < Base + group_name 'Resource types' + yard_types [:puppet_type] + def initialize(registry) @template = 'resource_type.erb' super(registry, 'type') diff --git a/lib/puppet-strings/markdown/resource_types.rb b/lib/puppet-strings/markdown/resource_types.rb deleted file mode 100644 index e4c87a816..000000000 --- a/lib/puppet-strings/markdown/resource_types.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative 'resource_type' - -module PuppetStrings::Markdown - # Generates Markdown for Puppet Resource Types. - module ResourceTypes - # @return [Array] list of resource types - def self.in_rtypes - arr = YARD::Registry.all(:puppet_type).sort_by!(&:name).map!(&:to_hash) - arr.map! { |a| PuppetStrings::Markdown::ResourceType.new(a) } - end - - def self.contains_private? - return if in_rtypes.nil? - in_rtypes.find { |type| type.private? }.nil? ? false : true - end - - def self.render - final = !in_rtypes.empty? ? "## Resource types\n\n" : '' - in_rtypes.each do |type| - final += type.render unless type.private? - end - final - end - - def self.toc_info - final = ['Resource types'] - - in_rtypes.each do |type| - final.push(type.toc_info) - end - - final - end - end -end diff --git a/lib/puppet-strings/markdown/table_of_contents.rb b/lib/puppet-strings/markdown/table_of_contents.rb deleted file mode 100644 index eaf2bf856..000000000 --- a/lib/puppet-strings/markdown/table_of_contents.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module PuppetStrings::Markdown - # Generates a table of contents. - module TableOfContents - def self.render - final = "## Table of Contents\n\n" - - [PuppetStrings::Markdown::PuppetClasses, - PuppetStrings::Markdown::DefinedTypes, - PuppetStrings::Markdown::ResourceTypes, - PuppetStrings::Markdown::Functions, - PuppetStrings::Markdown::DataTypes, - PuppetStrings::Markdown::PuppetTasks, - PuppetStrings::Markdown::PuppetPlans].each do |r| - toc = r.toc_info - group_name = toc.shift - group = toc - priv = r.contains_private? - - template = File.join(File.dirname(__FILE__), 'templates/table_of_contents.erb') - final += PuppetStrings::Markdown.erb(template).result(binding) - end - final - end - end -end diff --git a/lib/puppet-strings/markdown/templates/table_of_contents.erb b/lib/puppet-strings/markdown/templates/table_of_contents.erb index f20582a3a..72d91e207 100644 --- a/lib/puppet-strings/markdown/templates/table_of_contents.erb +++ b/lib/puppet-strings/markdown/templates/table_of_contents.erb @@ -1,26 +1,26 @@ -<% if group.length > 0 -%> +<% unless items.empty? -%> ### <%= group_name %> +<% if has_public -%> +<% if has_private # only display public heading if we have both -%> -<% if priv -%> #### Public <%= group_name %> +<% end -%> -<% group.each do |item| -%> +<% items.each do |item| -%> <% unless item[:private] -%> * [`<%= item[:name] %>`](#<%= item[:link] %>)<% unless item[:desc].nil? || item[:desc].empty? %>: <%= item[:desc] %><% end %> <% end -%> <% end -%> +<% end -%> +<% if has_private -%> #### Private <%= group_name %> -<% group.each do |item| -%> +<% items.each do |item| -%> <% if item[:private] -%> * `<%= item[:name] %>`<% unless item[:desc].nil? || item[:desc].empty? %>: <%= item[:desc] %><% end %> <% end -%> <% end -%> -<% else -%> -<% group.each do |item| -%> -* [`<%= item[:name] %>`](#<%= item[:link] %>)<% unless item[:desc].nil? || item[:desc].empty? %>: <%= item[:desc] %><% end %> -<% end -%> <% end -%> <% end -%> diff --git a/spec/unit/puppet-strings/markdown_spec.rb b/spec/unit/puppet-strings/markdown_spec.rb index 15652d2d7..0682875ae 100644 --- a/spec/unit/puppet-strings/markdown_spec.rb +++ b/spec/unit/puppet-strings/markdown_spec.rb @@ -2,54 +2,53 @@ require 'spec_helper' require 'puppet-strings/markdown' -require 'puppet-strings/markdown/table_of_contents' require 'tempfile' describe PuppetStrings::Markdown do - let(:fixture_path) do - File.expand_path('../../fixtures', __dir__) - end - let(:output) { described_class.generate } + describe 'rendering fixtures' do + let(:fixture_path) do + File.expand_path('../../fixtures', __dir__) + end + let(:output) { described_class.generate } - def fixture_content(fixture) - File.read(File.join(fixture_path, fixture)) - end + def fixture_content(fixture) + File.read(File.join(fixture_path, fixture)) + end - def parse_shared_content - # Populate the YARD registry with both Puppet and Ruby source - YARD::Parser::SourceParser.parse_string(fixture_content('puppet/class.pp'), :puppet) - YARD::Parser::SourceParser.parse_string(fixture_content('puppet/function.pp'), :puppet) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func4x.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func4x_1.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func3x.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func3x.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/provider.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/resource_type.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/resource_api.rb'), :ruby) - - # task metadata derives the task name from the filename, so we have to parse - # directly from the filesystem to correctly pick up the name - YARD::Parser::SourceParser.parse(File.join(fixture_path, 'json/backup.json')) - end + def parse_shared_content + # Populate the YARD registry with both Puppet and Ruby source + YARD::Parser::SourceParser.parse_string(fixture_content('puppet/class.pp'), :puppet) + YARD::Parser::SourceParser.parse_string(fixture_content('puppet/function.pp'), :puppet) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func4x.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func4x_1.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func3x.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/func3x.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/provider.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/resource_type.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/resource_api.rb'), :ruby) - def parse_plan_content - # the parser behaves differently when parsing puppet files in the the plans directory, - # so we have to parse directly from the filesystem to correctly pick up the name - YARD::Parser::SourceParser.parse(File.join(fixture_path, 'plans/plan.pp')) - end + # task metadata derives the task name from the filename, so we have to parse + # directly from the filesystem to correctly pick up the name + YARD::Parser::SourceParser.parse(File.join(fixture_path, 'json/backup.json')) + end - def parse_data_type_content - YARD::Parser::SourceParser.parse_string(fixture_content('ruby/data_type.rb'), :ruby) - YARD::Parser::SourceParser.parse_string(fixture_content('puppet/type_alias.pp'), :puppet) - end + def parse_plan_content + # the parser behaves differently when parsing puppet files in the the plans directory, + # so we have to parse directly from the filesystem to correctly pick up the name + YARD::Parser::SourceParser.parse(File.join(fixture_path, 'plans/plan.pp')) + end - RSpec.shared_examples 'markdown lint checker' do |_parameter| - it 'does not generate markdown lint errors from the rendered markdown' do - expect(output).to have_no_markdown_lint_errors + def parse_data_type_content + YARD::Parser::SourceParser.parse_string(fixture_content('ruby/data_type.rb'), :ruby) + YARD::Parser::SourceParser.parse_string(fixture_content('puppet/type_alias.pp'), :puppet) + end + + RSpec.shared_examples 'markdown lint checker' do |_parameter| + it 'does not generate markdown lint errors from the rendered markdown' do + expect(output).to have_no_markdown_lint_errors + end end - end - describe 'markdown rendering' do before(:each) do parse_shared_content end @@ -158,4 +157,105 @@ def parse_data_type_content end end end + + it 'renders only private functions correctly' do + expect(YARD::Parser::SourceParser.parse_string(<<~'PUPPET', :puppet).enumerator.length).to eq(1) + # @return void + # @api private + function func_private() {} + PUPPET + + expect(described_class.generate).to eq(<<~'MARKDOWN') + # Reference + + + + ## Table of Contents + + ### Functions + + #### Private Functions + + * `func_private` + + MARKDOWN + end + + it 'renders only public functions correctly' do + expect(YARD::Parser::SourceParser.parse_string(<<~'PUPPET', :puppet).enumerator.length).to eq(1) + # @return void + function func_public() {} + PUPPET + + expect(described_class.generate).to eq(<<~'MARKDOWN') + # Reference + + + + ## Table of Contents + + ### Functions + + * [`func_public`](#func_public) + + ## Functions + + ### `func_public` + + Type: Puppet Language + + The func_public function. + + #### `func_public()` + + The func_public function. + + Returns: `Any` void + + MARKDOWN + end + + it 'renders both public and private functions correctly' do + expect(YARD::Parser::SourceParser.parse_string(<<~'PUPPET', :puppet).enumerator.length).to eq(2) + # @return void + function func_public() {} + + # @return void + # @api private + function func_private() {} + PUPPET + + expect(described_class.generate).to eq(<<~'MARKDOWN') + # Reference + + + + ## Table of Contents + + ### Functions + + #### Public Functions + + * [`func_public`](#func_public) + + #### Private Functions + + * `func_private` + + ## Functions + + ### `func_public` + + Type: Puppet Language + + The func_public function. + + #### `func_public()` + + The func_public function. + + Returns: `Any` void + + MARKDOWN + end end