Module: Docbook::Services::ElementIdHelper

Included in:
Mirror::Transformer, NumberingService, TocGenerator
Defined in:
lib/docbook/services/element_id_helper.rb

Overview

Shared helpers for consistent element ID generation and title resolution. Used by TocGenerator, NumberingService, and Mirror::Transformer to ensure IDs match between TOC, numbering, and rendered DOM.

Instance Method Summary collapse

Instance Method Details

#element_id(element) ⇒ Object

Consistent ID for any element. For RefEntry: xml_id → p_varname → elem-object_id For others: xml_id → elem-object_id



12
13
14
15
16
17
18
19
# File 'lib/docbook/services/element_id_helper.rb', line 12

def element_id(element)
  if element.is_a?(Docbook::Elements::RefEntry)
    refentry_id(element)
  else
    id = element.xml_id if element.respond_to?(:xml_id)
    id && !id.to_s.empty? ? id.to_s : "elem-#{element.object_id}"
  end
end

#refentry_id(ref) ⇒ Object

Consistent ID for RefEntry elements. Priority: xml_id → p_varname (from fieldsynopsis) → synthetic



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/docbook/services/element_id_helper.rb', line 23

def refentry_id(ref)
  id = ref.xml_id if ref.respond_to?(:xml_id)
  return id.to_s if id && !id.to_s.empty?

  if ref.respond_to?(:refmeta) && ref.refmeta
    fs = ref.refmeta.fieldsynopsis if ref.refmeta.respond_to?(:fieldsynopsis)
    if fs && !fs.empty?
      varname = fs.first.varname
      return "p_#{varname.content.join}" if varname && !varname.content.join.empty?
    end
  end

  "elem-#{ref.object_id}"
end

#resolve_refentry_title(ref) ⇒ Object

Resolve the display title for a RefEntry. Priority: refentrytitle → fieldsynopsis.varname → refname → nil



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/docbook/services/element_id_helper.rb', line 40

def resolve_refentry_title(ref)
  if ref.respond_to?(:refmeta) && ref.refmeta
    meta = ref.refmeta
    if meta.respond_to?(:refentrytitle) && meta.refentrytitle
      title = meta.refentrytitle
      return title.content.join if title.respond_to?(:content) && title.content.any?
    end
    if meta.respond_to?(:fieldsynopsis) && meta.fieldsynopsis && !meta.fieldsynopsis.empty?
      vn = meta.fieldsynopsis.first.varname
      return vn.content.join if vn.respond_to?(:content) && vn.content.any?
    end
  end

  if ref.respond_to?(:refnamediv) && ref.refnamediv.respond_to?(:refname)
    names = ref.refnamediv.refname
    return names.map { |n| n.content.join }.join(", ") if names && !names.empty?
  end

  nil
end