motion-kramdown 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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