maiku 0.6.1.maiku
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/lib/maruku.rb +141 -0
- data/lib/maruku/attributes.rb +175 -0
- data/lib/maruku/defaults.rb +71 -0
- data/lib/maruku/errors_management.rb +92 -0
- data/lib/maruku/ext/div.rb +133 -0
- data/lib/maruku/ext/math.rb +41 -0
- data/lib/maruku/ext/math/elements.rb +27 -0
- data/lib/maruku/ext/math/latex_fix.rb +12 -0
- data/lib/maruku/ext/math/mathml_engines/blahtex.rb +107 -0
- data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
- data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
- data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
- data/lib/maruku/ext/math/parsing.rb +119 -0
- data/lib/maruku/ext/math/to_html.rb +187 -0
- data/lib/maruku/ext/math/to_latex.rb +26 -0
- data/lib/maruku/helpers.rb +260 -0
- data/lib/maruku/input/charsource.rb +326 -0
- data/lib/maruku/input/extensions.rb +69 -0
- data/lib/maruku/input/html_helper.rb +189 -0
- data/lib/maruku/input/linesource.rb +111 -0
- data/lib/maruku/input/parse_block.rb +616 -0
- data/lib/maruku/input/parse_doc.rb +232 -0
- data/lib/maruku/input/parse_span_better.rb +746 -0
- data/lib/maruku/input/rubypants.rb +225 -0
- data/lib/maruku/input/type_detection.rb +147 -0
- data/lib/maruku/input_textile2/t2_parser.rb +163 -0
- data/lib/maruku/maruku.rb +33 -0
- data/lib/maruku/output/s5/fancy.rb +756 -0
- data/lib/maruku/output/s5/to_s5.rb +138 -0
- data/lib/maruku/output/to_html.rb +991 -0
- data/lib/maruku/output/to_latex.rb +590 -0
- data/lib/maruku/output/to_latex_entities.rb +367 -0
- data/lib/maruku/output/to_latex_strings.rb +64 -0
- data/lib/maruku/output/to_markdown.rb +164 -0
- data/lib/maruku/output/to_s.rb +56 -0
- data/lib/maruku/string_utils.rb +201 -0
- data/lib/maruku/structures.rb +167 -0
- data/lib/maruku/structures_inspect.rb +87 -0
- data/lib/maruku/structures_iterators.rb +61 -0
- data/lib/maruku/textile2.rb +1 -0
- data/lib/maruku/toc.rb +199 -0
- data/lib/maruku/usage/example1.rb +33 -0
- data/lib/maruku/version.rb +39 -0
- metadata +167 -0
@@ -0,0 +1,225 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
|
3
|
+
#
|
4
|
+
# This file is part of Maruku.
|
5
|
+
#
|
6
|
+
# Maruku is free software; you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation; either version 2 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Maruku is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with Maruku; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
#
|
22
|
+
# NOTA BENE:
|
23
|
+
#
|
24
|
+
# The following algorithm is a rip-off of RubyPants written by
|
25
|
+
# Christian Neukirchen.
|
26
|
+
#
|
27
|
+
# RubyPants is a Ruby port of SmartyPants written by John Gruber.
|
28
|
+
#
|
29
|
+
# This file is distributed under the GPL, which I guess is compatible
|
30
|
+
# with the terms of the RubyPants license.
|
31
|
+
#
|
32
|
+
# -- Andrea Censi
|
33
|
+
|
34
|
+
|
35
|
+
# = RubyPants -- SmartyPants ported to Ruby
|
36
|
+
#
|
37
|
+
# Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
|
38
|
+
# Copyright (C) 2004 Christian Neukirchen
|
39
|
+
#
|
40
|
+
# Incooporates ideas, comments and documentation by Chad Miller
|
41
|
+
# Copyright (C) 2004 Chad Miller
|
42
|
+
#
|
43
|
+
# Original SmartyPants by John Gruber
|
44
|
+
# Copyright (C) 2003 John Gruber
|
45
|
+
#
|
46
|
+
|
47
|
+
#
|
48
|
+
# = RubyPants -- SmartyPants ported to Ruby
|
49
|
+
#
|
50
|
+
#
|
51
|
+
# [snip]
|
52
|
+
#
|
53
|
+
# == Authors
|
54
|
+
#
|
55
|
+
# John Gruber did all of the hard work of writing this software in
|
56
|
+
# Perl for Movable Type and almost all of this useful documentation.
|
57
|
+
# Chad Miller ported it to Python to use with Pyblosxom.
|
58
|
+
#
|
59
|
+
# Christian Neukirchen provided the Ruby port, as a general-purpose
|
60
|
+
# library that follows the *Cloth API.
|
61
|
+
#
|
62
|
+
#
|
63
|
+
# == Copyright and License
|
64
|
+
#
|
65
|
+
# === SmartyPants license:
|
66
|
+
#
|
67
|
+
# Copyright (c) 2003 John Gruber
|
68
|
+
# (http://daringfireball.net)
|
69
|
+
# All rights reserved.
|
70
|
+
#
|
71
|
+
# Redistribution and use in source and binary forms, with or without
|
72
|
+
# modification, are permitted provided that the following conditions
|
73
|
+
# are met:
|
74
|
+
#
|
75
|
+
# * Redistributions of source code must retain the above copyright
|
76
|
+
# notice, this list of conditions and the following disclaimer.
|
77
|
+
#
|
78
|
+
# * Redistributions in binary form must reproduce the above copyright
|
79
|
+
# notice, this list of conditions and the following disclaimer in
|
80
|
+
# the documentation and/or other materials provided with the
|
81
|
+
# distribution.
|
82
|
+
#
|
83
|
+
# * Neither the name "SmartyPants" nor the names of its contributors
|
84
|
+
# may be used to endorse or promote products derived from this
|
85
|
+
# software without specific prior written permission.
|
86
|
+
#
|
87
|
+
# This software is provided by the copyright holders and contributors
|
88
|
+
# "as is" and any express or implied warranties, including, but not
|
89
|
+
# limited to, the implied warranties of merchantability and fitness
|
90
|
+
# for a particular purpose are disclaimed. In no event shall the
|
91
|
+
# copyright owner or contributors be liable for any direct, indirect,
|
92
|
+
# incidental, special, exemplary, or consequential damages (including,
|
93
|
+
# but not limited to, procurement of substitute goods or services;
|
94
|
+
# loss of use, data, or profits; or business interruption) however
|
95
|
+
# caused and on any theory of liability, whether in contract, strict
|
96
|
+
# liability, or tort (including negligence or otherwise) arising in
|
97
|
+
# any way out of the use of this software, even if advised of the
|
98
|
+
# possibility of such damage.
|
99
|
+
#
|
100
|
+
# === RubyPants license
|
101
|
+
#
|
102
|
+
# RubyPants is a derivative work of SmartyPants and smartypants.py.
|
103
|
+
#
|
104
|
+
# Redistribution and use in source and binary forms, with or without
|
105
|
+
# modification, are permitted provided that the following conditions
|
106
|
+
# are met:
|
107
|
+
#
|
108
|
+
# * Redistributions of source code must retain the above copyright
|
109
|
+
# notice, this list of conditions and the following disclaimer.
|
110
|
+
#
|
111
|
+
# * Redistributions in binary form must reproduce the above copyright
|
112
|
+
# notice, this list of conditions and the following disclaimer in
|
113
|
+
# the documentation and/or other materials provided with the
|
114
|
+
# distribution.
|
115
|
+
#
|
116
|
+
# This software is provided by the copyright holders and contributors
|
117
|
+
# "as is" and any express or implied warranties, including, but not
|
118
|
+
# limited to, the implied warranties of merchantability and fitness
|
119
|
+
# for a particular purpose are disclaimed. In no event shall the
|
120
|
+
# copyright owner or contributors be liable for any direct, indirect,
|
121
|
+
# incidental, special, exemplary, or consequential damages (including,
|
122
|
+
# but not limited to, procurement of substitute goods or services;
|
123
|
+
# loss of use, data, or profits; or business interruption) however
|
124
|
+
# caused and on any theory of liability, whether in contract, strict
|
125
|
+
# liability, or tort (including negligence or otherwise) arising in
|
126
|
+
# any way out of the use of this software, even if advised of the
|
127
|
+
# possibility of such damage.
|
128
|
+
#
|
129
|
+
#
|
130
|
+
# == Links
|
131
|
+
#
|
132
|
+
# John Gruber:: http://daringfireball.net
|
133
|
+
# SmartyPants:: http://daringfireball.net/projects/smartypants
|
134
|
+
#
|
135
|
+
# Chad Miller:: http://web.chad.org
|
136
|
+
#
|
137
|
+
# Christian Neukirchen:: http://kronavita.de/chris
|
138
|
+
|
139
|
+
|
140
|
+
module MaRuKu; module In; module Markdown; module SpanLevelParser
|
141
|
+
Punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
|
142
|
+
Close_class = %![^\ \t\r\n\\[\{\(\-]!
|
143
|
+
|
144
|
+
Rules = [
|
145
|
+
[/---/, :mdash ],
|
146
|
+
[/--/, :ndash ],
|
147
|
+
['...', :hellip ],
|
148
|
+
['. . .', :hellip ],
|
149
|
+
["``", :ldquo ],
|
150
|
+
["''", :rdquo ],
|
151
|
+
[/<<\s/, [:laquo, :nbsp] ],
|
152
|
+
[/\s>>/, [:nbsp, :raquo] ],
|
153
|
+
[/<</, :laquo ],
|
154
|
+
[/>>/, :raquo ],
|
155
|
+
|
156
|
+
# def educate_single_backticks(str)
|
157
|
+
# ["`", :lsquo]
|
158
|
+
# ["'", :rsquo]
|
159
|
+
|
160
|
+
# Special case if the very first character is a quote followed by
|
161
|
+
# punctuation at a non-word-break. Close the quotes by brute
|
162
|
+
# force:
|
163
|
+
[/^'(?=#{Punct_class}\B)/, :rsquo],
|
164
|
+
[/^"(?=#{Punct_class}\B)/, :rdquo],
|
165
|
+
# Special case for double sets of quotes, e.g.:
|
166
|
+
# <p>He said, "'Quoted' words in a larger quote."</p>
|
167
|
+
[/"'(?=\w)/, [:ldquo, :lsquo] ],
|
168
|
+
[/'"(?=\w)/, [:lsquo, :ldquo] ],
|
169
|
+
# Special case for decade abbreviations (the '80s):
|
170
|
+
[/'(?=\d\ds)/, :rsquo ],
|
171
|
+
# Get most opening single quotes:
|
172
|
+
[/(\s)'(?=\w)/, [:one, :lsquo] ],
|
173
|
+
# Single closing quotes:
|
174
|
+
[/(#{Close_class})'/, [:one, :rsquo]],
|
175
|
+
[/'(\s|s\b|$)/, [:rsquo, :one]],
|
176
|
+
# Any remaining single quotes should be opening ones:
|
177
|
+
[/'/, :lsquo],
|
178
|
+
# Get most opening double quotes:
|
179
|
+
[/(\s)"(?=\w)/, [:one, :ldquo]],
|
180
|
+
# Double closing quotes:
|
181
|
+
[/(#{Close_class})"/, [:one, :rdquo]],
|
182
|
+
[/"(\s|s\b|$)/, [:rdquo, :one]],
|
183
|
+
# Any remaining quotes should be opening ones:
|
184
|
+
[/"/, :ldquo]
|
185
|
+
].
|
186
|
+
map{|reg, subst| # People should do the thinking, machines should do the work.
|
187
|
+
reg = Regexp.new(Regexp.escape(reg)) if not reg.kind_of? Regexp
|
188
|
+
subst = [subst] if not subst.kind_of?Array
|
189
|
+
[reg, subst]}
|
190
|
+
|
191
|
+
# note: input will be destroyed
|
192
|
+
def apply_one_rule(reg, subst, input)
|
193
|
+
output = []
|
194
|
+
while first = input.shift
|
195
|
+
if first.kind_of?(String) && (m = reg.match(first))
|
196
|
+
output.push m. pre_match if m. pre_match.size > 0
|
197
|
+
input.unshift m.post_match if m.post_match.size > 0
|
198
|
+
subst.reverse.each do |x|
|
199
|
+
input.unshift( x == :one ? m[1] : md_entity(x.to_s) ) end
|
200
|
+
else
|
201
|
+
output.push first
|
202
|
+
end
|
203
|
+
end
|
204
|
+
return output
|
205
|
+
end
|
206
|
+
|
207
|
+
def educate(elements)
|
208
|
+
Rules.each do |reg, subst|
|
209
|
+
elements = apply_one_rule(reg, subst, elements)
|
210
|
+
end
|
211
|
+
# strips empty strings
|
212
|
+
elements.delete_if {|x| x.kind_of?(String) && x.size == 0}
|
213
|
+
final = []
|
214
|
+
# join consecutive strings
|
215
|
+
elements.each do |x|
|
216
|
+
if x.kind_of?(String) && final.last.kind_of?(String)
|
217
|
+
final.last << x
|
218
|
+
else
|
219
|
+
final << x
|
220
|
+
end
|
221
|
+
end
|
222
|
+
return final
|
223
|
+
end
|
224
|
+
|
225
|
+
end end end end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
|
3
|
+
#
|
4
|
+
# This file is part of Maruku.
|
5
|
+
#
|
6
|
+
# Maruku is free software; you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation; either version 2 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Maruku is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with Maruku; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
class String
|
22
|
+
include MaRuKu::Strings
|
23
|
+
def md_type()
|
24
|
+
@md_type ||= line_md_type(self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class NilClass
|
29
|
+
def md_type() nil end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# This code does the classification of lines for block-level parsing.
|
34
|
+
module MaRuKu; module Strings
|
35
|
+
|
36
|
+
def line_md_type(l)
|
37
|
+
# The order of evaluation is important (:text is a catch-all)
|
38
|
+
return :text if l =~ /^[a-zA-Z]/
|
39
|
+
return :code if number_of_leading_spaces(l)>=4
|
40
|
+
return :empty if l =~ /^\s*$/
|
41
|
+
return :footnote_text if l =~ FootnoteText
|
42
|
+
return :ref_definition if l =~ LinkRegex or l=~ IncompleteLink
|
43
|
+
return :abbreviation if l =~ Abbreviation
|
44
|
+
return :definition if l =~ Definition
|
45
|
+
# I had a bug with emails and urls at the beginning of the
|
46
|
+
# line that were mistaken for raw_html
|
47
|
+
return :text if l=~ /^[ ]{0,3}#{EMailAddress}/
|
48
|
+
return :text if l=~ /^[ ]{0,3}<http:/
|
49
|
+
# raw html is like PHP Markdown Extra: at most three spaces before
|
50
|
+
return :xml_instr if l =~ %r{^\s*<\?}
|
51
|
+
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+}
|
52
|
+
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?<\!\-\-}
|
53
|
+
# Something is wrong with how we parse lists! :-(
|
54
|
+
#return :ulist if l =~ /^[ ]{0,3}([\*\-\+])\s+.*\w+/
|
55
|
+
#return :olist if l =~ /^[ ]{0,3}\d+\..*\w+/
|
56
|
+
return :ulist if l =~ /^[ ]{0,1}([\*\-\+])\s+.*\w+/
|
57
|
+
return :olist if l =~ /^[ ]{0,1}\d+\..*\w+/
|
58
|
+
return :header1 if l =~ /^(=)+/
|
59
|
+
return :header2 if l =~ /^([-\s])+$/
|
60
|
+
return :header3 if l =~ /^(#)+\s*\S+/
|
61
|
+
# at least three asterisks on a line, and only whitespace
|
62
|
+
return :hrule if l =~ /^(\s*\*\s*){3,1000}$/
|
63
|
+
return :hrule if l =~ /^(\s*-\s*){3,1000}$/ # or hyphens
|
64
|
+
return :hrule if l =~ /^(\s*_\s*){3,1000}$/ # or underscores
|
65
|
+
return :quote if l =~ /^>/
|
66
|
+
return :metadata if l =~ /^@/
|
67
|
+
# if @@new_meta_data?
|
68
|
+
return :ald if l =~ AttributeDefinitionList
|
69
|
+
return :ial if l =~ InlineAttributeList
|
70
|
+
# end
|
71
|
+
# return :equation_end if l =~ EquationEnd
|
72
|
+
return :text # else, it's just text
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# $1 = id $2 = attribute list
|
77
|
+
AttributeDefinitionList = /^\s{0,3}\{([\w\d\s]+)\}:\s*(.*)\s*$/
|
78
|
+
#
|
79
|
+
InlineAttributeList = /^\s{0,3}\{([:#\.].*)\}\s*$/
|
80
|
+
# Example:
|
81
|
+
# ^:blah blah
|
82
|
+
# ^: blah blah
|
83
|
+
# ^ : blah blah
|
84
|
+
Definition = %r{
|
85
|
+
^ # begin of line
|
86
|
+
[ ]{0,3} # up to 3 spaces
|
87
|
+
: # colon
|
88
|
+
\s* # whitespace
|
89
|
+
(\S.*) # the text = $1
|
90
|
+
$ # end of line
|
91
|
+
}x
|
92
|
+
|
93
|
+
# Example:
|
94
|
+
# *[HTML]: Hyper Text Markup Language
|
95
|
+
Abbreviation = %r{
|
96
|
+
^ # begin of line
|
97
|
+
[ ]{0,3} # up to 3 spaces
|
98
|
+
\* # one asterisk
|
99
|
+
\[ # opening bracket
|
100
|
+
([^\]]+) # any non-closing bracket: id = $1
|
101
|
+
\] # closing bracket
|
102
|
+
: # colon
|
103
|
+
\s* # whitespace
|
104
|
+
(\S.*\S)* # definition=$2
|
105
|
+
\s* # strip this whitespace
|
106
|
+
$ # end of line
|
107
|
+
}x
|
108
|
+
|
109
|
+
FootnoteText = %r{
|
110
|
+
^ # begin of line
|
111
|
+
[ ]{0,3} # up to 3 spaces
|
112
|
+
\[(\^.+)\]: # id = $1 (including '^')
|
113
|
+
\s*(\S.*)?$ # text = $2 (not obb.)
|
114
|
+
}x
|
115
|
+
|
116
|
+
# This regex is taken from BlueCloth sources
|
117
|
+
# Link defs are in the form: ^[id]: \n? url "optional title"
|
118
|
+
LinkRegex = %r{
|
119
|
+
^[ ]{0,3}\[([^\[\]]+)\]: # id = $1
|
120
|
+
[ ]*
|
121
|
+
<?([^>\s]+)>? # url = $2
|
122
|
+
[ ]*
|
123
|
+
(?:# Titles are delimited by "quotes" or (parens).
|
124
|
+
["(']
|
125
|
+
(.+?) # title = $3
|
126
|
+
[")'] # Matching ) or "
|
127
|
+
\s*(.+)? # stuff = $4
|
128
|
+
)? # title is optional
|
129
|
+
}x
|
130
|
+
|
131
|
+
IncompleteLink = %r{^[ ]{0,3}\[([^\[\]]+)\]:\s*$}
|
132
|
+
|
133
|
+
HeaderWithId = /^(.*)\{\#([\w_-]+)\}\s*$/
|
134
|
+
|
135
|
+
HeaderWithAttributes = /^(.*)\{(.*)\}\s*$/
|
136
|
+
|
137
|
+
|
138
|
+
# if contains a pipe, it could be a table header
|
139
|
+
MightBeTableHeader = %r{\|}
|
140
|
+
# -------------:
|
141
|
+
Sep = /\s*(\:)?\s*-+\s*(\:)?\s*/
|
142
|
+
# | -------------:| ------------------------------ |
|
143
|
+
TableSeparator = %r{^(\|?#{Sep}\|?)+\s*$}
|
144
|
+
|
145
|
+
|
146
|
+
EMailAddress = /<([^:]+@[^:]+)>/
|
147
|
+
end end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
class String
|
2
|
+
Textile2_EmptyLine = /^\s*$/
|
3
|
+
Textile2_Signature = /^(\S+\.?)\.\s(.*)/
|
4
|
+
|
5
|
+
def t2_empty?
|
6
|
+
self =~ Textile2_EmptyLine
|
7
|
+
end
|
8
|
+
|
9
|
+
def t2_contains_signature?
|
10
|
+
self =~ Textile2_Signature
|
11
|
+
end
|
12
|
+
|
13
|
+
# sig, rest = t2_get_signature
|
14
|
+
def t2_get_signature
|
15
|
+
self =~ Textile2_Signature
|
16
|
+
return Textile2Signature.new($1), $2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Textile2Signature
|
21
|
+
Reg = %r{
|
22
|
+
^
|
23
|
+
# block name is 1
|
24
|
+
([A-Za-z0-9]+)?
|
25
|
+
# style is 2
|
26
|
+
(
|
27
|
+
\{ # open bracket
|
28
|
+
([^\}]+) # style spec is 3
|
29
|
+
\} # close bracket
|
30
|
+
)?
|
31
|
+
# language is 4
|
32
|
+
(\[(\w+)\])? # value is 5
|
33
|
+
# class and id
|
34
|
+
(?:
|
35
|
+
\( # open par
|
36
|
+
(\w+)? # optional class specification is 6
|
37
|
+
(?:\#(\w+))? # optional id is 7
|
38
|
+
\) # close par
|
39
|
+
)?
|
40
|
+
# alignment is 8
|
41
|
+
(\<|\>|\<\>|\=)?
|
42
|
+
# padding
|
43
|
+
(\(+)? # left is 9
|
44
|
+
(\)+)? # right is 10
|
45
|
+
# filters is 11
|
46
|
+
(\|
|
47
|
+
(?:(?:\w+)\|)+
|
48
|
+
)?
|
49
|
+
# optional final dot is 12
|
50
|
+
(\.)?
|
51
|
+
$
|
52
|
+
}x
|
53
|
+
|
54
|
+
|
55
|
+
def initialize(s)
|
56
|
+
if m = Reg.match(s)
|
57
|
+
self.block_name = m[1]
|
58
|
+
self.style = m[3]
|
59
|
+
self.lang = m[4]
|
60
|
+
self.css_class = m[6]
|
61
|
+
self.css_id = m[7]
|
62
|
+
self.text_align = {nil=>nil,'>'=>'right','<'=>'left',
|
63
|
+
'<>'=>'center','='=>'justified'}[m[8]]
|
64
|
+
self.num_left_pad = m[9] && m[9].size
|
65
|
+
self.num_right_pad = m[10] && m[10].size
|
66
|
+
self.filters = m[11] && m[11].split('|')
|
67
|
+
self.double_dot = m[12] && true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
attr_accessor :block_name # or nil
|
73
|
+
attr_accessor :style # or nil
|
74
|
+
attr_accessor :lang # or nil
|
75
|
+
attr_accessor :css_class # or nil
|
76
|
+
attr_accessor :css_id # or nil
|
77
|
+
attr_accessor :text_align # {nil, 'left', 'right', 'center', 'justified'}
|
78
|
+
attr_accessor :num_left_pad # nil or 1..
|
79
|
+
attr_accessor :num_right_pad # nil or 1..
|
80
|
+
attr_accessor :filters # nil [], array of strings
|
81
|
+
attr_accessor :double_dot # nil or true
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
module MaRuKu
|
87
|
+
|
88
|
+
def self.textile2(source, params)
|
89
|
+
m = Maruku.new
|
90
|
+
m.t2_parse(source, params)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
class MDDocument
|
95
|
+
def t2_parse(source, params)
|
96
|
+
src = LineSource.new(source)
|
97
|
+
output = BlockContext.new
|
98
|
+
t2_parse_blocks(src, output)
|
99
|
+
self.children = output.elements
|
100
|
+
end
|
101
|
+
|
102
|
+
Handling = Struct.new(:method, :parse_lines)
|
103
|
+
T2_Handling = {
|
104
|
+
nil => Handling.new(:t2_block_paragraph, true),
|
105
|
+
'p' => Handling.new(:t2_block_paragraph, true)
|
106
|
+
}
|
107
|
+
|
108
|
+
# Input is a LineSource
|
109
|
+
def t2_parse_blocks(src, output)
|
110
|
+
while src.cur_line
|
111
|
+
l = src.shift_line
|
112
|
+
|
113
|
+
# ignore empty line
|
114
|
+
if l.t2_empty? then
|
115
|
+
src.shift_line
|
116
|
+
next
|
117
|
+
end
|
118
|
+
|
119
|
+
# TODO: lists
|
120
|
+
# TODO: xml
|
121
|
+
# TODO: `==`
|
122
|
+
|
123
|
+
signature, l =
|
124
|
+
if l.t2_contains_signature?
|
125
|
+
l.t2_get_signature
|
126
|
+
else
|
127
|
+
[Textile2Signature.new, l]
|
128
|
+
end
|
129
|
+
|
130
|
+
if handling = T2_Handling.has_key?(signature.block_name)
|
131
|
+
if self.responds_to? handling.method
|
132
|
+
# read as many non-empty lines that you can
|
133
|
+
lines = [l]
|
134
|
+
if handling.parse_lines
|
135
|
+
while not src.cur_line.t2_empty?
|
136
|
+
lines.push src.shift_line
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
self.send(handling.method, src, output, signature, lines)
|
141
|
+
else
|
142
|
+
maruku_error("We don't know about method #{handling.method.inspect}")
|
143
|
+
next
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def t2_block_paragraph(src, output, signature, lines)
|
152
|
+
paragraph = lines.join("\n")
|
153
|
+
src2 = CharSource.new(paragraph, src)
|
154
|
+
# output =
|
155
|
+
end
|
156
|
+
|
157
|
+
def t2_parse_span(src, output)
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end # MDDocument
|
162
|
+
|
163
|
+
end
|