notare 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 959b59c2f2dc30ff265115057c1fd304f3b7747adfe16c9818e6de9e5c564fc1
4
- data.tar.gz: 6c3da88bce319ed81fdb519308d6854c00f6a846343e37178e6bafab2b1fefbb
3
+ metadata.gz: 4e116d849dd9df432a85354eb49dffa27534f69396179a578f3b9a7a0e9dabc0
4
+ data.tar.gz: 8a17f5088b3353f1f5c7fc3883cd945af14b3f0b0e7ae530c8026692b0e359f3
5
5
  SHA512:
6
- metadata.gz: '00558f142269e3927cdb5aab15271a92533a48ff5ff2cf19c349e8757ccd9da77af9d27a249bc1a2551c910b8578a8bc9a354622cea7c20424183b7230bc06b9'
7
- data.tar.gz: 2f179ca2e773afe314151b61fb9de4e48a6b0037bba3ce50397636b9f2a26790f5e0399c11f5d807c4f3a3090f562e094d0e02da40b4a77719f1bd4c3ea7ee8a
6
+ metadata.gz: 5e95cfaa9f3259b6689c05615617fc1fdfeb38f664d9cf07b27dacc6107bf07c0f06461e2b2a13558b9f48b8aec277f44d6690958d36262f48ef2cda0a6be72f
7
+ data.tar.gz: 52ed371afa8c50a243e160d7903d616c43a5c2359b184a4c0e114c7fce99816554dfd1bdfa951eb8a7cdbcd77fc3fa1a501bbbb56b5959b9dc51140b7bd10040
@@ -4,16 +4,21 @@ module Notare
4
4
  class Document
5
5
  include Builder
6
6
 
7
- attr_reader :nodes, :styles, :table_styles, :hyperlinks
7
+ DEFAULT_FONT = "Arial"
8
+ DEFAULT_SIZE = 12
8
9
 
9
- def self.create(path, &block)
10
- doc = new
10
+ attr_reader :nodes, :styles, :table_styles, :hyperlinks, :default_font, :default_size
11
+
12
+ def self.create(path, default_font: DEFAULT_FONT, default_size: DEFAULT_SIZE, &block)
13
+ doc = new(default_font: default_font, default_size: default_size)
11
14
  block.call(doc)
12
15
  doc.save(path)
13
16
  doc
14
17
  end
15
18
 
16
- def initialize
19
+ def initialize(default_font: DEFAULT_FONT, default_size: DEFAULT_SIZE)
20
+ @default_font = default_font
21
+ @default_size = default_size
17
22
  @nodes = []
18
23
  @format_stack = []
19
24
  @current_target = nil
@@ -51,7 +56,7 @@ module Notare
51
56
  end
52
57
 
53
58
  def lists
54
- @nodes.select { |n| n.is_a?(Nodes::List) }
59
+ @nodes.grep(Nodes::List)
55
60
  end
56
61
 
57
62
  def uses_lists?
@@ -101,12 +106,12 @@ module Notare
101
106
 
102
107
  def register_built_in_styles
103
108
  # Headings (spacing_before ensures they're rendered as paragraph styles)
104
- define_style :heading1, size: 24, bold: true, spacing_before: 240, spacing_after: 120
105
- define_style :heading2, size: 18, bold: true, spacing_before: 200, spacing_after: 100
109
+ define_style :heading1, size: 20, bold: true, spacing_before: 240, spacing_after: 120
110
+ define_style :heading2, size: 16, bold: true, spacing_before: 200, spacing_after: 100
106
111
  define_style :heading3, size: 14, bold: true, spacing_before: 160, spacing_after: 80
107
112
  define_style :heading4, size: 12, bold: true, spacing_before: 120, spacing_after: 60
108
- define_style :heading5, size: 11, bold: true, italic: true, spacing_before: 100, spacing_after: 40
109
- define_style :heading6, size: 10, bold: true, italic: true, spacing_before: 80, spacing_after: 40
113
+ define_style :heading5, size: 12, bold: true, italic: true, spacing_before: 100, spacing_after: 40
114
+ define_style :heading6, size: 12, italic: true, spacing_before: 80, spacing_after: 40
110
115
 
111
116
  # Other built-in styles
112
117
  define_style :title, size: 26, bold: true, align: :center
@@ -8,7 +8,7 @@ module Notare
8
8
  def initialize(text, bold: false, italic: false, underline: false,
9
9
  strike: false, highlight: nil, color: nil, style: nil)
10
10
  super()
11
- @text = text
11
+ @text = XmlSanitizer.sanitize(text)
12
12
  @bold = bold
