Class: Oppen::Wadler

Inherits:
Object
  • Object
show all
Defined in:
lib/wadler/print.rb

Overview

Wadler.

Instance Attribute Summary collapse

Helpers collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: Config.wadler, space: ' ', new_line: "\n", out: StringIO.new, width: 80, whitespace: ' ') ⇒ Wadler

Returns a new instance of Wadler.

Parameters:

  • config (Oppen::Config) (defaults to: Config.wadler)
  • space (String, Proc) (defaults to: ' ')

    could be a String or a callable. If it's a string, spaces will be generated with the the lambda ->(n){ n * space }, where n is the number of columns to indent. If it's a callable, it will receive n and it needs to return a string.

  • new_line (String) (defaults to: "\n")
  • out (Object) (defaults to: StringIO.new)

    should have a write and string method

  • width (Integer) (defaults to: 80)
  • whitespace (String) (defaults to: ' ')

    the whitespace character. Used to trim trailing whitespaces.

See Also:



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/wadler/print.rb', line 28

def initialize(config: Config.wadler, space: ' ',
               new_line: "\n", out: StringIO.new,
               width: 80, whitespace: ' ')
  @config = config
  @current_indent = 0
  @space = space
  @width = width
  @new_line = new_line
  @out = out
  @tokens = []
  @whitespace = whitespace
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



7
8
9
# File 'lib/wadler/print.rb', line 7

def config
  @config
end

#current_indentObject (readonly)

Returns the value of attribute current_indent.



8
9
10
# File 'lib/wadler/print.rb', line 8

def current_indent
  @current_indent
end

#new_lineObject (readonly)

Returns the value of attribute new_line.



10
11
12
# File 'lib/wadler/print.rb', line 10

def new_line
  @new_line
end

#outObject (readonly)

Returns the value of attribute out.



11
12
13
# File 'lib/wadler/print.rb', line 11

def out
  @out
end

#spaceObject (readonly)

Returns the value of attribute space.



9
10
11
# File 'lib/wadler/print.rb', line 9

def space
  @space
end

#tokensObject (readonly)

Returns the value of attribute tokens.



12
13
14
# File 'lib/wadler/print.rb', line 12

def tokens
  @tokens
end

#whitespaceObject (readonly)

Returns the value of attribute whitespace.



13
14
15
# File 'lib/wadler/print.rb', line 13

def whitespace
  @whitespace
end

#widthObject (readonly)

Returns the value of attribute width.



14
15
16
# File 'lib/wadler/print.rb', line 14

def width
  @width
end

Instance Method Details

#add_missing_begin_and_endNil

Add missing Begin, End or EOF tokens.

Returns:

  • (Nil)


43
44
45
46
47
48
49
# File 'lib/wadler/print.rb', line 43

def add_missing_begin_and_end
  if !tokens.first.is_a? Token::Begin
    tokens.unshift Oppen.begin_consistent(offset: 0)
    tokens << Oppen.end
  end
  tokens << Oppen.eof if !tokens.last.is_a?(Oppen::Token::EOF)
end

#base_indent(indent = 0) ⇒ Nil

Set a base indenetaion level to the printer.

Parameters:

  • indent (Integer) (defaults to: 0)

Returns:

  • (Nil)


171
172
173
# File 'lib/wadler/print.rb', line 171

def base_indent(indent = 0)
  @current_indent = indent if !indent.nil?
end

#break(line_continuation: '') ⇒ Nil

Parameters:

  • line_continuation (String) (defaults to: '')

    If a new line is needed display this string before the new line

Returns:

  • (Nil)


160
161
162
# File 'lib/wadler/print.rb', line 160

def break(line_continuation: '')
  tokens << Oppen.line_break(line_continuation:, offset: current_indent)
end

#breakable(str = ' ', width: str.length, line_continuation: '') ⇒ Nil

Parameters:

  • str (String) (defaults to: ' ')
  • line_continuation (String) (defaults to: '')

    If a new line is needed display this string before the new line

Returns:

  • (Nil)


153
154
155
# File 'lib/wadler/print.rb', line 153

def breakable(str = ' ', width: str.length, line_continuation: '')
  tokens << Oppen.break(str, width:, line_continuation:, offset: current_indent)
end

#group(indent = 0, open_obj = '', close_obj = '', break_type = Oppen::Token::BreakType::CONSISTENT) { ... } ⇒ Nil

Parameters:

  • indent (Integer) (defaults to: 0)

    group indentation

  • open_obj (String) (defaults to: '')

    group opening delimiter

  • close_obj (String) (defaults to: '')

    group closing delimiter

  • break_type (Oppen::Token::BreakType) (defaults to: Oppen::Token::BreakType::CONSISTENT)

    group breaking type

Yields:

  • the block of text in a group

Returns:

  • (Nil)

