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.
Files changed (162) hide show
  1. data/AUTHORS +23 -0
  2. data/LICENSE +340 -0
  3. data/README.md +73 -0
  4. data/bin/maruku +196 -0
  5. data/bin/marutex +4 -0
  6. data/data/entities.xml +261 -0
  7. data/docs/changelog.md +334 -0
  8. data/docs/div_syntax.md +36 -0
  9. data/docs/entity_test.md +23 -0
  10. data/docs/markdown_syntax.md +899 -0
  11. data/docs/maruku.md +346 -0
  12. data/docs/math.md +194 -0
  13. data/docs/other_stuff.md +51 -0
  14. data/docs/proposal.md +309 -0
  15. data/docs/website/src/bluecloth.md +25 -0
  16. data/docs/website/src/download.md +31 -0
  17. data/docs/website/src/maruku.md +261 -0
  18. data/docs/website/src/proposal.md +271 -0
  19. data/lib/maruku.rb +132 -0
  20. data/lib/maruku/attributes.rb +138 -0
  21. data/lib/maruku/defaults.rb +69 -0
  22. data/lib/maruku/errors.rb +89 -0
  23. data/lib/maruku/ext/div.rb +121 -0
  24. data/lib/maruku/ext/fenced_code.rb +78 -0
  25. data/lib/maruku/ext/math.rb +37 -0
  26. data/lib/maruku/ext/math/elements.rb +21 -0
  27. data/lib/maruku/ext/math/latex_fix.rb +12 -0
  28. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +93 -0
  29. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +39 -0
  30. data/lib/maruku/ext/math/mathml_engines/none.rb +21 -0
  31. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  32. data/lib/maruku/ext/math/parsing.rb +125 -0
  33. data/lib/maruku/ext/math/to_html.rb +237 -0
  34. data/lib/maruku/ext/math/to_latex.rb +36 -0
  35. data/lib/maruku/ext/yaml.rb +43 -0
  36. data/lib/maruku/helpers.rb +214 -0
  37. data/lib/maruku/input/charsource.rb +326 -0
  38. data/lib/maruku/input/extensions.rb +69 -0
  39. data/lib/maruku/input/html_helper.rb +189 -0
  40. data/lib/maruku/input/linesource.rb +111 -0
  41. data/lib/maruku/input/parse_block.rb +608 -0
  42. data/lib/maruku/input/parse_doc.rb +240 -0
  43. data/lib/maruku/input/parse_span_better.rb +746 -0
  44. data/lib/maruku/input/rubypants.rb +225 -0
  45. data/lib/maruku/input/type_detection.rb +147 -0
  46. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  47. data/lib/maruku/maruku.rb +31 -0
  48. data/lib/maruku/output/s5/fancy.rb +756 -0
  49. data/lib/maruku/output/s5/to_s5.rb +138 -0
  50. data/lib/maruku/output/to_html.rb +994 -0
  51. data/lib/maruku/output/to_latex.rb +580 -0
  52. data/lib/maruku/output/to_latex_entities.rb +101 -0
  53. data/lib/maruku/output/to_latex_strings.rb +64 -0
  54. data/lib/maruku/output/to_markdown.rb +164 -0
  55. data/lib/maruku/output/to_s.rb +54 -0
  56. data/lib/maruku/string_utils.rb +185 -0
  57. data/lib/maruku/structures.rb +143 -0
  58. data/lib/maruku/structures_inspect.rb +51 -0
  59. data/lib/maruku/structures_iterators.rb +48 -0
  60. data/lib/maruku/textile2.rb +1 -0
  61. data/lib/maruku/toc.rb +214 -0
  62. data/lib/maruku/usage/example1.rb +33 -0
  63. data/lib/maruku/version +0 -0
  64. data/lib/maruku/version.rb +54 -0
  65. data/spec/block_docs/abbreviations.md +52 -0
  66. data/spec/block_docs/alt.md +17 -0
  67. data/spec/block_docs/attributes/att2.md +20 -0
  68. data/spec/block_docs/attributes/att3.md +28 -0
  69. data/spec/block_docs/attributes/attributes.md +57 -0
  70. data/spec/block_docs/attributes/circular.md +26 -0
  71. data/spec/block_docs/attributes/default.md +22 -0
  72. data/spec/block_docs/blank.md +24 -0
  73. data/spec/block_docs/blanks_in_code.md +75 -0
  74. data/spec/block_docs/bug_def.md +16 -0
  75. data/spec/block_docs/bug_table.md +46 -0
  76. data/spec/block_docs/code.md +34 -0
  77. data/spec/block_docs/code2.md +28 -0
  78. data/spec/block_docs/code3.md +71 -0
  79. data/spec/block_docs/data_loss.md +25 -0
  80. data/spec/block_docs/divs/div1.md +167 -0
  81. data/spec/block_docs/divs/div2.md +21 -0
  82. data/spec/block_docs/divs/div3_nest.md +45 -0
  83. data/spec/block_docs/easy.md +15 -0
  84. data/spec/block_docs/email.md +20 -0
  85. data/spec/block_docs/encoding/iso-8859-1.md +23 -0
  86. data/spec/block_docs/encoding/utf-8.md +18 -0
  87. data/spec/block_docs/entities.md +94 -0
  88. data/spec/block_docs/escaping.md +67 -0
  89. data/spec/block_docs/extra_dl.md +52 -0
  90. data/spec/block_docs/extra_header_id.md +63 -0
  91. data/spec/block_docs/extra_table1.md +37 -0
  92. data/spec/block_docs/footnotes.md +97 -0
  93. data/spec/block_docs/headers.md +37 -0
  94. data/spec/block_docs/hex_entities.md +37 -0
  95. data/spec/block_docs/hrule.md +39 -0
  96. data/spec/block_docs/html2.md +22 -0
  97. data/spec/block_docs/html3.md +31 -0
  98. data/spec/block_docs/html4.md +25 -0
  99. data/spec/block_docs/html5.md +23 -0
  100. data/spec/block_docs/ie.md +49 -0
  101. data/spec/block_docs/images.md +90 -0
  102. data/spec/block_docs/images2.md +31 -0
  103. data/spec/block_docs/inline_html.md +152 -0
  104. data/spec/block_docs/inline_html2.md +21 -0
  105. data/spec/block_docs/links.md +152 -0
  106. data/spec/block_docs/links2.md +22 -0
  107. data/spec/block_docs/list1.md +46 -0
  108. data/spec/block_docs/list12.md +28 -0
  109. data/spec/block_docs/list2.md +56 -0
  110. data/spec/block_docs/list3.md +64 -0
  111. data/spec/block_docs/list4.md +89 -0
  112. data/spec/block_docs/lists.md +192 -0
  113. data/spec/block_docs/lists10.md +34 -0
  114. data/spec/block_docs/lists11.md +23 -0
  115. data/spec/block_docs/lists6.md +41 -0
  116. data/spec/block_docs/lists9.md +64 -0
  117. data/spec/block_docs/lists_after_paragraph.md +208 -0
  118. data/spec/block_docs/lists_ol.md +262 -0
  119. data/spec/block_docs/loss.md +16 -0
  120. data/spec/block_docs/math/equations.md +45 -0
  121. data/spec/block_docs/math/inline.md +46 -0
  122. data/spec/block_docs/math/math2.md +45 -0
  123. data/spec/block_docs/math/notmath.md +25 -0
  124. data/spec/block_docs/math/table.md +25 -0
  125. data/spec/block_docs/math/table2.md +42 -0
  126. data/spec/block_docs/misc_sw.md +525 -0
  127. data/spec/block_docs/notyet/escape.md +21 -0
  128. data/spec/block_docs/notyet/header_after_par.md +58 -0
  129. data/spec/block_docs/notyet/ticks.md +18 -0
  130. data/spec/block_docs/notyet/triggering.md +157 -0
  131. data/spec/block_docs/olist.md +45 -0
  132. data/spec/block_docs/one.md +15 -0
  133. data/spec/block_docs/paragraph.md +16 -0
  134. data/spec/block_docs/paragraph_rules/dont_merge_ref.md +42 -0
  135. data/spec/block_docs/paragraph_rules/tab_is_blank.md +24 -0
  136. data/spec/block_docs/paragraphs.md +46 -0
  137. data/spec/block_docs/pending/amps.md +15 -0
  138. data/spec/block_docs/pending/empty_cells.md +37 -0
  139. data/spec/block_docs/pending/link.md +72 -0
  140. data/spec/block_docs/pending/ref.md +21 -0
  141. data/spec/block_docs/recover/recover_links.md +15 -0
  142. data/spec/block_docs/red_tests/abbrev.md +679 -0
  143. data/spec/block_docs/red_tests/lists7.md +32 -0
  144. data/spec/block_docs/red_tests/lists7b.md +65 -0
  145. data/spec/block_docs/red_tests/lists8.md +42 -0
  146. data/spec/block_docs/red_tests/ref.md +23 -0
  147. data/spec/block_docs/red_tests/xml.md +35 -0
  148. data/spec/block_docs/references/long_example.md +71 -0
  149. data/spec/block_docs/references/spaces_and_numbers.md +15 -0
  150. data/spec/block_docs/smartypants.md +114 -0
  151. data/spec/block_docs/syntax_hl.md +52 -0
  152. data/spec/block_docs/table_attributes.md +34 -0
  153. data/spec/block_docs/test.md +19 -0
  154. data/spec/block_docs/underscore_in_words.md +15 -0
  155. data/spec/block_docs/wrapping.md +67 -0
  156. data/spec/block_docs/xml2.md +19 -0
  157. data/spec/block_docs/xml3.md +26 -0
  158. data/spec/block_docs/xml_instruction.md +52 -0
  159. data/spec/block_spec.rb +49 -0
  160. data/spec/span_spec.rb +254 -0
  161. data/spec/spec_helper.rb +6 -0
  162. metadata +247 -0
