oxml_maker 0.1.1 → 0.1.2

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: 04e8ffba5e41ae76da239d31522428b1b0ea32f66f6ecf7cbf2a5c81c742a158
4
- data.tar.gz: 44b680d0515bc4081474d741a90ef4e75bb1baac4140dc25f94e54d91d4fa94c
3
+ metadata.gz: 8a34e4889ab877b4ffd10572cdf45d54cf1f860d1980e74fb20840190cd5b6f7
4
+ data.tar.gz: 81315caa4bf153a02f3045e0248c87348a0c8f0eb3984fec30253c3fb0d92bd7
5
5
  SHA512:
6
- metadata.gz: e861ef91354f8eae531c3863fe24051e5083de602a3f4ba5968affe66c2c8b0f41c229cc6c1b987d7f1b07961827d29610d0ad23d82f175257b98c2f92a785d4
7
- data.tar.gz: 565441a6e469752394a08bde5dd1baf50cb7d4bfc7e8d6d8f07fc9164f1f6354a6450fda223579421c961a9a67091f39578ad29595edd8a891abb877e0e0b494
6
+ metadata.gz: 3f67753dcad5da06668f027ac73cb93f77bf64a587d1ec2c63c305fcfba3340bf8e978ebf7f40e143865411547ce95035a706b381a8ccd749bdb26b4549fe295
7
+ data.tar.gz: 6b6cf09d9f221b644dc6308a6ae9503ebbb6e94e782367d1337af12bd9800e02733d5cca1e08906a82f70f1c3b5a82205d846170b0b03a91ec859de72a6a6b1d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2] - 2025-10-21
4
+
5
+ ### Added
6
+ - Advanced table features: `v_merge` and `new_line` functionality
7
+ - Comprehensive test suite for advanced table features (4 new tests)
8
+ - Support for vertical cell merging in tables
9
+ - Multi-line cell content with comma-separated value splitting
10
+ - Test coverage for complex table scenarios with real-world data examples
11
+
12
+ ### Enhanced
13
+ - Table functionality with advanced formatting capabilities
14
+ - Test suite expanded to 67 tests with 344 assertions
15
+ - Documentation of table feature limitations and implementation details
16
+
3
17
  ## [0.1.1] - 2025-10-20
4
18
 
5
19
  ### Added
data/README.md CHANGED
@@ -276,6 +276,156 @@ end
276
276
  - `refute condition` - Test falsiness
277
277
  - `assert_kind_of Class, object` - Test object type
278
278
 
