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.
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,164 +1,209 @@
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
- class String
23
- # XXX: markdown escaping
24
- def to_md(c=nil)
25
- to_s
26
- end
27
-
28
- # " andrea censi " => [" andrea ", "censi "]
29
- def mysplit
30
- split.map{|x| x+" "}
31
- end
32
- end
1
+ module MaRuKu::Out::Markdown
2
+
3
+ DefaultLineLength = 40
4
+
5
+ def to_md(context={})
6
+ children_to_md(context)
7
+ end
8
+
9
+ # " andrea censi " => [" andrea ", "censi "]
10
+ def mysplit(c)
11
+ res = c.split.map {|x| x + " " }
12
+ if c[0] == ' ' && res[0]
13
+ res[0] = " " + res[0]
14
+ end
15
+ res
16
+ end
17
+
18
+ def to_md_header(context)
19
+ pounds = "#" * @level
20
+ "#{pounds} #{children_to_md(context)} #{pounds}\n\n"
21
+ end
22
+
23
+ def to_md_inline_code(context)
24
+ "`#{@raw_code}`"
25
+ end
26
+
27
+ def to_md_code(context)
28
+ @raw_code.split("\n").collect { |line| " " + line}.join("\n") + "\n\n"
29
+ end
30
+
31
+ def to_md_quote(context)
32
+ line_length = (context[:line_length] || DefaultLineLength) - 2
33
+ wrap(@children, line_length, context).split(/\n/).collect { |line| "> " + line}.join("\n") + "\n"
34
+ end
35
+
36
+ def to_md_hrule(context)
37
+ "* * *\n"
38
+ end
39
+
40
+ def to_md_emphasis(context)
41
+ "*#{children_to_md(context)}*"
42
+ end
43
+
44
+ def to_md_strong(context)
45
+ "**#{children_to_md(context)}**"
46
+ end
47
+
48
+ def to_md_immediate_link(context)
49
+ "<#{@url}>"
50
+ end
51
+
52
+ def to_md_email_address(context)
53
+ "<#{@email}>"
54
+ end
55
+
56
+ def to_md_entity(context)
57
+ "&#{@entity_name};"
58
+ end
59
+
60
+ def to_md_linebreak(context)
61
+ "\n"
62
+ end
63
+
64
+ def to_md_paragraph(context)
65
+ line_length = context[:line_length] || DefaultLineLength
66
+ wrap(@children, line_length, context)+"\n"
67
+ end
68
+
69
+ def to_md_im_link(context)
70
+ "[#{children_to_md(context)}](#{@url}#{" \"#{@title}\"" if @title})"
71
+ end
72
+
73
+ def to_md_link(context)
74
+ "[#{children_to_md(context)}][#{@ref_id}]"
75
+ end
76
+
77
+ def to_md_im_image(context)
78
+ "![#{children_to_md(context)}](#{@url}#{" \"#{@title}\"" if @title})"
79
+ end
33
80
 
81
+ def to_md_image(context)
82
+ "![#{children_to_md(context)}][#{@ref_id}]"
83
+ end
34
84
 
