Class: Orgmode::Parser

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

Overview

Simple routines for loading / saving an ORG file.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lines, offset = 0) ⇒ Parser

I can construct a parser object either with an array of lines or with a single string that I will split along n boundaries.



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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/org-ruby/parser.rb', line 84

def initialize(lines, offset=0)
  if lines.is_a? Array then
    @lines = lines
  elsif lines.is_a? String then
    @lines = lines.split("\n")
  else
    raise "Unsupported type for +lines+: #{lines.class}"
  end

  @custom_keywords = []
  @headlines = Array.new
  @current_headline = nil
  @header_lines = []
  @in_buffer_settings = { }
  @options = { }
  mode = :normal
  previous_line = nil
  table_header_set = false
  @lines.each do |line|
    case mode
    when :normal

      if (Headline.headline? line) then
        @current_headline = Headline.new line, self, offset
        @headlines << @current_headline
      else
        line = Line.new line, self
        # If there is a setting on this line, remember it.
        line.in_buffer_setting? do |key, value|
          store_in_buffer_setting key, value
        end
        if line.table_separator? then
          if previous_line and previous_line.paragraph_type == :table_row and !table_header_set
            previous_line.assigned_paragraph_type = :table_header
            table_header_set = true
          end
        end
        table_header_set = false if !line.table?
        mode = :code if line.begin_block? and line.block_type.casecmp("EXAMPLE") == 0
        mode = :src_code if line.begin_block? and line.block_type.casecmp("SRC") == 0
        mode = :block_comment if line.begin_block? and line.block_type == "COMMENT"
        mode = :property_drawer if line.property_drawer_begin_block?
        if (@current_headline) then
          @current_headline.body_lines << line
        else
          @header_lines << line
        end
      end

    when :block_comment
      line = Line.new line, self
      if line.end_block? and line.block_type == "COMMENT"
        mode = :normal
      else
        line.assigned_paragraph_type = :comment
      end

    when :code

      # As long as we stay in code mode, force lines to be either blank or paragraphs.
      # Don't try to interpret structural items, like headings and tables.
      line = Line.new line, self
      if line.end_block? and line.code_block?
        mode = :normal
      else
        line.assigned_paragraph_type = :paragraph unless line.blank?
      end
      if (@current_headline) then
        @current_headline.body_lines << line
      else
        @header_lines << line
      end

    when :src_code

      line = Line.new line, self
      if line.end_block? and line.code_block?
        mode = :normal            
      else
        line.assigned_paragraph_type = :src
      end
      if (@current_headline) then
        @current_headline.body_lines << line
      else
        @header_lines << line
      end

    when :property_drawer

      line = Line.new line, self
      if line.property_drawer_end_block?
        mode = :normal
      else
        line.assigned_paragraph_type = :property_drawer unless line.blank?
      end
      if (@current_headline) then
        @current_headline.body_lines << line
      else
        @header_lines << line
      end
    end                     # case
    previous_line = line
  end                       # @lines.each
end

Instance Attribute Details

#custom_keywordsObject (readonly)

Array of custom keywords.



28
29
30
# File 'lib/org-ruby/parser.rb', line 28

def custom_keywords
  @custom_keywords
end

#header_linesObject (readonly)

These are any lines before the first headline



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

def header_lines
  @header_lines
end

#headlinesObject (readonly)

All of the headlines in the org file



15
16
17
# File 'lib/org-ruby/parser.rb', line 15

def headlines
  @headlines
end

#in_buffer_settingsObject (readonly)

This contains any in-buffer settings from the org-mode file. See orgmode.org/manual/In_002dbuffer-settings.html#In_002dbuffer-settings



22
23
24
# File 'lib/org-ruby/parser.rb', line 22

def in_buffer_settings
  @in_buffer_settings
end

#linesObject (readonly)

All of the lines of the orgmode file



12
13
14
# File 'lib/org-ruby/parser.rb', line 12

def lines
  @lines
end

#optionsObject (readonly)

This contains in-buffer options; a special case of in-buffer settings.



25
26
27
# File 'lib/org-ruby/parser.rb', line 25

def options
  @options
end

Class Method Details

.load(fname) ⇒ Object

Creates a new parser from the data in a given file



190
191
192
193
# File 'lib/org-ruby/parser.rb', line 190

def self.load(fname)
  lines = IO.readlines(fname)
  return self.new(lines)
