Class: Docbook::Output::SinglePage

Inherits:
Object
  • Object
show all
Defined in:
lib/docbook/output/single_page.rb

Overview

Generates a self-contained single-page HTML from DocBook XML.

Orchestrates the full pipeline: parse XML → generate TOC, numbering, index → transform to DocbookMirror JSON → resolve images → render HTML.

Usage: page = Docbook::Output::SinglePage.new( xml_path: "guide.xml", dist_dir: "frontend/dist", output_path: "output/guide.html", image_search_dirs: ["resources/media"], image_strategy: :data_url ) page.generate

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml_path:, output_path:, dist_dir: nil, image_search_dirs: [], image_strategy: :data_url, title: "DocBook Library", sort_glossary: false) ⇒ SinglePage

Returns a new instance of SinglePage.

Parameters:

  • xml_path (String)

    path to the DocBook XML file

  • dist_dir (String) (defaults to: nil)

    path to the frontend dist directory (defaults to gem's bundled frontend)

  • output_path (String)

    path to write the output HTML file

  • image_search_dirs (Array<String>) (defaults to: [])

    directories to search for images

  • image_strategy (Symbol) (defaults to: :data_url)

    :file_url, :data_url, or :relative

  • title (String) (defaults to: "DocBook Library")

    page title for the HTML

  • sort_glossary (Boolean) (defaults to: false)

    sort glossary entries alphabetically



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/docbook/output/single_page.rb', line 35

def initialize(xml_path:, output_path:, dist_dir: nil, image_search_dirs: [],
               image_strategy: :data_url, title: "DocBook Library",
               sort_glossary: false)
  @xml_path = xml_path
  @dist_dir = dist_dir || FRONTEND_DIST
  @output_path = output_path
  @image_search_dirs = Array(image_search_dirs)
  @image_strategy = image_strategy
  @title = title
  @sort_glossary = sort_glossary
end

Instance Attribute Details

#dist_dirObject (readonly)

Returns the value of attribute dist_dir.



25
26
27
# File 'lib/docbook/output/single_page.rb', line 25

def dist_dir
  @dist_dir
end

#image_search_dirsObject (readonly)

Returns the value of attribute image_search_dirs.



25
26
27
# File 'lib/docbook/output/single_page.rb', line 25

def image_search_dirs
  @image_search_dirs
end

#image_strategyObject (readonly)

Returns the value of attribute image_strategy.



25
26
27
# File 'lib/docbook/output/single_page.rb', line 25

def image_strategy
  @image_strategy
end

#output_pathObject (readonly)

Returns the value of attribute output_path.



25
26
27
# File 'lib/docbook/output/single_page.rb', line 25

def output_path
  @output_path
end

#xml_pathObject (readonly)

Returns the value of attribute xml_path.



25
26
27
# File 'lib/docbook/output/single_page.rb', line 25

def xml_path
  @xml_path
end

Instance Method Details

#generateString

Run the full pipeline and write the HTML file.

Returns:

  • (String)

    the output file path



49
50
51
52
53
54
55
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
# File 'lib/docbook/output/single_page.rb', line 49

def generate
  xml_dir = File.dirname(@xml_path)

  # 1. Parse the XML
  parsed = parse_xml

  # 2. Generate TOC
  toc_tree = Services::TocGenerator.new(parsed).generate
  toc_sections = toc_tree.map { |node| toc_node_to_hash(node) }

  # 3. Generate numbering
  numbering_list = Services::NumberingService.new(parsed).generate
  numbering_hash = {}
  numbering_list.each { |sn| numbering_hash[sn.id] = sn.number }

  # 4. Generate index
  index_collector = Docbook::Output::IndexCollector.new(parsed)
  index_terms = index_collector.collect
  index_generator = Docbook::Output::IndexGenerator.new(index_terms)
  index_data = index_generator.generate
  index_hash = { "title" => "Index", "type" => "index",
                 "groups" => index_data }

  # 5. Transform to DocbookMirror JSON
  require_relative "../mirror"
  require_relative "docbook_mirror"
  mirror_output = Docbook::Output::DocbookMirror.new(parsed, sort_glossary: @sort_glossary)
  guide = JSON.parse(mirror_output.to_pretty_json)

  # 6. Attach TOC, numbering, index, and metadata
  guide["toc"] =
    { "sections" => toc_sections, "numbering" => numbering_hash }
  guide["index"] = index_hash

  stats = Services::DocumentStats.new(parsed).generate
  guide["meta"] = {
    "title" => stats["title"] || @title,
    "subtitle" => stats["subtitle"],
    "author" => stats["author"],
    "pubdate" => stats["pubdate"],
    "releaseinfo" => stats["releaseinfo"],
    "copyright" => stats["copyright"],
    "root_element" => stats["root_element"],
  }.compact

  # 7. Generate lists of figures/tables/examples
  list_of = Services::ListOfGenerator.new(parsed).generate(numbering: numbering_hash)
  list_of.each do |type, entries|
    guide["list_of_#{type}"] = entries.map do |e|
      {
        "id" => e.id,
        "title" => e.title,
        "number" => e.number,
        "section_id" => e.section_id,
        "section_title" => e.section_title,
      }.compact
    end
  end

  # 8. Resolve image paths
  Services::ImageResolver.new(
    search_dirs: @image_search_dirs + [xml_dir],
    strategy: @image_strategy,
  ).resolve(guide)

  # 9. Build HTML
  write_html(guide)

  @output_path
end