35
- module MaRuKu; module Out; module Markdown
36
-
37
- DefaultLineLength = 40
38
-
39
- def to_md(context={})
40
- children_to_md(context)
41
- end
42
-
43
- def to_md_paragraph(context)
44
- line_length = context[:line_length] || DefaultLineLength
45
- wrap(@children, line_length, context)+"\n"
46
- end
47
-
48
- def to_md_li_span(context)
49
- len = (context[:line_length] || DefaultLineLength) - 2
50
- s = add_tabs(wrap(@children, len-2, context), 1, ' ')
51
- s[0] = ?*
52
- s + "\n"
53
- end
54
-
55
- def to_md_abbr_def(context)
56
- "*[#{self.abbr}]: #{self.text}\n"
57
- end
58
-
59
- def to_md_ol(context)
60
- len = (context[:line_length] || DefaultLineLength) - 2
61
- md = ""
62
- self.children.each_with_index do |li, i|
63
- s = add_tabs(w=wrap(li.children, len-2, context), 1, ' ')+"\n"
64
- s[0,4] = "#{i+1}. "[0,4]
65
- # puts w.inspect
66
- md += s
67
- end
68
- md + "\n"
69
- end
70
-
71
- def to_md_ul(context)
72
- len = (context[:line_length] || DefaultLineLength) - 2
73
- md = ""
74
- self.children.each_with_index do |li, i|
75
- w = wrap(li.children, len-2, context)
76
- # puts "W: "+ w.inspect
77
- s = add_indent(w)
78
- # puts "S: " +s.inspect
79
- s[0,1] = "-"
80
- md += s
81
- end
82
- md + "\n"
83
- end
84
-
85
- def add_indent(s,char=" ")
86
- t = s.split("\n").map{|x| char+x }.join("\n")
87
- s << ?\n if t[-1] == ?\n
88
- s
89
- end
90
-
91
- # Convert each child to html
92
- def children_to_md(context)
93
- array_to_md(@children, context)
94
- end
95
-
96
- def wrap(array, line_length, context)
97
- out = ""
98
- line = ""
99
- array.each do |c|
100
- if c.kind_of?(MDElement) && c.node_type == :linebreak
101
- out << line.strip << " \n"; line="";
102
- next
103
- end
104
-
105
- pieces =
106
- if c.kind_of? String
107
- c.to_md.mysplit
108
- else
109
- [c.to_md(context)].flatten
110
- end
111
-
112
- # puts "Pieces: #{pieces.inspect}"
113
- pieces.each do |p|
114
- if p.size + line.size > line_length
115
- out << line.strip << "\n";
116
- line = ""
117
- end
118
- line << p
119
- end
120
- end
121
- out << line.strip << "\n" if line.size > 0
122
- out << ?\n if not out[-1] == ?\n
123
- out
124
- end
125
-
126
-
127
- def array_to_md(array, context, join_char='')
128
- e = []
129
- array.each do |c|
130
- method = c.kind_of?(MDElement) ?
131
- "to_md_#{c.node_type}" : "to_md"
132
-
133
- if not c.respond_to?(method)
134
- #raise "Object does not answer to #{method}: #{c.class} #{c.inspect[0,100]}"
135
- # tell_user "Using default for #{c.node_type}"
136
- method = 'to_md'
137
- end
138
-
139
- # puts "#{c.inspect} created with method #{method}"
140
- h = c.send(method, context)
141
-
142
- if h.nil?
143
- raise "Nil md for #{c.inspect} created with method #{method}"
144
- end
145
-
146
- if h.kind_of?Array
147
- e = e + h
148
- else
149
- e << h
150
- end
151
- end
152
- e.join(join_char)
153
- end
154
-
155
- end end end
156
-
157
- module MaRuKu; class MDDocument
158
- alias old_md to_md
159
- def to_md(context={})
160
- s = old_md(context)
161
- # puts s
162
- s
163
- end
164
- end end
85
+ def to_md_ref_definition(context)
86
+ "[#{@ref_id}] #{@url}#{" \"#{@title}\"" if @title}"
87
+ end
88
+
89
+ def to_md_abbr_def(context)
90
+ "*[#{self.abbr}]: #{self.text}\n"
91
+ end
92
+
93
+ def to_md_ol(context)
94
+ len = (context[:line_length] || DefaultLineLength) - 2
95
+ md = ""
96
+ self.children.each_with_index do |li, i|
97
+ # s = (w=wrap(li.children, len-2, context)).rstrip.gsub(/^/, ' ')+"\n"
98
+ # s[0,4] = "#{i+1}. "[0,4]
99
+ # puts w.inspect
100
+ s = "#{i+1}. " + wrap(li.children, len-2, context).rstrip + "\n"
101
+ md += s
102
+ end
103
+ md + "\n"
104
+ end
105
+
106
+ def to_md_ul(context)
107
+ len = (context[:line_length] || DefaultLineLength) - 2
108
+ md = ""
109
+ self.children.each_with_index do |li, i|
110
+ w = wrap(li.children, len-2, context)
111
+ s = "- " + w
112
+ # puts "W: "+ w.inspect
113
+ # s = add_indent(w)
114
+ # puts "S: " +s.inspect
115
+ # s[0,1] = "-"
116
+ md += s
117
+ end
118
+ md + "\n"
119
+ end
120
+
121
+ def add_indent(s,char=" ")
122
+ t = s.split("\n").map{|x| char+x }.join("\n")
123
+ s << ?\n if t[-1] == ?\n
124
+ s
125
+ end
126
+
127
+ # Convert each child to html
128
+ def children_to_md(context)
129
+ array_to_md(@children, context)
130
+ end
131
+
132
+ def wrap(array, line_length, context)
133
+ out = ""
134
+ line = ""
135
+ array.each do |c|
136
+ if c.kind_of?(MaRuKu::MDElement) && c.node_type == :linebreak
137
+ out << line.strip << " \n"; line="";
138
+ next
139
+ end
140
+
141
+ pieces =
142
+ if c.kind_of? String
143
+ mysplit(c)
144
+ elsif c.kind_of?(MaRuKu::MDElement)
145
+ method = "to_md_#{c.node_type}"
146
+ method = "to_md" unless c.respond_to?(method)
147
+ [c.send(method, context)].flatten
148
+ else
149
+ [c.to_md(context)].flatten
150
+ end
151
+
152
+ # puts "Pieces: #{pieces.inspect}"
153
+ pieces.each do |p|
154
+ if p.size + line.size > line_length
155
+ out << line.strip << "\n";
156
+ line = ""
157
+ end
158
+ line << p
159
+ end
160
+ end
161
+ out << line.strip << "\n" if line.size > 0
162
+ out << ?\n if not out[-1] == ?\n
163
+ out
164
+ end
165
+
166
+
167
+ def array_to_md(array, context, join_char='')
168
+ e = []
169
+ array.each do |c|
170
+ if c.is_a?(String)
171
+ e << c
172
+ else
173
+ method = c.kind_of?(MaRuKu::MDElement) ?
174
+ "to_md_#{c.node_type}" : "to_md"
175
+
176
+ if not c.respond_to?(method)
177
+ #raise "Object does not answer to #{method}: #{c.class} #{c.inspect[0,100]}"
178
+ # tell_user "Using default for #{c.node_type}"
179
+ method = 'to_md'
180
+ end
181
+
182
+ # puts "#{c.inspect} created with method #{method}"
183
+ h = c.send(method, context)
184
+
185
+ if h.nil?
186
+ raise "Nil md for #{c.inspect} created with method #{method}"
187
+ end
188
+
189
+ if h.kind_of?Array
190
+ e = e + h
191
+ else
192
+ e << h
193
+ end
194
+ end
195
+ end
196
+ e.join(join_char)
197
+ end
198
+
199
+ end
200
+
201
+ module MaRuKu
202
+ class MDDocument
203
+ alias old_md to_md
204
+ def to_md(context={})
205
+ warn "Maruku#to_md is deprecated and will be removed in a near-future version of Maruku."
206
+ old_md(context)
207
+ end
208
+ end
209
+ end
@@ -1,56 +1,15 @@
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
1
  module MaRuKu
