wallyqs-org-ruby 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.bnsignore +18 -0
- data/.gitignore +2 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +36 -0
- data/History.txt +112 -0
- data/README.rdoc +67 -0
- data/Rakefile +33 -0
- data/TAGS +167 -0
- data/announcement.txt +24 -0
- data/bin/org-ruby +45 -0
- data/lib/org-ruby.rb +55 -0
- data/lib/org-ruby/headline.rb +110 -0
- data/lib/org-ruby/html_output_buffer.rb +273 -0
- data/lib/org-ruby/html_symbol_replace.rb +345 -0
- data/lib/org-ruby/line.rb +244 -0
- data/lib/org-ruby/output_buffer.rb +237 -0
- data/lib/org-ruby/parser.rb +366 -0
- data/lib/org-ruby/regexp_helper.rb +192 -0
- data/lib/org-ruby/textile_output_buffer.rb +102 -0
- data/lib/org-ruby/textile_symbol_replace.rb +346 -0
- data/lib/org-ruby/tilt.rb +29 -0
- data/org-ruby.gemspec +40 -0
- data/spec/data/freeform-example.org +113 -0
- data/spec/data/freeform.org +111 -0
- data/spec/data/hyp-planning.org +335 -0
- data/spec/data/remember.org +53 -0
- data/spec/headline_spec.rb +65 -0
- data/spec/html_examples/advanced-code.html +81 -0
- data/spec/html_examples/advanced-code.org +106 -0
- data/spec/html_examples/advanced-lists.html +31 -0
- data/spec/html_examples/advanced-lists.org +31 -0
- data/spec/html_examples/block_code.html +28 -0
- data/spec/html_examples/block_code.org +35 -0
- data/spec/html_examples/blockcomment.html +3 -0
- data/spec/html_examples/blockcomment.org +15 -0
- data/spec/html_examples/blockquote.html +7 -0
- data/spec/html_examples/blockquote.org +13 -0
- data/spec/html_examples/center.html +6 -0
- data/spec/html_examples/center.org +7 -0
- data/spec/html_examples/code-comment.html +18 -0
- data/spec/html_examples/code-comment.org +22 -0
- data/spec/html_examples/code-syntax.html +98 -0
- data/spec/html_examples/code-syntax.org +99 -0
- data/spec/html_examples/comment-trees.html +4 -0
- data/spec/html_examples/comment-trees.org +13 -0
- data/spec/html_examples/custom-seq-todo.html +15 -0
- data/spec/html_examples/custom-seq-todo.org +24 -0
- data/spec/html_examples/custom-todo.html +15 -0
- data/spec/html_examples/custom-todo.org +24 -0
- data/spec/html_examples/custom-typ-todo.html +15 -0
- data/spec/html_examples/custom-typ-todo.org +24 -0
- data/spec/html_examples/deflist.html +6 -0
- data/spec/html_examples/deflist.org +6 -0
- data/spec/html_examples/entities.html +4 -0
- data/spec/html_examples/entities.org +11 -0
- data/spec/html_examples/escape-pre.html +6 -0
- data/spec/html_examples/escape-pre.org +6 -0
- data/spec/html_examples/export-exclude-only.html +13 -0
- data/spec/html_examples/export-exclude-only.org +81 -0
- data/spec/html_examples/export-keywords.html +4 -0
- data/spec/html_examples/export-keywords.org +18 -0
- data/spec/html_examples/export-tags.html +8 -0
- data/spec/html_examples/export-tags.org +82 -0
- data/spec/html_examples/export-title.html +2 -0
- data/spec/html_examples/export-title.org +4 -0
- data/spec/html_examples/footnotes.html +10 -0
- data/spec/html_examples/footnotes.org +7 -0
- data/spec/html_examples/html-literal.html +2 -0
- data/spec/html_examples/html-literal.org +6 -0
- data/spec/html_examples/inline-formatting.html +20 -0
- data/spec/html_examples/inline-formatting.org +33 -0
- data/spec/html_examples/inline-images.html +10 -0
- data/spec/html_examples/inline-images.org +15 -0
- data/spec/html_examples/link-features.html +8 -0
- data/spec/html_examples/link-features.org +19 -0
- data/spec/html_examples/lists.html +23 -0
- data/spec/html_examples/lists.org +47 -0
- data/spec/html_examples/metadata-comment.html +27 -0
- data/spec/html_examples/metadata-comment.org +30 -0
- data/spec/html_examples/only-list.html +5 -0
- data/spec/html_examples/only-list.org +3 -0
- data/spec/html_examples/only-table.html +6 -0
- data/spec/html_examples/only-table.org +5 -0
- data/spec/html_examples/skip-header.html +3 -0
- data/spec/html_examples/skip-header.org +28 -0
- data/spec/html_examples/skip-table.html +4 -0
- data/spec/html_examples/skip-table.org +19 -0
- data/spec/html_examples/subsupscript-nil.html +3 -0
- data/spec/html_examples/subsupscript-nil.org +6 -0
- data/spec/html_examples/subsupscript.html +3 -0
- data/spec/html_examples/subsupscript.org +5 -0
- data/spec/html_examples/tables.html +35 -0
- data/spec/html_examples/tables.org +50 -0
- data/spec/html_examples/text.html +2 -0
- data/spec/html_examples/text.org +16 -0
- data/spec/line_spec.rb +155 -0
- data/spec/output_buffer_spec.rb +19 -0
- data/spec/parser_spec.rb +152 -0
- data/spec/regexp_helper_spec.rb +57 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/textile_examples/block_code.org +35 -0
- data/spec/textile_examples/block_code.textile +29 -0
- data/spec/textile_examples/blockquote.org +13 -0
- data/spec/textile_examples/blockquote.textile +11 -0
- data/spec/textile_examples/center.org +7 -0
- data/spec/textile_examples/center.textile +6 -0
- data/spec/textile_examples/footnotes.org +7 -0
- data/spec/textile_examples/footnotes.textile +8 -0
- data/spec/textile_examples/keywords.org +13 -0
- data/spec/textile_examples/keywords.textile +11 -0
- data/spec/textile_examples/links.org +11 -0
- data/spec/textile_examples/links.textile +10 -0
- data/spec/textile_examples/lists.org +36 -0
- data/spec/textile_examples/lists.textile +20 -0
- data/spec/textile_examples/single-space-plain-list.org +13 -0
- data/spec/textile_examples/single-space-plain-list.textile +10 -0
- data/spec/textile_examples/tables.org +50 -0
- data/spec/textile_examples/tables.textile +40 -0
- data/spec/textile_output_buffer_spec.rb +21 -0
- data/tasks/test_case.rake +49 -0
- data/test/test_orgmode_parser.rb +0 -0
- data/util/gen-special-replace.el +37 -0
- metadata +244 -0
data/announcement.txt
ADDED
@@ -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
|
data/bin/org-ruby
ADDED
@@ -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
|
+
|
data/lib/org-ruby.rb
ADDED
@@ -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!(/&/, "&")
|
190
|
+
@buffer.gsub!(/</, "<")
|
191
|
+
@buffer.gsub!(/>/, ">")
|
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
|