279
+ ## Why OxmlMaker is Different: The Ruby Object Revolution
280
+
281
+ ### The Problem with Traditional DOCX Gems
282
+
283
+ Most Ruby DOCX libraries force you into rigid patterns:
284
+
285
+ ```ruby
286
+ # Traditional approach - manual, inflexible
287
+ builder.table do |t|
288
+ t.row ["Name", "Age"] # Static arrays only
289
+ t.row ["John", "30"] # Manual string building
290
+ t.row ["Jane", "25"] # Can't use objects directly
291
+ end
292
+ ```
293
+
294
+ ### OxmlMaker's Revolutionary Approach
295
+
296
+ **Direct Ruby Object Mapping** - Use ANY Ruby object with methods:
297
+
298
+ ```ruby
299
+ # Revolutionary - works with ANY objects!
300
+ data: {
301
+ 0 => [
302
+ OpenStruct.new(name: "John", age: 30), # OpenStruct
303
+ User.find(1), # ActiveRecord model
304
+ JSON.parse('{"name": "Jane"}'), # JSON object
305
+ api_response.data, # API response
306
+ custom_object # Any object with methods
307
+ ]
308
+ }
309
+
310
+ # Table automatically calls methods dynamically
311
+ { value: :name } # Calls object.name on each object
312
+ { value: :email } # Calls object.email on each object
313
+ ```
314
+
315
+ ### Perfect for Modern Architectures
316
+
317
+ #### 1. **JSON-Native Design**
318
+ Built for API-first and headless architectures:
319
+
320
+ ```ruby
321
+ # HTML → JSON → DOCX pipeline
322
+ html_content = "<div><h1>Title</h1><table>...</table></div>"
323
+ json_data = html_to_json_parser(html_content)
324
+
325
+ # Direct consumption - no transformation needed!
326
+ doc = OxmlMaker::Document.new(
327
+ filename: "converted.docx",
328
+ params: json_data # Pure JSON input
329
+ )
330
+ ```
331
+
332
+ #### 2. **Polymorphic Data Handling**
333
+ Mix any data sources in the same document:
334
+
335
+ ```ruby
336
+ # Different object types in the same table!
337
+ data: {
338
+ 0 => [
339
+ user_model, # ActiveRecord object
340
+ { name: "Jane" }, # Hash
341
+ OpenStruct.new(name: "Bob"), # OpenStruct
342
+ json_api_response # JSON object
343
+ ]
344
+ }
345
+ ```
346
+
347
+ #### 3. **Configuration-Driven Architecture**
348
+ Documents are pure data structures - serializable and cacheable:
349
+
350
+ ```ruby
351
+ # Store templates as JSON in database
352
+ template = DocumentTemplate.find_by(name: "invoice")
353
+ live_data = Invoice.includes(:line_items).find(params[:id])
354
+
355
+ # Merge template with live data
356
+ params = template.structure.deep_merge({
357
+ sections: [{
358
+ table: {
359
+ data: { 0 => live_data.line_items.to_a } # Direct AR relation!
360
+ }
361
+ }]
362
+ })
363
+ ```
364
+
365
+ ### Comparison with Other Ruby DOCX Gems
366
+
367
+ | Feature | OxmlMaker | Caracal | ruby-docx | docx | sablon |
368
+ |---------|-----------|---------|-----------|------|--------|
369
+ | **Ruby Object Mapping** | ✅ Dynamic | ❌ Manual | ❌ Manual | ❌ Template | ❌ Template |
370
+ | **JSON Serializable** | ✅ 100% | ❌ Code-based | ❌ Code-based | ❌ Template | ❌ Template |
371
+ | **Any Ruby Object** | ✅ Polymorphic | ❌ Arrays only | ❌ Limited | ❌ Static | ❌ Mail merge |
372
+ | **HTML→JSON→DOCX** | ✅ Native | ❌ Complex | ❌ N/A | ❌ N/A | ❌ Template only |
373
+ | **API-Friendly** | ✅ Pure data | ❌ Code required | ❌ Code required | ❌ Files | ❌ Templates |
374
+ | **Microservices Ready** | ✅ Stateless | ❌ Complex | ❌ Complex | ❌ File-based | ❌ Template-based |
375
+
376
+ ### Perfect Use Cases
377
+
378
+ #### **CMS/Blog Export**
379
+ ```ruby
380
+ # Blog post with mixed content types
381
+ post_json = {
382
+ sections: [
383
+ { paragraph: { text: post.title } },
384
+ { table: {
385
+ data: { 0 => post.comments.approved } # Direct relation!
386
+ }
387
+ }
388
+ ]
389
+ }
390
+ ```
391
+
392
+ #### **API Report Generation**
393
+ ```ruby
394
+ # Consume external APIs directly
395
+ api_response = HTTParty.get("https://api.example.com/reports/#{id}")
396
+ json_data = JSON.parse(api_response.body, object_class: OpenStruct)
397
+
398
+ # No transformation needed!
399
+ doc = OxmlMaker::Document.new(params: { sections: json_data.sections })
400
+ ```
401
+
402
+ #### **Dynamic Form Processing**
403
+ ```ruby
404
+ # Form submission → DOCX
405
+ form_data = params[:form_responses] # Frontend JSON
406
+
407
+ document_params = {
408
+ sections: [{
409
+ table: {
410
+ data: { 0 => form_data.map { |item| OpenStruct.new(item) } }
411
+ }
412
+ }]
413
+ }
414
+ ```
415
+
416
+ ### The Architectural Advantage
417
+
418
+ **Zero Impedance Mismatch** - Your data flows directly into documents without transformation layers, making OxmlMaker perfect for:
419
+
420
+ - **Headless CMS** systems
421
+ - **API-first** applications
422
+ - **Microservice** architectures
423
+ - **HTML→DOCX** conversion pipelines
424
+ - **Real-time report** generation
425
+ - **JSON-driven** document templates
426
+
427
+ This isn't just a different API - it's a **fundamentally superior architecture** for modern Ruby applications.
428
+
279
429
  ## Dependencies
280
430
 
281
431
  - **rubyzip (~> 3.2)** - For ZIP file creation and DOCX generation
@@ -3,7 +3,7 @@
3
3
  <w:body>
4
4
  <w:p>
5
5
  <w:r>
6
- <w:t>Test with special chars: & < > " '</w:t>
6
+ <w:t>Test Document Content</w:t>
7
7
  </w:r>
