maruku 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/maruku +2 -2
- data/docs/changelog.html +37 -51
- data/docs/changelog.md +40 -46
- data/docs/div_syntax.md +36 -0
- data/docs/other_stuff.md +51 -0
- data/lib/maruku/helpers.rb +1 -2
- data/lib/maruku/input/html_helper.rb +22 -8
- data/lib/maruku/input/parse_block.rb +9 -2
- data/lib/maruku/input/parse_span_better.rb +31 -13
- data/lib/maruku/input/type_detection.rb +6 -3
- data/lib/maruku/output/s5/to_s5.rb +50 -41
- data/lib/maruku/output/to_html.rb +4 -4
- data/lib/maruku/string_utils.rb +1 -1
- data/lib/maruku/version.rb +1 -1
- data/tests/s5/a.md +13 -0
- data/tests/s5/instiki+s5.md +105 -0
- data/tests/unittest/alt.md +39 -0
- data/tests/unittest/email.md +2 -2
- data/tests/unittest/hex_entities.md +57 -0
- data/tests/unittest/html2.md +49 -0
- data/tests/unittest/html3.md +61 -0
- data/tests/unittest/html4.md +47 -0
- data/tests/unittest/html5.md +45 -0
- data/tests/unittest/images.md +5 -5
- data/tests/unittest/images2.md +2 -2
- data/tests/unittest/links.md +1 -1
- data/tests/unittest/lists8.md +109 -0
- data/tests/unittest/lists9.md +105 -0
- data/tests/unittest/lists_after_paragraph.md +5 -6
- data/tests/unittest/loss.md +32 -0
- metadata +15 -2
@@ -152,8 +152,13 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
152
152
|
con.push_char src.shift_char
|
153
153
|
end
|
154
154
|
when ?&
|
155
|
+
# named references
|
155
156
|
if m = src.read_regexp(/\&([\w\d]+);/)
|
156
157
|
con.push_element md_entity(m[1])
|
158
|
+
# numeric
|
159
|
+
elsif m = src.read_regexp(/\&\#(x)?([\w\d]+);/)
|
160
|
+
num = m[1] ? m[2].hex : m[2].to_i
|
161
|
+
con.push_element md_entity(num)
|
157
162
|
else
|
158
163
|
con.push_char src.shift_char
|
159
164
|
end
|
@@ -446,22 +451,35 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
446
451
|
h = HTMLHelper.new
|
447
452
|
begin
|
448
453
|
# This is our current buffer in the context
|
449
|
-
|
454
|
+
next_stuff = src.current_remaining_buffer
|
450
455
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
456
|
+
consumed = 0
|
457
|
+
while true
|
458
|
+
h.eat_this next_stuff[consumed].chr; consumed += 1
|
459
|
+
break if h.is_finished?
|
460
|
+
|
461
|
+
if consumed >= next_stuff.size
|
462
|
+
maruku_error "Malformed HTML starting at #{next_stuff.inspect}", src, con
|
463
|
+
end
|
455
464
|
end
|
465
|
+
src.ignore_chars(consumed)
|
466
|
+
con.push_element md_html(h.stuff_you_read)
|
456
467
|
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
468
|
+
#start = src.current_remaining_buffer
|
469
|
+
# h.eat_this start
|
470
|
+
# if not h.is_finished?
|
471
|
+
# error "inline_html: Malformed:\n "+
|
472
|
+
# "#{start.inspect}\n #{h.inspect}",src,con
|
473
|
+
# end
|
474
|
+
#
|
475
|
+
# consumed = start.size - h.rest.size
|
476
|
+
# if consumed > 0
|
477
|
+
# con.push_element md_html(h.stuff_you_read)
|
478
|
+
# src.ignore_chars(consumed)
|
479
|
+
# else
|
480
|
+
# puts "HTML helper did not work on #{start.inspect}"
|
481
|
+
# con.push_char src.shift_char
|
482
|
+
# end
|
465
483
|
rescue Exception => e
|
466
484
|
maruku_error "Bad html: \n" +
|
467
485
|
add_tabs(e.inspect+e.backtrace.join("\n"),1,'>'),
|
@@ -50,8 +50,11 @@ module MaRuKu; module Strings
|
|
50
50
|
return :xml_instr if l =~ %r{^\s*<\?}
|
51
51
|
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+}
|
52
52
|
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?<\!\-\-}
|
53
|
-
|
54
|
-
return :
|
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+/
|
55
58
|
return :header1 if l =~ /^(=)+/
|
56
59
|
return :header2 if l =~ /^([-\s])+$/
|
57
60
|
return :header3 if l =~ /^(#)+\s*\S+/
|
@@ -138,4 +141,4 @@ module MaRuKu; module Strings
|
|
138
141
|
|
139
142
|
|
140
143
|
EMailAddress = /<([^:]+@[^:]+)>/
|
141
|
-
end end
|
144
|
+
end end
|
@@ -5,46 +5,56 @@ module MaRuKu
|
|
5
5
|
|
6
6
|
# Render as an HTML fragment (no head, just the content of BODY). (returns a string)
|
7
7
|
def to_s5(context={})
|
8
|
-
indent
|
9
|
-
ie_hack
|
8
|
+
indent = context[:indent] || -1
|
9
|
+
ie_hack = !context[:ie_hack].kind_of?(FalseClass)
|
10
|
+
content_only = !context[:content_only].kind_of?(FalseClass)
|
10
11
|
|
11
12
|
doc = Document.new(nil,{:respect_whitespace =>:all})
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
|
14
|
+
if content_only
|
15
|
+
body = Element.new('div', doc)
|
16
|
+
else
|
17
|
+
html = Element.new('html', doc)
|
18
|
+
html.add_namespace('http://www.w3.org/1999/xhtml')
|
19
|
+
html.add_namespace('svg', "http://www.w3.org/2000/svg" )
|
20
|
+
|
21
|
+
head = Element.new('head', html)
|
17
22
|
me = Element.new 'meta', head
|
18
23
|
me.attributes['http-equiv'] = 'Content-type'
|
19
24
|
me.attributes['content'] = 'text/html;charset=utf-8'
|
20
25
|
|
21
|
-
|
22
26
|
# Create title element
|
23
27
|
doc_title = self.attributes[:title] || self.attributes[:subject] || ""
|
24
28
|
title = Element.new 'title', head
|
25
|
-
title << Text.new(doc_title)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
title << Text.new(doc_title)
|
30
|
+
body = Element.new('body', html)
|
31
|
+
|
32
|
+
end
|
29
33
|
|
30
34
|
slide_header = self.attributes[:slide_header]
|
31
35
|
slide_footer = self.attributes[:slide_footer]
|
36
|
+
slide_subfooter = self.attributes[:slide_subfooter]
|
32
37
|
slide_topleft = self.attributes[:slide_topleft]
|
33
38
|
slide_topright = self.attributes[:slide_topright]
|
34
39
|
slide_bottomleft = self.attributes[:slide_bottomleft]
|
35
40
|
slide_bottomright = self.attributes[:slide_bottomright]
|
36
41
|
|
37
42
|
dummy_layout_slide =
|
38
|
-
"
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
</div>
|
43
|
+
"
|
44
|
+
<div class='layout'>
|
45
|
+
<div id='controls'></div>
|
46
|
+
<div id='currentSlide'> </div>
|
47
|
+
<div id='header'> #{slide_header}</div>
|
48
|
+
<div id='footer'>
|
49
|
+
<h1>#{slide_footer}</h1>
|
50
|
+
<h2>#{slide_subfooter}</h2>
|
51
|
+
</div>
|
52
|
+
<div class='topleft'> #{slide_topleft}</div>
|
53
|
+
<div class='topright'> #{slide_topright}</div>
|
54
|
+
<div class='bottomleft'> #{slide_bottomleft}</div>
|
55
|
+
<div class='bottomright'> #{slide_bottomright}</div>
|
56
|
+
</div>
|
57
|
+
"
|
48
58
|
body.add_element Document.new(dummy_layout_slide, {:respect_whitespace =>:all}).root
|
49
59
|
|
50
60
|
presentation = Element.new 'div', body
|
@@ -52,10 +62,10 @@ module MaRuKu
|
|
52
62
|
|
53
63
|
first_slide="
|
54
64
|
<div class='slide'>
|
55
|
-
<h1> #{self.attributes[:title]}</h1>
|
56
|
-
<h2> #{self.attributes[:subtitle]}</h2>
|
57
|
-
<h3> #{self.attributes[:author]}</h3>
|
58
|
-
<h4> #{self.attributes[:company]}</h4>
|
65
|
+
<h1> #{self.attributes[:title] ||context[:title]}</h1>
|
66
|
+
<h2> #{self.attributes[:subtitle] ||context[:subtitle]}</h2>
|
67
|
+
<h3> #{self.attributes[:author] ||context[:author]}</h3>
|
68
|
+
<h4> #{self.attributes[:company] ||context[:company]}</h4>
|
59
69
|
</div>
|
60
70
|
"
|
61
71
|
presentation.add_element Document.new(first_slide).root
|
@@ -71,7 +81,6 @@ module MaRuKu
|
|
71
81
|
|
72
82
|
h1 = Element.new 'h1', div
|
73
83
|
slide.header_element.children_to_html.each do |e| h1 << e; end
|
74
|
-
|
75
84
|
|
76
85
|
array_to_html(slide.immediate_children).each do |e| div << e end
|
77
86
|
|
@@ -82,23 +91,23 @@ module MaRuKu
|
|
82
91
|
end
|
83
92
|
end
|
84
93
|
|
85
|
-
|
86
|
-
doc2 = Document.new("<div>"+S5_external+"</div>",{:respect_whitespace =>:all})
|
87
|
-
doc2.root.children.each{ |child| head << child }
|
88
|
-
|
89
|
-
|
90
|
-
add_css_to(head)
|
91
|
-
|
92
94
|
xml = ""
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
95
|
+
if (content_only)
|
96
|
+
body.write(xml,indent,transitive=true,ie_hack);
|
97
|
+
else
|
98
|
+
doc2 = Document.new("<div>"+S5_external+"</div>",{:respect_whitespace =>:all})
|
99
|
+
doc2.root.children.each{ |child| head << child }
|
100
|
+
|
101
|
+
add_css_to(head)
|
102
|
+
|
103
|
+
# REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
|
104
|
+
# containing code.
|
105
|
+
html.write(xml,indent,transitive=true,ie_hack);
|
106
|
+
Xhtml11_mathml2_svg11 + xml
|
107
|
+
end
|
99
108
|
end
|
100
109
|
|
101
110
|
end
|
102
111
|
|
103
112
|
|
104
|
-
end
|
113
|
+
end
|
@@ -79,8 +79,8 @@ module MaRuKu; module Out; module HTML
|
|
79
79
|
end
|
80
80
|
|
81
81
|
|
82
|
-
Xhtml10strict =
|
83
|
-
<?xml version='1.0' encoding='utf-8'?>
|
82
|
+
Xhtml10strict =
|
83
|
+
"<?xml version='1.0' encoding='utf-8'?>
|
84
84
|
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
|
85
85
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"
|
86
86
|
|
@@ -717,7 +717,7 @@ of the form `#ff00ff`.
|
|
717
717
|
url = ref[:url]
|
718
718
|
title = ref[:title]
|
719
719
|
a.attributes['src'] = url.to_s
|
720
|
-
a.attributes['alt'] =
|
720
|
+
a.attributes['alt'] = children_to_s
|
721
721
|
else
|
722
722
|
maruku_error"Could not find id = #{id.inspect} for\n #{self.inspect}"
|
723
723
|
tell_user "Could not create image with ref_id = #{id.inspect};"+
|
@@ -737,7 +737,7 @@ of the form `#ff00ff`.
|
|
737
737
|
title = self.title
|
738
738
|
a = create_html_element 'img'
|
739
739
|
a.attributes['src'] = url.to_s
|
740
|
-
a.attributes['alt'] =
|
740
|
+
a.attributes['alt'] = children_to_s
|
741
741
|
return a
|
742
742
|
end
|
743
743
|
|
data/lib/maruku/string_utils.rb
CHANGED
data/lib/maruku/version.rb
CHANGED
data/tests/s5/a.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
author: Jacques Distler
|
2
|
+
company: University of Texas at Austin
|
3
|
+
title: S5 Integration
|
4
|
+
subtitle: slides in Instiki
|
5
|
+
slide_footer: Released to the Internets
|
6
|
+
slide_subfooter: March 1, 2007
|
7
|
+
|
8
|
+
:category: S5-slideshow
|
9
|
+
|
10
|
+
S5 Integration
|
11
|
+
==============
|
12
|
+
|
13
|
+
S5
|
14
|
+
--------------------------------------
|
15
|
+
|
16
|
+
1. [S5](http://meyerweb.com/eric/tools/s5/) is an open-source presentation package, written by Eric Meyer.
|
17
|
+
2. Andrea Censi included some basic S5 support in [Maruku](http://maruku.rubyforge.org/), his Ruby Markdown implementation.
|
18
|
+
2. My role was to
|
19
|
+
* make it compatible[^xhtml] with real XHTML
|
20
|
+
* integrate it into Instiki
|
21
|
+
3. Driven by Maruku and itex2MML, it's trivial to include equations, inline SVG graphics, etc.
|
22
|
+
|
23
|
+
[^xhtml]: This consisted of fixing the Javascript to use DOM-scripting, instead of `innerHTML`.
|
24
|
+
|
25
|
+
Composing a presentation
|
26
|
+
--------------------------------------
|
27
|
+
|
28
|
+
At the top of this presentation, is some header information:
|
29
|
+
|
30
|
+
author: Jacques Distler
|
31
|
+
company: University of Texas at Austin
|
32
|
+
title: S5 Integration
|
33
|
+
subtitle: slides in Instiki
|
34
|
+
slide_footer: Released to the Internets
|
35
|
+
slide_subfooter: March 1, 2007
|
36
|
+
|
37
|
+
:category: S5-slideshow
|
38
|
+
|
39
|
+
The `:category: S5-slideshow` is essential. It tells Instiki that this page is an S5 slideshow. Any page in this category has an extra "S5" view, in addition to the "TeX" and "Print" views. The rest of the header fields are optional. If you omit `author: ...`, then the name of the person who last edited the page is used. If you omit `title: ...`, then the name of the page is used.
|
40
|
+
|
41
|
+
Composing ...
|
42
|
+
-----------------------------------------
|
43
|
+
|
44
|
+
After that header information, is a series of slides
|
45
|
+
|
46
|
+
My Slideshow
|
47
|
+
==============
|
48
|
+
|
49
|
+
First Slide Title
|
50
|
+
-----------------
|
51
|
+
|
52
|
+
* First point
|
53
|
+
* Second point
|
54
|
+
|
55
|
+
Second Slide Title
|
56
|
+
------------------
|
57
|
+
|
58
|
+
* Another boring bullet point.
|
59
|
+
|
60
|
+
etc.
|
61
|
+
|
62
|
+
|
63
|
+
Features
|
64
|
+
--------------------------------------
|
65
|
+
|
66
|
+
* Mathematics, either inline $\left(\frac{\sin(\pi x)}{\pi x}\right)$ or block
|
67
|
+
\[
|
68
|
+
\label{gaussian}
|
69
|
+
\int_{\infty}^{\infty}e^{-x^2} \mathrm{d}x = \sqrt{\pi}
|
70
|
+
\]
|
71
|
+
are fully supported. You just type standard [itex](http://golem.ph.utexas.edu/~distler/blog/itex2MMLcommands.html), and equations like (eq:gaussian) just appear.
|
72
|
+
* Incremental display is supported.
|
73
|
+
* Notes are allowed, but there isn't (yet) a native Maruku syntax for entering them. _Horror of horrors!_ You need to type a little XHTML markup to get them.
|
74
|
+
{: .incremental .show-first}
|
75
|
+
|
76
|
+
<div markdown="1" class="notes">
|
77
|
+
|
78
|
+
You have to type
|
79
|
+
|
80
|
+
<div class="notes">
|
81
|
+
|
82
|
+
These are my notes for this slide.
|
83
|
+
|
84
|
+
</div>
|
85
|
+
|
86
|
+
Usually, these optional notes contain the gory details and complicated equations, like $E=m c^2$, too messy to be presented in the main thread of the talk.
|
87
|
+
|
88
|
+
</div>
|
89
|
+
|
90
|
+
|
91
|
+
Features II
|
92
|
+
---------------------------------------------------
|
93
|
+
|
94
|
+
To get incremental display, use Maruku's [metadata syntax](http://maruku.rubyforge.org/proposal.html)
|
95
|
+
{: .incremental}
|
96
|
+
|
97
|
+
* Place a `{: .incremental .show-first}` or `{: .incremental}` to get incremental display.
|
98
|
+
|
99
|
+
* This even works with nested lists.
|
100
|
+
{: .incremental}
|
101
|
+
|
102
|
+
* Yes, all of S5's [other features](http://meyerweb.com/eric/tools/s5/features.html) are there, too.
|
103
|
+
* Of course, it doesn't have all the garish visual effects of Apple's Keynote.
|
104
|
+
* If you can't do without garish, tacky, visual effects, there's always SVG.
|
105
|
+
{: .incremental}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Write a comment here
|
2
|
+
*** Parameters: ***
|
3
|
+
{} # params
|
4
|
+
*** Markdown input: ***
|
5
|
+
![bar](/foo.jpg)
|
6
|
+
|
7
|
+
|
8
|
+
*** Output of inspect ***
|
9
|
+
md_el(:document,[md_par([md_im_image(["bar"], "/foo.jpg", nil)])],{},[])
|
10
|
+
*** Output of to_html ***
|
11
|
+
|
12
|
+
<p><img src='/foo.jpg' alt='bar' /></p>
|
13
|
+
|
14
|
+
*** Output of to_latex ***
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
*** Output of to_md ***
|
19
|
+
bar
|
20
|
+
|
21
|
+
|
22
|
+
*** Output of to_s ***
|
23
|
+
bar
|
24
|
+
*** EOF ***
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
OK!
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
*** Output of Markdown.pl ***
|
33
|
+
<p><img src="/foo.jpg" alt="bar" title="" /></p>
|
34
|
+
|
35
|
+
*** Output of Markdown.pl (parsed) ***
|
36
|
+
<p
|
37
|
+
><img title='' src='/foo.jpg' alt='bar'/
|
38
|
+
></p
|
39
|
+
>
|
data/tests/unittest/email.md
CHANGED
@@ -33,9 +33,9 @@ This is an email address:
|
|
33
33
|
|
34
34
|
|
35
35
|
*** Output of Markdown.pl ***
|
36
|
-
<p>This is an email address: <a href="m
|
36
|
+
<p>This is an email address: <a href="mailto:andrea@invalid.it">andrea@invalid.it</a></p>
|
37
37
|
|
38
38
|
*** Output of Markdown.pl (parsed) ***
|
39
|
-
<p>This is an email address: <a href='&#x6D
|
39
|
+
<p>This is an email address: <a href='&#x6D;&#x61;&#x69;l&#116;&#111;:&#97;&#x6E;&#x64;&#x72;&#101;&#97;&#64;&#x69;&#110;&#118;&#x61;&#x6C;&#x69;&#x64;&#46;&#x69;&#116;'>andrea@invalid.it</a
|
40
40
|
></p
|
41
41
|
>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Write a comment here
|
2
|
+
*** Parameters: ***
|
3
|
+
{} # params
|
4
|
+
*** Markdown input: ***
|
5
|
+
Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.
|
6
|
+
|
7
|
+
|
8
|
+
*** Output of inspect ***
|
9
|
+
md_el(:document,[
|
10
|
+
md_par([
|
11
|
+
"Examples of numeric character references include ",
|
12
|
+
md_entity(169),
|
13
|
+
" or ",
|
14
|
+
md_entity(169),
|
15
|
+
" for the copyright symbol, ",
|
16
|
+
md_entity(913),
|
17
|
+
" or ",
|
18
|
+
md_entity(913),
|
19
|
+
" for the Greek capital letter alpha, and ",
|
20
|
+
md_entity(1575),
|
21
|
+
" or ",
|
22
|
+
md_entity(1575),
|
23
|
+
" for the Arabic letter alef."
|
24
|
+
])
|
25
|
+
],{},[])
|
26
|
+
*** Output of to_html ***
|
27
|
+
|
28
|
+
<p>Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.</p>
|
29
|
+
|
30
|
+
*** Output of to_latex ***
|
31
|
+
Examples of numeric character references include \copyright{} or \copyright{} for the copyright symbol, $A${} or $A${} for the Greek capital letter alpha, and or for the Arabic letter alef.
|
32
|
+
|
33
|
+
|
34
|
+
*** Output of to_md ***
|
35
|
+
Examples of numeric character
|
36
|
+
references include or for the copyright
|
37
|
+
symbol, or for the Greek capital letter
|
38
|
+
alpha, and or for the Arabic letter
|
39
|
+
alef.
|
40
|
+
|
41
|
+
|
42
|
+
*** Output of to_s ***
|
43
|
+
Examples of numeric character references include or for the copyright symbol, or for the Greek capital letter alpha, and or for the Arabic letter alef.
|
44
|
+
*** EOF ***
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
OK!
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
*** Output of Markdown.pl ***
|
53
|
+
<p>Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.</p>
|
54
|
+
|
55
|
+
*** Output of Markdown.pl (parsed) ***
|
56
|
+
<p>Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.</p
|
57
|
+
>
|