rb_markdown 0.1.1 → 0.2.0
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 +5 -5
- data/src/markdown/abstract_line_tag.rb +27 -0
- data/src/markdown/block_splitter.rb +42 -0
- data/src/markdown/code_block_renderer.rb +15 -0
- data/src/markdown/engine.rb +15 -6
- data/src/markdown/heading_one_tag.rb +19 -0
- data/src/markdown/heading_three_tag.rb +19 -0
- data/src/markdown/heading_two_tag.rb +19 -0
- data/src/markdown/inline_processor.rb +13 -0
- data/src/markdown/line_processor.rb +34 -0
- data/src/markdown/ordered_list_tag.rb +27 -0
- data/src/markdown/unordered_list_tag.rb +19 -0
- metadata +27 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 17dbdf585f1866132db4a59586f1a718f533282c2abe3112feda769d53797d9e
|
|
4
|
+
data.tar.gz: b54373ccbb44e35b8d5daa3ba3e2f10d52082b49c9088998374898dab68d4810
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc1ccf31f89b17cb52b357e701c9fed65271d672aeb3812df83e85553af981e4e87f11a286fcbbd2ebf84309076ce9663543a257626a40ae54df607adfd0f73a
|
|
7
|
+
data.tar.gz: d673b082a8133b9dfbf691a6b272dce752855d9c230953c79f2e12b1b5b377a51ba6a24c5b8de9d974a572420ab8e9d626afc68c02be56a979ab4026f64daae3
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Markdown
|
|
4
|
+
module AbstractLineTag
|
|
5
|
+
def match?(line)
|
|
6
|
+
line.match?(prefix_pattern)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def process(line)
|
|
10
|
+
content = line.sub(prefix_pattern, "")
|
|
11
|
+
convert(content)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
# @return [Regexp]
|
|
17
|
+
def prefix_pattern
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param string [String]
|
|
22
|
+
# @return [String]
|
|
23
|
+
def convert(string)
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Markdown
|
|
4
|
+
class BlockSplitter
|
|
5
|
+
Segment = Struct.new(:type, :content, :language)
|
|
6
|
+
|
|
7
|
+
def split(string)
|
|
8
|
+
segments = []
|
|
9
|
+
current_lines = []
|
|
10
|
+
in_code_block = false
|
|
11
|
+
language = nil
|
|
12
|
+
|
|
13
|
+
string.each_line do |line|
|
|
14
|
+
line = line.chomp
|
|
15
|
+
|
|
16
|
+
if in_code_block
|
|
17
|
+
if line.match?(/^```\s*$/)
|
|
18
|
+
segments << Segment.new(:code, current_lines.join("\n"), language)
|
|
19
|
+
current_lines = []
|
|
20
|
+
in_code_block = false
|
|
21
|
+
language = nil
|
|
22
|
+
else
|
|
23
|
+
current_lines << line
|
|
24
|
+
end
|
|
25
|
+
elsif (match = line.match(/^```(\w*)\s*$/))
|
|
26
|
+
segments << Segment.new(:text, current_lines.join("\n")) unless current_lines.empty?
|
|
27
|
+
current_lines = []
|
|
28
|
+
in_code_block = true
|
|
29
|
+
language = match[1].empty? ? nil : match[1]
|
|
30
|
+
else
|
|
31
|
+
current_lines << line
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
unless current_lines.empty?
|
|
36
|
+
segments << Segment.new(in_code_block ? :code : :text, current_lines.join("\n"), language)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
segments
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rouge"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class CodeBlockRenderer
|
|
7
|
+
def render(content, language)
|
|
8
|
+
lexer = Rouge::Lexer.find(language) if language
|
|
9
|
+
lexer ||= Rouge::Lexers::PlainText.new
|
|
10
|
+
|
|
11
|
+
formatter = Rouge::Formatters::Terminal256.new(Rouge::Themes::Monokai.new)
|
|
12
|
+
formatter.format(lexer.lex(content))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/src/markdown/engine.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "./
|
|
4
|
-
require_relative "./
|
|
5
|
-
require_relative "./
|
|
3
|
+
require_relative "./block_splitter"
|
|
4
|
+
require_relative "./code_block_renderer"
|
|
5
|
+
require_relative "./inline_processor"
|
|
6
|
+
require_relative "./line_processor"
|
|
6
7
|
|
|
7
8
|
module Markdown
|
|
8
9
|
class Engine
|
|
@@ -11,9 +12,17 @@ module Markdown
|
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def to_ansi
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
line_processor = LineProcessor.new(InlineProcessor.new)
|
|
16
|
+
code_renderer = CodeBlockRenderer.new
|
|
17
|
+
|
|
18
|
+
BlockSplitter.new.split(@string).map do |segment|
|
|
19
|
+
case segment.type
|
|
20
|
+
when :text
|
|
21
|
+
line_processor.process(segment.content)
|
|
22
|
+
when :code
|
|
23
|
+
code_renderer.render(segment.content, segment.language)
|
|
24
|
+
end
|
|
25
|
+
end.join("\n")
|
|
17
26
|
end
|
|
18
27
|
end
|
|
19
28
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./abstract_line_tag"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class HeadingOneTag
|
|
7
|
+
include AbstractLineTag
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def prefix_pattern
|
|
12
|
+
/^#\s+/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(string)
|
|
16
|
+
string.bold.underline
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./abstract_line_tag"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class HeadingThreeTag
|
|
7
|
+
include AbstractLineTag
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def prefix_pattern
|
|
12
|
+
/^###\s+/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(string)
|
|
16
|
+
string.bold.italic
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./abstract_line_tag"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class HeadingTwoTag
|
|
7
|
+
include AbstractLineTag
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def prefix_pattern
|
|
12
|
+
/^##\s+/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(string)
|
|
16
|
+
string.bold
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./bold_tag"
|
|
4
|
+
require_relative "./code_tag"
|
|
5
|
+
require_relative "./italic_tag"
|
|
6
|
+
|
|
7
|
+
module Markdown
|
|
8
|
+
class InlineProcessor
|
|
9
|
+
def process(string)
|
|
10
|
+
CodeTag.new(ItalicTag.new(BoldTag.new(string))).to_ansi
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./heading_three_tag"
|
|
4
|
+
require_relative "./heading_two_tag"
|
|
5
|
+
require_relative "./heading_one_tag"
|
|
6
|
+
require_relative "./unordered_list_tag"
|
|
7
|
+
require_relative "./ordered_list_tag"
|
|
8
|
+
|
|
9
|
+
module Markdown
|
|
10
|
+
class LineProcessor
|
|
11
|
+
def initialize(inline_processor)
|
|
12
|
+
@inline_processor = inline_processor
|
|
13
|
+
@line_tags = [
|
|
14
|
+
HeadingThreeTag.new,
|
|
15
|
+
HeadingTwoTag.new,
|
|
16
|
+
HeadingOneTag.new,
|
|
17
|
+
UnorderedListTag.new,
|
|
18
|
+
OrderedListTag.new,
|
|
19
|
+
]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def process(string)
|
|
23
|
+
string.each_line(chomp: true).map do |line|
|
|
24
|
+
tag = @line_tags.find { |t| t.match?(line) }
|
|
25
|
+
|
|
26
|
+
if tag
|
|
27
|
+
@inline_processor.process(tag.process(line))
|
|
28
|
+
else
|
|
29
|
+
@inline_processor.process(line)
|
|
30
|
+
end
|
|
31
|
+
end.join("\n")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./abstract_line_tag"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class OrderedListTag
|
|
7
|
+
include AbstractLineTag
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def prefix_pattern
|
|
12
|
+
/^(\d+)\.\s+/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(string)
|
|
16
|
+
string
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
public
|
|
20
|
+
|
|
21
|
+
def process(line)
|
|
22
|
+
match = line.match(prefix_pattern)
|
|
23
|
+
content = line.sub(prefix_pattern, "")
|
|
24
|
+
" #{match[1]}. #{convert(content)}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./abstract_line_tag"
|
|
4
|
+
|
|
5
|
+
module Markdown
|
|
6
|
+
class UnorderedListTag
|
|
7
|
+
include AbstractLineTag
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def prefix_pattern
|
|
12
|
+
/^[*\-]\s+/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def convert(string)
|
|
16
|
+
" \u2022 #{string}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rb_markdown
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aurélien Delogu
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_monkey
|
|
@@ -24,17 +24,41 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.1.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rouge
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.30'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.30'
|
|
27
41
|
description:
|
|
28
42
|
email: aurelien.delogu@gmail.com
|
|
29
43
|
executables: []
|
|
30
44
|
extensions: []
|
|
31
45
|
extra_rdoc_files: []
|
|
32
46
|
files:
|
|
47
|
+
- src/markdown/abstract_line_tag.rb
|
|
33
48
|
- src/markdown/abstract_tag.rb
|
|
49
|
+
- src/markdown/block_splitter.rb
|
|
34
50
|
- src/markdown/bold_tag.rb
|
|
51
|
+
- src/markdown/code_block_renderer.rb
|
|
35
52
|
- src/markdown/code_tag.rb
|
|
36
53
|
- src/markdown/engine.rb
|
|
54
|
+
- src/markdown/heading_one_tag.rb
|
|
55
|
+
- src/markdown/heading_three_tag.rb
|
|
56
|
+
- src/markdown/heading_two_tag.rb
|
|
57
|
+
- src/markdown/inline_processor.rb
|
|
37
58
|
- src/markdown/italic_tag.rb
|
|
59
|
+
- src/markdown/line_processor.rb
|
|
60
|
+
- src/markdown/ordered_list_tag.rb
|
|
61
|
+
- src/markdown/unordered_list_tag.rb
|
|
38
62
|
- src/rb_markdown.rb
|
|
39
63
|
homepage:
|
|
40
64
|
licenses: []
|
|
@@ -54,8 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
54
78
|
- !ruby/object:Gem::Version
|
|
55
79
|
version: '0'
|
|
56
80
|
requirements: []
|
|
57
|
-
|
|
58
|
-
rubygems_version: 2.6.14.4
|
|
81
|
+
rubygems_version: 3.0.3.1
|
|
59
82
|
signing_key:
|
|
60
83
|
specification_version: 4
|
|
61
84
|
summary: A tiny markdown engine
|