org-ruby 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ == 0.7.0 / 2012-07-08
2
+
3
+ * Highlight source code blocks using Pygments or CodeRay when available
4
+
1
5
  == 0.6.4 / 2012-07-08
2
6
 
3
7
  * Fixed lists behavior when code fragments, tables and examples were present
@@ -17,6 +17,7 @@ extracting "content" from the orgfile as opposed to "metadata."
17
17
  * Supports bold, italic, underline, strikethrough, and code inline formatting.
18
18
  * Supports hyperlinks that are in double-brackets
19
19
  * Supports +.org+ views in Rails through Tilt.
20
+ * Code syntax highlight of code blocks using Pygments.rb or Coderay when available
20
21
  * Upcoming: Handle export options specified in the org buffer.
21
22
 
22
23
  == SYNOPSIS:
@@ -21,7 +21,7 @@ require 'org-ruby/tilt'
21
21
  module OrgRuby
22
22
 
23
23
  # :stopdoc:
24
- VERSION = '0.6.4'
24
+ VERSION = '0.7.0'
25
25
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
26
26
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
27
27
  # :startdoc:
@@ -1,3 +1,14 @@
1
+ begin
2
+ require 'pygments'
3
+ rescue LoadError
4
+ # Pygments is not supported so we try instead with CodeRay
5
+ begin
6
+ require 'coderay'
7
+ rescue LoadError
8
+ # No code syntax highlighting
9
+ end
10
+ end
11
+
1
12
  module Orgmode
2
13
 
3
14
  class HtmlOutputBuffer < OutputBuffer
@@ -56,8 +67,12 @@ module Orgmode
56
67
  css_class = " class=\"src src-#{@block_lang}\"" if mode == :src and not @block_lang.empty?
57
68
  css_class = " class=\"example\"" if (mode == :example || mode == :inline_example)
58
69
  css_class = " style=\"text-align: center\"" if mode == :center
59
- @logger.debug "#{mode}: <#{ModeTag[mode]}#{css_class}>\n"
60
- @output << "<#{ModeTag[mode]}#{css_class}>\n" unless mode == :table and skip_tables?
70
+
71
+ unless ((mode == :table and skip_tables?) or
72
+ (mode == :src and defined? Pygments))
73
+ @logger.debug "#{mode}: <#{ModeTag[mode]}#{css_class}>\n"
74
+ @output << "<#{ModeTag[mode]}#{css_class}>\n"
75
+ end
61
76
  # Entering a new mode obliterates the title decoration
62
77
  @title_decoration = ""
63
78
  end
@@ -78,8 +93,11 @@ module Orgmode
78
93
  close_floating_li_tags
79
94
  end
80
95
 
81
- @logger.debug "</#{ModeTag[m]}>\n"
82
- @output << "</#{ModeTag[m]}>\n" unless mode == :table and skip_tables?
96
+ unless ((mode == :table and skip_tables?) or
97
+ (mode == :src and defined? Pygments))
98
+ @logger.debug "</#{ModeTag[m]}>\n"
99
+ @output << "</#{ModeTag[m]}>\n"
100
+ end
83
101
 
84
102
  # In case it was a sublist, close it here
85
103
  close_last_li_tag_maybe
@@ -87,13 +105,40 @@ module Orgmode
87
105
  end
88
106
 
89
107
  def flush!
90
- escape_buffer!
91
- if mode_is_code(@buffer_mode) then
108
+ if buffer_mode_is_src_block?
109
+
110
+ # Only try to colorize #+BEGIN_SRC blocks with a specified language,
111
+ # but we still have to catch the cases when a lexer for the language was not available
112
+ if not @block_lang.empty? and (defined? Pygments or defined? CodeRay)
113
+ # NOTE: CodeRay and Pygments already escape the html once, so no need to escape_buffer!
114
+ if defined? Pygments
115
+ begin
116
+ @buffer = Pygments.highlight(@buffer, :lexer => @block_lang)
117
+ rescue ::RubyPython::PythonError
118
+ # Not supported lexer from Pygments, we fallback on using the text lexer
119
+ @buffer = Pygments.highlight(@buffer, :lexer => 'text')
120
+ end
121
+ elsif defined? CodeRay
122
+ # CodeRay might throw a warning when unsupported lang is set
123
+ silence_warnings do
124
+ @buffer = CodeRay.scan(@buffer, @block_lang).html(:wrap => nil, :css => :style)
125
+ end
126
+ end
127
+ else
128
+ escape_buffer!
129
+ end
130
+
131
+ @logger.debug "FLUSH SRC CODE ==========> #{@buffer.inspect}"
132
+ @output << @buffer
133
+ elsif mode_is_code(@buffer_mode) then
134
+ escape_buffer!
135
+
92
136
  # Whitespace is significant in :code mode. Always output the buffer
93
137
  # and do not do any additional translation.
94
138
  @logger.debug "FLUSH CODE ==========> #{@buffer.inspect}"
95
139
  @output << @buffer << "\n"
96
140
  else
141
+ escape_buffer!
97
142
  if @buffer.length > 0 and @output_type == :horizontal_rule then
98
143
  @output << "<hr />\n"
99
144
  elsif @buffer.length > 0 and @output_type == :definition_list then
@@ -183,6 +228,10 @@ module Orgmode
183
228
  @buffer_mode == :table
184
229
  end
185
230
 
