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,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
 
@@ -32,8 +19,9 @@ module Kramdown
32
19
 
33
20
  # Return +true+ if we are after a block boundary.
34
21
  def after_block_boundary?
35
- !@tree.children.last || @tree.children.last.type == :blank ||
36
- (@tree.children.last.type == :eob && @tree.children.last.value.nil?) || @block_ial
22
+ last_child = @tree.children.last
23
+ !last_child || last_child.type == :blank ||
24
+ (last_child.type == :eob && last_child.value.nil?) || @block_ial
37
25
  end
38
26
 
39
27
  # Return +true+ if we are before a block boundary.
@@ -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
 
@@ -32,20 +19,20 @@ module Kramdown
32
19
 
33
20
  # Parse the blockquote at the current location.
34
21
  def parse_blockquote
22
+ start_line_number = @src.current_line_number
35
23
  result = @src.scan(PARAGRAPH_MATCH)
36
- while !@src.match?(self.class::LAZY_END)
24
+ until @src.match?(self.class::LAZY_END)
37
25
  result << @src.scan(PARAGRAPH_MATCH)
38
26
  end
39
27
  result.gsub!(BLOCKQUOTE_START, '')
40
28
 
41
- el = new_block_el(:blockquote)
29
+ el = new_block_el(:blockquote, nil, nil, location: start_line_number)
42
30
  @tree.children << el
43
31
  parse_blocks(el, result)
44
32
  true
45
33
  end
46
34
  define_parser(:blockquote, BLOCKQUOTE_START)
47
35
 
48
-
49
36
  end
50
37
  end
51
38
  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
 
@@ -30,29 +17,33 @@ module Kramdown
30
17
  class Kramdown
31
18
 
32
19
  CODEBLOCK_START = INDENT
33
- CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{BLANK_LINE} {0,3}\S|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/
20
+ CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/
34
21
 
35
22
  # Parse the indented codeblock at the current location.
36
23
  def parse_codeblock
24
+ start_line_number = @src.current_line_number
37
25
  data = @src.scan(self.class::CODEBLOCK_MATCH)
38
26
  data.gsub!(/\n( {0,3}\S)/, ' \\1')
39
27
  data.gsub!(INDENT, '')
40
- @tree.children << new_block_el(:codeblock, data)
28
+ @tree.children << new_block_el(:codeblock, data, nil, location: start_line_number)
41
29
  true
42
30
  end
43
31
  define_parser(:codeblock, CODEBLOCK_START)
44
32
 
45
-
46
33
  FENCED_CODEBLOCK_START = /^~{3,}/
47
- FENCED_CODEBLOCK_MATCH = /^(~{3,})\s*?(\w+)?\s*?\n(.*?)^\1~*\s*?\n/m
34
+ FENCED_CODEBLOCK_MATCH = /^((~){3,})\s*?((\S+?)(?:\?\S*)?)?\s*?\n(.*?)^\1\2*\s*?\n/m
48
35
 
49
36
  # Parse the fenced codeblock at the current location.
50
37
  def parse_codeblock_fenced
51
- if @src.check(FENCED_CODEBLOCK_MATCH)
38
+ if @src.check(self.class::FENCED_CODEBLOCK_MATCH)
39
+ start_line_number = @src.current_line_number
52
40
  @src.pos += @src.matched_size
53
- el = new_block_el(:codeblock, @src[3])
54
- lang = @src[2].to_s.strip
55
- el.attr['class'] = "language-#{lang}" unless lang.empty?
41
+ el = new_block_el(:codeblock, @src[5], nil, location: start_line_number, fenced: true)
42
+ lang = @src[3].to_s.strip
43
+ unless lang.empty?
44
+ el.options[:lang] = lang
45
+ el.attr['class'] = "language-#{@src[4]}"
46
+ end
56
47
  @tree.children << el
57
48
  true
58
49
  else
@@ -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,24 +15,35 @@ module Kramdown
28
15
 
29
16
  # Parse the codespan at the current scanner location.
30
17
  def parse_codespan
18
+ start_line_number = @src.current_line_number
31
19
  result = @src.scan(CODESPAN_DELIMITER)
32
20
  simple = (result.length == 1)
33
- reset_pos = @src.pos
21
+ saved_pos = @src.save_pos
34
22
 
35
23
  if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
36
24
  add_text(result)
37
25
  return
38
26
  end
39
27
 
