wallyqs-org-ruby 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/.bnsignore +18 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +7 -0
  4. data/Gemfile.lock +36 -0
  5. data/History.txt +112 -0
  6. data/README.rdoc +67 -0
  7. data/Rakefile +33 -0
  8. data/TAGS +167 -0
  9. data/announcement.txt +24 -0
  10. data/bin/org-ruby +45 -0
  11. data/lib/org-ruby.rb +55 -0
  12. data/lib/org-ruby/headline.rb +110 -0
  13. data/lib/org-ruby/html_output_buffer.rb +273 -0
  14. data/lib/org-ruby/html_symbol_replace.rb +345 -0
  15. data/lib/org-ruby/line.rb +244 -0
  16. data/lib/org-ruby/output_buffer.rb +237 -0
  17. data/lib/org-ruby/parser.rb +366 -0
  18. data/lib/org-ruby/regexp_helper.rb +192 -0
  19. data/lib/org-ruby/textile_output_buffer.rb +102 -0
  20. data/lib/org-ruby/textile_symbol_replace.rb +346 -0
  21. data/lib/org-ruby/tilt.rb +29 -0
  22. data/org-ruby.gemspec +40 -0
  23. data/spec/data/freeform-example.org +113 -0
  24. data/spec/data/freeform.org +111 -0
  25. data/spec/data/hyp-planning.org +335 -0
  26. data/spec/data/remember.org +53 -0
  27. data/spec/headline_spec.rb +65 -0
  28. data/spec/html_examples/advanced-code.html +81 -0
  29. data/spec/html_examples/advanced-code.org +106 -0
  30. data/spec/html_examples/advanced-lists.html +31 -0
  31. data/spec/html_examples/advanced-lists.org +31 -0
  32. data/spec/html_examples/block_code.html +28 -0
  33. data/spec/html_examples/block_code.org +35 -0
  34. data/spec/html_examples/blockcomment.html +3 -0
  35. data/spec/html_examples/blockcomment.org +15 -0
  36. data/spec/html_examples/blockquote.html +7 -0
  37. data/spec/html_examples/blockquote.org +13 -0
  38. data/spec/html_examples/center.html +6 -0
  39. data/spec/html_examples/center.org +7 -0
  40. data/spec/html_examples/code-comment.html +18 -0
  41. data/spec/html_examples/code-comment.org +22 -0
  42. data/spec/html_examples/code-syntax.html +98 -0
  43. data/spec/html_examples/code-syntax.org +99 -0
  44. data/spec/html_examples/comment-trees.html +4 -0
  45. data/spec/html_examples/comment-trees.org +13 -0
  46. data/spec/html_examples/custom-seq-todo.html +15 -0
  47. data/spec/html_examples/custom-seq-todo.org +24 -0
  48. data/spec/html_examples/custom-todo.html +15 -0
  49. data/spec/html_examples/custom-todo.org +24 -0
  50. data/spec/html_examples/custom-typ-todo.html +15 -0
  51. data/spec/html_examples/custom-typ-todo.org +24 -0
  52. data/spec/html_examples/deflist.html +6 -0
  53. data/spec/html_examples/deflist.org +6 -0
  54. data/spec/html_examples/entities.html +4 -0
  55. data/spec/html_examples/entities.org +11 -0
  56. data/spec/html_examples/escape-pre.html +6 -0
  57. data/spec/html_examples/escape-pre.org +6 -0
  58. data/spec/html_examples/export-exclude-only.html +13 -0
  59. data/spec/html_examples/export-exclude-only.org +81 -0
  60. data/spec/html_examples/export-keywords.html +4 -0
  61. data/spec/html_examples/export-keywords.org +18 -0
  62. data/spec/html_examples/export-tags.html +8 -0
  63. data/spec/html_examples/export-tags.org +82 -0
  64. data/spec/html_examples/export-title.html +2 -0
  65. data/spec/html_examples/export-title.org +4 -0
  66. data/spec/html_examples/footnotes.html +10 -0
  67. data/spec/html_examples/footnotes.org +7 -0
  68. data/spec/html_examples/html-literal.html +2 -0
  69. data/spec/html_examples/html-literal.org +6 -0
  70. data/spec/html_examples/inline-formatting.html +20 -0
  71. data/spec/html_examples/inline-formatting.org +33 -0
  72. data/spec/html_examples/inline-images.html +10 -0
  73. data/spec/html_examples/inline-images.org +15 -0
  74. data/spec/html_examples/link-features.html +8 -0
  75. data/spec/html_examples/link-features.org +19 -0
  76. data/spec/html_examples/lists.html +23 -0
  77. data/spec/html_examples/lists.org +47 -0
  78. data/spec/html_examples/metadata-comment.html +27 -0
  79. data/spec/html_examples/metadata-comment.org +30 -0
  80. data/spec/html_examples/only-list.html +5 -0
  81. data/spec/html_examples/only-list.org +3 -0
  82. data/spec/html_examples/only-table.html +6 -0
  83. data/spec/html_examples/only-table.org +5 -0
  84. data/spec/html_examples/skip-header.html +3 -0
  85. data/spec/html_examples/skip-header.org +28 -0
  86. data/spec/html_examples/skip-table.html +4 -0
  87. data/spec/html_examples/skip-table.org +19 -0
  88. data/spec/html_examples/subsupscript-nil.html +3 -0
  89. data/spec/html_examples/subsupscript-nil.org +6 -0
  90. data/spec/html_examples/subsupscript.html +3 -0
  91. data/spec/html_examples/subsupscript.org +5 -0
  92. data/spec/html_examples/tables.html +35 -0
  93. data/spec/html_examples/tables.org +50 -0
  94. data/spec/html_examples/text.html +2 -0
  95. data/spec/html_examples/text.org +16 -0
  96. data/spec/line_spec.rb +155 -0
  97. data/spec/output_buffer_spec.rb +19 -0
  98. data/spec/parser_spec.rb +152 -0
  99. data/spec/regexp_helper_spec.rb +57 -0
  100. data/spec/spec_helper.rb +20 -0
  101. data/spec/textile_examples/block_code.org +35 -0
  102. data/spec/textile_examples/block_code.textile +29 -0
  103. data/spec/textile_examples/blockquote.org +13 -0
  104. data/spec/textile_examples/blockquote.textile +11 -0
  105. data/spec/textile_examples/center.org +7 -0
  106. data/spec/textile_examples/center.textile +6 -0
  107. data/spec/textile_examples/footnotes.org +7 -0
  108. data/spec/textile_examples/footnotes.textile +8 -0
  109. data/spec/textile_examples/keywords.org +13 -0
  110. data/spec/textile_examples/keywords.textile +11 -0
  111. data/spec/textile_examples/links.org +11 -0
  112. data/spec/textile_examples/links.textile +10 -0
  113. data/spec/textile_examples/lists.org +36 -0
  114. data/spec/textile_examples/lists.textile +20 -0
  115. data/spec/textile_examples/single-space-plain-list.org +13 -0
  116. data/spec/textile_examples/single-space-plain-list.textile +10 -0
  117. data/spec/textile_examples/tables.org +50 -0
  118. data/spec/textile_examples/tables.textile +40 -0
  119. data/spec/textile_output_buffer_spec.rb +21 -0
  120. data/tasks/test_case.rake +49 -0
  121. data/test/test_orgmode_parser.rb +0 -0
  122. data/util/gen-special-replace.el +37 -0
  123. metadata +244 -0