23
-
24
- class MDElement
25
-
26
- # Strips all formatting from the string
27
- def to_s
28
- children_to_s
29
- end
30
-
31
- def children_to_s
32
- @children.join
33
- end
34
-
35
- # Generate an id for headers. Assumes @children is set.
36
- def generate_id
37
-
38
- title = children_to_s
39
- title.gsub!(/ /,'_')
40
- title.downcase!
41
- title.gsub!(/[^\w_]/,'')
42
- title.strip!
43
-
44
- if title.size == 0
45
- $uid ||= 0
46
- $uid += 1
47
- title = "id#{$uid}"
48
- end
49
2
 
50
- # random is a very bad idea
51
- # title << "_" + rand(10000).to_s
52
- title
53
- end
54
- end
3
+ class MDElement
4
+
5
+ # Strips all formatting from the string
6
+ def to_s
7
+ warn "Maruku#to_s is deprecated and will be removed or changed in a near-future version of Maruku."
8
+ children_to_s
9
+ end
55
10
 
11
+ def children_to_s
12
+ @children.join
13
+ end
14
+ end
56
15
  end
@@ -1,191 +1,141 @@
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
- #++
1
+ require 'strscan'
20
2
 
3
+ module MaRuKu
4
+ # Utility functions for dealing with strings.
5
+ module Strings
6
+ TAB_SIZE = 4
21
7
 
