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.
- 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
|