class TaskJuggler::TextFormatter

This class provides a simple text block formatting function. Plain text can be indented and limited to a given text width.

Attributes

firstLineIndent[RW]
indentation[RW]
width[RW]

Public Class Methods

new(width = 80, indentation = 0, firstLineIndent = nil) click to toggle source
# File lib/taskjuggler/TextFormatter.rb, line 23
def initialize(width = 80, indentation = 0, firstLineIndent = nil)
  # The width of the text including the indent.
  @width = width
  # The indent for the first line of a paragraph
  @firstLineIndent = firstLineIndent || indentation
  # The indent for other lines.
  @indentation = indentation
end

Public Instance Methods

format(str) click to toggle source

Format the String str according to the class settings.

# File lib/taskjuggler/TextFormatter.rb, line 73
def format(str)
  # The resulting String.
  @out = ''
  # The column of the last character of the current line.
  @linePos = 0
  # A buffer for the currently processed word.
  @wordBuf = ''
  # True of we are at the beginning of a line.
  @beginOfLine = true
  # A buffer for the indentation to be used for the next line.
  @indentBuf = ' ' * @firstLineIndent
  # The status of the state machine.
  state = :beginOfParagraph

  # Process the input String from start to finish.
  str.each_utf8_char do |c|
    case state
    when :beginOfParagraph
      # We are currently a the beginning of a new paragraph.
      if c == ' ' || c == "\n"
        # ignore it
      else
        # A new word started.
        @wordBuf << c
        state = :inWord
      end
    when :inWord
      # We are in the middle of processing a word.
      if c == ' ' || c == "\n"
        # The word has ended.
        appendWord
        state = c == ' ' ? :betweenWords : :betweenWordsOrLines
      elsif c == "\r"
        # CR is used to start a new line but without starting a new
        # paragraph.
        appendWord
        @indentBuf = "\n" + ' ' * @firstLineIndent
        @beginOfLine = true
        state = :betweenWords
      else
        # Add the character to the word buffer.
        @wordBuf << c
      end
    when :betweenWords
      # We are in between words.
      if c == ' '
        # ignore it
      elsif c == "\n"
        state = :betweenWordsOrLines
      else
        # A new word started.
        @wordBuf << c
        state = :inWord
      end
    when :betweenWordsOrLines
      if c == "\n"
        # The word break is really a paragraph break.
        @indentBuf = "\n\n" + ' ' * @firstLineIndent
        @beginOfLine = true
        state = :beginOfParagraph
      elsif c == ' '
        state = :betweenWords
      else
        @wordBuf << c
        state = :inWord
      end
    else
      raise "Unknown state in state machine: #{state}"
    end
  end
  # Add any still pending word.
  appendWord

  # Always end with a line break
  @out += "\n" unless @out[-1] == "\n"

  @out
end
indent(str) click to toggle source

Add @indentation number of spaces at the beginning of each line. The first line will be indented by @firstLineIndent. Lines that are longer than @width will be clipped.

# File lib/taskjuggler/TextFormatter.rb, line 35
def indent(str)
  out = ''
  # Indentation to be used for the currently processed line. It will be
  # set to nil if it was inserted already.
  indentBuf = ' ' * @firstLineIndent
  linePos = 0
  # Process the input String from start to finish.
  str.each_utf8_char do |c|
    if c == "\n"
      # To prevent trailing white spaces we only insert a line break
      # instead of the indent buffer.
      if indentBuf
        out += "\n"
      end
      # The indent buffer for the next line.
      indentBuf = "\n" + ' ' * @indentation
    else
      # If we still have an indent buffer, we need to insert it first.
      if indentBuf
        out += indentBuf
        linePos = indentBuf.delete("\n").length
        indentBuf = nil
      end
      # Discard all characters that extend of the requested line width.
      if linePos < @width
        out << c
        linePos += 1
      end
    end
  end

  # Always end with a line break
  out += "\n" unless out[-1] == "\n"

  out
end