python-hwpx 6.2.1__py3-none-any.whl → 6.3.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.
- hwpx/oxml/_document_primitives.py +6 -2
- hwpx/oxml/body.py +4 -1
- hwpx/oxml/memo.py +3 -1
- hwpx/oxml/note_authoring.py +1 -1
- hwpx/table_patch.py +29 -0
- hwpx/tools/markdown_export.py +1 -1
- hwpx/tools/object_finder.py +1 -1
- hwpx/tools/package_validator.py +78 -8
- hwpx/tools/text_extractor.py +1 -1
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/METADATA +1 -1
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/RECORD +16 -16
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/WHEEL +1 -1
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/entry_points.txt +0 -0
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/licenses/LICENSE +0 -0
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/licenses/NOTICE +0 -0
- {python_hwpx-6.2.1.dist-info → python_hwpx-6.3.0.dist-info}/top_level.txt +0 -0
|
@@ -200,8 +200,12 @@ def _refresh_copied_paragraph_subtree_ids(paragraph: ET.Element) -> None:
|
|
|
200
200
|
}:
|
|
201
201
|
node.set("id", _object_id())
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
# 스키마·실한컴 산출물의 속성명은 소문자 "instid"다. 과거 이 코드가
|
|
204
|
+
# 방출한 "instId"(카멜케이스)를 실은 파일도 재발급 대상에 남긴다 —
|
|
205
|
+
# 속성명 자체는 보존(바이트 보수), 값만 재발급.
|
|
206
|
+
for inst_attr in ("instid", "instId"):
|
|
207
|
+
if inst_attr in node.attrib:
|
|
208
|
+
node.set(inst_attr, _object_id())
|
|
205
209
|
|
|
206
210
|
|
|
207
211
|
def _clone_paragraph_element(paragraph: ET.Element) -> ET.Element:
|
hwpx/oxml/body.py
CHANGED
|
@@ -32,7 +32,10 @@ INLINE_OBJECT_NAMES = {
|
|
|
32
32
|
"ole",
|
|
33
33
|
"chart",
|
|
34
34
|
"video",
|
|
35
|
-
"audio"
|
|
35
|
+
# "audio"는 제외 — 실한컴(Windows 한글 2024 실측)은 소리 삽입을
|
|
36
|
+
# hp:ole(EMBEDDED/ICON)로 방출하고 hp:audio를 생성하지 않으며, 보유
|
|
37
|
+
# 실코퍼스 표본도 0건이다. 실물 미검증 요소를 인라인 읽기 지원으로
|
|
38
|
+
# 분류하지 않는다(빈도 0 = 읽기측 불투명 보존만). python-hwpx#89.
|
|
36
39
|
"textart",
|
|
37
40
|
}
|
|
38
41
|
|
hwpx/oxml/memo.py
CHANGED
|
@@ -277,7 +277,9 @@ class HwpxOxmlNote:
|
|
|
277
277
|
|
|
278
278
|
@property
|
|
279
279
|
def inst_id(self) -> str | None:
|
|
280
|
-
|
|
280
|
+
# 정본 속성명은 "instid"(스키마·실한컴). "instId"는 과거 우리 저작이
|
|
281
|
+
# 방출한 카멜케이스 산출물 호환용 폴백.
|
|
282
|
+
return self.element.get("instid") or self.element.get("instId")
|
|
281
283
|
|
|
282
284
|
@property
|
|
283
285
|
def text(self) -> str:
|
hwpx/oxml/note_authoring.py
CHANGED
hwpx/table_patch.py
CHANGED
|
@@ -1053,6 +1053,34 @@ def _delete_rows(table: str, del_rows: Iterable[int]) -> str:
|
|
|
1053
1053
|
return _rebuild(prefix, rows, suffix, rowcnt=len(rows))
|
|
1054
1054
|
|
|
1055
1055
|
|
|
1056
|
+
def _reorder_rows(table: str, order: Sequence[int]) -> str:
|
|
1057
|
+
"""물리 행 재배열 — 편집기 [표>정렬…] 대응의 엔진 프리미티브.
|
|
1058
|
+
|
|
1059
|
+
*order*는 현재 물리 행 인덱스의 완전 순열: 새 ``i``번째 행 = 기존
|
|
1060
|
+
``order[i]``. 행 문자열을 통째로 옮기고 각 셀의 ``rowAddr``만 목적지
|
|
1061
|
+
인덱스로 재기입한다(행 높이·서식·문단은 행과 함께 이동). 수직 병합
|
|
1062
|
+
(rowSpan>1)이 하나라도 있으면 refuse — 병합 블록을 가로지르는 재배열은
|
|
1063
|
+
의미가 정의되지 않는다. 정렬 키 비교(어떤 순서로 놓을지)는 호출자 몫이다.
|
|
1064
|
+
"""
|
|
1065
|
+
_guard_flat(table)
|
|
1066
|
+
prefix, rows, suffix = _parse_table(table)
|
|
1067
|
+
if sorted(order) != list(range(len(rows))):
|
|
1068
|
+
raise TableStructureError(
|
|
1069
|
+
f"reorder_rows: order must be a permutation of 0..{len(rows) - 1}, got {list(order)}"
|
|
1070
|
+
)
|
|
1071
|
+
for row in rows:
|
|
1072
|
+
for tc in _S_TC.findall(row):
|
|
1073
|
+
if (_si(tc, "cellSpan", "rowSpan") or 1) > 1:
|
|
1074
|
+
raise TableStructureError(
|
|
1075
|
+
"reorder_rows: vertical merge (rowSpan>1) present — refuse"
|
|
1076
|
+
)
|
|
1077
|
+
new_rows = [
|
|
1078
|
+
_map_cells(rows[src], lambda tc, dest=dest: _ss(tc, "cellAddr", "rowAddr", dest))
|
|
1079
|
+
for dest, src in enumerate(order)
|
|
1080
|
+
]
|
|
1081
|
+
return _rebuild(prefix, new_rows, suffix)
|
|
1082
|
+
|
|
1083
|
+
|
|
1056
1084
|
_PARA_ID_RE = re.compile(r'(<hp:p\b[^>]*\bid=")(\d+)(")')
|
|
1057
1085
|
|
|
1058
1086
|
|
|
@@ -1389,6 +1417,7 @@ def _widths_arg(o: Mapping[str, Any]) -> dict[int, int]:
|
|
|
1389
1417
|
_STRUCT_OPS = {
|
|
1390
1418
|
"delete_column": lambda t, o: _collapse_empty_rows(_delete_columns(t, o["cols"] if "cols" in o else [o["col"]])),
|
|
1391
1419
|
"delete_row": lambda t, o: _delete_rows(t, o["rows"] if "rows" in o else [o["row"]]),
|
|
1420
|
+
"reorder_rows": lambda t, o: _reorder_rows(t, [int(x) for x in o["order"]]),
|
|
1392
1421
|
"insert_row_by_clone": lambda t, o: _insert_row_by_clone(t, o["ref_row"], int(o.get("count", 1))),
|
|
1393
1422
|
"insert_block_by_clone": lambda t, o: _insert_block_by_clone(t, int(o["ref_rows"][0]), int(o["ref_rows"][1]), int(o.get("count", 1))),
|
|
1394
1423
|
"set_column_widths": lambda t, o: _set_column_widths(t, _widths_arg(o)),
|
hwpx/tools/markdown_export.py
CHANGED
|
@@ -261,7 +261,7 @@ def _md_handle_ctrl_child(child, state: _MdParagraphState, base_cp, chars, doc=N
|
|
|
261
261
|
def _md_handle_note_child(
|
|
262
262
|
child, tag: str, state: _MdParagraphState, base_cp, chars, doc, notes_out: list | None
|
|
263
263
|
) -> None:
|
|
264
|
-
inst_id = child.get("instId", "")
|
|
264
|
+
inst_id = child.get("instid") or child.get("instId", "")
|
|
265
265
|
kind = "fn" if tag == "footNote" else "en"
|
|
266
266
|
marker = f"[^{kind}{inst_id}]"
|
|
267
267
|
if state.link_url is not None:
|
hwpx/tools/object_finder.py
CHANGED
|
@@ -317,7 +317,7 @@ class ObjectFinder:
|
|
|
317
317
|
) -> AnnotationMatch:
|
|
318
318
|
path = describe_element_path(element, parent_map)
|
|
319
319
|
found = FoundElement(section=section, path=path, element=element)
|
|
320
|
-
inst_id = element.get("instId") or ""
|
|
320
|
+
inst_id = element.get("instid") or element.get("instId") or ""
|
|
321
321
|
behavior = options.footnote if kind == "footnote" else options.endnote
|
|
322
322
|
if behavior == "inline":
|
|
323
323
|
text = _resolve_note_text(
|
hwpx/tools/package_validator.py
CHANGED
|
@@ -331,14 +331,17 @@ def _first_child_by_local(element: ET.Element, name: str) -> ET.Element | None:
|
|
|
331
331
|
return None
|
|
332
332
|
|
|
333
333
|
|
|
334
|
-
def
|
|
335
|
-
"""Return visible text
|
|
334
|
+
def _simple_paragraph_text(paragraph: ET.Element) -> str | None:
|
|
335
|
+
"""Return visible text for plain text-only paragraphs (``None`` = 판정 불가).
|
|
336
336
|
|
|
337
337
|
Paragraphs containing fields, shapes, tables, or other embedded controls are
|
|
338
338
|
skipped to avoid guessing how a specific editor counts their layout units.
|
|
339
|
+
Single-position control characters (tab/linebreak/hyphen/nbspace) are
|
|
340
|
+
represented as one space — a deliberate width underestimate so downstream
|
|
341
|
+
width judgments stay conservative.
|
|
339
342
|
"""
|
|
340
343
|
|
|
341
|
-
|
|
344
|
+
pieces: list[str] = []
|
|
342
345
|
for child in paragraph:
|
|
343
346
|
child_name = _local_name(child).lower()
|
|
344
347
|
if child_name == "linesegarray":
|
|
@@ -348,12 +351,73 @@ def _simple_paragraph_text_length(paragraph: ET.Element) -> int | None:
|
|
|
348
351
|
for run_child in child:
|
|
349
352
|
run_child_name = _local_name(run_child).lower()
|
|
350
353
|
if run_child_name == "t":
|
|
351
|
-
|
|
354
|
+
pieces.append("".join(run_child.itertext()))
|
|
352
355
|
elif run_child_name in {"tab", "linebreak", "hyphen", "nbspace"}:
|
|
353
|
-
|
|
356
|
+
pieces.append(" ")
|
|
354
357
|
else:
|
|
355
358
|
return None
|
|
356
|
-
return
|
|
359
|
+
return "".join(pieces)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _simple_paragraph_text_length(paragraph: ET.Element) -> int | None:
|
|
363
|
+
text = _simple_paragraph_text(paragraph)
|
|
364
|
+
return None if text is None else len(text)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
#: 꼬리 폭 판정 마진 — 추정 폭이 줄 폭의 이 배수를 넘을 때만 증명으로 취급.
|
|
368
|
+
_STALE_TAIL_WIDTH_FACTOR = 2.0
|
|
369
|
+
_STALE_TAIL_MIN_CHARS = 8
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _check_line_seg_tail_coverage(
|
|
373
|
+
issues: list[PackageValidationIssue],
|
|
374
|
+
part_name: str,
|
|
375
|
+
paragraph_index: int,
|
|
376
|
+
text: str,
|
|
377
|
+
line_segs: list[ET.Element],
|
|
378
|
+
) -> None:
|
|
379
|
+
"""Catch caches that lack lines for text grown past the last cached line.
|
|
380
|
+
|
|
381
|
+
The stale-cache direction the textpos range check cannot see: an edit made
|
|
382
|
+
the paragraph *longer* but an old ``<hp:linesegarray>`` survived, so every
|
|
383
|
+
cached ``textpos`` is still in range — yet the cache has too few lines and
|
|
384
|
+
Hancom renders the tail overlapped (the tracked-change overlap defect).
|
|
385
|
+
Provable-with-margin: the tail after the last cached line start must not
|
|
386
|
+
measure wider than that line's extent × ``_STALE_TAIL_WIDTH_FACTOR``,
|
|
387
|
+
with width estimated by the same conservative metrics the overflow lint
|
|
388
|
+
uses.
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
last: tuple[int, int, int] | None = None
|
|
392
|
+
for seg in line_segs:
|
|
393
|
+
try:
|
|
394
|
+
textpos = int(seg.get("textpos") or "")
|
|
395
|
+
horzsize = int(seg.get("horzsize") or "")
|
|
396
|
+
textheight = int(seg.get("textheight") or "")
|
|
397
|
+
except ValueError:
|
|
398
|
+
return
|
|
399
|
+
if last is None or textpos > last[0]:
|
|
400
|
+
last = (textpos, horzsize, textheight)
|
|
401
|
+
if last is None:
|
|
402
|
+
return
|
|
403
|
+
last_pos, horzsize, textheight = last
|
|
404
|
+
if horzsize <= 0 or textheight <= 0 or not 0 <= last_pos <= len(text):
|
|
405
|
+
return
|
|
406
|
+
tail = text[last_pos:]
|
|
407
|
+
if len(tail) < _STALE_TAIL_MIN_CHARS:
|
|
408
|
+
return
|
|
409
|
+
from hwpx.form_fit.measure import estimate_text_width
|
|
410
|
+
|
|
411
|
+
tail_width = estimate_text_width(tail, textheight / 100.0)
|
|
412
|
+
if tail_width > horzsize * _STALE_TAIL_WIDTH_FACTOR:
|
|
413
|
+
_error(
|
|
414
|
+
issues,
|
|
415
|
+
part_name,
|
|
416
|
+
f"paragraph {paragraph_index} lineseg cache lacks lines for its tail: "
|
|
417
|
+
f"{len(tail)} chars after the last cached line start (textpos={last_pos}) "
|
|
418
|
+
f"measure ~{tail_width / horzsize:.1f}x the cached line extent {horzsize} "
|
|
419
|
+
"— stale layout cache; Hancom reuses it and renders the tail overlapped",
|
|
420
|
+
)
|
|
357
421
|
|
|
358
422
|
|
|
359
423
|
def _check_line_seg_text_positions(
|
|
@@ -367,15 +431,18 @@ def _check_line_seg_text_positions(
|
|
|
367
431
|
for paragraph_index, paragraph in enumerate(
|
|
368
432
|
element for element in root.iter() if _local_name(element) == "p"
|
|
369
433
|
):
|
|
370
|
-
|
|
371
|
-
if
|
|
434
|
+
text = _simple_paragraph_text(paragraph)
|
|
435
|
+
if text is None:
|
|
372
436
|
continue
|
|
437
|
+
text_length = len(text)
|
|
373
438
|
for child in paragraph:
|
|
374
439
|
if _local_name(child).lower() != "linesegarray":
|
|
375
440
|
continue
|
|
441
|
+
line_segs: list[ET.Element] = []
|
|
376
442
|
for line_seg in child:
|
|
377
443
|
if _local_name(line_seg).lower() != "lineseg":
|
|
378
444
|
continue
|
|
445
|
+
line_segs.append(line_seg)
|
|
379
446
|
textpos_raw = line_seg.get("textpos")
|
|
380
447
|
if textpos_raw is None:
|
|
381
448
|
continue
|
|
@@ -396,6 +463,9 @@ def _check_line_seg_text_positions(
|
|
|
396
463
|
f"{paragraph_index} has stale lineseg textpos={textpos} "
|
|
397
464
|
f"beyond text length {text_length}",
|
|
398
465
|
)
|
|
466
|
+
_check_line_seg_tail_coverage(
|
|
467
|
+
issues, part_name, paragraph_index, text, line_segs
|
|
468
|
+
)
|
|
399
469
|
|
|
400
470
|
|
|
401
471
|
def _check_table_editor_acceptance(
|
hwpx/tools/text_extractor.py
CHANGED
|
@@ -483,7 +483,7 @@ class TextExtractor:
|
|
|
483
483
|
return
|
|
484
484
|
|
|
485
485
|
kind_name = "footnote" if kind == "footNote" else "endnote"
|
|
486
|
-
inst_id = element.get("instId") or ""
|
|
486
|
+
inst_id = element.get("instid") or element.get("instId") or ""
|
|
487
487
|
|
|
488
488
|
if option == "placeholder":
|
|
489
489
|
fragments.append(
|
|
@@ -9,7 +9,7 @@ hwpx/mutation_report.py,sha256=Uw9fxft8kioXpQ0feQwSlq4vOj3-418Oywt7qmDmU_8,19494
|
|
|
9
9
|
hwpx/package.py,sha256=0rKjGCJbPQvrVBIy07Jpjsu3fI7HhbqFCGWTiTDsJpo,1141
|
|
10
10
|
hwpx/patch.py,sha256=k_LoVxHzIBNs4kg2V4yBOgAxjsrim7pksG0rmRmLApE,27264
|
|
11
11
|
hwpx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
hwpx/table_patch.py,sha256=
|
|
12
|
+
hwpx/table_patch.py,sha256=GrQNmkdTS7nBolGOX473NSvq-PglM8qVSAH1zDaPJCQ,95805
|
|
13
13
|
hwpx/templates.py,sha256=28bYqeJVeDb1Cq8G9NZG9Mhnu4K2GamAKC4QhxvUZyA,1187
|
|
14
14
|
hwpx/_document/__init__.py,sha256=REiNqMbuk_TS4NVC27FIo1rUt3Z8nhJrTBGOgNtxBRg,90
|
|
15
15
|
hwpx/_document/_legacy.py,sha256=kmiiJ-U8GEUrSvTGG7L-3TaEoLGucCPMgEuGfAJoTb4,59780
|
|
@@ -73,8 +73,8 @@ hwpx/opc/security.py,sha256=0wZitXK0J55wkbsWhyMyyufq0syBu_ZsBkqozrp-2DA,9062
|
|
|
73
73
|
hwpx/opc/xml_utils.py,sha256=L_fHY1-D5I_TfdRkDQV-bn55EnXc6AqEDWItfMpawVs,3840
|
|
74
74
|
hwpx/oxml/__init__.py,sha256=Ogl__NFyPORPxboCHqrsn2IrRdcjaQBzmnYm4pPWXpA,6731
|
|
75
75
|
hwpx/oxml/_document_impl.py,sha256=41cxktJqXHER37fjA5HIFR8kw7dHMoISTxEv53PRBYo,5367
|
|
76
|
-
hwpx/oxml/_document_primitives.py,sha256=
|
|
77
|
-
hwpx/oxml/body.py,sha256=
|
|
76
|
+
hwpx/oxml/_document_primitives.py,sha256=IcGRT7B4gblNgJ5XDivV_DME-5cU5p88hRSAM1L8_Hk,56887
|
|
77
|
+
hwpx/oxml/body.py,sha256=RRopsZ7rvHDMIYNoEwHPty7DXyaZaFRDqJQSI6gVIls,52196
|
|
78
78
|
hwpx/oxml/canonical_defaults.py,sha256=WHAK7u_W-PDv3P3N1-1-aWAoiUgBh4x-UybFL4NqW-w,3791
|
|
79
79
|
hwpx/oxml/color.py,sha256=K2lbU_JdqRxFkQelGD6BbBkH1IspJSQyGlKHNz1Nmf4,2393
|
|
80
80
|
hwpx/oxml/common.py,sha256=TJkafzg7x4T3J29tZchRZk57ZTsrM9PEiqGT3rX3w5o,1044
|
|
@@ -90,9 +90,9 @@ hwpx/oxml/header_part.py,sha256=quQowt3JXSavPPE4AlOEKlDAFPLL_dc2wUdpsqLFvzY,6220
|
|
|
90
90
|
hwpx/oxml/history_part.py,sha256=U13RujivAo-mo_B-PvBxOx1JtAP_Uc1U-VcMdjjnukk,6555
|
|
91
91
|
hwpx/oxml/master_page.py,sha256=kS_4afrXtWL9TI_QpsOhhCQeChFT6pGHtynPxUDaeCM,4172
|
|
92
92
|
hwpx/oxml/master_page_authoring.py,sha256=U9Qt87G6XQ26nEJhHlWBclGyUV_rwGcf4WVuqi-12Dg,6645
|
|
93
|
-
hwpx/oxml/memo.py,sha256=
|
|
93
|
+
hwpx/oxml/memo.py,sha256=24wUY2rPMdKkHceMGFKQg9tEoiCZjM6HLAPwydPTQE4,13595
|
|
94
94
|
hwpx/oxml/namespaces.py,sha256=SPYOj0N3qm6TCcl2xiEj7hkVdCVHqx0GpkF3kKDKoZg,6838
|
|
95
|
-
hwpx/oxml/note_authoring.py,sha256=
|
|
95
|
+
hwpx/oxml/note_authoring.py,sha256=xOoYeX640XkwdftUQeHsdojGHHbiLbobZPi3aahh5ek,7198
|
|
96
96
|
hwpx/oxml/numbering.py,sha256=9a0ARGW1DkKsTF7mEEXM4FA5loQmzIBuqE4APA8UFIQ,669
|
|
97
97
|
hwpx/oxml/numbering_kinds.py,sha256=dikaExXr8GZ0gNL4KM5xxvGQOZDCkCdcA5qKDLsstsg,4034
|
|
98
98
|
hwpx/oxml/objects.py,sha256=8gUCyH8dMDqiz_TmISKu_ZxIIsboZOc3wJ9A6KENKz4,54118
|
|
@@ -132,10 +132,10 @@ hwpx/tools/idempotence.py,sha256=UNIgfItSCoMFBxSfd3vhA-1AMJ5YJ4eGLtdOpWtfZtc,527
|
|
|
132
132
|
hwpx/tools/ir_equality.py,sha256=zku8kKVNwrADcwLXWvmQ4U8VlhOgliPWyv9Ca2ao1yg,4860
|
|
133
133
|
hwpx/tools/layout_preview.py,sha256=-gXLXBgLnIxxFpRh--oyKOodsekzoFZZ_4xSZW2jB2U,22723
|
|
134
134
|
hwpx/tools/mail_merge.py,sha256=hGELwzgLm2Qxm320ldONt9npgAP50TkPRP_ZHLOGw3Y,18590
|
|
135
|
-
hwpx/tools/markdown_export.py,sha256=
|
|
136
|
-
hwpx/tools/object_finder.py,sha256=
|
|
135
|
+
hwpx/tools/markdown_export.py,sha256=yEMWK66izjwxDJCSbDlVCrQU90GWkd_QCu3Y2ki_i7M,21538
|
|
136
|
+
hwpx/tools/object_finder.py,sha256=sKP2aF-uSk8-dPT4_Ew_Su5NlSpKVgw2FiP_iqkdU-c,13825
|
|
137
137
|
hwpx/tools/package_reconcile.py,sha256=y1Hl7hbPh4YaV59LTdDLzQwgn4g1qEnFmSjmajnrEbA,2416
|
|
138
|
-
hwpx/tools/package_validator.py,sha256=
|
|
138
|
+
hwpx/tools/package_validator.py,sha256=OMbJ8dzB7fdNrhE7S8cKdMEkeLim0joQ2TsPutlLxnU,40476
|
|
139
139
|
hwpx/tools/page_guard.py,sha256=Qg9vHP46nnq9W5GCyaHbpNY5Ndt7ecJHAdSs8BfRggQ,9622
|
|
140
140
|
hwpx/tools/read_fidelity.py,sha256=f_a3Kftee3MRaCGraC6KjQDZ-iz3hv3b8-GGC5VCgyw,10528
|
|
141
141
|
hwpx/tools/recover.py,sha256=EOVAzMFAqR9YAT3sinZKCdjSkKygo4dKrs6T6SbGA7o,4963
|
|
@@ -147,16 +147,16 @@ hwpx/tools/table_cleanup.py,sha256=0_f6NnvNp3QD4owKd_bRX6FZbeUmoQC7a4_VGzF2SCE,1
|
|
|
147
147
|
hwpx/tools/table_navigation.py,sha256=rtbrWFKpJhqC3LD0ZXImyHgjmDR2hjHCFy3_S-qNBwA,16479
|
|
148
148
|
hwpx/tools/template_analyzer.py,sha256=iH7egGRYNb8UesDB1TJ4tvW41-mlmv5Ap3VacqJFSlE,21355
|
|
149
149
|
hwpx/tools/text_extract_cli.py,sha256=BmsDAwNXpDPhEayb9ez2ORtGNzPd_Xxduy4_cLXhnUw,2188
|
|
150
|
-
hwpx/tools/text_extractor.py,sha256=
|
|
150
|
+
hwpx/tools/text_extractor.py,sha256=PZ8rCsCJMDK8wjOgfcakfoTQ5iVviH2IhWF_9l_NzY4,27929
|
|
151
151
|
hwpx/tools/toc_author.py,sha256=eS1Zm5OBoonuD_H92JxcN2o276d5XmcJDqpfscd4wSg,15445
|
|
152
152
|
hwpx/tools/toc_fidelity.py,sha256=rvoKH8QJ65WNVrxS0d-i2AtODvBy-4O8NRudfQ244v4,19890
|
|
153
153
|
hwpx/tools/validator.py,sha256=U856izL9NcJZOiKDYoCpwOSaFNQ2Un8Jn4pzL20A96Q,7100
|
|
154
154
|
hwpx/tools/_schemas/header.xsd,sha256=mJXuFMuHGT1JnFFaluUpYUglwjMCNlfbFCRVM26eHXE,664
|
|
155
155
|
hwpx/tools/_schemas/section.xsd,sha256=MgvavVHG05RDfUnVPxVU10H4FQOja5ON04_m9Uk_m7E,522
|
|
156
|
-
python_hwpx-6.
|
|
157
|
-
python_hwpx-6.
|
|
158
|
-
python_hwpx-6.
|
|
159
|
-
python_hwpx-6.
|
|
160
|
-
python_hwpx-6.
|
|
161
|
-
python_hwpx-6.
|
|
162
|
-
python_hwpx-6.
|
|
156
|
+
python_hwpx-6.3.0.dist-info/licenses/LICENSE,sha256=_ubz4wv-BkkT3l3gu-QuH7JGeVjuRYGZoZK95eNsCHU,9688
|
|
157
|
+
python_hwpx-6.3.0.dist-info/licenses/NOTICE,sha256=he3PBLXnIZK0sNsozc-SAQ2jvWjV61goylWUZ8HPi3s,3837
|
|
158
|
+
python_hwpx-6.3.0.dist-info/METADATA,sha256=Ybcxl0xVXkDcdsqWplRYdERcAEZjAxQLqayu3AUnqV8,13652
|
|
159
|
+
python_hwpx-6.3.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
160
|
+
python_hwpx-6.3.0.dist-info/entry_points.txt,sha256=JUKRxbly9UaeHV7YzOea23y8IiqSTcrhUlooP3fS_Zc,405
|
|
161
|
+
python_hwpx-6.3.0.dist-info/top_level.txt,sha256=R1iToqDh80Nf2oQhRjTN0rbN2X6kyDUizIocZjkhuxc,5
|
|
162
|
+
python_hwpx-6.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|