maruku 0.2 → 0.2.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/bin/marutex +0 -1
- data/docs/Makefile +2 -2
- data/docs/index.html +7 -5
- data/docs/markdown_syntax.log +21 -21
- data/docs/markdown_syntax.pdf +0 -0
- data/docs/markdown_syntax.tex +110 -111
- data/docs/maruku.html +7 -5
- data/docs/maruku.log +30 -54
- data/docs/maruku.md +27 -13
- data/docs/maruku.pdf +0 -0
- data/docs/maruku.tex +75 -60
- data/docs/todo.md +1 -10
- data/lib/maruku/parse_span.rb +109 -38
- data/lib/maruku/to_latex.rb +23 -12
- data/tests/links.md +7 -0
- data/tests/sss06.md +10 -10
- metadata +1 -1
data/docs/todo.md
CHANGED
data/lib/maruku/parse_span.rb
CHANGED
@@ -16,18 +16,25 @@ class Maruku
|
|
16
16
|
span = MDElement.new
|
17
17
|
span.children = res
|
18
18
|
|
19
|
-
#
|
19
|
+
# encode all escapes
|
20
20
|
span.replace_each_string { |s| s.escape_md_special }
|
21
21
|
|
22
|
+
|
23
|
+
# The order of processing is significant:
|
24
|
+
# 1. inline code
|
25
|
+
# 2. immediate links
|
26
|
+
# 3. inline HTML
|
27
|
+
# 4. everything else
|
28
|
+
|
22
29
|
# search for ``code`` markers
|
23
|
-
span.match_couple_of('``') { |children|
|
30
|
+
span.match_couple_of('``') { |children, match1, match2|
|
24
31
|
e = create_md_element(:inline_code)
|
25
32
|
e.meta[:raw_code] = children.join('') # this is now opaque to processing
|
26
33
|
e
|
27
34
|
}
|
28
35
|
|
29
36
|
# Search for `single tick` code markers
|
30
|
-
span.match_couple_of('`') { |children|
|
37
|
+
span.match_couple_of('`') { |children, match1, match2|
|
31
38
|
e = create_md_element(:inline_code)
|
32
39
|
e.meta[:raw_code] = children.join('').unescape_md_special
|
33
40
|
# this is now opaque to processing
|
@@ -122,32 +129,76 @@ class Maruku
|
|
122
129
|
e
|
123
130
|
}
|
124
131
|
|
132
|
+
# an id reference: "[id]", "[ id ]"
|
133
|
+
reg_id_ref = %r{
|
134
|
+
\[ # opening bracket
|
135
|
+
([^\]]*) # 0 or more non-closing bracket (this is too permissive)
|
136
|
+
\] # closing bracket
|
137
|
+
}x
|
138
|
+
|
125
139
|
# Detect any link like [Google engine][google]
|
126
|
-
span.
|
127
|
-
|
128
|
-
|
140
|
+
span.match_couple_of('[', # opening bracket
|
141
|
+
%r{\] # closing bracket
|
142
|
+
[ ]? # optional whitespace
|
143
|
+
#{reg_id_ref} # ref id, with $1 being the reference
|
144
|
+
}x
|
145
|
+
) { |children, match1, match2|
|
146
|
+
id = match2[1]
|
129
147
|
id = id.strip.downcase
|
130
148
|
|
131
149
|
if id.size == 0
|
132
|
-
id =
|
150
|
+
id = children.join.strip.downcase
|
133
151
|
end
|
134
152
|
|
135
|
-
e = create_md_element(:link,
|
153
|
+
e = create_md_element(:link, children)
|
136
154
|
e.meta[:ref_id] = id
|
137
155
|
e
|
138
156
|
}
|
139
157
|
|
158
|
+
# validates a url, only $1 is set to the url
|
159
|
+
reg_url =
|
160
|
+
/((?:\w+):\/\/(?:\w+:{0,1}\w*@)?(?:\S+)(?::[0-9]+)?(?:\/|\/([\w#!:.?+=&%@!\-\/]))?)/
|
161
|
+
reg_url = %r{([^\s\]\)]+)}
|
162
|
+
|
163
|
+
# short_url = /(#?[\w]+)/
|
164
|
+
# reg_url = Regexp::union(long_url, short_url)
|
165
|
+
|
166
|
+
# A string enclosed in quotes.
|
167
|
+
reg_title = %r{
|
168
|
+
" # opening
|
169
|
+
[^"]* # anything = 1
|
170
|
+
" # closing
|
171
|
+
}x
|
172
|
+
|
173
|
+
# (http://www.google.com "Google.com"), (http://www.google.com),
|
174
|
+
reg_url_and_title = %r{
|
175
|
+
\( # opening
|
176
|
+
\s* # whitespace
|
177
|
+
#{reg_url} # url = 1
|
178
|
+
(?:\s+["'](.*)["'])? # optional title = 2
|
179
|
+
\s* # whitespace
|
180
|
+
\) # closing
|
181
|
+
}x
|
182
|
+
|
140
183
|
# Detect any link with immediate url: [Google](http://www.google.com)
|
141
184
|
# a dummy ref is created and put in the symbol table
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
185
|
+
|
186
|
+
span.match_couple_of('[', # opening bracket
|
187
|
+
%r{\] # closing bracket
|
188
|
+
[ ]? # optional whitespace
|
189
|
+
#{reg_url_and_title} # ref id, with $1 being the url and $2 being the title
|
190
|
+
}x
|
191
|
+
) { |children, match1, match2|
|
192
|
+
|
193
|
+
url = match2[1]
|
194
|
+
title = match2[3] # XXX? Is it a bug? I would use [2]
|
195
|
+
|
146
196
|
# create a dummy id
|
147
197
|
id="dummy_#{@refs.size}"
|
148
198
|
@refs[id] = {:url=>url}
|
149
|
-
|
150
|
-
|
199
|
+
@refs[id][:title] = title if title
|
200
|
+
|
201
|
+
e = create_md_element(:link, children)
|
151
202
|
e.meta[:ref_id] = id
|
152
203
|
e
|
153
204
|
}
|
@@ -164,16 +215,16 @@ class Maruku
|
|
164
215
|
# And now the easy stuff
|
165
216
|
|
166
217
|
# search for **strong**
|
167
|
-
span.match_couple_of('**') { |children| create_md_element(:strong, children) }
|
218
|
+
span.match_couple_of('**') { |children,m1,m2| create_md_element(:strong, children) }
|
168
219
|
|
169
220
|
# search for __strong__
|
170
|
-
span.match_couple_of('__') { |children| create_md_element(:strong, children) }
|
221
|
+
span.match_couple_of('__') { |children,m1,m2| create_md_element(:strong, children) }
|
171
222
|
|
172
223
|
# search for *emphasis*
|
173
|
-
span.match_couple_of('*') { |children| create_md_element(:emphasis, children) }
|
224
|
+
span.match_couple_of('*') { |children,m1,m2| create_md_element(:emphasis, children) }
|
174
225
|
|
175
226
|
# search for _emphasis_
|
176
|
-
span.match_couple_of('_') { |children| create_md_element(:emphasis, children) }
|
227
|
+
span.match_couple_of('_') { |children,m1,m2| create_md_element(:emphasis, children) }
|
177
228
|
|
178
229
|
# finally, unescape the special characters
|
179
230
|
span.replace_each_string { |s| s.unescape_md_special}
|
@@ -264,11 +315,20 @@ class MDElement
|
|
264
315
|
end
|
265
316
|
|
266
317
|
# Finds couple of delimiters in a hierarchy of Strings and MDElements
|
267
|
-
|
268
|
-
|
318
|
+
#
|
319
|
+
# Open and close are two delimiters (like '[' and ']'), or two Regexp.
|
320
|
+
#
|
321
|
+
# If you don't pass close, it defaults to open.
|
322
|
+
#
|
323
|
+
# Each block is called with |contained children, match1, match2|
|
324
|
+
def match_couple_of(open, close=nil, &block)
|
325
|
+
close = close || open
|
326
|
+
open_regexp = open.kind_of?(Regexp) ? open : Regexp.new(Regexp.escape(open))
|
327
|
+
close_regexp = close.kind_of?(Regexp) ? close : Regexp.new(Regexp.escape(close))
|
269
328
|
|
329
|
+
# Do the same to children first
|
270
330
|
for c in @children; if c.kind_of? MDElement
|
271
|
-
c.match_couple_of(
|
331
|
+
c.match_couple_of(open_regexp, close_regexp, &block)
|
272
332
|
end end
|
273
333
|
|
274
334
|
processed_children = []
|
@@ -276,37 +336,37 @@ class MDElement
|
|
276
336
|
until @children.empty?
|
277
337
|
c = @children.shift
|
278
338
|
if c.kind_of? String
|
279
|
-
|
280
|
-
if not
|
339
|
+
match1 = open_regexp.match(c)
|
340
|
+
if not match1
|
281
341
|
processed_children << c
|
282
342
|
else # we found opening, now search closing
|
283
343
|
# puts "Found opening (#{marker}) in #{c.inspect}"
|
284
344
|
# pre match is processed
|
285
|
-
processed_children.push
|
286
|
-
|
345
|
+
processed_children.push match1.pre_match if
|
346
|
+
match1.pre_match && match1.pre_match.size > 0
|
287
347
|
# we will process again the post_match
|
288
|
-
@children.unshift
|
289
|
-
|
290
|
-
|
348
|
+
@children.unshift match1.post_match if
|
349
|
+
match1.post_match && match1.post_match.size>0
|
350
|
+
|
291
351
|
contained = []; found_closing = false
|
292
352
|
until @children.empty? || found_closing
|
293
353
|
c = @children.shift
|
294
354
|
if c.kind_of? String
|
295
|
-
|
296
|
-
if not
|
355
|
+
match2 = close_regexp.match(c)
|
356
|
+
if not match2
|
297
357
|
contained << c
|
298
358
|
else
|
299
359
|
# we found closing
|
300
360
|
found_closing = true
|
301
361
|
# pre match is contained
|
302
|
-
contained.push
|
303
|
-
|
362
|
+
contained.push match2.pre_match if
|
363
|
+
match2.pre_match && match2.pre_match.size>0
|
304
364
|
# we will process again the post_match
|
305
|
-
@children.unshift
|
306
|
-
|
365
|
+
@children.unshift match2.post_match if
|
366
|
+
match2.post_match && match2.post_match.size>0
|
307
367
|
|
308
368
|
# And now we call the block
|
309
|
-
substitute = block.call(contained)
|
369
|
+
substitute = block.call(contained, match1, match2)
|
310
370
|
processed_children << substitute
|
311
371
|
|
312
372
|
# puts "Found closing (#{marker}) in #{c.inspect}"
|
@@ -319,8 +379,8 @@ class MDElement
|
|
319
379
|
end
|
320
380
|
|
321
381
|
if not found_closing
|
322
|
-
$stderr.puts "##### Could not find closing for #{
|
323
|
-
processed_children <<
|
382
|
+
# $stderr.puts "##### Could not find closing for #{open}, #{close} -- ignoring"
|
383
|
+
processed_children << match1.to_s
|
324
384
|
contained.reverse.each do |c|
|
325
385
|
@children.unshift c
|
326
386
|
end
|
@@ -331,6 +391,17 @@ class MDElement
|
|
331
391
|
end
|
332
392
|
end
|
333
393
|
|
334
|
-
@children
|
394
|
+
raise "BugBug" unless @children.empty?
|
395
|
+
|
396
|
+
rebuilt = []
|
397
|
+
# rebuild strings
|
398
|
+
processed_children.each do |c|
|
399
|
+
if c.kind_of?(String) && rebuilt.last && rebuilt.last.kind_of?(String)
|
400
|
+
rebuilt.last << c
|
401
|
+
else
|
402
|
+
rebuilt << c
|
403
|
+
end
|
404
|
+
end
|
405
|
+
@children = rebuilt
|
335
406
|
end
|
336
407
|
end
|
data/lib/maruku/to_latex.rb
CHANGED
@@ -78,7 +78,22 @@ class MDElement
|
|
78
78
|
else
|
79
79
|
color
|
80
80
|
end
|
81
|
-
|
81
|
+
end
|
82
|
+
|
83
|
+
# \color[named]{name}
|
84
|
+
# \color[rgb]{1,0.2,0.3}
|
85
|
+
def latex_color(s, command='color')
|
86
|
+
if s =~ /^\#(\w\w)(\w\w)(\w\w)$/
|
87
|
+
r = $1.hex; g = $2.hex; b=$3.hex
|
88
|
+
# convert from 0-255 to 0.0-1.0
|
89
|
+
r = r / 255.0
|
90
|
+
g = g / 255.0
|
91
|
+
b = b / 255.0
|
92
|
+
|
93
|
+
"\\#{command}[rgb]{#{r},#{g},#{b}}"
|
94
|
+
else
|
95
|
+
"\\#{command}{#{s}}"
|
96
|
+
end
|
82
97
|
end
|
83
98
|
|
84
99
|
def to_latex_code;
|
@@ -95,13 +110,10 @@ class MDElement
|
|
95
110
|
s+= "\\lstset{showspaces=false,showtabs=false}\n"
|
96
111
|
end
|
97
112
|
|
98
|
-
color = get_setting(:code_background_color,DEFAULT_CODE_COLOR)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
s+= "\\lstset{backgroundcolor=\\color{#{colorname}}}\n"
|
103
|
-
end
|
104
|
-
|
113
|
+
color = latex_color get_setting(:code_background_color,DEFAULT_CODE_COLOR)
|
114
|
+
|
115
|
+
s+= "\\lstset{backgroundcolor=#{color}}\n"
|
116
|
+
|
105
117
|
s+= "\\lstset{basicstyle=\\ttfamily\\footnotesize}\n"
|
106
118
|
|
107
119
|
|
@@ -175,10 +187,9 @@ class MDElement
|
|
175
187
|
# Convert to printable latex chars (is much better than using \verb)
|
176
188
|
s=latex_escape(source)
|
177
189
|
|
178
|
-
color = get_setting(:code_background_color,DEFAULT_CODE_COLOR)
|
179
|
-
|
180
|
-
|
181
|
-
"\\colorbox{#{colorname}}{\\tt #{s}}"
|
190
|
+
color = latex_color(get_setting(:code_background_color,DEFAULT_CODE_COLOR),'colorbox')
|
191
|
+
|
192
|
+
"#{color}{\\tt #{s}}"
|
182
193
|
end
|
183
194
|
|
184
195
|
def to_latex_immediate_link
|
data/tests/links.md
CHANGED
@@ -11,6 +11,13 @@ Search on [Google images][]
|
|
11
11
|
|
12
12
|
Search on [Google images][ GoOgle search ]
|
13
13
|
|
14
|
+
Inline: [Google images](http://google.com)
|
15
|
+
|
16
|
+
Inline with title: [Google images](http://google.com "Title")
|
17
|
+
|
18
|
+
Inline with title: [Google images]( http://google.com "Title" )
|
19
|
+
|
20
|
+
|
14
21
|
Search on <http://www.gogole.com> or <http://Here.com> or ask <mailto:bill@google.com>
|
15
22
|
or you might ask bill@google.com.
|
16
23
|
|
data/tests/sss06.md
CHANGED
@@ -339,14 +339,14 @@ And here's the research version:
|
|
339
339
|
References
|
340
340
|
----------
|
341
341
|
|
342
|
-
[1]
|
343
|
-
[2]
|
344
|
-
[3] [http://www.oxfordstory.co.uk](http://www.oxfordstory.co.uk)
|
345
|
-
[4]
|
346
|
-
[5] E. Meijer, M. Fokkinga, R. Paterson. "Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire" (1991)
|
342
|
+
\[1\] [http://www.spellingsociety.org/news/media/poems.php](http://www.spellingsociety.org/news/media/poems.php)
|
343
|
+
\[2\] dde [http://www.flickr.com/photos/censi/236722418/](http://www.flickr.com/photos/censi/236722418/)
|
344
|
+
\[3\] [http://www.oxfordstory.co.uk](http://www.oxfordstory.co.uk)
|
345
|
+
\[4\] [http://www.botanical.com/botanical/mgmh/p/parsni12.html](http://www.botanical.com/botanical/mgmh/p/parsni12.html )
|
346
|
+
\[5\] E. Meijer, M. Fokkinga, R. Paterson. "Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire" (1991)
|
347
347
|
[http://citeseer.ist.psu.edu/meijer91functional.html](http://citeseer.ist.psu.edu/meijer91functional.html)
|
348
|
-
[6] R. Lammel, J. Visser, J. Kort. "Dealing with large bananas" (2000) <http://citeseer.ist.psu.edu/lammel00dealing.html>
|
349
|
-
[7] [http://www.informatik.uni-freiburg.de/~burgard/](http://citeseer.ist.psu.edu/lammel00dealing.html)
|
350
|
-
[8] [http://asl.epfl.ch/~scaramuz/cabaret/cabaret.wmv](http://asl.epfl.ch/~scaramuz/cabaret/cabaret.wmv)
|
351
|
-
[9] [http://www.anth.uconn.edu/faculty/boster/cultvar/euweb/](http://www.anth.uconn.edu/faculty/boster/cultvar/euweb/)
|
352
|
-
[10] [http://www.infonegocio.com/xeron/bruno/italy.html](http://www.infonegocio.com/xeron/bruno/italy.html)
|
348
|
+
\[6\] R. Lammel, J. Visser, J. Kort. "Dealing with large bananas" (2000) <http://citeseer.ist.psu.edu/lammel00dealing.html>
|
349
|
+
\[7\] [http://www.informatik.uni-freiburg.de/~burgard/](http://citeseer.ist.psu.edu/lammel00dealing.html)
|
350
|
+
\[8\] [http://asl.epfl.ch/~scaramuz/cabaret/cabaret.wmv](http://asl.epfl.ch/~scaramuz/cabaret/cabaret.wmv)
|
351
|
+
\[9\] [http://www.anth.uconn.edu/faculty/boster/cultvar/euweb/](http://www.anth.uconn.edu/faculty/boster/cultvar/euweb/)
|
352
|
+
\[10\] [http://www.infonegocio.com/xeron/bruno/italy.html](http://www.infonegocio.com/xeron/bruno/italy.html)
|