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@.



143
144
145
146
147
148
149
150
# File 'lib/org-ruby/output_buffer.rb', line 143

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.



108
109
110
111
112
# File 'lib/org-ruby/output_buffer.rb', line 108

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)


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

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)


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

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.



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/org-ruby/output_buffer.rb', line 117

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.



153
154
155
# File 'lib/org-ruby/output_buffer.rb', line 153

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
96
97
98
99
100
101
102
# File 'lib/org-ruby/output_buffer.rb', line 80

def prepare(line)
  @logger.debug "Looking at #{line.paragraph_type}(#{current_mode}) : #{line.to_s}"
  if line.begin_block? and line.code_block?
    flush!
    # We try to get the lang from #+BEGIN_SRC blocks
    @block_lang = line.block_lang
    @output_type = line.paragraph_type
  elsif current_mode == :example and line.end_block?
    flush!
    @output_type = line.paragraph_type
  elsif not should_accumulate_output?(line)
    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)


158
159
160
# File 'lib/org-ruby/output_buffer.rb', line 158

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