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.
- data/lib/maruku.rb +141 -0
- data/lib/maruku/attributes.rb +175 -0
- data/lib/maruku/defaults.rb +71 -0
- data/lib/maruku/errors_management.rb +92 -0
- data/lib/maruku/ext/div.rb +133 -0
- data/lib/maruku/ext/math.rb +41 -0
- data/lib/maruku/ext/math/elements.rb +27 -0
- data/lib/maruku/ext/math/latex_fix.rb +12 -0
- data/lib/maruku/ext/math/mathml_engines/blahtex.rb +107 -0
- data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +29 -0
- data/lib/maruku/ext/math/mathml_engines/none.rb +20 -0
- data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
- data/lib/maruku/ext/math/parsing.rb +119 -0
- data/lib/maruku/ext/math/to_html.rb +187 -0
- data/lib/maruku/ext/math/to_latex.rb +26 -0
- data/lib/maruku/helpers.rb +260 -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 +616 -0
- data/lib/maruku/input/parse_doc.rb +232 -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 +33 -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 +991 -0
- data/lib/maruku/output/to_latex.rb +590 -0
- data/lib/maruku/output/to_latex_entities.rb +367 -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 +56 -0
- data/lib/maruku/string_utils.rb +201 -0
- data/lib/maruku/structures.rb +167 -0
- data/lib/maruku/structures_inspect.rb +87 -0
- data/lib/maruku/structures_iterators.rb +61 -0
- data/lib/maruku/textile2.rb +1 -0
- data/lib/maruku/toc.rb +199 -0
- data/lib/maruku/usage/example1.rb +33 -0
- data/lib/maruku/version.rb +39 -0
- 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
|
+
|