Raises:

  • (ArgumentError)


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
# File 'lib/wadler/print.rb', line 77

def group(indent = 0, open_obj = '', close_obj = '',
          break_type = Oppen::Token::BreakType::CONSISTENT)
  raise ArgumentError, "#{open_obj.nil? ? 'open_obj' : 'close_obj'} cannot be nil" \
    if open_obj.nil? || close_obj.nil?

  tokens <<
    case break_type
    in Oppen::Token::BreakType::CONSISTENT
      Oppen.begin_consistent(offset: indent)
    in Oppen::Token::BreakType::INCONSISTENT
      Oppen.begin_inconsistent(offset: indent)
    end

  if !open_obj.empty?
    self.break
    text(open_obj)
  end

  yield

  if !close_obj.empty?
    self.break
    text(close_obj)
  end

  tokens << Oppen.end
end

#group_close(_) ⇒ Nil

Close a group.

Returns:

  • (Nil)


193
194
195
# File 'lib/wadler/print.rb', line 193

def group_close(_)
  tokens << Oppen.end
end

#group_open(inconsistent: false, indent: 0) ⇒ Nil

Open a consistent group.

Parameters:

  • inconsistent (Boolean) (defaults to: false)
  • indent (Integer) (defaults to: 0)

Returns:

  • (Nil)


181
182
183
184
185
186
187
188
# File 'lib/wadler/print.rb', line 181

def group_open(inconsistent: false, indent: 0)
  tokens <<
    if inconsistent
      Oppen.begin_inconsistent(offset: indent)
    else
      Oppen.begin_consistent(offset: indent)
    end
end

#indent_close(group, indent) ⇒ Nil

Close a group with indent.

Parameters:

  • indent (Integer)

Returns:

  • (Nil)


212
213
214
215
# File 'lib/wadler/print.rb', line 212

def indent_close(group, indent)
  @current_indent -= indent
  group_close(group)
end

#indent_open(indent) ⇒ Nil

Open a consistent group with indent.

Parameters:

  • indent (Integer)

Returns:

  • (Nil)


202
203
204
205
# File 'lib/wadler/print.rb', line 202

def indent_open(indent)
  @current_indent += indent
  group_open
end

#nest(indent, open_obj = '', close_obj = '') ⇒ Nil

Parameters:

  • indent (Integer)

    nest indentation

  • open_obj (String) (defaults to: '')

    nest opening delimiter

  • close_obj (String) (defaults to: '')

    nest closing delimiter

Returns:

  • (Nil)

Raises:

  • (ArgumentError)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/wadler/print.rb', line 110

def nest(indent, open_obj = '', close_obj = '')
  raise ArgumentError, "#{open_obj.nil? ? 'open_obj' : 'close_obj'} cannot be nil" \
    if open_obj.nil? || close_obj.nil?

  @current_indent += indent

  if !open_obj.empty?
    text(open_obj)
    self.break
  end

  begin
    yield
  ensure
    @current_indent -= indent
  end

  return if close_obj.empty?

  self.break
  text(close_obj)
end

#nest_close(indent) ⇒ Nil

Close a nest by indent.

Parameters:

  • indent (Integer)

Returns:

  • (Nil)


231
232
233
# File 'lib/wadler/print.rb', line 231

def nest_close(indent)
  @current_indent -= indent
end

#nest_open(indent) ⇒ Nil

Open a nest by indent.

Parameters:

  • indent (Integer)

Returns:

  • (Nil)


222
223
224
# File 'lib/wadler/print.rb', line 222

def nest_open(indent)
  @current_indent += indent
end

#outputString

Generate the output string of the built list of tokens using Oppen's pretty printing algorithm.

Returns:

  • (String)


55
56
57
58
# File 'lib/wadler/print.rb', line 55

def output
  add_missing_begin_and_end
  Oppen.print(tokens:, new_line:, config:, space:, out:, width:)
end

#show_print_commandsString

Generate the the list of Wadler commands needed to build the built list of tokens.

Returns:

  • (String)


64
65
66
67
# File 'lib/wadler/print.rb', line 64

def show_print_commands(**)
  add_missing_begin_and_end
  Oppen.tokens_to_wadler(tokens, **)
end

#text(value, width: value.length) ⇒ Nil

Parameters:

  • value (String)

Returns:

  • (Nil)


136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/wadler/print.rb', line 136

def text(value, width: value.length)
  if config.trim_trailing_whitespaces? && value.match(/((?:#{Regexp.escape(whitespace)})+)\z/)
    match = Regexp.last_match(1)
    matched_length = match.length
    if value.length != matched_length
      tokens << Oppen.string(value[0...-matched_length], width: width - matched_length)
    end
    tokens << Oppen.whitespace(match)
  else
    tokens << Oppen.string(value, width:)
  end
end