22
- # Boring stuff with strings.
23
- module MaRuKu; module Strings
24
-
25
- def add_tabs(s,n=1,char="\t")
26
- s.split("\n").map{|x| char*n+x }.join("\n")
27
- end
28
-
29
- TabSize = 4;
30
-
31
- def split_lines(s)
32
- s.gsub("\r","").split("\n")
33
- end
34
-
35
- # This parses email headers. Returns an hash.
36
- #
37
- # +hash['data']+ is the message.
38
- #
39
- # Keys are downcased, space becomes underscore, converted to symbols.
40
- #
41
- # My key: true
42
- #
43
- # becomes:
44
- #
45
- # {:my_key => true}
46
- #
47
- def parse_email_headers(s)
48
- keys={}
49
- match = (s =~ /\A((\w[\w\s\_\-]+: .*\n)+)\s*\n/)
50
- if match != 0
51
- keys[:data] = s
52
- else
53
- keys[:data] = $'
54
- headers = $1
55
- headers.split("\n").each do |l|
56
- # Fails if there are other ':' characters.
57
- # k, v = l.split(':')
58
- k, v = l.split(':', 2)
59
- k, v = normalize_key_and_value(k, v)
60
- k = k.to_sym
61
- # puts "K = #{k}, V=#{v}"
62
- keys[k] = v
63
- end
64
- end
65
- keys
66
- end
8
+ # Split a string into multiple lines,
9
+ # on line feeds and/or carriage returns.
10
+ #
11
+ # @param s [String]
12
+ # @return [String]
13
+ def split_lines(s)
14
+ s.split(/\r\n|\r|\n/)
15
+ end
67
16
 
68
- # Keys are downcased, space becomes underscore, converted to symbols.
69
- def normalize_key_and_value(k,v)
70
- v = v ? v.strip : true # no value defaults to true
71
- k = k.strip
72
-
73
- # check synonyms
74
- v = true if ['yes','true'].include?(v.to_s.downcase)
75
- v = false if ['no','false'].include?(v.to_s.downcase)
76
-
77
- k = k.downcase.gsub(' ','_')
78
- return k, v
79
- end
80
-
81
- # Returns the number of leading spaces, considering that
82
- # a tab counts as `TabSize` spaces.
83
- def number_of_leading_spaces(s)
84
- n=0; i=0;
85
- while i < s.size
86
- c = s[i,1]
87
- if c == ' '
88
- i+=1; n+=1;
89
- elsif c == "\t"
90
- i+=1; n+=TabSize;
91
- else
92
- break
93
- end
94
- end
95
- n
96
- end
17
+ # Parses email headers, returning a hash.
18
+ # `hash[:data]` is the message;
19
+ # that is, anything past the headers.
20
+ #
21
+ # Keys are downcased and converted to symbols;
22
+ # spaces become underscores. For example:
23
+ #
24
+ # !!!plain
25
+ # My key: true
26
+ #
27
+ # becomes:
28
+ #
29
+ # {:my_key => true}
30
+ #
31
+ # @param s [String] The email
32
+ # @return [Symbol => String] The header values
33
+ def parse_email_headers(s)
34
+ headers = {}
35
+ scanner = StringScanner.new(s)
97
36
 
98
- # This returns the position of the first real char in a list item
99
- #
100
- # For example:
101
- # '*Hello' # => 1
102
- # '* Hello' # => 2
103
- # ' * Hello' # => 3
104
- # ' * Hello' # => 5
105
- # '1.Hello' # => 2
106
- # ' 1. Hello' # => 5
107
-
108
- def spaces_before_first_char(s)
109
- case s.md_type
110
- when :ulist
111
- i=0;
112
- # skip whitespace if present
113
- while s[i,1] =~ /\s/; i+=1 end
114
- # skip indicator (+, -, *)
115
- i+=1
116
- # skip optional whitespace
117
- while s[i,1] =~ /\s/; i+=1 end
118
- return i
119
- when :olist
120
- i=0;
121
- # skip whitespace
122
- while s[i,1] =~ /\s/; i+=1 end
123
- # skip digits
124
- while s[i,1] =~ /\d/; i+=1 end
125
- # skip dot
126
- i+=1
127
- # skip whitespace
128
- while s[i,1] =~ /\s/; i+=1 end
129
- return i
130
- else
131
- tell_user "BUG (my bad): '#{s}' is not a list"
132
- 0
133
- end
134
- end
37
+ while scanner.scan(/(\w[\w\s\-]+): +(.*)\n/)
38
+ k, v = normalize_key_and_value(scanner[1], scanner[2])
39
+ headers[k.to_sym] = v
40
+ end
135
41
 