13
13
  @italic = italic
14
14
  @underline = underline
@@ -59,7 +59,12 @@ module Notare
59
59
  end
60
60
 
61
61
  def styles_xml
62
- Xml::StylesXml.new(@document.styles, @document.table_styles).to_xml
62
+ Xml::StylesXml.new(
63
+ @document.styles,
64
+ @document.table_styles,
65
+ default_font: @document.default_font,
66
+ default_size: @document.default_size
67
+ ).to_xml
63
68
  end
64
69
 
65
70
  def numbering_xml
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Notare
4
- VERSION = "0.0.5"
4
+ VERSION = "0.0.7"
5
5
  end
@@ -18,9 +18,11 @@ module Notare
18
18
  right: "right"
19
19
  }.freeze
20
20
 
21
- def initialize(styles, table_styles = {})
21
+ def initialize(styles, table_styles = {}, default_font: nil, default_size: nil)
22
22
  @styles = styles
23
23
  @table_styles = table_styles
24
+ @default_font = default_font
25
+ @default_size = default_size
24
26
  end
25
27
 
26
28
  def to_xml
@@ -28,6 +30,8 @@ module Notare
28
30
  xml.styles("xmlns:w" => NAMESPACE) do
29
31
  xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
30
32
 
33
+ render_doc_defaults(xml) if @default_font || @default_size
34
+
31
35
  @styles.each_value do |style|
32
36
  render_style(xml, style)
33
37
  end
@@ -44,6 +48,28 @@ module Notare
44
48
 
45
49
  private
46
50
 
51
+ def render_doc_defaults(xml)
52
+ xml["w"].docDefaults do
53
+ xml["w"].rPrDefault do
54
+ xml["w"].rPr do
55
+ if @default_font
56
+ xml["w"].rFonts(
57
+ "w:ascii" => @default_font,
58
+ "w:hAnsi" => @default_font,
59
+ "w:eastAsia" => @default_font,
60
+ "w:cs" => @default_font
61
+ )
62
+ end
63
+ if @default_size
64
+ half_points = (@default_size * 2).to_i
65
+ xml["w"].sz("w:val" => half_points.to_s)
66
+ xml["w"].szCs("w:val" => half_points.to_s)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
47
73
  def render_style(xml, style)
48
74
  style_type = style.paragraph_properties? ? "paragraph" : "character"
49
75
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notare
4
+ module XmlSanitizer
5
+ # Invalid XML 1.0 characters: 0x00, 0x01-0x08, 0x0B-0x0C, 0x0E-0x1F
6
+ # Valid whitespace preserved: 0x09 (tab), 0x0A (LF), 0x0D (CR)
7
+ INVALID_XML_CHARS = /[\x00-\x08\x0B\x0C\x0E-\x1F]/
8
+
9
+ def self.sanitize(text)
10
+ return text unless text.is_a?(String)
11
+
12
+ text.gsub(INVALID_XML_CHARS, "")
13
+ end
14
+ end
15
+ end
data/lib/notare.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "nokogiri"
4
4
 
5
5
  require_relative "notare/version"
6
+ require_relative "notare/xml_sanitizer"
6
7
  require_relative "notare/nodes/base"
7
8
  require_relative "notare/nodes/break"
8
9
  require_relative "notare/nodes/hyperlink"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notare
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-12-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: fastimage
@@ -109,7 +108,6 @@ dependencies:
109
108
  - !ruby/object:Gem::Version
110
109
  version: '1.69'
111
110
  description: Notare provides a clean DSL for creating Word documents in Ruby
112
- email:
113
111
  executables: []
114
112
  extensions: []
115
113
  extra_rdoc_files: []
@@ -141,12 +139,12 @@ files:
141
139
  - lib/notare/xml/numbering.rb
142
140
  - lib/notare/xml/relationships.rb
143
141
  - lib/notare/xml/styles_xml.rb
142
+ - lib/notare/xml_sanitizer.rb
144
143
  homepage: https://git.kaukus.no/Kaukus/Notare
145
144
  licenses:
146
145
  - MIT
147
146
  metadata:
148
147
  rubygems_mfa_required: 'true'
149
- post_install_message:
150
148
  rdoc_options: []
151
149
  require_paths:
152
150
  - lib
@@ -161,8 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
159
  - !ruby/object:Gem::Version
162
160
  version: '0'
163
161
  requirements: []
164
- rubygems_version: 3.4.13
165
- signing_key:
162
+ rubygems_version: 4.0.3
166
163
  specification_version: 4
167
164
  summary: A Ruby gem for creating docx files with a simple DSL
168
165
  test_files: []