patcito-maruku 0.6.0
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/AUTHORS +23 -0
- data/LICENSE +340 -0
- data/README.md +73 -0
- data/bin/maruku +196 -0
- data/bin/marutex +4 -0
- data/data/entities.xml +261 -0
- data/docs/changelog.md +334 -0
- data/docs/div_syntax.md +36 -0
- data/docs/entity_test.md +23 -0
- data/docs/markdown_syntax.md +899 -0
- data/docs/maruku.md +346 -0
- data/docs/math.md +194 -0
- data/docs/other_stuff.md +51 -0
- data/docs/proposal.md +309 -0
- data/docs/website/src/bluecloth.md +25 -0
- data/docs/website/src/download.md +31 -0
- data/docs/website/src/maruku.md +261 -0
- data/docs/website/src/proposal.md +271 -0
- data/lib/maruku.rb +132 -0
- data/lib/maruku/attributes.rb +138 -0
- data/lib/maruku/defaults.rb +69 -0
- data/lib/maruku/errors.rb +89 -0
- data/lib/maruku/ext/div.rb +121 -0
- data/lib/maruku/ext/fenced_code.rb +78 -0
- data/lib/maruku/ext/math.rb +37 -0
- data/lib/maruku/ext/math/elements.rb +21 -0
- data/lib/maruku/ext/math/latex_fix.rb +12 -0
- data/lib/maruku/ext/math/mathml_engines/blahtex.rb +93 -0
- data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +39 -0
- data/lib/maruku/ext/math/mathml_engines/none.rb +21 -0
- data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
- data/lib/maruku/ext/math/parsing.rb +125 -0
- data/lib/maruku/ext/math/to_html.rb +237 -0
- data/lib/maruku/ext/math/to_latex.rb +36 -0
- data/lib/maruku/ext/yaml.rb +43 -0
- data/lib/maruku/helpers.rb +214 -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 +608 -0
- data/lib/maruku/input/parse_doc.rb +240 -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 +31 -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 +994 -0
- data/lib/maruku/output/to_latex.rb +580 -0
- data/lib/maruku/output/to_latex_entities.rb +101 -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 +54 -0
- data/lib/maruku/string_utils.rb +185 -0
- data/lib/maruku/structures.rb +143 -0
- data/lib/maruku/structures_inspect.rb +51 -0
- data/lib/maruku/structures_iterators.rb +48 -0
- data/lib/maruku/textile2.rb +1 -0
- data/lib/maruku/toc.rb +214 -0
- data/lib/maruku/usage/example1.rb +33 -0
- data/lib/maruku/version +0 -0
- data/lib/maruku/version.rb +54 -0
- data/spec/block_docs/abbreviations.md +52 -0
- data/spec/block_docs/alt.md +17 -0
- data/spec/block_docs/attributes/att2.md +20 -0
- data/spec/block_docs/attributes/att3.md +28 -0
- data/spec/block_docs/attributes/attributes.md +57 -0
- data/spec/block_docs/attributes/circular.md +26 -0
- data/spec/block_docs/attributes/default.md +22 -0
- data/spec/block_docs/blank.md +24 -0
- data/spec/block_docs/blanks_in_code.md +75 -0
- data/spec/block_docs/bug_def.md +16 -0
- data/spec/block_docs/bug_table.md +46 -0
- data/spec/block_docs/code.md +34 -0
- data/spec/block_docs/code2.md +28 -0
- data/spec/block_docs/code3.md +71 -0
- data/spec/block_docs/data_loss.md +25 -0
- data/spec/block_docs/divs/div1.md +167 -0
- data/spec/block_docs/divs/div2.md +21 -0
- data/spec/block_docs/divs/div3_nest.md +45 -0
- data/spec/block_docs/easy.md +15 -0
- data/spec/block_docs/email.md +20 -0
- data/spec/block_docs/encoding/iso-8859-1.md +23 -0
- data/spec/block_docs/encoding/utf-8.md +18 -0
- data/spec/block_docs/entities.md +94 -0
- data/spec/block_docs/escaping.md +67 -0
- data/spec/block_docs/extra_dl.md +52 -0
- data/spec/block_docs/extra_header_id.md +63 -0
- data/spec/block_docs/extra_table1.md +37 -0
- data/spec/block_docs/footnotes.md +97 -0
- data/spec/block_docs/headers.md +37 -0
- data/spec/block_docs/hex_entities.md +37 -0
- data/spec/block_docs/hrule.md +39 -0
- data/spec/block_docs/html2.md +22 -0
- data/spec/block_docs/html3.md +31 -0
- data/spec/block_docs/html4.md +25 -0
- data/spec/block_docs/html5.md +23 -0
- data/spec/block_docs/ie.md +49 -0
- data/spec/block_docs/images.md +90 -0
- data/spec/block_docs/images2.md +31 -0
- data/spec/block_docs/inline_html.md +152 -0
- data/spec/block_docs/inline_html2.md +21 -0
- data/spec/block_docs/links.md +152 -0
- data/spec/block_docs/links2.md +22 -0
- data/spec/block_docs/list1.md +46 -0
- data/spec/block_docs/list12.md +28 -0
- data/spec/block_docs/list2.md +56 -0
- data/spec/block_docs/list3.md +64 -0
- data/spec/block_docs/list4.md +89 -0
- data/spec/block_docs/lists.md +192 -0
- data/spec/block_docs/lists10.md +34 -0
- data/spec/block_docs/lists11.md +23 -0
- data/spec/block_docs/lists6.md +41 -0
- data/spec/block_docs/lists9.md +64 -0
- data/spec/block_docs/lists_after_paragraph.md +208 -0
- data/spec/block_docs/lists_ol.md +262 -0
- data/spec/block_docs/loss.md +16 -0
- data/spec/block_docs/math/equations.md +45 -0
- data/spec/block_docs/math/inline.md +46 -0
- data/spec/block_docs/math/math2.md +45 -0
- data/spec/block_docs/math/notmath.md +25 -0
- data/spec/block_docs/math/table.md +25 -0
- data/spec/block_docs/math/table2.md +42 -0
- data/spec/block_docs/misc_sw.md +525 -0
- data/spec/block_docs/notyet/escape.md +21 -0
- data/spec/block_docs/notyet/header_after_par.md +58 -0
- data/spec/block_docs/notyet/ticks.md +18 -0
- data/spec/block_docs/notyet/triggering.md +157 -0
- data/spec/block_docs/olist.md +45 -0
- data/spec/block_docs/one.md +15 -0
- data/spec/block_docs/paragraph.md +16 -0
- data/spec/block_docs/paragraph_rules/dont_merge_ref.md +42 -0
- data/spec/block_docs/paragraph_rules/tab_is_blank.md +24 -0
- data/spec/block_docs/paragraphs.md +46 -0
- data/spec/block_docs/pending/amps.md +15 -0
- data/spec/block_docs/pending/empty_cells.md +37 -0
- data/spec/block_docs/pending/link.md +72 -0
- data/spec/block_docs/pending/ref.md +21 -0
- data/spec/block_docs/recover/recover_links.md +15 -0
- data/spec/block_docs/red_tests/abbrev.md +679 -0
- data/spec/block_docs/red_tests/lists7.md +32 -0
- data/spec/block_docs/red_tests/lists7b.md +65 -0
- data/spec/block_docs/red_tests/lists8.md +42 -0
- data/spec/block_docs/red_tests/ref.md +23 -0
- data/spec/block_docs/red_tests/xml.md +35 -0
- data/spec/block_docs/references/long_example.md +71 -0
- data/spec/block_docs/references/spaces_and_numbers.md +15 -0
- data/spec/block_docs/smartypants.md +114 -0
- data/spec/block_docs/syntax_hl.md +52 -0
- data/spec/block_docs/table_attributes.md +34 -0
- data/spec/block_docs/test.md +19 -0
- data/spec/block_docs/underscore_in_words.md +15 -0
- data/spec/block_docs/wrapping.md +67 -0
- data/spec/block_docs/xml2.md +19 -0
- data/spec/block_docs/xml3.md +26 -0
- data/spec/block_docs/xml_instruction.md +52 -0
- data/spec/block_spec.rb +49 -0
- data/spec/span_spec.rb +254 -0
- data/spec/spec_helper.rb +6 -0
- metadata +247 -0
@@ -0,0 +1,101 @@
|
|
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
|
+
require 'rexml/document'
|
23
|
+
|
24
|
+
module MaRuKu; module Out; module Latex
|
25
|
+
|
26
|
+
include REXML
|
27
|
+
|
28
|
+
def to_latex_entity
|
29
|
+
MaRuKu::Out::Latex.need_entity_table
|
30
|
+
|
31
|
+
entity_name = self.entity_name
|
32
|
+
|
33
|
+
entity = ENTITY_TABLE[entity_name]
|
34
|
+
if not entity
|
35
|
+
maruku_error "I don't know how to translate entity '#{entity_name}' "+
|
36
|
+
"to LaTeX."
|
37
|
+
return ""
|
38
|
+
end
|
39
|
+
replace = entity.latex_string
|
40
|
+
|
41
|
+
entity.latex_packages.each do |p|
|
42
|
+
@doc.latex_require_package p
|
43
|
+
end
|
44
|
+
|
45
|
+
# if replace =~ /^\\/
|
46
|
+
# replace = replace + " "
|
47
|
+
# end
|
48
|
+
|
49
|
+
if replace
|
50
|
+
return replace + "{}"
|
51
|
+
else
|
52
|
+
tell_user "Cannot translate entity #{entity_name.inspect} to LaTeX."
|
53
|
+
return entity_name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class LatexEntity
|
58
|
+
attr_accessor :html_num
|
59
|
+
attr_accessor :html_entity
|
60
|
+
attr_accessor :latex_string
|
61
|
+
attr_accessor :latex_packages
|
62
|
+
end
|
63
|
+
|
64
|
+
def Latex.need_entity_table
|
65
|
+
Latex.init_entity_table if ENTITY_TABLE.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
# create hash @@entity_to_latex
|
69
|
+
def Latex.init_entity_table
|
70
|
+
# $stderr.write "Creating entity table.."
|
71
|
+
# $stderr.flush
|
72
|
+
doc = Document.new(File.read(File.dirname(__FILE__) + "/../../../data/entities.xml"))
|
73
|
+
doc.elements.each("//char") do |c|
|
74
|
+
num = c.attributes['num'].to_i
|
75
|
+
name = c.attributes['name']
|
76
|
+
package = c.attributes['package']
|
77
|
+
|
78
|
+
convert = c.attributes['convertTo']
|
79
|
+
convert.gsub!(/@DOUBLEQUOT/,'"')
|
80
|
+
convert.gsub!(/@QUOT/,"'")
|
81
|
+
convert.gsub!(/@GT/,">")
|
82
|
+
convert.gsub!(/@LT/,"<")
|
83
|
+
convert.gsub!(/@AMP/,"&")
|
84
|
+
convert.freeze
|
85
|
+
|
86
|
+
e = LatexEntity.new
|
87
|
+
e.html_num = num
|
88
|
+
e.html_entity = name
|
89
|
+
e.latex_string = convert
|
90
|
+
e.latex_packages = package ? package.split : []
|
91
|
+
|
92
|
+
ENTITY_TABLE[num] = e
|
93
|
+
ENTITY_TABLE[name] = e
|
94
|
+
end
|
95
|
+
# $stderr.puts "..done."
|
96
|
+
end
|
97
|
+
|
98
|
+
ENTITY_TABLE = {}
|
99
|
+
|
100
|
+
end end end
|
101
|
+
|
@@ -0,0 +1,64 @@
|
|
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
|
+
|
23
|
+
class String
|
24
|
+
|
25
|
+
# These are TeX's special characters
|
26
|
+
LATEX_ADD_SLASH = [ '{', '}', '$', '&', '#', '_', '%']
|
27
|
+
|
28
|
+
# These, we transform to {\tt \char<ascii code>}
|
29
|
+
LATEX_TO_CHARCODE = [ '^', '~', '>', '<']
|
30
|
+
|
31
|
+
def escape_to_latex(s)
|
32
|
+
s2 = ""
|
33
|
+
s.each_char do |b|
|
34
|
+
if LATEX_TO_CHARCODE.include? b
|
35
|
+
s2 += "{\\tt \\symbol{#{b.ord}}}"
|
36
|
+
elsif LATEX_ADD_SLASH.include? b
|
37
|
+
s2 << ?\\ << b
|
38
|
+
elsif b == '\\'
|
39
|
+
# there is no backslash in cmr10 fonts
|
40
|
+
s2 += "$\\backslash$"
|
41
|
+
else
|
42
|
+
s2 << b
|
43
|
+
end
|
44
|
+
end
|
45
|
+
s2
|
46
|
+
end
|
47
|
+
|
48
|
+
# escapes special characters
|
49
|
+
def to_latex
|
50
|
+
s = escape_to_latex(self)
|
51
|
+
OtherGoodies.each do |k, v|
|
52
|
+
s.gsub!(k, v)
|
53
|
+
end
|
54
|
+
s
|
55
|
+
end
|
56
|
+
|
57
|
+
# other things that are good on the eyes
|
58
|
+
OtherGoodies = {
|
59
|
+
/(\s)LaTeX/ => '\1\\LaTeX\\xspace ', # XXX not if already \LaTeX
|
60
|
+
# 'HTML' => '\\textsc{html}\\xspace ',
|
61
|
+
# 'PDF' => '\\textsc{pdf}\\xspace '
|
62
|
+
}
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,164 @@
|
|
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
|
+
class String
|
23
|
+
# XXX: markdown escaping
|
24
|
+
def to_md(c=nil)
|
25
|
+
to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
# " andrea censi " => [" andrea ", "censi "]
|
29
|
+
def mysplit
|
30
|
+
split.map{|x| x+" "}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
module MaRuKu; module Out; module Markdown
|
36
|
+
|
37
|
+
DefaultLineLength = 40
|
38
|
+
|
39
|
+
def to_md(context={})
|
40
|
+
children_to_md(context)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_md_paragraph(context)
|
44
|
+
line_length = context[:line_length] || DefaultLineLength
|
45
|
+
wrap(@children, line_length, context)+"\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_md_li_span(context)
|
49
|
+
len = (context[:line_length] || DefaultLineLength) - 2
|
50
|
+
s = wrap(@children, len-2, context).rstrip.gsub(/^/, ' ')
|
51
|
+
s[0] = ?*
|
52
|
+
s + "\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_md_abbr_def(context)
|
56
|
+
"*[#{self.abbr}]: #{self.text}\n"
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_md_ol(context)
|
60
|
+
len = (context[:line_length] || DefaultLineLength) - 2
|
61
|
+
md = ""
|
62
|
+
self.children.each_with_index do |li, i|
|
63
|
+
s = (w=wrap(li.children, len-2, context)).rstrip.gsub(/^/, ' ')+"\n"
|
64
|
+
s[0,4] = "#{i+1}. "[0,4]
|
65
|
+
# puts w.inspect
|
66
|
+
md += s
|
67
|
+
end
|
68
|
+
md + "\n"
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_md_ul(context)
|
72
|
+
len = (context[:line_length] || DefaultLineLength) - 2
|
73
|
+
md = ""
|
74
|
+
self.children.each_with_index do |li, i|
|
75
|
+
w = wrap(li.children, len-2, context)
|
76
|
+
# puts "W: "+ w.inspect
|
77
|
+
s = add_indent(w)
|
78
|
+
# puts "S: " +s.inspect
|
79
|
+
s[0,1] = "-"
|
80
|
+
md += s
|
81
|
+
end
|
82
|
+
md + "\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_indent(s,char=" ")
|
86
|
+
t = s.split("\n").map{|x| char+x }.join("\n")
|
87
|
+
s << ?\n if t[-1] == ?\n
|
88
|
+
s
|
89
|
+
end
|
90
|
+
|
91
|
+
# Convert each child to html
|
92
|
+
def children_to_md(context)
|
93
|
+
array_to_md(@children, context)
|
94
|
+
end
|
95
|
+
|
96
|
+
def wrap(array, line_length, context)
|
97
|
+
out = ""
|
98
|
+
line = ""
|
99
|
+
array.each do |c|
|
100
|
+
if c.kind_of?(MDElement) && c.node_type == :linebreak
|
101
|
+
out << line.strip << " \n"; line="";
|
102
|
+
next
|
103
|
+
end
|
104
|
+
|
105
|
+
pieces =
|
106
|
+
if c.kind_of? String
|
107
|
+
c.to_md.mysplit
|
108
|
+
else
|
109
|
+
[c.to_md(context)].flatten
|
110
|
+
end
|
111
|
+
|
112
|
+
# puts "Pieces: #{pieces.inspect}"
|
113
|
+
pieces.each do |p|
|
114
|
+
if p.size + line.size > line_length
|
115
|
+
out << line.strip << "\n";
|
116
|
+
line = ""
|
117
|
+
end
|
118
|
+
line << p
|
119
|
+
end
|
120
|
+
end
|
121
|
+
out << line.strip << "\n" if line.size > 0
|
122
|
+
out << ?\n if not out[-1] == ?\n
|
123
|
+
out
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def array_to_md(array, context, join_char='')
|
128
|
+
e = []
|
129
|
+
array.each do |c|
|
130
|
+
method = c.kind_of?(MDElement) ?
|
131
|
+
"to_md_#{c.node_type}" : "to_md"
|
132
|
+
|
133
|
+
if not c.respond_to?(method)
|
134
|
+
#raise "Object does not answer to #{method}: #{c.class} #{c.inspect[0,100]}"
|
135
|
+
# tell_user "Using default for #{c.node_type}"
|
136
|
+
method = 'to_md'
|
137
|
+
end
|
138
|
+
|
139
|
+
# puts "#{c.inspect} created with method #{method}"
|
140
|
+
h = c.send(method, context)
|
141
|
+
|
142
|
+
if h.nil?
|
143
|
+
raise "Nil md for #{c.inspect} created with method #{method}"
|
144
|
+
end
|
145
|
+
|
146
|
+
if h.kind_of?Array
|
147
|
+
e = e + h
|
148
|
+
else
|
149
|
+
e << h
|
150
|
+
end
|
151
|
+
end
|
152
|
+
e.join(join_char)
|
153
|
+
end
|
154
|
+
|
155
|
+
end end end
|
156
|
+
|
157
|
+
module MaRuKu; class MDDocument
|
158
|
+
alias old_md to_md
|
159
|
+
def to_md(context={})
|
160
|
+
s = old_md(context)
|
161
|
+
# puts s
|
162
|
+
s
|
163
|
+
end
|
164
|
+
end end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
module MaRuKu
|
23
|
+
|
24
|
+
class MDElement
|
25
|
+
|
26
|
+
# Strips all formatting from the string
|
27
|
+
def to_s
|
28
|
+
children_to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def children_to_s
|
32
|
+
@children.join
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate an id for headers. Assumes @children is set.
|
36
|
+
def generate_id
|
37
|
+
title = children_to_s
|
38
|
+
title.gsub!(/ /,'_')
|
39
|
+
title.downcase!
|
40
|
+
title.gsub!(/[^\w_]/,'')
|
41
|
+
title.strip!
|
42
|
+
|
43
|
+
if title.size == 0
|
44
|
+
$uid ||= 0
|
45
|
+
$uid += 1
|
46
|
+
title = "id#{$uid}"
|
47
|
+
end
|
48
|
+
|
49
|
+
@doc.id_counter += 1
|
50
|
+
title << "_" + @doc.id_counter.to_s
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,185 @@
|
|
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
|
+
require 'strscan'
|
22
|
+
|
23
|
+
module MaRuKu
|
24
|
+
# Utility functions for dealing with strings.
|
25
|
+
module Strings
|
26
|
+
TAB_SIZE = 4
|
27
|
+
|
28
|
+
# Split a string into multiple lines,
|
29
|
+
# on line feeds and/or carriage returns.
|
30
|
+
#
|
31
|
+
# @param s [String]
|
32
|
+
# @return [String]
|
33
|
+
def split_lines(s)
|
34
|
+
s.split(/\r\n|\r|\n/)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parses email headers, returning a hash.
|
38
|
+
# `hash[:data]` is the message;
|
39
|
+
# that is, anything past the headers.
|
40
|
+
#
|
41
|
+
# Keys are downcased and converted to symbols;
|
42
|
+
# spaces become underscores. For example:
|
43
|
+
#
|
44
|
+
# !!!plain
|
45
|
+
# My key: true
|
46
|
+
#
|
47
|
+
# becomes:
|
48
|
+
#
|
49
|
+
# {:my_key => true}
|
50
|
+
#
|
51
|
+
# @param s [String] The email
|
52
|
+
# @return [Symbol => String] The header values
|
53
|
+
def parse_email_headers(s)
|
54
|
+
headers = {}
|
55
|
+
scanner = StringScanner.new(s)
|
56
|
+
|
57
|
+
while scanner.scan(/(\w[\w\s\-]+): +(.*)\n/)
|
58
|
+
k, v = normalize_key_and_value(scanner[1], scanner[2])
|
59
|
+
headers[k.to_sym] = v
|
60
|
+
end
|
61
|
+
|
62
|
+
headers[:data] = scanner.rest
|
63
|
+
headers
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the number of leading spaces,
|
67
|
+
# considering that a tab counts as {TAB_SIZE} spaces.
|
68
|
+
#
|
69
|
+
# @param s [String]
|
70
|
+
# @return [Fixnum]
|
71
|
+
def number_of_leading_spaces(s)
|
72
|
+
spaces = s.scan(/^\s*/).first
|
73
|
+
spaces.count(" ") + spaces.count("\t") * TAB_SIZE
|
74
|
+
end
|
75
|
+
|
76
|
+
# This returns the position of the first non-list character
|
77
|
+
# in a list item.
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# spaces_before_first_char('*Hello') #=> 1
|
81
|
+
# spaces_before_first_char('* Hello') #=> 2
|
82
|
+
# spaces_before_first_char(' * Hello') #=> 3
|
83
|
+
# spaces_before_first_char(' * Hello') #=> 5
|
84
|
+
# spaces_before_first_char('1.Hello') #=> 2
|
85
|
+
# spaces_before_first_char(' 1. Hello') #=> 5
|
86
|
+
#
|
87
|
+
# @param s [String]
|
88
|
+
# @return [Fixnum]
|
89
|
+
def spaces_before_first_char(s)
|
90
|
+
match =
|
91
|
+
case s.md_type
|
92
|
+
when :ulist; s.match(/\s*.(\s*\{(.*?)\})?\s*/)
|
93
|
+
when :olist; s.match(/s*\d+.(\s*\{(.*?)\})?\s*/)
|
94
|
+
else
|
95
|
+
tell_user "MARUKU BUG: '#{s.inspect}' is not a list"
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
match ? [match.end(0), match[0]] : [0, nil]
|
99
|
+
end
|
100
|
+
|
101
|
+
# Replace spaces with underscores and remove non-word characters.
|
102
|
+
#
|
103
|
+
# @param s [String]
|
104
|
+
# @return [String]
|
105
|
+
def sanitize_ref_id(s)
|
106
|
+
s.strip.downcase.gsub(' ', '_').gsub(/[^\w]/, '')
|
107
|
+
end
|
108
|
+
|
109
|
+
# Remove line-initial `>` characters for a quotation.
|
110
|
+
#
|
111
|
+
# @param s [String]
|
112
|
+
# @return [String]
|
113
|
+
def unquote(s)
|
114
|
+
s.gsub(/^>\s?/, '')
|
115
|
+
end
|
116
|
+
|
117
|
+
# Removes indentation from the beginning of `s`,
|
118
|
+
# up to at most `n` spaces.
|
119
|
+
# Tabs are counted as {TAB_SIZE} spaces.
|
120
|
+
#
|
121
|
+
# @param s [String]
|
122
|
+
# @param n [Fixnum]
|
123
|
+
# @return [String]
|
124
|
+
def strip_indent(s, n)
|
125
|
+
while n > 0
|
126
|
+
case s[0]
|
127
|
+
when ?\s; n -= 1
|
128
|
+
when ?\t; n -= TAB_SIZE
|
129
|
+
else; return s
|
130
|
+
end
|
131
|
+
s = s[1..-1]
|
132
|
+
end
|
133
|
+
return s
|
134
|
+
end
|
135
|
+
|
136
|
+
# Escapes a string so that it can be safely used in a Bourne shell command line.
|
137
|
+
#
|
138
|
+
# Note that a resulted string should be used unquoted
|
139
|
+
# and is not intended for use in double quotes nor in single quotes.
|
140
|
+
#
|
141
|
+
# This is a copy of the Shellwords.shellescape function in Ruby 1.8.7.
|
142
|
+
# It's included for Ruby 1.8.6 compatibility.
|
143
|
+
#
|
144
|
+
# @param str [String]
|
145
|
+
# @return [String]
|
146
|
+
def shellescape(str)
|
147
|
+
# An empty argument will be skipped, so return empty quotes.
|
148
|
+
return "''" if str.empty?
|
149
|
+
|
150
|
+
str = str.dup
|
151
|
+
|
152
|
+
# Process as a single byte sequence because not all shell
|
153
|
+
# implementations are multibyte aware.
|
154
|
+
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
|
155
|
+
|
156
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
157
|
+
# combo is regarded as line continuation and simply ignored.
|
158
|
+
str.gsub!(/\n/, "'\n'")
|
159
|
+
|
160
|
+
return str
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
# Normalize the key/value pairs for email headers.
|
166
|
+
# Keys are downcased and converted to symbols;
|
167
|
+
# spaces become underscores.
|
168
|
+
#
|
169
|
+
# Values of `"yes"`, `"true"`, `"no"`, and `"false"`
|
170
|
+
# are converted to appropriate booleans.
|
171
|
+
#
|
172
|
+
# @param k [String]
|
173
|
+
# @param v [String]
|
174
|
+
# @return [Array(String, String or Boolean)]
|
175
|
+
def normalize_key_and_value(k, v)
|
176
|
+
k = k.strip.downcase.gsub(/\s+/, '_')
|
177
|
+
v = v.strip
|
178
|
+
|
179
|
+
# check synonyms
|
180
|
+
return k, true if %w[yes true].include?(v.downcase)
|
181
|
+
return k, false if %w[no false].include?(v.downcase)
|
182
|
+
return k, v
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|