motion-kramdown 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +84 -0
  3. data/lib/kramdown/compatibility.rb +36 -0
  4. data/lib/kramdown/converter/base.rb +259 -0
  5. data/lib/kramdown/converter/html.rb +461 -0
  6. data/lib/kramdown/converter/kramdown.rb +423 -0
  7. data/lib/kramdown/converter/latex.rb +600 -0
  8. data/lib/kramdown/converter/math_engine/itex2mml.rb +39 -0
  9. data/lib/kramdown/converter/math_engine/mathjax.rb +33 -0
  10. data/lib/kramdown/converter/math_engine/ritex.rb +38 -0
  11. data/lib/kramdown/converter/pdf.rb +624 -0
  12. data/lib/kramdown/converter/remove_html_tags.rb +53 -0
  13. data/lib/kramdown/converter/syntax_highlighter/coderay.rb +78 -0
  14. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +37 -0
  15. data/lib/kramdown/converter/toc.rb +69 -0
  16. data/lib/kramdown/converter.rb +69 -0
  17. data/lib/kramdown/document.rb +144 -0
  18. data/lib/kramdown/element.rb +515 -0
  19. data/lib/kramdown/error.rb +17 -0
  20. data/lib/kramdown/options.rb +584 -0
  21. data/lib/kramdown/parser/base.rb +130 -0
  22. data/lib/kramdown/parser/gfm.rb +55 -0
  23. data/lib/kramdown/parser/html.rb +575 -0
  24. data/lib/kramdown/parser/kramdown/abbreviation.rb +67 -0
  25. data/lib/kramdown/parser/kramdown/autolink.rb +37 -0
  26. data/lib/kramdown/parser/kramdown/blank_line.rb +30 -0
  27. data/lib/kramdown/parser/kramdown/block_boundary.rb +33 -0
  28. data/lib/kramdown/parser/kramdown/blockquote.rb +39 -0
  29. data/lib/kramdown/parser/kramdown/codeblock.rb +56 -0
  30. data/lib/kramdown/parser/kramdown/codespan.rb +44 -0
  31. data/lib/kramdown/parser/kramdown/emphasis.rb +61 -0
  32. data/lib/kramdown/parser/kramdown/eob.rb +26 -0
  33. data/lib/kramdown/parser/kramdown/escaped_chars.rb +25 -0
  34. data/lib/kramdown/parser/kramdown/extensions.rb +201 -0
  35. data/lib/kramdown/parser/kramdown/footnote.rb +56 -0
  36. data/lib/kramdown/parser/kramdown/header.rb +59 -0
  37. data/lib/kramdown/parser/kramdown/horizontal_rule.rb +27 -0
  38. data/lib/kramdown/parser/kramdown/html.rb +160 -0
  39. data/lib/kramdown/parser/kramdown/html_entity.rb +33 -0
  40. data/lib/kramdown/parser/kramdown/line_break.rb +25 -0
  41. data/lib/kramdown/parser/kramdown/link.rb +139 -0
  42. data/lib/kramdown/parser/kramdown/list.rb +256 -0
  43. data/lib/kramdown/parser/kramdown/math.rb +54 -0
  44. data/lib/kramdown/parser/kramdown/paragraph.rb +54 -0
  45. data/lib/kramdown/parser/kramdown/smart_quotes.rb +174 -0
  46. data/lib/kramdown/parser/kramdown/table.rb +171 -0
  47. data/lib/kramdown/parser/kramdown/typographic_symbol.rb +44 -0
  48. data/lib/kramdown/parser/kramdown.rb +359 -0
  49. data/lib/kramdown/parser/markdown.rb +56 -0
  50. data/lib/kramdown/parser.rb +27 -0
  51. data/lib/kramdown/utils/configurable.rb +44 -0
  52. data/lib/kramdown/utils/entities.rb +347 -0
  53. data/lib/kramdown/utils/html.rb +75 -0
  54. data/lib/kramdown/utils/ordered_hash.rb +87 -0
  55. data/lib/kramdown/utils/string_scanner.rb +74 -0
  56. data/lib/kramdown/utils/unidecoder.rb +51 -0
  57. data/lib/kramdown/utils.rb +58 -0
  58. data/lib/kramdown/version.rb +15 -0
  59. data/lib/kramdown.rb +10 -0
  60. data/lib/motion-kramdown.rb +47 -0
  61. data/lib/rubymotion/encodings.rb +37 -0
  62. data/lib/rubymotion/rexml_shim.rb +25 -0
  63. data/lib/rubymotion/set.rb +1349 -0
  64. data/lib/rubymotion/version.rb +6 -0
  65. data/spec/document_tree.rb +48 -0
  66. data/spec/gfm_to_html.rb +95 -0
  67. data/spec/helpers/it_behaves_like.rb +27 -0
  68. data/spec/helpers/option_file.rb +46 -0
  69. data/spec/helpers/spec_options.rb +37 -0
  70. data/spec/helpers/tidy.rb +12 -0
  71. data/spec/html_to_html.rb +40 -0
  72. data/spec/html_to_kramdown_to_html.rb +46 -0
  73. data/spec/kramdown_to_xxx.rb +40 -0
  74. data/spec/test_location.rb +203 -0
  75. data/spec/test_string_scanner_kramdown.rb +19 -0
  76. data/spec/text_to_kramdown_to_html.rb +52 -0
  77. data/spec/text_to_latex.rb +33 -0
  78. metadata +164 -0
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2014 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+
10
+ # RM require 'kramdown/parser/kramdown/blank_line'
11
+ # RM require 'kramdown/parser/kramdown/extensions'
12
+ # RM require 'kramdown/parser/kramdown/eob'
13
+ # RM require 'kramdown/parser/kramdown/list'
14
+ # RM require 'kramdown/parser/kramdown/html'
15
+
16
+ module Kramdown
17
+ module Parser
18
+ class Kramdown
19
+
20
+ LAZY_END_HTML_SPAN_ELEMENTS = Kramdown::Parser::Html::HTML_SPAN_ELEMENTS + %w{script} # RM
21
+ 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
22
+ LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m
23
+
24
+ OPT_SPACE_LAZY_END_HTML_START = /^#{OPT_SPACE}#{LAZY_END_HTML_START}/m # RM Oniguruma -> ICU
25
+ OPT_SPACE_LAZY_END_HTML_STOP = /^#{OPT_SPACE}#{LAZY_END_HTML_STOP}/m # RM Oniguruma -> ICU
26
+
27
+ LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|#{OPT_SPACE_LAZY_END_HTML_STOP}|#{OPT_SPACE_LAZY_END_HTML_START}|\Z/ # RM
28
+
29
+ PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
30
+ PARAGRAPH_MATCH = /^.*?\n/
31
+ PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/
32
+
33
+ # Parse the paragraph at the current location.
34
+ def parse_paragraph
35
+ start_line_number = @src.current_line_number
36
+ result = @src.scan(PARAGRAPH_MATCH)
37
+ while !@src.match?(self.class::PARAGRAPH_END)
38
+ result << @src.scan(PARAGRAPH_MATCH)
39
+ end
40
+ result.chomp!
41
+ if @tree.children.last && @tree.children.last.type == :p
42
+ @tree.children.last.children.first.value << "\n" << result
43
+ else
44
+ @tree.children << new_block_el(:p, nil, nil, :location => start_line_number)
45
+ result.lstrip!
46
+ add_text(result, @tree.children.last)
47
+ end
48
+ true
49
+ end
50
+ define_parser(:paragraph, PARAGRAPH_START)
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,174 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2014 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+ #--
10
+ # Parts of this file are based on code from RubyPants:
11
+ #
12
+ # = RubyPants -- SmartyPants ported to Ruby
13
+ #
14
+ # Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
15
+ # Copyright (C) 2004 Christian Neukirchen
16
+ #
17
+ # Incooporates ideas, comments and documentation by Chad Miller
18
+ # Copyright (C) 2004 Chad Miller
19
+ #
20
+ # Original SmartyPants by John Gruber
21
+ # Copyright (C) 2003 John Gruber
22
+ #
23
+ #
24
+ # = RubyPants -- SmartyPants ported to Ruby
25
+ #
26
+ #
27
+ # [snip]
28
+ #
29
+ # == Authors
30
+ #
31
+ # John Gruber did all of the hard work of writing this software in
32
+ # Perl for Movable Type and almost all of this useful documentation.
33
+ # Chad Miller ported it to Python to use with Pyblosxom.
34
+ #
35
+ # Christian Neukirchen provided the Ruby port, as a general-purpose
36
+ # library that follows the *Cloth API.
37
+ #
38
+ #
39
+ # == Copyright and License
40
+ #
41
+ # === SmartyPants license:
42
+ #
43
+ # Copyright (c) 2003 John Gruber
44
+ # (http://daringfireball.net)
45
+ # All rights reserved.
46
+ #
47
+ # Redistribution and use in source and binary forms, with or without
48
+ # modification, are permitted provided that the following conditions
49
+ # are met:
50
+ #
51
+ # * Redistributions of source code must retain the above copyright
52
+ # notice, this list of conditions and the following disclaimer.
53
+ #
54
+ # * Redistributions in binary form must reproduce the above copyright
55
+ # notice, this list of conditions and the following disclaimer in
56
+ # the documentation and/or other materials provided with the
57
+ # distribution.
58
+ #
59
+ # * Neither the name "SmartyPants" nor the names of its contributors
60
+ # may be used to endorse or promote products derived from this
61
+ # software without specific prior written permission.
62
+ #
63
+ # This software is provided by the copyright holders and contributors
64
+ # "as is" and any express or implied warranties, including, but not
65
+ # limited to, the implied warranties of merchantability and fitness
66
+ # for a particular purpose are disclaimed. In no event shall the
67
+ # copyright owner or contributors be liable for any direct, indirect,
68
+ # incidental, special, exemplary, or consequential damages (including,
69
+ # but not limited to, procurement of substitute goods or services;
70
+ # loss of use, data, or profits; or business interruption) however
71
+ # caused and on any theory of liability, whether in contract, strict
72
+ # liability, or tort (including negligence or otherwise) arising in
73
+ # any way out of the use of this software, even if advised of the
74
+ # possibility of such damage.
75
+ #
76
+ # === RubyPants license
77
+ #
78
+ # RubyPants is a derivative work of SmartyPants and smartypants.py.
79
+ #
80
+ # Redistribution and use in source and binary forms, with or without
81
+ # modification, are permitted provided that the following conditions
82
+ # are met:
83
+ #
84
+ # * Redistributions of source code must retain the above copyright
85
+ # notice, this list of conditions and the following disclaimer.
86
+ #
87
+ # * Redistributions in binary form must reproduce the above copyright
88
+ # notice, this list of conditions and the following disclaimer in
89
+ # the documentation and/or other materials provided with the
90
+ # distribution.
91
+ #
92
+ # This software is provided by the copyright holders and contributors
93
+ # "as is" and any express or implied warranties, including, but not
94
+ # limited to, the implied warranties of merchantability and fitness
95
+ # for a particular purpose are disclaimed. In no event shall the
96
+ # copyright owner or contributors be liable for any direct, indirect,
97
+ # incidental, special, exemplary, or consequential damages (including,
98
+ # but not limited to, procurement of substitute goods or services;
99
+ # loss of use, data, or profits; or business interruption) however
100
+ # caused and on any theory of liability, whether in contract, strict
101
+ # liability, or tort (including negligence or otherwise) arising in
102
+ # any way out of the use of this software, even if advised of the
103
+ # possibility of such damage.
104
+ #
105
+ # == Links
106
+ #
107
+ # John Gruber:: http://daringfireball.net
108
+ # SmartyPants:: http://daringfireball.net/projects/smartypants
109
+ #
110
+ # Chad Miller:: http://web.chad.org
111
+ #
112
+ # Christian Neukirchen:: http://kronavita.de/chris
113
+ #
114
+ #++
115
+ #
116
+
117
+ module Kramdown
118
+ module Parser
119
+ class Kramdown
120
+
121
+ SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
122
+ SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
123
+
124
+ SQ_RULES = [
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]],
133
+
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, 2]],
140
+ # Any remaining single quotes should be opening ones:
141
+ [/(.?)'/m, [1, :lsquo]],
142
+ [/(.?)"/m, [1, :ldquo]],
143
+ ] #'"
144
+
145
+ SQ_SUBSTS = {
146
+ [:rquote1, '"'] => :rdquo,
147
+ [:rquote1, "'"] => :rsquo,
148
+ [:rquote2, '"'] => :rdquo,
149
+ [:rquote2, "'"] => :rsquo,
150
+ [:lquote1, '"'] => :ldquo,
151
+ [:lquote1, "'"] => :lsquo,
152
+ [:lquote2, '"'] => :ldquo,
153
+ [:lquote2, "'"] => :lsquo,
154
+ }
155
+ SMART_QUOTES_RE = /[^\\]?["']/
156
+
157
+ # Parse the smart quotes at current location.
158
+ def parse_smart_quotes
159
+ start_line_number = @src.current_line_number
160
+ substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1]
161
+ substs.each do |subst|
162
+ if subst.kind_of?(Integer)
163
+ add_text(@src[subst])
164
+ else
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)
167
+ end
168
+ end
169
+ end
170
+ define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']')
171
+
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,171 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2014 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+
10
+ # RM require 'kramdown/parser/kramdown/block_boundary'
11
+
12
+ module Kramdown
13
+ module Parser
14
+ class Kramdown
15
+
16
+ TABLE_SEP_LINE = /^([+|: -]*?-[+|: -]*?)[ \t]*\n/
17
+ TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
18
+ TABLE_FSEP_LINE = /^[+|: =]*?=[+|: =]*?[ \t]*\n/
19
+ TABLE_ROW_LINE = /^(.*?)[ \t]*\n/
20
+ TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/
21
+ TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/
22
+ TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/
23
+
24
+ # Parse the table at the current location.
25
+ def parse_table
26
+ return false if !after_block_boundary?
27
+
28
+ saved_pos = @src.save_pos
29
+ orig_pos = @src.pos
30
+ table = new_block_el(:table, nil, nil, :alignment => [], :location => @src.current_line_number)
31
+ leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
32
+ @src.scan(TABLE_SEP_LINE)
33
+
34
+ rows = []
35
+ has_footer = false
36
+ columns = 0
37
+
38
+ add_container = lambda do |type, force|
39
+ if !has_footer || type != :tbody || force
40
+ cont = Element.new(type)
41
+ cont.children, rows = rows, []
42
+ table.children << cont
43
+ end
44
+ end
45
+
46
+ while !@src.eos?
47
+ break if !@src.check(TABLE_LINE)
48
+ if @src.scan(TABLE_SEP_LINE) && !rows.empty?
49
+ if table.options[:alignment].empty? && !has_footer
50
+ add_container.call(:thead, false)
51
+ table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
52
+ (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
53
+ end
54
+ else # treat as normal separator line
55
+ add_container.call(:tbody, false)
56
+ end
57
+ elsif @src.scan(TABLE_FSEP_LINE)
58
+ add_container.call(:tbody, true) if !rows.empty?
59
+ has_footer = true
60
+ elsif @src.scan(TABLE_ROW_LINE)
61
+ trow = Element.new(:tr)
62
+
63
+ # parse possible code spans on the line and correctly split the line into cells
64
+ env = save_env
65
+ cells = []
66
+ @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
67
+ if i % 2 == 1
68
+ (cells.empty? ? cells : cells.last) << str
69
+ else
70
+ reset_env(:src => Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
71
+ root = Element.new(:root)
72
+ parse_spans(root, nil, [:codespan])
73
+
74
+ root.children.each do |c|
75
+ if c.type == :raw_text
76
+ # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
77
+ f, *l = c.value.split(/\\\|/, -1).map {|t| t.split(/\|/, -1)}.inject([]) do |memo, t|
78
+ memo.last << "|#{t.shift}" if memo.size > 0
79
+ memo.concat(t)
80
+ end
81
+ (cells.empty? ? cells : cells.last) << f
82
+ cells.concat(l)
83
+ else
84
+ delim = (c.value.scan(/`+/).max || '') + '`'
85
+ tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
86
+ (cells.empty? ? cells : cells.last) << tmp
87
+ end
88
+ end
89
+ end
90
+ end
91
+ restore_env(env)
92
+
93
+ cells.shift if leading_pipe && cells.first.strip.empty?
94
+ cells.pop if cells.last.strip.empty?
95
+ cells.each do |cell_text|
96
+ tcell = Element.new(:td)
97
+ tcell.children << Element.new(:raw_text, cell_text.strip)
98
+ trow.children << tcell
99
+ end
100
+ columns = [columns, cells.length].max
101
+ rows << trow
102
+ else
103
+ break
104
+ end
105
+ end
106
+
107
+ if !before_block_boundary?
108
+ @src.revert_pos(saved_pos)
109
+ return false
110
+ end
111
+
112
+ # Parse all lines of the table with the code span parser
113
+ env = save_env
114
+ l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src),
115
+ @src.current_line_number)
116
+ reset_env(:src => l_src)
117
+ root = Element.new(:root)
118
+ parse_spans(root, nil, [:codespan, :span_html])
119
+ restore_env(env)
120
+
121
+ # Check if each line has at least one unescaped pipe that is not inside a code span/code
122
+ # HTML element
123
+ # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting
124
+ # algorithm above only takes <code> elements into account!
125
+ pipe_on_line = false
126
+ while (c = root.children.shift)
127
+ lines = c.value.split(/\n/)
128
+ if c.type == :codespan
129
+ if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
130
+ break
131
+ elsif lines.size == 2 && pipe_on_line
132
+ pipe_on_line = false
133
+ end
134
+ else
135
+ break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
136
+ pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
137
+ end
138
+ end
139
+ @src.revert_pos(saved_pos) and return false if !pipe_on_line
140
+
141
+ add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
142
+
143
+ if !table.children.any? {|el| el.type == :tbody}
144
+ warning("Found table without body on line #{table.options[:location]} - ignoring it")
145
+ @src.revert_pos(saved_pos)
146
+ return false
147
+ end
148
+
149
+ # adjust all table rows to have equal number of columns, same for alignment defs
150
+ table.children.each do |kind|
151
+ kind.children.each do |row|
152
+ (columns - row.children.length).times do
153
+ row.children << Element.new(:td)
154
+ end
155
+ end
156
+ end
157
+ if table.options[:alignment].length > columns
158
+ table.options[:alignment] = table.options[:alignment][0...columns]
159
+ else
160
+ table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
161
+ end
162
+
163
+ @tree.children << table
164
+
165
+ true
166
+ end
167
+ define_parser(:table, TABLE_START)
168
+
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ #--
4
+ # Copyright (C) 2009-2014 Thomas Leitner <t_leitner@gmx.at>
5
+ #
6
+ # This file is part of kramdown which is licensed under the MIT.
7
+ #++
8
+ #
9
+
10
+ module Kramdown
11
+ module Parser
12
+ class Kramdown
13
+
14
+ TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :hellip],
15
+ ['\\<<', '&lt;&lt;'], ['\\>>', '&gt;&gt;'],
16
+ ['<< ', :laquo_space], [' >>', :raquo_space],
17
+ ['<<', :laquo], ['>>', :raquo]]
18
+ TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten]
19
+ TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/
20
+
21
+ # Parse the typographic symbols at the current location.
22
+ def parse_typographic_syms
23
+ start_line_number = @src.current_line_number
24
+ @src.pos += @src.matched_size
25
+ val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
26
+ if val.kind_of?(Symbol)
27
+ @tree.children << Element.new(:typographic_sym, val, nil, :location => start_line_number)
28
+ elsif @src.matched == '\\<<'
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)
33
+ else
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)
38
+ end
39
+ end
40
+ define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)')
41
+
42
+ end
43
+ end
44
+ end