This commit is contained in:
85
lib/notare/document.rb
Normal file
85
lib/notare/document.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Notare
|
||||
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
|
||||
Reference in New Issue
Block a user