pot_markdown 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc4198215a42e5cd6a0036b8a54a0c26b81cbd2b
4
- data.tar.gz: b8ffad58b41b1a57cfdca3da7a593c2711fbfab5
3
+ metadata.gz: 25749f2c547bae4016ee64ba355ca02196fdb602
4
+ data.tar.gz: 7418b2154bc42f8befd82dacf38e7b3841c1c06e
5
5
  SHA512:
6
- metadata.gz: ab1aa42c91f747191b806c75c8116b309d53b655cc015b3b51c1e6a9598e8c5f358a5aba7a4312eed00d2a862ae8cf12d31342cd9872a41839168613637bf13c
7
- data.tar.gz: 8207218248059fc0a5d6ba3062d0ed2c9e76b4524147425fcfd54e85f33276d46278d4dcdaa741ad365a2ff43c84773dbd1e66fc2e1ea290979d1a5dcf391b47
6
+ metadata.gz: 25877400f6b2a83947387aabd20f16158770ecb35685369b4df861b61a3c1dfcd4d8a2eba8b0cdc5d76c206bc7bd9cc92216f2e7208b4fada401f52be3cc1977
7
+ data.tar.gz: bb66231610f8e01e1175672b58ff8a72b3891d826bd4d5c843ee884a2f51fd797a3da8a590bbd68262e0037366675b34a7432f5c9f1d4dc652d4ce2415ff657c
data/.rubocop.yml CHANGED
@@ -4,6 +4,7 @@ AllCops:
4
4
  - tmp/**/*
5
5
  - vendor/**/*
6
6
  - test/files/**/*
7
+ - lib/kramdown/parser/pot_markdown/table.rb
7
8
 
8
9
  AsciiComments:
9
10
  Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,12 +1,11 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-02-28 03:04:33 +0900 using RuboCop version 0.37.2.
3
+ # on 2016-03-12 02:43:19 +0900 using RuboCop version 0.37.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
9
+ # Offense count: 6
10
10
  Metrics/AbcSize:
11
- Max: 35
12
-
11
+ Max: 33
@@ -0,0 +1,24 @@
1
+ module Kramdown
2
+ module Parser
3
+ class PotMarkdown
4
+ def parse_atx_header
5
+ # ↓ removed in pot_markdown
6
+ # return false if !after_block_boundary?
7
+
8
+ start_line_number = @src.current_line_number
9
+ @src.check(ATX_HEADER_MATCH)
10
+ level = @src[1]
11
+ text = @src[2].to_s.strip
12
+ id = @src[3]
13
+ return false if text.empty?
14
+
15
+ @src.pos += @src.matched_size
16
+ el = new_block_el(:header, nil, nil, level: level.length, raw_text: text, location: start_line_number)
17
+ add_text(text, el)
18
+ el.attr['id'] = id if id
19
+ @tree.children << el
20
+ true
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ module Kramdown
2
+ module Parser
3
+ class PotMarkdown
4
+ FENCED_CODEBLOCK_MATCH = /^(([~`]){3,})\s*?((\w[\w\:\.-]*)(?:\?\S*)?)?\s*?\n(.*?)^\1\2*\s*?\n/m
5
+
6
+ def parse_codeblock_fenced
7
+ if @src.check(self.class::FENCED_CODEBLOCK_MATCH)
8
+ start_line_number = @src.current_line_number
9
+ @src.pos += @src.matched_size
10
+ el = new_block_el(:codeblock, @src[5], nil, location: start_line_number)
11
+ lang = @src[3].to_s.strip
12
+ unless lang.empty?
13
+ lang, filename = lang.split(':', 2)
14
+ if filename.nil? && lang.include?('.')
15
+ filename = lang
16
+ lang = Rouge::Lexer.guess_by_filename(filename).name.match(/[^\:]+\z/).to_s.downcase
17
+ end
18
+ el.options[:lang] = lang
19
+ el.attr['data-lang'] = lang
20
+ if filename
21
+ el.attr['class'] = "language-#{lang} has-filename"
22
+ el.attr['data-filename'] = filename
23
+ else
24
+ el.attr['class'] = "language-#{lang}"
25
+ end
26
+ end
27
+ @tree.children << el
28
+ true
29
+ else
30
+ false
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,161 @@
1
+ module Kramdown
2
+ module Parser
3
+ class PotMarkdown
4
+ TABLE_SEP_LINE = /^([+|: -]*?-[+|: -]*?)[ \t]*\n/
5
+ TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
6
+ TABLE_FSEP_LINE = /^[+|: =]*?=[+|: =]*?[ \t]*\n/
7
+ TABLE_ROW_LINE = /^(.*?)[ \t]*\n/
8
+ TABLE_PIPE_CHECK = /(?:^\|)/
9
+ TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\|\s*\n/
10
+ TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/
11
+
12
+ def parse_table_pot
13
+ return false unless after_block_boundary?
14
+
15
+ saved_pos = @src.save_pos
16
+ orig_pos = @src.pos
17
+ table = new_block_el(:table, nil, nil, alignment: [], location: @src.current_line_number)
18
+ leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
19
+ @src.scan(TABLE_SEP_LINE)
20
+
21
+ rows = []
22
+ has_footer = false
23
+ columns = 0
24
+
25
+ add_container = lambda do |type, force|
26
+ if !has_footer || type != :tbody || force
27
+ cont = Element.new(type)
28
+ cont.children = rows
29
+ rows = []
30
+ table.children << cont
31
+ end
32
+ end
33
+
34
+ until @src.eos?
35
+ break unless @src.check(TABLE_LINE)
36
+ if @src.scan(TABLE_SEP_LINE)
37
+ if rows.empty?
38
+ # nothing to do, ignoring multiple consecutive separator lines
39
+ elsif table.options[:alignment].empty? && !has_footer
40
+ add_container.call(:thead, false)
41
+ table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
42
+ (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
43
+ end
44
+ else # treat as normal separator line
45
+ add_container.call(:tbody, false)
46
+ end
47
+ elsif @src.scan(TABLE_FSEP_LINE)
48
+ add_container.call(:tbody, true) unless rows.empty?
49
+ has_footer = true
50
+ elsif @src.scan(TABLE_ROW_LINE)
51
+ trow = Element.new(:tr)
52
+
53
+ # parse possible code spans on the line and correctly split the line into cells
54
+ env = save_env
55
+ cells = []
56
+ @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
57
+ if i.odd?
58
+ (cells.empty? ? cells : cells.last) << str
59
+ else
60
+ reset_env(src: Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
61
+ root = Element.new(:root)
62
+ parse_spans(root, nil, [:codespan])
63
+
64
+ root.children.each do |c|
65
+ if c.type == :raw_text
66
+ # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')}
67
+ f, *l = c.value.split(/\\\|/, -1).map { |t| t.split(/\|/, -1) }.inject([]) do |memo, t|
68
+ memo.last << "|#{t.shift}" if memo.size > 0
69
+ memo.concat(t)
70
+ end
71
+ (cells.empty? ? cells : cells.last) << f
72
+ cells.concat(l)
73
+ else
74
+ delim = (c.value.scan(/`+/).max || '') + '`'
75
+ tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
76
+ (cells.empty? ? cells : cells.last) << tmp
77
+ end
78
+ end
79
+ end
80
+ end
81
+ restore_env(env)
82
+
83
+ cells.shift if leading_pipe && cells.first.strip.empty?
84
+ cells.pop if cells.last.strip.empty?
85
+ cells.each do |cell_text|
86
+ tcell = Element.new(:td)
87
+ tcell.children << Element.new(:raw_text, cell_text.strip)
88
+ trow.children << tcell
89
+ end
90
+ columns = [columns, cells.length].max
91
+ rows << trow
92
+ else
93
+ break
94
+ end
95
+ end
96
+
97
+ unless before_block_boundary?
98
+ @src.revert_pos(saved_pos)
99
+ return false
100
+ end
101
+
102
+ # Parse all lines of the table with the code span parser
103
+ env = save_env
104
+ l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos - 1), @src),
105
+ @src.current_line_number)
106
+ reset_env(src: l_src)
107
+ root = Element.new(:root)
108
+ parse_spans(root, nil, [:codespan, :span_html])
109
+ restore_env(env)
110
+
111
+ # Check if each line has at least one unescaped pipe that is not inside a code span/code
112
+ # HTML element
113
+ # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting
114
+ # algorithm above only takes <code> elements into account!
115
+ pipe_on_line = false
116
+ while (c = root.children.shift)
117
+ lines = c.value.split(/\n/)
118
+ if c.type == :codespan
119
+ if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
120
+ break
121
+ elsif lines.size == 2 && pipe_on_line
122
+ pipe_on_line = false
123
+ end
124
+ else
125
+ break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
126
+ pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
127
+ end
128
+ end
129
+ @src.revert_pos(saved_pos) && (return false) unless pipe_on_line
130
+
131
+ add_container.call(has_footer ? :tfoot : :tbody, false) unless rows.empty?
132
+
133
+ unless table.children.any? { |el| el.type == :tbody }
134
+ warning("Found table without body on line #{table.options[:location]} - ignoring it")
135
+ @src.revert_pos(saved_pos)
136
+ return false
137
+ end
138
+
139
+ # adjust all table rows to have equal number of columns, same for alignment defs
140
+ table.children.each do |kind|
141
+ kind.children.each do |row|
142
+ (columns - row.children.length).times do
143
+ row.children << Element.new(:td)
144
+ end
145
+ end
146
+ end
147
+ if table.options[:alignment].length > columns
148
+ table.options[:alignment] = table.options[:alignment][0...columns]
149
+ else
150
+ table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
151
+ end
152
+
153
+ @tree.children << table
154
+
155
+ true
156
+ end
157
+
158
+ define_parser(:table_pot, TABLE_START)
159
+ end
160
+ end
161
+ end
@@ -6,85 +6,15 @@ module Kramdown
6
6
  class PotMarkdown < Kramdown::Parser::GFM
