maiku 0.6.1.maiku

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.
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
+