Class: TaskJuggler::TextFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/taskjuggler/TextFormatter.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width = 80, indentation = 0, firstLineIndent = nil) ⇒ TextFormatter

Returns a new instance of TextFormatter.



25
26
27
28
29
30
31
32
# File 'lib/taskjuggler/TextFormatter.rb', line 25

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

Instance Attribute Details

#firstLineIndentObject

Returns the value of attribute firstLineIndent.



23
24
25
# File 'lib/taskjuggler/TextFormatter.rb', line 23

def firstLineIndent
  @firstLineIndent
end

#indentationObject

Returns the value of attribute indentation.



23
24
25
# File 'lib/taskjuggler/TextFormatter.rb', line 23

def indentation
  @indentation
end

#widthObject

Returns the value of attribute width.



23
24
25
# File 'lib/taskjuggler/TextFormatter.rb', line 23

def width
  @width
end

Instance Method Details

#format(str) ⇒ Object

Format the String str according to the class settings.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/taskjuggler/TextFormatter.rb', line 75

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) ⇒ Object

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.



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
67
68
69
70
71
72
# File 'lib/taskjuggler/TextFormatter.rb', line 37

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