Module: Puppet::Util::Docs

Overview

Some simple methods for helping manage automatic documentation generation.

Constant Summary collapse

HEADER_LEVELS =
[nil, "#", "##", "###", "####", "#####"]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#docObject

Generate the full doc string.

 22 23 24 25 26 27 28 29 30 31 32
# File 'lib/puppet/util/docs.rb', line 22 def doc extra = methods.find_all { |m| m.to_s =~ /^dochook_.+/ }.sort.filter_map { |m| send(m) }.collect { |r| "* #{r}" }.join("\n") if @doc scrub(@doc) + (extra.empty? ? '' : "\n\n#{extra}") else extra end end

#nodocObject (readonly)

There is nothing that would ever set this. It gets read in reference/type.rb, but will never have any value but nil.

 69 70 71
# File 'lib/puppet/util/docs.rb', line 69 def nodoc @nodoc end

Class Method Details

.scrub(text) ⇒ Object

Strip indentation and trailing whitespace from embedded doc fragments.

Multi-line doc fragments are sometimes indented in order to preserve the formatting of the code they’re embedded in. Since indents are syntactic elements in Markdown, we need to make sure we remove any indent that was added solely to preserve surrounding code formatting, but LEAVE any indent that delineates a Markdown element (code blocks, multi-line bulleted list items). We can do this by removing the *least common indent* from each line.

Least common indent is defined as follows:

  • Find the smallest amount of leading space on any line…

  • …excluding the first line (which may have zero indent without affecting the common indent)…

  • …and excluding lines that consist solely of whitespace.

  • The least common indent may be a zero-length string, if the fragment is not indented to match code.

  • If there are hard tabs for some dumb reason, we assume they’re at least consistent within this doc fragment.

See tests in spec/unit/util/docs_spec.rb for examples.

 117 118 119 120 121 122 123 124 125 126 127 128 129
# File 'lib/puppet/util/docs.rb', line 117 def scrub(text) # One-liners are easy! (One-liners may be buffered with extra newlines.)  return text.strip if text.strip !~ /\n/ excluding_first_line = text.partition("\n").last indent = excluding_first_line.scan(/^[ \t]*(?=\S)/).min || '' # prevent nil  # Clean hanging indent, if any  if indent.length > 0 text = text.gsub(/^#{indent}/, '') end # Clean trailing space  text.lines.map(&:rstrip).join("\n").rstrip end

Instance Method Details

#desc(str) ⇒ Object

Specify the actual doc string.

 6 7 8
# File 'lib/puppet/util/docs.rb', line 6 def desc(str) @doc = str end

#dochook(name, &block) ⇒ Object

Add a new autodoc block. We have to define these as class methods, rather than just sticking them in a hash, because otherwise they’re too difficult to do inheritance with.

 13 14 15 16 17
# File 'lib/puppet/util/docs.rb', line 13 def dochook(name, &block) method = "dochook_#{name}" meta_def method, &block end

#doctable(headers, data) ⇒ Object

Build a table

 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
# File 'lib/puppet/util/docs.rb', line 35 def doctable(headers, data) str = "\n\n" lengths = [] # Figure out the longest field for all columns  data.each do |name, values| [name, values].flatten.each_with_index do |value, i| lengths[i] ||= 0 lengths[i] = value.to_s.length if value.to_s.length > lengths[i] end end # The headers could also be longest  headers.each_with_index do |value, i| lengths[i] = value.to_s.length if value.to_s.length > lengths[i] end # Add the header names  str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" | ") + " |" + "\n" # And the header row  str += lengths.collect { |num| "-" * num }.join(" | ") + " |" + "\n" # Now each data row  data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows| str += [name, rows].flatten.zip(lengths).collect do |value, length| pad(value, length) end.join(" | ") + " |" + "\n" end str + "\n" end

#markdown_definitionlist(term, definition) ⇒ Object

 86 87 88 89 90 91 92 93 94
# File 'lib/puppet/util/docs.rb', line 86 def markdown_definitionlist(term, definition) lines = scrub(definition).split("\n") str = "#{term}\n: #{lines.shift}\n" lines.each do |line| str << " " if line =~ /\S/ str << "#{line}\n" end str << "\n" end

#markdown_header(name, level) ⇒ Object

 82 83 84
# File 'lib/puppet/util/docs.rb', line 82 def markdown_header(name, level) "#{HEADER_LEVELS[level]} #{name}\n\n" end

#nodoc?Boolean

Returns:

  • (Boolean)
 71 72 73
# File 'lib/puppet/util/docs.rb', line 71 def nodoc? nodoc end

#pad(value, length) ⇒ Object

Pad a field with spaces

 76 77 78
# File 'lib/puppet/util/docs.rb', line 76 def pad(value, length) value.to_s + (" " * (length - value.to_s.length)) end