kramdown 0.14.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kramdown might be problematic. Click here for more details.

Files changed (323) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTERS +63 -1
  3. data/COPYING +17 -11
  4. data/README.md +35 -14
  5. data/VERSION +1 -1
  6. data/bin/kramdown +92 -40
  7. data/data/kramdown/document.html +4 -0
  8. data/data/kramdown/document.latex +7 -0
  9. data/lib/kramdown.rb +3 -16
  10. data/lib/kramdown/converter.rb +42 -16
  11. data/lib/kramdown/converter/base.rb +102 -38
  12. data/lib/kramdown/converter/hash_ast.rb +38 -0
  13. data/lib/kramdown/converter/html.rb +232 -141
  14. data/lib/kramdown/converter/kramdown.rb +122 -104
  15. data/lib/kramdown/converter/latex.rb +95 -78
  16. data/lib/kramdown/converter/man.rb +300 -0
  17. data/lib/kramdown/converter/math_engine/mathjax.rb +32 -0
  18. data/lib/kramdown/converter/remove_html_tags.rb +8 -17
  19. data/lib/kramdown/converter/syntax_highlighter.rb +56 -0
  20. data/lib/kramdown/converter/syntax_highlighter/minted.rb +35 -0
  21. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +85 -0
  22. data/lib/kramdown/converter/toc.rb +7 -20
  23. data/lib/kramdown/document.rb +30 -37
  24. data/lib/kramdown/element.rb +54 -27
  25. data/lib/kramdown/error.rb +3 -16
  26. data/lib/kramdown/options.rb +392 -247
  27. data/lib/kramdown/parser.rb +3 -16
  28. data/lib/kramdown/parser/base.rb +28 -33
  29. data/lib/kramdown/parser/html.rb +151 -119
  30. data/lib/kramdown/parser/kramdown.rb +87 -50
  31. data/lib/kramdown/parser/kramdown/abbreviation.rb +33 -27
  32. data/lib/kramdown/parser/kramdown/autolink.rb +7 -25
  33. data/lib/kramdown/parser/kramdown/blank_line.rb +6 -19
  34. data/lib/kramdown/parser/kramdown/block_boundary.rb +6 -18
  35. data/lib/kramdown/parser/kramdown/blockquote.rb +6 -19
  36. data/lib/kramdown/parser/kramdown/codeblock.rb +15 -24
  37. data/lib/kramdown/parser/kramdown/codespan.rb +20 -22
  38. data/lib/kramdown/parser/kramdown/emphasis.rb +15 -24
  39. data/lib/kramdown/parser/kramdown/eob.rb +3 -16
  40. data/lib/kramdown/parser/kramdown/escaped_chars.rb +3 -16
  41. data/lib/kramdown/parser/kramdown/extensions.rb +66 -56
  42. data/lib/kramdown/parser/kramdown/footnote.rb +21 -31
  43. data/lib/kramdown/parser/kramdown/header.rb +37 -37
  44. data/lib/kramdown/parser/kramdown/horizontal_rule.rb +5 -17
  45. data/lib/kramdown/parser/kramdown/html.rb +47 -56
  46. data/lib/kramdown/parser/kramdown/html_entity.rb +9 -19
  47. data/lib/kramdown/parser/kramdown/line_break.rb +4 -17
  48. data/lib/kramdown/parser/kramdown/link.rb +39 -38
  49. data/lib/kramdown/parser/kramdown/list.rb +124 -82
  50. data/lib/kramdown/parser/kramdown/math.rb +12 -24
  51. data/lib/kramdown/parser/kramdown/paragraph.rb +23 -24
  52. data/lib/kramdown/parser/kramdown/smart_quotes.rb +26 -66
  53. data/lib/kramdown/parser/kramdown/table.rb +41 -48
  54. data/lib/kramdown/parser/kramdown/typographic_symbol.rb +14 -22
  55. data/lib/kramdown/parser/markdown.rb +11 -23
  56. data/lib/kramdown/utils.rb +21 -18
  57. data/lib/kramdown/utils/configurable.rb +45 -0
  58. data/lib/kramdown/utils/entities.rb +287 -292
  59. data/lib/kramdown/utils/html.rb +27 -30
  60. data/lib/kramdown/utils/lru_cache.rb +41 -0
  61. data/lib/kramdown/utils/string_scanner.rb +81 -0
  62. data/lib/kramdown/utils/unidecoder.rb +50 -0
  63. data/lib/kramdown/version.rb +4 -17
  64. data/man/man1/kramdown.1 +340 -347
  65. data/test/run_tests.rb +7 -20
  66. data/test/test_files.rb +188 -100
  67. data/test/test_location.rb +216 -0
  68. data/test/test_string_scanner_kramdown.rb +27 -0
  69. data/test/testcases/block/03_paragraph/indented.html.gfm +18 -0
  70. data/test/testcases/block/03_paragraph/line_break_last_line.html +9 -0
  71. data/test/testcases/block/03_paragraph/line_break_last_line.text +9 -0
  72. data/test/testcases/block/03_paragraph/standalone_image.html +8 -0
  73. data/test/testcases/block/03_paragraph/standalone_image.text +6 -0
  74. data/test/testcases/block/03_paragraph/with_html_to_native.html +1 -0
  75. data/test/testcases/block/03_paragraph/with_html_to_native.options +1 -0
  76. data/test/testcases/block/03_paragraph/with_html_to_native.text +1 -0
  77. data/test/testcases/block/04_header/atx_header.html +15 -1
  78. data/test/testcases/block/04_header/atx_header.text +14 -1
  79. data/test/testcases/block/04_header/setext_header.html +3 -1
  80. data/test/testcases/block/04_header/setext_header.text +4 -1
  81. data/test/testcases/block/04_header/with_auto_id_stripping.html +1 -0
  82. data/test/testcases/block/04_header/with_auto_id_stripping.options +1 -0
  83. data/test/testcases/block/04_header/with_auto_id_stripping.text +1 -0
  84. data/test/testcases/block/04_header/with_auto_ids.html +2 -0
  85. data/test/testcases/block/04_header/with_auto_ids.options +1 -0
  86. data/test/testcases/block/04_header/with_auto_ids.text +2 -0
  87. data/test/testcases/block/06_codeblock/guess_lang_css_class.html +15 -0
  88. data/test/testcases/block/06_codeblock/guess_lang_css_class.options +2 -0
  89. data/test/testcases/block/06_codeblock/guess_lang_css_class.text +13 -0
  90. data/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex +9 -0
  91. data/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options +4 -0
  92. data/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text +5 -0
  93. data/test/testcases/block/06_codeblock/highlighting-minted.latex +8 -0
  94. data/test/testcases/block/06_codeblock/highlighting-minted.options +3 -0
  95. data/test/testcases/block/06_codeblock/highlighting-minted.text +4 -0
  96. data/test/testcases/block/06_codeblock/highlighting-opts.html +6 -0
  97. data/test/testcases/block/06_codeblock/highlighting-opts.options +7 -0
  98. data/test/testcases/block/06_codeblock/highlighting-opts.text +4 -0
  99. data/test/testcases/block/06_codeblock/highlighting.html +5 -6
  100. data/test/testcases/block/06_codeblock/issue_gh45.html +164 -0
  101. data/test/testcases/block/06_codeblock/issue_gh45.test +188 -0
  102. data/test/testcases/block/06_codeblock/rouge/disabled.html +2 -0
  103. data/test/testcases/block/06_codeblock/rouge/disabled.options +4 -0
  104. data/test/testcases/block/06_codeblock/rouge/disabled.text +1 -0
  105. data/test/testcases/block/06_codeblock/rouge/multiple.html +11 -0
  106. data/test/testcases/block/06_codeblock/rouge/multiple.options +4 -0
  107. data/test/testcases/block/06_codeblock/rouge/multiple.text +11 -0
  108. data/test/testcases/block/06_codeblock/rouge/simple.html +10 -0
  109. data/test/testcases/block/06_codeblock/rouge/simple.options +3 -0
  110. data/test/testcases/block/06_codeblock/rouge/simple.text +9 -0
  111. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options +1 -1
  112. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html +8 -0
  113. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options +2 -0
  114. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text +11 -0
  115. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html +3 -0
  116. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options +2 -0
  117. data/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text +4 -0
  118. data/test/testcases/block/07_horizontal_rule/error.html +2 -2
  119. data/test/testcases/block/07_horizontal_rule/normal.html +2 -0
  120. data/test/testcases/block/07_horizontal_rule/normal.text +3 -0
  121. data/test/testcases/block/08_list/brackets_in_item.latex +3 -0
  122. data/test/testcases/block/08_list/brackets_in_item.text +1 -0
  123. data/test/testcases/block/08_list/lazy_and_nested.html +9 -0
  124. data/test/testcases/block/08_list/lazy_and_nested.text +4 -0
  125. data/test/testcases/block/09_html/html5_attributes.html +2 -0
  126. data/test/testcases/block/09_html/html5_attributes.text +2 -0
  127. data/test/testcases/block/09_html/html_after_block.html +7 -0
  128. data/test/testcases/block/09_html/html_after_block.text +5 -0
  129. data/test/testcases/block/09_html/html_to_native/table_simple.html +13 -0
  130. data/test/testcases/block/09_html/html_to_native/table_simple.text +15 -0
  131. data/test/testcases/block/09_html/html_to_native/typography.html +1 -1
  132. data/test/testcases/block/09_html/not_parsed.html +1 -1
  133. data/test/testcases/block/09_html/processing_instruction.html +5 -6
  134. data/test/testcases/block/09_html/simple.html +1 -5
  135. data/test/testcases/block/09_html/simple.text +1 -5
  136. data/test/testcases/block/09_html/standalone_image_in_div.htmlinput +7 -0
  137. data/test/testcases/block/09_html/standalone_image_in_div.text +8 -0
  138. data/test/testcases/block/09_html/textarea.html +8 -0
  139. data/test/testcases/block/09_html/textarea.text +8 -0
  140. data/test/testcases/block/09_html/xml.html +8 -0
  141. data/test/testcases/block/09_html/xml.text +7 -0
  142. data/test/testcases/block/11_ial/simple.html +5 -1
  143. data/test/testcases/block/11_ial/simple.text +8 -1
  144. data/test/testcases/block/12_extension/options.html +4 -4
  145. data/test/testcases/block/12_extension/options.text +2 -0
  146. data/test/testcases/block/12_extension/options2.html +4 -4
  147. data/test/testcases/block/12_extension/options3.html +7 -6
  148. data/test/testcases/block/12_extension/options3.text +2 -2
  149. data/test/testcases/block/13_definition_list/auto_ids.html +15 -0
  150. data/test/testcases/block/13_definition_list/auto_ids.text +18 -0
  151. data/test/testcases/block/13_definition_list/item_ial.html +5 -0
  152. data/test/testcases/block/13_definition_list/item_ial.text +8 -0
  153. data/test/testcases/block/14_table/empty_tag_in_cell.html +8 -0
  154. data/test/testcases/block/14_table/empty_tag_in_cell.options +1 -0
  155. data/test/testcases/block/14_table/empty_tag_in_cell.text +1 -0
  156. data/test/testcases/block/14_table/errors.html +4 -0
  157. data/test/testcases/block/14_table/errors.text +4 -0
  158. data/test/testcases/block/14_table/header.html +21 -0
  159. data/test/testcases/block/14_table/header.text +7 -0
  160. data/test/testcases/block/14_table/simple.html +22 -7
  161. data/test/testcases/block/14_table/simple.text +4 -0
  162. data/test/testcases/block/14_table/table_with_footnote.html +4 -4
  163. data/test/testcases/block/15_math/gh_128.html +1 -0
  164. data/test/testcases/block/15_math/gh_128.text +1 -0
  165. data/test/testcases/block/15_math/no_engine.html +3 -0
  166. data/test/testcases/block/15_math/no_engine.options +1 -0
  167. data/test/testcases/block/15_math/no_engine.text +2 -0
  168. data/test/testcases/block/15_math/normal.html +17 -14
  169. data/test/testcases/block/15_math/normal.text +2 -0
  170. data/test/testcases/block/16_toc/toc_exclude.html +7 -7
  171. data/test/testcases/block/16_toc/toc_levels.html +5 -5
  172. data/test/testcases/block/16_toc/toc_levels.text +1 -1
  173. data/test/testcases/block/16_toc/toc_with_footnotes.html +5 -5
  174. data/test/testcases/block/16_toc/toc_with_links.html +8 -0
  175. data/test/testcases/block/16_toc/toc_with_links.options +2 -0
  176. data/test/testcases/block/16_toc/toc_with_links.text +8 -0
  177. data/test/testcases/cjk-line-break.html +4 -0
  178. data/test/testcases/cjk-line-break.options +1 -0
  179. data/test/testcases/cjk-line-break.text +12 -0
  180. data/test/testcases/man/example.man +123 -0
  181. data/test/testcases/man/example.text +85 -0
  182. data/test/testcases/man/heading-name-dash-description.man +4 -0
  183. data/test/testcases/man/heading-name-dash-description.text +1 -0
  184. data/test/testcases/man/heading-name-description.man +4 -0
  185. data/test/testcases/man/heading-name-description.text +2 -0
  186. data/test/testcases/man/heading-name-section-description.man +4 -0
  187. data/test/testcases/man/heading-name-section-description.text +1 -0
  188. data/test/testcases/man/heading-name-section.man +2 -0
  189. data/test/testcases/man/heading-name-section.text +1 -0
  190. data/test/testcases/man/heading-name.man +2 -0
  191. data/test/testcases/man/heading-name.text +1 -0
  192. data/test/testcases/man/sections.man +4 -0
  193. data/test/testcases/man/sections.text +11 -0
  194. data/test/testcases/man/text-escaping.man +8 -0
  195. data/test/testcases/man/text-escaping.text +7 -0
  196. data/test/testcases/span/01_link/empty.html +1 -1
  197. data/test/testcases/span/01_link/empty_title.htmlinput +3 -0
  198. data/test/testcases/span/01_link/empty_title.text +7 -0
  199. data/test/testcases/span/01_link/imagelinks.html +1 -0
  200. data/test/testcases/span/01_link/imagelinks.text +2 -0
  201. data/test/testcases/span/01_link/inline.html +1 -1
  202. data/test/testcases/span/01_link/latex_escaping.latex +6 -0
  203. data/test/testcases/span/01_link/latex_escaping.text +5 -0
  204. data/test/testcases/span/01_link/link_defs.html +1 -1
  205. data/test/testcases/span/01_link/link_defs.text +2 -1
  206. data/test/testcases/span/01_link/link_defs_with_ial.html +4 -0
  207. data/test/testcases/span/01_link/link_defs_with_ial.text +16 -0
  208. data/test/testcases/span/01_link/reference.html +3 -3
  209. data/test/testcases/span/02_emphasis/nesting.html +3 -0
  210. data/test/testcases/span/02_emphasis/nesting.text +4 -1
  211. data/test/testcases/span/02_emphasis/normal.html +19 -0
  212. data/test/testcases/span/02_emphasis/normal.options +1 -0
  213. data/test/testcases/span/02_emphasis/normal.text +17 -0
  214. data/test/testcases/span/03_codespan/highlighting-minted.latex +2 -0
  215. data/test/testcases/span/03_codespan/highlighting-minted.options +1 -0
  216. data/test/testcases/span/03_codespan/highlighting-minted.text +1 -0
  217. data/test/testcases/span/03_codespan/highlighting.html +1 -1
  218. data/test/testcases/span/03_codespan/normal-css-class.html +1 -0
  219. data/test/testcases/span/03_codespan/normal-css-class.options +2 -0
  220. data/test/testcases/span/03_codespan/normal-css-class.text +1 -0
  221. data/test/testcases/span/03_codespan/rouge/disabled.html +1 -0
  222. data/test/testcases/span/03_codespan/rouge/disabled.options +4 -0
  223. data/test/testcases/span/03_codespan/rouge/disabled.text +1 -0
  224. data/test/testcases/span/03_codespan/rouge/simple.html +1 -0
  225. data/test/testcases/span/03_codespan/rouge/simple.options +1 -0
  226. data/test/testcases/span/03_codespan/rouge/simple.text +1 -0
  227. data/test/testcases/span/04_footnote/backlink_inline.html +79 -0
  228. data/test/testcases/span/04_footnote/backlink_inline.options +1 -0
  229. data/test/testcases/span/04_footnote/backlink_inline.text +38 -0
  230. data/test/testcases/span/04_footnote/backlink_text.html +9 -0
  231. data/test/testcases/span/04_footnote/backlink_text.options +1 -0
  232. data/test/testcases/span/04_footnote/backlink_text.text +3 -0
  233. data/test/testcases/span/04_footnote/definitions.latex +2 -2
  234. data/test/testcases/span/04_footnote/footnote_nr.html +6 -6
  235. data/test/testcases/span/04_footnote/footnote_prefix.html +12 -0
  236. data/test/testcases/span/04_footnote/footnote_prefix.options +1 -0
  237. data/test/testcases/span/04_footnote/footnote_prefix.text +4 -0
  238. data/test/testcases/span/04_footnote/inside_footnote.html +17 -0
  239. data/test/testcases/span/04_footnote/inside_footnote.text +9 -0
  240. data/test/testcases/span/04_footnote/markers.html +16 -16
  241. data/test/testcases/span/04_footnote/markers.latex +3 -3
  242. data/test/testcases/span/04_footnote/markers.options +2 -0
  243. data/test/testcases/span/04_footnote/markers.text +2 -1
  244. data/test/testcases/span/04_footnote/placement.html +11 -0
  245. data/test/testcases/span/04_footnote/placement.options +1 -0
  246. data/test/testcases/span/04_footnote/placement.text +8 -0
  247. data/test/testcases/span/04_footnote/regexp_problem.html +14 -0
  248. data/test/testcases/span/04_footnote/regexp_problem.options +2 -0
  249. data/test/testcases/span/04_footnote/regexp_problem.text +52 -0
  250. data/test/testcases/span/04_footnote/without_backlink.html +9 -0
  251. data/test/testcases/span/04_footnote/without_backlink.options +1 -0
  252. data/test/testcases/span/04_footnote/without_backlink.text +3 -0
  253. data/test/testcases/span/05_html/button.html +7 -0
  254. data/test/testcases/span/05_html/button.text +7 -0
  255. data/test/testcases/span/05_html/mark_element.html +3 -0
  256. data/test/testcases/span/05_html/mark_element.text +3 -0
  257. data/test/testcases/span/05_html/normal.html +10 -1
  258. data/test/testcases/span/05_html/normal.text +9 -0
  259. data/test/testcases/span/05_html/raw_span_elements.html +2 -0
  260. data/test/testcases/span/05_html/raw_span_elements.text +2 -0
  261. data/test/testcases/span/05_html/xml.html +5 -0
  262. data/test/testcases/span/05_html/xml.text +5 -0
  263. data/test/testcases/span/abbreviations/abbrev.html +14 -1
  264. data/test/testcases/span/abbreviations/abbrev.text +18 -2
  265. data/test/testcases/span/abbreviations/in_footnote.html +9 -0
  266. data/test/testcases/span/abbreviations/in_footnote.text +5 -0
  267. data/test/testcases/span/autolinks/url_links.html +5 -4
  268. data/test/testcases/span/autolinks/url_links.text +1 -0
  269. data/test/testcases/span/line_breaks/normal.html +2 -2
  270. data/test/testcases/span/line_breaks/normal.latex +2 -2
  271. data/test/testcases/span/math/no_engine.html +1 -0
  272. data/test/testcases/span/math/no_engine.options +1 -0
  273. data/test/testcases/span/math/no_engine.text +1 -0
  274. data/test/testcases/span/math/normal.html +4 -3
  275. data/test/testcases/span/math/normal.text +2 -1
  276. data/test/testcases/span/text_substitutions/entities_as_char.html +1 -1
  277. data/test/testcases/span/text_substitutions/entities_as_char.options +1 -0
  278. data/test/testcases/span/text_substitutions/entities_as_char.text +1 -1
  279. data/test/testcases/span/text_substitutions/typography.html +22 -0
  280. data/test/testcases/span/text_substitutions/typography.text +22 -0
  281. data/test/testcases/span/text_substitutions/typography_subst.html +3 -0
  282. data/test/testcases/span/text_substitutions/typography_subst.latex +4 -0
  283. data/test/testcases/span/text_substitutions/typography_subst.options +8 -0
  284. data/test/testcases/span/text_substitutions/typography_subst.text +3 -0
  285. metadata +218 -67
  286. data/ChangeLog +0 -7436
  287. data/GPL +0 -674
  288. data/Rakefile +0 -306
  289. data/benchmark/benchmark.rb +0 -36
  290. data/benchmark/benchmark.sh +0 -74
  291. data/benchmark/generate_data.rb +0 -119
  292. data/benchmark/mdbasics.text +0 -306
  293. data/benchmark/mdsyntax.text +0 -888
  294. data/benchmark/testing.sh +0 -9
  295. data/benchmark/timing.sh +0 -10
  296. data/doc/bg.png +0 -0
  297. data/doc/default.scss.css +0 -181
  298. data/doc/default.template +0 -68
  299. data/doc/design.scss.css +0 -441
  300. data/doc/documentation.page +0 -84
  301. data/doc/documentation.template +0 -20
  302. data/doc/index.page +0 -94
  303. data/doc/installation.page +0 -88
  304. data/doc/links.markdown +0 -6
  305. data/doc/metainfo +0 -3
  306. data/doc/news.feed +0 -10
  307. data/doc/news.page +0 -29
  308. data/doc/options.page +0 -10
  309. data/doc/quickref.page +0 -598
  310. data/doc/sidebar.template +0 -21
  311. data/doc/syntax.page +0 -1700
  312. data/doc/tests.page +0 -91
  313. data/doc/virtual +0 -2
  314. data/lib/kramdown/compatibility.rb +0 -49
  315. data/lib/kramdown/utils/ordered_hash.rb +0 -100
  316. data/setup.rb +0 -1585
  317. data/test/testcases/block/07_horizontal_rule/error.html.19 +0 -7
  318. data/test/testcases/block/09_html/html_to_native/typography.html.19 +0 -1
  319. data/test/testcases/block/09_html/simple.html.19 +0 -64
  320. data/test/testcases/block/14_table/simple.html.19 +0 -177
  321. data/test/testcases/span/01_link/inline.html.19 +0 -46
  322. data/test/testcases/span/01_link/reference.html.19 +0 -37
  323. data/test/testcases/span/text_substitutions/entities_as_char.html.19 +0 -1
