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
 
@@ -30,33 +17,34 @@ module Kramdown
30
17
 
31
18
  # Parse the math block at the current location.
32
19
  def parse_block_math
20
+ start_line_number = @src.current_line_number
33
21
  if !after_block_boundary?
34
22
  return false
35
23
  elsif @src[1]
36
- @src.scan(/^#{OPT_SPACE}\\/) if @src[3]
24
+ @src.scan(/^#{OPT_SPACE}\\/o) if @src[3]
37
25
  return false
38
26
  end
39
27
 
40
- orig_pos = @src.pos
28
+ saved_pos = @src.save_pos
41
29
  @src.pos += @src.matched_size
42
- data = @src[2]
30
+ data = @src[2].strip
43
31
  if before_block_boundary?
44
- @tree.children << new_block_el(:math, data, nil, :category => :block)
32
+ @tree.children << new_block_el(:math, data, nil, category: :block, location: start_line_number)
45
33
  true
46
34
  else
47
- @src.pos = orig_pos
35
+ @src.revert_pos(saved_pos)
48
36
  false
49
37
  end
50
38
  end
51
39
  define_parser(:block_math, BLOCK_MATH_START)
52
40
 
53
-
54
- INLINE_MATH_START = /\$\$(.*?)\$\$/
41
+ INLINE_MATH_START = /\$\$(.*?)\$\$/m
55
42
 
56
43
  # Parse the inline math at the current location.
57
44
  def parse_inline_math
45
+ start_line_number = @src.current_line_number
58
46
  @src.pos += @src.matched_size
59
- @tree.children << Element.new(:math, @src[1], nil, :category => :span)
47
+ @tree.children << Element.new(:math, @src[1].strip, nil, category: :span, location: start_line_number)
60
48
  end
61
49
  define_parser(:inline_math, INLINE_MATH_START, '\$')
62
50
 
@@ -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,8 +17,8 @@ module Kramdown
30
17
  module Parser
31
18
  class Kramdown
32
19
 
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
20
+ LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w[script]
21
+ LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})/
35
22
  LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m
36
23
 
37
24
  LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/
@@ -42,22 +29,34 @@ module Kramdown
42
29
 
43
30
  # Parse the paragraph at the current location.
44
31
  def parse_paragraph
32
+ pos = @src.pos
33
+ start_line_number = @src.current_line_number
45
34
  result = @src.scan(PARAGRAPH_MATCH)
46
- while !@src.match?(self.class::PARAGRAPH_END)
35
+ until @src.match?(paragraph_end)
47
36
  result << @src.scan(PARAGRAPH_MATCH)
48
37
  end
49
- result.chomp!
50
- if @tree.children.last && @tree.children.last.type == :p
51
- @tree.children.last.children.first.value << "\n" << result
38
+ result.rstrip!
39
+ if (last_child = @tree.children.last) && last_child.type == :p
40
+ last_item_in_para = last_child.children.last
41
+ if last_item_in_para && last_item_in_para.type == @text_type
42
+ joiner = (extract_string((pos - 3)...pos, @src) == " \n" ? " \n" : "\n")
43
+ last_item_in_para.value << joiner << result
44
+ else
45
+ add_text(result, last_child)
46
+ end
52
47
  else
53
- @tree.children << new_block_el(:p)
48
+ @tree.children << new_block_el(:p, nil, nil, location: start_line_number)
54
49
  result.lstrip!
55
- @tree.children.last.children << Element.new(@text_type, result)
50
+ add_text(result, @tree.children.last)
56
51
  end
57
52
  true
58
53
  end
59
54
  define_parser(:paragraph, PARAGRAPH_START)
60
55
 
56
+ def paragraph_end
57
+ self.class::PARAGRAPH_END
58
+ end
59
+
61
60
  end
62
61
  end
63
62
  end
@@ -1,55 +1,13 @@
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
- # 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
10
+ # Parts of this file are based on code from RubyPants:
53
11
  #
54
12
  # = RubyPants -- SmartyPants ported to Ruby
55
13
  #
@@ -164,24 +122,25 @@ module Kramdown
164
122
  SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
165
123
 
166
124
  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]],
