Class: Ast::Merge::FencedCodeBlockDetector
- Inherits:
-
RegionDetectorBase
- Object
- RegionDetectorBase
- Ast::Merge::FencedCodeBlockDetector
- Defined in:
- lib/ast/merge/fenced_code_block_detector.rb
Overview
Detects fenced code blocks with a specific language identifier.
This detector finds Markdown-style fenced code blocks (using “‘ or ~~~) that have a specific language identifier. It can be configured for any language: ruby, json, yaml, mermaid, etc.
Instance Attribute Summary collapse
-
#aliases ⇒ Array<String>
readonly
Alternative language identifiers.
-
#language ⇒ String
readonly
The primary language identifier.
Class Method Summary collapse
-
.bash ⇒ FencedCodeBlockDetector
Creates a detector for Bash/Shell code blocks.
-
.css ⇒ FencedCodeBlockDetector
Creates a detector for CSS code blocks.
-
.html ⇒ FencedCodeBlockDetector
Creates a detector for HTML code blocks.
-
.javascript ⇒ FencedCodeBlockDetector
Creates a detector for JavaScript code blocks.
-
.json ⇒ FencedCodeBlockDetector
Creates a detector for JSON code blocks.
-
.markdown ⇒ FencedCodeBlockDetector
Creates a detector for Markdown code blocks (nested markdown).
-
.mermaid ⇒ FencedCodeBlockDetector
Creates a detector for Mermaid diagram blocks.
-
.python ⇒ FencedCodeBlockDetector
Creates a detector for Python code blocks.
-
.ruby ⇒ FencedCodeBlockDetector
Creates a detector for Ruby code blocks.
-
.sql ⇒ FencedCodeBlockDetector
Creates a detector for SQL code blocks.
-
.toml ⇒ FencedCodeBlockDetector
Creates a detector for TOML code blocks.
-
.typescript ⇒ FencedCodeBlockDetector
Creates a detector for TypeScript code blocks.
-
.yaml ⇒ FencedCodeBlockDetector
Creates a detector for YAML code blocks.
Instance Method Summary collapse
-
#detect_all(source) ⇒ Array<Region>
Detects all fenced code blocks with the configured language.
-
#initialize(language, aliases: []) ⇒ FencedCodeBlockDetector
constructor
Creates a new detector for the specified language.
-
#inspect ⇒ String
A description of this detector.
-
#matches_language?(lang) ⇒ Boolean
Check if a language identifier matches this detector.
-
#region_type ⇒ Symbol
The region type (e.g., :ruby_code_block).
Methods inherited from RegionDetectorBase
Constructor Details
#initialize(language, aliases: []) ⇒ FencedCodeBlockDetector
Creates a new detector for the specified language.
32 33 34 35 36 37 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 32 def initialize(language, aliases: []) super() @language = language.to_s.downcase @aliases = aliases.map { |a| a.to_s.downcase } @all_identifiers = [@language] + @aliases end |
Instance Attribute Details
#aliases ⇒ Array<String> (readonly)
Returns Alternative language identifiers.
26 27 28 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 26 def aliases @aliases end |
#language ⇒ String (readonly)
Returns The primary language identifier.
23 24 25 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 23 def language @language end |
Class Method Details
.bash ⇒ FencedCodeBlockDetector
Creates a detector for Bash/Shell code blocks.
181 182 183 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 181 def bash new("bash", aliases: ["sh", "shell", "zsh"]) end |
.css ⇒ FencedCodeBlockDetector
Creates a detector for CSS code blocks.
199 200 201 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 199 def css new("css") end |
.html ⇒ FencedCodeBlockDetector
Creates a detector for HTML code blocks.
193 194 195 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 193 def html new("html") end |
.javascript ⇒ FencedCodeBlockDetector
Creates a detector for JavaScript code blocks.
163 164 165 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 163 def javascript new("javascript", aliases: ["js"]) end |
.json ⇒ FencedCodeBlockDetector
Creates a detector for JSON code blocks.
139 140 141 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 139 def json new("json") end |
.markdown ⇒ FencedCodeBlockDetector
Creates a detector for Markdown code blocks (nested markdown).
205 206 207 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 205 def markdown new("markdown", aliases: ["md"]) end |
.mermaid ⇒ FencedCodeBlockDetector
Creates a detector for Mermaid diagram blocks.
157 158 159 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 157 def mermaid new("mermaid") end |
.python ⇒ FencedCodeBlockDetector
Creates a detector for Python code blocks.
175 176 177 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 175 def python new("python", aliases: ["py"]) end |
.ruby ⇒ FencedCodeBlockDetector
Creates a detector for Ruby code blocks.
133 134 135 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 133 def ruby new("ruby", aliases: ["rb"]) end |
.sql ⇒ FencedCodeBlockDetector
Creates a detector for SQL code blocks.
187 188 189 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 187 def sql new("sql") end |
.toml ⇒ FencedCodeBlockDetector
Creates a detector for TOML code blocks.
151 152 153 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 151 def toml new("toml") end |
.typescript ⇒ FencedCodeBlockDetector
Creates a detector for TypeScript code blocks.
169 170 171 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 169 def typescript new("typescript", aliases: ["ts"]) end |
.yaml ⇒ FencedCodeBlockDetector
Creates a detector for YAML code blocks.
145 146 147 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 145 def yaml new("yaml", aliases: ["yml"]) end |
Instance Method Details
#detect_all(source) ⇒ Array<Region>
Detects all fenced code blocks with the configured language.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 56 def detect_all(source) return [] if source.nil? || source.empty? regions = [] lines = source.lines in_block = false start_line = nil content_lines = [] current_language = nil fence_char = nil fence_length = nil indent = "" lines.each_with_index do |line, idx| line_num = idx + 1 if !in_block # Match opening fence: ```lang or ~~~lang (optionally indented) match = line.match(/^(\s*)(`{3,}|~{3,})(\w*)\s*$/) if match indent = match[1] || "" fence = match[2] lang = match[3].downcase if @all_identifiers.include?(lang) in_block = true start_line = line_num content_lines = [] current_language = lang fence_char = fence[0] fence_length = fence.length end end elsif line.match?(/^#{Regexp.escape(indent)}#{Regexp.escape(fence_char)}{#{fence_length},}\s*$/) # Match closing fence (must use same char, same indent, and at least same length) opening_fence = "#{fence_char * fence_length}#{current_language}" closing_fence = fence_char * fence_length regions << build_region( type: region_type, content: content_lines.join, start_line: start_line, end_line: line_num, delimiters: [opening_fence, closing_fence], metadata: {language: current_language, indent: indent.empty? ? nil : indent}, ) in_block = false start_line = nil content_lines = [] current_language = nil fence_char = nil fence_length = nil indent = "" else # Accumulate content lines (strip the indent if present) content_lines << if indent.empty? line else # Strip the common indent from content lines line.sub(/^#{Regexp.escape(indent)}/, "") end end end # Note: Unclosed blocks are ignored (no region created) regions end |
#inspect ⇒ String
Returns A description of this detector.
125 126 127 128 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 125 def inspect aliases_str = @aliases.empty? ? "" : " aliases=#{@aliases.inspect}" "#<#{self.class.name} language=#{@language}#{aliases_str}>" end |
#matches_language?(lang) ⇒ Boolean
Check if a language identifier matches this detector.
48 49 50 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 48 def matches_language?(lang) @all_identifiers.include?(lang.to_s.downcase) end |
#region_type ⇒ Symbol
Returns The region type (e.g., :ruby_code_block).
40 41 42 |
# File 'lib/ast/merge/fenced_code_block_detector.rb', line 40 def region_type :"#{@language}_code_block" end |