maiku 0.6.1.maiku

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/lib/maruku.rb +141 -0
  2. data/lib/maruku/attributes.rb +175 -0
  3. data/lib/maruku/defaults.rb +71 -0
  4. data/lib/maruku/errors_management.rb +92 -0
  5. data/lib/maruku/ext/div.rb +133 -0
  6. data/lib/maruku/ext/math.rb +41 -0
  7. data/lib/maruku/ext/math/elements.rb +27 -0
  8. data/lib/maruku/ext/math/latex_fix.rb +12 -0
  9. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +107 -0
  10. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
  11. data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
  12. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  13. data/lib/maruku/ext/math/parsing.rb +119 -0
  14. data/lib/maruku/ext/math/to_html.rb +187 -0
  15. data/lib/maruku/ext/math/to_latex.rb +26 -0
  16. data/lib/maruku/helpers.rb +260 -0
  17. data/lib/maruku/input/charsource.rb +326 -0
  18. data/lib/maruku/input/extensions.rb +69 -0
  19. data/lib/maruku/input/html_helper.rb +189 -0
  20. data/lib/maruku/input/linesource.rb +111 -0
  21. data/lib/maruku/input/parse_block.rb +616 -0
  22. data/lib/maruku/input/parse_doc.rb +232 -0
  23. data/lib/maruku/input/parse_span_better.rb +746 -0
  24. data/lib/maruku/input/rubypants.rb +225 -0
  25. data/lib/maruku/input/type_detection.rb +147 -0
  26. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  27. data/lib/maruku/maruku.rb +33 -0
  28. data/lib/maruku/output/s5/fancy.rb +756 -0
  29. data/lib/maruku/output/s5/to_s5.rb +138 -0
  30. data/lib/maruku/output/to_html.rb +991 -0
  31. data/lib/maruku/output/to_latex.rb +590 -0
  32. data/lib/maruku/output/to_latex_entities.rb +367 -0
  33. data/lib/maruku/output/to_latex_strings.rb +64 -0
  34. data/lib/maruku/output/to_markdown.rb +164 -0
  35. data/lib/maruku/output/to_s.rb +56 -0
  36. data/lib/maruku/string_utils.rb +201 -0
  37. data/lib/maruku/structures.rb +167 -0
  38. data/lib/maruku/structures_inspect.rb +87 -0
  39. data/lib/maruku/structures_iterators.rb +61 -0
  40. data/lib/maruku/textile2.rb +1 -0
  41. data/lib/maruku/toc.rb +199 -0
  42. data/lib/maruku/usage/example1.rb +33 -0
  43. data/lib/maruku/version.rb +39 -0
  44. metadata +167 -0