8
8
  </w:p>
9
9
 
@@ -24,7 +24,8 @@
24
24
  <w:tblLook w:val="0600"/>
25
25
  </w:tblPr>
26
26
  <w:tblGrid>
27
- <w:gridCol w:w="3000"/>
27
+ <w:gridCol w:w="2000"/>
28
+ <w:gridCol w:w="1500"/>
28
29
  </w:tblGrid>
29
30
  <w:tr>
30
31
  <w:tblPrEx>
@@ -38,7 +39,7 @@
38
39
  </w:trPr>
39
40
  <w:tc>
40
41
  <w:tcPr>
41
- <w:tcW w:w="3000"/>
42
+ <w:tcW w:w="2000"/>
42
43
  </w:tcPr>
43
44
  <w:p>
44
45
  <w:pPr>
@@ -52,7 +53,28 @@
52
53
  <w:b/>
53
54
  <w:sz w:val="22"/>
54
55
  </w:rPr>
55
- <w:t>Data & Info</w:t>
56
+ <w:t>Name</w:t>
57
+ </w:r>
58
+ </w:p>
59
+ </w:tc>
60
+
61
+ <w:tc>
62
+ <w:tcPr>
63
+ <w:tcW w:w="1500"/>
64
+ </w:tcPr>
65
+ <w:p>
66
+ <w:pPr>
67
+ <w:jc w:val="center"/>
68
+ <w:rPr>
69
+ <w:b/>
70
+ </w:rPr>
71
+ </w:pPr>
72
+ <w:r>
73
+ <w:rPr>
74
+ <w:b/>
75
+ <w:sz w:val="22"/>
76
+ </w:rPr>
77
+ <w:t>Value</w:t>
56
78
  </w:r>
57
79
  </w:p>
58
80
  </w:tc>
@@ -61,7 +83,61 @@
61
83
  <w:tr>
62
84
  <w:tc>
63
85
  <w:tcPr>
64
- <w:tcW w:w='3000' w:type='dxa'/>
86
+ <w:tcW w:w='2000' w:type='dxa'/>
87
+
88
+ <w:vAlign w:val="center"/>
89
+ </w:tcPr>
90
+ <w:p>
91
+ <w:pPr>
92
+ <w:jc w:val='center'/>
93
+ </w:pPr>
94
+ <w:r>
95
+ <w:rPr><w:sz w:val='22'/></w:rPr>
96
+ <w:t>Item 1</w:t>
97
+ </w:r>
98
+ </w:p>
99
+ </w:tc>
100
+
101
+ <w:tc>
102
+ <w:tcPr>
103
+ <w:tcW w:w='1500' w:type='dxa'/>
104
+
105
+ <w:vAlign w:val="center"/>
106
+ </w:tcPr>
107
+ <w:p>
108
+ <w:pPr>
109
+ <w:jc w:val='center'/>
110
+ </w:pPr>
111
+ <w:r>
112
+ <w:rPr><w:sz w:val='22'/></w:rPr>
113
+ <w:t>100</w:t>
114
+ </w:r>
115
+ </w:p>
116
+ </w:tc>
117
+
118
+ </w:tr>
119
+
120
+ <w:tr>
121
+ <w:tc>
122
+ <w:tcPr>
123
+ <w:tcW w:w='2000' w:type='dxa'/>
124
+
125
+ <w:vAlign w:val="center"/>
126
+ </w:tcPr>
127
+ <w:p>
128
+ <w:pPr>
129
+ <w:jc w:val='center'/>
130
+ </w:pPr>
131
+ <w:r>
132
+ <w:rPr><w:sz w:val='22'/></w:rPr>
133
+ <w:t>Item 2</w:t>
134
+ </w:r>
135
+ </w:p>
136
+ </w:tc>
137
+
138
+ <w:tc>
139
+ <w:tcPr>
140
+ <w:tcW w:w='1500' w:type='dxa'/>
65
141
 
66
142
  <w:vAlign w:val="center"/>
67
143
  </w:tcPr>
@@ -71,7 +147,7 @@
71
147
  </w:pPr>
72
148
  <w:r>
73
149
  <w:rPr><w:sz w:val='22'/></w:rPr>
74
- <w:t>Content with &lt;tags&gt; &amp; symbols</w:t>
150
+ <w:t>200</w:t>
75
151
  </w:r>
76
152
  </w:p>
77
153
  </w:tc>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OxmlMaker
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxml_maker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - airbearr