40
- if text = @src.scan_until(/#{result}/)
41
- text.sub!(/#{result}\Z/, '')
42
- if !simple
28
+ # assign static regex to avoid allocating the same on every instance
29
+ # where +result+ equals a single-backtick. Interpolate otherwise.
30
+ if result == '`'
31
+ scan_pattern = /`/
32
+ str_sub_pattern = /`\Z/
33
+ else
34
+ scan_pattern = /#{result}/
35
+ str_sub_pattern = /#{result}\Z/
36
+ end
37
+
38
+ if (text = @src.scan_until(scan_pattern))
39
+ text.sub!(str_sub_pattern, '')
40
+ unless simple
43
41
  text = text[1..-1] if text[0..0] == ' '
44
42
  text = text[0..-2] if text[-1..-1] == ' '
45
43
  end
46
- @tree.children << Element.new(:codespan, text)
44
+ @tree.children << Element.new(:codespan, text, nil, location: start_line_number)
47
45
  else
48
- @src.pos = reset_pos
46
+ @src.revert_pos(saved_pos)
49
47
  add_text(result)
50
48
  end
51
49
  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
 
@@ -28,38 +15,42 @@ module Kramdown
28
15
 
29
16
  # Parse the emphasis at the current location.
30
17
  def parse_emphasis
18
+ start_line_number = @src.current_line_number
19
+ saved_pos = @src.save_pos
20
+
31
21
  result = @src.scan(EMPHASIS_START)
32
22
  element = (result.length == 2 ? :strong : :em)
33
23
  type = result[0..0]
34
- reset_pos = @src.pos
35
24
 
36
- if (type == '_' && @src.pre_match =~ /[[:alpha:]]\z/ && @src.check(/[[:alpha:]]/)) || @src.check(/\s/) ||
37
- @tree.type == element || @stack.any? {|el, _| el.type == element}
25
+ if (type == '_' && @src.pre_match =~ /[[:alpha:]]-?[[:alpha:]]*\z/) || @src.check(/\s/) ||
26
+ @tree.type == element || @stack.any? {|el, _| el.type == element }
38
27
  add_text(result)
39
28
  return
40
29
  end
41
30
 
42
31
  sub_parse = lambda do |delim, elem|
43
- el = Element.new(elem)
32
+ el = Element.new(elem, nil, nil, location: start_line_number)
44
33
  stop_re = /#{Regexp.escape(delim)}/
45
34
  found = parse_spans(el, stop_re) do
46
35
  (@src.pre_match[-1, 1] !~ /\s/) &&
47
- (elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) &&
48
- (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alpha:]]/)) && el.children.size > 0
36
+ (elem != :em || !@src.match?(/#{Regexp.escape(delim * 2)}(?!#{Regexp.escape(delim)})/)) &&
37
+ (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && !el.children.empty?
49
38
  end
50
39
  [found, el, stop_re]
51
40
  end
52
41
 
53
42
  found, el, stop_re = sub_parse.call(result, element)
54
43
  if !found && element == :strong && @tree.type != :em
55
- @src.pos = reset_pos - 1
44
+ @src.revert_pos(saved_pos)
45
+ @src.pos += 1
56
46
  found, el, stop_re = sub_parse.call(type, :em)
57
47
  end
58
48
  if found
59
49
  @src.scan(stop_re)
60
50
  @tree.children << el
61
51
  else
62
- @src.pos = reset_pos
52
+ @src.revert_pos(saved_pos)
53
+ @src.pos += result.length
63
54
  add_text(result)
64
55
  end
65
56
  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
 
@@ -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
 
@@ -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
 
@@ -29,28 +16,33 @@ module Kramdown
29
16
  # Parse the string +str+ and extract all attributes and add all found attributes to the hash
30
17
  # +opts+.
31
18
  def parse_attribute_list(str, opts)
32
- str.scan(ALD_TYPE_ANY).each do |key, sep, val, id_attr, class_attr, ref|
19
+ return if str.strip.empty? || str.strip == ':'
20
+ attrs = str.scan(ALD_TYPE_ANY)
21
+ attrs.each do |key, sep, val, ref, id_and_or_class, _, _|
33
22
  if ref
34
23
  (opts[:refs] ||= []) << ref
35
- elsif class_attr
36
- opts[IAL_CLASS_ATTR] = (opts[IAL_CLASS_ATTR] || '') << " #{class_attr}"
37
- opts[IAL_CLASS_ATTR].lstrip!
38
- elsif id_attr
39
- opts['id'] = id_attr
24
+ elsif id_and_or_class
25
+ id_and_or_class.scan(ALD_TYPE_ID_OR_CLASS).each do |id_attr, class_attr|
26
+ if class_attr
27
+ opts[IAL_CLASS_ATTR] = "#{opts[IAL_CLASS_ATTR]} #{class_attr}".lstrip
28
+ else
29
+ opts['id'] = id_attr
30
+ end
31
+ end
40
32
  else
41
33
  val.gsub!(/\\(\}|#{sep})/, "\\1")
42
34
  opts[key] = val
43
35
  end
44
36
  end
37
+ warning("No or invalid attributes found in IAL/ALD content: #{str}") if attrs.empty?
45
38
  end
46
39
 
47
40
  # Update the +ial+ with the information from the inline attribute list +opts+.
48
41
  def update_ial_with_ial(ial, opts)
49
- (ial[:refs] ||= []) << opts[:refs]
50
- opts.each do |k,v|
42
+ (ial[:refs] ||= []).concat(opts[:refs]) if opts.key?(:refs)
43
+ opts.each do |k, v|
51
44
  if k == IAL_CLASS_ATTR
52
- ial[k] = (ial[k] || '') << " #{v}"
53
- ial[k].lstrip!
45
+ ial[k] = "#{ial[k]} #{v}".lstrip
54
46
  elsif k.kind_of?(String)
55
47
  ial[k] = v
56
48
  end
@@ -60,19 +52,21 @@ module Kramdown
60
52
  # Parse the generic extension at the current point. The parameter +type+ can either be :block
61
53
  # or :span depending whether we parse a block or span extension tag.
62
54
  def parse_extension_start_tag(type)
63
- orig_pos = @src.pos
55
+ saved_pos = @src.save_pos
56
+ start_line_number = @src.current_line_number
64
57
  @src.pos += @src.matched_size
65
58
 
66
59
  error_block = lambda do |msg|
67
60
  warning(msg)
68
- @src.pos = orig_pos
61
+ @src.revert_pos(saved_pos)
69
62
  add_text(@src.getch) if type == :span
70
63
  false
71
64
  end
72
65
 
73
66
  if @src[4] || @src.matched == '{:/}'
74
67
  name = (@src[4] ? "for '#{@src[4]}' " : '')
75
- return error_block.call("Invalid extension stop tag #{name}found - ignoring it")
68
+ return error_block.call("Invalid extension stop tag #{name} found on line " \
69
+ "#{start_line_number} - ignoring it")
76
70
  end
77
71
 
78
72
  ext = @src[1]
@@ -80,64 +74,79 @@ module Kramdown
80
74
  body = nil
81
75
  parse_attribute_list(@src[2] || '', opts)
82
76
 
83
- if !@src[3]
77
+ unless @src[3]
84
78
  stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/)
85
- if result = @src.scan_until(stop_re)
79
+ if (result = @src.scan_until(stop_re))
86
80
  body = result.sub!(stop_re, '')
87
81
  body.chomp! if type == :block
88
82
  else
89
- return error_block.call("No stop tag for extension '#{ext}' found - ignoring it")
83
+ return error_block.call("No stop tag for extension '#{ext}' found on line " \
84
+ "#{start_line_number} - ignoring it")
90
85
  end
91
86
  end
92
87
 
93
- if !handle_extension(ext, opts, body, type)
94
- error_block.call("Invalid extension with name '#{ext}' specified - ignoring it")
88
+ if !handle_extension(ext, opts, body, type, start_line_number)
89
+ error_block.call("Invalid extension with name '#{ext}' specified on line " \
90
+ "#{start_line_number} - ignoring it")
95
91
  else
96
92
  true
97
93
  end
98
94
  end
99
95
 
100
- def handle_extension(name, opts, body, type)
96
+ def handle_extension(name, opts, body, type, line_no = nil)
101
97
  case name
102
98
  when 'comment'
103
- @tree.children << Element.new(:comment, body, nil, :category => type) if body.kind_of?(String)
99
+ if body.kind_of?(String)
100
+ @tree.children << Element.new(:comment, body, nil, category: type, location: line_no)
101
+ end
104
102
  true
105
103
  when 'nomarkdown'
106
- @tree.children << Element.new(:raw, body, nil, :category => type, :type => opts['type'].to_s.split(/\s+/)) if body.kind_of?(String)
104
+ if body.kind_of?(String)
105
+ @tree.children << Element.new(:raw, body, nil, category: type,
106
+ location: line_no, type: opts['type'].to_s.split(/\s+/))
107
+ end
107
108
  true
108
109
  when 'options'
109
- opts.select do |k,v|
110
+ opts.select do |k, v|
110
111
  k = k.to_sym
111
112
  if Kramdown::Options.defined?(k)
113
+ if @options[:forbidden_inline_options].include?(k) ||
114
+ k == :forbidden_inline_options
115
+ warning("Option #{k} may not be set inline")
116
+ next false
117
+ end
118
+
112
119
  begin
113
120
  val = Kramdown::Options.parse(k, v)
114
121
  @options[k] = val
115
122
  (@root.options[:options] ||= {})[k] = val
116
- rescue
123
+ rescue StandardError
117
124
  end
118
125
  false
119
126
  else
120
127
  true
121
128
  end
122
- end.each do |k,v|
129
+ end.each do |k, _v|
123
130
  warning("Unknown kramdown option '#{k}'")
124
131
  end
125
- @tree.children << Element.new(:eob, :extension) if type == :block
132
+ @tree.children << new_block_el(:eob, :extension) if type == :block
126
133
  true
127
134
  else
128
135
  false
129
136
  end
130
137
  end
131
138
 
132
-
133
139
  ALD_ID_CHARS = /[\w-]/
134
140
  ALD_ANY_CHARS = /\\\}|[^\}]/
135
141
  ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/
142
+ ALD_CLASS_NAME = /[^\s\.#]+/
136
143
  ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/
137
- ALD_TYPE_CLASS_NAME = /\.(#{ALD_ID_NAME})/
138
- ALD_TYPE_ID_NAME = /#(\w[\w:-]*)/
144
+ ALD_TYPE_CLASS_NAME = /\.(#{ALD_CLASS_NAME})/
145
+ ALD_TYPE_ID_NAME = /#([A-Za-z][\w:-]*)/
146
+ ALD_TYPE_ID_OR_CLASS = /#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}/
147
+ ALD_TYPE_ID_OR_CLASS_MULTI = /((?:#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME})+)/
139
148
  ALD_TYPE_REF = /(#{ALD_ID_NAME})/
140
- ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}|#{ALD_TYPE_REF})(?=\s|\Z)/
149
+ ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_REF}|#{ALD_TYPE_ID_OR_CLASS_MULTI})(?=\s|\Z)/
141
150
  ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/
142
151
 
143
152
  EXT_STOP_STR = "\\{:/(%s)?\\}"
@@ -154,17 +163,19 @@ module Kramdown
154
163
  # location.
155
164
  def parse_block_extensions
156
165
  if @src.scan(ALD_START)
157
- parse_attribute_list(@src[2], @alds[@src[1]] ||= Utils::OrderedHash.new)
158
- @tree.children << Element.new(:eob, :ald)
166
+ parse_attribute_list(@src[2], @alds[@src[1]] ||= {})
167
+ @tree.children << new_block_el(:eob, :ald)
159
168
  true
160
169
  elsif @src.check(EXT_BLOCK_START)
161
170
  parse_extension_start_tag(:block)
162
171
  elsif @src.scan(IAL_BLOCK_START)
163
- if @tree.children.last && @tree.children.last.type != :blank && @tree.children.last.type != :eob
164
- parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= Utils::OrderedHash.new)
165
- @tree.children << Element.new(:eob, :ial) unless @src.check(IAL_BLOCK_START)
172
+ if (last_child = @tree.children.last) && last_child.type != :blank &&
173
+ (last_child.type != :eob ||
174
+ [:link_def, :abbrev_def, :footnote_def].include?(last_child.value))
175
+ parse_attribute_list(@src[1], last_child.options[:ial] ||= {})
176
+ @tree.children << new_block_el(:eob, :ial) unless @src.check(IAL_BLOCK_START)
166
177
  else
167
- parse_attribute_list(@src[1], @block_ial = Utils::OrderedHash.new)
178
+ parse_attribute_list(@src[1], @block_ial ||= {})
168
179
  end
169
180
  true
170
181
  else
@@ -173,7 +184,6 @@ module Kramdown
173
184
  end
174
185
  define_parser(:block_extensions, BLOCK_EXTENSIONS_START)
175
186
 
176
-
177
187
  EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/
178
188
  IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/
179
189
  SPAN_EXTENSIONS_START = /\{:/
@@ -183,12 +193,12 @@ module Kramdown
183
193
  if @src.check(EXT_SPAN_START)
184
194
  parse_extension_start_tag(:span)
185
195
  elsif @src.check(IAL_SPAN_START)
186
- if @tree.children.last && @tree.children.last.type != :text
196
+ if (last_child = @tree.children.last) && last_child.type != :text
187
197
  @src.pos += @src.matched_size
188
- attr = Utils::OrderedHash.new
198
+ attr = {}
189
199
  parse_attribute_list(@src[1], attr)
190
- update_ial_with_ial(@tree.children.last.options[:ial] ||= Utils::OrderedHash.new, attr)
191
- update_attr_with_ial(@tree.children.last.attr, attr)
200
+ update_ial_with_ial(last_child.options[:ial] ||= {}, attr)
201
+ update_attr_with_ial(last_child.attr, attr)
192
202
  else
193
203
  warning("Found span IAL after text - ignoring it")
194
204
  add_text(@src.getch)