Class: Orgmode::OutputBuffer

Inherits:
Object
  • Object
show all
Defined in:
lib/org-ruby/output_buffer.rb

Overview

The OutputBuffer is used to accumulate multiple lines of orgmode text, and then emit them to the output all in one go. The class will do the final textile substitution for inline formatting and add a newline character prior emitting the output.

Direct Known Subclasses

HtmlOutputBuffer, TextileOutputBuffer

Constant Summary collapse

Modes =
[:normal, :ordered_list, :unordered_list, :definition_list, :blockquote, :src, :example, :table, :inline_example, :center, :property_drawer]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output) ⇒ OutputBuffer

Creates a new OutputBuffer object that is bound to an output object. The output will get flushed to =output=.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/org-ruby/output_buffer.rb', line 34

def initialize(output)
  @output = output
  @buffer = ""
  @buffered_lines = []
  @buffer_mode = nil
  @output_type = :start
  @list_indent_stack = []
  @paragraph_modifier = nil
  @cancel_modifier = false
  @mode_stack = []
  @headline_number_stack = []

  @logger = Logger.new(STDERR)
  if ENV['DEBUG'] or $DEBUG
    @logger.level = Logger::DEBUG
  else
    @logger.level = Logger::WARN
  end

  @re_help = RegexpHelper.new
  push_mode(:normal)
end

Instance Attribute Details

#bufferObject (readonly)

This is the accumulation buffer. It’s a holding pen so consecutive lines of the right type can get stuck together without intervening newlines.



14
15
16
# File 'lib/org-ruby/output_buffer.rb', line 14

def buffer
  @buffer
end

#buffer_modeObject (readonly)

This is the output mode of the accumulation buffer.



21
22
23
# File 'lib/org-ruby/output_buffer.rb', line 21

def buffer_mode
  @buffer_mode
end

#buffered_linesObject (readonly)

These are the Line objects that are currently in the accumulation buffer.



18
19
20
# File 'lib/org-ruby/output_buffer.rb', line 18

def buffered_lines
  @buffered_lines
end

#headline_number_stackObject

This stack is used to do proper outline numbering of headlines.



30
31
32
# File 'lib/org-ruby/output_buffer.rb', line 30

def headline_number_stack
  @headline_number_stack
end

#outputObject (readonly)

This is the overall output buffer



24
25
26
# File 'lib/org-ruby/output_buffer.rb', line 24

def output
  @output
end

#output_typeObject

This is the current type of output being accumulated.



27
28
29
# File 'lib/org-ruby/output_buffer.rb', line 27

def output_type
  @output_type
end

Instance Method Details

#<<(str) ⇒ Object

Accumulate the string @str@.



136
137
138
139
140
141
142
143
# File 'lib/org-ruby/output_buffer.rb', line 136

def << (str)
  if @buffer_mode && @buffer_mode != current_mode then
    raise "Accumulation buffer is mixing modes: @buffer_mode == #{@buffer_mode}, current_mode == #{current_mode}"
  else
    @buffer_mode = current_mode
  end
  @buffer << str
end

#clear_accumulation_buffer!Object

Flushes everything currently in the accumulation buffer into the output buffer. Derived classes must override this to actually move content into the output buffer with the appropriate markup. This method just does common bookkeeping cleanup.



101
102
103
104
105
# File 'lib/org-ruby/output_buffer.rb', line 101

def clear_accumulation_buffer!
  @buffer = ""
  @buffer_mode = nil
  @buffered_lines = []
end

#current_modeObject



59
60
61
# File 'lib/org-ruby/output_buffer.rb', line 59

def current_mode
  @mode_stack.last
end

#current_mode_list?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/org-ruby/output_buffer.rb', line 63

def current_mode_list?
  (current_mode == :ordered_list) or (current_mode == :unordered_list)
end

#enter_table?Boolean

Tests if we are entering a table mode.

Returns:

  • (Boolean)


124
125
126
127
# File 'lib/org-ruby/output_buffer.rb', line 124

def enter_table?
  ((@output_type == :table_row) || (@output_type == :table_header) || (@output_type == :table_separator)) &&
    (current_mode != :table)
end

#exit_table?Boolean

Tests if we are existing a table mode.

Returns:

  • (Boolean)


130
131
132
133
# File 'lib/org-ruby/output_buffer.rb', line 130

def exit_table?
  ((@output_type != :table_row) && (@output_type != :table_header) && (@output_type != :table_separator)) &&
    (current_mode == :table)
end

#get_next_headline_number(level) ⇒ Object

Gets the next headline number for a given level. The intent is this function is called sequentially for each headline that needs to get numbered. It does standard outline numbering.



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/org-ruby/output_buffer.rb', line 110

def get_next_headline_number(level)
  raise "Headline level not valid: #{level}" if level <= 0
  while level > @headline_number_stack.length do
    @headline_number_stack.push 0
  end
  while level < @headline_number_stack.length do
    @headline_number_stack.pop
  end
  raise "Oops, shouldn't happen" unless level == @headline_number_stack.length
  @headline_number_stack[@headline_number_stack.length - 1] += 1
  @headline_number_stack.join(".")
end

#list_indent_levelObject

Gets the current list indent level.



146
147
148
# File 'lib/org-ruby/output_buffer.rb', line 146

def list_indent_level
  @list_indent_stack.length
end

#pop_mode(mode = nil) ⇒ Object



72
73
74
75
76
# File 'lib/org-ruby/output_buffer.rb', line 72

def pop_mode(mode = nil)
  m = @mode_stack.pop
  @logger.warn "Modes don't match. Expected to pop #{mode}, but popped #{m}" if mode && mode != m
  m
end

#prepare(line) ⇒ Object

Prepares the output buffer to receive content from a line. As a side effect, this may flush the current accumulated text.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/org-ruby/output_buffer.rb', line 80

def prepare(line)
  @logger.debug "Looking at #{line.paragraph_type}: #{line.to_s}"
  if not should_accumulate_output?(line) then
    @block_lang = line.block_lang if line.begin_block? and line.code_block_type?
    flush!
    maintain_list_indent_stack(line)
    @output_type = line.paragraph_type 
  end
  push_mode(:inline_example) if line.inline_example? and current_mode != :inline_example and not line.property_drawer?
  pop_mode(:inline_example) if current_mode == :inline_example and !line.inline_example?
  push_mode(:property_drawer) if line.property_drawer? and current_mode != :property_drawer
  pop_mode(:property_drawer) if current_mode == :property_drawer and line.property_drawer_end_block?
  push_mode(:table) if enter_table?
  pop_mode(:table) if exit_table?
  @buffered_lines.push(line)
end

#preserve_whitespace?Boolean

Test if we’re in an output mode in which whitespace is significant.

Returns:

  • (Boolean)


151
152
153
# File 'lib/org-ruby/output_buffer.rb', line 151

def preserve_whitespace?
  mode_is_code current_mode
end

#push_mode(mode) ⇒ Object



67
68
69
70
# File 'lib/org-ruby/output_buffer.rb', line 67

def push_mode(mode)
  raise "Not a recognized mode: #{mode}" unless Modes.include?(mode)
  @mode_stack.push(mode)
end