@@ -0,0 +1,24 @@
1
+ org-ruby version 0.6.1
2
+ by Brian Dewey
3
+ http://github.com/wallyqs/org-ruby
4
+
5
+ == DESCRIPTION
6
+
7
+ This gem contains Ruby routines for parsing org-mode files.The most
8
+ significant thing this library does today is convert org-mode files to
9
+ HTML or textile. Currently, you cannot do much to customize the
10
+ conversion. The supplied textile conversion is optimized for
11
+ extracting "content" from the orgfile as opposed to "metadata."
12
+
13
+ == CHANGES
14
+ * Added encoding directive to support Ruby 1.9.2
15
+ * Included .org support for Tilt templates (thanks to crnixon)
16
+ * #+BEGIN/END_SRC lang code blocks are embedded in code tags with class that specifies the coding language
17
+ * CodeRay is used to give code syntax highlight support to #+BEGIN/END_SRC blocks
18
+
19
+ * Minor Enhancements
20
+ * Angle links in org-mode are embedded in anchor tags on html output
21
+ * Headlines with the COMMENT keyword, and the PROPERTIES drawer are not exported
22
+
23
+ * Bug fixes
24
+ * Fixed bug with InlineExampleRegexp when a colon is at the beginning of a block
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib org-ruby]))
5
+ require 'optparse'
6
+
7
+ # Put your code here
8
+
9
+ options = {}
10
+ options_parser = OptionParser.new do |opts|
11
+ options[:help] = false
12
+ options[:format] = :html
13
+
14
+ opts.banner = "Usage: org-ruby <file> [options]"
15
+
16
+ opts.on("-h", "--help", "Show this message") do |v|
17
+ options[:help] = true
18
+ end
19
+
20
+ opts.on("-d", "--debug", "Run with $DEBUG true") do |v|
21
+ options[:debug] = true
22
+ end
23
+
24
+ opts.on("-t", "--translate FORMAT", [:html, :textile],
25
+ "Translate the ORG file to the specified format.") do |v|
26
+ options[:format] = v
27
+ end
28
+ end
29
+
30
+ begin
31
+ options_parser.parse!
32
+ if (ARGV.length == 0) then
33
+ puts options_parser
34
+ else
35
+ data = IO.read(ARGV[0])
36
+ p = Orgmode::Parser.new(data)
37
+ $DEBUG = true if options[:debug]
38
+ puts p.to_html if options[:format] == :html
39
+ puts p.to_textile if options[:format] == :textile
40
+ end
41
+ rescue OptionParser::ParseError
42
+ puts options_parser
43
+ end
44
+
45
+
@@ -0,0 +1,55 @@
1
+ unless defined? ::OrgRuby
2
+
3
+ # Default to UTF-8 in Ruby 1.9 rather than ASCII
4
+ if defined? Encoding and Encoding.respond_to? 'default_external='
5
+ Encoding.default_external = Encoding.default_internal = Encoding::UTF_8
6
+ end
7
+
8
+ module OrgRuby
9
+
10
+ # :stopdoc:
11
+ VERSION = '0.6.1'
12
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
13
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
14
+ # :startdoc:
15
+
16
+ # Returns the version string for the library.
17
+ #
18
+ def self.version
19
+ VERSION
20
+ end
21
+
22
+ # Returns the library path for the module. If any arguments are given,
23
+ # they will be joined to the end of the libray path using
24
+ # <tt>File.join</tt>.
25
+ #
26
+ def self.libpath( *args )
27
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
28
+ end
29
+
30
+ # Returns the lpath for the module. If any arguments are given,
31
+ # they will be joined to the end of the path using
32
+ # <tt>File.join</tt>.
33
+ #
34
+ def self.path( *args )
35
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
36
+ end
37
+
38
+ # Utility method used to require all files ending in .rb that lie in the
39
+ # directory below this file that has the same name as the filename passed
40
+ # in. Optionally, a specific _directory_ name can be passed in such that
41
+ # the _filename_ does not have to be equivalent to the directory.
42
+ #
43
+ def self.require_all_libs_relative_to( fname, dir = nil )
44
+ dir ||= ::File.basename(fname, '.*')
45
+ search_me = ::File.expand_path(
46
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
47
+
48
+ Dir.glob(search_me).sort.each {|rb| require rb}
49
+ end
50
+
51
+ end # module OrgmodeParser
52
+
53
+ OrgRuby.require_all_libs_relative_to(__FILE__)
54
+
55
+ end # unless defined?
@@ -0,0 +1,110 @@
1
+ require OrgRuby.libpath(*%w[org-ruby line])
2
+
3
+ module Orgmode
4
+
5
+ # Represents a headline in an orgmode file.
6
+ class Headline < Line
7
+
8
+ # This is the "level" of the headline
9
+ attr_reader :level
10
+
11
+ # This is the headline text -- the part of the headline minus the leading
12
+ # asterisks, the keywords, and the tags.
13
+ attr_reader :headline_text
14
+
15
+ # This contains the lines that "belong" to the headline.
16
+ attr_reader :body_lines
17
+
18
+ # These are the headline tags
19
+ attr_reader :tags
20
+
21
+ # Optional keyword found at the beginning of the headline.
22
+ attr_reader :keyword
23
+
24
+ # Valid states for partial export.
25
+ # exclude:: The entire subtree from this heading should be excluded.
26
+ # headline_only:: The headline should be exported, but not the body.
27
+ # all:: Everything should be exported, headline/body/children.
28
+ ValidExportStates = [:exclude, :headline_only, :all]
29
+
30
+ # The export state of this headline. See +ValidExportStates+.
31
+ attr_accessor :export_state
32
+
33
+ # This is the regex that matches a line
34
+ LineRegexp = /^\*+\s+/
35
+
36
+ # This matches the tags on a headline
37
+ TagsRegexp = /\s*:[\w:]*:\s*$/
38
+
39
+ # Special keywords allowed at the start of a line.
40
+ Keywords = %w[TODO DONE]
41
+
42
+ KeywordsRegexp = Regexp.new("^(#{Keywords.join('|')})\$")
43
+
44
+ # This matches a headline marked as COMMENT
45
+ CommentHeadlineRegexp = /^COMMENT\s+/
46
+
47
+ def initialize(line, parser = nil, offset=0)
48
+ super(line, parser)
49
+ @body_lines = []
50
+ @body_lines << self # Make @body_lines contain the headline?
51
+ @tags = []
52
+ @export_state = :exclude
53
+ if (@line =~ LineRegexp) then
54
+ @level = $&.strip.length + offset
55
+ @headline_text = $'.strip
56
+ if (@headline_text =~ TagsRegexp) then
57
+ @tags = $&.split(/:/) # split tag text on semicolon
58
+ @tags.delete_at(0) # the first item will be empty; discard
59
+ @headline_text.gsub!(TagsRegexp, "") # Removes the tags from the headline
60
+ end
61
+ @keyword = nil
62
+ parse_keywords
63
+ else
64
+ raise "'#{line}' is not a valid headline"
65
+ end
66
+ end
67
+
68
+ # Override Line.output_text. For a heading, @headline_text
69
+ # is what we should output.
70
+ def output_text
71
+ return @headline_text
72
+ end
73
+
74
+ # Determines if a line is an orgmode "headline":
75
+ # A headline begins with one or more asterisks.
76
+ def self.headline?(line)
77
+ line =~ LineRegexp
78
+ end
79
+
80
+ # Determines if a headline has the COMMENT keyword.
81
+ def comment_headline?
82
+ @headline_text =~ CommentHeadlineRegexp
83
+ end
84
+
85
+ # Overrides Line.paragraph_type.
86
+ def paragraph_type
87
+ :"heading#{@level}"
88
+ end
89
+
90
+ # Converts this headline and its body to textile.
91
+ def to_textile
92
+ output = "h#{@level}. #{@headline_text}\n"
93
+ output << Line.to_textile(@body_lines[1..-1])
94
+ output
95
+ end
96
+
97
+ ######################################################################
98
+ private
99
+
100
+ def parse_keywords
101
+ re = @parser.custom_keyword_regexp if @parser
102
+ re ||= KeywordsRegexp
103
+ words = @headline_text.split
104
+ if words.length > 0 && words[0] =~ re then
105
+ @keyword = words[0]
106
+ @headline_text.sub!(Regexp.new("^#{@keyword}\s*"), "")
107
+ end
108
+ end
109
+ end # class Headline
110
+ end # class Orgmode
@@ -0,0 +1,273 @@
1
+ require OrgRuby.libpath(*%w[org-ruby html_symbol_replace])
2
+ require OrgRuby.libpath(*%w[org-ruby output_buffer])
3
+
4
+ begin
5
+ require 'coderay'
6
+ rescue LoadError
7
+ # CodeRay is not supported
8
+ end
9
+
10
+ module Orgmode
11
+
12
+ class HtmlOutputBuffer < OutputBuffer
13
+
14
+ HtmlBlockTag = {
15
+ :paragraph => "p",
16
+ :ordered_list => "li",
17
+ :unordered_list => "li",
18
+ :definition_term => "dt",
19
+ :definition_descr => "dd",
20
+ :table_row => "tr",
21
+ :table_header => "tr",
22
+ :heading1 => "h1",
23
+ :heading2 => "h2",
24
+ :heading3 => "h3",
25
+ :heading4 => "h4",
26
+ :heading5 => "h5",
27
+ :heading6 => "h6"
28
+ }
29
+
30
+ ModeTag = {
31
+ :unordered_list => "ul",
32
+ :ordered_list => "ol",
33
+ :definition_list => "dl",
34
+ :table => "table",
35
+ :blockquote => "blockquote",
36
+ :example => "pre",
37
+ :src => "pre",
38
+ :inline_example => "pre",
39
+ :center => "div"
40
+ }
41
+
42
+ attr_reader :options
43
+
44
+ def initialize(output, opts = {})
45
+ super(output)
46
+ if opts[:decorate_title] then
47
+ @title_decoration = " class=\"title\""
48
+ else
49
+ @title_decoration = ""
50
+ end
51
+ @options = opts
52
+ @footnotes = {}
53
+ @logger.debug "HTML export options: #{@options.inspect}"
54
+ end
55
+
56
+ # Output buffer is entering a new mode. Use this opportunity to
57
+ # write out one of the block tags in the ModeTag constant to put
58
+ # this information in the HTML stream.
59
+ def push_mode(mode)
60
+ if ModeTag[mode] then
61
+ output_indentation
62
+ css_class = ""
63
+ css_class = " class=\"src\"" if mode == :src
64
+ css_class = " class=\"example\"" if (mode == :example || mode == :inline_example)
65
+ css_class = " style=\"text-align: center\"" if mode == :center
66
+ @logger.debug "#{mode}: <#{ModeTag[mode]}#{css_class}>\n"
67
+ @output << "<#{ModeTag[mode]}#{css_class}>\n" unless mode == :table and skip_tables?
68
+ # Special case to add code tags to src blogs and specify language
69
+ if mode == :src
70
+ @logger.debug "<code class=\"#{@block_lang}\">\n"
71
+ @output << "<code class=\"#{@block_lang}\">\n"
72
+ end
73
+ # Entering a new mode obliterates the title decoration
74
+ @title_decoration = ""
75
+ end
76
+ super(mode)
77
+ end
78
+
79
+ # We are leaving a mode. Close any tags that were opened when
80
+ # entering this mode.
81
+ def pop_mode(mode = nil)
82
+ m = super(mode)
83
+ if ModeTag[m] then
84
+ output_indentation
85
+ if mode == :src
86
+ @logger.debug "</code>\n"
87
+ @output << "</code>\n"
88
+ end
89
+ @logger.debug "</#{ModeTag[m]}>\n"
90
+ @output << "</#{ModeTag[m]}>\n" unless mode == :table and skip_tables?
91
+ end
92
+ end
93
+
94
+ def flush!
95
+ if mode_is_code(@buffer_mode) then
96
+ # Only colorize #+BEGIN_SRC blocks with a specified language,
97
+ # CodeRay already escapes the html once
98
+ if @buffer_mode == :src and @block_lang != "" and defined?(CodeRay)
99
+ @logger.debug "Applying syntax coloring for: #{@block_lang}"
100
+
101
+ # Also suppress CodeRay warning message when it cannot find the language alias
102
+ silence_warnings do
103
+ @buffer = CodeRay.scan(@buffer, @block_lang.to_s).html(:wrap => nil, :css => :style)
104
+ end
105
+ else
106
+ escape_buffer!
107
+ end
108
+
109
+ # Whitespace is significant in :code mode. Always output the buffer
110
+ # and do not do any additional translation.
111
+ @logger.debug "FLUSH CODE ==========> #{@buffer.inspect}"
112
+
113
+ @output << @buffer << "\n"
114
+ else
115
+ escape_buffer!
116
+ if @buffer.length > 0 and @output_type == :definition_list then
117
+ unless buffer_mode_is_table? and skip_tables?
118
+ output_indentation
119
+ d = @buffer.split("::", 2)
120
+ @output << "<#{HtmlBlockTag[:definition_term]}#{@title_decoration}>" << inline_formatting(d[0].strip) \
121
+ << "</#{HtmlBlockTag[:definition_term]}>"
122
+ if d.length > 1 then
123
+ @output << "<#{HtmlBlockTag[:definition_descr]}#{@title_decoration}>" << inline_formatting(d[1].strip) \
124
+ << "</#{HtmlBlockTag[:definition_descr]}>\n"
125
+ else
126
+ @output << "\n"
127
+ end
128
+ @title_decoration = ""
129
+ end
130
+ elsif @buffer.length > 0 then
131
+ unless buffer_mode_is_table? and skip_tables?
132
+ @logger.debug "FLUSH ==========> #{@buffer_mode}"
133
+ output_indentation
134
+ @output << "<#{HtmlBlockTag[@output_type]}#{@title_decoration}>"
135
+ if (@buffered_lines[0].kind_of?(Headline)) then
136
+ headline = @buffered_lines[0]
137
+ raise "Cannot be more than one headline!" if @buffered_lines.length > 1
138
+ if @options[:export_heading_number] then
139
+ level = headline.level
140
+ heading_number = get_next_headline_number(level)
141
+ output << "<span class=\"heading-number heading-number-#{level}\">#{heading_number} </span>"
142
+ end
143
+ if @options[:export_todo] and headline.keyword then
144
+ keyword = headline.keyword
145
+ output << "<span class=\"todo-keyword #{keyword}\">#{keyword} </span>"
146
+ end
147
+ end
148
+ @output << inline_formatting(@buffer)
149
+ @output << "</#{HtmlBlockTag[@output_type]}>\n"
150
+ @title_decoration = ""
151
+ else
152
+ @logger.debug "SKIP ==========> #{@buffer_mode}"
153
+ end
154
+ end
155
+ end
156
+ clear_accumulation_buffer!
157
+ end
158
+
159
+ def output_footnotes!
160
+ return false unless @options[:export_footnotes] and not @footnotes.empty?
161
+
162
+ @output << "<div id=\"footnotes\">\n<h2 class=\"footnotes\">Footnotes: </h2>\n<div id=\"text-footnotes\">\n"
163
+
164
+ @footnotes.each do |name, defi|
165
+ @output << "<p class=\"footnote\"><sup><a class=\"footnum\" name=\"fn.#{name}\" href=\"#fnr.#{name}\">#{name}</a></sup>" \
166
+ << inline_formatting(defi) \
167
+ << "</p>\n"
168
+ end
169
+
170
+ @output << "</div>\n</div>\n"
171
+
172
+ return true
173
+ end
174
+
175
+
176
+ ######################################################################
177
+ private
178
+
179
+ def skip_tables?
180
+ @options[:skip_tables]
181
+ end
182
+
183
+ def buffer_mode_is_table?
184
+ @buffer_mode == :table
185
+ end
186
+
187
+ # Escapes any HTML content in the output accumulation buffer @buffer.
188
+ def escape_buffer!
189
+ @buffer.gsub!(/&/, "&amp;")
190
+ @buffer.gsub!(/</, "&lt;")
191
+ @buffer.gsub!(/>/, "&gt;")
192
+ end
193
+
194
+ def output_indentation
195
+ indent = " " * (@mode_stack.length - 1)
196
+ @output << indent
197
+ end
198
+
199
+ Tags = {
200
+ "*" => { :open => "<b>", :close => "</b>" },
201
+ "/" => { :open => "<i>", :close => "</i>" },
202
+ "_" => { :open => "<span style=\"text-decoration:underline;\">",
203
+ :close => "</span>" },
204
+ "=" => { :open => "<code>", :close => "</code>" },
205
+ "~" => { :open => "<code>", :close => "</code>" },
206
+ "+" => { :open => "<del>", :close => "</del>" }
207
+ }
208
+
209
+ # Applies inline formatting rules to a string.
210
+ def inline_formatting(str)
211
+ str.rstrip!
212
+ str = @re_help.rewrite_emphasis(str) do |marker, s|
213
+ "#{Tags[marker][:open]}#{s}#{Tags[marker][:close]}"
214
+ end
215
+ if @options[:use_sub_superscripts] then
216
+ str = @re_help.rewrite_subp(str) do |type, text|
217
+ if type == "_" then
218
+ "<sub>#{text}</sub>"
219
+ elsif type == "^" then
220
+ "<sup>#{text}</sup>"
221
+ end
222
+ end
223
+ end
224
+ str = @re_help.rewrite_images(str) do |link|
225
+ "<a href=\"#{link}\"><img src=\"#{link}\" /></a>"
226
+ end
227
+ str = @re_help.rewrite_links(str) do |link, text|
228
+ text ||= link
229
+ link = link.sub(/^file:(.*)::(.*?)$/) do
230
+
231
+ # We don't support search links right now. Get rid of it.
232
+
233
+ "file:#{$1}"
234
+ end
235
+ link = link.sub(/^file:/i, "") # will default to HTTP
236
+ link = link.sub(/\.org$/i, ".html")
237
+ text = text.gsub(/([^\]]*\.(jpg|jpeg|gif|png))/xi) do |img_link|
238
+ "<img src=\"#{img_link}\" />"
239
+ end
240
+ "<a href=\"#{link}\">#{text}</a>"
241
+ end
242
+ if (@output_type == :table_row) then
243
+ str.gsub!(/^\|\s*/, "<td>")
244
+ str.gsub!(/\s*\|$/, "</td>")
245
+ str.gsub!(/\s*\|\s*/, "</td><td>")
246
+ end
247
+ if (@output_type == :table_header) then
248
+ str.gsub!(/^\|\s*/, "<th>")
249
+ str.gsub!(/\s*\|$/, "</th>")
250
+ str.gsub!(/\s*\|\s*/, "</th><th>")
251
+ end
252
+ if @options[:export_footnotes] then
253
+ str = @re_help.rewrite_footnote(str) do |name, defi|
254
+ # TODO escape name for url?
255
+ @footnotes[name] = defi if defi
256
+ "<sup><a class=\"footref\" name=\"fnr.#{name}\" href=\"#fn.#{name}\">#{name}</a></sup>"
257
+ end
258
+ end
259
+ Orgmode.special_symbols_to_html(str)
260
+ str
261
+ end
262
+
263
+ # Helper method taken from Rails
264
+ # https://github.com/rails/rails/blob/c2c8ef57d6f00d1c22743dc43746f95704d67a95/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10
265
+ def silence_warnings
266
+ warn_level = $VERBOSE
267
+ $VERBOSE = nil
268
+ yield
269
+ ensure
270
+ $VERBOSE = warn_level
271
+ end
272
+ end # class HtmlOutputBuffer
273
+ end # module Orgmode