numbers-parser 4.11.4__tar.gz → 4.12.0__tar.gz

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.
Files changed (59) hide show
  1. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/PKG-INFO +2 -1
  2. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/pyproject.toml +2 -2
  3. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/cell.py +2 -2
  4. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/data/empty.numbers +0 -0
  5. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/model.py +178 -48
  6. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/LICENSE.rst +0 -0
  7. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/README.md +0 -0
  8. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/__init__.py +0 -0
  9. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/_cat_numbers.py +0 -0
  10. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/_unpack_numbers.py +0 -0
  11. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/bullets.py +0 -0
  12. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/constants.py +0 -0
  13. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/containers.py +0 -0
  14. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/currencies.py +0 -0
  15. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/document.py +0 -0
  16. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/exceptions.py +0 -0
  17. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/experimental.py +0 -0
  18. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/formula.py +0 -0
  19. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TNArchives_pb2.py +0 -0
  20. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TNArchives_sos_pb2.py +0 -0
  21. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TNCommandArchives_pb2.py +0 -0
  22. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TNCommandArchives_sos_pb2.py +0 -0
  23. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSAArchives_pb2.py +0 -0
  24. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSAArchives_sos_pb2.py +0 -0
  25. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSACommandArchives_sos_pb2.py +0 -0
  26. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCEArchives_pb2.py +0 -0
  27. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCH3DArchives_pb2.py +0 -0
  28. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHArchives_Common_pb2.py +0 -0
  29. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHArchives_GEN_pb2.py +0 -0
  30. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHArchives_pb2.py +0 -0
  31. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHArchives_sos_pb2.py +0 -0
  32. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHCommandArchives_pb2.py +0 -0
  33. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCHPreUFFArchives_pb2.py +0 -0
  34. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCKArchives_pb2.py +0 -0
  35. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSCKArchives_sos_pb2.py +0 -0
  36. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSDArchives_pb2.py +0 -0
  37. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSDArchives_sos_pb2.py +0 -0
  38. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSDCommandArchives_pb2.py +0 -0
  39. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSKArchives_pb2.py +0 -0
  40. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSPArchiveMessages_pb2.py +0 -0
  41. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSPDatabaseMessages_pb2.py +0 -0
  42. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSPMessages_pb2.py +0 -0
  43. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSSArchives_pb2.py +0 -0
  44. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSSArchives_sos_pb2.py +0 -0
  45. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSTArchives_pb2.py +0 -0
  46. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSTArchives_sos_pb2.py +0 -0
  47. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSTCommandArchives_pb2.py +0 -0
  48. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSTStylePropertyArchiving_pb2.py +0 -0
  49. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSWPArchives_pb2.py +0 -0
  50. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSWPArchives_sos_pb2.py +0 -0
  51. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/TSWPCommandArchives_pb2.py +0 -0
  52. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/__init__.py +0 -0
  53. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/fontmap.py +0 -0
  54. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/functionmap.py +0 -0
  55. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/generated/mapping.py +0 -0
  56. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/iwafile.py +0 -0
  57. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/iwork.py +0 -0
  58. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/numbers_cache.py +0 -0
  59. {numbers_parser-4.11.4 → numbers_parser-4.12.0}/src/numbers_parser/numbers_uuid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: numbers-parser
3
- Version: 4.11.4
3
+ Version: 4.12.0
4
4
  Summary: Read and write Apple Numbers spreadsheets
5
5
  Home-page: https://github.com/masaccio/numbers-parser
6
6
  License: MIT
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
18
+ Requires-Dist: colorama (>=0.4.6,<0.5.0)
18
19
  Requires-Dist: compact-json (>=1.1.3,<2.0.0)
19
20
  Requires-Dist: enum-tools (>=0.11)
20
21
  Requires-Dist: importlib-resources (>=6.1)
@@ -12,7 +12,7 @@ name = "numbers-parser"
12
12
  packages = [{include = "numbers_parser", from = "src"}]
13
13
  readme = "README.md"
14
14
  repository = "https://github.com/masaccio/numbers-parser"
15
- version = "4.11.4"
15
+ version = "4.12.0"
16
16
 
17
17
  [tool.poetry.scripts]
18
18
  cat-numbers = "numbers_parser._cat_numbers:main"
@@ -30,6 +30,7 @@ sigfig = "^1.3.2"
30
30
  setuptools = ">=69.0.3"
31
31
  importlib-resources = ">=6.1"