7
7
  def initialize(source, options)
8
8
  super
9
- @span_parsers << :strikethrough_pot unless methods.include?(:parse_strikethrough_gfm)
10
- end
11
-
12
- def parse_atx_header
13
- # ↓ removed in pot_markdown
14
- # return false if !after_block_boundary?
15
-
16
- start_line_number = @src.current_line_number
17
- @src.check(ATX_HEADER_MATCH)
18
- level = @src[1]
19
- text = @src[2].to_s.strip
20
- id = @src[3]
21
- return false if text.empty?
22
-
23
- @src.pos += @src.matched_size
24
- el = new_block_el(:header, nil, nil, level: level.length, raw_text: text, location: start_line_number)
25
- add_text(text, el)
26
- el.attr['id'] = id if id
27
- @tree.children << el
28
- true
29
- end
30
-
31
- FENCED_CODEBLOCK_MATCH = /^(([~`]){3,})\s*?((\w[\w\:\.-]*)(?:\?\S*)?)?\s*?\n(.*?)^\1\2*\s*?\n/m
32
9
 
33
- def parse_codeblock_fenced
34
- if @src.check(self.class::FENCED_CODEBLOCK_MATCH)
35
- start_line_number = @src.current_line_number
36
- @src.pos += @src.matched_size
37
- el = new_block_el(:codeblock, @src[5], nil, location: start_line_number)
38
- lang = @src[3].to_s.strip
39
- unless lang.empty?
40
- lang, filename = lang.split(':', 2)
41
- if filename.nil? && lang.include?('.')
42
- filename = lang
43
- lang = Rouge::Lexer.guess_by_filename(filename).name.match(/[^\:]+\z/).to_s.downcase
44
- end
45
- el.options[:lang] = lang
46
- el.attr['data-lang'] = lang
47
- if filename
48
- el.attr['class'] = "language-#{lang} has-filename"
49
- el.attr['data-filename'] = filename
50
- else
51
- el.attr['class'] = "language-#{lang}"
52
- end
53
- end
54
- @tree.children << el
55
- true
56
- else
57
- false
58
- end
10
+ # replace table
11
+ @block_parsers.insert(@block_parsers.index(:table), :table_pot)
12
+ @block_parsers.delete(:table)
59
13
  end
60
14
 
61
- unless instance_methods.include?(:parse_strikethrough_gfm)
62
- STRIKETHROUGH_POT_DELIMITER = /~~/
63
-
64
- def parse_strikethrough_pot
65
- start_line_number = @src.current_line_number
66
- result = @src.scan(STRIKETHROUGH_POT_DELIMITER)
67
- saved_pos = @src.save_pos
68
-
69
- if @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
70
- add_text(result)
71
- return
72
- end
73
-
74
- text = @src.scan_until(/#{result}/)
75
- if text
76
- text.sub!(/#{result}\Z/, '')
77
- del = Element.new(:html_element, 'del', {}, category: :span, line: start_line_number)
78
- del.children << Element.new(:text, text, category: :span, line: start_line_number)
79
- @tree.children << del
80
- else
81
- @src.revert_pos(saved_pos)
82
- add_text(result)
83
- end
84
- end
85
-
86
- define_parser(:strikethrough_pot, STRIKETHROUGH_POT_DELIMITER, '~')
87
- end
15
+ require 'kramdown/parser/pot_markdown/atx_header'
16
+ require 'kramdown/parser/pot_markdown/code_block'
17
+ require 'kramdown/parser/pot_markdown/table'
88
18
  end
89
19
  end
90
20
  end
@@ -1,3 +1,3 @@
1
1
  module PotMarkdown
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.1.1'.freeze
3
3
  end
data/pot_markdown.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_dependency 'html-pipeline', '~> 2.0'
21
- spec.add_dependency 'kramdown', '~> 1.9'
21
+ spec.add_dependency 'kramdown', '~> 1.10'
22
22
  spec.add_dependency 'rouge'
23
23
  spec.add_dependency 'gemoji'
24
24
  spec.add_dependency 'rinku'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pot_markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ru_shalm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-05 00:00:00.000000000 Z
11
+ date: 2016-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: html-pipeline
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.9'
33
+ version: '1.10'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.9'
40
+ version: '1.10'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rouge
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -223,6 +223,9 @@ files:
223
223
  - bin/console
224
224
  - bin/setup
225
225
  - lib/kramdown/parser/pot_markdown.rb
226
+ - lib/kramdown/parser/pot_markdown/atx_header.rb
227
+ - lib/kramdown/parser/pot_markdown/code_block.rb
228
+ - lib/kramdown/parser/pot_markdown/table.rb
226
229
  - lib/pot_markdown.rb
227
230
  - lib/pot_markdown/filters/checkbox_filter.rb
228
231
  - lib/pot_markdown/filters/markdown_filter.rb