@@ -1,30 +1,18 @@
1
- # -*- coding: utf-8 -*-
1
+ # -*- coding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
5
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/>.
6
+ # This file is part of kramdown which is licensed under the MIT.
20
7
  #++
21
8
  #
22
9
 
23
10
  require 'strscan'
24
11
  require 'stringio'
12
+ require 'kramdown/parser'
25
13
 
26
- #TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1
27
- #NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed
14
+ # TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1
15
+ # NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed
28
16
 
29
17
  module Kramdown
30
18
 
@@ -79,35 +67,55 @@ module Kramdown
79
67
 
80
68
  reset_env
81
69
 
82
- @root.options[:abbrev_defs] = {}
83
70
  @alds = {}
84
- @link_defs = {}
85
- @options[:link_defs].each {|k,v| @link_defs[normalize_link_id(k)] = v}
86
71
  @footnotes = {}
72
+ @link_defs = {}
73
+ update_link_definitions(@options[:link_defs])
87
74
 
88
75
  @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header,
89
76
  :horizontal_rule, :list, :definition_list, :block_html, :setext_header,
90
- :table, :footnote_definition, :link_definition, :abbrev_definition,
91
- :block_extensions, :block_math, :eob_marker, :paragraph]
92
- @span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, :smart_quotes, :inline_math,
93
- :span_extensions, :html_entity, :typographic_syms, :line_break, :escaped_chars]
77
+ :block_math, :table, :footnote_definition, :link_definition,
78
+ :abbrev_definition, :block_extensions, :eob_marker, :paragraph]
79
+ @span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link,
80
+ :smart_quotes, :inline_math, :span_extensions, :html_entity,
81
+ :typographic_syms, :line_break, :escaped_chars]
94
82
 
