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