magic-pdf 1.3.2__py3-none-any.whl → 1.3.4__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.
magic_pdf/libs/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.3.2"
1
+ __version__ = "1.3.4"
@@ -147,7 +147,7 @@ def doc_analyze(
147
147
  images.append(img_dict['img'])
148
148
  page_wh_list.append((img_dict['width'], img_dict['height']))
149
149
 
150
- images_with_extra_info = [(images[index], ocr, dataset._lang) for index in range(len(dataset))]
150
+ images_with_extra_info = [(images[index], ocr, dataset._lang) for index in range(len(images))]
151
151
 
152
152
  if len(images) >= MIN_BATCH_INFERENCE_SIZE:
153
153
  batch_size = MIN_BATCH_INFERENCE_SIZE
@@ -2,6 +2,8 @@ import time
2
2
  import torch
3
3
  from loguru import logger
4
4
  import numpy as np
5
+
6
+ from magic_pdf.libs.boxbase import get_minbox_if_overlap_by_ratio
5
7
  from magic_pdf.libs.clean_memory import clean_memory
6
8
 
7
9
 
@@ -188,9 +190,46 @@ def filter_nested_tables(table_res_list, overlap_threshold=0.8, area_threshold=0
188
190
  return [table for i, table in enumerate(table_res_list) if i not in big_tables_idx]
189
191
 
190
192
 
193
+ def remove_overlaps_min_blocks(res_list):
194
+ # 重叠block,小的不能直接删除,需要和大的那个合并成一个更大的。
195
+ # 删除重叠blocks中较小的那些
196
+ need_remove = []
197
+ for res1 in res_list:
198
+ for res2 in res_list:
199
+ if res1 != res2:
200
+ overlap_box = get_minbox_if_overlap_by_ratio(
201
+ res1['bbox'], res2['bbox'], 0.8
202
+ )
203
+ if overlap_box is not None:
204
+ res_to_remove = next(
205
+ (res for res in res_list if res['bbox'] == overlap_box),
206
+ None,
207
+ )
208
+ if (
209
+ res_to_remove is not None
210
+ and res_to_remove not in need_remove
211
+ ):
212
+ large_res = res1 if res1 != res_to_remove else res2
213
+ x1, y1, x2, y2 = large_res['bbox']
214
+ sx1, sy1, sx2, sy2 = res_to_remove['bbox']
215
+ x1 = min(x1, sx1)
216
+ y1 = min(y1, sy1)
217
+ x2 = max(x2, sx2)
218
+ y2 = max(y2, sy2)
219
+ large_res['bbox'] = [x1, y1, x2, y2]
220
+ need_remove.append(res_to_remove)
221
+
222
+ if len(need_remove) > 0:
223
+ for res in need_remove:
224
+ res_list.remove(res)
225
+
226
+ return res_list, need_remove
227
+
228
+
191
229
  def get_res_list_from_layout_res(layout_res, iou_threshold=0.7, overlap_threshold=0.8, area_threshold=0.8):
192
230
  """Extract OCR, table and other regions from layout results."""
193
231
  ocr_res_list = []
232
+ text_res_list = []
194
233
  table_res_list = []
195
234
  table_indices = []
196
235
  single_page_mfdetrec_res = []
@@ -204,11 +243,14 @@ def get_res_list_from_layout_res(layout_res, iou_threshold=0.7, overlap_threshol
204
243
  "bbox": [int(res['poly'][0]), int(res['poly'][1]),
205
244
  int(res['poly'][4]), int(res['poly'][5])],
206
245
  })
207
- elif category_id in [0, 1, 2, 4, 6, 7]: # OCR regions
246
+ elif category_id in [0, 2, 4, 6, 7]: # OCR regions
208
247
  ocr_res_list.append(res)
209
248
  elif category_id == 5: # Table regions
210
249
  table_res_list.append(res)
211
250
  table_indices.append(i)
251
+ elif category_id in [1]: # Text regions
252
+ res['bbox'] = [int(res['poly'][0]), int(res['poly'][1]), int(res['poly'][4]), int(res['poly'][5])]
253
+ text_res_list.append(res)
212
254
 
213
255
  # Process tables: merge high IoU tables first, then filter nested tables
214
256
  table_res_list, table_indices = merge_high_iou_tables(
@@ -226,6 +268,22 @@ def get_res_list_from_layout_res(layout_res, iou_threshold=0.7, overlap_threshol
226
268
  for idx in sorted(to_remove, reverse=True):
227
269
  del layout_res[idx]
228
270
 
271
+ # Remove overlaps in OCR and text regions
272
+ text_res_list, need_remove = remove_overlaps_min_blocks(text_res_list)
273
+ for res in text_res_list:
274
+ # 将res的poly使用bbox重构
275
+ res['poly'] = [res['bbox'][0], res['bbox'][1], res['bbox'][2], res['bbox'][1],
276
+ res['bbox'][2], res['bbox'][3], res['bbox'][0], res['bbox'][3]]
277
+ # 删除res的bbox
278
+ del res['bbox']
279
+
280
+ ocr_res_list.extend(text_res_list)
281
+
282
+ if len(need_remove) > 0:
283
+ for res in need_remove:
284
+ del res['bbox']
285
+ layout_res.remove(res)
286
+
229
287
  return ocr_res_list, filtered_table_res_list, single_page_mfdetrec_res
230
288
 
231
289
 
@@ -490,7 +490,7 @@ def insert_lines_into_block(block_bbox, line_height, page_w, page_h):
490
490
  return [[x0, y0, x1, y1]]
491
491
 
492
492
 
493
- def sort_lines_by_model(fix_blocks, page_w, page_h, line_height):
493
+ def sort_lines_by_model(fix_blocks, page_w, page_h, line_height, footnote_blocks):
494
494
  page_line_list = []
495
495
 
496
496
  def add_lines_to_block(b):
@@ -519,6 +519,10 @@ def sort_lines_by_model(fix_blocks, page_w, page_h, line_height):
519
519
  block['real_lines'] = copy.deepcopy(block['lines'])
520
520
  add_lines_to_block(block)
521
521
 
522
+ for block in footnote_blocks:
523
+ footnote_block = {'bbox': block[:4]}
524
+ add_lines_to_block(footnote_block)
525
+
522
526
  if len(page_line_list) > 200: # layoutreader最高支持512line
523
527
  return None
524
528
 
@@ -779,7 +783,7 @@ def parse_page_core(
779
783
  # interline_equation_blocks参数不够准,后面切换到interline_equations上
780
784
  interline_equation_blocks = []
781
785
  if len(interline_equation_blocks) > 0:
782
- all_bboxes, all_discarded_blocks = ocr_prepare_bboxes_for_layout_split_v2(
786
+ all_bboxes, all_discarded_blocks, footnote_blocks = ocr_prepare_bboxes_for_layout_split_v2(
783
787
  img_body_blocks, img_caption_blocks, img_footnote_blocks,
784
788
  table_body_blocks, table_caption_blocks, table_footnote_blocks,
785
789
  discarded_blocks,
@@ -790,7 +794,7 @@ def parse_page_core(
790
794
  page_h,
791
795
  )
792
796
  else:
793
- all_bboxes, all_discarded_blocks = ocr_prepare_bboxes_for_layout_split_v2(
797
+ all_bboxes, all_discarded_blocks, footnote_blocks = ocr_prepare_bboxes_for_layout_split_v2(
794
798
  img_body_blocks, img_caption_blocks, img_footnote_blocks,
795
799
  table_body_blocks, table_caption_blocks, table_footnote_blocks,
796
800
  discarded_blocks,
@@ -866,7 +870,7 @@ def parse_page_core(
866
870
  line_height = get_line_height(fix_blocks)
867
871
 
868
872
  """获取所有line并对line排序"""
869
- sorted_bboxes = sort_lines_by_model(fix_blocks, page_w, page_h, line_height)
873
+ sorted_bboxes = sort_lines_by_model(fix_blocks, page_w, page_h, line_height, footnote_blocks)
870
874
 
871
875
  """根据line的中位数算block的序列关系"""
872
876
  fix_blocks = cal_block_index(fix_blocks, sorted_bboxes)
@@ -99,11 +99,11 @@ def ocr_prepare_bboxes_for_layout_split_v2(
99
99
  all_discarded_blocks = []
100
100
  add_bboxes(discarded_blocks, BlockType.Discarded, all_discarded_blocks)
101
101
 
102
- """footnote识别:宽度超过1/3页面宽度的,高度超过10的,处于页面下半50%区域的"""
102
+ """footnote识别:宽度超过1/3页面宽度的,高度超过10的,处于页面下半30%区域的"""
103
103
  footnote_blocks = []
104
104
  for discarded in discarded_blocks:
105
105
  x0, y0, x1, y1 = discarded['bbox']
106
- if (x1 - x0) > (page_w / 3) and (y1 - y0) > 10 and y0 > (page_h / 2):
106
+ if (x1 - x0) > (page_w / 3) and (y1 - y0) > 10 and y0 > (page_h * 0.7):
107
107
  footnote_blocks.append([x0, y0, x1, y1])
108
108
 
109
109
  """移除在footnote下面的任何框"""
@@ -119,7 +119,7 @@ def ocr_prepare_bboxes_for_layout_split_v2(
119
119
  """将剩余的bbox做分离处理,防止后面分layout时出错"""
120
120
  # all_bboxes, drop_reasons = remove_overlap_between_bbox_for_block(all_bboxes)
121
121
  all_bboxes.sort(key=lambda x: x[0]+x[1])
122
- return all_bboxes, all_discarded_blocks
122
+ return all_bboxes, all_discarded_blocks, footnote_blocks
123
123
 
124
124
 
125
125
  def find_blocks_under_footnote(all_bboxes, footnote_blocks):
@@ -1,6 +1,8 @@
1
1
  import os
2
2
  import subprocess
3
+ import platform
3
4
  from pathlib import Path
5
+ import shutil
4
6
 
5
7
 
6
8
  class ConvertToPdfError(Exception):
@@ -9,21 +11,114 @@ class ConvertToPdfError(Exception):
9
11
  super().__init__(self.msg)
10
12
 
11
13
 
14
+ # Chinese font list
15
+ REQUIRED_CHS_FONTS = ['SimSun', 'Microsoft YaHei', 'Noto Sans CJK SC']
16
+
17
+
18
+ def check_fonts_installed():
19
+ """Check if required Chinese fonts are installed."""
20
+ system_type = platform.system()
21
+
22
+ if system_type == 'Windows':
23
+ # Windows: check fonts via registry or system font folder
24
+ font_dir = Path("C:/Windows/Fonts")
25
+ installed_fonts = [f.name for f in font_dir.glob("*.ttf")]
26
+ if any(font for font in REQUIRED_CHS_FONTS if any(font in f for f in installed_fonts)):
27
+ return True
28
+ raise EnvironmentError(
29
+ f"Missing Chinese font. Please install at least one of: {', '.join(REQUIRED_CHS_FONTS)}"
30
+ )
31
+ else:
32
+ # Linux/macOS: use fc-list
33
+ try:
34
+ output = subprocess.check_output(['fc-list', ':lang=zh'], encoding='utf-8')
35
+ for font in REQUIRED_CHS_FONTS:
36
+ if font in output:
37
+ return True
38
+ raise EnvironmentError(
39
+ f"Missing Chinese font. Please install at least one of: {', '.join(REQUIRED_CHS_FONTS)}"
40
+ )
41
+ except Exception as e:
42
+ raise EnvironmentError(f"Font detection failed. Please install 'fontconfig' and fonts: {str(e)}")
43
+
44
+
45
+ def get_soffice_command():
46
+ """Return the path to LibreOffice's soffice executable depending on the platform."""
47
+ system_type = platform.system()
48
+
49
+ # First check if soffice is in PATH
50
+ soffice_path = shutil.which('soffice')
51
+ if soffice_path:
52
+ return soffice_path
53
+
54
+ if system_type == 'Windows':
55
+ # Check common installation paths
56
+ possible_paths = [
57
+ Path(os.environ.get('PROGRAMFILES', 'C:/Program Files')) / 'LibreOffice/program/soffice.exe',
58
+ Path(os.environ.get('PROGRAMFILES(X86)', 'C:/Program Files (x86)')) / 'LibreOffice/program/soffice.exe',
59
+ Path('C:/Program Files/LibreOffice/program/soffice.exe'),
60
+ Path('C:/Program Files (x86)/LibreOffice/program/soffice.exe')
61
+ ]
62
+
63
+ # Check other drives for windows
64
+ for drive in ['C:', 'D:', 'E:', 'F:', 'G:', 'H:']:
65
+ possible_paths.append(Path(f"{drive}/LibreOffice/program/soffice.exe"))
66
+
67
+ for path in possible_paths:
68
+ if path.exists():
69
+ return str(path)
70
+
71
+ raise ConvertToPdfError(
72
+ "LibreOffice not found. Please install LibreOffice from https://www.libreoffice.org/ "
73
+ "or ensure soffice.exe is in your PATH environment variable."
74
+ )
75
+ else:
76
+ # For Linux/macOS, provide installation instructions if not found
77
+ try:
78
+ # Try to find soffice in standard locations
79
+ possible_paths = [
80
+ '/usr/bin/soffice',
81
+ '/usr/local/bin/soffice',
82
+ '/opt/libreoffice/program/soffice',
83
+ '/Applications/LibreOffice.app/Contents/MacOS/soffice'
84
+ ]
85
+ for path in possible_paths:
86
+ if os.path.exists(path):
87
+ return path
88
+
89
+ raise ConvertToPdfError(
90
+ "LibreOffice not found. Please install it:\n"
91
+ " - Ubuntu/Debian: sudo apt-get install libreoffice\n"
92
+ " - CentOS/RHEL: sudo yum install libreoffice\n"
93
+ " - macOS: brew install libreoffice or download from https://www.libreoffice.org/\n"
94
+ " - Or ensure soffice is in your PATH environment variable."
95
+ )
96
+ except Exception as e:
97
+ raise ConvertToPdfError(f"Error locating LibreOffice: {str(e)}")
98
+
99
+
12
100
  def convert_file_to_pdf(input_path, output_dir):
101
+ """Convert a single document (ppt, doc, etc.) to PDF."""
13
102
  if not os.path.isfile(input_path):
14
103
  raise FileNotFoundError(f"The input file {input_path} does not exist.")
15
104
 
16
105
  os.makedirs(output_dir, exist_ok=True)
17
-
106
+
107
+ check_fonts_installed()
108
+
109
+ soffice_cmd = get_soffice_command()
110
+
18
111
  cmd = [
19
- 'soffice',
112
+ soffice_cmd,
20
113
  '--headless',
114
+ '--norestore',
115
+ '--invisible',
21
116
  '--convert-to', 'pdf',
22
117
  '--outdir', str(output_dir),
23
118
  str(input_path)
24
119
  ]
25
-
120
+
26
121
  process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
27
-
122
+
28
123
  if process.returncode != 0:
29
- raise ConvertToPdfError(process.stderr.decode())
124
+ raise ConvertToPdfError(f"LibreOffice convert failed: {process.stderr.decode()}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: magic-pdf
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: A practical tool for converting PDF to Markdown
5
5
  License: AGPL-3.0
6
6
  Project-URL: Home, https://mineru.net/
@@ -29,7 +29,7 @@ Requires-Dist: tqdm >=4.67.1
29
29
  Requires-Dist: transformers !=4.51.0,<5.0.0,>=4.49.0
30
30
  Provides-Extra: full
31
31
  Requires-Dist: PyYAML <7,>=6.0.2 ; extra == 'full'
32
- Requires-Dist: dill <1,>=0.3.9 ; extra == 'full'
32
+ Requires-Dist: dill <1,>=0.3.8 ; extra == 'full'
33
33
  Requires-Dist: doclayout-yolo ==0.0.2b1 ; extra == 'full'
34
34
  Requires-Dist: ftfy <7,>=6.3.1 ; extra == 'full'
35
35
  Requires-Dist: matplotlib <4,>=3.10 ; extra == 'full'
@@ -42,7 +42,7 @@ Requires-Dist: ultralytics <9,>=8.3.48 ; extra == 'full'
42
42
  Provides-Extra: full_old_linux
43
43
  Requires-Dist: PyYAML ==6.0.2 ; extra == 'full_old_linux'
44
44
  Requires-Dist: albumentations ==1.4.20 ; extra == 'full_old_linux'
45
- Requires-Dist: dill ==0.3.9 ; extra == 'full_old_linux'
45
+ Requires-Dist: dill ==0.3.8 ; extra == 'full_old_linux'
46
46
  Requires-Dist: doclayout-yolo ==0.0.2b1 ; extra == 'full_old_linux'
47
47
  Requires-Dist: ftfy ==6.3.1 ; extra == 'full_old_linux'
48
48
  Requires-Dist: matplotlib <=3.10.1,>=3.10 ; extra == 'full_old_linux'
@@ -107,6 +107,9 @@ Easier to use: Just grab MinerU Desktop. No coding, no login, just a simple inte
107
107
  </div>
108
108
 
109
109
  # Changelog
110
+ - 2025/04/16 1.3.4 Released
111
+ - Slightly improved the speed of OCR detection by removing some unused blocks.
112
+ - Fixed page-level sorting errors caused by footnotes in certain cases.
110
113
  - 2025/04/12 1.3.2 released
111
114
  - Fixed the issue of incompatible dependency package versions when installing in Python 3.13 environment on Windows systems.
112
115
  - Optimized memory usage during batch inference.
@@ -1,5 +1,5 @@
1
1
  magic_pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- magic_pdf/pdf_parse_union_core_v2.py,sha256=6b7EHzNJrKGBIIRnK8zqeWn8tcnNZpP-7hYGP9DA82I,40384
2
+ magic_pdf/pdf_parse_union_core_v2.py,sha256=2dW8Y2FTuSsy9hun1kmKpJFcanijHfPUVd1jKrrvqXU,40575
3
3
  magic_pdf/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  magic_pdf/config/constants.py,sha256=fXGzANULnJWLPxwYp3BEFWx-rnorzpySMx63ffyEyq4,1272
5
5
  magic_pdf/config/drop_reason.py,sha256=CqjMzBE96Qo8OeFvhhhItY8WhyqsKhE3DmyJLoQZNCc,2248
@@ -52,17 +52,17 @@ magic_pdf/libs/pdf_check.py,sha256=7GWWvDR6g_rj_fE6XJlbTq5AFVX11ngRIzT0N18F214,3
52
52
  magic_pdf/libs/pdf_image_tools.py,sha256=_au7plmKKctpPKozBumSKgP8689q4vH1mU8VMLO0IbM,2260
53
53
  magic_pdf/libs/performance_stats.py,sha256=DW-c6nUTUnWKGTONRKfpucsYZm1ake016F9K7jJwbik,2136
54
54
  magic_pdf/libs/safe_filename.py,sha256=ckwcM_eqoysTb5id8czp-tXq2G9da0-l3pshZDCHQtE,236
55
- magic_pdf/libs/version.py,sha256=HgKA3RqZvC7slo8MgLyffCGwJbQ3cY6I7oUMFvGLWps,22
55
+ magic_pdf/libs/version.py,sha256=U6E-HRsrit7kgSGgIeTI2eMUeyUCny5DH8LDV4I1o0g,22
56
56
  magic_pdf/model/__init__.py,sha256=sa-dO2k-TLy25I2gRrzjm_cQeYfzMf-pLwBJHkIxGo0,51
57
57
  magic_pdf/model/batch_analyze.py,sha256=yKhKQuZTh9GG83p61bw2BRqKMbnsjsmX73gfuTRk8xE,11272
58
- magic_pdf/model/doc_analyze_by_custom_model.py,sha256=R9oowGvH3tN1knoSHiyECKsoW3RuKZ1y5cJd42FNurE,10318
58
+ magic_pdf/model/doc_analyze_by_custom_model.py,sha256=-cjn7DQi6kZCqVZ0IxbXuL2kmeGhSVLzLaezIHPFzMU,10317
59
59
  magic_pdf/model/magic_model.py,sha256=yZKWo_wRck_-YLyFGRiUHGar8sV1Y6458BFLbyBAt74,30682
60
60
  magic_pdf/model/model_list.py,sha256=aqfEJlEfbib3D3ISrxc0Coh6SbffYh8Yq2FlQN35_zA,213
61
61
  magic_pdf/model/pdf_extract_kit.py,sha256=C3sKqRkoD20Ldmo-cqGn1zRldEL-l5NYqcFvd05_fGU,10845
62
62
  magic_pdf/model/pp_structure_v2.py,sha256=NcqFWL4nUtjl82MFak8HX_8V3i4Aw_fK4dATrIp5uGs,3840
63
63
  magic_pdf/model/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  magic_pdf/model/sub_modules/model_init.py,sha256=e2t95kxiuU47luOHByDokbQ2uob6oQhEA4b6UGVfMjY,8303
65
- magic_pdf/model/sub_modules/model_utils.py,sha256=iNC-zuDLWkwUAwMZ0YcGxAwHn5SAAFRdZBQgTy9nmgY,9880
65
+ magic_pdf/model/sub_modules/model_utils.py,sha256=HKRC9ubCs6O0nNqaztrZO0YKuFpRhs0LKWOaeZfDrTw,12166
66
66
  magic_pdf/model/sub_modules/language_detection/__init__.py,sha256=8CRrCQVuExa0BttRFh3Z40lFy2K5jN0sp67KWjOlj5c,50
67
67
  magic_pdf/model/sub_modules/language_detection/utils.py,sha256=Q__v6DdNJztt8GhVSuSB0txahVq-aj8RLhWn2VScx4w,3047
68
68
  magic_pdf/model/sub_modules/language_detection/yolov11/YOLOv11.py,sha256=7T8eFl8zlZe6F0j0jSB3jrwOapDft320JQ1fuWxpvAY,5230
@@ -178,7 +178,7 @@ magic_pdf/post_proc/para_split_v3.py,sha256=SPN_VVGvFX5KpFMGw9OzgoE-kTZq-FF036i0
178
178
  magic_pdf/pre_proc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  magic_pdf/pre_proc/construct_page_dict.py,sha256=OFmq5XRKi6fYIo-lmGlL-NB16Sf0egzsfEx-fT2uYrc,660
180
180
  magic_pdf/pre_proc/cut_image.py,sha256=NDzbxwD7z7Tb4uAxL4KR6LzURFdN1Tzr4nPvj-VmEqc,1225
181
- magic_pdf/pre_proc/ocr_detect_all_bboxes.py,sha256=nt88ttXCEI_1ihAF7HU15SQjwM69V-iJmk-L_nyzA6o,9328
181
+ magic_pdf/pre_proc/ocr_detect_all_bboxes.py,sha256=o1VgMgP0KB-0pKyrkQfANYkhf7cGtzsSOXZR6DdxYZ4,9347
182
182
  magic_pdf/pre_proc/ocr_dict_merge.py,sha256=PscKGF0uJIjMxZRM69FLUs1SZO_wOswDQQV1f0M2xAo,5627
183
183
  magic_pdf/pre_proc/ocr_span_list_modify.py,sha256=bs5RLvk4kIyx9_Hqq0FU3AGPPxE8Sxs97Uwlf1sBryM,4725
184
184
  magic_pdf/pre_proc/remove_bbox_overlap.py,sha256=mcdxAh4P56NZ3Ij8h3vW8qC_SrszfXflVWuWUuUiTNg,3089
@@ -194,10 +194,10 @@ magic_pdf/tools/cli_dev.py,sha256=3RbubfTIagWoFYdu8wSDanr-BJDjFGeDet55jTy7He0,39
194
194
  magic_pdf/tools/common.py,sha256=-x0RSFr7SNbdYq7DntaLYmQmaxyF-xKSf4xMpSUTzA0,12623
195
195
  magic_pdf/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
196
  magic_pdf/utils/annotations.py,sha256=82ou3uELNbQWa9hOFFkVt0gsIskAKf5msCv5J2IJ5V0,211
197
- magic_pdf/utils/office_to_pdf.py,sha256=7aj-Ls2v8saD-Rgu_t3FIc-J3Ka9wnmiEH5zY-H1Vxs,729
198
- magic_pdf-1.3.2.dist-info/LICENSE.md,sha256=jVa0BUaKrRH4erV2P5AeJ24I2WRv9chIGxditreJ6e0,34524
199
- magic_pdf-1.3.2.dist-info/METADATA,sha256=R56SxjE08VgwAabtD81lCHxjH0hho1-c3-Zeb_zkUjo,45615
200
- magic_pdf-1.3.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
201
- magic_pdf-1.3.2.dist-info/entry_points.txt,sha256=wXwYke3j8fqDQTocUspL-CqDUEv3Tfcwp09fM8dZAhA,98
202
- magic_pdf-1.3.2.dist-info/top_level.txt,sha256=J9I0AzmHWGkp9c6DL8Oe4mEx3yYphLzkRn4H25Lg1rE,10
203
- magic_pdf-1.3.2.dist-info/RECORD,,
197
+ magic_pdf/utils/office_to_pdf.py,sha256=uYiKYPcJtxl_VmQYuQiQq3JJsfh5XXAHwmH5KyV6VhM,4525
198
+ magic_pdf-1.3.4.dist-info/LICENSE.md,sha256=jVa0BUaKrRH4erV2P5AeJ24I2WRv9chIGxditreJ6e0,34524
199
+ magic_pdf-1.3.4.dist-info/METADATA,sha256=t4InKDeOdm6_4ptByThj-XFEmTmpFSEMhl62SELBXrk,45798
200
+ magic_pdf-1.3.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
201
+ magic_pdf-1.3.4.dist-info/entry_points.txt,sha256=wXwYke3j8fqDQTocUspL-CqDUEv3Tfcwp09fM8dZAhA,98
202
+ magic_pdf-1.3.4.dist-info/top_level.txt,sha256=J9I0AzmHWGkp9c6DL8Oe4mEx3yYphLzkRn4H25Lg1rE,10
203
+ magic_pdf-1.3.4.dist-info/RECORD,,