lib/maruku/input_textile2/t2_parser.rb
class String
Textile2_EmptyLine = /^\s*$/
Textile2_Signature = /^(\S+\.?)\.\s(.*)/
def t2_empty?
self =~ Textile2_EmptyLine
end
def t2_contains_signature?
self =~ Textile2_Signature
end
# sig, rest = t2_get_signature
def t2_get_signature
self =~ Textile2_Signature
return Textile2Signature.new($1), $2
end
end
class Textile2Signature
Reg = %r{
^
# block name is 1
([A-Za-z0-9]+)?
# style is 2
(
\{ # open bracket
([^\}]+) # style spec is 3
\} # close bracket
)?
# language is 4
(\[(\w+)\])? # value is 5
# class and id
(?:
\( # open par
(\w+)? # optional class specification is 6
(?:\#(\w+))? # optional id is 7
\) # close par
)?
# alignment is 8
(\<|\>|\<\>|\=)?
# padding
(\(+)? # left is 9
(\)+)? # right is 10
# filters is 11
(\|
(?:(?:\w+)\|)+
)?
# optional final dot is 12
(\.)?
$
}x
def initialize(s)
if m = Reg.match(s)
self.block_name = m[1]
self.style = m[3]
self.lang = m[4]
self.css_class = m[6]
self.css_id = m[7]
self.text_align = {nil=>nil,'>'=>'right','<'=>'left',
'<>'=>'center','='=>'justified'}[m[8]]
self.num_left_pad = m[9] && m[9].size
self.num_right_pad = m[10] && m[10].size
self.filters = m[11] && m[11].split('|')
self.double_dot = m[12] && true
end
end
attr_accessor :block_name # or nil
attr_accessor :style # or nil
attr_accessor :lang # or nil
attr_accessor :css_class # or nil
attr_accessor :css_id # or nil
attr_accessor :text_align # {nil, 'left', 'right', 'center', 'justified'}
attr_accessor :num_left_pad # nil or 1..
attr_accessor :num_right_pad # nil or 1..
attr_accessor :filters # nil [], array of strings
attr_accessor :double_dot # nil or true
end
module MaRuKu
def self.textile2(source, params)
m = Maruku.new
m.t2_parse(source, params)
end
class MDDocument
def t2_parse(source, params)
src = LineSource.new(source)
output = BlockContext.new
t2_parse_blocks(src, output)
self.children = output.elements
end
Handling = Struct.new(:method, :parse_lines)
T2_Handling = {
nil => Handling.new(:t2_block_paragraph, true),
'p' => Handling.new(:t2_block_paragraph, true)
}
# Input is a LineSource
def t2_parse_blocks(src, output)
while src.cur_line
l = src.shift_line
# ignore empty line
if l.t2_empty? then
src.shift_line
next
end
# TODO: lists
# TODO: xml
# TODO: `==`
signature, l =
if l.t2_contains_signature?
l.t2_get_signature
else
[Textile2Signature.new, l]
end
if handling = T2_Handling.has_key?(signature.block_name)
if self.responds_to? handling.method
# read as many non-empty lines that you can
lines = [l]
if handling.parse_lines
while not src.cur_line.t2_empty?
lines.push src.shift_line
end
end
self.send(handling.method, src, output, signature, lines)
else
maruku_error("We don't know about method #{handling.method.inspect}")
next
end
end
end
end
def t2_block_paragraph(src, output, signature, lines)
paragraph = lines.join("\n")
src2 = CharSource.new(paragraph, src)
# output =
end
def t2_parse_span(src, output)
end
end # MDDocument
end