Class: Markbridge::Processors::DiscourseMarkdown::CodeBlockTracker
- Inherits:
-
Object
- Object
- Markbridge::Processors::DiscourseMarkdown::CodeBlockTracker
- Defined in:
- lib/markbridge/processors/discourse_markdown/code_block_tracker.rb
Overview
Tracks whether the current position is inside a code block. Handles fenced code blocks (“‘ or ~~~), indented code blocks (4+ spaces), and inline code (`).
Fenced code blocks:
-
Can have leading whitespace (up to 3 spaces)
-
Opening fence: 3+ backticks or tildes, optionally followed by language
-
Closing fence: same or more fence characters as opening
Indented code blocks:
-
Lines indented by 4+ spaces or 1+ tab
-
Continues until a non-blank line with less indentation
Inline code:
-
Single or multiple backticks as delimiter
-
Content between matching backticks
Instance Attribute Summary collapse
-
#in_fenced_block ⇒ Boolean
readonly
True if currently inside a fenced code block.
-
#in_indented_block ⇒ Boolean
readonly
True if currently inside an indented code block.
-
#in_inline_code ⇒ Boolean
readonly
True if currently inside an inline code span.
Instance Method Summary collapse
-
#check_fenced_boundary(input, pos, line_start:) ⇒ Integer?
Check if position is at start of a fenced code block boundary.
-
#check_indented_boundary(input, pos, line_start:) ⇒ Integer?
Check if line at position is an indented code block line.
-
#check_inline_boundary(input, pos) ⇒ Integer?
Check for inline code boundary.
-
#in_code? ⇒ Boolean
Check if currently inside any code context.
-
#initialize ⇒ CodeBlockTracker
constructor
A new instance of CodeBlockTracker.
-
#reset! ⇒ Object
Reset the tracker state.
Constructor Details
#initialize ⇒ CodeBlockTracker
Returns a new instance of CodeBlockTracker.
32 33 34 35 36 37 38 39 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 32 def initialize @in_fenced_block = false @fence_char = nil @fence_length = 0 @in_indented_block = false @in_inline_code = false @inline_delimiter = nil end |
Instance Attribute Details
#in_fenced_block ⇒ Boolean (readonly)
Returns true if currently inside a fenced code block.
24 25 26 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 24 def in_fenced_block @in_fenced_block end |
#in_indented_block ⇒ Boolean (readonly)
Returns true if currently inside an indented code block.
27 28 29 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 27 def in_indented_block @in_indented_block end |
#in_inline_code ⇒ Boolean (readonly)
Returns true if currently inside an inline code span.
30 31 32 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 30 def in_inline_code @in_inline_code end |
Instance Method Details
#check_fenced_boundary(input, pos, line_start:) ⇒ Integer?
Check if position is at start of a fenced code block boundary
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 52 def check_fenced_boundary(input, pos, line_start:) return nil unless line_start input_length = input.length scan_pos = skip_leading_spaces(input, pos, input_length) return nil if scan_pos >= input_length fence_char = input[scan_pos] return nil unless fence_char == "`" || fence_char == "~" fence_length, scan_pos = count_fence_chars(input, scan_pos, fence_char, input_length) return nil if fence_length < 3 if @in_fenced_block try_close_fence(input, scan_pos, fence_char, fence_length, input_length) else open_fence(input, scan_pos, fence_char, fence_length, input_length) end end |
#check_indented_boundary(input, pos, line_start:) ⇒ Integer?
Check if line at position is an indented code block line. A line is considered indented code if it starts with 4+ spaces or 1+ tab. Blank lines within an indented block are considered part of it.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 80 def check_indented_boundary(input, pos, line_start:) return nil unless line_start return nil if @in_fenced_block # Fenced blocks take precedence input_length = input.length line_end = input.index("\n", pos) || input_length line_content = input[pos...line_end] is_blank = line_content.match?(/\A\s*\z/) has_code_indent = line_content.start_with?(" ") || line_content.start_with?("\t") if @in_indented_block if is_blank || has_code_indent pos_after_line(line_end, input_length) else @in_indented_block = false nil end elsif has_code_indent @in_indented_block = true pos_after_line(line_end, input_length) end end |
#check_inline_boundary(input, pos) ⇒ Integer?
Check for inline code boundary
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 107 def check_inline_boundary(input, pos) return nil if @in_fenced_block || @in_indented_block input_length = input.length return nil if pos >= input_length || input[pos] != "`" if @in_inline_code try_close_inline(input, pos, input_length) else open_inline(input, pos, input_length) end end |
#in_code? ⇒ Boolean
Check if currently inside any code context
43 44 45 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 43 def in_code? @in_fenced_block || @in_indented_block || @in_inline_code end |
#reset! ⇒ Object
Reset the tracker state
200 201 202 203 204 205 206 207 |
# File 'lib/markbridge/processors/discourse_markdown/code_block_tracker.rb', line 200 def reset! @in_fenced_block = false @fence_char = nil @fence_length = 0 @in_indented_block = false @in_inline_code = false @inline_delimiter = nil end |