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,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
|