# frozen_string_literal: true module Ezdoc class Document include Builder attr_reader :nodes, :styles def self.create(path, &block) doc = new block.call(doc) doc.save(path) doc end def initialize @nodes = [] @format_stack = [] @current_target = nil @current_list = nil @current_table = nil @current_row = nil @num_id_counter = 0 @images = {} @styles = {} register_built_in_styles end def define_style(name, **properties) @styles[name] = Style.new(name, **properties) end def style(name) @styles[name] end def save(path) Package.new(self).save(path) end def lists @nodes.select { |n| n.is_a?(Nodes::List) } end def images @images.values end def register_image(path, width: nil, height: nil) return @images[path] if @images[path] rid = next_image_rid width_emu, height_emu = ImageDimensions.calculate_emus(path, width: width, height: height) image = Nodes::Image.new(path, rid: rid, width_emu: width_emu, height_emu: height_emu) @images[path] = image image end private def next_image_rid # rId1 = styles.xml (always present) # rId2 = numbering.xml (if lists present) # rId3+ = images base = lists.any? ? 3 : 2 "rId#{base + @images.size}" end def register_built_in_styles # Headings (spacing_before ensures they're rendered as paragraph styles) define_style :heading1, size: 24, bold: true, spacing_before: 240, spacing_after: 120 define_style :heading2, size: 18, bold: true, spacing_before: 200, spacing_after: 100 define_style :heading3, size: 14, bold: true, spacing_before: 160, spacing_after: 80 define_style :heading4, size: 12, bold: true, spacing_before: 120, spacing_after: 60 define_style :heading5, size: 11, bold: true, italic: true, spacing_before: 100, spacing_after: 40 define_style :heading6, size: 10, bold: true, italic: true, spacing_before: 80, spacing_after: 40 # Other built-in styles define_style :title, size: 26, bold: true, align: :center define_style :subtitle, size: 15, italic: true, color: "666666" define_style :quote, italic: true, color: "666666", indent: 720 define_style :code, font: "Courier New", size: 10 end end end