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

Inherits:
Object
  • Object
show all
Includes:
Comparable, Enumerable
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

Returns a new instance of Node.



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

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.



246
247
248
# File 'lib/tree_haver/backends/markly.rb', line 246

def inner_node
  @inner_node
end

#sourceObject (readonly)

Returns the value of attribute source.



246
247
248
# File 'lib/tree_haver/backends/markly.rb', line 246

def source
  @source
end

Instance Method Details

#<=>(other) ⇒ Object



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

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



338
339
340
# File 'lib/tree_haver/backends/markly.rb', line 338

def child(index)
  children[index]
end

#child_countObject



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

def child_count
  children.size
end

#childrenArray<Node>

Get child nodes

Markly uses first_child/next pattern

Returns:

  • (Array<Node>)

    Child nodes



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/tree_haver/backends/markly.rb', line 311

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



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

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

#end_byteObject



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

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

Returns:

  • (Integer)

    1-based line number



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

def end_line
  inner_source_position[:end_line]
end

#end_pointObject



366
367
368
369
370
371
# File 'lib/tree_haver/backends/markly.rb', line 366

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

Returns:

  • (String, nil)


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

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

#first_childNode?

Get the first child node

Returns:

  • (Node, nil)

    First child or nil



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

def first_child
  children.first
end

#has_error?Boolean

Returns:

  • (Boolean)


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

def has_error?
  false
end

#header_levelInteger?

Get heading level (1-6)

Returns:

  • (Integer, nil)


476
477
478
479
480
481
482
483
# File 'lib/tree_haver/backends/markly.rb', line 476

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).

Returns:

  • (Hash{Symbol => Integer})

    Source position from Markly



261
262
263
264
265
266
267
# File 'lib/tree_haver/backends/markly.rb', line 261

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



432
433
434
# File 'lib/tree_haver/backends/markly.rb', line 432

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

#missing?Boolean

Returns:

  • (Boolean)


421
422
423
# File 'lib/tree_haver/backends/markly.rb', line 421

def missing?
  false
end

#named?Boolean Also known as: structural?

Returns:

  • (Boolean)


411
412
413
# File 'lib/tree_haver/backends/markly.rb', line 411

def named?
  true
end

#next_siblingNode?

Get the next sibling (Markly uses .next)

Returns:



514
515
516
517
518
519
520
521
# File 'lib/tree_haver/backends/markly.rb', line 514

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

#parentNode?

Get the parent node

Returns:



536
537
538
539
540
541
542
543
# File 'lib/tree_haver/backends/markly.rb', line 536

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

#prev_siblingNode?

Get the previous sibling

Returns:



525
526
527
528
529
530
531
532
# File 'lib/tree_haver/backends/markly.rb', line 525

def prev_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

Returns:

  • (String)


283
284
285
# File 'lib/tree_haver/backends/markly.rb', line 283

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.

Returns:

  • (Hash{Symbol => Integer})

    Position hash



395
396
397
398
399
400
401
402
# File 'lib/tree_haver/backends/markly.rb', line 395

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)



345
346
347
348
349
350
# File 'lib/tree_haver/backends/markly.rb', line 345

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.

Returns:

  • (Integer)

    1-based line number



378
379
380
# File 'lib/tree_haver/backends/markly.rb', line 378

def start_line
  inner_source_position[:start_line]
end

#start_pointObject



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

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

Returns:

  • (String)

    Node text



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

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

Returns:

  • (String, nil)


506
507
508
509
510
# File 'lib/tree_haver/backends/markly.rb', line 506

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.

Returns:

  • (String)

    CommonMark representation



441
442
443
# File 'lib/tree_haver/backends/markly.rb', line 441

def to_commonmark
  @inner_node.to_commonmark
end

#to_htmlString

Convert node to HTML

Delegates to the inner Markly node’s to_html method.

Returns:

  • (String)

    HTML representation



468
469
470
# File 'lib/tree_haver/backends/markly.rb', line 468

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.

Returns:

  • (String)

    Markdown representation



450
451
452
# File 'lib/tree_haver/backends/markly.rb', line 450

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.

Returns:

  • (String)

    Plain text representation



459
460
461
# File 'lib/tree_haver/backends/markly.rb', line 459

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.

Returns:

  • (String)

    Node type



274
275
276
277
# File 'lib/tree_haver/backends/markly.rb', line 274

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

Returns:

  • (String, nil)


498
499
500
501
502
# File 'lib/tree_haver/backends/markly.rb', line 498

def url
  @inner_node.url
rescue
  nil
end