gitdown 0.0.1

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 (416) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +24 -0
  3. data/GPL +674 -0
  4. data/README +43 -0
  5. data/Rakefile +370 -0
  6. data/VERSION +1 -0
  7. data/benchmark/benchmark.rb +34 -0
  8. data/benchmark/benchmark.sh +74 -0
  9. data/benchmark/generate_data.rb +119 -0
  10. data/benchmark/mdbasics.text +306 -0
  11. data/benchmark/mdsyntax.text +888 -0
  12. data/benchmark/testing.sh +9 -0
  13. data/benchmark/timing.sh +10 -0
  14. data/bin/kramdown +78 -0
  15. data/data/kramdown/document.html +18 -0
  16. data/data/kramdown/document.latex +43 -0
  17. data/doc/default.scss.css +530 -0
  18. data/doc/default.template +80 -0
  19. data/doc/documentation.page +71 -0
  20. data/doc/index.page +98 -0
  21. data/doc/installation.page +88 -0
  22. data/doc/links.markdown +6 -0
  23. data/doc/news.feed +10 -0
  24. data/doc/news.page +28 -0
  25. data/doc/quickref.page +585 -0
  26. data/doc/syntax.page +1644 -0
  27. data/doc/tests.page +52 -0
  28. data/doc/virtual +2 -0
  29. data/lib/kramdown.rb +23 -0
  30. data/lib/kramdown/compatibility.rb +35 -0
  31. data/lib/kramdown/converter.rb +41 -0
  32. data/lib/kramdown/converter/base.rb +169 -0
  33. data/lib/kramdown/converter/html.rb +410 -0
  34. data/lib/kramdown/converter/kramdown.rb +422 -0
  35. data/lib/kramdown/converter/latex.rb +607 -0
  36. data/lib/kramdown/converter/toc.rb +82 -0
  37. data/lib/kramdown/document.rb +117 -0
  38. data/lib/kramdown/element.rb +524 -0
  39. data/lib/kramdown/error.rb +30 -0
  40. data/lib/kramdown/options.rb +373 -0
  41. data/lib/kramdown/parser.rb +40 -0
  42. data/lib/kramdown/parser/base.rb +136 -0
  43. data/lib/kramdown/parser/github_markdown.rb +44 -0
  44. data/lib/kramdown/parser/github_markdown/github_codeblock.rb +44 -0
  45. data/lib/kramdown/parser/html.rb +570 -0
  46. data/lib/kramdown/parser/kramdown.rb +338 -0
  47. data/lib/kramdown/parser/kramdown/abbreviation.rb +71 -0
  48. data/lib/kramdown/parser/kramdown/autolink.rb +53 -0
  49. data/lib/kramdown/parser/kramdown/blank_line.rb +43 -0
  50. data/lib/kramdown/parser/kramdown/block_boundary.rb +46 -0
  51. data/lib/kramdown/parser/kramdown/blockquote.rb +51 -0
  52. data/lib/kramdown/parser/kramdown/codeblock.rb +63 -0
  53. data/lib/kramdown/parser/kramdown/codespan.rb +56 -0
  54. data/lib/kramdown/parser/kramdown/emphasis.rb +70 -0
  55. data/lib/kramdown/parser/kramdown/eob.rb +39 -0
  56. data/lib/kramdown/parser/kramdown/escaped_chars.rb +38 -0
  57. data/lib/kramdown/parser/kramdown/extensions.rb +204 -0
  58. data/lib/kramdown/parser/kramdown/footnote.rb +74 -0
  59. data/lib/kramdown/parser/kramdown/header.rb +68 -0
  60. data/lib/kramdown/parser/kramdown/horizontal_rule.rb +39 -0
  61. data/lib/kramdown/parser/kramdown/html.rb +169 -0
  62. data/lib/kramdown/parser/kramdown/html_entity.rb +44 -0
  63. data/lib/kramdown/parser/kramdown/line_break.rb +38 -0
  64. data/lib/kramdown/parser/kramdown/link.rb +148 -0
  65. data/lib/kramdown/parser/kramdown/list.rb +240 -0
  66. data/lib/kramdown/parser/kramdown/math.rb +64 -0
  67. data/lib/kramdown/parser/kramdown/paragraph.rb +63 -0
  68. data/lib/kramdown/parser/kramdown/smart_quotes.rb +214 -0
  69. data/lib/kramdown/parser/kramdown/table.rb +178 -0
  70. data/lib/kramdown/parser/kramdown/typographic_symbol.rb +52 -0
  71. data/lib/kramdown/parser/markdown.rb +69 -0
  72. data/lib/kramdown/utils.rb +37 -0
  73. data/lib/kramdown/utils/entities.rb +348 -0
  74. data/lib/kramdown/utils/html.rb +85 -0
  75. data/lib/kramdown/utils/ordered_hash.rb +100 -0
  76. data/lib/kramdown/version.rb +28 -0
  77. data/setup.rb +1585 -0
  78. data/test/run_tests.rb +59 -0
  79. data/test/test_files.rb +197 -0
  80. data/test/testcases/block/01_blank_line/spaces.html +1 -0
  81. data/test/testcases/block/01_blank_line/spaces.text +3 -0
  82. data/test/testcases/block/01_blank_line/tabs.html +1 -0
  83. data/test/testcases/block/01_blank_line/tabs.text +6 -0
  84. data/test/testcases/block/02_eob/beginning.html +1 -0
  85. data/test/testcases/block/02_eob/beginning.text +3 -0
  86. data/test/testcases/block/02_eob/end.html +1 -0
  87. data/test/testcases/block/02_eob/end.text +3 -0
  88. data/test/testcases/block/02_eob/middle.html +1 -0
  89. data/test/testcases/block/02_eob/middle.text +5 -0
  90. data/test/testcases/block/03_paragraph/indented.html +18 -0
  91. data/test/testcases/block/03_paragraph/indented.text +19 -0
  92. data/test/testcases/block/03_paragraph/no_newline_at_end.html +5 -0
  93. data/test/testcases/block/03_paragraph/no_newline_at_end.text +5 -0
  94. data/test/testcases/block/03_paragraph/one_para.html +1 -0
  95. data/test/testcases/block/03_paragraph/one_para.text +1 -0
  96. data/test/testcases/block/03_paragraph/two_para.html +4 -0
  97. data/test/testcases/block/03_paragraph/two_para.text +4 -0
  98. data/test/testcases/block/04_header/atx_header.html +37 -0
  99. data/test/testcases/block/04_header/atx_header.text +34 -0
  100. data/test/testcases/block/04_header/atx_header_no_newline_at_end.html +1 -0
  101. data/test/testcases/block/04_header/atx_header_no_newline_at_end.text +1 -0
  102. data/test/testcases/block/04_header/setext_header.html +30 -0
  103. data/test/testcases/block/04_header/setext_header.html.19 +30 -0
  104. data/test/testcases/block/04_header/setext_header.text +36 -0
  105. data/test/testcases/block/04_header/setext_header_no_newline_at_end.html +1 -0
  106. data/test/testcases/block/04_header/setext_header_no_newline_at_end.text +2 -0
  107. data/test/testcases/block/04_header/with_auto_id_prefix.html +3 -0
  108. data/test/testcases/block/04_header/with_auto_id_prefix.options +2 -0
  109. data/test/testcases/block/04_header/with_auto_id_prefix.text +3 -0
  110. data/test/testcases/block/04_header/with_auto_ids.html +17 -0
  111. data/test/testcases/block/04_header/with_auto_ids.options +1 -0
  112. data/test/testcases/block/04_header/with_auto_ids.text +19 -0
  113. data/test/testcases/block/05_blockquote/indented.html +25 -0
  114. data/test/testcases/block/05_blockquote/indented.text +14 -0
  115. data/test/testcases/block/05_blockquote/lazy.html +34 -0
  116. data/test/testcases/block/05_blockquote/lazy.text +20 -0
  117. data/test/testcases/block/05_blockquote/nested.html +10 -0
  118. data/test/testcases/block/05_blockquote/nested.text +6 -0
  119. data/test/testcases/block/05_blockquote/no_newline_at_end.html +4 -0
  120. data/test/testcases/block/05_blockquote/no_newline_at_end.text +2 -0
  121. data/test/testcases/block/05_blockquote/very_long_line.html +3 -0
  122. data/test/testcases/block/05_blockquote/very_long_line.text +1 -0
  123. data/test/testcases/block/05_blockquote/with_code_blocks.html +15 -0
  124. data/test/testcases/block/05_blockquote/with_code_blocks.text +11 -0
  125. data/test/testcases/block/06_codeblock/error.html +4 -0
  126. data/test/testcases/block/06_codeblock/error.text +4 -0
  127. data/test/testcases/block/06_codeblock/lazy.html +4 -0
  128. data/test/testcases/block/06_codeblock/lazy.text +5 -0
  129. data/test/testcases/block/06_codeblock/no_newline_at_end.html +2 -0
  130. data/test/testcases/block/06_codeblock/no_newline_at_end.text +1 -0
  131. data/test/testcases/block/06_codeblock/no_newline_at_end_1.html +2 -0
  132. data/test/testcases/block/06_codeblock/no_newline_at_end_1.text +2 -0
  133. data/test/testcases/block/06_codeblock/normal.html +13 -0
  134. data/test/testcases/block/06_codeblock/normal.text +10 -0
  135. data/test/testcases/block/06_codeblock/tilde_syntax.html +7 -0
  136. data/test/testcases/block/06_codeblock/tilde_syntax.text +9 -0
  137. data/test/testcases/block/06_codeblock/whitespace.html +3 -0
  138. data/test/testcases/block/06_codeblock/whitespace.text +3 -0
  139. data/test/testcases/block/06_codeblock/with_blank_line.html +13 -0
  140. data/test/testcases/block/06_codeblock/with_blank_line.text +12 -0
  141. data/test/testcases/block/06_codeblock/with_eob_marker.html +6 -0
  142. data/test/testcases/block/06_codeblock/with_eob_marker.text +5 -0
  143. data/test/testcases/block/06_codeblock/with_ial.html +6 -0
  144. data/test/testcases/block/06_codeblock/with_ial.text +5 -0
  145. data/test/testcases/block/07_horizontal_rule/error.html +7 -0
  146. data/test/testcases/block/07_horizontal_rule/error.html.19 +7 -0
  147. data/test/testcases/block/07_horizontal_rule/error.text +7 -0
  148. data/test/testcases/block/07_horizontal_rule/normal.html +17 -0
  149. data/test/testcases/block/07_horizontal_rule/normal.text +17 -0
  150. data/test/testcases/block/07_horizontal_rule/sepspaces.html +3 -0
  151. data/test/testcases/block/07_horizontal_rule/sepspaces.text +3 -0
  152. data/test/testcases/block/07_horizontal_rule/septabs.html +3 -0
  153. data/test/testcases/block/07_horizontal_rule/septabs.text +3 -0
  154. data/test/testcases/block/08_list/escaping.html +17 -0
  155. data/test/testcases/block/08_list/escaping.text +17 -0
  156. data/test/testcases/block/08_list/item_ial.html +10 -0
  157. data/test/testcases/block/08_list/item_ial.text +8 -0
  158. data/test/testcases/block/08_list/lazy.html +39 -0
  159. data/test/testcases/block/08_list/lazy.text +29 -0
  160. data/test/testcases/block/08_list/list_and_hr.html +9 -0
  161. data/test/testcases/block/08_list/list_and_hr.text +5 -0
  162. data/test/testcases/block/08_list/list_and_others.html +40 -0
  163. data/test/testcases/block/08_list/list_and_others.text +26 -0
  164. data/test/testcases/block/08_list/mixed.html +117 -0
  165. data/test/testcases/block/08_list/mixed.text +66 -0
  166. data/test/testcases/block/08_list/nested.html +17 -0
  167. data/test/testcases/block/08_list/nested.text +7 -0
  168. data/test/testcases/block/08_list/other_first_element.html +39 -0
  169. data/test/testcases/block/08_list/other_first_element.text +18 -0
  170. data/test/testcases/block/08_list/simple_ol.html +19 -0
  171. data/test/testcases/block/08_list/simple_ol.text +13 -0
  172. data/test/testcases/block/08_list/simple_ul.html +48 -0
  173. data/test/testcases/block/08_list/simple_ul.text +36 -0
  174. data/test/testcases/block/08_list/single_item.html +3 -0
  175. data/test/testcases/block/08_list/single_item.text +1 -0
  176. data/test/testcases/block/08_list/special_cases.html +55 -0
  177. data/test/testcases/block/08_list/special_cases.text +35 -0
  178. data/test/testcases/block/09_html/comment.html +18 -0
  179. data/test/testcases/block/09_html/comment.text +15 -0
  180. data/test/testcases/block/09_html/content_model/deflists.html +6 -0
  181. data/test/testcases/block/09_html/content_model/deflists.options +1 -0
  182. data/test/testcases/block/09_html/content_model/deflists.text +6 -0
  183. data/test/testcases/block/09_html/content_model/tables.html +14 -0
  184. data/test/testcases/block/09_html/content_model/tables.options +1 -0
  185. data/test/testcases/block/09_html/content_model/tables.text +14 -0
  186. data/test/testcases/block/09_html/html_and_codeblocks.html +15 -0
  187. data/test/testcases/block/09_html/html_and_codeblocks.options +1 -0
  188. data/test/testcases/block/09_html/html_and_codeblocks.text +13 -0
  189. data/test/testcases/block/09_html/html_and_headers.html +5 -0
  190. data/test/testcases/block/09_html/html_and_headers.text +6 -0
  191. data/test/testcases/block/09_html/html_to_native/code.html +10 -0
  192. data/test/testcases/block/09_html/html_to_native/code.text +9 -0
  193. data/test/testcases/block/09_html/html_to_native/comment.html +7 -0
  194. data/test/testcases/block/09_html/html_to_native/comment.text +8 -0
  195. data/test/testcases/block/09_html/html_to_native/emphasis.html +6 -0
  196. data/test/testcases/block/09_html/html_to_native/emphasis.text +6 -0
  197. data/test/testcases/block/09_html/html_to_native/entity.html +1 -0
  198. data/test/testcases/block/09_html/html_to_native/entity.text +1 -0
  199. data/test/testcases/block/09_html/html_to_native/header.html +6 -0
  200. data/test/testcases/block/09_html/html_to_native/header.options +2 -0
  201. data/test/testcases/block/09_html/html_to_native/header.text +6 -0
  202. data/test/testcases/block/09_html/html_to_native/list_dl.html +8 -0
  203. data/test/testcases/block/09_html/html_to_native/list_dl.text +8 -0
  204. data/test/testcases/block/09_html/html_to_native/list_ol.html +15 -0
  205. data/test/testcases/block/09_html/html_to_native/list_ol.text +17 -0
  206. data/test/testcases/block/09_html/html_to_native/list_ul.html +19 -0
  207. data/test/testcases/block/09_html/html_to_native/list_ul.text +22 -0
  208. data/test/testcases/block/09_html/html_to_native/options +1 -0
  209. data/test/testcases/block/09_html/html_to_native/paragraph.html +3 -0
  210. data/test/testcases/block/09_html/html_to_native/paragraph.text +4 -0
  211. data/test/testcases/block/09_html/html_to_native/table_normal.html +12 -0
  212. data/test/testcases/block/09_html/html_to_native/table_normal.text +12 -0
  213. data/test/testcases/block/09_html/html_to_native/table_simple.html +48 -0
  214. data/test/testcases/block/09_html/html_to_native/table_simple.text +56 -0
  215. data/test/testcases/block/09_html/html_to_native/typography.html +1 -0
  216. data/test/testcases/block/09_html/html_to_native/typography.html.19 +1 -0
  217. data/test/testcases/block/09_html/html_to_native/typography.text +1 -0
  218. data/test/testcases/block/09_html/invalid_html_1.html +5 -0
  219. data/test/testcases/block/09_html/invalid_html_1.text +5 -0
  220. data/test/testcases/block/09_html/invalid_html_2.html +5 -0
  221. data/test/testcases/block/09_html/invalid_html_2.text +5 -0
  222. data/test/testcases/block/09_html/markdown_attr.html +38 -0
  223. data/test/testcases/block/09_html/markdown_attr.text +38 -0
  224. data/test/testcases/block/09_html/not_parsed.html +24 -0
  225. data/test/testcases/block/09_html/not_parsed.text +24 -0
  226. data/test/testcases/block/09_html/parse_as_raw.html +35 -0
  227. data/test/testcases/block/09_html/parse_as_raw.htmlinput +34 -0
  228. data/test/testcases/block/09_html/parse_as_raw.options +1 -0
  229. data/test/testcases/block/09_html/parse_as_raw.text +33 -0
  230. data/test/testcases/block/09_html/parse_as_span.html +12 -0
  231. data/test/testcases/block/09_html/parse_as_span.htmlinput +12 -0
  232. data/test/testcases/block/09_html/parse_as_span.options +1 -0
  233. data/test/testcases/block/09_html/parse_as_span.text +9 -0
  234. data/test/testcases/block/09_html/parse_block_html.html +21 -0
  235. data/test/testcases/block/09_html/parse_block_html.options +1 -0
  236. data/test/testcases/block/09_html/parse_block_html.text +17 -0
  237. data/test/testcases/block/09_html/processing_instruction.html +13 -0
  238. data/test/testcases/block/09_html/processing_instruction.text +12 -0
  239. data/test/testcases/block/09_html/simple.html +64 -0
  240. data/test/testcases/block/09_html/simple.html.19 +64 -0
  241. data/test/testcases/block/09_html/simple.options +1 -0
  242. data/test/testcases/block/09_html/simple.text +59 -0
  243. data/test/testcases/block/10_ald/simple.html +2 -0
  244. data/test/testcases/block/10_ald/simple.text +8 -0
  245. data/test/testcases/block/11_ial/auto_id_and_ial.html +1 -0
  246. data/test/testcases/block/11_ial/auto_id_and_ial.options +1 -0
  247. data/test/testcases/block/11_ial/auto_id_and_ial.text +2 -0
  248. data/test/testcases/block/11_ial/nested.html +11 -0
  249. data/test/testcases/block/11_ial/nested.text +15 -0
  250. data/test/testcases/block/11_ial/simple.html +25 -0
  251. data/test/testcases/block/11_ial/simple.text +34 -0
  252. data/test/testcases/block/12_extension/comment.html +8 -0
  253. data/test/testcases/block/12_extension/comment.text +12 -0
  254. data/test/testcases/block/12_extension/ignored.html +8 -0
  255. data/test/testcases/block/12_extension/ignored.text +8 -0
  256. data/test/testcases/block/12_extension/nomarkdown.html +10 -0
  257. data/test/testcases/block/12_extension/nomarkdown.kramdown +20 -0
  258. data/test/testcases/block/12_extension/nomarkdown.latex +13 -0
  259. data/test/testcases/block/12_extension/nomarkdown.text +21 -0
  260. data/test/testcases/block/12_extension/options.html +21 -0
  261. data/test/testcases/block/12_extension/options.text +21 -0
  262. data/test/testcases/block/12_extension/options2.html +10 -0
  263. data/test/testcases/block/12_extension/options2.text +5 -0
  264. data/test/testcases/block/12_extension/options3.html +7 -0
  265. data/test/testcases/block/12_extension/options3.text +7 -0
  266. data/test/testcases/block/13_definition_list/definition_at_beginning.html +1 -0
  267. data/test/testcases/block/13_definition_list/definition_at_beginning.text +1 -0
  268. data/test/testcases/block/13_definition_list/item_ial.html +12 -0
  269. data/test/testcases/block/13_definition_list/item_ial.text +8 -0
  270. data/test/testcases/block/13_definition_list/multiple_terms.html +13 -0
  271. data/test/testcases/block/13_definition_list/multiple_terms.text +10 -0
  272. data/test/testcases/block/13_definition_list/no_def_list.html +2 -0
  273. data/test/testcases/block/13_definition_list/no_def_list.text +2 -0
  274. data/test/testcases/block/13_definition_list/para_wrapping.html +10 -0
  275. data/test/testcases/block/13_definition_list/para_wrapping.text +6 -0
  276. data/test/testcases/block/13_definition_list/separated_by_eob.html +8 -0
  277. data/test/testcases/block/13_definition_list/separated_by_eob.text +5 -0
  278. data/test/testcases/block/13_definition_list/simple.html +8 -0
  279. data/test/testcases/block/13_definition_list/simple.text +7 -0
  280. data/test/testcases/block/13_definition_list/styled_terms.html +4 -0
  281. data/test/testcases/block/13_definition_list/styled_terms.text +2 -0
  282. data/test/testcases/block/13_definition_list/too_much_space.html +3 -0
  283. data/test/testcases/block/13_definition_list/too_much_space.text +4 -0
  284. data/test/testcases/block/13_definition_list/with_blocks.html +38 -0
  285. data/test/testcases/block/13_definition_list/with_blocks.text +24 -0
  286. data/test/testcases/block/14_table/errors.html +8 -0
  287. data/test/testcases/block/14_table/errors.text +9 -0
  288. data/test/testcases/block/14_table/escaping.html +52 -0
  289. data/test/testcases/block/14_table/escaping.text +19 -0
  290. data/test/testcases/block/14_table/footer.html +65 -0
  291. data/test/testcases/block/14_table/footer.text +25 -0
  292. data/test/testcases/block/14_table/header.html +96 -0
  293. data/test/testcases/block/14_table/header.text +32 -0
  294. data/test/testcases/block/14_table/no_table.html +3 -0
  295. data/test/testcases/block/14_table/no_table.text +3 -0
  296. data/test/testcases/block/14_table/simple.html +177 -0
  297. data/test/testcases/block/14_table/simple.html.19 +177 -0
  298. data/test/testcases/block/14_table/simple.text +49 -0
  299. data/test/testcases/block/14_table/table_with_footnote.html +25 -0
  300. data/test/testcases/block/14_table/table_with_footnote.latex +11 -0
  301. data/test/testcases/block/14_table/table_with_footnote.text +6 -0
  302. data/test/testcases/block/15_math/normal.html +26 -0
  303. data/test/testcases/block/15_math/normal.text +28 -0
  304. data/test/testcases/block/16_toc/no_toc.html +33 -0
  305. data/test/testcases/block/16_toc/no_toc.options +1 -0
  306. data/test/testcases/block/16_toc/no_toc.text +16 -0
  307. data/test/testcases/block/16_toc/toc_levels.html +24 -0
  308. data/test/testcases/block/16_toc/toc_levels.options +1 -0
  309. data/test/testcases/block/16_toc/toc_levels.text +16 -0
  310. data/test/testcases/block/17_github_codeblock/backtick_syntax.html +7 -0
  311. data/test/testcases/block/17_github_codeblock/backtick_syntax.text +9 -0
  312. data/test/testcases/block/17_github_codeblock/error.html +4 -0
  313. data/test/testcases/block/17_github_codeblock/error.text +4 -0
  314. data/test/testcases/block/17_github_codeblock/no_newline_at_end.html +2 -0
  315. data/test/testcases/block/17_github_codeblock/no_newline_at_end.text +3 -0
  316. data/test/testcases/encoding.html +46 -0
  317. data/test/testcases/encoding.text +28 -0
  318. data/test/testcases/span/01_link/empty.html +5 -0
  319. data/test/testcases/span/01_link/empty.text +5 -0
  320. data/test/testcases/span/01_link/image_in_a.html +5 -0
  321. data/test/testcases/span/01_link/image_in_a.text +5 -0
  322. data/test/testcases/span/01_link/imagelinks.html +14 -0
  323. data/test/testcases/span/01_link/imagelinks.text +16 -0
  324. data/test/testcases/span/01_link/inline.html +46 -0
  325. data/test/testcases/span/01_link/inline.html.19 +46 -0
  326. data/test/testcases/span/01_link/inline.text +48 -0
  327. data/test/testcases/span/01_link/link_defs.html +9 -0
  328. data/test/testcases/span/01_link/link_defs.text +26 -0
  329. data/test/testcases/span/01_link/links_with_angle_brackets.html +3 -0
  330. data/test/testcases/span/01_link/links_with_angle_brackets.text +3 -0
  331. data/test/testcases/span/01_link/reference.html +36 -0
  332. data/test/testcases/span/01_link/reference.html.19 +36 -0
  333. data/test/testcases/span/01_link/reference.text +50 -0
  334. data/test/testcases/span/02_emphasis/empty.html +3 -0
  335. data/test/testcases/span/02_emphasis/empty.text +3 -0
  336. data/test/testcases/span/02_emphasis/errors.html +9 -0
  337. data/test/testcases/span/02_emphasis/errors.text +9 -0
  338. data/test/testcases/span/02_emphasis/nesting.html +38 -0
  339. data/test/testcases/span/02_emphasis/nesting.text +33 -0
  340. data/test/testcases/span/02_emphasis/normal.html +46 -0
  341. data/test/testcases/span/02_emphasis/normal.text +46 -0
  342. data/test/testcases/span/03_codespan/empty.html +5 -0
  343. data/test/testcases/span/03_codespan/empty.text +5 -0
  344. data/test/testcases/span/03_codespan/errors.html +1 -0
  345. data/test/testcases/span/03_codespan/errors.text +1 -0
  346. data/test/testcases/span/03_codespan/highlighting.html +1 -0
  347. data/test/testcases/span/03_codespan/highlighting.text +1 -0
  348. data/test/testcases/span/03_codespan/normal.html +16 -0
  349. data/test/testcases/span/03_codespan/normal.text +16 -0
  350. data/test/testcases/span/04_footnote/definitions.html +17 -0
  351. data/test/testcases/span/04_footnote/definitions.latex +17 -0
  352. data/test/testcases/span/04_footnote/definitions.text +24 -0
  353. data/test/testcases/span/04_footnote/footnote_nr.html +12 -0
  354. data/test/testcases/span/04_footnote/footnote_nr.latex +2 -0
  355. data/test/testcases/span/04_footnote/footnote_nr.options +1 -0
  356. data/test/testcases/span/04_footnote/footnote_nr.text +4 -0
  357. data/test/testcases/span/04_footnote/markers.html +46 -0
  358. data/test/testcases/span/04_footnote/markers.latex +23 -0
  359. data/test/testcases/span/04_footnote/markers.text +26 -0
  360. data/test/testcases/span/05_html/across_lines.html +1 -0
  361. data/test/testcases/span/05_html/across_lines.text +2 -0
  362. data/test/testcases/span/05_html/invalid.html +1 -0
  363. data/test/testcases/span/05_html/invalid.text +1 -0
  364. data/test/testcases/span/05_html/link_with_mailto.html +1 -0
  365. data/test/testcases/span/05_html/link_with_mailto.text +1 -0
  366. data/test/testcases/span/05_html/markdown_attr.html +6 -0
  367. data/test/testcases/span/05_html/markdown_attr.text +6 -0
  368. data/test/testcases/span/05_html/normal.html +34 -0
  369. data/test/testcases/span/05_html/normal.text +34 -0
  370. data/test/testcases/span/abbreviations/abbrev.html +8 -0
  371. data/test/testcases/span/abbreviations/abbrev.text +15 -0
  372. data/test/testcases/span/abbreviations/abbrev_defs.html +2 -0
  373. data/test/testcases/span/abbreviations/abbrev_defs.text +5 -0
  374. data/test/testcases/span/autolinks/url_links.html +12 -0
  375. data/test/testcases/span/autolinks/url_links.text +12 -0
  376. data/test/testcases/span/escaped_chars/normal.html +47 -0
  377. data/test/testcases/span/escaped_chars/normal.text +47 -0
  378. data/test/testcases/span/extension/comment.html +6 -0
  379. data/test/testcases/span/extension/comment.text +6 -0
  380. data/test/testcases/span/extension/ignored.html +1 -0
  381. data/test/testcases/span/extension/ignored.text +1 -0
  382. data/test/testcases/span/extension/nomarkdown.html +1 -0
  383. data/test/testcases/span/extension/nomarkdown.text +1 -0
  384. data/test/testcases/span/extension/options.html +1 -0
  385. data/test/testcases/span/extension/options.text +1 -0
  386. data/test/testcases/span/ial/simple.html +6 -0
  387. data/test/testcases/span/ial/simple.text +6 -0
  388. data/test/testcases/span/line_breaks/normal.html +11 -0
  389. data/test/testcases/span/line_breaks/normal.latex +12 -0
  390. data/test/testcases/span/line_breaks/normal.text +11 -0
  391. data/test/testcases/span/math/normal.html +5 -0
  392. data/test/testcases/span/math/normal.text +5 -0
  393. data/test/testcases/span/text_substitutions/entities.html +6 -0
  394. data/test/testcases/span/text_substitutions/entities.options +1 -0
  395. data/test/testcases/span/text_substitutions/entities.text +6 -0
  396. data/test/testcases/span/text_substitutions/entities_as_char.html +1 -0
  397. data/test/testcases/span/text_substitutions/entities_as_char.html.19 +1 -0
  398. data/test/testcases/span/text_substitutions/entities_as_char.options +1 -0
  399. data/test/testcases/span/text_substitutions/entities_as_char.text +1 -0
  400. data/test/testcases/span/text_substitutions/entities_as_input.html +1 -0
  401. data/test/testcases/span/text_substitutions/entities_as_input.options +1 -0
  402. data/test/testcases/span/text_substitutions/entities_as_input.text +1 -0
  403. data/test/testcases/span/text_substitutions/entities_numeric.html +1 -0
  404. data/test/testcases/span/text_substitutions/entities_numeric.options +1 -0
  405. data/test/testcases/span/text_substitutions/entities_numeric.text +1 -0
  406. data/test/testcases/span/text_substitutions/entities_symbolic.html +1 -0
  407. data/test/testcases/span/text_substitutions/entities_symbolic.options +1 -0
  408. data/test/testcases/span/text_substitutions/entities_symbolic.text +1 -0
  409. data/test/testcases/span/text_substitutions/greaterthan.html +1 -0
  410. data/test/testcases/span/text_substitutions/greaterthan.text +1 -0
  411. data/test/testcases/span/text_substitutions/lowerthan.html +1 -0
  412. data/test/testcases/span/text_substitutions/lowerthan.text +1 -0
  413. data/test/testcases/span/text_substitutions/typography.html +18 -0
  414. data/test/testcases/span/text_substitutions/typography.html.19 +18 -0
  415. data/test/testcases/span/text_substitutions/typography.text +18 -0
  416. metadata +817 -0