@@ -0,0 +1,36 @@
1
+ require 'maruku/ext/math/latex_fix'
2
+
3
+ module MaRuKu
4
+ module Out
5
+ module Latex
6
+ def to_latex_inline_math
7
+ fix_latex("$#{self.math.strip}$")
8
+ end
9
+
10
+ def to_latex_equation
11
+ if self.label
12
+ fix_latex("\\begin{equation}\n#{self.math.strip}\n\\label{#{self.label}}\\end{equation}\n")
13
+ else
14
+ fix_latex("\\begin{displaymath}\n#{self.math.strip}\n\\end{displaymath}\n")
15
+ end
16
+ end
17
+
18
+ def to_latex_eqref
19
+ "\\eqref{#{self.eqid}}"
20
+ end
21
+
22
+ def to_latex_divref
23
+ "\\ref{#{self.refid}}"
24
+ end
25
+
26
+ private
27
+
28
+ def fix_latex(str)
29
+ return str unless self.get_setting(:html_math_engine) == 'itex2mml'
30
+ s = str.gsub("\\mathop{", "\\operatorname{")
31
+ s.gsub!(/\\begin\{svg\}.*?\\end\{svg\}/m, " ")
32
+ s.gsub("\\space{", "\\itexspace{")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ require 'YAML'
2
+
3
+ module MaRuKu
4
+ # Utility functions for dealing with strings.
5
+ module Strings
6
+ # Parses yaml headers, returning a hash.
7
+ # `hash[:data]` is the message;
8
+ # that is, anything past the headers.
9
+ #
10
+ # Keys are downcased and converted to symbols;
11
+ # spaces become underscores. For example:
12
+ #
13
+ # ---
14
+ # My key: true
15
+ # ---
16
+ #
17
+ # becomes:
18
+ #
19
+ # {:my_deg => true}
20
+ #
21
+ # @param s [String] the entire contents
22
+ # @return [Symbol => String] The header values
23
+ def parse_yaml_headers(s)
24
+ headers = {}
25
+ if s =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
26
+
27
+ begin
28
+ hash = YAML.load($1)
29
+ rescue => e
30
+ puts "YAML Exception reading #{name}: #{e.message}"
31
+ hash = {}
32
+ end
33
+ end
34
+ hash.each_pair do |yamlkey,yamlval|
35
+ k, v = normalize_key_and_value(yamlkey, yamlval)
36
+ headers[k.to_sym] = v
37
+ end
38
+
39
+ headers[:data] = $' # the postmatch string
40
+ headers
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,214 @@
1
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
2
+ #
3
+ # This file is part of Maruku.
4
+ #
5
+ # Maruku is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Maruku is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Maruku; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+
20
+ module MaRuKu
21
+ # A collection of helper functions for creating Markdown elements.
22
+ # They hide the particular internal representations.
23
+ #
24
+ # Always use these rather than creating an {MDElement} directly.
25
+ module Helpers
26
+ # @param children [Array<MDElement, String>]
27
+ # The child nodes.
28
+ # If the first child is a \{#md\_ial}, it's merged with `al`
29
+ def md_el(node_type, children = [], meta = {}, al = nil)
30
+ first = children.first
31
+ if first.is_a?(MDElement) && first.node_type == :ial
32
+ if al
33
+ al += first.ial
34
+ else
35
+ al = first.ial
36
+ end
37
+ children.shift
38
+ end
39
+
40
+ e = MDElement.new(node_type, children, meta, al)
41
+ e.doc = @doc
42
+ e
43
+ end
44
+
45
+ def md_header(level, children, al = nil)
46
+ md_el(:header, children, {:level => level}, al)
47
+ end
48
+
49
+ # Inline code
50
+ def md_code(code, al = nil)
51
+ md_el(:inline_code, [], {:raw_code => code}, al)
52
+ end
53
+
54
+ # Code block
55
+ def md_codeblock(source, al = nil)
56
+ md_el(:code, [], {:raw_code => source}, al)
57
+ end
58
+
59
+ def md_quote(children, al = nil)
60
+ md_el(:quote, children, {}, al)
61
+ end
62
+
63
+ def md_li(children, want_my_par, al = nil)
64
+ md_el(:li, children, {:want_my_paragraph => want_my_par}, al)
65
+ end
66
+
67
+ def md_footnote(footnote_id, children, al = nil)
68
+ md_el(:footnote, children, {:footnote_id => footnote_id}, al)
69
+ end
70
+
71
+ def md_abbr_def(abbr, text, al = nil)
72
+ md_el(:abbr_def, [], {:abbr => abbr, :text => text}, al)
73
+ end
74
+
75
+ def md_abbr(abbr, title)
76
+ md_el(:abbr, [abbr], :title => title)
77
+ end
78
+
79
+ def md_html(raw_html, al = nil)
80
+ e = md_el(:raw_html, [], :raw_html => raw_html)
81
+ begin
82
+ e.instance_variable_set("@parsed_html",
83
+ REXML::Document.new("<marukuwrap>#{raw_html.strip}</marukuwrap>"))
84
+ rescue REXML::ParseException => ex
85
+ e.instance_variable_set "@parsed_html", nil
86
+ maruku_recover <<ERR
87
+ REXML cannot parse this block of HTML/XML:
88
+ #{raw_html.gsub(/^/, '|').rstrip}
89
+ #{ex.inspect}
90
+ ERR
91
+ end
92
+ e
93
+ end
94
+
95
+ def md_link(children, ref_id, al = nil)
96
+ md_el(:link, children, {:ref_id => ref_id.downcase}, al)
97
+ end
98
+
99
+ def md_im_link(children, url, title = nil, al = nil)
100
+ md_el(:im_link, children, {:url => url, :title => title}, al)
101
+ end
102
+
103
+ def md_image(children, ref_id, al = nil)
104
+ md_el(:image, children, {:ref_id => ref_id}, al)
105
+ end
106
+
107
+ def md_im_image(children, url, title = nil, al = nil)
108
+ md_el(:im_image, children, {:url => url, :title => title}, al)
109
+ end
110
+
111
+ def md_em(children, al = nil)
112
+ md_el(:emphasis, [children].flatten, {}, al)
113
+ end
114
+
115
+ def md_br
116
+ md_el(:linebreak, [], {}, nil)
117
+ end
118
+
119
+ def md_hrule
120
+ md_el(:hrule, [], {}, nil)
121
+ end
122
+
123
+ def md_strong(children, al = nil)
124
+ md_el(:strong, [children].flatten, {}, al)
125
+ end
126
+
127
+ def md_emstrong(children, al = nil)
128
+ md_strong(md_em(children), al)
129
+ end
130
+
131
+ # A URL to be linkified (e.g. `<http://www.example.com/>`).
132
+ def md_url(url, al = nil)
133
+ md_el(:immediate_link, [], {:url => url}, al)
134
+ end
135
+
136
+ # An email to be linkified
137
+ # (e.g. `<andrea@rubyforge.org>` or `<mailto:andrea@rubyforge.org>`).
138
+ def md_email(email, al = nil)
139
+ md_el(:email_address, [], {:email => email}, al)
140
+ end
141
+
142
+ def md_entity(entity_name, al = nil)
143
+ md_el(:entity, [], {:entity_name => entity_name}, al)
144
+ end
145
+
146
+ # Markdown extra
147
+ def md_foot_ref(ref_id, al = nil)
148
+ md_el(:footnote_reference, [], {:footnote_id => ref_id}, al)
149
+ end
150
+
151
+ def md_par(children, al = nil)
152
+ md_el(:paragraph, children, meta = {}, al)
153
+ end
154
+
155
+ # A definition of a reference (e.g. `[1]: http://url [properties]`).
156
+ def md_ref_def(ref_id, url, title = nil, meta = {}, al = nil)
157
+ meta[:url] = url
158
+ meta[:ref_id] = ref_id
159
+ meta[:title] = title if title
160
+ md_el(:ref_definition, [], meta, al)
161
+ end
162
+
163
+ # inline attribute list
164
+ def md_ial(al)
165
+ al = Maruku::AttributeList.new(al) unless al.is_a?(Maruku::AttributeList)
166
+ md_el(:ial, [], :ial => al)
167
+ end
168
+
169
+ # Attribute list definition
170
+ def md_ald(id, al)
171
+ md_el(:ald, [], :ald_id => id, :ald => al)
172
+ end
173
+
174
+ # A server directive (e.g. `<?target code... ?>`)
175
+ def md_xml_instr(target, code)
176
+ md_el(:xml_instr, [], :target => target, :code => code)
177
+ end
178
+ end
179
+
180
+ class MDElement
181
+ INSPECT2_FORMS = {
182
+ :paragraph => ["par", :children],
183
+ :footnote_reference => ["foot_ref", :footnote_id],
184
+ :entity => ["entity", :entity_name],
185
+ :email_address => ["email", :email],
186
+ :inline_code => ["code", :raw_code],
187
+ :raw_html => ["html", :raw_html],
188
+ :emphasis => ["em", :children],
189
+ :strong => ["strong", :children],
190
+ :immediate_link => ["url", :url],
191
+ :image => ["image", :children, :ref_id],
192
+ :im_image => ["im_image", :children, :url, :title],
193
+ :link => ["link", :children, :ref_id],
194
+ :im_link => ["im_link", :children, :url, :title],
195
+ :ref_definition => ["ref_def", :ref_id, :url, :title],
196
+ :ial => ["ial", :ial]
197
+ }
198
+
199
+ # Outputs the abbreviated form of an element
200
+ # (this should be `eval`-able to get a copy of the original element).
201
+ def inspect2
202
+ name, *params = INSPECT2_FORMS[@node_type]
203
+ return nil unless name
204
+
205
+ params = params.map do |p|
206
+ next children_inspect if p == :children
207
+ send(p).inspect
208
+ end
209
+ params << @al.inspect if @al && !@al.empty?
210
+
211
+ "md_#{name}(#{params.join(', ')})"
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,326 @@
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; module In; module Markdown; module SpanLevelParser
23
+
24
+ # a string scanner coded by me
25
+ class CharSourceManual; end
26
+
27
+ # a wrapper around StringScanner
28
+ class CharSourceStrscan; end
29
+
30
+ # A debug scanner that checks the correctness of both
31
+ # by comparing their output
32
+ class CharSourceDebug; end
33
+
34
+ # Choose!
35
+
36
+ CharSource = CharSourceManual # faster! 58ms vs. 65ms
37
+ #CharSource = CharSourceStrscan
38
+ #CharSource = CharSourceDebug
39
+
40
+
41
+ class CharSourceManual
42
+ include MaRuKu::Strings
43
+
44
+ def initialize(s, parent=nil)
45
+ raise "Passed #{s.class}" if not s.kind_of? String
46
+ @buffer = s
47
+ @buffer_index = 0
48
+ @parent = parent
49
+ end
50
+
51
+ # Return current char as a FixNum (or nil).
52
+ def cur_char; @buffer[@buffer_index] end
53
+
54
+ # Return the next n chars as a String.
55
+ def cur_chars(n); @buffer[@buffer_index,n] end
56
+
57
+ # Return the char after current char as a FixNum (or nil).
58
+ def next_char; @buffer[@buffer_index+1] end
59
+
60
+ def shift_char
61
+ c = @buffer[@buffer_index]
62
+ @buffer_index+=1
63
+ c
64
+ end
65
+
66
+ def ignore_char
67
+ @buffer_index+=1
68
+ nil
69
+ end
70
+
71
+ def ignore_chars(n)
72
+ @buffer_index+=n
73
+ nil
74
+ end
75
+
76
+ def current_remaining_buffer
77
+ @buffer[@buffer_index, @buffer.size-@buffer_index]
78
+ end
79
+
80
+ def cur_chars_are(string)
81
+ # There is a bug here
82
+ if false
83
+ r2 = /^.{#{@buffer_index}}#{Regexp.escape string}/m
84
+ @buffer =~ r2
85
+ else
86
+ cur_chars(string.size) == string
87
+ end
88
+ end
89
+
90
+ def next_matches(r)
91
+ r2 = /^.{#{@buffer_index}}#{r}/m
92
+ md = r2.match @buffer
93
+ return !!md
94
+ end
95
+
96
+ def read_regexp3(r)
97
+ r2 = /^.{#{@buffer_index}}#{r}/m
98
+ m = r2.match @buffer
99
+ if m
100
+ consumed = m.to_s.size - @buffer_index
101
+ # puts "Consumed #{consumed} chars (entire is #{m.to_s.inspect})"
102
+ ignore_chars consumed
103
+ else
104
+ # puts "Could not read regexp #{r2.inspect} from buffer "+
105
+ # " index=#{@buffer_index}"
106
+ # puts "Cur chars = #{cur_chars(20).inspect}"
107
+ # puts "Matches? = #{cur_chars(20) =~ r}"
108
+ end
109
+ m
110
+ end
111
+
112
+ def read_regexp(r)
113
+ r2 = /^#{r}/
114
+ rest = current_remaining_buffer
115
+ m = r2.match(rest)
116
+ if m
117
+ @buffer_index += m.to_s.size
118
+ # puts "#{r} matched #{rest.inspect}: #{m.to_s.inspect}"
119
+ end
120
+ return m
121
+ end
122
+
123
+ def consume_whitespace
124
+ while c = cur_char
125
+ if (c == ?\s || c == ?\t)
126
+ # puts "ignoring #{c}"
127
+ ignore_char
128
+ else
129
+ # puts "#{c} is not ws: "<<c
130
+ break
131
+ end
132
+ end
133
+ end
134
+
135
+ def read_text_chars(out)
136
+ s = @buffer.size; c=nil
137
+ while @buffer_index < s && (c=@buffer[@buffer_index]) &&
138
+ ((c>=?a && c<=?z) || (c>=?A && c<=?Z))
139
+ out << c
140
+ @buffer_index += 1
141
+ end
142
+ end
143
+
144
+ def describe
145
+ s = describe_pos(@buffer, @buffer_index)
146
+ if @parent
147
+ s += "\n\n" + @parent.describe
148
+ end
149
+ s
150
+ end
151
+ include SpanLevelParser
152
+ end
153
+
154
+ def describe_pos(buffer, buffer_index)
155
+ len = 75
156
+ num_before = [len/2, buffer_index].min
157
+ num_after = [len/2, buffer.size-buffer_index].min
158
+ num_before_max = buffer_index
159
+ num_after_max = buffer.size-buffer_index
160
+
161
+ # puts "num #{num_before} #{num_after}"
162
+ num_before = [num_before_max, len-num_after].min
163
+ num_after = [num_after_max, len-num_before].min
164
+ # puts "num #{num_before} #{num_after}"
165
+
166
+ index_start = [buffer_index - num_before, 0].max
167
+ index_end = [buffer_index + num_after, buffer.size].min
168
+
169
+ size = index_end- index_start
170
+
171
+ # puts "- #{index_start} #{size}"
172
+
173
+ str = buffer[index_start, size]
174
+ str.gsub!("\n",'N')
175
+ str.gsub!("\t",'T')
176
+
177
+ if index_end == buffer.size
178
+ str += "EOF"
179
+ end
180
+
181
+ pre_s = buffer_index-index_start
182
+ pre_s = [pre_s, 0].max
183
+ pre_s2 = [len-pre_s,0].max
184
+ # puts "pre_S = #{pre_s}"
185
+ pre =" "*(pre_s)
186
+
187
+ "-"*len+"\n"+
188
+ str + "\n" +
189
+ "-"*pre_s + "|" + "-"*(pre_s2)+"\n"+
190
+ # pre + "|\n"+
191
+ pre + "+--- Byte #{buffer_index}\n"+
192
+
193
+ "Shown bytes [#{index_start} to #{size}] of #{buffer.size}:\n"+
194
+ buffer.gsub(/^/, ">")
195
+
196
+ # "CharSource: At character #{@buffer_index} of block "+
197
+ # " beginning with:\n #{@buffer[0,50].inspect} ...\n"+
198
+ # " before: \n ... #{cur_chars(50).inspect} ... "
199
+ end
200
+
201
+
202
+ require 'strscan'
203
+
204
+ class CharSourceStrscan
205
+ include SpanLevelParser
206
+ include MaRuKu::Strings
207
+
208
+ def initialize(s, parent=nil)
209
+ @s = StringScanner.new(s)
210
+ @parent = parent
211
+ end
212
+
213
+ # Return current char as a FixNum (or nil).
214
+ def cur_char
215
+ @s.peek(1)[0]
216
+ end
217
+
218
+ # Return the next n chars as a String.
219
+ def cur_chars(n);
220
+ @s.peek(n)
221
+ end
222
+
223
+ # Return the char after current char as a FixNum (or nil).
224
+ def next_char;
225
+ @s.peek(2)[1]
226
+ end
227
+
228
+ def shift_char
229
+ (@s.get_byte)[0]
230
+ end
231
+
232
+ def ignore_char
233
+ @s.get_byte
234
+ nil
235
+ end
236
+
237
+ def ignore_chars(n)
238
+ n.times do @s.get_byte end
239
+ nil
240
+ end
241
+
242
+ def current_remaining_buffer
243
+ @s.rest #nil #@buffer[@buffer_index, @buffer.size-@buffer_index]
244
+ end
245
+
246
+ def cur_chars_are(string)
247
+ cur_chars(string.size) == string
248
+ end
249
+
250
+ def next_matches(r)
251
+ len = @s.match?(r)
252
+ return !!len
253
+ end
254
+
255
+ def read_regexp(r)
256
+ string = @s.scan(r)
257
+ if string
258
+ return r.match(string)
259
+ else
260
+ return nil
261
+ end
262
+ end
263
+
264
+ def consume_whitespace
265
+ @s.scan(/\s+/)
266
+ nil
267
+ end
268
+
269
+ def describe
270
+ describe_pos(@s.string, @s.pos)
271
+ end
272
+
273
+ end
274
+
275
+
276
+ class CharSourceDebug
277
+ def initialize(s, parent)
278
+ @a = CharSourceManual.new(s, parent)
279
+ @b = CharSourceStrscan.new(s, parent)
280
+ end
281
+
282
+ def method_missing(methodname, *args)
283
+ a_bef = @a.describe
284
+ b_bef = @b.describe
285
+
286
+ a = @a.send(methodname, *args)
287
+ b = @b.send(methodname, *args)
288
+
289
+ # if methodname == :describe
290
+ # return a
291
+ # end
292
+
293
+ if a.kind_of? MatchData
294
+ if a.to_a != b.to_a
295
+ puts "called: #{methodname}(#{args})"
296
+ puts "Matchdata:\na = #{a.to_a.inspect}\nb = #{b.to_a.inspect}"
297
+ puts "AFTER: "+@a.describe
298
+ puts "AFTER: "+@b.describe
299
+ puts "BEFORE: "+a_bef
300
+ puts "BEFORE: "+b_bef
301
+ puts caller.join("\n")
302
+ exit
303
+ end
304
+ else
305
+ if a!=b
306
+ puts "called: #{methodname}(#{args})"
307
+ puts "Attenzione!\na = #{a.inspect}\nb = #{b.inspect}"
308
+ puts ""+@a.describe
309
+ puts ""+@b.describe
310
+ puts caller.join("\n")
311
+ exit
312
+ end
313
+ end
314
+
315
+ if @a.cur_char != @b.cur_char
316
+ puts "Fuori sincronia dopo #{methodname}(#{args})"
317
+ puts ""+@a.describe
318
+ puts ""+@b.describe
319
+ exit
320
+ end
321
+
322
+ return a
323
+ end
324
+ end
325
+
326
+ end end end end