32
32
  enum-tools = ">=0.11"
33
+ colorama = "^0.4.6"
33
34
 
34
35
  [tool.poetry.group.dev.dependencies]
35
36
  black = "*"
@@ -44,7 +45,6 @@ pytest-cov = ">=4.0,>=5.0"
44
45
  pytest-profiling = "^1.7.0"
45
46
  pytest-xdist = "^3.3.1"
46
47
  ruff = "*"
47
- termcolor = ">=2.2"
48
48
  tox = "^4.11.4"
49
49
  python-magic = ">=0.4"
50
50
  tqdm = ">=4.66"
@@ -993,7 +993,7 @@ class Cell(CellStorageFlags, Cacheable):
993
993
  )
994
994
  self._model.add_component_reference(
995
995
  self._style._text_style_obj_id,
996
- parent_id=self._model._table_styles.id(self._table_id),
996
+ component_id=self._model._table_styles.id(self._table_id),
997
997
  )
998
998
 
999
999
  if self._style._cell_style_obj_id is not None:
@@ -1003,7 +1003,7 @@ class Cell(CellStorageFlags, Cacheable):
1003
1003
  )
1004
1004
  self._model.add_component_reference(
1005
1005
  self._style._cell_style_obj_id,
1006
- parent_id=self._model._table_styles.id(self._table_id),
1006
+ component_id=self._model._table_styles.id(self._table_id),
1007
1007
  )
1008
1008
 
1009
1009
  length = 12
@@ -55,6 +55,7 @@ from numbers_parser.containers import ObjectStore
55
55
  from numbers_parser.exceptions import UnsupportedError
56
56
  from numbers_parser.formula import TableFormulas
57
57
  from numbers_parser.generated import TNArchives_pb2 as TNArchives
58
+ from numbers_parser.generated import TSAArchives_pb2 as TSAArchives
58
59
  from numbers_parser.generated import TSCEArchives_pb2 as TSCEArchives
59
60
  from numbers_parser.generated import TSDArchives_pb2 as TSDArchives
60
61
  from numbers_parser.generated import TSKArchives_pb2 as TSKArchives
@@ -330,10 +331,140 @@ class _NumbersModel(Cacheable):
330
331
  else:
331
332
  return not table_info.super.caption_hidden
332
333
 
