markdown_metrics 0.0.1

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