coradoc-docx 0.1.2 → 0.1.3

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: e46f27d58495c1034b6fcb7e18a4b3f7361399bae351f07feecc70bf96998c00
4
- data.tar.gz: e635bc232ec683c7ac69d29ca3051cb7ff79858fb6726d97cf57abeef736405a
3
+ metadata.gz: b2d3e5bd2f76d67000623cf3a2cb3889d5b49105a7420494f6f09622bac8a61b
4
+ data.tar.gz: 2c611f389f427ac79c73b5ce6e727e602b1d392f97f6090af837d2c6a5d05d9a
5
5
  SHA512:
6
- metadata.gz: 8f59bc132f05dbc709ed0c7b31e6c633e94efde7a95e4bbf1661c18e3a737ad0ca8e592257a1029c9935e57ce679f771705cef1bbdeea0b4d00c11e4e112e4d9
7
- data.tar.gz: 926131183805ae1163e544f464417c21fe38dfb5705cb363427c83e053d7f60c8a71f65cfd0189f9003cc6498f1ec0fa54215ef3d21d87fd721619c844de7b3a
6
+ metadata.gz: faff02134845b773db02e2e8e8f4a0f99e58548b013db9ad99212fe349f1e8be7088fc153465bb32b54c584c05030d24c8cc5a07dbf0e8365ab2cd3368ed5bc6
7
+ data.tar.gz: 308659e8aaee319757fb35fd19abf69296aebe00e8d31d4405b9d262454cd1e8e020aed702a6ab043664dd13e64670bf2758bcfda41ef7c80115d6c02d4f513b
@@ -89,6 +89,8 @@ module Coradoc
89
89
  doc = Uniword::Builder::DocumentBuilder.new
90
90
  doc.title(element.title) if element.title
91
91
 
92
+ FrontmatterCoreProperties.apply(doc, FrontmatterCoreProperties.extract(element))
93
+
92
94
  transform_children(element.children, doc)
93
95
 
94
96
  doc.build
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Docx
5
+ module Transform
6
+ # Single source of truth for FrontmatterBlock -> OOXML core
7
+ # properties mapping. (MECE: DOCX-specific concerns live in the
8
+ # DOCX gem; CoreModel has no knowledge of OOXML.)
9
+ #
10
+ # Uniword's DocumentBuilder exposes setter methods (title, author,
11
+ # subject, keywords, description, date_field) that write the
12
+ # docProps/core.xml Dublin Core elements. This module reads
13
+ # FrontmatterBlock entries and invokes the right setters, so the
14
+ # mapping table lives in exactly one place.
15
+ #
16
+ # Mapping table (single source of truth):
17
+ #
18
+ # | Frontmatter key | OOXML element | Builder method |
19
+ # |-----------------------|----------------------|----------------|
20
+ # | title | dc:title | title |
21
+ # | author | dc:creator | author |
22
+ # | date | dc:date | created |
23
+ # | description, excerpt | dc:description | description |
24
+ # | subject | dc:subject | subject |
25
+ # | tags, categories | cp:keywords | keywords |
26
+ module FrontmatterCoreProperties
27
+ DESCRIPTION_KEYS = %w[description excerpt].freeze
28
+ KEYWORDS_KEYS = %w[tags categories].freeze
29
+
30
+ class << self
31
+ # Apply FrontmatterBlock data to a Uniword DocumentBuilder.
32
+ # Skips nil/empty values. Does not overwrite builder values
33
+ # that the caller has set explicitly (caller invokes this
34
+ # AFTER setting document.title, for example).
35
+ #
36
+ # @param builder [Uniword::Builder::DocumentBuilder]
37
+ # @param block [Coradoc::CoreModel::FrontmatterBlock, nil]
38
+ # @return [void]
39
+ def apply(builder, block)
40
+ return unless block.is_a?(Coradoc::CoreModel::FrontmatterBlock)
41
+
42
+ data = block.data || {}
43
+
44
+ if (v = find_first_scalar(data, KEYWORDS_KEYS))
45
+ builder.keywords(v)
46
+ end
47
+ if (v = find_first_scalar(data, %w[author]))
48
+ builder.author(v)
49
+ end
50
+ if (v = find_first_scalar(data, %w[subject]))
51
+ builder.subject(v)
52
+ end
53
+ if (v = find_first_scalar(data, DESCRIPTION_KEYS))
54
+ builder.description(v)
55
+ end
56
+ if (v = find_first_scalar(data, %w[date]))
57
+ builder.created(v)
58
+ end
59
+ end
60
+
61
+ # Locate the FrontmatterBlock in a DocumentElement's children,
62
+ # if any.
63
+ #
64
+ # @param document [Coradoc::CoreModel::DocumentElement]
65
+ # @return [Coradoc::CoreModel::FrontmatterBlock, nil]
66
+ def extract(document)
67
+ return nil unless document.is_a?(Coradoc::CoreModel::DocumentElement)
68
+
69
+ Array(document.children).find { |c| c.is_a?(Coradoc::CoreModel::FrontmatterBlock) }
70
+ end
71
+
72
+ private
73
+
74
+ def find_first_scalar(data, keys)
75
+ keys.each do |k|
76
+ value = data[k.to_s]
77
+ next if value.nil?
78
+
79
+ str = scalar_value(value)
80
+ return str if str && !str.empty?
81
+ end
82
+ nil
83
+ end
84
+
85
+ def scalar_value(value)
86
+ return nil if value.nil?
87
+
88
+ case value
89
+ when String then value
90
+ when Integer, Float, TrueClass, FalseClass then value.to_s
91
+ when Date, Time, DateTime then value.iso8601
92
+ when Symbol then value.to_s
93
+ when Array then array_to_csv(value)
94
+ when Hash then nil
95
+ else value.to_s
96
+ end
97
+ end
98
+
99
+ def array_to_csv(value)
100
+ strings = value.map { |i| scalar_value(i) }.compact
101
+ strings.any? ? strings.join(', ') : nil
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -94,7 +94,12 @@ module Coradoc
94
94
  return false unless paragraph.properties
