wallyqs-org-ruby 0.6.1 → 0.8.0
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/History.txt +41 -11
- data/README.rdoc +55 -50
- data/bin/org-ruby +11 -5
- data/lib/org-ruby.rb +20 -27
- data/lib/org-ruby/headline.rb +0 -10
- data/lib/org-ruby/html_output_buffer.rb +224 -143
- data/lib/org-ruby/html_symbol_replace.rb +359 -340
- data/lib/org-ruby/line.rb +91 -30
- data/lib/org-ruby/output_buffer.rb +147 -139
- data/lib/org-ruby/parser.rb +45 -111
- data/lib/org-ruby/regexp_helper.rb +52 -57
- data/lib/org-ruby/textile_output_buffer.rb +90 -37
- data/lib/org-ruby/textile_symbol_replace.rb +360 -341
- metadata +39 -200
- data/.bnsignore +0 -18
- data/.gitignore +0 -2
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -36
- data/Rakefile +0 -33
- data/TAGS +0 -167
- data/announcement.txt +0 -24
- data/org-ruby.gemspec +0 -40
- data/spec/data/freeform-example.org +0 -113
- data/spec/data/freeform.org +0 -111
- data/spec/data/hyp-planning.org +0 -335
- data/spec/data/remember.org +0 -53
- data/spec/headline_spec.rb +0 -65
- data/spec/html_examples/advanced-code.html +0 -81
- data/spec/html_examples/advanced-code.org +0 -106
- data/spec/html_examples/advanced-lists.html +0 -31
- data/spec/html_examples/advanced-lists.org +0 -31
- data/spec/html_examples/block_code.html +0 -28
- data/spec/html_examples/block_code.org +0 -35
- data/spec/html_examples/blockcomment.html +0 -3
- data/spec/html_examples/blockcomment.org +0 -15
- data/spec/html_examples/blockquote.html +0 -7
- data/spec/html_examples/blockquote.org +0 -13
- data/spec/html_examples/center.html +0 -6
- data/spec/html_examples/center.org +0 -7
- data/spec/html_examples/code-comment.html +0 -18
- data/spec/html_examples/code-comment.org +0 -22
- data/spec/html_examples/code-syntax.html +0 -98
- data/spec/html_examples/code-syntax.org +0 -99
- data/spec/html_examples/comment-trees.html +0 -4
- data/spec/html_examples/comment-trees.org +0 -13
- data/spec/html_examples/custom-seq-todo.html +0 -15
- data/spec/html_examples/custom-seq-todo.org +0 -24
- data/spec/html_examples/custom-todo.html +0 -15
- data/spec/html_examples/custom-todo.org +0 -24
- data/spec/html_examples/custom-typ-todo.html +0 -15
- data/spec/html_examples/custom-typ-todo.org +0 -24
- data/spec/html_examples/deflist.html +0 -6
- data/spec/html_examples/deflist.org +0 -6
- data/spec/html_examples/entities.html +0 -4
- data/spec/html_examples/entities.org +0 -11
- data/spec/html_examples/escape-pre.html +0 -6
- data/spec/html_examples/escape-pre.org +0 -6
- data/spec/html_examples/export-exclude-only.html +0 -13
- data/spec/html_examples/export-exclude-only.org +0 -81
- data/spec/html_examples/export-keywords.html +0 -4
- data/spec/html_examples/export-keywords.org +0 -18
- data/spec/html_examples/export-tags.html +0 -8
- data/spec/html_examples/export-tags.org +0 -82
- data/spec/html_examples/export-title.html +0 -2
- data/spec/html_examples/export-title.org +0 -4
- data/spec/html_examples/footnotes.html +0 -10
- data/spec/html_examples/footnotes.org +0 -7
- data/spec/html_examples/html-literal.html +0 -2
- data/spec/html_examples/html-literal.org +0 -6
- data/spec/html_examples/inline-formatting.html +0 -20
- data/spec/html_examples/inline-formatting.org +0 -33
- data/spec/html_examples/inline-images.html +0 -10
- data/spec/html_examples/inline-images.org +0 -15
- data/spec/html_examples/link-features.html +0 -8
- data/spec/html_examples/link-features.org +0 -19
- data/spec/html_examples/lists.html +0 -23
- data/spec/html_examples/lists.org +0 -47
- data/spec/html_examples/metadata-comment.html +0 -27
- data/spec/html_examples/metadata-comment.org +0 -30
- data/spec/html_examples/only-list.html +0 -5
- data/spec/html_examples/only-list.org +0 -3
- data/spec/html_examples/only-table.html +0 -6
- data/spec/html_examples/only-table.org +0 -5
- data/spec/html_examples/skip-header.html +0 -3
- data/spec/html_examples/skip-header.org +0 -28
- data/spec/html_examples/skip-table.html +0 -4
- data/spec/html_examples/skip-table.org +0 -19
- data/spec/html_examples/subsupscript-nil.html +0 -3
- data/spec/html_examples/subsupscript-nil.org +0 -6
- data/spec/html_examples/subsupscript.html +0 -3
- data/spec/html_examples/subsupscript.org +0 -5
- data/spec/html_examples/tables.html +0 -35
- data/spec/html_examples/tables.org +0 -50
- data/spec/html_examples/text.html +0 -2
- data/spec/html_examples/text.org +0 -16
- data/spec/line_spec.rb +0 -155
- data/spec/output_buffer_spec.rb +0 -19
- data/spec/parser_spec.rb +0 -152
- data/spec/regexp_helper_spec.rb +0 -57
- data/spec/spec_helper.rb +0 -20
- data/spec/textile_examples/block_code.org +0 -35
- data/spec/textile_examples/block_code.textile +0 -29
- data/spec/textile_examples/blockquote.org +0 -13
- data/spec/textile_examples/blockquote.textile +0 -11
- data/spec/textile_examples/center.org +0 -7
- data/spec/textile_examples/center.textile +0 -6
- data/spec/textile_examples/footnotes.org +0 -7
- data/spec/textile_examples/footnotes.textile +0 -8
- data/spec/textile_examples/keywords.org +0 -13
- data/spec/textile_examples/keywords.textile +0 -11
- data/spec/textile_examples/links.org +0 -11
- data/spec/textile_examples/links.textile +0 -10
- data/spec/textile_examples/lists.org +0 -36
- data/spec/textile_examples/lists.textile +0 -20
- data/spec/textile_examples/single-space-plain-list.org +0 -13
- data/spec/textile_examples/single-space-plain-list.textile +0 -10
- data/spec/textile_examples/tables.org +0 -50
- data/spec/textile_examples/tables.textile +0 -40
- data/spec/textile_output_buffer_spec.rb +0 -21
- data/tasks/test_case.rake +0 -49
- data/test/test_orgmode_parser.rb +0 -0
- data/util/gen-special-replace.el +0 -37
data/lib/org-ruby/parser.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
1
|
require 'rubypants'
|
|
3
2
|
|
|
4
3
|
module Orgmode
|
|
@@ -100,74 +99,48 @@ module Orgmode
|
|
|
100
99
|
mode = :normal
|
|
101
100
|
previous_line = nil
|
|
102
101
|
table_header_set = false
|
|
103
|
-
@lines.each do |
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
@lines.each do |text|
|
|
103
|
+
line = Line.new text, self
|
|
104
|
+
mode = :normal if line.end_block? and mode == line.paragraph_type
|
|
105
|
+
mode = :normal if line.property_drawer_end_block? and mode == :property_drawer
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
end
|
|
116
|
-
if line.table_separator? then
|
|
117
|
-
if previous_line and previous_line.paragraph_type == :table_row and !table_header_set
|
|
118
|
-
previous_line.assigned_paragraph_type = :table_header
|
|
119
|
-
table_header_set = true
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
table_header_set = false if !line.table?
|
|
123
|
-
mode = :code if line.begin_block? and line.block_type == "EXAMPLE"
|
|
124
|
-
mode = :block_comment if line.begin_block? and line.block_type == "COMMENT"
|
|
125
|
-
mode = :property_drawer if line.property_drawer_begin_block?
|
|
126
|
-
if (@current_headline) then
|
|
127
|
-
@current_headline.body_lines << line
|
|
128
|
-
else
|
|
129
|
-
@header_lines << line
|
|
107
|
+
case mode
|
|
108
|
+
when :normal, :quote, :center
|
|
109
|
+
if Headline.headline? line.line
|
|
110
|
+
line = Headline.new line.line, self, offset
|
|
111
|
+
elsif line.table_separator?
|
|
112
|
+
if previous_line and previous_line.paragraph_type == :table_row and !table_header_set
|
|
113
|
+
previous_line.assigned_paragraph_type = :table_header
|
|
114
|
+
table_header_set = true
|
|
130
115
|
end
|
|
131
116
|
end
|
|
117
|
+
table_header_set = false if !line.table?
|
|
132
118
|
|
|
133
|
-
when :
|
|
134
|
-
|
|
135
|
-
if line.end_block? and line.block_type == "COMMENT"
|
|
136
|
-
mode = :normal
|
|
137
|
-
else
|
|
138
|
-
line.assigned_paragraph_type = :comment
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
when :code
|
|
142
|
-
|
|
143
|
-
# As long as we stay in code mode, force lines to be either blank or paragraphs.
|
|
119
|
+
when :example, :html, :src
|
|
120
|
+
# As long as we stay in code mode, force lines to be code.
|
|
144
121
|
# Don't try to interpret structural items, like headings and tables.
|
|
145
|
-
line =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
else
|
|
154
|
-
@header_lines << line
|
|
122
|
+
line.assigned_paragraph_type = :code
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if mode == :normal
|
|
126
|
+
@headlines << @current_headline = line if Headline.headline? line.line
|
|
127
|
+
# If there is a setting on this line, remember it.
|
|
128
|
+
line.in_buffer_setting? do |key, value|
|
|
129
|
+
store_in_buffer_setting key.upcase, value
|
|
155
130
|
end
|
|
156
131
|
|
|
157
|
-
|
|
132
|
+
mode = line.paragraph_type if line.begin_block?
|
|
133
|
+
mode = :property_drawer if line.property_drawer_begin_block?
|
|
134
|
+
end
|
|
158
135
|
|
|
159
|
-
|
|
160
|
-
if
|
|
161
|
-
mode = :normal
|
|
162
|
-
else
|
|
163
|
-
line.assigned_paragraph_type = :property_drawer unless line.blank?
|
|
164
|
-
end
|
|
165
|
-
if (@current_headline) then
|
|
136
|
+
unless mode == :comment
|
|
137
|
+
if @current_headline
|
|
166
138
|
@current_headline.body_lines << line
|
|
167
139
|
else
|
|
168
140
|
@header_lines << line
|
|
169
141
|
end
|
|
170
|
-
end
|
|
142
|
+
end
|
|
143
|
+
|
|
171
144
|
previous_line = line
|
|
172
145
|
end # @lines.each
|
|
173
146
|
end # initialize
|
|
@@ -181,9 +154,11 @@ module Orgmode
|
|
|
181
154
|
# Saves the loaded orgmode file as a textile file.
|
|
182
155
|
def to_textile
|
|
183
156
|
output = ""
|
|
184
|
-
|
|
157
|
+
output_buffer = TextileOutputBuffer.new(output)
|
|
158
|
+
|
|
159
|
+
translate(@header_lines, output_buffer)
|
|
185
160
|
@headlines.each do |headline|
|
|
186
|
-
|
|
161
|
+
translate(headline.body_lines, output_buffer)
|
|
187
162
|
end
|
|
188
163
|
output
|
|
189
164
|
end
|
|
@@ -192,7 +167,7 @@ module Orgmode
|
|
|
192
167
|
def to_html
|
|
193
168
|
mark_trees_for_export
|
|
194
169
|
export_options = {
|
|
195
|
-
:decorate_title =>
|
|
170
|
+
:decorate_title => @in_buffer_settings["TITLE"],
|
|
196
171
|
:export_heading_number => export_heading_number?,
|
|
197
172
|
:export_todo => export_todo?,
|
|
198
173
|
:use_sub_superscripts => use_sub_superscripts?,
|
|
@@ -207,9 +182,9 @@ module Orgmode
|
|
|
207
182
|
# If we're given a new title, then just create a new line
|
|
208
183
|
# for that title.
|
|
209
184
|
title = Line.new(@in_buffer_settings["TITLE"], self)
|
|
210
|
-
|
|
185
|
+
translate([title], output_buffer)
|
|
211
186
|
end
|
|
212
|
-
|
|
187
|
+
translate(@header_lines, output_buffer) unless skip_header_lines?
|
|
213
188
|
|
|
214
189
|
# If we've output anything at all, remove the :decorate_title option.
|
|
215
190
|
export_options.delete(:decorate_title) if (output.length > 0)
|
|
@@ -219,11 +194,13 @@ module Orgmode
|
|
|
219
194
|
when :exclude
|
|
220
195
|
# NOTHING
|
|
221
196
|
when :headline_only
|
|
222
|
-
|
|
197
|
+
translate(headline.body_lines[0, 1], output_buffer)
|
|
223
198
|
when :all
|
|
224
|
-
|
|
199
|
+
translate(headline.body_lines, output_buffer)
|
|
225
200
|
end
|
|
226
201
|
end
|
|
202
|
+
output << "\n"
|
|
203
|
+
|
|
227
204
|
rp = RubyPants.new(output)
|
|
228
205
|
rp.to_html
|
|
229
206
|
end
|
|
@@ -233,54 +210,11 @@ module Orgmode
|
|
|
233
210
|
|
|
234
211
|
# Converts an array of lines to the appropriate format.
|
|
235
212
|
# Writes the output to +output_buffer+.
|
|
236
|
-
def
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# See if we're carrying paragraph payload, and output
|
|
240
|
-
# it if we're about to switch to some other output type.
|
|
241
|
-
output_buffer.prepare(line)
|
|
242
|
-
case line.paragraph_type
|
|
243
|
-
when :metadata, :table_separator, :blank, :comment, :property_drawer_item, :property_drawer_begin_block, :property_drawer_end_block
|
|
244
|
-
|
|
245
|
-
output_buffer << line.line if output_buffer.preserve_whitespace?
|
|
246
|
-
|
|
247
|
-
when :begin_block
|
|
248
|
-
|
|
249
|
-
output_buffer.push_mode(:blockquote) if line.block_type.casecmp("QUOTE") == 0
|
|
250
|
-
output_buffer.push_mode(:src) if line.block_type.casecmp("SRC") == 0
|
|
251
|
-
output_buffer.push_mode(:example) if line.block_type.casecmp("EXAMPLE") == 0
|
|
252
|
-
output_buffer.push_mode(:center) if line.block_type.casecmp("CENTER") == 0
|
|
253
|
-
|
|
254
|
-
when :end_block
|
|
255
|
-
|
|
256
|
-
output_buffer.pop_mode(:blockquote) if line.block_type.casecmp("QUOTE") == 0
|
|
257
|
-
output_buffer.pop_mode(:src) if line.block_type.casecmp("SRC") == 0
|
|
258
|
-
output_buffer.pop_mode(:example) if line.block_type.casecmp("EXAMPLE") == 0
|
|
259
|
-
output_buffer.pop_mode(:center) if line.block_type.casecmp("CENTER") == 0
|
|
260
|
-
|
|
261
|
-
when :table_row, :table_header
|
|
262
|
-
|
|
263
|
-
output_buffer << line.line.lstrip
|
|
264
|
-
|
|
265
|
-
when :unordered_list, :ordered_list, :definition_list
|
|
266
|
-
|
|
267
|
-
output_buffer << line.output_text << " "
|
|
268
|
-
|
|
269
|
-
when :inline_example
|
|
270
|
-
|
|
271
|
-
output_buffer << line.output_text
|
|
272
|
-
|
|
273
|
-
else
|
|
274
|
-
|
|
275
|
-
if output_buffer.preserve_whitespace? then
|
|
276
|
-
output_buffer << line.output_text
|
|
277
|
-
else
|
|
278
|
-
output_buffer << line.output_text.strip << " "
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
end
|
|
213
|
+
def translate(lines, output_buffer)
|
|
214
|
+
output_buffer.output_type = :start
|
|
215
|
+
lines.each { |line| output_buffer.insert(line) }
|
|
282
216
|
output_buffer.flush!
|
|
283
|
-
output_buffer.pop_mode
|
|
217
|
+
output_buffer.pop_mode while output_buffer.current_mode
|
|
284
218
|
output_buffer.output_footnotes!
|
|
285
219
|
output_buffer.output
|
|
286
220
|
end
|
|
@@ -3,7 +3,7 @@ require 'logger'
|
|
|
3
3
|
module Orgmode
|
|
4
4
|
|
|
5
5
|
# = Summary
|
|
6
|
-
#
|
|
6
|
+
#
|
|
7
7
|
# This class contains helper routines to deal with the Regexp "black
|
|
8
8
|
# magic" you need to properly parse org-mode files.
|
|
9
9
|
#
|
|
@@ -39,24 +39,20 @@ module Orgmode
|
|
|
39
39
|
# body-regexp A regexp like \".\" to match a body character. Don't use
|
|
40
40
|
# non-shy groups here, and don't allow newline here.
|
|
41
41
|
# newline The maximum number of newlines allowed in an emphasis exp.
|
|
42
|
-
#
|
|
43
|
-
# I currently don't use +newline+ because I've thrown this information
|
|
44
|
-
# away by this point in the code. TODO -- revisit?
|
|
45
|
-
attr_reader :pre_emphasis
|
|
46
|
-
attr_reader :post_emphasis
|
|
47
|
-
attr_reader :border_forbidden
|
|
48
|
-
attr_reader :body_regexp
|
|
49
|
-
attr_reader :markers
|
|
50
42
|
|
|
51
|
-
attr_reader
|
|
43
|
+
attr_reader :org_image_file_regexp
|
|
52
44
|
|
|
53
45
|
def initialize
|
|
54
46
|
# Set up the emphasis regular expression.
|
|
55
|
-
@pre_emphasis =
|
|
56
|
-
@post_emphasis =
|
|
57
|
-
@border_forbidden = "
|
|
58
|
-
@body_regexp =
|
|
59
|
-
@
|
|
47
|
+
@pre_emphasis = ' \t\(\'"\{'
|
|
48
|
+
@post_emphasis = '- \t\.,:!\?;\'"\)\}\\\\'
|
|
49
|
+
@border_forbidden = '\s,"\''
|
|
50
|
+
@body_regexp = '.*?'
|
|
51
|
+
@max_newlines = 1
|
|
52
|
+
@body_regexp = "#{@body_regexp}" +
|
|
53
|
+
"(?:\\n#{@body_regexp}){0,#{@max_newlines}}" if @max_newlines > 0
|
|
54
|
+
@markers = '\*\/_=~\+'
|
|
55
|
+
@code_snippet_stack = []
|
|
60
56
|
@logger = Logger.new(STDERR)
|
|
61
57
|
@logger.level = Logger::WARN
|
|
62
58
|
build_org_emphasis_regexp
|
|
@@ -94,23 +90,32 @@ module Orgmode
|
|
|
94
90
|
# replace "*bold*", "/italic/", and "=code=",
|
|
95
91
|
# respectively. (Clearly this sample string will use HTML-like
|
|
96
92
|
# syntax, assuming +map+ is defined appropriately.)
|
|
97
|
-
def rewrite_emphasis
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
def rewrite_emphasis str
|
|
94
|
+
# escape the percent signs for safe restoring code snippets
|
|
95
|
+
str.gsub!(/%/, "%%")
|
|
96
|
+
format_str = "%s"
|
|
97
|
+
str.gsub! @org_emphasis_regexp do |match|
|
|
98
|
+
# preserve the code snippet from further formatting
|
|
99
|
+
inner = if $2 == "=" or $2 == "~"
|
|
100
|
+
@code_snippet_stack.push $3
|
|
101
|
+
yield $2, format_str
|
|
102
|
+
else
|
|
103
|
+
yield $2, $3
|
|
104
|
+
end
|
|
105
|
+
"#{$1}#{inner}"
|
|
101
106
|
end
|
|
102
107
|
end
|
|
103
108
|
|
|
104
109
|
# rewrite subscript and superscript (_{foo} and ^{bar})
|
|
105
|
-
def rewrite_subp
|
|
106
|
-
str.gsub
|
|
110
|
+
def rewrite_subp str # :yields: type ("_" for subscript and "^" for superscript), text
|
|
111
|
+
str.gsub! @org_subp_regexp do |match|
|
|
107
112
|
yield $1, $2
|
|
108
113
|
end
|
|
109
114
|
end
|
|
110
115
|
|
|
111
116
|
# rewrite footnotes
|
|
112
|
-
def rewrite_footnote
|
|
113
|
-
str.gsub
|
|
117
|
+
def rewrite_footnote str # :yields: name, definition or nil
|
|
118
|
+
str.gsub! @org_footnote_regexp do |match|
|
|
114
119
|
yield $1, $3
|
|
115
120
|
end
|
|
116
121
|
end
|
|
@@ -121,7 +126,7 @@ module Orgmode
|
|
|
121
126
|
# output format.
|
|
122
127
|
#
|
|
123
128
|
# = Usage
|
|
124
|
-
#
|
|
129
|
+
#
|
|
125
130
|
# Give this a block that expect the link and optional friendly
|
|
126
131
|
# text. Return how that link should get formatted.
|
|
127
132
|
#
|
|
@@ -140,53 +145,43 @@ module Orgmode
|
|
|
140
145
|
# +http://www.hotmail.com+. In both cases, the block returns an
|
|
141
146
|
# HTML-style link, and that is how things will get recorded in
|
|
142
147
|
# +result+.
|
|
143
|
-
def rewrite_links
|
|
144
|
-
|
|
145
|
-
yield $1,
|
|
148
|
+
def rewrite_links str # :yields: link, text
|
|
149
|
+
str.gsub! @org_link_regexp do |match|
|
|
150
|
+
yield $1, $3
|
|
146
151
|
end
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
yield "#{$2}:#{$3}", nil
|
|
150
|
-
end
|
|
151
|
-
else
|
|
152
|
-
i.gsub(@org_link_text_regexp) do |match|
|
|
153
|
-
yield $1, $2
|
|
154
|
-
end
|
|
152
|
+
str.gsub! @org_angle_link_text_regexp do |match|
|
|
153
|
+
yield $1, nil
|
|
155
154
|
end
|
|
155
|
+
|
|
156
|
+
str # for testing
|
|
156
157
|
end
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
end
|
|
159
|
+
def restore_code_snippets str
|
|
160
|
+
str = str % @code_snippet_stack
|
|
161
|
+
@code_snippet_stack = []
|
|
162
|
+
str
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
private
|
|
166
166
|
|
|
167
167
|
def build_org_emphasis_regexp
|
|
168
|
-
@org_emphasis_regexp = Regexp.new("([#{@pre_emphasis}]|^)
|
|
169
|
-
"(
|
|
170
|
-
"(
|
|
171
|
-
"
|
|
172
|
-
"\\2
|
|
173
|
-
"([#{@post_emphasis}]|$)
|
|
168
|
+
@org_emphasis_regexp = Regexp.new("([#{@pre_emphasis}]|^)" +
|
|
169
|
+
"([#{@markers}])(?!\\2)" +
|
|
170
|
+
"([^#{@border_forbidden}]|" +
|
|
171
|
+
"[^#{@border_forbidden}]#{@body_regexp}" +
|
|
172
|
+
"[^#{@border_forbidden}])\\2" +
|
|
173
|
+
"(?=[#{@post_emphasis}]|$)")
|
|
174
174
|
@logger.debug "Just created regexp: #{@org_emphasis_regexp}"
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
def build_org_link_regexp
|
|
178
178
|
@org_link_regexp = /\[\[
|
|
179
|
-
([^\]]
|
|
180
|
-
\]\
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
@
|
|
185
|
-
([^\]]*) # This is the URL
|
|
186
|
-
\]\[
|
|
187
|
-
([^\]]*) # This is the friendly text
|
|
188
|
-
\]\]/x
|
|
189
|
-
@org_angle_link_text_regexp = /(<|<)(\w+):([^\]\t\n\r<> ][^\]\t\n\r<> ]*)(>|>)/x
|
|
179
|
+
([^\]\[]+) # This is the URL
|
|
180
|
+
\](\[
|
|
181
|
+
([^\]\[]+) # This is the friendly text
|
|
182
|
+
\])?\]/x
|
|
183
|
+
@org_angle_link_text_regexp = /<(\w+:[^\]\s<>]+)>/
|
|
184
|
+
@org_image_file_regexp = /\.(gif|jpe?g|p(?:bm|gm|n[gm]|pm)|svg|tiff?|x[bp]m)/i
|
|
190
185
|
end
|
|
191
186
|
end # class Emphasis
|
|
192
187
|
end # module Orgmode
|
|
@@ -6,21 +6,28 @@ module Orgmode
|
|
|
6
6
|
|
|
7
7
|
def initialize(output)
|
|
8
8
|
super(output)
|
|
9
|
-
@add_paragraph =
|
|
9
|
+
@add_paragraph = true
|
|
10
10
|
@support_definition_list = true # TODO this should be an option
|
|
11
|
-
@footnotes =
|
|
11
|
+
@footnotes = []
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def push_mode(mode)
|
|
14
|
+
def push_mode(mode, indent)
|
|
15
|
+
@list_indent_stack.push(indent)
|
|
15
16
|
super(mode)
|
|
16
|
-
@output << "bc
|
|
17
|
-
|
|
17
|
+
@output << "bc. " if mode_is_code? mode
|
|
18
|
+
if mode == :center or mode == :quote
|
|
19
|
+
@add_paragraph = false
|
|
20
|
+
@output << "\n"
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
def pop_mode(mode = nil)
|
|
21
25
|
m = super(mode)
|
|
22
|
-
@
|
|
23
|
-
|
|
26
|
+
@list_indent_stack.pop
|
|
27
|
+
if m == :center or m == :quote
|
|
28
|
+
@add_paragraph = true
|
|
29
|
+
@output << "\n"
|
|
30
|
+
end
|
|
24
31
|
m
|
|
25
32
|
end
|
|
26
33
|
|
|
@@ -36,37 +43,68 @@ module Orgmode
|
|
|
36
43
|
|
|
37
44
|
# Handles inline formatting for textile.
|
|
38
45
|
def inline_formatting(input)
|
|
39
|
-
|
|
46
|
+
@re_help.rewrite_emphasis input do |marker, body|
|
|
40
47
|
m = TextileMap[marker]
|
|
41
48
|
"#{m}#{body}#{m}"
|
|
42
49
|
end
|
|
43
|
-
|
|
50
|
+
@re_help.rewrite_subp input do |type, text|
|
|
44
51
|
if type == "_" then
|
|
45
52
|
"~#{text}~"
|
|
46
53
|
elsif type == "^" then
|
|
47
54
|
"^#{text}^"
|
|
48
55
|
end
|
|
49
56
|
end
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
@re_help.rewrite_links input do |link, defi|
|
|
58
|
+
[link, defi].compact.each do |text|
|
|
59
|
+
# We don't support search links right now. Get rid of it.
|
|
60
|
+
text.sub!(/\A(file:[^\s]+)::[^\s]*?\Z/, "\\1")
|
|
61
|
+
text.sub!(/\A(file:[^\s]+)\.org\Z/i, "\\1.textile")
|
|
62
|
+
text.sub!(/\Afile:(?=[^\s]+\Z)/, "")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# We don't add a description for images in links, because its
|
|
66
|
+
# empty value forces the image to be inlined.
|
|
67
|
+
defi ||= link unless link =~ @re_help.org_image_file_regexp
|
|
68
|
+
link = link.gsub(/ /, "%%20")
|
|
69
|
+
|
|
70
|
+
if defi =~ @re_help.org_image_file_regexp
|
|
71
|
+
defi = "!#{defi}(#{defi})!"
|
|
72
|
+
elsif defi
|
|
73
|
+
defi = "\"#{defi}\""
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if defi
|
|
77
|
+
"#{defi}:#{link}"
|
|
78
|
+
else
|
|
79
|
+
"!#{link}(#{link})!"
|
|
80
|
+
end
|
|
54
81
|
end
|
|
55
|
-
|
|
56
|
-
# textile only support numerical names
|
|
57
|
-
|
|
58
|
-
@footnotes[name]
|
|
59
|
-
|
|
82
|
+
@re_help.rewrite_footnote input do |name, definition|
|
|
83
|
+
# textile only support numerical names, so we need to do some conversion
|
|
84
|
+
# Try to find the footnote and use its index
|
|
85
|
+
footnote = @footnotes.select {|f| f[:name] == name }.first
|
|
86
|
+
if footnote
|
|
87
|
+
# The latest definition overrides other ones
|
|
88
|
+
footnote[:definition] = definition if definition and not footnote[:definition]
|
|
89
|
+
else
|
|
90
|
+
# There is no footnote with the current name so we add it
|
|
91
|
+
footnote = { :name => name, :definition => definition }
|
|
92
|
+
@footnotes << footnote
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
"[#{@footnotes.index(footnote)}]"
|
|
60
96
|
end
|
|
61
97
|
Orgmode.special_symbols_to_textile(input)
|
|
98
|
+
input = @re_help.restore_code_snippets input
|
|
62
99
|
input
|
|
63
100
|
end
|
|
64
101
|
|
|
65
102
|
def output_footnotes!
|
|
66
103
|
return false if @footnotes.empty?
|
|
67
104
|
|
|
68
|
-
@footnotes.each do |
|
|
69
|
-
|
|
105
|
+
@footnotes.each do |footnote|
|
|
106
|
+
index = @footnotes.index(footnote)
|
|
107
|
+
@output << "\nfn#{index}. #{footnote[:definition] || 'DEFINITION NOT FOUND' }\n"
|
|
70
108
|
end
|
|
71
109
|
|
|
72
110
|
return true
|
|
@@ -74,29 +112,44 @@ module Orgmode
|
|
|
74
112
|
|
|
75
113
|
# Flushes the current buffer
|
|
76
114
|
def flush!
|
|
115
|
+
return false if @buffer.empty? and @output_type != :blank
|
|
77
116
|
@logger.debug "FLUSH ==========> #{@output_type}"
|
|
78
|
-
|
|
117
|
+
@buffer.gsub!(/\A\n*/, "")
|
|
118
|
+
|
|
119
|
+
case
|
|
120
|
+
when preserve_whitespace?
|
|
121
|
+
@output << @buffer << "\n"
|
|
122
|
+
|
|
123
|
+
when @output_type == :blank
|
|
79
124
|
@output << "\n"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
125
|
+
|
|
126
|
+
else
|
|
127
|
+
case current_mode
|
|
128
|
+
when :paragraph
|
|
129
|
+
@output << "p. " if @add_paragraph
|
|
130
|
+
@output << "p=. " if @mode_stack[0] == :center
|
|
131
|
+
@output << "bq. " if @mode_stack[0] == :quote
|
|
132
|
+
|
|
133
|
+
when :list_item
|
|
134
|
+
if @mode_stack[-2] == :ordered_list
|
|
135
|
+
@output << "#" * @mode_stack.count(:list_item) << " "
|
|
136
|
+
else # corresponds to unordered list
|
|
137
|
+
@output << "*" * @mode_stack.count(:list_item) << " "
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
when :definition_term
|
|
141
|
+
if @support_definition_list
|
|
142
|
+
@output << "-" * @mode_stack.count(:definition_term) << " "
|
|
143
|
+
@buffer.sub!("::", ":=")
|
|
144
|
+
end
|
|
94
145
|
end
|
|
95
146
|
@output << inline_formatting(@buffer) << "\n"
|
|
96
147
|
end
|
|
97
|
-
|
|
148
|
+
@buffer = ""
|
|
98
149
|
end
|
|
99
150
|
|
|
100
|
-
|
|
151
|
+
def add_line_attributes headline
|
|
152
|
+
@output << "h#{headline.level}. "
|
|
153
|
+
end
|
|
101
154
|
end # class TextileOutputBuffer
|
|
102
155
|
end # module Orgmode
|