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.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/lib/extensions/array.rb +15 -0
  3. data/lib/extensions/string.rb +21 -0
  4. data/lib/markdown_metrics.rb +81 -0
  5. data/lib/markdown_metrics/elements/base.rb +23 -0
  6. data/lib/markdown_metrics/elements/block/list.rb +67 -0
  7. data/lib/markdown_metrics/elements/block/pre.rb +43 -0
  8. data/lib/markdown_metrics/elements/block/quote.rb +37 -0
  9. data/lib/markdown_metrics/elements/block/table.rb +43 -0
  10. data/lib/markdown_metrics/elements/inline/empty_line.rb +21 -0
  11. data/lib/markdown_metrics/elements/inline/h1.rb +21 -0
  12. data/lib/markdown_metrics/elements/inline/h2.rb +21 -0
  13. data/lib/markdown_metrics/elements/inline/h3.rb +21 -0
  14. data/lib/markdown_metrics/elements/inline/h4.rb +21 -0
  15. data/lib/markdown_metrics/elements/inline/h5.rb +21 -0
  16. data/lib/markdown_metrics/elements/inline/h6.rb +21 -0
  17. data/lib/markdown_metrics/elements/inline/image.rb +25 -0
  18. data/lib/markdown_metrics/elements/inline/paragraph.rb +21 -0
  19. data/lib/markdown_metrics/elements/inline/pre.rb +21 -0
  20. data/lib/markdown_metrics/elements/sentence/base.rb +21 -0
  21. data/lib/markdown_metrics/elements/sentence/bold.rb +31 -0
  22. data/lib/markdown_metrics/elements/sentence/code.rb +31 -0
  23. data/lib/markdown_metrics/elements/sentence/italic.rb +31 -0
  24. data/lib/markdown_metrics/elements/sentence/link.rb +37 -0
  25. data/lib/markdown_metrics/elements/sentence/text.rb +38 -0
  26. data/lib/markdown_metrics/file_lines.rb +10 -0
  27. data/lib/markdown_metrics/line_low_element.rb +19 -0
  28. data/lib/markdown_metrics/line_top_element.rb +28 -0
  29. data/lib/markdown_metrics/low_elements_parser.rb +30 -0
  30. data/lib/markdown_metrics/top_elements_parser.rb +30 -0
  31. data/lib/markdown_metrics/version.rb +12 -0
  32. metadata +106 -0
@@ -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,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MarkdownMetrics
4
+ class FileLines
5
+ def self.from(file_path)
6
+ content = File.open(file_path).read
7
+ content.split("\n")
8
+ end
9
+ end
10
+ 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
@@ -0,0 +1,12 @@
1
+ module MarkdownMetrics
2
+ module Version
3
+ module_function
4
+
5
+ # Gem current version
6
+ #
7
+ # @return [String]
8
+ def to_s
9
+ "0.0.1"
10
+ end
11
+ end
12
+ 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: []