Class: TreeHaver::Backends::Markly::Node

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/tree_haver/backends/markly.rb

Overview

Markly node wrapper

Wraps Markly::Node to provide TreeHaver::Node-compatible interface.

Note: Markly uses different type names than Commonmarker:

  • :header instead of :heading

  • :hrule instead of :thematic_break

  • :blockquote instead of :block_quote

  • :html instead of :html_block

Constant Summary collapse

TYPE_MAP =

Type normalization map (Markly → canonical)

{
  header: "heading",
  hrule: "thematic_break",
  html: "html_block",
  # blockquote is the same
  # Most types are the same between Markly and Commonmarker
}.freeze
DEFAULT_SOURCE_POSITION =

Default source position for nodes that don’t have position info

{
  start_line: 1,
  start_column: 1,
  end_line: 1,
  end_column: 1,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, source, lines = nil) ⇒ Node



223
224
225
226
227
# File 'lib/tree_haver/backends/markly.rb', line 223

def initialize(node, source, lines = nil)
  @inner_node = node
  @source = source
  @lines = lines || source.lines
end

Instance Attribute Details

#inner_nodeObject (readonly)

Returns the value of attribute inner_node.



221
222
223
# File 'lib/tree_haver/backends/markly.rb', line 221

def inner_node
  @inner_node
end

#sourceObject (readonly)

Returns the value of attribute source.



221
222
223
# File 'lib/tree_haver/backends/markly.rb', line 221

def source
  @source
end

Instance Method Details

#<=>(other) ⇒ Object



400
401
402
403
404
405
# File 'lib/tree_haver/backends/markly.rb', line 400

def <=>(other)
  return unless other.respond_to?(:start_byte)
  cmp = start_byte <=> other.start_byte
  return cmp unless cmp&.zero?
  end_byte <=> other.end_byte
end

#child(index) ⇒ Object



313
314
315
# File 'lib/tree_haver/backends/markly.rb', line 313

def child(index)
  children[index]
end

#child_countObject



309
310
311
# File 'lib/tree_haver/backends/markly.rb', line 309

def child_count
  children.size
end

#childrenArray<Node>

Get child nodes

Markly uses first_child/next pattern



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/tree_haver/backends/markly.rb', line 286

def children
  result = []
  child = begin
    @inner_node.first_child
  rescue
    nil
  end
  while child
    result << Node.new(child, @source, @lines)
    child = begin
      child.next
    rescue
      nil
    end
  end
  result
end

#each(&block) ⇒ Object



304
305
306
307
# File 'lib/tree_haver/backends/markly.rb', line 304

def each(&block)
  return to_enum(__method__) unless block
  children.each(&block)
end

#end_byteObject



327
328
329
330
331
332
# File 'lib/tree_haver/backends/markly.rb', line 327

def end_byte
  pos = inner_source_position
  line = pos[:end_line] - 1
  col = pos[:end_column] - 1
  calculate_byte_offset(line, col)
end

#end_lineInteger

Get the 1-based line number where this node ends



360
361
362
# File 'lib/tree_haver/backends/markly.rb', line 360

def end_line
  inner_source_position[:end_line]
end

#end_pointObject



341
342
343
344
345
346
# File 'lib/tree_haver/backends/markly.rb', line 341

def end_point
  pos = inner_source_position
  line = pos[:end_line] - 1
  col = pos[:end_column] - 1
  Point.new(line, col)
end

#fence_infoString?

Get fence info for code blocks



462
463
464
465
466
467
468
469
# File 'lib/tree_haver/backends/markly.rb', line 462

def fence_info
  return unless type == "code_block"
  begin
    @inner_node.fence_info
  rescue
    nil
  end
end

#first_childNode?

Get the first child node



382
383
384
# File 'lib/tree_haver/backends/markly.rb', line 382

def first_child
  children.first
end

#has_error?Boolean



392
393
394
# File 'lib/tree_haver/backends/markly.rb', line 392

def has_error?
  false
end

#header_levelInteger?

Get heading level (1-6)



451
452
453
454
455
456
457
458
# File 'lib/tree_haver/backends/markly.rb', line 451

def header_level
  return unless raw_type == "header"
  begin
    @inner_node.header_level
  rescue
    nil
  end
end

#inner_source_positionHash{Symbol => Integer}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get source position from the inner Markly node

Markly provides source_position as a hash with :start_line, :start_column, :end_line, :end_column (all 1-based).



236
237
238
239
240
241
242
# File 'lib/tree_haver/backends/markly.rb', line 236

def inner_source_position
  @inner_source_position ||= if @inner_node.respond_to?(:source_position)
    @inner_node.source_position || DEFAULT_SOURCE_POSITION
  else
    DEFAULT_SOURCE_POSITION
  end
end

#inspectObject



407
408
409
# File 'lib/tree_haver/backends/markly.rb', line 407

def inspect
  "#<TreeHaver::Backends::Markly::Node type=#{type} raw_type=#{raw_type}>"
