markdown_metrics 0.0.1
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.
- checksums.yaml +7 -0
- data/lib/extensions/array.rb +15 -0
- data/lib/extensions/string.rb +21 -0
- data/lib/markdown_metrics.rb +81 -0
- data/lib/markdown_metrics/elements/base.rb +23 -0
- data/lib/markdown_metrics/elements/block/list.rb +67 -0
- data/lib/markdown_metrics/elements/block/pre.rb +43 -0
- data/lib/markdown_metrics/elements/block/quote.rb +37 -0
- data/lib/markdown_metrics/elements/block/table.rb +43 -0
- data/lib/markdown_metrics/elements/inline/empty_line.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h1.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h2.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h3.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h4.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h5.rb +21 -0
- data/lib/markdown_metrics/elements/inline/h6.rb +21 -0
- data/lib/markdown_metrics/elements/inline/image.rb +25 -0
- data/lib/markdown_metrics/elements/inline/paragraph.rb +21 -0
- data/lib/markdown_metrics/elements/inline/pre.rb +21 -0
- data/lib/markdown_metrics/elements/sentence/base.rb +21 -0
- data/lib/markdown_metrics/elements/sentence/bold.rb +31 -0
- data/lib/markdown_metrics/elements/sentence/code.rb +31 -0
- data/lib/markdown_metrics/elements/sentence/italic.rb +31 -0
- data/lib/markdown_metrics/elements/sentence/link.rb +37 -0
- data/lib/markdown_metrics/elements/sentence/text.rb +38 -0
- data/lib/markdown_metrics/file_lines.rb +10 -0
- data/lib/markdown_metrics/line_low_element.rb +19 -0
- data/lib/markdown_metrics/line_top_element.rb +28 -0
- data/lib/markdown_metrics/low_elements_parser.rb +30 -0
- data/lib/markdown_metrics/top_elements_parser.rb +30 -0
- data/lib/markdown_metrics/version.rb +12 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9a02e18c2096a35503f253e3adf0b158a3140990ae74a08846c34a2260634260
|
4
|
+
data.tar.gz: 3c9d38b1ee6b0bc4e138d293de70ef841fc323925049bb16633cf46e5e83e8aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f6ac24c99b1433cefc936f996f8f4bc67c5b62deca816e2ef448d4bab85060bdf3e0d05e72b725422ffa8d2c8d62ca7182fa431c6b5330f4e7239f7dd8941116
|
7
|
+
data.tar.gz: 1beff848022ac3ba4ec6fe3fc1bdd6660a7231fec720116c888d1747d057588fc7052b9f66dfb63dd585ee2f5fd8eb74a49355ea2799b749740c2c7d50a23213
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Array
|
4
|
+
def each_with_index_and_catch
|
5
|
+
self.each_with_index do |el, index|
|
6
|
+
next if !@skip_iteration_index.nil? && @skip_iteration_index >= index
|
7
|
+
|
8
|
+
skip_iteration_index = catch :skip_iteration do
|
9
|
+
yield(el, index) if block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
@skip_iteration_index = skip_iteration_index if skip_iteration_index.kind_of?(Integer)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
def each_character_with_index_from(from_index)
|
5
|
+
self.split("")[from_index..-1].each_with_index do |chr, index|
|
6
|
+
yield(chr, index + from_index) if block_given?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def each_character_with_index
|
11
|
+
self.split("").each_with_index do |chr, index|
|
12
|
+
next if !@skip_iteration_index.nil? && @skip_iteration_index >= index
|
13
|
+
|
14
|
+
skip_iteration_index = catch :skip_iteration do
|
15
|
+
yield(chr, index) if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
@skip_iteration_index = skip_iteration_index if skip_iteration_index.kind_of?(Integer)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'extensions/string'
|
4
|
+
require 'extensions/array'
|
5
|
+
|
6
|
+
require 'markdown_metrics/elements/base'
|
7
|
+
|
8
|
+
require 'markdown_metrics/elements/inline/h1'
|
9
|
+
require 'markdown_metrics/elements/inline/h2'
|
10
|
+
require 'markdown_metrics/elements/inline/h3'
|
11
|
+
require 'markdown_metrics/elements/inline/h4'
|
12
|
+
require 'markdown_metrics/elements/inline/h5'
|
13
|
+
require 'markdown_metrics/elements/inline/h6'
|
14
|
+
require 'markdown_metrics/elements/inline/image'
|
15
|
+
require 'markdown_metrics/elements/inline/pre'
|
16
|
+
require 'markdown_metrics/elements/inline/empty_line'
|
17
|
+
require 'markdown_metrics/elements/inline/paragraph'
|
18
|
+
|
19
|
+
require 'markdown_metrics/elements/block/table'
|
20
|
+
require 'markdown_metrics/elements/block/pre'
|
21
|
+
require 'markdown_metrics/elements/block/quote'
|
22
|
+
require 'markdown_metrics/elements/block/list'
|
23
|
+
|
24
|
+
require 'markdown_metrics/elements/sentence/base'
|
25
|
+
require 'markdown_metrics/elements/sentence/bold'
|
26
|
+
require 'markdown_metrics/elements/sentence/italic'
|
27
|
+
require 'markdown_metrics/elements/sentence/link'
|
28
|
+
require 'markdown_metrics/elements/sentence/code'
|
29
|
+
require 'markdown_metrics/elements/sentence/text'
|
30
|
+
|
31
|
+
require 'markdown_metrics/file_lines'
|
32
|
+
require 'markdown_metrics/line_top_element'
|
33
|
+
require 'markdown_metrics/top_elements_parser'
|
34
|
+
require 'markdown_metrics/line_low_element'
|
35
|
+
require 'markdown_metrics/low_elements_parser'
|
36
|
+
|
37
|
+
module MarkdownMetrics
|
38
|
+
ELEMENTS_WITH_LOW_ELEMENTS = %i[paragraph list h1 h2 h3 h4 h5 h6]
|
39
|
+
|
40
|
+
class << self
|
41
|
+
def generate(file_path:)
|
42
|
+
file_lines = MarkdownMetrics::FileLines.from(file_path)
|
43
|
+
top_elements_parser = MarkdownMetrics::TopElementsParser.new(file_lines)
|
44
|
+
top_elements_parser.parse
|
45
|
+
|
46
|
+
top_elements_parser.elements.map do |element|
|
47
|
+
unless ELEMENTS_WITH_LOW_ELEMENTS.include?(element[:name])
|
48
|
+
element
|
49
|
+
else
|
50
|
+
if element[:name] == :table
|
51
|
+
new_rows = []
|
52
|
+
element[:value][:rows].each do |r|
|
53
|
+
new_rows << r.map do |row|
|
54
|
+
low_elements(row)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
element[:value].merge!(rows: new_rows)
|
59
|
+
element
|
60
|
+
else
|
61
|
+
low_level_values = if element[:value].kind_of?(Array)
|
62
|
+
element[:value].map { |v| low_elements(v) }
|
63
|
+
else
|
64
|
+
low_elements(element[:value])
|
65
|
+
end
|
66
|
+
|
67
|
+
element.merge(value: low_level_values)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def low_elements(value)
|
76
|
+
parser = MarkdownMetrics::LowElementsParser.new(value: value)
|
77
|
+
parser.parse
|
78
|
+
parser.elements
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MarkdownMetrics
|
2
|
+
module Elements
|
3
|
+
class Base
|
4
|
+
attr_reader :skip_lines_until
|
5
|
+
|
6
|
+
def initialize(lines:, start_at:)
|
7
|
+
@lines = lines
|
8
|
+
@start_at = start_at
|
9
|
+
@skip_lines_until = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes
|
13
|
+
{}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def current_line
|
19
|
+
@lines[@start_at]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Block
|
6
|
+
class List < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\- .*/) || line.to_s.match(/^\d+. .*/) || line.to_s.match(/^\* .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:list
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
end_line = nil
|
17
|
+
next_line = @start_at
|
18
|
+
|
19
|
+
@lines[(@start_at + 1)..-1].each do |code_line|
|
20
|
+
next_line += 1
|
21
|
+
unless code_line.match(value_regex)
|
22
|
+
end_line = next_line - 1
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
end_line = @lines.size - 1 if end_line.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
if !end_line.nil?
|
30
|
+
@skip_lines_until = end_line
|
31
|
+
if list_type == :number
|
32
|
+
@lines[@start_at..end_line].map { |e| e[2..-1] }
|
33
|
+
else
|
34
|
+
@lines[@start_at..end_line].map { |e| e[1..-1] }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def attributes
|
40
|
+
{ type: list_type }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def value_regex
|
46
|
+
if list_type == :dash
|
47
|
+
/^\- .*/
|
48
|
+
elsif list_type == :number
|
49
|
+
/^\d+. .*/
|
50
|
+
elsif list_type == :star
|
51
|
+
/^\* .*/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def list_type
|
56
|
+
if current_line.match(/^\- .*/)
|
57
|
+
:dash
|
58
|
+
elsif current_line.match(/^\d+. .*/)
|
59
|
+
:number
|
60
|
+
elsif current_line.match(/^\* .*/)
|
61
|
+
:star
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Block
|
6
|
+
class Pre < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^```(?<language>.*)/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:pre
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
end_line = nil
|
17
|
+
next_line = @start_at
|
18
|
+
|
19
|
+
@lines[(@start_at + 1)..-1].each do |code_line|
|
20
|
+
next_line += 1
|
21
|
+
if code_line == '```'
|
22
|
+
end_line = next_line
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
end_line = @lines.size - 1 if end_line.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
if !end_line.nil?
|
30
|
+
@skip_lines_until = end_line
|
31
|
+
@lines[(@start_at + 1)..(end_line - 1)].join("\n")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def attributes
|
36
|
+
language_name = current_line.match(/^```(?<language>.*)/)['language']
|
37
|
+
|
38
|
+
{ language: language_name }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Block
|
6
|
+
class Quote < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\>/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:quote
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
end_line = nil
|
17
|
+
next_line = @start_at
|
18
|
+
|
19
|
+
@lines[(@start_at + 1)..-1].each do |code_line|
|
20
|
+
next_line += 1
|
21
|
+
unless code_line.match(/^\>/)
|
22
|
+
end_line = next_line - 1
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
end_line = @lines.size - 1 if end_line.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
if !end_line.nil?
|
30
|
+
@skip_lines_until = end_line
|
31
|
+
@lines[@start_at..end_line].map { |e| e[1..-1] }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Block
|
6
|
+
class Table < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^.* \| .*$/) && next_line.to_s.match(/^\-{1,} \| \-{1,}$/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:table
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
headers = current_line.split("|")
|
17
|
+
rows = []
|
18
|
+
end_line = nil
|
19
|
+
next_line = @start_at
|
20
|
+
|
21
|
+
@lines[(@start_at + 2)..-1].each do |code_line|
|
22
|
+
next_line += 1
|
23
|
+
unless code_line.match(/^.* \| .*$/)
|
24
|
+
end_line = next_line
|
25
|
+
break
|
26
|
+
end
|
27
|
+
|
28
|
+
end_line = @lines.size - 1 if end_line.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
if !end_line.nil?
|
32
|
+
@skip_lines_until = end_line
|
33
|
+
@lines[@start_at+2..end_line].each do |row_line|
|
34
|
+
rows << row_line.split("|")
|
35
|
+
end
|
36
|
+
|
37
|
+
{ rows: rows, headers: headers }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class EmptyLine < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.nil? || line == ''
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:empty_line
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H1 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{1} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h1
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{1} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H2 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{2} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h2
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{2} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H3 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{3} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h3
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{3} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H4 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{4} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h4
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{4} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H5 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{5} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h5
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{5} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class H6 < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\#{6} .*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:h6
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/^\#{6} /, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class Image < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/^\!\[.*\)$/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:image
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.match(/\((?<image>.*)\)$/)['image']
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
{ alt: current_line.match(/\[(?<alt>.*)\]/)['alt'] }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class Paragraph < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
!line.nil? && line != ''
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:paragraph
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Inline
|
6
|
+
class Pre < MarkdownMetrics::Elements::Base
|
7
|
+
def self.match_element(line, next_line)
|
8
|
+
line.to_s.match(/\s{4}.*/)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:pre
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
current_line.gsub(/\s{4}/, '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Base
|
7
|
+
attr_accessor :skip_lines_until
|
8
|
+
|
9
|
+
def initialize(value:, start_at:)
|
10
|
+
@value = value
|
11
|
+
@start_at = start_at
|
12
|
+
@skip_lines_until = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def attributes
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Bold < MarkdownMetrics::Elements::Sentence::Base
|
7
|
+
def self.match_element(character, next_character)
|
8
|
+
character.to_s == '*' && next_character.to_s == '*'
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:bold
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
final_value = nil
|
17
|
+
|
18
|
+
@value.each_character_with_index_from(@start_at + 2) do |chr2, index2|
|
19
|
+
next unless @value[index2..(index2 + 1)] == '**'
|
20
|
+
|
21
|
+
final_value = @value[@start_at + 2..(index2 - 1)]
|
22
|
+
@skip_lines_until = index2 + 1
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
final_value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Code < MarkdownMetrics::Elements::Sentence::Base
|
7
|
+
def self.match_element(character, next_character)
|
8
|
+
character.to_s == '`'
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:code
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
final_value = nil
|
17
|
+
|
18
|
+
@value.each_character_with_index_from(@start_at + 1) do |chr2, index2|
|
19
|
+
next unless @value[index2] == '`'
|
20
|
+
|
21
|
+
final_value = @value[@start_at + 1..(index2 - 1)]
|
22
|
+
@skip_lines_until = index2
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
final_value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Italic < MarkdownMetrics::Elements::Sentence::Base
|
7
|
+
def self.match_element(character, next_character)
|
8
|
+
character.to_s == '*' && next_character.to_s != '*'
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:italic
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
final_value = nil
|
17
|
+
|
18
|
+
@value.each_character_with_index_from(@start_at + 1) do |chr2, index2|
|
19
|
+
next unless @value[index2] == '*'
|
20
|
+
|
21
|
+
final_value = @value[@start_at + 1..(index2 - 1)]
|
22
|
+
@skip_lines_until = index2
|
23
|
+
break
|
24
|
+
end
|
25
|
+
|
26
|
+
final_value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Link < MarkdownMetrics::Elements::Sentence::Base
|
7
|
+
def self.match_element(character, next_character)
|
8
|
+
character.to_s == '(' && next_character.to_s == '['
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
:link
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
@final_value = nil
|
17
|
+
|
18
|
+
@value.each_character_with_index_from(@start_at + 2) do |chr2, index2|
|
19
|
+
next unless @value[index2..(index2 + 1)] == '))'
|
20
|
+
@final_value = @value[@start_at..(index2 + 1)]
|
21
|
+
@skip_lines_until = index2 + 1
|
22
|
+
break
|
23
|
+
end
|
24
|
+
|
25
|
+
@final_value
|
26
|
+
end
|
27
|
+
|
28
|
+
def attributes
|
29
|
+
link_text = @final_value.match(/^\(\[(?<link_text>.*)\]/)['link_text']
|
30
|
+
link_href = @final_value.match(/\((?<link>(http|https).*)\)/)['link'].gsub(")", "")
|
31
|
+
|
32
|
+
{ text: link_text, href: link_href, value: nil }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
module Elements
|
5
|
+
module Sentence
|
6
|
+
class Text < MarkdownMetrics::Elements::Sentence::Base
|
7
|
+
def self.match_element(character, next_character)
|
8
|
+
return false if ['*', '`'].include?(character)
|
9
|
+
return true if character != '('
|
10
|
+
|
11
|
+
next_character != '['
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
:text
|
16
|
+
end
|
17
|
+
|
18
|
+
def value
|
19
|
+
final_value = nil
|
20
|
+
|
21
|
+
@value.each_character_with_index_from(@start_at + 1) do |chr2, index2|
|
22
|
+
if @value[index2 + 1].nil?
|
23
|
+
@skip_lines_until = index2 + 2
|
24
|
+
final_value = @value[@start_at..index2]
|
25
|
+
break
|
26
|
+
elsif chr2 == "`" || chr2 == "*" || (chr2 == "(" && @value[index2 + 1] == "[")
|
27
|
+
@skip_lines_until = index2 - 1
|
28
|
+
final_value = @value[@start_at..(index2 - 1)]
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
final_value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
class LineLowElement
|
5
|
+
ELEMENTS = [
|
6
|
+
MarkdownMetrics::Elements::Sentence::Bold,
|
7
|
+
MarkdownMetrics::Elements::Sentence::Italic,
|
8
|
+
MarkdownMetrics::Elements::Sentence::Link,
|
9
|
+
MarkdownMetrics::Elements::Sentence::Code,
|
10
|
+
MarkdownMetrics::Elements::Sentence::Text
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
def self.match_element(character, next_character)
|
14
|
+
ELEMENTS.find do |element_class|
|
15
|
+
element_class.match_element(character, next_character)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarkdownMetrics
|
4
|
+
class LineTopElement
|
5
|
+
ELEMENTS = [
|
6
|
+
MarkdownMetrics::Elements::Block::List,
|
7
|
+
MarkdownMetrics::Elements::Block::Pre,
|
8
|
+
MarkdownMetrics::Elements::Block::Quote,
|
9
|
+
MarkdownMetrics::Elements::Block::Table,
|
10
|
+
MarkdownMetrics::Elements::Inline::H1,
|
11
|
+
MarkdownMetrics::Elements::Inline::H2,
|
12
|
+
MarkdownMetrics::Elements::Inline::H3,
|
13
|
+
MarkdownMetrics::Elements::Inline::H4,
|
14
|
+
MarkdownMetrics::Elements::Inline::H5,
|
15
|
+
MarkdownMetrics::Elements::Inline::H6,
|
16
|
+
MarkdownMetrics::Elements::Inline::Image,
|
17
|
+
MarkdownMetrics::Elements::Inline::Pre,
|
18
|
+
MarkdownMetrics::Elements::Inline::EmptyLine,
|
19
|
+
MarkdownMetrics::Elements::Inline::Paragraph
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def self.match_element(line, next_line)
|
23
|
+
ELEMENTS.find do |element_class|
|
24
|
+
element_class.match_element(line, next_line)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MarkdownMetrics
|
2
|
+
class LowElementsParser
|
3
|
+
attr_reader :elements
|
4
|
+
|
5
|
+
def initialize(value:)
|
6
|
+
@value = value
|
7
|
+
@elements = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse
|
11
|
+
@value.each_character_with_index do |chr, index|
|
12
|
+
element = initialize_element(chr, index)
|
13
|
+
@elements << {
|
14
|
+
name: element.name,
|
15
|
+
value: element.value
|
16
|
+
}.merge(element.attributes)
|
17
|
+
|
18
|
+
throw :skip_iteration, element.skip_lines_until if element.skip_lines_until > 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def initialize_element(chr, index)
|
25
|
+
MarkdownMetrics::LineLowElement.match_element(
|
26
|
+
chr, @value[index + 1]
|
27
|
+
).new(value: @value, start_at: index)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MarkdownMetrics
|
2
|
+
class TopElementsParser
|
3
|
+
attr_reader :elements
|
4
|
+
|
5
|
+
def initialize(lines)
|
6
|
+
@lines = lines
|
7
|
+
@elements = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse
|
11
|
+
@lines.each_with_index_and_catch do |line, index|
|
12
|
+
element = initialize_element(line, index)
|
13
|
+
@elements << {
|
14
|
+
name: element.name,
|
15
|
+
value: element.value
|
16
|
+
}.merge(element.attributes)
|
17
|
+
|
18
|
+
throw :skip_iteration, element.skip_lines_until if element.skip_lines_until > 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def initialize_element(line, index)
|
25
|
+
MarkdownMetrics::LineTopElement.match_element(
|
26
|
+
line, @lines[index + 1]
|
27
|
+
).new(lines: @lines, start_at: index)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: markdown_metrics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paweł Dąbrowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.7'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.7.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.7'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.7.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: pry
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: Analyze markdown document
|
48
|
+
email: dziamber@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/extensions/array.rb
|
54
|
+
- lib/extensions/string.rb
|
55
|
+
- lib/markdown_metrics.rb
|
56
|
+
- lib/markdown_metrics/elements/base.rb
|
57
|
+
- lib/markdown_metrics/elements/block/list.rb
|
58
|
+
- lib/markdown_metrics/elements/block/pre.rb
|
59
|
+
- lib/markdown_metrics/elements/block/quote.rb
|
60
|
+
- lib/markdown_metrics/elements/block/table.rb
|
61
|
+
- lib/markdown_metrics/elements/inline/empty_line.rb
|
62
|
+
- lib/markdown_metrics/elements/inline/h1.rb
|
63
|
+
- lib/markdown_metrics/elements/inline/h2.rb
|
64
|
+
- lib/markdown_metrics/elements/inline/h3.rb
|
65
|
+
- lib/markdown_metrics/elements/inline/h4.rb
|
66
|
+
- lib/markdown_metrics/elements/inline/h5.rb
|
67
|
+
- lib/markdown_metrics/elements/inline/h6.rb
|
68
|
+
- lib/markdown_metrics/elements/inline/image.rb
|
69
|
+
- lib/markdown_metrics/elements/inline/paragraph.rb
|
70
|
+
- lib/markdown_metrics/elements/inline/pre.rb
|
71
|
+
- lib/markdown_metrics/elements/sentence/base.rb
|
72
|
+
- lib/markdown_metrics/elements/sentence/bold.rb
|
73
|
+
- lib/markdown_metrics/elements/sentence/code.rb
|
74
|
+
- lib/markdown_metrics/elements/sentence/italic.rb
|
75
|
+
- lib/markdown_metrics/elements/sentence/link.rb
|
76
|
+
- lib/markdown_metrics/elements/sentence/text.rb
|
77
|
+
- lib/markdown_metrics/file_lines.rb
|
78
|
+
- lib/markdown_metrics/line_low_element.rb
|
79
|
+
- lib/markdown_metrics/line_top_element.rb
|
80
|
+
- lib/markdown_metrics/low_elements_parser.rb
|
81
|
+
- lib/markdown_metrics/top_elements_parser.rb
|
82
|
+
- lib/markdown_metrics/version.rb
|
83
|
+
homepage:
|
84
|
+
licenses: []
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.7.6
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: Analyze markdown document
|
106
|
+
test_files: []
|