136
- # Counts the number of leading '#' in the string
137
- def num_leading_hashes(s)
138
- i=0;
139
- while i<(s.size-1) && (s[i,1]=='#'); i+=1 end
140
- i
141
- end
142
-
143
- # Strips initial and final hashes
144
- def strip_hashes(s)
145
- s = s[num_leading_hashes(s), s.size]
146
- i = s.size-1
147
- while i > 0 && (s[i,1] =~ /(#|\s)/); i-=1; end
148
- s[0, i+1].strip
149
- end
150
-
151
- # change space to "_" and remove any non-word character
152
- def sanitize_ref_id(x)
153
- x.strip.downcase.gsub(' ','_').gsub(/[^\w]/,'')
154
- end
42
+ headers[:data] = scanner.rest
43
+ headers
44
+ end
155
45
 
46
+ # This returns the position of the first non-list character
47
+ # in a list item.
48
+ #
49
+ # @example
50
+ # spaces_before_first_char('*Hello') #=> 1
51
+ # spaces_before_first_char('* Hello') #=> 2
52
+ # spaces_before_first_char(' * Hello') #=> 3
53
+ # spaces_before_first_char(' * Hello') #=> 5
54
+ # spaces_before_first_char('1.Hello') #=> 2
55
+ # spaces_before_first_char(' 1. Hello') #=> 5
56
+ #
57
+ # @param s [String]
58
+ # @return [Fixnum]
59
+ def spaces_before_first_char(s)
60
+ match =
61
+ case s.md_type
62
+ when :ulist
63
+ # whitespace, followed by ('*'|'+'|'-') followed by
64
+ # more whitespace, followed by an optional IAL, followed
65
+ # by yet more whitespace
66
+ s[/^\s*(\*|\+|\-)\s*(\{[:#\.].*?\})?\s*/]
67
+ when :olist
68
+ # whitespace, followed by a number, followed by a period,
69
+ # more whitespace, an optional IAL, and more whitespace
70
+ s[/^\s*\d+\.\s*(\{[:#\.].*?\})?\s*/]
71
+ else
72
+ tell_user "BUG (my bad): '#{s}' is not a list"
73
+ ''
74
+ end
75
+ f = /\{(.*?)\}/.match(match)
76
+ ial = f[1] if f
77
+ [match.length, ial]
78
+ end
156
79
 
157
- # removes initial quote
158
- def unquote(s)
159
- s.gsub(/^>\s?/,'')
160
- end
80
+ # Normalize a link reference.
81
+ #
82
+ # @param s [String]
83
+ # @return [String]
84
+ def sanitize_ref_id(s)
85
+ s.downcase.gsub(/\s+/, ' ')
86
+ end
161
87
 
162
- # toglie al massimo n caratteri
163
- def strip_indent(s, n)
164
- i = 0
165
- while i < s.size && n>0
166
- c = s[i,1]
167
- if c == ' '
168
- n-=1;
169
- elsif c == "\t"
170
- n-=TabSize;
171
- else
172
- break
173
- end
174
- i+=1
175
- end
176
- s[i, s.size]
177
- end
88
+ # Remove line-initial `>` characters for a quotation.
89
+ #
90
+ # @param s [String]
91
+ # @return [String]
92
+ def unquote(s)
93
+ s.gsub(/^>\s?/, '')
94
+ end
178
95
 
179
- def dbg_describe_ary(a, prefix='')
180
- i = 0
181
- a.each do |l|
182
- puts "#{prefix} (#{i+=1})# #{l.inspect}"
183
- end
184
- end
96
+ # Removes indentation from the beginning of `s`,
97
+ # up to at most `n` spaces.
98
+ # Tabs are counted as {TAB_SIZE} spaces.
99
+ #
100
+ # @param s [String]
101
+ # @param n [Fixnum]
102
+ # @return [String]
103
+ def strip_indent(s, n)
104
+ while n > 0
105
+ case s[0, 1]
106
+ when ' '
107
+ n -= 1
108
+ when "\t"
109
+ n -= TAB_SIZE
110
+ else
111
+ break
112
+ end
113
+ s = s[1..-1]
114
+ end
185
115
 
186
- def force_linebreak?(l)
187
- l =~ / $/
188
- end
116
+ MDLine.new(s)
117
+ end
189
118
 
190
- end
119
+ private
120
+
121
+ # Normalize the key/value pairs for email headers.
122
+ # Keys are downcased and converted to symbols;
123
+ # spaces become underscores.
124
+ #
125
+ # Values of `"yes"`, `"true"`, `"no"`, and `"false"`
126
+ # are converted to appropriate booleans.
127
+ #
128
+ # @param k [String]
129
+ # @param v [String]
130
+ # @return [Array(String, String or Boolean)]
131
+ def normalize_key_and_value(k, v)
132
+ k = k.strip.downcase.gsub(/\s+/, '_').to_sym
133
+ v = v.strip
134
+
135
+ # check synonyms
136
+ return k, true if %w[yes true].include?(v.downcase)
137
+ return k, false if %w[no false].include?(v.downcase)
138
+ return k, v
139
+ end
140
+ end
191
141
  end