maruku 0.4.0 → 0.4.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/maruku +74 -22
- data/bin/marutest +15 -3
- data/docs/{changelog-0.3.md → changelog.md} +47 -18
- data/docs/entity_test.html +253 -0
- data/docs/entity_test.md +21 -0
- data/docs/index.html +124 -31
- data/docs/markdown_syntax.html +46 -46
- data/docs/maruku.html +124 -31
- data/docs/maruku.md +47 -9
- data/docs/proposal.html +4 -4
- data/lib/maruku.rb +1 -0
- data/lib/maruku/defaults.rb +1 -1
- data/lib/maruku/helpers.rb +4 -4
- data/lib/maruku/input/parse_block.rb +39 -33
- data/lib/maruku/input/parse_doc.rb +57 -3
- data/lib/maruku/input/parse_span_better.rb +28 -8
- data/lib/maruku/input/rubypants.rb +225 -0
- data/lib/maruku/input/type_detection.rb +1 -0
- data/lib/maruku/output/to_html.rb +46 -47
- data/lib/maruku/output/to_latex.rb +166 -45
- data/lib/maruku/output/to_latex_entities.rb +75 -43
- data/lib/maruku/string_utils.rb +21 -19
- data/lib/maruku/structures.rb +21 -12
- data/lib/maruku/structures_inspect.rb +12 -3
- data/lib/maruku/tests/new_parser.rb +2 -1
- data/lib/maruku/version.rb +1 -1
- data/tests/unittest/abbreviations.md +8 -8
- data/tests/unittest/attributes/attributes.md +10 -10
- data/tests/unittest/attributes/circular.md +4 -4
- data/tests/unittest/attributes/default.md +3 -3
- data/tests/unittest/blank.md +2 -2
- data/tests/unittest/blanks_in_code.md +12 -12
- data/tests/unittest/code.md +4 -4
- data/tests/unittest/code2.md +7 -6
- data/tests/unittest/code3.md +16 -16
- data/tests/unittest/easy.md +4 -4
- data/tests/unittest/email.md +4 -4
- data/tests/unittest/encoding/iso-8859-1.md +2 -2
- data/tests/unittest/encoding/utf-8.md +2 -2
- data/tests/unittest/entities.md +20 -20
- data/tests/unittest/escaping.md +16 -16
- data/tests/unittest/extra_dl.md +17 -7
- data/tests/unittest/extra_header_id.md +11 -11
- data/tests/unittest/extra_table1.md +4 -4
- data/tests/unittest/footnotes.md +38 -28
- data/tests/unittest/headers.md +6 -6
- data/tests/unittest/hrule.md +6 -6
- data/tests/unittest/images.md +18 -16
- data/tests/unittest/inline_html.md +7 -29
- data/tests/unittest/inline_html2.md +3 -3
- data/tests/unittest/links.md +7 -27
- data/tests/unittest/list1.md +9 -8
- data/tests/unittest/list2.md +15 -12
- data/tests/unittest/list3.md +16 -14
- data/tests/unittest/list4.md +4 -4
- data/tests/unittest/lists.md +33 -29
- data/tests/unittest/lists_after_paragraph.md +36 -36
- data/tests/unittest/lists_ol.md +43 -38
- data/tests/unittest/misc_sw.md +172 -156
- data/tests/unittest/notyet/escape.md +8 -8
- data/tests/unittest/notyet/header_after_par.md +6 -6
- data/tests/unittest/notyet/ticks.md +4 -4
- data/tests/unittest/notyet/triggering.md +21 -21
- data/tests/unittest/olist.md +5 -5
- data/tests/unittest/one.md +1 -1
- data/tests/unittest/paragraph.md +1 -1
- data/tests/unittest/paragraph_rules/dont_merge_ref.md +1 -1
- data/tests/unittest/paragraph_rules/tab_is_blank.md +2 -2
- data/tests/unittest/paragraphs.md +5 -5
- data/tests/unittest/recover/recover_links.md +2 -2
- data/tests/unittest/references/long_example.md +27 -19
- data/tests/unittest/smartypants.md +148 -0
- data/tests/unittest/syntax_hl.md +14 -14
- data/tests/unittest/test.md +2 -2
- data/tests/unittest/wrapping.md +8 -8
- data/tests/unittest/xml_instruction.md +82 -0
- metadata +149 -160
- data/docs/TOFIX.html +0 -22
- data/docs/TOFIX.md +0 -3
- data/docs/changelog-0.2.13.html +0 -30
- data/docs/changelog-0.2.13.md +0 -6
- data/docs/changelog-0.3.html +0 -113
- data/docs/faq.html +0 -57
- data/docs/faq.md +0 -32
- data/docs/hidden_o_n_squared.md +0 -10
- data/docs/todo.html +0 -40
- data/docs/todo.md +0 -9
@@ -21,6 +21,7 @@
|
|
21
21
|
|
22
22
|
require 'iconv'
|
23
23
|
|
24
|
+
|
24
25
|
module MaRuKu; module In; module Markdown; module BlockLevelParser
|
25
26
|
|
26
27
|
def parse_doc(s)
|
@@ -31,10 +32,20 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser
|
|
31
32
|
|
32
33
|
self.attributes.merge! meta2
|
33
34
|
|
35
|
+
=begin maruku_doc
|
36
|
+
Attribute: encoding
|
37
|
+
Scope: document
|
38
|
+
Summary: Encoding for the document.
|
39
|
+
|
40
|
+
If the `encoding` attribute is specified, then the content
|
41
|
+
will be converted from the specified encoding to UTF-8.
|
42
|
+
|
43
|
+
Conversion happens using the `iconv` library.
|
44
|
+
=end
|
45
|
+
|
34
46
|
enc = self.attributes[:encoding]
|
35
47
|
self.attributes.delete :encoding
|
36
48
|
if enc && enc.downcase != 'utf-8'
|
37
|
-
# puts "Converting from #{enc} to UTF-8."
|
38
49
|
converted = Iconv.new('utf-8', enc).iconv(data)
|
39
50
|
|
40
51
|
# puts "Data: #{data.inspect}: #{data}"
|
@@ -71,8 +82,19 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser
|
|
71
82
|
expand_attribute_list(e.al, e.attributes)
|
72
83
|
# puts "#{e.node_type}: #{e.attributes.inspect}"
|
73
84
|
end
|
74
|
-
|
75
|
-
|
85
|
+
|
86
|
+
=begin maruku_doc
|
87
|
+
Attribute: exec
|
88
|
+
Scope: document
|
89
|
+
Summary: Enables execution of XML instructions.
|
90
|
+
|
91
|
+
Disabled by default because of security concerns.
|
92
|
+
=end
|
93
|
+
|
94
|
+
if Maruku::Globals[:unsafe_features]
|
95
|
+
self.execute_code_blocks
|
96
|
+
# TODO: remove executed code blocks
|
97
|
+
end
|
76
98
|
end
|
77
99
|
|
78
100
|
# Expands an attribute list in an Hash
|
@@ -111,6 +133,38 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser
|
|
111
133
|
end
|
112
134
|
end
|
113
135
|
|
136
|
+
def execute_code_blocks
|
137
|
+
self.each_element(:xml_instr) do |e|
|
138
|
+
if e.target == 'maruku'
|
139
|
+
puts e.attributes.inspect
|
140
|
+
code = e.code
|
141
|
+
result = nil
|
142
|
+
begin
|
143
|
+
e.instance_eval(code)
|
144
|
+
rescue Exception => e
|
145
|
+
maruku_error "Exception while executing this:\n"+
|
146
|
+
add_tabs(code, 1, ">")+
|
147
|
+
"\nThe error was:\n"+
|
148
|
+
add_tabs(e.inspect+"\n"+e.caller.join("\n"), 1, "|")
|
149
|
+
next
|
150
|
+
rescue RuntimeError => e
|
151
|
+
maruku_error "2: Exception while executing this:\n"+
|
152
|
+
add_tabs(code, 1, ">")+
|
153
|
+
"\nThe error was:\n"+
|
154
|
+
add_tabs(e.inspect, 1, "|")
|
155
|
+
rescue SyntaxError => e
|
156
|
+
maruku_error "2: Exception while executing this:\n"+
|
157
|
+
add_tabs(code, 1, ">")+
|
158
|
+
"\nThe error was:\n"+
|
159
|
+
add_tabs(e.inspect, 1, "|")
|
160
|
+
end
|
161
|
+
if result.kind_of?(String)
|
162
|
+
puts "Result is : #{result.inspect}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
114
168
|
def search_abbreviations
|
115
169
|
self.abbreviations.each do |abbrev, title|
|
116
170
|
reg = Regexp.new(Regexp.escape(abbrev))
|
@@ -89,8 +89,13 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
89
89
|
# 3) url "<http:// ", "<ftp:// ..."
|
90
90
|
# 4) email "<andrea@... ", "<mailto:andrea@..."
|
91
91
|
# 5) on itself! "a < b "
|
92
|
+
# 6) Start of <<guillemettes>>
|
92
93
|
|
93
94
|
case d = src.next_char
|
95
|
+
when ?<; # guillemettes
|
96
|
+
src.ignore_chars(2)
|
97
|
+
con.push_char ?<
|
98
|
+
con.push_char ?<
|
94
99
|
when ?!;
|
95
100
|
if src.cur_chars_are '<!--'
|
96
101
|
read_inline_html(src, con)
|
@@ -98,7 +103,7 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
98
103
|
con.push_char src.shift_char
|
99
104
|
end
|
100
105
|
when ??
|
101
|
-
|
106
|
+
read_xml_instr_span(src, con)
|
102
107
|
when ?\ , ?\t
|
103
108
|
con.push_char src.shift_char
|
104
109
|
else
|
@@ -117,7 +122,13 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
117
122
|
end
|
118
123
|
when ?\\
|
119
124
|
d = src.next_char
|
120
|
-
if
|
125
|
+
if d == ?'
|
126
|
+
src.ignore_chars(2)
|
127
|
+
con.push_element md_entity('apos')
|
128
|
+
elsif d == ?"
|
129
|
+
src.ignore_chars(2)
|
130
|
+
con.push_element md_entity('quot')
|
131
|
+
elsif escaped.include? d
|
121
132
|
src.ignore_chars(2)
|
122
133
|
con.push_char d
|
123
134
|
else
|
@@ -236,13 +247,22 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
236
247
|
con.elements.pop if s.size == 0
|
237
248
|
end
|
238
249
|
|
239
|
-
con.elements
|
250
|
+
educated = educate(con.elements)
|
251
|
+
|
252
|
+
educated
|
240
253
|
end
|
241
254
|
|
242
|
-
def
|
243
|
-
|
255
|
+
def read_xml_instr_span(src, con)
|
256
|
+
src.ignore_chars(2) # starting <?
|
257
|
+
|
258
|
+
# read target <?target code... ?>
|
259
|
+
target = if m = src.read_regexp(/(\w+)/)
|
260
|
+
m[1]
|
261
|
+
else
|
262
|
+
''
|
263
|
+
end
|
244
264
|
|
245
|
-
|
265
|
+
delim = "?>"
|
246
266
|
|
247
267
|
code =
|
248
268
|
read_simple(src, escaped=[], break_on_chars=[],
|
@@ -251,7 +271,7 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
251
271
|
src.ignore_chars delim.size
|
252
272
|
|
253
273
|
code = (code || "").strip
|
254
|
-
con.push_element
|
274
|
+
con.push_element md_xml_instr(target, code)
|
255
275
|
end
|
256
276
|
|
257
277
|
def read_url_el(src,con)
|
@@ -340,7 +360,7 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
340
360
|
"#{exit_on_chars.map{|x|""<<x}.inspect})"+
|
341
361
|
" already read: #{text.inspect}"
|
342
362
|
maruku_error s, src
|
343
|
-
maruku_recover "I boldly continue", src
|
363
|
+
maruku_recover "I boldly continue", src
|
344
364
|
break
|
345
365
|
when ?\\
|
346
366
|
d = src.next_char
|
@@ -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
|
@@ -46,6 +46,7 @@ module MaRuKu; module Strings
|
|
46
46
|
# line that were mistaken for raw_html
|
47
47
|
return :text if l=~EMailAddress or l=~ URL
|
48
48
|
# raw html is like PHP Markdown Extra: at most three spaces before
|
49
|
+
return :xml_instr if l =~ %r{^\s*<\?}
|
49
50
|
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+}
|
50
51
|
return :raw_html if l =~ %r{[ ]{0,3}<\!\-\-}
|
51
52
|
return :ulist if l =~ /^\s?([\*\-\+])\s+.*\w+/
|
@@ -40,8 +40,6 @@ class REXML::Element
|
|
40
40
|
public :write_children
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
43
|
# This module groups all functions related to HTML export.
|
46
44
|
module MaRuKu; module Out; module HTML
|
47
45
|
include REXML
|
@@ -64,7 +62,6 @@ module MaRuKu; module Out; module HTML
|
|
64
62
|
|
65
63
|
doc = Document.new(nil,{:respect_whitespace =>:all})
|
66
64
|
doc << div
|
67
|
-
#add_whitespace(doc)
|
68
65
|
|
69
66
|
# REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
|
70
67
|
# containing code.
|
@@ -98,7 +95,7 @@ module MaRuKu; module Out; module HTML
|
|
98
95
|
root = Element.new('html', doc)
|
99
96
|
root.add_namespace('http://www.w3.org/1999/xhtml')
|
100
97
|
|
101
|
-
lang =
|
98
|
+
lang = self.attributes[:lang] || 'en'
|
102
99
|
root.attributes['lang'] = lang
|
103
100
|
root.attributes['xml:lang'] = lang
|
104
101
|
|
@@ -110,15 +107,12 @@ module MaRuKu; module Out; module HTML
|
|
110
107
|
me.attributes['content'] = 'text/html; charset=utf-8'
|
111
108
|
|
112
109
|
# Create title element
|
113
|
-
doc_title =
|
110
|
+
doc_title = self.attributes[:title] || self.attributes[:subject] || ""
|
114
111
|
title = Element.new 'title', head
|
115
112
|
title << Text.new(doc_title)
|
116
113
|
|
117
|
-
# Encoding
|
118
|
-
|
119
|
-
|
120
114
|
|
121
|
-
css =
|
115
|
+
css = self.attributes[:css]
|
122
116
|
if css
|
123
117
|
# <link type="text/css" rel="stylesheet" href="..." />
|
124
118
|
link = Element.new 'link'
|
@@ -145,7 +139,6 @@ module MaRuKu; module Out; module HTML
|
|
145
139
|
|
146
140
|
root << body
|
147
141
|
|
148
|
-
# add_whitespace(doc)
|
149
142
|
doc
|
150
143
|
end
|
151
144
|
|
@@ -195,7 +188,7 @@ module MaRuKu; module Out; module HTML
|
|
195
188
|
span << Text.new('Created by ')
|
196
189
|
a = Element.new('a', span)
|
197
190
|
a.attributes['href'] = 'http://maruku.rubyforge.org'
|
198
|
-
a.attributes['title'] = 'Maruku: a Markdown interpreter'
|
191
|
+
a.attributes['title'] = 'Maruku: a Markdown interpreter for Ruby'
|
199
192
|
a << Text.new('Maruku')
|
200
193
|
span << Text.new(nice_date+".")
|
201
194
|
div
|
@@ -227,7 +220,7 @@ module MaRuKu; module Out; module HTML
|
|
227
220
|
end
|
228
221
|
|
229
222
|
|
230
|
-
def to_html_hrule;
|
223
|
+
def to_html_hrule; create_html_element 'hr' end
|
231
224
|
def to_html_linebreak; Element.new 'br' end
|
232
225
|
|
233
226
|
# renders children as html and wraps into an element of given name
|
@@ -314,7 +307,7 @@ module MaRuKu; module Out; module HTML
|
|
314
307
|
def to_html_code;
|
315
308
|
source = self.raw_code
|
316
309
|
|
317
|
-
lang =
|
310
|
+
lang = self.attributes[:lang] || @doc.attributes[:code_lang]
|
318
311
|
|
319
312
|
lang = 'xml' if lang=='html'
|
320
313
|
use_syntax = get_setting(:html_use_syntax)
|
@@ -329,12 +322,6 @@ module MaRuKu; module Out; module HTML
|
|
329
322
|
|
330
323
|
html = convertor.convert( source )
|
331
324
|
|
332
|
-
show_spaces = get_setting(:code_show_spaces)
|
333
|
-
if show_spaces
|
334
|
-
s.gsub!(/\t/,'»'+' '*3)
|
335
|
-
s.gsub!(/ /,'¬')
|
336
|
-
end
|
337
|
-
|
338
325
|
pre = Document.new(html, {:respect_whitespace =>:all}).root
|
339
326
|
pre.attributes['class'] = lang
|
340
327
|
pre
|
@@ -365,6 +352,8 @@ module MaRuKu; module Out; module HTML
|
|
365
352
|
|
366
353
|
s = s.gsub(/&/,'&')
|
367
354
|
s = Text.normalize(s)
|
355
|
+
s = s.gsub(/\'/,''') # IE bug
|
356
|
+
s = s.gsub(/'/,''') # IE bug
|
368
357
|
|
369
358
|
show_spaces = get_setting(:code_show_spaces)
|
370
359
|
if show_spaces
|
@@ -372,7 +361,7 @@ module MaRuKu; module Out; module HTML
|
|
372
361
|
s.gsub!(/ /,'¬')
|
373
362
|
end
|
374
363
|
|
375
|
-
text = Text.new(s, true, nil,
|
364
|
+
text = Text.new(s, respect_ws=true, parent=nil, raw=true )
|
376
365
|
|
377
366
|
code << text
|
378
367
|
pre
|
@@ -411,8 +400,8 @@ module MaRuKu; module Out; module HTML
|
|
411
400
|
if ref = @doc.refs[id]
|
412
401
|
url = ref[:url]
|
413
402
|
title = ref[:title]
|
414
|
-
a.attributes['href']=url if url
|
415
|
-
a.attributes['title']=title if title
|
403
|
+
a.attributes['href'] = url if url
|
404
|
+
a.attributes['title'] = title if title
|
416
405
|
else
|
417
406
|
maruku_error"Could not find ref_id = #{id.inspect} for #{self.inspect}"
|
418
407
|
tell_user "Not creating a link for ref_id = #{id.inspect}."
|
@@ -422,18 +411,17 @@ module MaRuKu; module Out; module HTML
|
|
422
411
|
end
|
423
412
|
|
424
413
|
def to_html_im_link
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
if url
|
414
|
+
if url = self.url
|
415
|
+
title = self.title
|
416
|
+
a = wrap_as_element 'a'
|
429
417
|
a.attributes['href'] = url
|
430
418
|
a.attributes['title'] = title if title
|
419
|
+
return a
|
431
420
|
else
|
432
421
|
maruku_error"Could not find url in #{self.inspect}"
|
433
422
|
tell_user "Not creating a link for ref_id = #{id.inspect}."
|
434
423
|
return wrap_as_element('span')
|
435
424
|
end
|
436
|
-
return a
|
437
425
|
end
|
438
426
|
|
439
427
|
def add_ws(e)
|
@@ -471,9 +459,7 @@ module MaRuKu; module Out; module HTML
|
|
471
459
|
url = ref[:url]
|
472
460
|
a.attributes['src'] = url
|
473
461
|
[:title, :class, :style].each do |s|
|
474
|
-
if ref[s]
|
475
|
-
a.attributes[s.to_s] = ref[s]
|
476
|
-
end
|
462
|
+
a.attributes[s.to_s] = ref[s] if ref[s]
|
477
463
|
end
|
478
464
|
else
|
479
465
|
maruku_error"Could not find id = #{id.inspect} for\n #{self.inspect}"
|
@@ -485,17 +471,16 @@ module MaRuKu; module Out; module HTML
|
|
485
471
|
end
|
486
472
|
|
487
473
|
def to_html_im_image
|
488
|
-
|
489
|
-
url = self.url
|
490
|
-
title = self.title
|
491
|
-
if not url
|
474
|
+
if not url = self.url
|
492
475
|
maruku_error"Image with no url: #{self.inspect}"
|
493
476
|
tell_user "Could not create image with ref_id = #{id.inspect};"+
|
494
477
|
+" Using SPAN element as replacement."
|
495
478
|
return wrap_as_element('span')
|
496
479
|
end
|
497
|
-
|
498
|
-
a.
|
480
|
+
title = self.title
|
481
|
+
a = Element.new 'img'
|
482
|
+
a.attributes['src'] = url
|
483
|
+
a.attributes['title'] = title if title
|
499
484
|
return a
|
500
485
|
end
|
501
486
|
|
@@ -555,17 +540,14 @@ module MaRuKu; module Out; module HTML
|
|
555
540
|
|
556
541
|
sup
|
557
542
|
end
|
543
|
+
|
558
544
|
## Definition lists ###
|
559
|
-
def to_html_definition_list
|
560
|
-
|
561
|
-
end
|
562
|
-
def
|
563
|
-
children_to_html
|
564
|
-
end
|
565
|
-
def to_html_definition_term; wrap_as_element('dt') end
|
566
|
-
def to_html_definition_data; wrap_as_element('dd') end
|
545
|
+
def to_html_definition_list() add_ws wrap_as_element('dl') end
|
546
|
+
def to_html_definition() children_to_html end
|
547
|
+
def to_html_definition_term() add_ws wrap_as_element('dt') end
|
548
|
+
def to_html_definition_data() add_ws wrap_as_element('dd') end
|
567
549
|
|
568
|
-
|
550
|
+
# FIXME: Ugly code
|
569
551
|
def to_html_table
|
570
552
|
align = self.align
|
571
553
|
num_columns = align.size
|
@@ -575,7 +557,7 @@ module MaRuKu; module Out; module HTML
|
|
575
557
|
i = num_columns
|
576
558
|
while i<@children.size
|
577
559
|
rows << @children.slice(i, num_columns)
|
578
|
-
i+=num_columns
|
560
|
+
i += num_columns
|
579
561
|
end
|
580
562
|
|
581
563
|
table = create_html_element 'table'
|
@@ -604,7 +586,24 @@ module MaRuKu; module Out; module HTML
|
|
604
586
|
|
605
587
|
def to_html_entity
|
606
588
|
entity_name = self.entity_name
|
607
|
-
|
589
|
+
|
590
|
+
# Fix for Internet Explorer
|
591
|
+
if entity_name == 'apos'
|
592
|
+
entity_name = 39
|
593
|
+
end
|
594
|
+
|
595
|
+
if entity_name.kind_of? Fixnum
|
596
|
+
# Entity.new(entity_name)
|
597
|
+
Text.new('&#%d;' % [entity_name], false, nil, true)
|
598
|
+
else
|
599
|
+
Text.new('&%s;' % [entity_name])
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
def to_html_xml_instr
|
604
|
+
target = self.target || ''
|
605
|
+
code = self.code || ''
|
606
|
+
REXML::Instruction.new(target, code)
|
608
607
|
end
|
609
608
|
|
610
609
|
# Convert each child to html
|