@@ -0,0 +1,240 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown.
7
+ #
8
+ # kramdown is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+ #
22
+
23
+ require 'kramdown/parser/kramdown/blank_line'
24
+ require 'kramdown/parser/kramdown/eob'
25
+ require 'kramdown/parser/kramdown/horizontal_rule'
26
+ require 'kramdown/parser/kramdown/extensions'
27
+
28
+ module Kramdown
29
+ module Parser
30
+ class Kramdown
31
+
32
+ LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/
33
+ LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/
34
+
35
+ # Used for parsing the first line of a list item or a definition, i.e. the line with list item
36
+ # marker or the definition marker.
37
+ def parse_first_list_line(indentation, content)
38
+ if content =~ self.class::LIST_ITEM_IAL_CHECK
39
+ indentation = 4
40
+ else
41
+ while content =~ /^ *\t/
42
+ temp = content.scan(/^ */).first.length + indentation
43
+ content.sub!(/^( *)(\t+)/) {$1 << " "*(4 - (temp % 4) + ($2.length - 1)*4)}
44
+ end
45
+ indentation += content.scan(/^ */).first.length
46
+ end
47
+ content.sub!(/^\s*/, '')
48
+
49
+ indent_re = /^ {#{indentation}}/
50
+ content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*\S.*\n/
51
+ lazy_re = /(?!^ {0,#{[indentation, 3].min}}(?:#{IAL_BLOCK}|#{LAZY_END_HTML_STOP}|#{LAZY_END_HTML_START})).*\S.*\n/
52
+ [content, indentation, content_re, lazy_re, indent_re]
53
+ end
54
+
55
+
56
+ LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/
57
+ LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/
58
+ LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/
59
+
60
+ # Parse the ordered or unordered list at the current location.
61
+ def parse_list
62
+ type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
63
+ list = new_block_el(type)
64
+
65
+ item = nil
66
+ content_re, lazy_re, indent_re = nil
67
+ eob_found = false
68
+ nested_list_found = false
69
+ last_is_blank = false
70
+ while !@src.eos?
71
+ if last_is_blank && @src.check(HR_START)
72
+ break
73
+ elsif @src.scan(EOB_MARKER)
74
+ eob_found = true
75
+ break
76
+ elsif @src.scan(list_start_re)
77
+ item = Element.new(:li)
78
+ item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
79
+ list.children << item
80
+
81
+ item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
82
+ parse_attribute_list($1, item.options[:ial] ||= {})
83
+ ''
84
+ end
85
+
86
+ list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ :
87
+ /^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/)
88
+ nested_list_found = (item.value =~ LIST_START)
89
+ last_is_blank = false
90
+ elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
91
+ result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
92
+ result.sub!(indent_re, '')
93
+ if !nested_list_found && result =~ LIST_START
94
+ item.value << "^\n"
95
+ nested_list_found = true
96
+ end
97
+ item.value << result
98
+ last_is_blank = false
99
+ elsif result = @src.scan(BLANK_LINE)
100
+ nested_list_found = true
101
+ last_is_blank = true
102
+ item.value << result
103
+ else
104
+ break
105
+ end
106
+ end
107
+
108
+ @tree.children << list
109
+
110
+ last = nil
111
+ list.children.each do |it|
112
+ temp = Element.new(:temp)
113
+ parse_blocks(temp, it.value)
114
+ it.children = temp.children
115
+ it.value = nil
116
+ next if it.children.size == 0
117
+
118
+ # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph
119
+ it.children.delete_at(1) if it.children.first.type == :p &&
120
+ it.children.length >= 2 && it.children[1].type == :eob && it.children.first.options[:ial]
121
+
122
+ if it.children.first.type == :p &&
123
+ (it.children.length < 2 || it.children[1].type != :blank ||
124
+ (it == list.children.last && it.children.length == 2 && !eob_found)) &&
125
+ (list.children.last != it || list.children.size == 1 ||
126
+ list.children[0..-2].any? {|cit| cit.children.first.type != :p || cit.children.first.options[:transparent]})
127
+ it.children.first.children.first.value << "\n" if it.children.size > 1 && it.children[1].type != :blank
128
+ it.children.first.options[:transparent] = true
129
+ end
130
+
131
+ if it.children.last.type == :blank
132
+ last = it.children.pop
133
+ else
134
+ last = nil
135
+ end
136
+ end
137
+
138
+ @tree.children << last if !last.nil? && !eob_found
139
+
140
+ true
141
+ end
142
+ define_parser(:list, LIST_START)
143
+
144
+
145
+ DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/
146
+
147
+ # Parse the ordered or unordered list at the current location.
148
+ def parse_definition_list
149
+ children = @tree.children
150
+ if !children.last || (children.length == 1 && children.last.type != :p ) ||
151
+ (children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
152
+ return false
153
+ end
154
+
155
+ first_as_para = false
156
+ deflist = new_block_el(:dl)
157
+ para = @tree.children.pop
158
+ if para.type == :blank
159
+ para = @tree.children.pop
160
+ first_as_para = true
161
+ end
162
+ para.children.first.value.split(/\n/).each do |term|
163
+ el = Element.new(:dt)
164
+ el.children << Element.new(:raw_text, term)
165
+ deflist.children << el
166
+ end
167
+
168
+ item = nil
169
+ content_re, lazy_re, indent_re = nil
170
+ def_start_re = DEFINITION_LIST_START
171
+ last_is_blank = false
172
+ while !@src.eos?
173
+ if @src.scan(def_start_re)
174
+ item = Element.new(:dd)
175
+ item.options[:first_as_para] = first_as_para
176
+ item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
177
+ deflist.children << item
178
+
179
+ item.value.sub!(self.class::LIST_ITEM_IAL) do |match|
180
+ parse_attribute_list($1, item.options[:ial] ||= {})
181
+ ''
182
+ end
183
+
184
+ def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
185
+ first_as_para = false
186
+ last_is_blank = false
187
+ elsif @src.check(EOB_MARKER)
188
+ break
189
+ elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
190
+ result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) }
191
+ result.sub!(indent_re, '')
192
+ item.value << result
193
+ first_as_para = false
194
+ last_is_blank = false
195
+ elsif result = @src.scan(BLANK_LINE)
196
+ first_as_para = true
197
+ item.value << result
198
+ last_is_blank = true
199
+ else
200
+ break
201
+ end
202
+ end
203
+
204
+ last = nil
205
+ deflist.children.each do |it|
206
+ next if it.type == :dt
207
+
208
+ parse_blocks(it, it.value)
209
+ it.value = nil
210
+ next if it.children.size == 0
211
+
212
+ if it.children.last.type == :blank
213
+ last = it.children.pop
214
+ else
215
+ last = nil
216
+ end
217
+ if it.children.first.type == :p && !it.options.delete(:first_as_para)
218
+ it.children.first.children.first.value << "\n" if it.children.size > 1
219
+ it.children.first.options[:transparent] = true
220
+ end
221
+ end
222
+
223
+ if @tree.children.length >= 1 && @tree.children.last.type == :dl
224
+ @tree.children[-1].children.concat(deflist.children)
225
+ elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl
226
+ @tree.children.pop
227
+ @tree.children[-1].children.concat(deflist.children)
228
+ else
229
+ @tree.children << deflist
230
+ end
231
+
232
+ @tree.children << last if !last.nil?
233
+
234
+ true
235
+ end
236
+ define_parser(:definition_list, DEFINITION_LIST_START)
237
+
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown.
7
+ #
8
+ # kramdown is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+ #
22
+
23
+ require 'kramdown/parser/kramdown/block_boundary'
24
+
25
+ module Kramdown
26
+ module Parser
27
+ class Kramdown
28
+
29
+ BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$\s*?\n/m
30
+
31
+ # Parse the math block at the current location.
32
+ def parse_block_math
33
+ if !after_block_boundary?
34
+ return false
35
+ elsif @src[1]
36
+ @src.scan(/^#{OPT_SPACE}\\/)
37
+ return false
38
+ end
39
+ orig_pos = @src.pos
40
+ @src.pos += @src.matched_size
41
+ data = @src[2]
42
+ if before_block_boundary?
43
+ @tree.children << new_block_el(:math, data, nil, :category => :block)
44
+ true
45
+ else
46
+ @src.pos = orig_pos
47
+ false
48
+ end
49
+ end
50
+ define_parser(:block_math, BLOCK_MATH_START)
51
+
52
+
53
+ INLINE_MATH_START = /\$\$(.*?)\$\$/
54
+
55
+ # Parse the inline math at the current location.
56
+ def parse_inline_math
57
+ @src.pos += @src.matched_size
58
+ @tree.children << Element.new(:math, @src[1], nil, :category => :span)
59
+ end
60
+ define_parser(:inline_math, INLINE_MATH_START, '\$')
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown.
7
+ #
8
+ # kramdown is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+ #
22
+
23
+ require 'kramdown/parser/kramdown/blank_line'
24
+ require 'kramdown/parser/kramdown/extensions'
25
+ require 'kramdown/parser/kramdown/eob'
26
+ require 'kramdown/parser/kramdown/list'
27
+ require 'kramdown/parser/kramdown/html'
28
+
29
+ module Kramdown
30
+ module Parser
31
+ class Kramdown
32
+
33
+ LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w{script}
34
+ LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})\s*(?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}\s*=\s*(["']).*?\1)*\s*\/?>/m
35
+ LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m
36
+
37
+ LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/
38
+
39
+ PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
40
+ PARAGRAPH_MATCH = /^.*?\n/
41
+ PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/
42
+
43
+ # Parse the paragraph at the current location.
44
+ def parse_paragraph
45
+ result = @src.scan(PARAGRAPH_MATCH)
46
+ while !@src.match?(self.class::PARAGRAPH_END)
47
+ result << @src.scan(PARAGRAPH_MATCH)
48
+ end
49
+ result.chomp!
50
+ if @tree.children.last && @tree.children.last.type == :p
51
+ @tree.children.last.children.first.value << "\n" << result
52
+ else
53
+ @tree.children << new_block_el(:p)
54
+ result.lstrip!
55
+ @tree.children.last.children << Element.new(@text_type, result)
56
+ end
57
+ true
58
+ end
59
+ define_parser(:paragraph, PARAGRAPH_START)
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,214 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown.
7
+ #
8
+ # kramdown is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+ #
22
+ #--
23
+ # Parts of this file are based on code from Maruku by Andrea Censi.
24
+ # The needed license statements follow:
25
+ #
26
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
27
+ #
28
+ # Maruku is free software; you can redistribute it and/or modify
29
+ # it under the terms of the GNU General Public License as published by
30
+ # the Free Software Foundation; either version 2 of the License, or
31
+ # (at your option) any later version.
32
+ #
33
+ # Maruku is distributed in the hope that it will be useful,
34
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+ # GNU General Public License for more details.
37
+ #
38
+ # You should have received a copy of the GNU General Public License
39
+ # along with Maruku; if not, write to the Free Software
40
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
41
+ #
42
+ # NOTA BENE:
43
+ #
44
+ # The following algorithm is a rip-off of RubyPants written by
45
+ # Christian Neukirchen.
46
+ #
47
+ # RubyPants is a Ruby port of SmartyPants written by John Gruber.
48
+ #
49
+ # This file is distributed under the GPL, which I guess is compatible
50
+ # with the terms of the RubyPants license.
51
+ #
52
+ # -- Andrea Censi
53
+ #
54
+ # = RubyPants -- SmartyPants ported to Ruby
55
+ #
56
+ # Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
57
+ # Copyright (C) 2004 Christian Neukirchen
58
+ #
59
+ # Incooporates ideas, comments and documentation by Chad Miller
60
+ # Copyright (C) 2004 Chad Miller
61
+ #
62
+ # Original SmartyPants by John Gruber
63
+ # Copyright (C) 2003 John Gruber
64
+ #
65
+ #
66
+ # = RubyPants -- SmartyPants ported to Ruby
67
+ #
68
+ #
69
+ # [snip]
70
+ #
71
+ # == Authors
72
+ #
73
+ # John Gruber did all of the hard work of writing this software in
74
+ # Perl for Movable Type and almost all of this useful documentation.
75
+ # Chad Miller ported it to Python to use with Pyblosxom.
76
+ #
77
+ # Christian Neukirchen provided the Ruby port, as a general-purpose
78
+ # library that follows the *Cloth API.
79
+ #
80
+ #
81
+ # == Copyright and License
82
+ #
83
+ # === SmartyPants license:
84
+ #
85
+ # Copyright (c) 2003 John Gruber
86
+ # (http://daringfireball.net)
87
+ # All rights reserved.
88
+ #
89
+ # Redistribution and use in source and binary forms, with or without
90
+ # modification, are permitted provided that the following conditions
91
+ # are met:
92
+ #
93
+ # * Redistributions of source code must retain the above copyright
94
+ # notice, this list of conditions and the following disclaimer.
95
+ #
96
+ # * Redistributions in binary form must reproduce the above copyright
97
+ # notice, this list of conditions and the following disclaimer in
98
+ # the documentation and/or other materials provided with the
99
+ # distribution.
100
+ #
101
+ # * Neither the name "SmartyPants" nor the names of its contributors
102
+ # may be used to endorse or promote products derived from this
103
+ # software without specific prior written permission.
104
+ #
105
+ # This software is provided by the copyright holders and contributors
106
+ # "as is" and any express or implied warranties, including, but not
107
+ # limited to, the implied warranties of merchantability and fitness
108
+ # for a particular purpose are disclaimed. In no event shall the
109
+ # copyright owner or contributors be liable for any direct, indirect,
110
+ # incidental, special, exemplary, or consequential damages (including,
111
+ # but not limited to, procurement of substitute goods or services;
112
+ # loss of use, data, or profits; or business interruption) however
113
+ # caused and on any theory of liability, whether in contract, strict
114
+ # liability, or tort (including negligence or otherwise) arising in
115
+ # any way out of the use of this software, even if advised of the
116
+ # possibility of such damage.
117
+ #
118
+ # === RubyPants license
119
+ #
120
+ # RubyPants is a derivative work of SmartyPants and smartypants.py.
121
+ #
122
+ # Redistribution and use in source and binary forms, with or without
123
+ # modification, are permitted provided that the following conditions
124
+ # are met:
125
+ #
126
+ # * Redistributions of source code must retain the above copyright
127
+ # notice, this list of conditions and the following disclaimer.
128
+ #
129
+ # * Redistributions in binary form must reproduce the above copyright
130
+ # notice, this list of conditions and the following disclaimer in
131
+ # the documentation and/or other materials provided with the
132
+ # distribution.
133
+ #
134
+ # This software is provided by the copyright holders and contributors
135
+ # "as is" and any express or implied warranties, including, but not
136
+ # limited to, the implied warranties of merchantability and fitness
137
+ # for a particular purpose are disclaimed. In no event shall the
138
+ # copyright owner or contributors be liable for any direct, indirect,
139
+ # incidental, special, exemplary, or consequential damages (including,
140
+ # but not limited to, procurement of substitute goods or services;
141
+ # loss of use, data, or profits; or business interruption) however
142
+ # caused and on any theory of liability, whether in contract, strict
143
+ # liability, or tort (including negligence or otherwise) arising in
144
+ # any way out of the use of this software, even if advised of the
145
+ # possibility of such damage.
146
+ #
147
+ # == Links
148
+ #
149
+ # John Gruber:: http://daringfireball.net
150
+ # SmartyPants:: http://daringfireball.net/projects/smartypants
151
+ #
152
+ # Chad Miller:: http://web.chad.org
153
+ #
154
+ # Christian Neukirchen:: http://kronavita.de/chris
155
+ #
156
+ #++
157
+ #
158
+
159
+ module Kramdown
160
+ module Parser
161
+ class Kramdown
162
+
163
+ SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
164
+ SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
165
+
166
+ SQ_RULES = [
167
+ [/("|')(?=#{SQ_PUNCT}\B)/, [:rquote1]],
168
+ # Special case for double sets of quotes, e.g.:
169
+ # <p>He said, "'Quoted' words in a larger quote."</p>
170
+ [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]],
171
+ [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]],
172
+ # Special case for decade abbreviations (the '80s):
173
+ [/(\s?)'(?=\d\ds)/, [1, :rsquo]],
174
+
175
+ # Get most opening single/double quotes:
176
+ [/(\s)('|")(?=\w)/, [1, :lquote2]],
177
+ # Single/double closing quotes:
178
+ [/(#{SQ_CLOSE})('|")/, [1, :rquote2]],
179
+ # Special case for e.g. "<i>Custer</i>'s Last Stand."
180
+ [/("|')(\s|s\b|$)/, [:rquote1, 2]],
181
+ # Any remaining single quotes should be opening ones:
182
+ [/(.?)'/m, [1, :lsquo]],
183
+ [/(.?)"/m, [1, :ldquo]],
184
+ ] #'"
185
+
186
+ SQ_SUBSTS = {
187
+ [:rquote1, '"'] => :rdquo,
188
+ [:rquote1, "'"] => :rsquo,
189
+ [:rquote2, '"'] => :rdquo,
190
+ [:rquote2, "'"] => :rsquo,
191
+ [:lquote1, '"'] => :ldquo,
192
+ [:lquote1, "'"] => :lsquo,
193
+ [:lquote2, '"'] => :ldquo,
194
+ [:lquote2, "'"] => :lsquo,
195
+ }
196
+ SMART_QUOTES_RE = /[^\\]?["']/
197
+
198
+ # Parse the smart quotes at current location.
199
+ def parse_smart_quotes
200
+ substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1]
201
+ substs.each do |subst|
202
+ if subst.kind_of?(Integer)
203
+ add_text(@src[subst])
204
+ else
205
+ val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst
206
+ @tree.children << Element.new(:smart_quote, val)
207
+ end
208
+ end
209
+ end
210
+ define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']')
211
+
212
+ end
213
+ end
214
+ end