83
+ @span_pattern_cache ||= Hash.new { |h, k| h[k] = {} }
95
84
  end
96
85
  private_class_method(:new, :allocate)
97
86
 
98
-
99
87
  # The source string provided on initialization is parsed into the @root element.
100
88
  def parse
101
89
  configure_parser
102
90
  parse_blocks(@root, adapt_source(source))
103
91
  update_tree(@root)
92
+ correct_abbreviations_attributes
104
93
  replace_abbreviations(@root)
105
- @footnotes.each {|name,data| update_tree(data[:marker].value) if data[:marker]}
94
+ @footnotes.each do |_name, data|
95
+ update_tree(data[:content])
96
+ replace_abbreviations(data[:content])
97
+ end
98
+ footnote_count = 0
99
+ @footnotes.each do |name, data|
100
+ (footnote_count += 1; next) if data.key?(:marker)
101
+ line = data[:content].options[:location]
102
+ warning("Footnote definition for '#{name}' on line #{line} is unreferenced - ignoring")
103
+ end
104
+ @root.options[:footnote_count] = footnote_count
106
105
  end
107
106
 
108
- #######
109
107
  protected
110
- #######
108
+
109
+ # :doc:
110
+ #
111
+ # Update the parser specific link definitions with the data from +link_defs+ (the value of the
112
+ # :link_defs option).
113
+ #
114
+ # The parameter +link_defs+ is a hash where the keys are possibly unnormalized link IDs and
115
+ # the values are two element arrays consisting of the link target and a title (can be +nil+).
116
+ def update_link_definitions(link_defs)
117
+ link_defs.each {|k, v| @link_defs[normalize_link_id(k)] = v }
118
+ end
111
119
 
