maruku 0.6.1 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/MIT-LICENSE.txt +20 -0
  5. data/bin/maruku +153 -152
  6. data/bin/marutex +2 -29
  7. data/data/entities.xml +261 -0
  8. data/docs/math.md +14 -18
  9. data/lib/maruku.rb +65 -77
  10. data/lib/maruku/attributes.rb +109 -214
  11. data/lib/maruku/defaults.rb +45 -67
  12. data/lib/maruku/document.rb +43 -0
  13. data/lib/maruku/element.rb +112 -0
  14. data/lib/maruku/errors.rb +71 -0
  15. data/lib/maruku/ext/div.rb +105 -113
  16. data/lib/maruku/ext/fenced_code.rb +97 -0
  17. data/lib/maruku/ext/math.rb +22 -26
  18. data/lib/maruku/ext/math/elements.rb +20 -26
  19. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +92 -104
  20. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +33 -26
  21. data/lib/maruku/ext/math/mathml_engines/none.rb +11 -19
  22. data/lib/maruku/ext/math/mathml_engines/ritex.rb +2 -4
  23. data/lib/maruku/ext/math/parsing.rb +107 -113
  24. data/lib/maruku/ext/math/to_html.rb +184 -187
  25. data/lib/maruku/ext/math/to_latex.rb +30 -21
  26. data/lib/maruku/helpers.rb +158 -257
  27. data/lib/maruku/html.rb +254 -0
  28. data/lib/maruku/input/charsource.rb +272 -319
  29. data/lib/maruku/input/extensions.rb +62 -63
  30. data/lib/maruku/input/html_helper.rb +220 -189
  31. data/lib/maruku/input/linesource.rb +90 -110
  32. data/lib/maruku/input/mdline.rb +129 -0
  33. data/lib/maruku/input/parse_block.rb +618 -612
  34. data/lib/maruku/input/parse_doc.rb +145 -215
  35. data/lib/maruku/input/parse_span.rb +658 -0
  36. data/lib/maruku/input/rubypants.rb +200 -128
  37. data/lib/maruku/inspect_element.rb +60 -0
  38. data/lib/maruku/maruku.rb +10 -31
  39. data/lib/maruku/output/entity_table.rb +33 -0
  40. data/lib/maruku/output/s5/fancy.rb +462 -462
  41. data/lib/maruku/output/s5/to_s5.rb +115 -135
  42. data/lib/maruku/output/to_html.rb +898 -983
  43. data/lib/maruku/output/to_latex.rb +561 -560
  44. data/lib/maruku/output/to_markdown.rb +207 -162
  45. data/lib/maruku/output/to_s.rb +11 -52
  46. data/lib/maruku/string_utils.rb +129 -179
  47. data/lib/maruku/toc.rb +185 -196
  48. data/lib/maruku/version.rb +33 -38
  49. data/spec/block_docs/abbrev.md +776 -0
  50. data/{tests/unittest → spec/block_docs}/abbreviations.md +11 -20
  51. data/{tests/unittest → spec/block_docs}/alt.md +2 -14
  52. data/{tests/unittest/pending → spec/block_docs}/amps.md +1 -13
  53. data/{tests/unittest → spec/block_docs}/attributes/att2.md +0 -12
  54. data/{tests/unittest → spec/block_docs}/attributes/att3.md +2 -14
  55. data/{tests/unittest → spec/block_docs}/attributes/attributes.md +12 -16
  56. data/{tests/unittest → spec/block_docs}/attributes/circular.md +0 -12
  57. data/{tests/unittest → spec/block_docs}/attributes/default.md +1 -13
  58. data/{tests/unittest → spec/block_docs}/blank.md +0 -12
  59. data/{tests/unittest → spec/block_docs}/blanks_in_code.md +16 -15
  60. data/{tests/unittest/loss.md → spec/block_docs/bug_def.md} +6 -18
  61. data/{tests/unittest → spec/block_docs}/bug_table.md +3 -15
  62. data/{tests/unittest → spec/block_docs}/code.md +7 -14
  63. data/{tests/unittest → spec/block_docs}/code2.md +4 -14
  64. data/{tests/unittest → spec/block_docs}/code3.md +12 -16
  65. data/{tests/unittest → spec/block_docs}/data_loss.md +2 -14
  66. data/{tests/unittest → spec/block_docs}/divs/div1.md +0 -12
  67. data/{tests/unittest → spec/block_docs}/divs/div2.md +0 -12
  68. data/{tests/unittest → spec/block_docs}/divs/div3_nest.md +3 -15
  69. data/{tests/unittest → spec/block_docs}/easy.md +1 -13
  70. data/spec/block_docs/email.md +29 -0
  71. data/{tests/unittest/pending → spec/block_docs}/empty_cells.md +3 -15
  72. data/{tests/unittest → spec/block_docs}/encoding/iso-8859-1.md +1 -14
  73. data/{tests/unittest → spec/block_docs}/encoding/utf-8.md +0 -12
  74. data/{tests/unittest → spec/block_docs}/entities.md +27 -29
  75. data/{tests/unittest/notyet → spec/block_docs}/escape.md +2 -14
  76. data/{tests/unittest → spec/block_docs}/escaping.md +11 -22
  77. data/{tests/unittest → spec/block_docs}/extra_dl.md +2 -13
  78. data/{tests/unittest → spec/block_docs}/extra_header_id.md +14 -20
  79. data/{tests/unittest → spec/block_docs}/extra_table1.md +3 -15
  80. data/spec/block_docs/fenced_code_blocks.md +66 -0
  81. data/spec/block_docs/fenced_code_blocks_highlighted.md +18 -0
  82. data/{tests/unittest → spec/block_docs}/footnotes.md +12 -24
  83. data/spec/block_docs/footnotes2.md +78 -0
  84. data/spec/block_docs/hard.md +25 -0
  85. data/spec/block_docs/header_after_par.md +62 -0
  86. data/{tests/unittest → spec/block_docs}/headers.md +10 -18
  87. data/{tests/unittest → spec/block_docs}/hex_entities.md +7 -18
  88. data/{tests/unittest → spec/block_docs}/hrule.md +5 -12
  89. data/{tests/unittest → spec/block_docs}/html3.md +1 -13
  90. data/{tests/unittest → spec/block_docs}/html4.md +2 -14
  91. data/{tests/unittest → spec/block_docs}/html5.md +2 -14
  92. data/spec/block_docs/html_block_in_para.md +22 -0
  93. data/spec/block_docs/html_inline.md +25 -0
  94. data/spec/block_docs/html_trailing.md +31 -0
  95. data/spec/block_docs/ie.md +62 -0
  96. data/spec/block_docs/iframe.md +29 -0
  97. data/{tests/unittest → spec/block_docs}/images.md +22 -28
  98. data/{tests/unittest → spec/block_docs}/images2.md +7 -17
  99. data/{tests/unittest → spec/block_docs}/inline_html.md +37 -67
  100. data/{tests/unittest → spec/block_docs}/inline_html2.md +1 -13
  101. data/spec/block_docs/inline_html_beginning.md +10 -0
  102. data/spec/block_docs/issue20.md +9 -0
  103. data/spec/block_docs/issue26.md +22 -0
  104. data/spec/block_docs/issue29.md +9 -0
  105. data/spec/block_docs/issue30.md +30 -0
  106. data/spec/block_docs/issue31.md +25 -0
  107. data/spec/block_docs/issue40.md +40 -0
  108. data/spec/block_docs/issue64.md +55 -0
  109. data/spec/block_docs/issue67.md +19 -0
  110. data/spec/block_docs/issue70.md +11 -0
  111. data/spec/block_docs/issue72.md +17 -0
  112. data/spec/block_docs/issue74.md +38 -0
  113. data/spec/block_docs/issue79.md +15 -0
  114. data/spec/block_docs/issue83.md +13 -0
  115. data/spec/block_docs/issue85.md +25 -0
  116. data/spec/block_docs/issue88.md +19 -0
  117. data/spec/block_docs/issue89.md +12 -0
  118. data/spec/block_docs/issue90.md +38 -0
  119. data/{tests/unittest/pending → spec/block_docs}/link.md +21 -18
  120. data/{tests/unittest → spec/block_docs}/links.md +33 -32
  121. data/spec/block_docs/links2.md +21 -0
  122. data/{tests/unittest → spec/block_docs}/list1.md +0 -12
  123. data/{tests/unittest → spec/block_docs}/list12.md +2 -14
  124. data/{tests/unittest → spec/block_docs}/list2.md +2 -14
  125. data/spec/block_docs/list_multipara.md +42 -0
  126. data/{tests/unittest → spec/block_docs}/lists.md +28 -29
  127. data/{tests/unittest → spec/block_docs}/lists10.md +2 -14
  128. data/spec/block_docs/lists11.md +23 -0
  129. data/spec/block_docs/lists12.md +43 -0
  130. data/spec/block_docs/lists13.md +55 -0
  131. data/spec/block_docs/lists14.md +61 -0
  132. data/spec/block_docs/lists15.md +36 -0
  133. data/spec/block_docs/lists6.md +88 -0
  134. data/spec/block_docs/lists7b.md +58 -0
  135. data/spec/block_docs/lists9.md +53 -0
  136. data/{tests/unittest → spec/block_docs}/lists_after_paragraph.md +19 -25
  137. data/spec/block_docs/lists_blank.md +35 -0
  138. data/{tests/unittest/list3.md → spec/block_docs/lists_blockquote_code.md} +2 -14
  139. data/{tests/unittest/list4.md → spec/block_docs/lists_need_blank_line.md} +50 -21
  140. data/spec/block_docs/lists_nested.md +44 -0
  141. data/spec/block_docs/lists_nested_blankline.md +28 -0
  142. data/spec/block_docs/lists_nested_deep.md +43 -0
  143. data/{tests/unittest → spec/block_docs}/lists_ol.md +37 -54
  144. data/spec/block_docs/lists_paraindent.md +47 -0
  145. data/spec/block_docs/lists_tab.md +54 -0
  146. data/spec/block_docs/loss.md +17 -0
  147. data/spec/block_docs/math-blahtex/equations.md +30 -0
  148. data/spec/block_docs/math-blahtex/inline.md +48 -0
  149. data/spec/block_docs/math-blahtex/math2.md +45 -0
  150. data/spec/block_docs/math-blahtex/table.md +25 -0
  151. data/spec/block_docs/math/embedded_invalid_svg.md +79 -0
  152. data/spec/block_docs/math/embedded_svg.md +97 -0
  153. data/spec/block_docs/math/equations.md +44 -0
  154. data/{tests/unittest → spec/block_docs}/math/inline.md +7 -19
  155. data/spec/block_docs/math/math2.md +45 -0
  156. data/{tests/unittest → spec/block_docs}/math/notmath.md +0 -12
  157. data/spec/block_docs/math/raw_mathml.md +87 -0
  158. data/spec/block_docs/math/table.md +25 -0
  159. data/{tests/unittest → spec/block_docs}/math/table2.md +5 -17
  160. data/{tests/unittest → spec/block_docs}/misc_sw.md +181 -118
  161. data/{tests/unittest → spec/block_docs}/olist.md +6 -18
  162. data/{tests/unittest → spec/block_docs}/one.md +0 -12
  163. data/{tests/unittest → spec/block_docs}/paragraph.md +0 -12
  164. data/{tests/unittest → spec/block_docs}/paragraph_rules/dont_merge_ref.md +4 -12
  165. data/{tests/unittest → spec/block_docs}/paragraph_rules/tab_is_blank.md +0 -12
  166. data/{tests/unittest → spec/block_docs}/paragraphs.md +1 -13
  167. data/{tests/unittest → spec/block_docs}/recover/recover_links.md +4 -16
  168. data/{tests/unittest/pending/ref.md → spec/block_docs/ref_with_period.md} +7 -16
  169. data/spec/block_docs/ref_with_title.md +22 -0
  170. data/{tests/unittest → spec/block_docs}/references/long_example.md +16 -23
  171. data/{tests/unittest → spec/block_docs}/references/spaces_and_numbers.md +0 -12
  172. data/{tests/unittest → spec/block_docs}/smartypants.md +24 -31
  173. data/{tests/unittest → spec/block_docs}/syntax_hl.md +13 -17
  174. data/{tests/unittest → spec/block_docs}/table_attributes.md +2 -14
  175. data/spec/block_docs/tables.md +58 -0
  176. data/{tests/unittest → spec/block_docs}/test.md +1 -13
  177. data/{tests/unittest/notyet → spec/block_docs}/ticks.md +1 -13
  178. data/spec/block_docs/toc.md +87 -0
  179. data/{tests/unittest/notyet → spec/block_docs}/triggering.md +14 -25
  180. data/{tests/unittest → spec/block_docs}/underscore_in_words.md +0 -12
  181. data/{tests/unittest → spec/block_docs}/wrapping.md +4 -16
  182. data/spec/block_docs/xml.md +33 -0
  183. data/{tests/unittest → spec/block_docs}/xml2.md +0 -12
  184. data/spec/block_docs/xml3.md +24 -0
  185. data/{tests/unittest → spec/block_docs}/xml_instruction.md +9 -20
  186. data/spec/block_spec.rb +110 -0
  187. data/spec/cli_spec.rb +8 -0
  188. data/spec/span_spec.rb +256 -0
  189. data/spec/spec_helper.rb +2 -0
  190. data/spec/to_html_utf8_spec.rb +13 -0
  191. metadata +205 -243
  192. metadata.gz.sig +3 -0
  193. data/Rakefile +0 -48
  194. data/bin/marudown +0 -29
  195. data/bin/marutest +0 -345
  196. data/docs/changelog.md +0 -334
  197. data/lib/maruku/errors_management.rb +0 -92
  198. data/lib/maruku/ext/math/latex_fix.rb +0 -12
  199. data/lib/maruku/input/parse_span_better.rb +0 -746
  200. data/lib/maruku/input/type_detection.rb +0 -147
  201. data/lib/maruku/output/to_latex_entities.rb +0 -367
  202. data/lib/maruku/output/to_latex_strings.rb +0 -64
  203. data/lib/maruku/structures.rb +0 -167
  204. data/lib/maruku/structures_inspect.rb +0 -87
  205. data/lib/maruku/structures_iterators.rb +0 -61
  206. data/lib/maruku/tests/benchmark.rb +0 -82
  207. data/lib/maruku/tests/new_parser.rb +0 -373
  208. data/lib/maruku/tests/tests.rb +0 -136
  209. data/lib/maruku/usage/example1.rb +0 -33
  210. data/tests/bugs/code_in_links.md +0 -101
  211. data/tests/bugs/complex_escaping.md +0 -38
  212. data/tests/math/syntax.md +0 -46
  213. data/tests/math_usage/document.md +0 -13
  214. data/tests/others/abbreviations.md +0 -11
  215. data/tests/others/blank.md +0 -4
  216. data/tests/others/code.md +0 -5
  217. data/tests/others/code2.md +0 -8
  218. data/tests/others/code3.md +0 -16
  219. data/tests/others/email.md +0 -4
  220. data/tests/others/entities.md +0 -19
  221. data/tests/others/escaping.md +0 -16
  222. data/tests/others/extra_dl.md +0 -101
  223. data/tests/others/extra_header_id.md +0 -13
  224. data/tests/others/extra_table1.md +0 -40
  225. data/tests/others/footnotes.md +0 -17
  226. data/tests/others/headers.md +0 -10
  227. data/tests/others/hrule.md +0 -10
  228. data/tests/others/images.md +0 -20
  229. data/tests/others/inline_html.md +0 -42
  230. data/tests/others/links.md +0 -38
  231. data/tests/others/list1.md +0 -4
  232. data/tests/others/list2.md +0 -5
  233. data/tests/others/list3.md +0 -8
  234. data/tests/others/lists.md +0 -32
  235. data/tests/others/lists_after_paragraph.md +0 -44
  236. data/tests/others/lists_ol.md +0 -39
  237. data/tests/others/misc_sw.md +0 -105
  238. data/tests/others/one.md +0 -1
  239. data/tests/others/paragraphs.md +0 -13
  240. data/tests/others/sss06.md +0 -352
  241. data/tests/others/test.md +0 -4
  242. data/tests/s5/s5profiling.md +0 -48
  243. data/tests/unittest/bug_def.md +0 -28
  244. data/tests/unittest/email.md +0 -32
  245. data/tests/unittest/html2.md +0 -34
  246. data/tests/unittest/ie.md +0 -61
  247. data/tests/unittest/links2.md +0 -34
  248. data/tests/unittest/lists11.md +0 -28
  249. data/tests/unittest/lists6.md +0 -53
  250. data/tests/unittest/lists9.md +0 -76
  251. data/tests/unittest/math/equations.md +0 -86
  252. data/tests/unittest/math/math2.md +0 -57
  253. data/tests/unittest/math/table.md +0 -37
  254. data/tests/unittest/notyet/header_after_par.md +0 -70
  255. data/tests/unittest/red_tests/abbrev.md +0 -1388
  256. data/tests/unittest/red_tests/lists7.md +0 -68
  257. data/tests/unittest/red_tests/lists7b.md +0 -128
  258. data/tests/unittest/red_tests/lists8.md +0 -76
  259. data/tests/unittest/red_tests/xml.md +0 -70
  260. data/tests/unittest/xml3.md +0 -38
  261. data/tests/utf8-files/simple.md +0 -1
  262. data/unit_test_block.sh +0 -5
  263. data/unit_test_span.sh +0 -3