95
95
 
96
96
  num_id = paragraph.properties.num_id
97
- num_id.to_i.positive?
97
+ # Uniword (via lutaml-model) returns an UninitializedClass
98
+ # sentinel for attributes that weren't deserialized from source.
99
+ # Treat anything that isn't a real Integer as "no list id".
100
+ return false unless num_id.is_a?(Integer)
101
+
102
+ num_id.positive?
98
103
  end
99
104
 
100
105
  # Check if paragraph has a specific role based on style name
@@ -11,6 +11,7 @@ module Coradoc
11
11
  autoload :StyleResolver, 'coradoc/docx/transform/style_resolver'
12
12
  autoload :NumberingResolver, 'coradoc/docx/transform/numbering_resolver'
13
13
  autoload :OrderedContent, 'coradoc/docx/transform/ordered_content'
14
+ autoload :FrontmatterCoreProperties, 'coradoc/docx/transform/frontmatter_core_properties'
14
15
 
15
16
  # Element transform rules
16
17
  module Rules
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module Docx
5
- VERSION = '0.1.2'
5
+ VERSION = '0.1.3'
6
6
  end
7
7
  end
data/lib/coradoc/docx.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'coradoc'
4
- require 'coradoc/core_model'
5
4
  require 'uniword'
6
5
 
7
6
  # Coradoc::Docx provides DOCX (OOXML) format support for Coradoc.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coradoc-docx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -108,6 +108,7 @@ files:
108
108
  - lib/coradoc/docx/transform.rb
109
109
  - lib/coradoc/docx/transform/context.rb
110
110
  - lib/coradoc/docx/transform/from_core_model.rb
111
+ - lib/coradoc/docx/transform/frontmatter_core_properties.rb
111
112
  - lib/coradoc/docx/transform/numbering_resolver.rb
112
113
  - lib/coradoc/docx/transform/ordered_content.rb
113
114
  - lib/coradoc/docx/transform/rule.rb
@@ -136,6 +137,7 @@ licenses:
136
137
  metadata:
137
138
  homepage_uri: https://github.com/lutaml/coradoc
138
139
  source_code_uri: https://github.com/lutaml/coradoc
140
+ rubygems_mfa_required: 'true'
139
141
  rdoc_options: []
140
142
  require_paths:
141
143
  - lib