112
120
  # Adapt the object to allow parsing like specified in the options.
113
121
  def configure_parser
@@ -124,18 +132,18 @@ module Kramdown
124
132
 
125
133
  # Create the needed span parser regexps.
126
134
  def span_parser_regexps(parsers = @span_parsers)
127
- span_start = /#{parsers.map {|name| @parsers[name].span_start}.join('|')}/
135
+ span_start = /#{parsers.map {|name| @parsers[name].span_start }.join('|')}/
128
136
  [span_start, /(?=#{span_start})/]
129
137
  end
130
138
 
131
139
  # Parse all block-level elements in +text+ into the element +el+.
132
140
  def parse_blocks(el, text = nil)
133
141
  @stack.push([@tree, @src, @block_ial])
134
- @tree, @src, @block_ial = el, (text.nil? ? @src : StringScanner.new(text)), nil
142
+ @tree, @block_ial = el, nil
143
+ @src = (text.nil? ? @src : ::Kramdown::Utils::StringScanner.new(text, el.options[:location]))
135
144
 
136
145
  status = catch(:stop_block_parsing) do
137
- while !@src.eos?
138
- block_ial_set = @block_ial
146
+ until @src.eos?
139
147
  @block_parsers.any? do |name|
140
148
  if @src.check(@parsers[name].start_re)
141
149
  send(@parsers[name].method)
@@ -146,7 +154,6 @@ module Kramdown
146
154
  warning('Warning: this should not occur - no block parser handled the line')
147
155
  add_text(@src.scan(/.*\n/))
148
156
  end
149
- @block_ial = nil if block_ial_set
150
157
  end
151
158
  end
152
159
 
@@ -161,10 +168,12 @@ module Kramdown
161
168
  element.children.map! do |child|
162
169
  if child.type == :raw_text
163
170
  last_blank = nil
164
- reset_env(:src => StringScanner.new(child.value), :text_type => :text)
171
+ reset_env(src: ::Kramdown::Utils::StringScanner.new(child.value, element.options[:location]),
172
+ text_type: :text)
165
173
  parse_spans(child)
166
174
  child.children
167
175
  elsif child.type == :eob
176
+ update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial]
168
177
  []
169
178
  elsif child.type == :blank
170
179
  if last_blank
@@ -178,11 +187,21 @@ module Kramdown
178
187
  last_blank = nil
179
188
  update_tree(child)
180
189
  update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial]
