numbers-parser 4.8.0__py3-none-any.whl → 4.9.0__py3-none-any.whl

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.
numbers_parser/file.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  import os
3
+ import re
3
4
  from io import BytesIO
4
5
  from sys import version_info
5
6
  from zipfile import BadZipFile, ZipFile
@@ -32,11 +33,15 @@ def read_numbers_file(path, file_handler, object_handler=None):
32
33
  read_numbers_file(filepath, file_handler, object_handler)
33
34
  else:
34
35
  f = open(filepath, "rb")
35
- if filename.endswith(".iwa"):
36
- blob = f.read()
37
- extract_iwa_archives(blob, filepath, file_handler, object_handler)
38
36
  blob = f.read()
39
- file_handler(os.path.join(path, filename), blob)
37
+ if filename.endswith(".iwa"):
38
+ package_filepath = re.sub(r".*\.numbers/*", "", filepath)
39
+ extract_iwa_archives(blob, package_filepath, file_handler, object_handler)
40
+ else:
41
+ package_filepath = os.path.join(
42
+ re.sub(r".*\.numbers/*", "", path), filename
43
+ )
44
+ file_handler(package_filepath, blob)
40
45
  else:
41
46
  try:
42
47
  zipf = open_zipfile(path)
numbers_parser/model.py CHANGED
@@ -2,6 +2,7 @@ import math
2
2
  import re
3
3
  from array import array
4
4
  from collections import defaultdict
5
+ from hashlib import sha1
5
6
  from struct import pack
6
7
  from typing import Dict, List, Tuple, Union
7
8
  from warnings import warn
@@ -34,7 +35,6 @@ from numbers_parser.cell import (
34
35
  TextCell,
35
36
  VerticalJustification,
36
37
  xl_col_to_name,
37
- xl_range,
38
38
  xl_rowcol_to_cell,
39
39
  )
40
40
  from numbers_parser.cell_storage import CellStorage
@@ -56,6 +56,7 @@ from numbers_parser.constants import (
56
56
  FORMAT_TYPE_MAP,
57
57
  MAX_TILE_SIZE,
58
58
  PACKAGE_ID,
59
+ CellInteractionType,
59
60
  FormatType,
60
61
  )
61
62
  from numbers_parser.containers import ObjectStore
@@ -118,11 +119,6 @@ class MergeCells:
118
119
  def rect(self, row_col: Tuple) -> Tuple:
119
120
  return self._references[row_col].rect
120
121
 
121
- def merge_cell_names(self):
122
- return [
123
- xl_range(*v.rect) for k, v in self._references.items() if self.is_merge_reference(k)
124
- ]
125
-
126
122
  def merge_cells(self):
127
123
  return [k for k, v in self._references.items() if self.is_merge_anchor(k)]
128
124
 
@@ -225,6 +221,7 @@ class _NumbersModel(Cacheable):
225
221
  self._table_formats = DataLists(self, "format_table", "format")
226
222
  self._table_styles = DataLists(self, "styleTable", "reference")
227
223
  self._table_strings = DataLists(self, "stringTable", "string")
224
+ self._control_specs = DataLists(self, "control_cell_spec_table", "cell_spec")
228
225
  self._table_data = {}
229
226
  self._styles = None
230
227
  self._custom_formats = None
@@ -368,6 +365,64 @@ class _NumbersModel(Cacheable):
368
365
  format = TSKArchives.FormatStructArchive(**attrs)
369
366
  return self._table_formats.lookup_key(table_id, format)
370
367
 