@@ -1,33 +1,13 @@
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
- # 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 GPL, which I guess is compatible
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; module In; module Markdown; module SpanLevelParser
141
- Punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
142
- Close_class = %![^\ \t\r\n\\[\{\(\-]!
143
-
144
- Rules = [
145
- [/---/, :mdash ],
146
- [/--/, :ndash ],
147
- ['...', :hellip ],
148
- ['. . .', :hellip ],
149
- ["``", :ldquo ],
150
- ["''", :rdquo ],
151
- [/<<\s/, [:laquo, :nbsp] ],
152
- [/\s>>/, [:nbsp, :raquo] ],
153
- [/<</, :laquo ],
154
- [/>>/, :raquo ],
155
-
156
- # def educate_single_backticks(str)
157
- # ["`", :lsquo]
158
- # ["'", :rsquo]
159
-
160
- # Special case if the very first character is a quote followed by
161
- # punctuation at a non-word-break. Close the quotes by brute
162
- # force:
163
- [/^'(?=#{Punct_class}\B)/, :rsquo],
164
- [/^"(?=#{Punct_class}\B)/, :rdquo],
165
- # Special case for double sets of quotes, e.g.:
166
- # <p>He said, "'Quoted' words in a larger quote."</p>
167
- [/"'(?=\w)/, [:ldquo, :lsquo] ],
168
- [/'"(?=\w)/, [:lsquo, :ldquo] ],
169
- # Special case for decade abbreviations (the '80s):
170
- [/'(?=\d\ds)/, :rsquo ],
171
- # Get most opening single quotes:
172
- [/(\s)'(?=\w)/, [:one, :lsquo] ],
173
- # Single closing quotes:
174
- [/(#{Close_class})'/, [:one, :rsquo]],
175
- [/'(\s|s\b|$)/, [:rsquo, :one]],
176
- # Any remaining single quotes should be opening ones:
177
- [/'/, :lsquo],
178
- # Get most opening double quotes:
179
- [/(\s)"(?=\w)/, [:one, :ldquo]],
180
- # Double closing quotes:
181
- [/(#{Close_class})"/, [:one, :rdquo]],
182
- [/"(\s|s\b|$)/, [:rdquo, :one]],
183
- # Any remaining quotes should be opening ones:
184
- [/"/, :ldquo]
185
- ].
186
- map{|reg, subst| # People should do the thinking, machines should do the work.
187
- reg = Regexp.new(Regexp.escape(reg)) if not reg.kind_of? Regexp
188
- subst = [subst] if not subst.kind_of?Array
189
- [reg, subst]}
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
- end end end end
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