Class: Uniword::Assembly::Toc

Inherits:
Object
  • Object
show all
Defined in:
lib/uniword/assembly/toc.rb

Overview

Table of Contents model.

Represents a Word Table of Contents with configuration and entries. This is a non-serializable model that generates serializable paragraphs.

Following TODO.themes design principles:

  • Non-Serializable Model: Has state + behavior, no direct XML serialization

  • Generates serializable Paragraph objects for the document

Examples:

Create a TOC with default settings

toc = Toc.new
entries = toc.extract_entries(document)
paragraphs = toc.generate_paragraphs(entries)

Create a TOC with custom settings

toc = Toc.new(
  max_level: 3,
  title: "Contents",
  include_page_numbers: true,
  create_hyperlinks: true
)
paragraphs = toc.generate_from_document(document)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title: "Table of Contents", max_level: 9, include_page_numbers: true, create_hyperlinks: true, instruction: nil) ⇒ Toc

Initialize a TOC.

Parameters:

  • title (String) (defaults to: "Table of Contents")

    The TOC title (default: “Table of Contents”)

  • max_level (Integer) (defaults to: 9)

    Maximum heading level to include (1-9)

  • include_page_numbers (Boolean) (defaults to: true)

    Whether to include page numbers

  • create_hyperlinks (Boolean) (defaults to: true)

    Whether to create hyperlinks

  • instruction (TocInstruction, nil) (defaults to: nil)

    Optional custom instruction



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/uniword/assembly/toc.rb', line 53

def initialize(title: "Table of Contents",
               max_level: 9,
               include_page_numbers: true,
               create_hyperlinks: true,
               instruction: nil)
  @title = title
  @max_level = max_level
  @include_page_numbers = include_page_numbers
  @create_hyperlinks = create_hyperlinks
  @instruction = instruction || TocInstruction.new(outline_levels: "1-#{max_level}")
  @entries = []
end

Instance Attribute Details

Returns Whether to create hyperlinks to headings.

Returns:

  • (Boolean)

    Whether to create hyperlinks to headings



38
39
40
# File 'lib/uniword/assembly/toc.rb', line 38

def create_hyperlinks
  @create_hyperlinks
end

#entriesArray<TocEntry> (readonly)

Returns The TOC entries.

Returns:



44
45
46
# File 'lib/uniword/assembly/toc.rb', line 44

def entries
  @entries
end

#include_page_numbersBoolean (readonly)

Returns Whether to include page numbers.

Returns:

  • (Boolean)

    Whether to include page numbers



35
36
37
# File 'lib/uniword/assembly/toc.rb', line 35

def include_page_numbers
  @include_page_numbers
end

#instructionTocInstruction? (readonly)

Returns The TOC field instruction.

Returns:



41
42
43
# File 'lib/uniword/assembly/toc.rb', line 41

def instruction
  @instruction
end

#max_levelInteger (readonly)

Returns Maximum heading level to include (1-9).

Returns:

  • (Integer)

    Maximum heading level to include (1-9)



32
33
34
# File 'lib/uniword/assembly/toc.rb', line 32

def max_level
  @max_level
end

#titleString (readonly)

Returns The TOC title.

Returns:

  • (String)

    The TOC title



29
30
31
# File 'lib/uniword/assembly/toc.rb', line 29

def title
  @title
end

Instance Method Details

#extract_entries(document) ⇒ Array<TocEntry>

Extract TOC entries from a document.

Parameters:

Returns:

  • (Array<TocEntry>)

    Extracted entries



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
# File 'lib/uniword/assembly/toc.rb', line 70

def extract_entries(document)
  @entries = []
  bookmark_counter = 0

  document.paragraphs.each_with_index do |paragraph, index|
    level = heading_level(paragraph)
    next unless level && level <= @max_level

    text = extract_text(paragraph)
    next if text.nil? || text.strip.empty?

    # Create bookmark name if creating hyperlinks
    bookmark_name = nil
    if @create_hyperlinks
      bookmark_counter += 1
      bookmark_name = "_Toc#{bookmark_counter}"
    end

    @entries << TocEntry.new(
      text: text.strip,
      level: level,
      paragraph_index: index,
      bookmark_name: bookmark_name,
    )
  end

  @entries
end

#generate_document(document) ⇒ Wordprocessingml::DocumentRoot

Generate a new document containing the TOC.

Parameters:

Returns:



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/uniword/assembly/toc.rb', line 129

def generate_document(document)
  toc_paragraphs = generate_from_document(document)

  # Create new document
  toc_doc = Wordprocessingml::DocumentRoot.new

  # Add TOC paragraphs
  toc_doc.body.paragraphs.concat(toc_paragraphs)

  toc_doc
end

#generate_from_document(document) ⇒ Array<Wordprocessingml::Paragraph>

Generate TOC from document in one step.

Parameters:

Returns:



120
121
122
123
# File 'lib/uniword/assembly/toc.rb', line 120

def generate_from_document(document)
  extract_entries(document)
  generate_paragraphs
end

#generate_paragraphsArray<Wordprocessingml::Paragraph>

Generate TOC paragraphs from entries.

Returns:



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/uniword/assembly/toc.rb', line 102

def generate_paragraphs
  paragraphs = []

  # Add title paragraph
  paragraphs << create_title_paragraph if @title && !@title.empty?

  # Add entry paragraphs
  @entries.each do |entry|
    paragraphs << entry.to_paragraph(include_page_numbers: @include_page_numbers)
  end

  paragraphs
end

#insert_into(document, position = 0) ⇒ void

This method returns an undefined value.

Insert TOC into document at position.

Parameters:



146
147
148
149
150
151
152
153
# File 'lib/uniword/assembly/toc.rb', line 146

def insert_into(document, position = 0)
  toc_paragraphs = generate_from_document(document)

  # Insert paragraphs at position (reverse to maintain order)
  toc_paragraphs.reverse.each do |para|
    document.paragraphs.insert(position, para)
  end
end

#instruction_stringString

Get the TOC field instruction string.

Returns:

  • (String)

    The instruction string



158
159
160
# File 'lib/uniword/assembly/toc.rb', line 158

def instruction_string
  @instruction&.to_s || "TOC \\o \"1-#{@max_level}\" \\h \\z"
end