@@ -0,0 +1,56 @@
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
+
38
+ title = children_to_s
39
+ title.gsub!(/ /,'_')
40
+ title.downcase!
41
+ title.gsub!(/[^\w_]/,'')
42
+ title.strip!
43
+
44
+ if title.size == 0
45
+ $uid ||= 0
46
+ $uid += 1
47
+ title = "id#{$uid}"
48
+ end
49
+
50
+ # random is a very bad idea
51
+ # title << "_" + rand(10000).to_s
52
+ title
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,201 @@
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
+ # Boring stuff with strings.
23
+ module MaRuKu; module Strings
24
+
25
+ def add_tabs(s,n=1,char="\t")
26
+ s.split("\n").map{|x| char*n+x }.join("\n")
27
+ end
28
+
29
+ TabSize = 4;
30
+
31
+ def split_lines(s)
32
+ s.gsub("\r","").split("\n")
33
+ end
34
+
35
+ # This parses email headers. Returns an hash.
36
+ #
37
+ # +hash['data']+ is the message.
38
+ #
39
+ # Keys are downcased, space becomes underscore, converted to symbols.
40
+ #
41
+ # My key: true
42
+ #
43
+ # becomes:
44
+ #
45
+ # {:my_key => true}
46
+ #
47
+ def parse_email_headers(s)
48
+ keys={}
49
+ match = (s =~ /\A((\w[\w\s\_\-]+: .*\n)+)\s*\n/)
50
+ if match != 0
51
+ keys[:data] = s
52
+ else
53
+ keys[:data] = $'
54
+ headers = $1
55
+ headers.split("\n").each do |l|
56
+ # Fails if there are other ':' characters.
57
+ # k, v = l.split(':')
58
+ k, v = l.split(':', 2)
59
+ k, v = normalize_key_and_value(k, v)
60
+ k = k.to_sym
61
+ # puts "K = #{k}, V=#{v}"
62
+ keys[k] = v
63
+ end
64
+ end
65
+ keys
66
+ end
67
+
68
+ # Keys are downcased, space becomes underscore, converted to symbols.
69
+ def normalize_key_and_value(k,v)
70
+ v = v ? v.strip : true # no value defaults to true
71
+ k = k.strip
72
+
73
+ # check synonyms
74
+ v = true if ['yes','true'].include?(v.to_s.downcase)
75
+ v = false if ['no','false'].include?(v.to_s.downcase)
76
+
77
+ k = k.downcase.gsub(' ','_')
78
+ return k, v
79
+ end
80
+
81
+ # Returns the number of leading spaces, considering that
82
+ # a tab counts as `TabSize` spaces.
83
+ def number_of_leading_spaces(s)
84
+ n=0; i=0;
85
+ while i < s.size
86
+ c = s[i,1]
87
+ if c == ' '
88
+ i+=1; n+=1;
89
+ elsif c == "\t"
90
+ i+=1; n+=TabSize;
91
+ else
92
+ break
93
+ end
94
+ end
95
+ n
96
+ end
97
+
98
+ # This returns the position of the first real char in a list item
99
+ #
100
+ # For example:
101
+ # '*Hello' # => 1
102
+ # '* Hello' # => 2
103
+ # ' * Hello' # => 3
104
+ # ' * Hello' # => 5
105
+ # '1.Hello' # => 2
106
+ # ' 1. Hello' # => 5
107
+
108
+ def spaces_before_first_char(s)
109
+ case s.md_type
110
+ when :ulist
111
+ i=0;
112
+ # skip whitespace if present
113
+ while s[i,1] =~ /\s/; i+=1 end
114
+ # skip indicator (+, -, *)
115
+ i+=1
116
+ # skip whitespace
117
+ while s[i,1] =~ /\s/; i+=1 end
118
+ # find an IAL
119
+ ial = s[i,s.length - i][/^\{(.*?)\}/]
120
+ i+= ial.length if ial
121
+ # skip optional whitespace
122
+ while s[i,1] =~ /\s/; i+=1 end
123
+ return [i, ial]
124
+ when :olist
125
+ i=0;
126
+ # skip whitespace
127
+ while s[i,1] =~ /\s/; i+=1 end
128
+ # skip digits
129
+ while s[i,1] =~ /\d/; i+=1 end
130
+ # skip dot
131
+ i+=1
132
+ # skip optional whitespace
133
+ while s[i,1] =~ /\s/; i+=1 end
134
+ # find an IAL
135
+ ial = s[i,s.length - i][/^\{(.*?)\}/]
136
+ i+= ial.length if ial
137
+ # skip whitespace
138
+ while s[i,1] =~ /\s/; i+=1 end
139
+ return [i, ial]
140
+ else
141
+ tell_user "BUG (my bad): '#{s}' is not a list"
142
+ [0, nil]
143
+ end
144
+ end
145
+
146
+ # Counts the number of leading '#' in the string
147
+ def num_leading_hashes(s)
148
+ i=0;
149
+ while i<(s.size-1) && (s[i,1]=='#'); i+=1 end
150
+ i
151
+ end
152
+
153
+ # Strips initial and final hashes
154
+ def strip_hashes(s)
155
+ s = s[num_leading_hashes(s), s.size]
156
+ i = s.size-1
157
+ while i > 0 && (s[i,1] =~ /(#|\s)/); i-=1; end
158
+ s[0, i+1].strip
159
+ end
160
+
161
+ # change space to "_" and remove any non-word character
162
+ def sanitize_ref_id(x)
163
+ x.strip.downcase.gsub(' ','_').gsub(/[^\w]/,'')
164
+ end
165
+
166
+
167
+ # removes initial quote
168
+ def unquote(s)
169
+ s.gsub(/^>\s?/,'')
170
+ end
171
+
172
+ # toglie al massimo n caratteri
173
+ def strip_indent(s, n)
174
+ i = 0
175
+ while i < s.size && n>0
176
+ c = s[i,1]
177
+ if c == ' '
178
+ n-=1;
179
+ elsif c == "\t"
180
+ n-=TabSize;
181
+ else
182
+ break
183
+ end
184
+ i+=1
185
+ end
186
+ s[i, s.size]
187
+ end
188
+
189
+ def dbg_describe_ary(a, prefix='')
190
+ i = 0
191
+ a.each do |l|
192
+ puts "#{prefix} (#{i+=1})# #{l.inspect}"
193
+ end
194
+ end
195
+
196
+ def force_linebreak?(l)
197
+ l =~ / $/
198
+ end
199
+
200
+ end
201
+ end
@@ -0,0 +1,167 @@
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 Module
24
+ def safe_attr_accessor1(symbol, klass)
25
+ attr_reader symbol
26
+ code = <<-EOF
27
+ def #{symbol}=(val)
28
+ if not val.kind_of? #{klass}
29
+ s = "\nCould not assign an object of type \#{val.class} to #{symbol}.\n\n"
30
+ s += "Tried to assign object of class \#{val.class}:\n"+
31
+ "\#{val.inspect}\n"+
32
+ "to \#{self.class}::#{symbol} constrained to be of class #{klass}.\n"
33
+ raise s
34
+ end
35
+ @#{symbol} = val
36
+ end
37
+
38
+ EOF
39
+ module_eval code
40
+ end
41
+
42
+ def safe_attr_accessor2(symbol, klass)
43
+ attr_accessor symbol
44
+ end
45
+
46
+ alias safe_attr_accessor safe_attr_accessor2
47
+ end
48
+
49
+ module MaRuKu
50
+
51
+ # I did not want to have a class for each possible element.
52
+ # Instead I opted to have only the class "MDElement"
53
+ # that represents eveything in the document (paragraphs, headers, etc).
54
+ #
55
+ # You can tell what it is by the variable `node_type`.
56
+ #
57
+ # In the instance-variable `children` there are the children. These
58
+ # can be of class 1) String or 2) MDElement.
59
+ #
60
+ # The @doc variable points to the document to which the MDElement
61
+ # belongs (which is an instance of Maruku, subclass of MDElement).
62
+ #
63
+ # Attributes are contained in the hash `attributes`.
64
+ # Keys are symbols (downcased, with spaces substituted by underscores)
65
+ #
66
+ # For example, if you write in the source document.
67
+ #
68
+ # Title: test document
69
+ # My property: value
70
+ #
71
+ # content content
72
+ #
73
+ # You can access `value` by writing:
74
+ #
75
+ # @doc.attributes[:my_property] # => 'value'
76
+ #
77
+ # from whichever MDElement in the hierarchy.
78
+ #
79
+ class MDElement
80
+ # See helpers.rb for the list of allowed #node_type values
81
+ safe_attr_accessor :node_type, Symbol
82
+
83
+ # Children are either Strings or MDElement
84
+ safe_attr_accessor :children, Array
85
+
86
+ # An attribute list, may not be nil
87
+ safe_attr_accessor :al, Array #Maruku::AttributeList
88
+
89
+ # These are the processed attributes
90
+ safe_attr_accessor :attributes, Hash
91
+
92
+ # Reference of the document (which is of class Maruku)
93
+ attr_accessor :doc
94
+
95
+ def initialize(node_type=:unset, children=[], meta={},
96
+ al=MaRuKu::AttributeList.new )
97
+ super();
98
+ self.children = children
99
+ self.node_type = node_type
100
+
101
+ @attributes = {}
102
+
103
+ meta.each do |symbol, value|
104
+ self.instance_eval "
105
+ def #{symbol}; @#{symbol}; end
106
+ def #{symbol}=(val); @#{symbol}=val; end"
107
+ self.send "#{symbol}=", value
108
+ end
109
+
110
+ self.al = al || AttributeList.new
111
+
112
+ self.meta_priv = meta
113
+ end
114
+
115
+ attr_accessor :meta_priv
116
+
117
+ def ==(o)
118
+ ok = o.kind_of?(MDElement) &&
119
+ (self.node_type == o.node_type) &&
120
+ (self.meta_priv == o.meta_priv) &&
121
+ (self.children == o.children)
122
+
123
+ if not ok
124
+ # puts "This:\n"+self.inspect+"\nis different from\n"+o.inspect+"\n\n"
125
+ end
126
+ ok
127
+ end
128
+ end
129
+
130
+ # This represents the whole document and holds global data.
131
+
132
+ class MDDocument
133
+
134
+ safe_attr_accessor :refs, Hash
135
+ safe_attr_accessor :footnotes, Hash
136
+
137
+ # This is an hash. The key might be nil.
138
+ safe_attr_accessor :abbreviations, Hash
139
+
140
+ # Attribute lists definition
141
+ safe_attr_accessor :ald, Hash
142
+
143
+ # The order in which footnotes are used. Contains the id.
144
+ safe_attr_accessor :footnotes_order, Array
145
+
146
+ safe_attr_accessor :latex_required_packages, Array
147
+
148
+ safe_attr_accessor :refid2ref, Hash
149
+
150
+ def initialize(s=nil)
151
+ super(:document)
152
+ @doc = self
153
+
154
+ self.refs = {}
155
+ self.footnotes = {}
156
+ self.footnotes_order = []
157
+ self.abbreviations = {}
158
+ self.ald = {}
159
+ self.latex_required_packages = []
160
+
161
+ parse_doc(s) if s
162
+ end
163
+ end
164
+
165
+
166
+ end # MaRuKu
167
+
@@ -0,0 +1,87 @@
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
+ def inspect_more(a=nil,b=nil)
25
+ inspect
26
+ end
27
+ end
28
+
29
+ class Object
30
+ def inspect_more(a=nil,b=nil)
31
+ inspect
32
+ end
33
+ end
34
+
35
+ class Array
36
+ def inspect_more(compact, join_string, add_brackets=true)
37
+ s = map {|x|
38
+ x.kind_of?(String) ? x.inspect :
39
+ x.kind_of?(MaRuKu::MDElement) ? x.inspect(compact) :
40
+ (raise "WTF #{x.class} #{x.inspect}")
41
+ }.join(join_string)
42
+
43
+ add_brackets ? "[#{s}]" : s
44
+ end
45
+ end
46
+
47
+ class Hash
48
+ def inspect_ordered(a=nil,b=nil)
49
+ "{"+keys.map{|x|x.to_s}.sort.map{|x|x.to_sym}.
50
+ map{|k| k.inspect + "=>"+self[k].inspect}.join(',')+"}"
51
+ end
52
+ end
53
+
54
+ module MaRuKu
55
+ class MDElement
56
+ def inspect(compact=true)
57
+ if compact
58
+ i2 = inspect2
59
+ return i2 if i2
60
+ end
61
+
62
+ "md_el(:%s,%s,%s,%s)" %
63
+ [
64
+ self.node_type,
65
+ children_inspect(compact),
66
+ @meta_priv.inspect_ordered,
67
+ self.al.inspect
68
+ ]
69
+ end
70
+
71
+ def children_inspect(compact=true)
72
+ s = @children.inspect_more(compact,', ')
73
+ if @children.empty?
74
+ "[]"
75
+ elsif s.size < 70
76
+ s
77
+ else
78
+ "[\n"+
79
+ add_tabs(@children.inspect_more(compact,",\n",false))+
80
+ "\n]"
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+