end

#missing?Boolean



396
397
398
# File 'lib/tree_haver/backends/markly.rb', line 396

def missing?
  false
end

#named?Boolean Also known as: structural?



386
387
388
# File 'lib/tree_haver/backends/markly.rb', line 386

def named?
  true
end

#next_siblingNode?

Get the next sibling (Markly uses .next)



489
490
491
492
493
494
495
496
# File 'lib/tree_haver/backends/markly.rb', line 489

def next_sibling
  sibling = begin
    @inner_node.next
  rescue
    nil
  end
  sibling ? Node.new(sibling, @source, @lines) : nil
end

#parentNode?

Get the parent node



511
512
513
514
515
516
517
518
# File 'lib/tree_haver/backends/markly.rb', line 511

def parent
  p = begin
    @inner_node.parent
  rescue
    nil
  end
  p ? Node.new(p, @source, @lines) : nil
end

#previous_siblingNode?

Get the previous sibling



500
501
502
503
504
505
506
507
# File 'lib/tree_haver/backends/markly.rb', line 500

def previous_sibling
  sibling = begin
    @inner_node.previous
  rescue
    nil
  end
  sibling ? Node.new(sibling, @source, @lines) : nil
end

#raw_typeString

Get the raw (non-normalized) type



258
259
260
# File 'lib/tree_haver/backends/markly.rb', line 258

def raw_type
  @inner_node.type.to_s
end

#source_positionHash{Symbol => Integer}

Get position information as a hash

Returns a hash with 1-based line numbers and 0-based columns. Compatible with *-merge gems’ FileAnalysisBase.



370
371
372
373
374
375
376
377
# File 'lib/tree_haver/backends/markly.rb', line 370

def source_position
  {
    start_line: start_line,
    end_line: end_line,
    start_column: start_point.column,
    end_column: end_point.column,
  }
end

#start_byteObject

Position information Markly provides source_position as a hash with :start_line, :start_column, :end_line, :end_column (1-based)



320
321
322
323
324
325
# File 'lib/tree_haver/backends/markly.rb', line 320

def start_byte
  pos = inner_source_position
  line = pos[:start_line] - 1
  col = pos[:start_column] - 1
  calculate_byte_offset(line, col)
end

#start_lineInteger

Get the 1-based line number where this node starts

Markly provides 1-based line numbers via source_position hash.



353
354
355
# File 'lib/tree_haver/backends/markly.rb', line 353

def start_line
  inner_source_position[:start_line]
end

#start_pointObject



334
335
336
337
338
339
# File 'lib/tree_haver/backends/markly.rb', line 334

def start_point
  pos = inner_source_position
  line = pos[:start_line] - 1
  col = pos[:start_column] - 1
  Point.new(line, col)
end

#textString

Get the text content of this node



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/tree_haver/backends/markly.rb', line 265

def text
  # Markly nodes have string_content for leaf nodes
  if @inner_node.respond_to?(:string_content)
    @inner_node.string_content.to_s
  elsif @inner_node.respond_to?(:to_plaintext)
    # For container nodes, use to_plaintext or concatenate
    begin
      @inner_node.to_plaintext
    rescue
      children.map(&:text).join
    end
  else
    children.map(&:text).join
  end
end

#titleString?

Get title for links/images



481
482
483
484
485
# File 'lib/tree_haver/backends/markly.rb', line 481

def title
  @inner_node.title
rescue
  nil
end

#to_commonmarkString

Convert node to CommonMark format

Delegates to the inner Markly node’s to_commonmark method.



416
417
418
# File 'lib/tree_haver/backends/markly.rb', line 416

def to_commonmark
  @inner_node.to_commonmark
end

#to_htmlString

Convert node to HTML

Delegates to the inner Markly node’s to_html method.



443
444
445
# File 'lib/tree_haver/backends/markly.rb', line 443

def to_html
  @inner_node.to_html
end

#to_markdownString

Convert node to Markdown format

Delegates to the inner Markly node’s to_markdown method.



425
426
427
# File 'lib/tree_haver/backends/markly.rb', line 425

def to_markdown
  @inner_node.to_markdown
end

#to_plaintextString

Convert node to plain text

Delegates to the inner Markly node’s to_plaintext method.



434
435
436
# File 'lib/tree_haver/backends/markly.rb', line 434

def to_plaintext
  @inner_node.to_plaintext
end

#typeString Also known as: kind

Get the node type as a string

Normalizes Markly types to canonical names for consistency.



249
250
251
252
# File 'lib/tree_haver/backends/markly.rb', line 249

def type
  raw_type = @inner_node.type.to_s
  TYPE_MAP[raw_type.to_sym]&.to_s || raw_type
end

#urlString?

Get URL for links/images



473
474
475
476
477
# File 'lib/tree_haver/backends/markly.rb', line 473

def url
  @inner_node.url
rescue
  nil
end