334
+ def captions_style_id(self):
335
+ stylesheet = self.objects[self.find_refs("StylesheetArchive")[0]]
336
+ caption_styles = [
337
+ x for x in stylesheet.identifier_to_style_map if "Caption" in x.identifier
338
+ ]
339
+ return caption_styles[0].style.identifier
340
+
341
+ def caption_paragraph_style_id(self):
342
+ style_map = {
343
+ id: self.objects[id]
344
+ for id in self.find_refs("ParagraphStyleArchive")
345
+ if "Caption" in self.objects[id].super.name
346
+ }
347
+ return list(style_map.keys())[0]
348
+
349
+ @cache(num_args=0)
350
+ def stylesheet_id(self):
351
+ return self.find_refs("StylesheetArchive")[0]
352
+
353
+ def set_reference(self, obj: object, id: int):
354
+ obj.MergeFrom(TSPMessages.Reference(identifier=id))
355
+
356
+ def create_path_source_archive(self, table_id):
357
+ return TSDArchives.PathSourceArchive(
358
+ horizontalFlip=False,
359
+ verticalFlip=False,
360
+ bezier_path_source=TSDArchives.BezierPathSourceArchive(
361
+ naturalSize=TSPMessages.Size(width=self.table_width(table_id), height=0.0),
362
+ path=TSPMessages.Path(
363
+ elements=[
364
+ TSPMessages.Path.Element(
365
+ type=TSPMessages.Path.ElementType.moveTo,
366
+ points=[TSPMessages.Point(x=0.0, y=0.0)],
367
+ ),
368
+ TSPMessages.Path.Element(
369
+ type=TSPMessages.Path.ElementType.lineTo,
370
+ points=[TSPMessages.Point(x=100.0, y=0.0)],
371
+ ),
372
+ TSPMessages.Path.Element(
373
+ type=TSPMessages.Path.ElementType.lineTo,
374
+ points=[TSPMessages.Point(x=100.0, y=100.0)],
375
+ ),
376
+ TSPMessages.Path.Element(
377
+ type=TSPMessages.Path.ElementType.lineTo,
378
+ points=[TSPMessages.Point(x=0.0, y=100.0)],
379
+ ),
380
+ TSPMessages.Path.Element(
381
+ type=TSPMessages.Path.ElementType.closeSubpath,
382
+ ),
383
+ TSPMessages.Path.Element(
384
+ type=TSPMessages.Path.ElementType.moveTo,
385
+ points=[TSPMessages.Point(x=0.0, y=0.0)],
386
+ ),
387
+ ]
388
+ ),
389
+ ),
390
+ )
391
+
392
+ def create_caption_archive(self, table_id):
393
+ table_info_id = self.table_info_id(table_id)
394
+ table_info = self.objects[table_info_id]
395
+ caption_placement_id, _ = self.objects.create_object_from_dict(
396
+ "CalculationEngine",
397
+ {
398
+ "caption_anchor_location": 1,
399
+ "drawable_anchor_location": 7,
400
+ },
401
+ TSAArchives.CaptionPlacementArchive,
402
+ )
403
+ caption_info_id, caption_info = self.objects.create_object_from_dict(
404
+ "CalculationEngine",
405
+ {"childInfoKind": "Caption", "placement": {"identifier": caption_placement_id}},
406
+ TSAArchives.CaptionInfoArchive,
407
+ )
408
+ storage_id, storage = self.objects.create_object_from_dict(
409
+ "CalculationEngine",
410
+ {
411
+ "text": ["Caption"],
412
+ "in_document": True,
413
+ "style_sheet": {"identifier": self.stylesheet_id()},
414
+ "table_para_style": {
415
+ "entries": [
416
+ {
417
+ "character_index": 0,
418
+ "object": {"identifier": self.caption_paragraph_style_id()},
419
+ }
420
+ ]
421
+ },
422
+ "table_para_starts": {"entries": [{"character_index": 0, "first": 0, "second": 0}]},
423
+ "table_para_bidi": {"entries": [{"character_index": 0, "first": 0, "second": 0}]},
424
+ "table_drop_cap_style": {"entries": [{"character_index": 0}]},
425
+ },
426
+ TSWPArchives.StorageArchive,
427
+ )
428
+ for object_id in [storage_id, self.captions_style_id(), self.caption_paragraph_style_id()]:
429
+ self.add_component_reference(
430
+ object_id, location="CalculationEngine", component_id=self.stylesheet_id()
431
+ )
432
+ caption_info.super.MergeFrom(
433
+ TSWPArchives.ShapeInfoArchive(
434
+ is_text_box=True,
435
+ owned_storage=TSPMessages.Reference(identifier=storage_id),
436
+ deprecated_storage=TSPMessages.Reference(identifier=storage_id),
437
+ super=TSDArchives.ShapeArchive(
438
+ super=self.create_drawable(table_info_id, 0, 0, flags=1),
439
+ style={"identifier": self.captions_style_id()},
440
+ strokePatternOffsetDistance=0.0,
441
+ pathsource=self.create_path_source_archive(table_id),
442
+ ),
443
+ )
444
+ )
445
+
446
+ self.set_reference(table_info.super.caption, caption_info_id)
447
+ component = self.metadata_component(self.calc_engine_id())
448
+ component.object_uuid_map_entries.append(
449
+ TSPArchiveMessages.ObjectUUIDMapEntry(
450
+ identifier=caption_info_id, uuid=NumbersUUID().protobuf2
451
+ )
452
+ )
453
+
333
454
  def caption_text(self, table_id: int, caption: str = None) -> str:
334
455
  table_info = self.objects[self.table_info_id(table_id)]
335
456
  caption_info_id = table_info.super.caption.identifier
336
- caption_storage_id = self.objects[caption_info_id].super.owned_storage.identifier
457
+ caption_archive = self.objects[caption_info_id]
458
+
459
+ if caption_archive.DESCRIPTOR.name == "StandinCaptionArchive":
460
+ if caption is None:
461
+ return "Caption"
462
+ else:
463
+ self.create_caption_archive(table_id)
464
+ caption_info_id = table_info.super.caption.identifier
465
+ caption_archive = self.objects[caption_info_id]
466
+
467
+ caption_storage_id = caption_archive.super.owned_storage.identifier
337
468
  caption_text = self.objects[caption_storage_id].text
338
469
  if caption is not None:
339
470
  caption_text[0] = caption