125
+ [/("|')(?=[_*]{1,2}\S)/, [:lquote1]],
126
+ [/("|')(?=#{SQ_PUNCT}(?!\.\.)\B)/, [:rquote1]],
127
+ # Special case for double sets of quotes, e.g.:
128
+ # <p>He said, "'Quoted' words in a larger quote."</p>
129
+ [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]],
130
+ [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]],
131
+ # Special case for decade abbreviations (the '80s):
132
+ [/(\s?)'(?=\d\ds)/, [1, :rsquo]],
174
133
 
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
- ] #'"
134
+ # Get most opening single/double quotes:
135
+ [/(\s)('|")(?=\w)/, [1, :lquote2]],
136
+ # Single/double closing quotes:
137
+ [/(#{SQ_CLOSE})('|")/, [1, :rquote2]],
138
+ # Special case for e.g. "<i>Custer</i>'s Last Stand."
139
+ [/("|')(?=\s|s\b|$)/, [:rquote1]],
140
+ # Any remaining single quotes should be opening ones:
141
+ [/(.?)'/m, [1, :lsquo]],
142
+ [/(.?)"/m, [1, :ldquo]],
143
+ ] # '"
185
144
 
186
145
  SQ_SUBSTS = {
187
146
  [:rquote1, '"'] => :rdquo,
@@ -197,13 +156,14 @@ module Kramdown
197
156
 
198
157
  # Parse the smart quotes at current location.
199
158
  def parse_smart_quotes
200
- substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1]
159
+ start_line_number = @src.current_line_number
160
+ substs = SQ_RULES.find {|reg, _subst| @src.scan(reg) }[1]
201
161
  substs.each do |subst|
202
162
  if subst.kind_of?(Integer)
203
163
  add_text(@src[subst])
204
164
  else
205
- val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst
206
- @tree.children << Element.new(:smart_quote, val)
165
+ val = SQ_SUBSTS[[subst, @src[subst.to_s[-1, 1].to_i]]] || subst
166
+ @tree.children << Element.new(:smart_quote, val, nil, location: start_line_number)
207
167
  end
208
168
  end
209
169
  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
 
@@ -26,9 +13,9 @@ module Kramdown
26
13
  module Parser
27
14
  class Kramdown
28
15
 
29
- TABLE_SEP_LINE = /^([+|: -]*?-[+|: -]*?)[ \t]*\n/
30
- TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
31
- TABLE_FSEP_LINE = /^[+|: =]*?=[+|: =]*?[ \t]*\n/
16
+ TABLE_SEP_LINE = /^([+|: \t-]*?-[+|: \t-]*?)[ \t]*\n/
17
+ TABLE_HSEP_ALIGN = /[ \t]?(:?)-+(:?)[ \t]?/
18
+ TABLE_FSEP_LINE = /^[+|: \t=]*?=[+|: \t=]*?[ \t]*\n/
32
19
  TABLE_ROW_LINE = /^(.*?)[ \t]*\n/
33
20
  TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/
34
21
  TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/
@@ -36,10 +23,11 @@ module Kramdown
36
23
 
37
24
  # Parse the table at the current location.
38
25
  def parse_table
39
- return false if !after_block_boundary?
26
+ return false unless after_block_boundary?
40
27
 
28
+ saved_pos = @src.save_pos
41
29
  orig_pos = @src.pos
42
- table = new_block_el(:table, nil, nil, :alignment => [])
30
+ table = new_block_el(:table, nil, nil, alignment: [], location: @src.current_line_number)
43
31
  leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
44
32
  @src.scan(TABLE_SEP_LINE)
45
33
 
@@ -55,19 +43,22 @@ module Kramdown
55
43
  end
56
44
  end
57
45
 
58
- while !@src.eos?
59
- break if !@src.check(TABLE_LINE)
60
- if @src.scan(TABLE_SEP_LINE) && !rows.empty?
61
- if table.options[:alignment].empty? && !has_footer
46
+ until @src.eos?
47
+ break unless @src.check(TABLE_LINE)
48
+ if @src.scan(TABLE_SEP_LINE)
49
+ if rows.empty?
50
+ # nothing to do, ignoring multiple consecutive separator lines
51
+ elsif table.options[:alignment].empty? && !has_footer
62
52
  add_container.call(:thead, false)
63
53
  table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
64
- (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
54
+ (left.empty? && right.empty? && :default) || (right.empty? && :left) ||
55
+ (left.empty? && :right) || :center
65
56
  end
66
57
  else # treat as normal separator line
67
58
  add_container.call(:tbody, false)
68
59
  end
69
60
  elsif @src.scan(TABLE_FSEP_LINE)
70
- add_container.call(:tbody, true) if !rows.empty?
61
+ add_container.call(:tbody, true) unless rows.empty?
71
62
  has_footer = true
72
63
  elsif @src.scan(TABLE_ROW_LINE)
73
64
  trow = Element.new(:tr)
@@ -76,25 +67,21 @@ module Kramdown
76
67
  env = save_env
77
68
  cells = []
78
69
  @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
79
- if i % 2 == 1
70
+ if i.odd?
80
71
  (cells.empty? ? cells : cells.last) << str
81
72
  else
82
- reset_env(:src => StringScanner.new(str))
73
+ reset_env(src: Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
83
74
  root = Element.new(:root)
84
75
  parse_spans(root, nil, [:codespan])
85
76
 
86
77
  root.children.each do |c|
87
78
  if c.type == :raw_text
88
- # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
89
- f, *l = c.value.split(/\\\|/, -1).map {|t| t.split(/\|/, -1)}.inject([]) do |memo, t|
90
- memo.last << "|#{t.shift}" if memo.size > 0
91
- memo.concat(t)
92
- end
79
+ f, *l = c.value.split(/(?<!\\)\|/, -1).map {|t| t.gsub(/\\\|/, '|') }
93
80
  (cells.empty? ? cells : cells.last) << f
94
81
  cells.concat(l)
95
82
  else
96
83
  delim = (c.value.scan(/`+/).max || '') + '`'
97
- tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
84
+ tmp = +"#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
98
85
  (cells.empty? ? cells : cells.last) << tmp
99
86
  end
100
87
  end
@@ -116,22 +103,28 @@ module Kramdown
116
103
  end
117
104
  end
118
105
 
119
- if !before_block_boundary?
120
- @src.pos = orig_pos
106
+ unless before_block_boundary?
107
+ @src.revert_pos(saved_pos)
121
108
  return false
122
109
  end
123
110
 
124
111
  # Parse all lines of the table with the code span parser
125
112
  env = save_env
126
- reset_env(:src => StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src)))
113
+ l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos - 1), @src),
114
+ @src.current_line_number)
115
+ reset_env(src: l_src)
127
116
  root = Element.new(:root)
128
- parse_spans(root, nil, [:codespan])
117
+ parse_spans(root, nil, [:codespan, :span_html])
129
118
  restore_env(env)
130
119
 
131
- # Check if each line has at least one unescaped backslash that is not inside a code span
120
+ # Check if each line has at least one unescaped pipe that is not inside a code span/code
121
+ # HTML element
122
+ # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting
123
+ # algorithm above only takes <code> elements into account!
132
124
  pipe_on_line = false
133
125
  while (c = root.children.shift)
134
- lines = c.value.split(/\n/)
126
+ next unless (lines = c.value)
127
+ lines = lines.split("\n")
135
128
  if c.type == :codespan
136
129
  if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
137
130
  break
@@ -139,17 +132,17 @@ module Kramdown
139
132
  pipe_on_line = false
140
133
  end
141
134
  else
142
- break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
143
- pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
135
+ break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/o
136
+ pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/o)
144
137
  end
145
138
  end
146
- @src.pos = orig_pos and return false if !pipe_on_line
139
+ @src.revert_pos(saved_pos) and return false unless pipe_on_line
147
140
 
148
- add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
141
+ add_container.call(has_footer ? :tfoot : :tbody, false) unless rows.empty?
149
142
 
150
- if !table.children.any? {|el| el.type == :tbody}
151
- warning("Found table without body - ignoring it")
152
- @src.pos = orig_pos
143
+ if table.children.none? {|el| el.type == :tbody }
144
+ warning("Found table without body on line #{table.options[:location]} - ignoring it")
145
+ @src.revert_pos(saved_pos)
153
146
  return false
154
147
  end
155
148
 
@@ -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,20 +16,25 @@ module Kramdown
29
16
  ['<< ', :laquo_space], [' >>', :raquo_space],
30
17
  ['<<', :laquo], ['>>', :raquo]]
31
18
  TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten]
32
- TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/
19
+ TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k, _v| Regexp.escape(k) }.join('|')}/
33
20
 
34
21
  # Parse the typographic symbols at the current location.
35
22
  def parse_typographic_syms
23
+ start_line_number = @src.current_line_number
36
24
  @src.pos += @src.matched_size
37
25
  val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
38
26
  if val.kind_of?(Symbol)
39
- @tree.children << Element.new(:typographic_sym, val)
27
+ @tree.children << Element.new(:typographic_sym, val, nil, location: start_line_number)
40
28
  elsif @src.matched == '\\<<'
41
- @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'))
42
- @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'))
29
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
30
+ nil, location: start_line_number)
31
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
32
+ nil, location: start_line_number)
43
33
  else
44
- @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'))
45
- @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'))
34
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
35
+ nil, location: start_line_number)
36
+ @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
37
+ nil, location: start_line_number)
46
38
  end
47
39
  end
48
40
  define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)')