Support configurable default font and size #10

Merged
mathias234 merged 2 commits from feature/default-font-and-size into main 2026-03-05 14:49:09 +00:00
5 changed files with 49 additions and 13 deletions

View File

@@ -4,16 +4,21 @@ module Notare
class Document class Document
include Builder include Builder
attr_reader :nodes, :styles, :table_styles, :hyperlinks DEFAULT_FONT = "Arial"
DEFAULT_SIZE = 12
def self.create(path, &block) attr_reader :nodes, :styles, :table_styles, :hyperlinks, :default_font, :default_size
doc = new
def self.create(path, default_font: DEFAULT_FONT, default_size: DEFAULT_SIZE, &block)
doc = new(default_font: default_font, default_size: default_size)
block.call(doc) block.call(doc)
doc.save(path) doc.save(path)
doc doc
end end
def initialize def initialize(default_font: DEFAULT_FONT, default_size: DEFAULT_SIZE)
@default_font = default_font
@default_size = default_size
@nodes = [] @nodes = []
@format_stack = [] @format_stack = []
@current_target = nil @current_target = nil
@@ -51,7 +56,7 @@ module Notare
end end
def lists def lists
@nodes.select { |n| n.is_a?(Nodes::List) } @nodes.grep(Nodes::List)
end end
def uses_lists? def uses_lists?
@@ -101,12 +106,12 @@ module Notare
def register_built_in_styles def register_built_in_styles
# Headings (spacing_before ensures they're rendered as paragraph 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 :heading1, size: 20, bold: true, spacing_before: 240, spacing_after: 120
define_style :heading2, size: 18, bold: true, spacing_before: 200, spacing_after: 100 define_style :heading2, size: 16, bold: true, spacing_before: 200, spacing_after: 100
define_style :heading3, size: 14, bold: true, spacing_before: 160, spacing_after: 80 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 :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 :heading5, size: 12, 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 define_style :heading6, size: 12, italic: true, spacing_before: 80, spacing_after: 40
# Other built-in styles # Other built-in styles
define_style :title, size: 26, bold: true, align: :center define_style :title, size: 26, bold: true, align: :center

View File

@@ -59,7 +59,12 @@ module Notare
end end
def styles_xml def styles_xml
Xml::StylesXml.new(@document.styles, @document.table_styles).to_xml Xml::StylesXml.new(
@document.styles,
@document.table_styles,
default_font: @document.default_font,
default_size: @document.default_size
).to_xml
end end
def numbering_xml def numbering_xml

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module Notare module Notare
VERSION = "0.0.6" VERSION = "0.0.7"
end end

View File

@@ -18,9 +18,11 @@ module Notare
right: "right" right: "right"
}.freeze }.freeze
def initialize(styles, table_styles = {}) def initialize(styles, table_styles = {}, default_font: nil, default_size: nil)
@styles = styles @styles = styles
@table_styles = table_styles @table_styles = table_styles
@default_font = default_font
@default_size = default_size
end end
def to_xml def to_xml
@@ -28,6 +30,8 @@ module Notare
xml.styles("xmlns:w" => NAMESPACE) do xml.styles("xmlns:w" => NAMESPACE) do
xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" } xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
render_doc_defaults(xml) if @default_font || @default_size
@styles.each_value do |style| @styles.each_value do |style|
render_style(xml, style) render_style(xml, style)
end end
@@ -44,6 +48,28 @@ module Notare
private private
def render_doc_defaults(xml)
xml["w"].docDefaults do
xml["w"].rPrDefault do
xml["w"].rPr do
if @default_font
xml["w"].rFonts(
"w:ascii" => @default_font,
"w:hAnsi" => @default_font,
"w:eastAsia" => @default_font,
"w:cs" => @default_font
)
end
if @default_size
half_points = (@default_size * 2).to_i
xml["w"].sz("w:val" => half_points.to_s)
xml["w"].szCs("w:val" => half_points.to_s)
end
end
end
end
end
def render_style(xml, style) def render_style(xml, style)
style_type = style.paragraph_properties? ? "paragraph" : "character" style_type = style.paragraph_properties? ? "paragraph" : "character"

View File

@@ -69,6 +69,6 @@ class DocumentTest < Minitest::Test
doc.table { doc.tr { doc.td "Cell" } } doc.table { doc.tr { doc.td "Cell" } }
assert_equal 2, doc.lists.count assert_equal 2, doc.lists.count
assert(doc.lists.all? { |l| l.is_a?(Notare::Nodes::List) }) assert(doc.lists.all?(Notare::Nodes::List))
end end
end end