@@ -881,7 +1012,7 @@ class _NumbersModel(Cacheable):
881
1012
  merge_map.cell_range.append(cell_range)
882
1013
 
883
1014
  base_data_store = self.objects[table_id].base_data_store
884
- base_data_store.merge_region_map.CopyFrom(TSPMessages.Reference(identifier=merge_map_id))
1015
+ self.set_reference(base_data_store.merge_region_map, merge_map_id)
885
1016
 
886
1017
  def recalculate_row_info(
887
1018
  self,
@@ -942,19 +1073,19 @@ class _NumbersModel(Cacheable):
942
1073
  save_token=1,
943
1074
  )
944
1075
  self.objects[PACKAGE_ID].components.append(component_info)
945
- self.add_component_reference(object_id, parent)
1076
+ self.add_component_reference(object_id, location=parent)
946
1077
 
947
1078
  def add_component_reference(
948
1079
  self,
949
1080
  object_id: int,
950
1081
  location: Optional[str] = None,
951
- parent_id: Optional[int] = None,
1082
+ component_id: Optional[int] = None,
952
1083
  is_weak: bool = False,
953
1084
  ):
954
1085
  """Add an external reference to an object in a metadata component."""
955
- component = self.metadata_component(location or parent_id)
956
- if parent_id is not None:
957
- params = {"object_identifier": object_id, "component_identifier": parent_id}
1086
+ component = self.metadata_component(location or component_id)
1087
+ if component_id is not None:
1088
+ params = {"object_identifier": object_id, "component_identifier": component_id}
958
1089
  else:
959
1090
  params = {"component_identifier": object_id}
960
1091
  if is_weak:
@@ -1174,7 +1305,15 @@ class _NumbersModel(Cacheable):
1174
1305
 
1175
1306
  return self.table_height(table_id) + y_offset
1176
1307
 
1177
- def create_drawable(self, sheet_id: int, x: float, y: float) -> object:
1308
+ def create_drawable(
1309
+ self,
1310
+ sheet_id: int,
1311
+ x: float,
1312
+ y: float,
1313
+ flags: int = 3,
1314
+ height: float = 231.0,
1315
+ width: float = 494.0,
1316
+ ) -> object:
1178
1317
  """Create a DrawableArchive for a new table in a sheet."""
1179
1318
  table_x = x if x is not None else 0.0
1180
1319
  table_y = y if y is not None else self.last_table_offset(sheet_id) + DEFAULT_TABLE_OFFSET
@@ -1182,9 +1321,9 @@ class _NumbersModel(Cacheable):
1182
1321
  parent=TSPMessages.Reference(identifier=sheet_id),
1183
1322
  geometry=TSDArchives.GeometryArchive(
1184
1323
  angle=0.0,
1185
- flags=3,
1324
+ flags=flags,
1186
1325
  position=TSPMessages.Point(x=table_x, y=table_y),
1187
- size=TSPMessages.Size(height=231.0, width=494.0),
1326
+ size=TSPMessages.Size(height=height, width=width),
1188
1327
  ),
1189
1328
  )
1190
1329
 
@@ -1238,43 +1377,30 @@ class _NumbersModel(Cacheable):
1238
1377
  "Tables/HeaderStorageBucket-{}",
1239
1378
  )
1240
1379
 