231
+ def buffer_mode_is_src_block?
232
+ @buffer_mode == :src
233
+ end
234
+
186
235
  # Escapes any HTML content in the output accumulation buffer @buffer.
187
236
  def escape_buffer!
188
237
  @buffer.gsub!(/&/, "&amp;")
@@ -286,5 +335,15 @@ module Orgmode
286
335
  end
287
336
  end
288
337
  end
338
+
339
+ # Helper method taken from Rails
340
+ # https://github.com/rails/rails/blob/c2c8ef57d6f00d1c22743dc43746f95704d67a95/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10
341
+ def silence_warnings
342
+ warn_level = $VERBOSE
343
+ $VERBOSE = nil
344
+ yield
345
+ ensure
346
+ $VERBOSE = warn_level
347
+ end
289
348
  end # class HtmlOutputBuffer
290
349
  end # module Orgmode
@@ -164,10 +164,14 @@ module Orgmode
164
164
  $3 if @line =~ BlockRegexp
165
165
  end
166
166
 
167
- def code_block_type?
167
+ def code_block?
168
168
  block_type =~ /^(EXAMPLE|SRC)$/i
169
169
  end
170
170
 
171
+ def code_block_line?
172
+ @assigned_paragraph_type == :src
173
+ end
174
+
171
175
  InlineExampleRegexp = /^\s*:\s/
172
176
 
173
177
  # Test if the line matches the "inline example" case:
@@ -200,6 +204,7 @@ module Orgmode
200
204
  # Determines the paragraph type of the current line.
201
205
  def paragraph_type
202
206
  return :blank if blank?
207
+ return :src if code_block_line? # Do not try to guess the type of this line if it is accumulating source code
203
208
  return :definition_list if definition_list? # order is important! A definition_list is also an unordered_list!
204
209
  return :ordered_list if ordered_list?
205
210
  return :unordered_list if unordered_list?
@@ -78,9 +78,16 @@ module Orgmode
78
78
  # Prepares the output buffer to receive content from a line.
79
79
  # As a side effect, this may flush the current accumulated text.
80
80
  def prepare(line)
81
- @logger.debug "Looking at #{line.paragraph_type}: #{line.to_s}"
82
- if not should_accumulate_output?(line) then
83
- @block_lang = line.block_lang if line.begin_block? and line.code_block_type?
81
+ @logger.debug "Looking at #{line.paragraph_type}(#{current_mode}) : #{line.to_s}"
82
+ if line.begin_block? and line.code_block?
83
+ flush!
84
+ # We try to get the lang from #+BEGIN_SRC blocks
85
+ @block_lang = line.block_lang
86
+ @output_type = line.paragraph_type
87
+ elsif current_mode == :example and line.end_block?
88
+ flush!
89
+ @output_type = line.paragraph_type
90
+ elsif not should_accumulate_output?(line)
84
91
  flush!
85
92
  maintain_list_indent_stack(line)
86
93
  @output_type = line.paragraph_type
@@ -207,6 +214,9 @@ module Orgmode
207
214
  # line breaks.)
208
215
  def should_accumulate_output?(line)
209
216
 
217
+ # Special case: We are accumulating source code block content for colorizing
218
+ return true if line.paragraph_type == :src and @output_type == :src
219
+
210
220
  # Special case: Preserve line breaks in block code mode.
211
221
  return false if preserve_whitespace?
212
222
 
@@ -119,7 +119,8 @@ module Orgmode
119
119
  end
120
120
  end
121
121
  table_header_set = false if !line.table?
122
- mode = :code if line.begin_block? and line.block_type == "EXAMPLE"
122
+ mode = :code if line.begin_block? and line.block_type.casecmp("EXAMPLE") == 0
123
+ mode = :src_code if line.begin_block? and line.block_type.casecmp("SRC") == 0
123
124
  mode = :block_comment if line.begin_block? and line.block_type == "COMMENT"
124
125
  mode = :property_drawer if line.property_drawer_begin_block?
125
126
  if (@current_headline) then
@@ -142,7 +143,7 @@ module Orgmode
142
143
  # As long as we stay in code mode, force lines to be either blank or paragraphs.
143
144
  # Don't try to interpret structural items, like headings and tables.
144
145
  line = Line.new line, self
145
- if line.end_block? and line.block_type == "EXAMPLE"
146
+ if line.end_block? and line.code_block?
146
147
  mode = :normal
147
148
  else
148
149
  line.assigned_paragraph_type = :paragraph unless line.blank?
@@ -153,6 +154,20 @@ module Orgmode
153
154
  @header_lines << line
154
155
  end
155
156
 
157
+ when :src_code
158
+
159
+ line = Line.new line, self
160
+ if line.end_block? and line.code_block?
161
+ mode = :normal
162
+ else
163
+ line.assigned_paragraph_type = :src
164
+ end
165
+ if (@current_headline) then
166
+ @current_headline.body_lines << line
167
+ else
168
+ @header_lines << line
169
+ end
170
+
156
171
  when :property_drawer
157
172
 
158
173
  line = Line.new line, self
@@ -274,7 +289,6 @@ module Orgmode
274
289
  output_buffer << line.output_text << "\n"
275
290
 
276
291
  else
277
-
278
292
  if output_buffer.preserve_whitespace? then
279
293
  output_buffer << line.output_text
280
294
  else
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: org-ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 6
9
- - 4
10
- version: 0.6.4
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian Dewey