maruku 0.6.1 → 0.7.0.beta1
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/MIT-LICENSE.txt +20 -0
- data/bin/maruku +153 -152
- data/bin/marutex +2 -29
- data/data/entities.xml +261 -0
- data/docs/math.md +14 -18
- data/lib/maruku.rb +65 -77
- data/lib/maruku/attributes.rb +109 -214
- data/lib/maruku/defaults.rb +45 -67
- data/lib/maruku/document.rb +43 -0
- data/lib/maruku/element.rb +112 -0
- data/lib/maruku/errors.rb +71 -0
- data/lib/maruku/ext/div.rb +105 -113
- data/lib/maruku/ext/fenced_code.rb +97 -0
- data/lib/maruku/ext/math.rb +22 -26
- data/lib/maruku/ext/math/elements.rb +20 -26
- data/lib/maruku/ext/math/mathml_engines/blahtex.rb +92 -104
- data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +33 -26
- data/lib/maruku/ext/math/mathml_engines/none.rb +11 -19
- data/lib/maruku/ext/math/mathml_engines/ritex.rb +2 -4
- data/lib/maruku/ext/math/parsing.rb +107 -113
- data/lib/maruku/ext/math/to_html.rb +184 -187
- data/lib/maruku/ext/math/to_latex.rb +30 -21
- data/lib/maruku/helpers.rb +158 -257
- data/lib/maruku/html.rb +254 -0
- data/lib/maruku/input/charsource.rb +272 -319
- data/lib/maruku/input/extensions.rb +62 -63
- data/lib/maruku/input/html_helper.rb +220 -189
- data/lib/maruku/input/linesource.rb +90 -110
- data/lib/maruku/input/mdline.rb +129 -0
- data/lib/maruku/input/parse_block.rb +618 -612
- data/lib/maruku/input/parse_doc.rb +145 -215
- data/lib/maruku/input/parse_span.rb +658 -0
- data/lib/maruku/input/rubypants.rb +200 -128
- data/lib/maruku/inspect_element.rb +60 -0
- data/lib/maruku/maruku.rb +10 -31
- data/lib/maruku/output/entity_table.rb +33 -0
- data/lib/maruku/output/s5/fancy.rb +462 -462
- data/lib/maruku/output/s5/to_s5.rb +115 -135
- data/lib/maruku/output/to_html.rb +898 -983
- data/lib/maruku/output/to_latex.rb +561 -560
- data/lib/maruku/output/to_markdown.rb +207 -162
- data/lib/maruku/output/to_s.rb +11 -52
- data/lib/maruku/string_utils.rb +129 -179
- data/lib/maruku/toc.rb +185 -196
- data/lib/maruku/version.rb +33 -38
- data/spec/block_docs/abbrev.md +776 -0
- data/{tests/unittest → spec/block_docs}/abbreviations.md +11 -20
- data/{tests/unittest → spec/block_docs}/alt.md +2 -14
- data/{tests/unittest/pending → spec/block_docs}/amps.md +1 -13
- data/{tests/unittest → spec/block_docs}/attributes/att2.md +0 -12
- data/{tests/unittest → spec/block_docs}/attributes/att3.md +2 -14
- data/{tests/unittest → spec/block_docs}/attributes/attributes.md +12 -16
- data/{tests/unittest → spec/block_docs}/attributes/circular.md +0 -12
- data/{tests/unittest → spec/block_docs}/attributes/default.md +1 -13
- data/{tests/unittest → spec/block_docs}/blank.md +0 -12
- data/{tests/unittest → spec/block_docs}/blanks_in_code.md +16 -15
- data/{tests/unittest/loss.md → spec/block_docs/bug_def.md} +6 -18
- data/{tests/unittest → spec/block_docs}/bug_table.md +3 -15
- data/{tests/unittest → spec/block_docs}/code.md +7 -14
- data/{tests/unittest → spec/block_docs}/code2.md +4 -14
- data/{tests/unittest → spec/block_docs}/code3.md +12 -16
- data/{tests/unittest → spec/block_docs}/data_loss.md +2 -14
- data/{tests/unittest → spec/block_docs}/divs/div1.md +0 -12
- data/{tests/unittest → spec/block_docs}/divs/div2.md +0 -12
- data/{tests/unittest → spec/block_docs}/divs/div3_nest.md +3 -15
- data/{tests/unittest → spec/block_docs}/easy.md +1 -13
- data/spec/block_docs/email.md +29 -0
- data/{tests/unittest/pending → spec/block_docs}/empty_cells.md +3 -15
- data/{tests/unittest → spec/block_docs}/encoding/iso-8859-1.md +1 -14
- data/{tests/unittest → spec/block_docs}/encoding/utf-8.md +0 -12
- data/{tests/unittest → spec/block_docs}/entities.md +27 -29
- data/{tests/unittest/notyet → spec/block_docs}/escape.md +2 -14
- data/{tests/unittest → spec/block_docs}/escaping.md +11 -22
- data/{tests/unittest → spec/block_docs}/extra_dl.md +2 -13
- data/{tests/unittest → spec/block_docs}/extra_header_id.md +14 -20
- data/{tests/unittest → spec/block_docs}/extra_table1.md +3 -15
- data/spec/block_docs/fenced_code_blocks.md +66 -0
- data/spec/block_docs/fenced_code_blocks_highlighted.md +18 -0
- data/{tests/unittest → spec/block_docs}/footnotes.md +12 -24
- data/spec/block_docs/footnotes2.md +78 -0
- data/spec/block_docs/hard.md +25 -0
- data/spec/block_docs/header_after_par.md +62 -0
- data/{tests/unittest → spec/block_docs}/headers.md +10 -18
- data/{tests/unittest → spec/block_docs}/hex_entities.md +7 -18
- data/{tests/unittest → spec/block_docs}/hrule.md +5 -12
- data/{tests/unittest → spec/block_docs}/html3.md +1 -13
- data/{tests/unittest → spec/block_docs}/html4.md +2 -14
- data/{tests/unittest → spec/block_docs}/html5.md +2 -14
- data/spec/block_docs/html_block_in_para.md +22 -0
- data/spec/block_docs/html_inline.md +25 -0
- data/spec/block_docs/html_trailing.md +31 -0
- data/spec/block_docs/ie.md +62 -0
- data/spec/block_docs/iframe.md +29 -0
- data/{tests/unittest → spec/block_docs}/images.md +22 -28
- data/{tests/unittest → spec/block_docs}/images2.md +7 -17
- data/{tests/unittest → spec/block_docs}/inline_html.md +37 -67
- data/{tests/unittest → spec/block_docs}/inline_html2.md +1 -13
- data/spec/block_docs/inline_html_beginning.md +10 -0
- data/spec/block_docs/issue20.md +9 -0
- data/spec/block_docs/issue26.md +22 -0
- data/spec/block_docs/issue29.md +9 -0
- data/spec/block_docs/issue30.md +30 -0
- data/spec/block_docs/issue31.md +25 -0
- data/spec/block_docs/issue40.md +40 -0
- data/spec/block_docs/issue64.md +55 -0
- data/spec/block_docs/issue67.md +19 -0
- data/spec/block_docs/issue70.md +11 -0
- data/spec/block_docs/issue72.md +17 -0
- data/spec/block_docs/issue74.md +38 -0
- data/spec/block_docs/issue79.md +15 -0
- data/spec/block_docs/issue83.md +13 -0
- data/spec/block_docs/issue85.md +25 -0
- data/spec/block_docs/issue88.md +19 -0
- data/spec/block_docs/issue89.md +12 -0
- data/spec/block_docs/issue90.md +38 -0
- data/{tests/unittest/pending → spec/block_docs}/link.md +21 -18
- data/{tests/unittest → spec/block_docs}/links.md +33 -32
- data/spec/block_docs/links2.md +21 -0
- data/{tests/unittest → spec/block_docs}/list1.md +0 -12
- data/{tests/unittest → spec/block_docs}/list12.md +2 -14
- data/{tests/unittest → spec/block_docs}/list2.md +2 -14
- data/spec/block_docs/list_multipara.md +42 -0
- data/{tests/unittest → spec/block_docs}/lists.md +28 -29
- data/{tests/unittest → spec/block_docs}/lists10.md +2 -14
- data/spec/block_docs/lists11.md +23 -0
- data/spec/block_docs/lists12.md +43 -0
- data/spec/block_docs/lists13.md +55 -0
- data/spec/block_docs/lists14.md +61 -0
- data/spec/block_docs/lists15.md +36 -0
- data/spec/block_docs/lists6.md +88 -0
- data/spec/block_docs/lists7b.md +58 -0
- data/spec/block_docs/lists9.md +53 -0
- data/{tests/unittest → spec/block_docs}/lists_after_paragraph.md +19 -25
- data/spec/block_docs/lists_blank.md +35 -0
- data/{tests/unittest/list3.md → spec/block_docs/lists_blockquote_code.md} +2 -14
- data/{tests/unittest/list4.md → spec/block_docs/lists_need_blank_line.md} +50 -21
- data/spec/block_docs/lists_nested.md +44 -0
- data/spec/block_docs/lists_nested_blankline.md +28 -0
- data/spec/block_docs/lists_nested_deep.md +43 -0
- data/{tests/unittest → spec/block_docs}/lists_ol.md +37 -54
- data/spec/block_docs/lists_paraindent.md +47 -0
- data/spec/block_docs/lists_tab.md +54 -0
- data/spec/block_docs/loss.md +17 -0
- data/spec/block_docs/math-blahtex/equations.md +30 -0
- data/spec/block_docs/math-blahtex/inline.md +48 -0
- data/spec/block_docs/math-blahtex/math2.md +45 -0
- data/spec/block_docs/math-blahtex/table.md +25 -0
- data/spec/block_docs/math/embedded_invalid_svg.md +79 -0
- data/spec/block_docs/math/embedded_svg.md +97 -0
- data/spec/block_docs/math/equations.md +44 -0
- data/{tests/unittest → spec/block_docs}/math/inline.md +7 -19
- data/spec/block_docs/math/math2.md +45 -0
- data/{tests/unittest → spec/block_docs}/math/notmath.md +0 -12
- data/spec/block_docs/math/raw_mathml.md +87 -0
- data/spec/block_docs/math/table.md +25 -0
- data/{tests/unittest → spec/block_docs}/math/table2.md +5 -17
- data/{tests/unittest → spec/block_docs}/misc_sw.md +181 -118
- data/{tests/unittest → spec/block_docs}/olist.md +6 -18
- data/{tests/unittest → spec/block_docs}/one.md +0 -12
- data/{tests/unittest → spec/block_docs}/paragraph.md +0 -12
- data/{tests/unittest → spec/block_docs}/paragraph_rules/dont_merge_ref.md +4 -12
- data/{tests/unittest → spec/block_docs}/paragraph_rules/tab_is_blank.md +0 -12
- data/{tests/unittest → spec/block_docs}/paragraphs.md +1 -13
- data/{tests/unittest → spec/block_docs}/recover/recover_links.md +4 -16
- data/{tests/unittest/pending/ref.md → spec/block_docs/ref_with_period.md} +7 -16
- data/spec/block_docs/ref_with_title.md +22 -0
- data/{tests/unittest → spec/block_docs}/references/long_example.md +16 -23
- data/{tests/unittest → spec/block_docs}/references/spaces_and_numbers.md +0 -12
- data/{tests/unittest → spec/block_docs}/smartypants.md +24 -31
- data/{tests/unittest → spec/block_docs}/syntax_hl.md +13 -17
- data/{tests/unittest → spec/block_docs}/table_attributes.md +2 -14
- data/spec/block_docs/tables.md +58 -0
- data/{tests/unittest → spec/block_docs}/test.md +1 -13
- data/{tests/unittest/notyet → spec/block_docs}/ticks.md +1 -13
- data/spec/block_docs/toc.md +87 -0
- data/{tests/unittest/notyet → spec/block_docs}/triggering.md +14 -25
- data/{tests/unittest → spec/block_docs}/underscore_in_words.md +0 -12
- data/{tests/unittest → spec/block_docs}/wrapping.md +4 -16
- data/spec/block_docs/xml.md +33 -0
- data/{tests/unittest → spec/block_docs}/xml2.md +0 -12
- data/spec/block_docs/xml3.md +24 -0
- data/{tests/unittest → spec/block_docs}/xml_instruction.md +9 -20
- data/spec/block_spec.rb +110 -0
- data/spec/cli_spec.rb +8 -0
- data/spec/span_spec.rb +256 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/to_html_utf8_spec.rb +13 -0
- metadata +205 -243
- metadata.gz.sig +3 -0
- data/Rakefile +0 -48
- data/bin/marudown +0 -29
- data/bin/marutest +0 -345
- data/docs/changelog.md +0 -334
- data/lib/maruku/errors_management.rb +0 -92
- data/lib/maruku/ext/math/latex_fix.rb +0 -12
- data/lib/maruku/input/parse_span_better.rb +0 -746
- data/lib/maruku/input/type_detection.rb +0 -147
- data/lib/maruku/output/to_latex_entities.rb +0 -367
- data/lib/maruku/output/to_latex_strings.rb +0 -64
- data/lib/maruku/structures.rb +0 -167
- data/lib/maruku/structures_inspect.rb +0 -87
- data/lib/maruku/structures_iterators.rb +0 -61
- data/lib/maruku/tests/benchmark.rb +0 -82
- data/lib/maruku/tests/new_parser.rb +0 -373
- data/lib/maruku/tests/tests.rb +0 -136
- data/lib/maruku/usage/example1.rb +0 -33
- data/tests/bugs/code_in_links.md +0 -101
- data/tests/bugs/complex_escaping.md +0 -38
- data/tests/math/syntax.md +0 -46
- data/tests/math_usage/document.md +0 -13
- data/tests/others/abbreviations.md +0 -11
- data/tests/others/blank.md +0 -4
- data/tests/others/code.md +0 -5
- data/tests/others/code2.md +0 -8
- data/tests/others/code3.md +0 -16
- data/tests/others/email.md +0 -4
- data/tests/others/entities.md +0 -19
- data/tests/others/escaping.md +0 -16
- data/tests/others/extra_dl.md +0 -101
- data/tests/others/extra_header_id.md +0 -13
- data/tests/others/extra_table1.md +0 -40
- data/tests/others/footnotes.md +0 -17
- data/tests/others/headers.md +0 -10
- data/tests/others/hrule.md +0 -10
- data/tests/others/images.md +0 -20
- data/tests/others/inline_html.md +0 -42
- data/tests/others/links.md +0 -38
- data/tests/others/list1.md +0 -4
- data/tests/others/list2.md +0 -5
- data/tests/others/list3.md +0 -8
- data/tests/others/lists.md +0 -32
- data/tests/others/lists_after_paragraph.md +0 -44
- data/tests/others/lists_ol.md +0 -39
- data/tests/others/misc_sw.md +0 -105
- data/tests/others/one.md +0 -1
- data/tests/others/paragraphs.md +0 -13
- data/tests/others/sss06.md +0 -352
- data/tests/others/test.md +0 -4
- data/tests/s5/s5profiling.md +0 -48
- data/tests/unittest/bug_def.md +0 -28
- data/tests/unittest/email.md +0 -32
- data/tests/unittest/html2.md +0 -34
- data/tests/unittest/ie.md +0 -61
- data/tests/unittest/links2.md +0 -34
- data/tests/unittest/lists11.md +0 -28
- data/tests/unittest/lists6.md +0 -53
- data/tests/unittest/lists9.md +0 -76
- data/tests/unittest/math/equations.md +0 -86
- data/tests/unittest/math/math2.md +0 -57
- data/tests/unittest/math/table.md +0 -37
- data/tests/unittest/notyet/header_after_par.md +0 -70
- data/tests/unittest/red_tests/abbrev.md +0 -1388
- data/tests/unittest/red_tests/lists7.md +0 -68
- data/tests/unittest/red_tests/lists7b.md +0 -128
- data/tests/unittest/red_tests/lists8.md +0 -76
- data/tests/unittest/red_tests/xml.md +0 -70
- data/tests/unittest/xml3.md +0 -38
- data/tests/utf8-files/simple.md +0 -1
- data/unit_test_block.sh +0 -5
- data/unit_test_span.sh +0 -3
@@ -1,33 +1,13 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
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
|
-
# NOTA BENE:
|
23
|
-
#
|
24
|
-
# The following algorithm is a rip-off of RubyPants written by
|
25
|
-
# Christian Neukirchen.
|
1
|
+
#
|
2
|
+
# NOTA BENE:
|
3
|
+
#
|
4
|
+
# The following algorithm is a rip-off of RubyPants written by
|
5
|
+
# Christian Neukirchen.
|
26
6
|
#
|
27
7
|
# RubyPants is a Ruby port of SmartyPants written by John Gruber.
|
28
8
|
#
|
29
|
-
# This file is distributed under the
|
30
|
-
# with the terms of the RubyPants license.
|
9
|
+
# This file is distributed under the MIT license, which is compatible
|
10
|
+
# with the terms of the RubyPants license (3-clause BSD).
|
31
11
|
#
|
32
12
|
# -- Andrea Censi
|
33
13
|
|
@@ -51,39 +31,39 @@
|
|
51
31
|
# [snip]
|
52
32
|
#
|
53
33
|
# == Authors
|
54
|
-
#
|
34
|
+
#
|
55
35
|
# John Gruber did all of the hard work of writing this software in
|
56
36
|
# Perl for Movable Type and almost all of this useful documentation.
|
57
37
|
# Chad Miller ported it to Python to use with Pyblosxom.
|
58
38
|
#
|
59
39
|
# Christian Neukirchen provided the Ruby port, as a general-purpose
|
60
40
|
# library that follows the *Cloth API.
|
61
|
-
#
|
41
|
+
#
|
62
42
|
#
|
63
43
|
# == Copyright and License
|
64
|
-
#
|
44
|
+
#
|
65
45
|
# === SmartyPants license:
|
66
|
-
#
|
46
|
+
#
|
67
47
|
# Copyright (c) 2003 John Gruber
|
68
48
|
# (http://daringfireball.net)
|
69
49
|
# All rights reserved.
|
70
|
-
#
|
50
|
+
#
|
71
51
|
# Redistribution and use in source and binary forms, with or without
|
72
52
|
# modification, are permitted provided that the following conditions
|
73
53
|
# are met:
|
74
|
-
#
|
54
|
+
#
|
75
55
|
# * Redistributions of source code must retain the above copyright
|
76
56
|
# notice, this list of conditions and the following disclaimer.
|
77
|
-
#
|
57
|
+
#
|
78
58
|
# * Redistributions in binary form must reproduce the above copyright
|
79
59
|
# notice, this list of conditions and the following disclaimer in
|
80
60
|
# the documentation and/or other materials provided with the
|
81
61
|
# distribution.
|
82
|
-
#
|
62
|
+
#
|
83
63
|
# * Neither the name "SmartyPants" nor the names of its contributors
|
84
64
|
# may be used to endorse or promote products derived from this
|
85
65
|
# software without specific prior written permission.
|
86
|
-
#
|
66
|
+
#
|
87
67
|
# This software is provided by the copyright holders and contributors
|
88
68
|
# "as is" and any express or implied warranties, including, but not
|
89
69
|
# limited to, the implied warranties of merchantability and fitness
|
@@ -96,23 +76,23 @@
|
|
96
76
|
# liability, or tort (including negligence or otherwise) arising in
|
97
77
|
# any way out of the use of this software, even if advised of the
|
98
78
|
# possibility of such damage.
|
99
|
-
#
|
79
|
+
#
|
100
80
|
# === RubyPants license
|
101
|
-
#
|
81
|
+
#
|
102
82
|
# RubyPants is a derivative work of SmartyPants and smartypants.py.
|
103
|
-
#
|
83
|
+
#
|
104
84
|
# Redistribution and use in source and binary forms, with or without
|
105
85
|
# modification, are permitted provided that the following conditions
|
106
86
|
# are met:
|
107
|
-
#
|
87
|
+
#
|
108
88
|
# * Redistributions of source code must retain the above copyright
|
109
89
|
# notice, this list of conditions and the following disclaimer.
|
110
|
-
#
|
90
|
+
#
|
111
91
|
# * Redistributions in binary form must reproduce the above copyright
|
112
92
|
# notice, this list of conditions and the following disclaimer in
|
113
93
|
# the documentation and/or other materials provided with the
|
114
94
|
# distribution.
|
115
|
-
#
|
95
|
+
#
|
116
96
|
# This software is provided by the copyright holders and contributors
|
117
97
|
# "as is" and any express or implied warranties, including, but not
|
118
98
|
# limited to, the implied warranties of merchantability and fitness
|
@@ -125,7 +105,7 @@
|
|
125
105
|
# liability, or tort (including negligence or otherwise) arising in
|
126
106
|
# any way out of the use of this software, even if advised of the
|
127
107
|
# possibility of such damage.
|
128
|
-
#
|
108
|
+
#
|
129
109
|
#
|
130
110
|
# == Links
|
131
111
|
#
|
@@ -137,89 +117,181 @@
|
|
137
117
|
# Christian Neukirchen:: http://kronavita.de/chris
|
138
118
|
|
139
119
|
|
140
|
-
module MaRuKu
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
# note: input will be destroyed
|
192
|
-
def apply_one_rule(reg, subst, input)
|
193
|
-
output = []
|
194
|
-
while first = input.shift
|
195
|
-
if first.kind_of?(String) && (m = reg.match(first))
|
196
|
-
output.push m. pre_match if m. pre_match.size > 0
|
197
|
-
input.unshift m.post_match if m.post_match.size > 0
|
198
|
-
subst.reverse.each do |x|
|
199
|
-
input.unshift( x == :one ? m[1] : md_entity(x.to_s) ) end
|
200
|
-
else
|
201
|
-
output.push first
|
202
|
-
end
|
203
|
-
end
|
204
|
-
return output
|
205
|
-
end
|
206
|
-
|
207
|
-
def educate(elements)
|
208
|
-
Rules.each do |reg, subst|
|
209
|
-
elements = apply_one_rule(reg, subst, elements)
|
210
|
-
end
|
211
|
-
# strips empty strings
|
212
|
-
elements.delete_if {|x| x.kind_of?(String) && x.size == 0}
|
213
|
-
final = []
|
214
|
-
# join consecutive strings
|
215
|
-
elements.each do |x|
|
216
|
-
if x.kind_of?(String) && final.last.kind_of?(String)
|
217
|
-
final.last << x
|
218
|
-
else
|
219
|
-
final << x
|
220
|
-
end
|
221
|
-
end
|
222
|
-
return final
|
223
|
-
end
|
120
|
+
module MaRuKu::In::Markdown::SpanLevelParser
|
121
|
+
Punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
|
122
|
+
Close_class = "[^\ \t\r\n\\[\{\(\-]"
|
123
|
+
|
124
|
+
# A rule to apply a particular pattern (like double quotes)
|
125
|
+
# against a list of strings and MDElements, replacing that
|
126
|
+
# pattern with the smartypants version.
|
127
|
+
class Rule
|
128
|
+
# The pattern to search for
|
129
|
+
attr_accessor :pattern
|
130
|
+
|
131
|
+
# The replacement tokens (entities or other instructions)
|
132
|
+
attr_accessor :replacement
|
133
|
+
|
134
|
+
# This is a hack to allow us to build entities.
|
135
|
+
attr_accessor :doc
|
136
|
+
|
137
|
+
def initialize(pattern, replacement)
|
138
|
+
@pattern = pattern
|
139
|
+
@replacement = replacement
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
# Add something to the output array. If it's
|
145
|
+
# not a string (like an MDElement) just add it direcltly,
|
146
|
+
# otherwise attempt to add on to the last element in the
|
147
|
+
# output if it's a string.
|
148
|
+
def append_to_output(output, str)
|
149
|
+
if !str.kind_of?(String)
|
150
|
+
output << str
|
151
|
+
return
|
152
|
+
end
|
153
|
+
return if str.empty?
|
154
|
+
if output.last.kind_of?(String)
|
155
|
+
output.last << str
|
156
|
+
else
|
157
|
+
output << str
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Simple rule that says "Replace this pattern with these entities"
|
163
|
+
class ReplaceRule < Rule
|
164
|
+
# Replace all matches in the input at once with the
|
165
|
+
# same elements from "replacement".
|
166
|
+
def apply(first, input, output)
|
167
|
+
intersperse(first.split(pattern), replacement).each do |x|
|
168
|
+
append_to_output(output, x)
|
169
|
+
end
|
170
|
+
end
|
224
171
|
|
225
|
-
|
172
|
+
private
|
173
|
+
|
174
|
+
# Sort of like "join" - places the elements in "elem"
|
175
|
+
# between each adjacent element in the array.
|
176
|
+
def intersperse(ary, elem)
|
177
|
+
return ary if ary.length <= 1
|
178
|
+
h, *t = ary
|
179
|
+
t.inject([h]) do |r, e|
|
180
|
+
entities = elem.map do |el|
|
181
|
+
en = el.clone
|
182
|
+
en.doc = doc
|
183
|
+
en
|
184
|
+
end
|
185
|
+
r.concat entities
|
186
|
+
r << e
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# A more complex rule that uses a capture group from the
|
192
|
+
# pattern in its replacement.
|
193
|
+
class CaptureRule < Rule
|
194
|
+
# One at a time, replace each match, including
|
195
|
+
# some part of the match, and put the rest back into
|
196
|
+
# input to be processed next.
|
197
|
+
def apply(first, input, output)
|
198
|
+
if pattern =~ first
|
199
|
+
m = Regexp.last_match
|
200
|
+
append_to_output(output, m.pre_match)
|
201
|
+
input.unshift m.post_match unless m.post_match.empty?
|
202
|
+
replacement.reverse_each do |sub|
|
203
|
+
if sub == :one
|
204
|
+
input.unshift m[1]
|
205
|
+
else
|
206
|
+
entity = sub.clone
|
207
|
+
sub.doc = doc
|
208
|
+
input.unshift entity
|
209
|
+
end
|
210
|
+
end
|
211
|
+
else
|
212
|
+
append_to_output(output, first)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# All the rules that will be applied (in order) to smarten the document.
|
218
|
+
Rules =
|
219
|
+
[
|
220
|
+
['---', :mdash ],
|
221
|
+
['--', :ndash ],
|
222
|
+
['...', :hellip ],
|
223
|
+
['. . .', :hellip ],
|
224
|
+
["``", :ldquo ],
|
225
|
+
["''", :rdquo ],
|
226
|
+
[/<<\s/, [:laquo, :nbsp] ],
|
227
|
+
[/\s>>/, [:nbsp, :raquo] ],
|
228
|
+
['<<', :laquo ],
|
229
|
+
['>>', :raquo ],
|
230
|
+
|
231
|
+
# Special case if the very first character is a quote followed by
|
232
|
+
# punctuation at a non-word-break. Close the quotes by brute
|
233
|
+
# force:
|
234
|
+
[/\A'(?=#{Punct_class}\B)/, :rsquo],
|
235
|
+
[/\A"(?=#{Punct_class}\B)/, :rdquo],
|
236
|
+
# Special case for double sets of quotes, e.g.:
|
237
|
+
# <p>He said, "'Quoted' words in a larger quote."</p>
|
238
|
+
[/"'(?=\w)/, [:ldquo, :lsquo] ],
|
239
|
+
[/'"(?=\w)/, [:lsquo, :ldquo] ],
|
240
|
+
# Special case for decade abbreviations (the '80s):
|
241
|
+
[/'(?=\d\ds)/, :rsquo ],
|
242
|
+
# Get most opening single quotes:
|
243
|
+
[/(\s)'(?=\w)/, [:one, :lsquo] ],
|
244
|
+
# Single closing quotes:
|
245
|
+
[/(#{Close_class})'/, [:one, :rsquo]],
|
246
|
+
[/'(\s|s\b|$)/, [:rsquo, :one]],
|
247
|
+
# Any remaining single quotes should be opening ones:
|
248
|
+
["'", :lsquo],
|
249
|
+
# Get most opening double quotes:
|
250
|
+
[/(\s)"(?=\w)/, [:one, :ldquo]],
|
251
|
+
# Double closing quotes:
|
252
|
+
[/(#{Close_class})"/, [:one, :rdquo]],
|
253
|
+
[/"(\s|s\b|$)/, [:rdquo, :one]],
|
254
|
+
# Any remaining quotes should be opening ones:
|
255
|
+
['"', :ldquo]
|
256
|
+
].
|
257
|
+
map do |reg, subst| # People should do the thinking, machines should do the work.
|
258
|
+
captures = false
|
259
|
+
subst = Array(subst).map do |s|
|
260
|
+
if s == :one
|
261
|
+
captures = true
|
262
|
+
s
|
263
|
+
else
|
264
|
+
MaRuKu::MDElement.new(:entity, [], { :entity_name => s.to_s.freeze }, nil)
|
265
|
+
end
|
266
|
+
end.freeze
|
267
|
+
|
268
|
+
if captures
|
269
|
+
CaptureRule.new reg, subst
|
270
|
+
else
|
271
|
+
ReplaceRule.new reg, subst
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# Fully apply a single rule to an entire array
|
276
|
+
# of elements.
|
277
|
+
# note: input will be modified in place
|
278
|
+
def apply_one_rule!(rule, input)
|
279
|
+
output = []
|
280
|
+
while first = input.shift
|
281
|
+
if first.kind_of?(String)
|
282
|
+
rule.doc = @doc
|
283
|
+
rule.apply(first, input, output)
|
284
|
+
else
|
285
|
+
output << first
|
286
|
+
end
|
287
|
+
end
|
288
|
+
output
|
289
|
+
end
|
290
|
+
|
291
|
+
# Transform elements to have SmartyPants punctuation.
|
292
|
+
def educate(elements)
|
293
|
+
Rules.inject(elements) do |elems, rule|
|
294
|
+
apply_one_rule!(rule, elems)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module MaRuKu
|
2
|
+
class MDElement
|
3
|
+
INSPECT_FORMS = {
|
4
|
+
:paragraph => ["par", :children],
|
5
|
+
:footnote_reference => ["foot_ref", :footnote_id],
|
6
|
+
:entity => ["entity", :entity_name],
|
7
|
+
:email_address => ["email", :email],
|
8
|
+
:inline_code => ["code", :raw_code],
|
9
|
+
:raw_html => ["html", :raw_html],
|
10
|
+
:emphasis => ["em", :children],
|
11
|
+
:strong => ["strong", :children],
|
12
|
+
:immediate_link => ["url", :url],
|
13
|
+
:image => ["image", :children, :ref_id],
|
14
|
+
:im_image => ["im_image", :children, :url, :title],
|
15
|
+
:link => ["link", :children, :ref_id],
|
16
|
+
:im_link => ["im_link", :children, :url, :title],
|
17
|
+
:ref_definition => ["ref_def", :ref_id, :url, :title],
|
18
|
+
:ial => ["ial", :ial],
|
19
|
+
:li => ["li", :children, :want_my_paragraph]
|
20
|
+
}
|
21
|
+
|
22
|
+
# Outputs the document AST as calls to document helpers.
|
23
|
+
# (this should be `eval`-able to get a copy of the original element).
|
24
|
+
def inspect
|
25
|
+
if INSPECT_FORMS.has_key? @node_type
|
26
|
+
name, *params = INSPECT_FORMS[@node_type]
|
27
|
+
|
28
|
+
params = params.map do |p|
|
29
|
+
if p == :children
|
30
|
+
children_inspect
|
31
|
+
else
|
32
|
+
send(p).inspect
|
33
|
+
end
|
34
|
+
end
|
35
|
+
params << @al.inspect if @al && !@al.empty?
|
36
|
+
else
|
37
|
+
name = 'el'
|
38
|
+
params = [self.node_type.inspect, children_inspect]
|
39
|
+
params << @meta_priv.inspect unless @meta_priv.empty? && self.al.empty?
|
40
|
+
params << self.al.inspect unless self.al.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
"md_#{name}(#{params.join(', ')})"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def children_inspect
|
49
|
+
kids = @children.map(&:inspect)
|
50
|
+
return kids.first if kids.size == 1
|
51
|
+
|
52
|
+
comma = kids.join(", ")
|
53
|
+
if comma.size < 70
|
54
|
+
"[#{comma}]"
|
55
|
+
else
|
56
|
+
"[\n\t#{kids.join(",\n\t")}\n]"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|