1241
- # caption_storage_id, caption_storage = self.objects.create_object_from_dict(
1242
- # "CalculationEngine",
1243
- # {"text": ["TEST Caption"]},
1244
- # TSWPArchives.StorageArchive,
1245
- # )
1246
- # caption_info_id, caption_info = self.objects.create_object_from_dict(
1247
- # "CalculationEngine",
1248
- # {},
1249
- # TSAArchives.CaptionInfoArchive,
1250
- # )
1251
- # # caption_info.super.MergeFrom(TSWPArchives.ShapeInfoArchive())
1252
- # # caption_info.super.super.MergeFrom(TSDArchives.ShapeArchive())
1253
- # # caption_info.super.super.super.MergeFrom(TSDArchives.DrawableArchive())
1254
- # from_table_info = self.objects[self.table_info_id(from_table_id)]
1255
- # from_caption_info = self.objects[from_table_info.super.caption.identifier]
1256
- # caption_info.super.CopyFrom(from_caption_info.super)
1257
- # caption_info.super.super.CopyFrom(from_caption_info.super.super)
1258
- # caption_info.super.super.super.CopyFrom(from_caption_info.super.super.super)
1259
- # caption_info.super.deprecated_storage.MergeFrom(
1260
- # TSPMessages.Reference(identifier=caption_storage_id)
1261
- # )
1262
- # caption_info.super.owned_storage.MergeFrom(
1263
- # TSPMessages.Reference(identifier=caption_storage_id)
1264
- # )
1265
-
1266
- # TST.TableModelArchive.stroke_sidecar -> TST.StrokeSidecarArchive
1267
- # TST.StrokeSidecarArchive
1268
- # top_row_stroke_layers -> [TST.StrokeLayerArchive]
1269
- # left_row_stroke_layers -> [TST.StrokeLayerArchive]
1270
- # right_row_stroke_layers -> [TST.StrokeLayerArchive]
1271
- # bottom_row_stroke_layers -> [TST.StrokeLayerArchive]
1380
+ from_table_info = self.objects[self.table_info_id(from_table_id)]
1381
+ from_caption_info = self.objects[from_table_info.super.caption.identifier]
1382
+ caption_storage_id, caption_storage = self.objects.create_object_from_dict(
1383
+ "CalculationEngine",
1384
+ {"text": ["Caption"]},
1385
+ TSWPArchives.StorageArchive,
1386
+ )
1387
+ caption_storage.MergeFrom(self.objects[from_caption_info.super.owned_storage.identifier])
1388
+ caption_info_id, caption_info = self.objects.create_object_from_dict(
1389
+ "CalculationEngine",
1390
+ {},
1391
+ TSAArchives.CaptionInfoArchive,
1392
+ )
1393
+ caption_info.super.CopyFrom(from_caption_info.super)
1394
+ caption_info.super.super.CopyFrom(from_caption_info.super.super)
1395
+ caption_info.super.super.super.CopyFrom(from_caption_info.super.super.super)
1396
+ self.set_reference(caption_info.super.deprecated_storage, caption_storage_id)
1397
+ self.set_reference(caption_info.super.owned_storage, caption_storage_id)
1272
1398
  sidecar_id, _ = self.objects.create_object_from_dict(
1273
1399
  "CalculationEngine",
1274
1400
  {"max_order": 1, "column_count": 0, "row_count": 0},
1275
1401
  TSTArchives.StrokeSidecarArchive,
1276
1402
  )
1277
- table_model.stroke_sidecar.MergeFrom(TSPMessages.Reference(identifier=sidecar_id))
1403
+ self.set_reference(table_model.stroke_sidecar, sidecar_id)
1278
1404
 
1279
1405
  style_table_id, _ = self.objects.create_object_from_dict(
1280
1406
  "Index/Tables/DataList-{}",
@@ -1354,11 +1480,13 @@ class _NumbersModel(Cacheable):
1354
1480
  )
1355
1481
  table_info.tableModel.MergeFrom(TSPMessages.Reference(identifier=table_model_id))
1356
1482
  table_info.super.MergeFrom(self.create_drawable(sheet_id, x, y))
1357
- # caption_info.super.super.super.parent.MergeFrom(
1358
- # TSPMessages.Reference(identifier=table_info_id)
1359
- # )
1360
- # table_info.super.caption.MergeFrom(TSPMessages.Reference(identifier=caption_info_id))
1361
- self.add_component_reference(table_info_id, "Document", self.calc_engine_id())
1483
+ caption_info.super.super.super.parent.MergeFrom(
1484
+ TSPMessages.Reference(identifier=table_info_id)
1485
+ )
1486
+ table_info.super.caption.MergeFrom(TSPMessages.Reference(identifier=caption_info_id))
1487
+ self.add_component_reference(
1488
+ table_info_id, location="Document", component_id=self.calc_engine_id()
1489
+ )
1362
1490
 
1363
1491
  self.add_formula_owner(
1364
1492
  table_info_id,
@@ -1459,7 +1587,9 @@ class _NumbersModel(Cacheable):
1459
1587
  TNArchives.SheetArchive,
1460
1588
  )
1461
1589
 
1462
- self.add_component_reference(sheet_id, "CalculationEngine", DOCUMENT_ID, is_weak=True)
1590
+ self.add_component_reference(
1591
+ sheet_id, location="CalculationEngine", component_id=DOCUMENT_ID, is_weak=True
1592
+ )
1463
1593
 
1464
1594
  self.objects[DOCUMENT_ID].sheets.append(TSPMessages.Reference(identifier=sheet_id))
1465
1595