368
+ def cell_popup_model(self, parent_id: int, format: Formatting):
369
+ tsce_items = [{"cell_value_type": "NIL_TYPE"}]
370
+ for item in format.popup_values:
371
+ if isinstance(item, str):
372
+ tsce_items.append(
373
+ {
374
+ "cell_value_type": "STRING_TYPE",
375
+ "string_value": {
376
+ "value": item,
377
+ "format": {"format_type": FormatType.TEXT},
378
+ },
379
+ }
380
+ )
381
+ else:
382
+ tsce_items.append(
383
+ {
384
+ "cell_value_type": "NUMBER_TYPE",
385
+ "number_value": {
386
+ "value": item,
387
+ "format": {"format_type": FormatType.DECIMAL},
388
+ },
389
+ }
390
+ )
391
+ popup_menu_id, _ = self.objects.create_object_from_dict(
392
+ f"Index/Tables/DataList-{parent_id}",
393
+ {"tsce_item": tsce_items},
394
+ TSTArchives.PopUpMenuModel,
395
+ True,
396
+ )
397
+ return popup_menu_id
398
+
399
+ def control_cell_archive(self, table_id: int, format_type: FormattingType, format: Formatting):
400
+ """Create control cell archive from a Formatting spec and return the table format ID"""
401
+ if format_type == FormattingType.TICKBOX:
402
+ cell_spec = TSTArchives.CellSpecArchive(interaction_type=CellInteractionType.TOGGLE)
403
+ elif format_type == FormattingType.RATING:
404
+ cell_spec = TSTArchives.CellSpecArchive(
405
+ interaction_type=CellInteractionType.RATING,
406
+ range_control_min=0.0,
407
+ range_control_max=5.0,
408
+ range_control_inc=1.0,
409
+ )
410
+ elif format_type == FormattingType.SLIDER:
411
+ cell_spec = TSTArchives.CellSpecArchive(
412
+ interaction_type=CellInteractionType.SLIDER,
413
+ range_control_min=format.minimum,
414
+ range_control_max=format.maximum,
415
+ range_control_inc=format.increment,
416
+ )
417
+ else: # POPUP
418
+ popup_id = self.cell_popup_model(self._control_specs.id(table_id), format)
419
+ cell_spec = TSTArchives.CellSpecArchive(
420
+ interaction_type=CellInteractionType.POPUP,
421
+ chooser_control_popup_model=TSPMessages.Reference(identifier=popup_id),
422
+ chooser_control_start_w_first=not (format.allow_none),
423
+ )
424
+ return self._control_specs.lookup_key(table_id, cell_spec)
425
+
371
426
  def add_custom_decimal_format_archive(self, format: CustomFormatting) -> None:
372
427
  """Create a custom format from the format spec"""
373
428
  integer_format = format.integer_format
@@ -1482,12 +1537,35 @@ class _NumbersModel(Cacheable):
1482
1537
  + str(cell.style.bg_color.g)
1483
1538
  + str(cell.style.bg_color.b)
1484
1539
  )
1540
+ if cell._style.bg_image is not None:
1541
+ fingerprint += cell._style.bg_image.filename
1485
1542
  if fingerprint not in cell_styles:
1486
1543
  cell_styles[fingerprint] = self.add_cell_style(cell._style)
1487
1544
  cell._style._cell_style_obj_id = cell_styles[fingerprint]
1488
1545
 
1489
1546
  def add_cell_style(self, style: Style) -> int:
1490
- if style.bg_color is not None:
1547
+ if style.bg_image is not None:
1548
+ datas = self.objects[PACKAGE_ID].datas
1549
+ image_id = self.next_image_identifier()
1550
+ datas.append(
1551
+ TSPArchiveMessages.DataInfo(
1552
+ identifier=image_id,
1553
+ digest=sha1(style.bg_image.data).digest(),
1554
+ preferred_file_name=style.bg_image.filename,
1555
+ file_name=style.bg_image.filename,
1556
+ materialized_length=len(style.bg_image.data),
1557
+ )
1558
+ )
1559
+ color_attrs = {
1560
+ "cell_fill": {
1561
+ "image": {
1562
+ "technique": "ScaleToFill",
1563
+ "imagedata": {"identifier": image_id},
1564
+ "interpretsUntaggedImageDataAsGeneric": False,
1565
+ }
1566
+ }
1567
+ }
1568
+ elif style.bg_color is not None:
1491
1569
  color_attrs = {
1492
1570
  "cell_fill": {
1493
1571
  "color": {
@@ -1536,6 +1614,7 @@ class _NumbersModel(Cacheable):
1536
1614
  style=TSPMessages.Reference(identifier=cell_style_id),
1537
1615
  )
1538
1616
  )
1617
+
1539
1618
  return cell_style_id
1540
1619
 
1541
1620
  def text_style_object_id(self, cell_storage) -> int:
@@ -1704,6 +1783,10 @@ class _NumbersModel(Cacheable):
1704
1783
  flags |= 0x200
1705
1784
  length += 4
1706
1785
  storage += pack("<i", cell._storage.formula_id)
1786
+ if cell._storage.control_id is not None:
1787
+ flags |= 0x400
1788
+ length += 4
1789
+ storage += pack("<i", cell._storage.control_id)
1707
1790
  if cell._storage.suggest_id is not None:
1708
1791
  flags |= 0x1000
1709
1792
  length += 4
@@ -2209,6 +2292,20 @@ class _NumbersModel(Cacheable):
2209
2292
  stroke_layer.stroke_runs.append(self.create_stroke(origin, length, border_value))
2210
2293
  layer_ids.append(TSPMessages.Reference(identifier=stroke_layer_id))
2211
2294
 
2295
+ def store_image(self, data: bytes, filename: str) -> None:
2296
+ """Store image data in the file store."""
2297
+ stored_filename = f"Data/{filename}"
2298
+ if stored_filename in self.objects.file_store:
2299
+ raise IndexError(f"{filename}: image already exists in document")
2300
+ self.objects.file_store[stored_filename] = data
2301
+
2302
+ def next_image_identifier(self):
2303
+ """Return the next available ID in the list of images in the document."""
2304
+ datas = self.objects[PACKAGE_ID].datas
2305
+ image_ids = [x.identifier for x in datas]
2306
+ # datas never appears to be an empty list (default themes include images)
2307
+ return max(image_ids) + 1
2308
+
2212
2309
 
2213
2310
  def rgb(obj) -> RGB:
2214
2311
  """Convert a TSPArchives.Color into an RGB tuple."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: numbers-parser
3
- Version: 4.8.0
3
+ Version: 4.9.0
4
4
  Summary: Read and write Apple Numbers spreadsheets
5
5
  Home-page: https://github.com/masaccio/numbers-parser
6
6
  License: MIT
@@ -57,14 +57,16 @@ For Intel Macs:
57
57
 
58
58
  ```bash
59
59
  brew install snappy python3
60
- CPPFLAGS="-I/usr/local/include -L/usr/local/lib" python3 -m pip install python-snappy
60
+ CPPFLAGS="-I/usr/local/include -L/usr/local/lib" \
61
+ python3 -m pip install python-snappy
61
62
  ```
62
63
 
63
64
  For Apple Silicon Macs:
64
65
 
65
66
  ```bash
66
67
  brew install snappy python3
67
- CPPFLAGS="-I/opt/homebrew/include -L/opt/homebrew/lib" python3 -m pip install python-snappy
68
+ CPPFLAGS="-I/opt/homebrew/include -L/opt/homebrew/lib" \
69
+ python3 -m pip install python-snappy
68
70
  ```
69
71
 
70
72
  For Linux (your package manager may be different):
@@ -78,10 +80,10 @@ binary libraries compiled by [Christoph Gohlke](https://www.lfd.uci.edu/~gohlke/
78
80
  version for your installation. For example for python 3.11:
79
81
 
80
82
  ```text
81
- C:\Users\Jon>pip install C:\Users\Jon\Downloads\python_snappy-0.6.1-cp311-cp311-win_amd64.whl
83
+ pip install python_snappy-0.6.1-cp311-cp311-win_amd64.whl
82
84
  ```
83
85
 
84
- ### Quick Start
86
+ ## Quick Start
85
87
 
86
88
  Reading documents:
87
89
 
@@ -121,7 +123,7 @@ the column values.
121
123
  'Debit'
122
124
  ```
123
125
 
124
- #### Cell Data
126
+ ### Cell Data
125
127
 
126
128
  Cells are objects with a common base class of `Cell`. All cell types
127
129
  have a property `value` which returns the contents of the cell as a
@@ -129,17 +131,17 @@ python datatype. `numbers-parser` uses
129
131
  [pendulum](https://pendulum.eustace.io) instead of python’s builtin
130
132
  types. Available cell types are:
131
133
 
132
- | Cell type | value type | Additional properties |
133
- |-------------------|--------------------------|-------------------------------------------------------------------------------------------------|
134
- | N<br/>umberCell | `float` | |
135
- | TextCell | `str` | |
136
- | Ric<br/>hTextCell | `str` | See [Bullets and<br/>lists](#bullets-and-lists) |
137
- | EmptyCell | `None` | |
138
- | BoolCell | `bool` | |
139
- | DateCell | `pend<br/>ulum.datetime` | |
140
- | Dur<br/>ationCell | `pend<br/>ulum.duration` | |
141
- | ErrorCell | `None` | |
142
- | M<br/>ergedCell | `None` | See [Merged<br/>c<br/>ells](https://masaccio.github.io/numbers-parser/#table-cell-merged-cells) |
134
+ | Cell type | value type | Additional properties |
135
+ |--------------|---------------------|--------------------------------------------------------------------------------------------------------|
136
+ | NumberCell | `float` | |
137
+ | TextCell | `str` | |
138
+ | RichTextCell | `str` | See [Rich text](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.RichTextCell) |
139
+ | EmptyCell | `None` | |
140
+ | BoolCell | `bool` | |
141
+ | DateCell | `pendulum.datetime` | |
142
+ | DurationCell | `pendulum.duration` | |
143
+ | ErrorCell | `None` | |
144
+ | MergedCell | `None` | See [Merged cells](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.MergedCell) |
143
145
 
144
146
  Cell references can be either zero-offset row/column integers or an
145
147
  Excel/Numbers A1 notation. Where cell values are not `None` the
@@ -161,7 +163,7 @@ any kind `ErrorCell`.
161
163
  '£1,234.50'
162
164
  ```
163
165
 
164
- #### Pandas Support
166
+ ### Pandas Support
165
167
 
166
168
  Since the return value of `rows()` is a list of lists, you can pass
167
169
  this directly to pandas. Assuming you have a Numbers table with a single
@@ -178,15 +180,15 @@ data = tables[0].rows(values_only=True)
178
180
  df = pd.DataFrame(data[1:], columns=data[0])
179
181
  ```
180
182
 
181
- #### Writing Numbers Documents
183
+ ### Writing Numbers Documents
182
184
 
183
185
  Whilst support for writing numbers files has been stable since version
184
186
  3.4.0, you are highly recommended not to overwrite working Numbers files
185
187
  and instead save data to a new file.
186
188
 
187
189
  Cell values are written using
188
- [Table.write()](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.write)
189
- and `numbers-parser` will automatically create empty rows and columns
190
+ [Table.write()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.write) and
191
+ `numbers-parser` will automatically create empty rows and columns
190
192
  for any cell references that are out of range of the current table.
191
193
 
192
194
  ```python
@@ -199,12 +201,9 @@ table.write("B7", datetime(2020, 12, 25))
199
201
  doc.save("new-sheet.numbers")
200
202
  ```
201
203
 
202
- Additional tables and worksheets can be added to a `Document` before
203
- saving using
204
- [Document.add_sheet()](https://masaccio.github.io/numbers-parser/#numbers_parser.Document.add_sheet)
205
- and
206
- [Sheet.add_table()](https://masaccio.github.io/numbers-parser/#numbers_parser.Sheet.add_table)
207
- respectively:
204
+ Additional tables and worksheets can be added to a `Document` before saving using
205
+ [Document.add_sheet()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_sheet) and
206
+ [Sheet.add_table()](https://masaccio.github.io/numbers-parser/api/sheet.html#numbers_parser.Sheet.add_table) respectively:
208
207
 
209
208
  ```python
210
209
  doc = Document()
@@ -217,37 +216,48 @@ table.write(1, 3, 3000)
217
216
  doc.save("sheet.numbers")
218
217
  ```
219
218
 
220
- #### Styles
219
+ ### Styles
221
220
 
222
221
  `numbers_parser` currently only supports paragraph styles and cell
223
- styles. The following paragraph styles are supported:
222
+ styles. The following styles are supported:
224
223
 
225
224
  - font attributes: bold, italic, underline, strikethrough
226
225
  - font selection and size
227
226
  - text foreground color
228
227
  - horizontal and vertical alignment
229
228
  - cell background color
229
+ - cell background images
230
230
  - cell indents (first line, left, right, and text inset)
231
231
 
232
232
  Numbers conflates style attributes that can be stored in paragraph
233
233
  styles (the style menu in the text panel) with the settings that are
234
234
  available on the Style tab of the Text panel. Some attributes in Numbers
235
- are not applied to new cells when a style is applied. To keep the API
236
- simple, `numbers-parser` packs all styling into a single
237
- [Style](https://masaccio.github.io/numbers-parser/#numbers_parser.Style)
238
- object. When a document is saved, the attributes not stored in a
239
- paragraph style are applied to each cell that includes it.
235
+ are not applied to new cells when a style is applied.
236
+
237
+ To keep the API simple, `numbers-parser` packs all styling into a single
238
+ [Style](https://masaccio.github.io/numbers-parser/api/style.html) object. When a document is saved, the attributes
239
+ not stored in a paragraph style are applied to each cell that includes it.
240
240
 
241
241
  Styles are read from cells using the
242
- [Cell.style](https://masaccio.github.io/numbers-parser/#numbers_parser.Cell.style)
243
- propert and you can add new styles with
244
- [Document.add_style](https://masaccio.github.io/numbers-parser/#numbers_parser.Document.add_style).
242
+ [Cell.style](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.style) property and you can
243
+ add new styles with
244
+ [Document.add_style](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_style).
245
245
 
246
- Since `Style` objects are shared, changing `Cell.style.font_size`
247
- will have the effect of changing the font size for that style and will
248
- in turn affect the styles of all cells using that style.
246
+ ```python
247
+ red_text = doc.add_style(
248
+ name="Red Text",
249
+ font_name="Lucida Grande",
250
+ font_color=RGB(230, 25, 25),
251
+ font_size=14.0,
252
+ bold=True,
253
+ italic=True,
254
+ alignment=Alignment("right", "top"),
255
+ )
256
+ table.write("B2", "Red", style=red_text)
257
+ table.set_cell_style("C2", red_text)
258
+ ```
249
259
 
250
- #### Cell Data Formatting
260
+ ### Cell Data Formatting
251
261
 
252
262
  Numbers has two different cell formatting types: data formats and custom
253
263
  formats.
@@ -260,23 +270,37 @@ internally by the package. Changing a data format for cell has no impact
260
270
  on any other cells.
261
271
 
262
272
  Cell formats are changed using
263
- [Table.set_cell_formatting](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_formatting):
273
+ [Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
264
274
 
265
275
  ```python
266
- table.set_cell_formatting("C1", "date", date_time_format="EEEE, d MMMM yyyy")
267
- table.set_cell_formatting(0, 4, "number", decimal_places=3, negative_style=NegativeNumberStyle.RED)
276
+ table.set_cell_formatting(
277
+ "C1",
278
+ "date",
279
+ date_time_format="EEEE, d MMMM yyyy"
280
+ )
281
+ table.set_cell_formatting(
282
+ 0,
283
+ 4,
284
+ "number",
285
+ decimal_places=3,
286
+ negative_style=NegativeNumberStyle.RED
287
+ )
268
288
  ```
269
289
 
270
290
  Custom formats are shared across a Document and can be applied to
271
291
  multiple cells in multiple tables. Editing a custom format changes the
272
292
  appearance of data in all cells that share that format. You must first
273
293
  add a custom format to the document using
274
- [Document.add_custom_format](https://masaccio.github.io/numbers-parser/#numbers_parser.Document.add_custom_format)
294
+ [Document.add_custom_format()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_custom_format)
275
295
  before assigning it to cells using
276
- [Table.set_cell_formatting](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_formatting):
296
+ [Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
277
297
 
278
298
  ```python
279
- long_date = doc.add_custom_format(name="Long Date", type="date", date_time_format="EEEE, d MMMM yyyy")
299
+ long_date = doc.add_custom_format(
300
+ name="Long Date",
301
+ type="date",
302
+ date_time_format="EEEE, d MMMM yyyy"
303
+ )
280
304
  table.set_cell_formatting("C1", "custom", format=long_date)
281
305
  ```
282
306
 
@@ -287,7 +311,7 @@ example, US dollars are referred to as `US$` whereas Euros and British
287
311
  Pounds are referred to using their symbols of `€` and `£`
288
312
  respectively.
289
313
 
290
- #### Borders
314
+ ### Borders
291
315
 
292
316
  `numbers-parser` supports reading and writing cell borders, though the
293
317
  interface for each differs. Individual cells can have each of their four
@@ -296,13 +320,11 @@ table to allow for drawing borders across multiple cells. Setting the
296
320
  border of merged cells is not possible unless the edge of the cells is
297
321
  at the end of the merged region.
298
322
 
299
- Borders are represented using the
300
- [Border](https://masaccio.github.io/numbers-parser/#numbers_parser.Border)
301
- class that can be initialized with line width, color and line style. The
323
+ Borders are represented using the [Border](https://masaccio.github.io/numbers-parser/api/border.html) class
324
+ that can be initialized with line width, color and line style. The
302
325
  current state of a cell border is read using the
303
- [Cell.border](https://masaccio.github.io/numbers-parser/#numbers_parser.Cell.border)
304
- property. The
305
- [Table.set_cell_border](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_border)
326
+ [Cell.border](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.border) property
327
+ and [Table.set_cell_border()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_border)
306
328
  sets the border for a cell edge or a range of cells.
307
329
 
308
330
  ## API
@@ -319,25 +341,30 @@ format, iterating through all the spreadsheets passed on the
319
341
  command-line.
320
342
 
321
343
  ```text
322
- usage: cat-numbers [-h] [-T | -S | -b] [-V] [--debug] [--formulas]
323
- [--formatting] [-s SHEET] [-t TABLE] [document ...]
344
+ usage: cat-numbers [-h] [-T | -S | -b] [-V] [--formulas] [--formatting]
345
+ [-s SHEET] [-t TABLE] [--debug]
346
+ [document ...]
324
347
 
325
348
  Export data from Apple Numbers spreadsheet tables
326
349
 
327
350
  positional arguments:
328
- document Document(s) to export
329
-
330
- optional arguments:
331
- -h, --help show this help message and exit
332
- -T, --list-tables List the names of tables and exit
333
- -S, --list-sheets List the names of sheets and exit
334
- -b, --brief Don't prefix data rows with name of sheet/table (default: false)
351
+ document Document(s) to export
352
+
353
+ options:
354
+ -h, --help show this help message and exit
355
+ -T, --list-tables List the names of tables and exit
356
+ -S, --list-sheets List the names of sheets and exit
357
+ -b, --brief Don't prefix data rows with name of sheet/table
358
+ (default: false)
335
359
  -V, --version
336
- --debug Enable debug output
337
- --formulas Dump formulas instead of formula results
338
- --formatting Dump formatted cells (durations) as they appear in Numbers
339
- -s SHEET, --sheet SHEET Names of sheet(s) to include in export
340
- -t TABLE, --table TABLE Names of table(s) to include in export
360
+ --formulas Dump formulas instead of formula results
361
+ --formatting Dump formatted cells (durations) as they appear
362
+ in Numbers
363
+ -s SHEET, --sheet SHEET
364
+ Names of sheet(s) to include in export
365
+ -t TABLE, --table TABLE
366
+ Names of table(s) to include in export
367
+ --debug Enable debug logging
341
368
  ```
342
369
 
343
370
  Note: `--formatting` will return different capitalization for 12-hour
@@ -358,10 +385,6 @@ Current known limitations of `numbers-parser` are:
358
385
  worksheet which does not take into account title or caption size
359
386
  - New sheets insert tables with formats copied from the first table in
360
387
  the previous sheet rather than default table formats
361
- - Creating custom cell formats and cell data formats is experimental
362
- and not all formats are supported. See
363
- [Table.set_cell_formatting](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_formatting)
364
- for more details.
365
388
  - Due to a limitation in Python’s
366
389
  [ZipFile](https://docs.python.org/3/library/zipfile.html), Python
367
390
  versions older than 3.11 do not support image filenames with UTF-8
@@ -373,6 +396,5 @@ Current known limitations of `numbers-parser` are:
373
396
 
374
397
  ## License
375
398
 
376
- All code in this repository is licensed under the [MIT
377
- License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst)
399
+ All code in this repository is licensed under the [MIT License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst).
378
400
 
@@ -2,16 +2,16 @@ numbers_parser/__init__.py,sha256=hyoQ4x-1E8yDBMR128kZhSDLCfrnjNdz4_dEpKlekk4,19
2
2
  numbers_parser/_cat_numbers.py,sha256=-HboBJT11Vjcr8sjLZl7Z6qAapnPEc_kFYq6PTqON20,4619
3
3
  numbers_parser/_unpack_numbers.py,sha256=zfpBOfM92rMHSRQVR4tExf0fWI2Lbbb6WrwQPoq4gMo,5689
4
4
  numbers_parser/bullets.py,sha256=OnVVMPjhTDrC-ncw52Gb00UEXNmn2Rvd3xi7lfqW3hk,2616
5
- numbers_parser/cell.py,sha256=aWQpVAAY-YmJW3ADU-cQGEmMDrPYCtaY02KNoKgB6ew,35399
6
- numbers_parser/cell_storage.py,sha256=_anyiHnG-pAZ9OTSdisT7lted9PGSzQcn_-xpsJVU0o,32873
7
- numbers_parser/constants.py,sha256=4D_u5v8r2YQGBK-ScRL6jGHhThFpxKpbS8LnTuVvlR4,7179
8
- numbers_parser/containers.py,sha256=b9sOCBd60YjMxJ-s9u-erWusA3guHU-c1RAUqM8CyKs,4191
5
+ numbers_parser/cell.py,sha256=YfHs1xxVSNY_oEodTN3IhqdO5tUhdgzZz5Z0m10dtpw,38457
6
+ numbers_parser/cell_storage.py,sha256=jaGpleFg8xWPT3U-O4bczAMYFR54t3x920UBKcrUiOQ,34354
7
+ numbers_parser/constants.py,sha256=BJGNz0ZZCs5xfAXlzLox4tvKOHIpDMXgJQ6i5yvdr4A,9606
8
+ numbers_parser/containers.py,sha256=yR_T2yF5QiVj7Dg22nCMLvo___Xrec3j8kitbxiaWyU,4220
9
9
  numbers_parser/currencies.py,sha256=8k4a3WKmDoHeurkDICymHX13N7ManHSTaka_JNXCZYA,3767
10
10
  numbers_parser/data/empty.numbers,sha256=8JOp035V-p2ff9_Wao7mLcYvb6_if6O2cus_esjVA9k,90316
11
- numbers_parser/document.py,sha256=V3XiPKgk68Sp607ZLQfahEEO-PiKN2TH5AX_iCpJaxI,48087
11
+ numbers_parser/document.py,sha256=JmGyafm10FXnS5zmXkMTRVvYM-KnCKtcmbNCwMDyuSU,55333
12
12
  numbers_parser/exceptions.py,sha256=G8dASUQZI8ksHYRVfdGWJzgsJD5CBpcZvmDJUZTqT-c,670
13
13
  numbers_parser/experimental.py,sha256=WARjTa-2ePb8Ga8Q6oDP6EJCs12ofLRF2YpwzUu66ZI,374
14
- numbers_parser/file.py,sha256=ivcl5326TQXwj1GP9FCh-WiM_oXZumgQdByehAEw1f8,3966
14
+ numbers_parser/file.py,sha256=buNbZRzQCIlr7H4JxwTh2_eh7oDA2fGH5ZiFpIEVHoo,4200
15
15
  numbers_parser/formula.py,sha256=JRsG0L21wS70oJ-FB46Amyoy-sKizWb-iUhSXUcVJ-U,10572
16
16
  numbers_parser/generated/TNArchives_pb2.py,sha256=txkTtPHvdXVvv7zO1dHCxxnixaFulK7hJVLQrH3cIJc,16007
17
17
  numbers_parser/generated/TNArchives_sos_pb2.py,sha256=AYI1X5t5Gb4l941jXlHEY0v97ToIze0bSYBR7KQmS0A,1215
@@ -50,11 +50,11 @@ numbers_parser/generated/fontmap.py,sha256=pqc1HwwTr3UbFMmhUaHJg1dX5-3pXbyhfS2bk
50
50
  numbers_parser/generated/functionmap.py,sha256=VdZo0ERMYONcrnJFwABcSCHb8pjA4wY2ogt8Janz57M,6082
51
51
  numbers_parser/iwafile.py,sha256=MuFIlB_hdXTTZflxoX_ZvA_68OaJkmRQ4eJ2UAiCKXQ,11833
52
52
  numbers_parser/mapping.py,sha256=in8W3S8DmTcPefFaxnATLw0FQ4YnFsnAE-cl5dljzJE,32215
53
- numbers_parser/model.py,sha256=MY3qrLVIGwXX4xOQAlN0uN_njoisdiM5LQJJPPT7wPQ,98925
53
+ numbers_parser/model.py,sha256=qvU0RRF4YgUcfhtRlDdRP09gl8rUY0GNgeHpOTJYvHk,103312
54
54
  numbers_parser/numbers_cache.py,sha256=1ghEBghQAYFpPiEeOtb74i016mXc039v1pOubbqvaLs,1141
55
55
  numbers_parser/numbers_uuid.py,sha256=-LeAj_ULC0va57pEmyegGY0xXqkNNjyuLukCaiQJhOk,2642
56
- numbers_parser-4.8.0.dist-info/LICENSE.rst,sha256=8vTa1-5KSdHrTpU9rlheO5005EWReEPMpjV7BjSaMc4,1050
57
- numbers_parser-4.8.0.dist-info/METADATA,sha256=is-2Cwuuhq9It-c28uaOEfk089WxNutFQc95g2Nvf6E,16089
58
- numbers_parser-4.8.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
59
- numbers_parser-4.8.0.dist-info/entry_points.txt,sha256=V91uB9vBPxf3eCY1h-0syv21imYCT0MJfMxf87DmwIk,115
60
- numbers_parser-4.8.0.dist-info/RECORD,,
56
+ numbers_parser-4.9.0.dist-info/LICENSE.rst,sha256=8vTa1-5KSdHrTpU9rlheO5005EWReEPMpjV7BjSaMc4,1050
57
+ numbers_parser-4.9.0.dist-info/METADATA,sha256=RWBbYXp1YHBV7Jj4Q6C_RwXIA_-JEi55l6o1A7G9r4w,16152
58
+ numbers_parser-4.9.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
59
+ numbers_parser-4.9.0.dist-info/entry_points.txt,sha256=V91uB9vBPxf3eCY1h-0syv21imYCT0MJfMxf87DmwIk,115
60
+ numbers_parser-4.9.0.dist-info/RECORD,,