190
+ # DEPRECATED: option auto_id_stripping will be removed in 2.0 because then this will be
191
+ # the default behaviour
192
+ if child.type == :dt || (child.type == :header && @options[:auto_id_stripping])
193
+ update_raw_text(child)
194
+ end
181
195
  child
182
196
  end
183
197
  end.flatten!
184
198
  end
185
199
 
200
+ def span_pattern_cache(stop_re, span_start)
201
+ @span_pattern_cache[stop_re][span_start] ||= /(?=#{Regexp.union(stop_re, span_start)})/
202
+ end
203
+ private :span_pattern_cache
204
+
186
205
  # Parse all span-level elements in the source string of @src into +el+.
187
206
  #
188
207
  # If the parameter +stop_re+ (a regexp) is used, parsing is immediately stopped if the regexp
@@ -199,12 +218,12 @@ module Kramdown
199
218
  span_start = @span_start
200
219
  span_start_re = @span_start_re
201
220
  span_start, span_start_re = span_parser_regexps(parsers) if parsers
202
- parsers = parsers || @span_parsers
221
+ parsers ||= @span_parsers
203
222
 
204
- used_re = (stop_re.nil? ? span_start_re : /(?=#{Regexp.union(stop_re, span_start)})/)
223
+ used_re = (stop_re.nil? ? span_start_re : span_pattern_cache(stop_re, span_start))
205
224
  stop_re_found = false
206
225
  while !@src.eos? && !stop_re_found
207
- if result = @src.scan_until(used_re)
226
+ if (result = @src.scan_until(used_re))
208
227
  add_text(result)
209
228
  if stop_re && @src.check(stop_re)
210
229
  stop_re_found = (block_given? ? yield : true)
@@ -232,7 +251,7 @@ module Kramdown
232
251
  # Reset the current parsing environment. The parameter +env+ can be used to set initial
233
252
  # values for one or more environment variables.
234
253
  def reset_env(opts = {})
235
- opts = {:text_type => :raw_text, :stack => []}.merge(opts)
254
+ opts = {text_type: :raw_text, stack: []}.merge(opts)
236
255
  @src = opts[:src]
237
256
  @tree = opts[:tree]
238
257
  @block_ial = opts[:block_ial]
@@ -242,35 +261,53 @@ module Kramdown
242
261
 
243
262
  # Return the current parsing environment.
244
263
  def save_env
245
- [@src, @tree, @block_ial, @stack, @text_type]
264
+ [@src, @tree, @block_ial, @stack, @text_type]
246
265
  end
247
266
 
248
267
  # Restore the current parsing environment.
249
268
  def restore_env(env)
250
- @src, @tree, @block_ial, @stack, @text_type = *env
269
+ @src, @tree, @block_ial, @stack, @text_type = *env
251
270
  end
252
271
 
253
272
  # Update the given attributes hash +attr+ with the information from the inline attribute list
254
273
  # +ial+ and all referenced ALDs.
255
274
  def update_attr_with_ial(attr, ial)
256
- ial[:refs].each do |ref|
257
- update_attr_with_ial(attr, ref) if ref = @alds[ref]
258
- end if ial[:refs]
259
- ial.each do |k,v|
275
+ ial[:refs]&.each do |ref|
276
+ update_attr_with_ial(attr, ref) if (ref = @alds[ref])
277
+ end
278
+ ial.each do |k, v|
260
279
  if k == IAL_CLASS_ATTR
261
- attr[k] = (attr[k] || '') << " #{v}"
262
- attr[k].lstrip!
280
+ attr[k] = "#{attr[k]} #{v}".lstrip
263
281
  elsif k.kind_of?(String)
264
282
  attr[k] = v
265
283
  end
266
284
  end
267
285
  end
268
286
 
287
+ # Update the raw text for automatic ID generation.
288
+ def update_raw_text(item)
289
+ raw_text = +''
290
+
291
+ append_text = lambda do |child|
292
+ if child.type == :text
293
+ raw_text << child.value
294
+ else
295
+ child.children.each {|c| append_text.call(c) }
296
+ end
297
+ end
298
+
299
+ append_text.call(item)
300
+ item.options[:raw_text] = raw_text
301
+ end
302
+
269
303
  # Create a new block-level element, taking care of applying a preceding block IAL if it
270
304
  # exists. This method should always be used for creating a block-level element!
271
305
  def new_block_el(*args)
272
306
  el = Element.new(*args)
273
- el.options[:ial] = @block_ial if @block_ial && el.type != :blank && el.type != :eob
307
+ if @block_ial
308
+ el.options[:ial] = @block_ial
309
+ @block_ial = nil
310
+ end
274
311
  el
275
312
  end
276
313
 
@@ -289,7 +326,7 @@ module Kramdown
289
326
  # to the registry. The method name is automatically derived from the +name+ or can explicitly
290
327
  # be set by using the +meth_name+ parameter.
291
328
  def self.define_parser(name, start_re, span_start = nil, meth_name = "parse_#{name}")
292
- raise "A parser with the name #{name} already exists!" if @@parsers.has_key?(name)
329
+ raise "A parser with the name #{name} already exists!" if @@parsers.key?(name)
293
330
  @@parsers[name] = Data.new(name, start_re, span_start, meth_name)
294
331
  end
295
332
 
@@ -300,7 +337,7 @@ module Kramdown
300
337
 
301
338
  # Return +true+ if there is a parser called +name+.
302
339
  def self.has_parser?(name)
303
- @@parsers.has_key?(name)
340
+ @@parsers.key?(name)
304
341
  end
305
342
 
306
343
  # Regexp for matching indentation (one tab or four spaces)
@@ -1,22 +1,9 @@
1
- # -*- coding: utf-8 -*-
1
+ # -*- coding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
5
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/>.
6
+ # This file is part of kramdown which is licensed under the MIT.
20
7
  #++
21
8
  #
22
9
 
@@ -28,35 +15,54 @@ module Kramdown
28
15
 
29
16
  # Parse the link definition at the current location.
30
17
  def parse_abbrev_definition
18
+ start_line_number = @src.current_line_number
31
19
  @src.pos += @src.matched_size
32
20
  abbrev_id, abbrev_text = @src[1], @src[2]
33
21
  abbrev_text.strip!
34
- warning("Duplicate abbreviation ID '#{abbrev_id}' - overwriting") if @root.options[:abbrev_defs][abbrev_id]
22
+ if @root.options[:abbrev_defs][abbrev_id]
23
+ warning("Duplicate abbreviation ID '#{abbrev_id}' on line #{start_line_number} " \
24
+ "- overwriting")
25
+ end
26
+ @tree.children << new_block_el(:eob, :abbrev_def)
35
27
  @root.options[:abbrev_defs][abbrev_id] = abbrev_text
36
- @tree.children << Element.new(:eob, :abbrev_def)
28
+ @root.options[:abbrev_attr][abbrev_id] = @tree.children.last
37
29
  true
38
30
  end
39
31
  define_parser(:abbrev_definition, ABBREV_DEFINITION_START)
40
32
 
33
+ # Correct abbreviation attributes.
34
+ def correct_abbreviations_attributes
35
+ @root.options[:abbrev_attr].keys.each do |k|
36
+ @root.options[:abbrev_attr][k] = @root.options[:abbrev_attr][k].attr
37
+ end
38
+ end
39
+
41
40
  # Replace the abbreviation text with elements.
42
41
  def replace_abbreviations(el, regexps = nil)
43
42
  return if @root.options[:abbrev_defs].empty?
44
- if !regexps
45
- sorted_abbrevs = @root.options[:abbrev_defs].keys.sort {|a,b| b.length <=> a.length}
46
- regexps = [Regexp.union(*sorted_abbrevs.map {|k| /#{Regexp.escape(k)}/})]
43
+ unless regexps
44
+ sorted_abbrevs = @root.options[:abbrev_defs].keys.sort {|a, b| b.length <=> a.length }
45
+ regexps = [Regexp.union(*sorted_abbrevs.map {|k| /#{Regexp.escape(k)}/ })]
47
46
  regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries
48
47
  end
49
48
  el.children.map! do |child|
50
49
  if child.type == :text
51
50
  if child.value =~ regexps.first
52
51
  result = []
53
- strscan = StringScanner.new(child.value)
54
- while temp = strscan.scan_until(regexps.last)
55
- temp << strscan.scan(/\W|^/)
56
- abbr = strscan.scan(regexps.first)
57
- result << Element.new(:text, temp) << Element.new(:abbreviation, abbr)
52
+ strscan = Kramdown::Utils::StringScanner.new(child.value, child.options[:location])
53
+ text_lineno = strscan.current_line_number
54
+ while (temp = strscan.scan_until(regexps.last))
55
+ abbr_lineno = strscan.current_line_number
56
+ abbr = strscan.scan(regexps.first) # begin of line case of abbr with \W char as first one
57
+ if abbr.nil?
58
+ temp << strscan.scan(/\W|^/)
59
+ abbr = strscan.scan(regexps.first)
60
+ end
61
+ result << Element.new(:text, temp, nil, location: text_lineno)
62
+ result << Element.new(:abbreviation, abbr, nil, location: abbr_lineno)
63
+ text_lineno = strscan.current_line_number
58
64
  end
59
- result << Element.new(:text, strscan.rest)
65
+ result << Element.new(:text, strscan.rest, nil, location: text_lineno)
60
66
  else
61
67
  child
62
68
  end
@@ -1,22 +1,9 @@
1
- # -*- coding: utf-8 -*-
1
+ # -*- coding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
5
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/>.
6
+ # This file is part of kramdown which is licensed under the MIT.
20
7
  #++
21
8
  #
22
9
 
@@ -24,21 +11,16 @@ module Kramdown
24
11
  module Parser
25
12
  class Kramdown
26
13
 
27
- if RUBY_VERSION == '1.8.5'
28
- ACHARS = '\w\x80-\xFF'
29
- elsif RUBY_VERSION < '1.9.0'
30
- ACHARS = '\w'
31
- else
32
- ACHARS = '[[:alnum:]]'
33
- end
34
- AUTOLINK_START_STR = "<((mailto|https?|ftps?):.+?|[-.#{ACHARS}]+@[-#{ACHARS}]+(?:\.[-#{ACHARS}]+)*\.[a-z]+)>"
14
+ ACHARS = '[[:alnum:]]-_.'
15
+ AUTOLINK_START_STR = "<((mailto|https?|ftps?):.+?|[#{ACHARS}]+?@[#{ACHARS}]+?)>"
35
16
  AUTOLINK_START = /#{AUTOLINK_START_STR}/u
36
17
 
37
18
  # Parse the autolink at the current location.
38
19
  def parse_autolink
20
+ start_line_number = @src.current_line_number
39
21
  @src.pos += @src.matched_size
40
22
  href = (@src[2].nil? ? "mailto:#{@src[1]}" : @src[1])
41
- el = Element.new(:a, nil, {'href' => href})
23
+ el = Element.new(:a, nil, {'href' => href}, location: start_line_number)
42
24
  add_text(@src[1].sub(/^mailto:/, ''), el)
43
25
  @tree.children << el
44
26
  end
@@ -1,22 +1,9 @@
1
- # -*- coding: utf-8 -*-
1
+ # -*- coding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
4
- # Copyright (C) 2009-2012 Thomas Leitner <t_leitner@gmx.at>
4
+ # Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
5
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/>.
6
+ # This file is part of kramdown which is licensed under the MIT.
20
7
  #++
21
8
  #
22
9
 
@@ -24,13 +11,13 @@ module Kramdown
24
11
  module Parser
25
12
  class Kramdown
26
13
 
27
- BLANK_LINE = /(?:^\s*\n)+/
14
+ BLANK_LINE = /(?>^\s*\n)+/
28
15
 
29
16
  # Parse the blank line at the current postition.
30
17
  def parse_blank_line
31
18
  @src.pos += @src.matched_size
32
- if @tree.children.last && @tree.children.last.type == :blank
33
- @tree.children.last.value << @src.matched
19
+ if (last_child = @tree.children.last) && last_child.type == :blank
20
+ last_child.value << @src.matched
34
21
  else
35
22
  @tree.children << new_block_el(:blank, @src.matched)
36
23
  end