module Puppet::Util::Docs
Some simple methods for helping manage automatic documentation generation.
Constants
- HEADER_LEVELS
Attributes
There is nothing that would ever set this. It gets read in reference/type.rb, but will never have any value but nil.
Public Class Methods
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.
# File lib/puppet/util/docs.rb 114 def scrub(text) 115 # One-liners are easy! (One-liners may be buffered with extra newlines.) 116 return text.strip if text.strip !~ /\n/ 117 excluding_first_line = text.partition("\n").last 118 indent = excluding_first_line.scan(/^[ \t]*(?=\S)/).min || '' # prevent nil 119 # Clean hanging indent, if any 120 if indent.length > 0 121 text = text.gsub(/^#{indent}/, '') 122 end 123 # Clean trailing space 124 text.lines.map{|line|line.rstrip}.join("\n").rstrip 125 end
Public Instance Methods
Specify the actual doc string.
# File lib/puppet/util/docs.rb 4 def desc(str) 5 @doc = str 6 end
Generate
the full doc string.
# File lib/puppet/util/docs.rb 20 def doc 21 extra = methods.find_all { |m| m.to_s =~ /^dochook_.+/ }.sort.collect { |m| 22 self.send(m) 23 }.delete_if {|r| r.nil? }.collect {|r| "* #{r}"}.join("\n") 24 25 if @doc 26 scrub(@doc) + (extra.empty? ? '' : "\n\n#{extra}") 27 else 28 extra 29 end 30 end
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.
# File lib/puppet/util/docs.rb 11 def dochook(name, &block) 12 method = "dochook_#{name}" 13 14 meta_def method, &block 15 end
Build a table
# File lib/puppet/util/docs.rb 33 def doctable(headers, data) 34 str = "\n\n" 35 36 lengths = [] 37 # Figure out the longest field for all columns 38 data.each do |name, values| 39 [name, values].flatten.each_with_index do |value, i| 40 lengths[i] ||= 0 41 lengths[i] = value.to_s.length if value.to_s.length > lengths[i] 42 end 43 end 44 45 # The headers could also be longest 46 headers.each_with_index do |value, i| 47 lengths[i] = value.to_s.length if value.to_s.length > lengths[i] 48 end 49 50 # Add the header names 51 str += headers.zip(lengths).collect { |value, num| pad(value, num) }.join(" | ") + " |" + "\n" 52 53 # And the header row 54 str += lengths.collect { |num| "-" * num }.join(" | ") + " |" + "\n" 55 56 # Now each data row 57 data.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |name, rows| 58 str += [name, rows].flatten.zip(lengths).collect do |value, length| 59 pad(value, length) 60 end.join(" | ") + " |" + "\n" 61 end 62 63 str + "\n" 64 end
# File lib/puppet/util/docs.rb 83 def markdown_definitionlist(term, definition) 84 lines = scrub(definition).split("\n") 85 str = "#{term}\n: #{lines.shift}\n" 86 lines.each do |line| 87 str << " " if line =~ /\S/ 88 str << "#{line}\n" 89 end 90 str << "\n" 91 end
# File lib/puppet/util/docs.rb 79 def markdown_header(name, level) 80 "#{HEADER_LEVELS[level]} #{name}\n\n" 81 end
# File lib/puppet/util/docs.rb 68 def nodoc? 69 nodoc 70 end
Pad a field with spaces
# File lib/puppet/util/docs.rb 73 def pad(value, length) 74 value.to_s + (" " * (length - value.to_s.length)) 75 end
Private Instance Methods
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.
# File lib/puppet/util/docs.rb 114 def scrub(text) 115 # One-liners are easy! (One-liners may be buffered with extra newlines.) 116 return text.strip if text.strip !~ /\n/ 117 excluding_first_line = text.partition("\n").last 118 indent = excluding_first_line.scan(/^[ \t]*(?=\S)/).min || '' # prevent nil 119 # Clean hanging indent, if any 120 if indent.length > 0 121 text = text.gsub(/^#{indent}/, '') 122 end 123 # Clean trailing space 124 text.lines.map{|line|line.rstrip}.join("\n").rstrip 125 end