end

Instance Method Details

#custom_keyword_regexpObject

Regexp that recognizes words in custom_keywords.



31
32
33
34
# File 'lib/org-ruby/parser.rb', line 31

def custom_keyword_regexp
  return nil if @custom_keywords.empty?
  Regexp.new("^(#{@custom_keywords.join('|')})\$")
end

#export_exclude_tagsObject

A set of tags that, if present on any headlines in the org-file, means that subtree will not get exported.



45
46
47
48
# File 'lib/org-ruby/parser.rb', line 45

def export_exclude_tags
  return Array.new unless @in_buffer_settings["EXPORT_EXCLUDE_TAGS"]
  @in_buffer_settings["EXPORT_EXCLUDE_TAGS"].split
end

#export_footnotes?Boolean

Returns true if we are to export footnotes

Returns:

  • (Boolean)


56
57
58
# File 'lib/org-ruby/parser.rb', line 56

def export_footnotes?
  "t" == @options["f"]
end

#export_heading_number?Boolean

Returns true if we are to export heading numbers.

Returns:

  • (Boolean)


61
62
63
# File 'lib/org-ruby/parser.rb', line 61

def export_heading_number?
  "t" == @options["num"]
end

#export_select_tagsObject

A set of tags that, if present on any headlines in the org-file, means only those headings will get exported.



38
39
40
41
# File 'lib/org-ruby/parser.rb', line 38

def export_select_tags
  return Array.new unless @in_buffer_settings["EXPORT_SELECT_TAGS"]
  @in_buffer_settings["EXPORT_SELECT_TAGS"].split
end

#export_tables?Boolean

Should we export tables? Defaults to true, must be overridden with an explicit “nil”

Returns:

  • (Boolean)


72
73
74
# File 'lib/org-ruby/parser.rb', line 72

def export_tables?
  "nil" != @options["|"]
end

#export_todo?Boolean

Returns true if we are to export todo keywords on headings.

Returns:

  • (Boolean)


51
52
53
# File 'lib/org-ruby/parser.rb', line 51

def export_todo?
  "t" == @options["todo"]
end

#skip_header_lines?Boolean

Should we skip exporting text before the first heading?

Returns:

  • (Boolean)


66
67
68
# File 'lib/org-ruby/parser.rb', line 66

def skip_header_lines?
  "t" == @options["skip"]
end

#to_htmlObject

Converts the loaded org-mode file to HTML.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/org-ruby/parser.rb', line 206

def to_html
  mark_trees_for_export
  export_options = {
    :decorate_title => true,
    :export_heading_number => export_heading_number?,
    :export_todo => export_todo?,
    :use_sub_superscripts =>  use_sub_superscripts?,
    :export_footnotes => export_footnotes?
  }
  export_options[:skip_tables] = true if not export_tables?
  output = ""
  output_buffer = HtmlOutputBuffer.new(output, export_options)

  if @in_buffer_settings["TITLE"] then

    # If we're given a new title, then just create a new line
    # for that title.
    title = Line.new(@in_buffer_settings["TITLE"], self)
    Parser.translate([title], output_buffer)
  end
  Parser.translate(@header_lines, output_buffer) unless skip_header_lines?

  # If we've output anything at all, remove the :decorate_title option.
  export_options.delete(:decorate_title) if (output.length > 0)
  @headlines.each do |headline|
    next if headline.export_state == :exclude
    case headline.export_state
    when :exclude
      # NOTHING
    when :headline_only
      Parser.translate(headline.body_lines[0, 1], output_buffer)
    when :all
      Parser.translate(headline.body_lines, output_buffer)
    end
  end
  rp = RubyPants.new(output)
  rp.to_html
end

#to_textileObject

Saves the loaded orgmode file as a textile file.



196
197
198
199
200
201
202
203
# File 'lib/org-ruby/parser.rb', line 196

def to_textile
  output = ""
  output << Line.to_textile(@header_lines)
  @headlines.each do |headline|
    output << headline.to_textile
  end
  output
end

#use_sub_superscripts?Boolean

Should we export sub/superscripts? (_foo/^foo) only {} mode is currently supported.

Returns:

  • (Boolean)


78
79
80
# File 'lib/org-ruby/parser.rb', line 78

def use_sub_superscripts?
  @options["^"] != "nil"
end