wallyqs-org-ruby 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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