From 43eb31b97a25e6fa8d2230bbe1c894347123a019 Mon Sep 17 00:00:00 2001 From: onetwothr1 Date: Thu, 23 Jul 2026 23:52:14 +0900 Subject: [PATCH] chore: bump fig-extract to v2.12.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hugePenalty 전면 figure 오발 완화 [계약 무변경]. - src/core/fig-extract.js: v2.11.0 → v2.12.0 byte-identical (md5 32d13b96…) - docs/fig-extract-integration.md: §주의사항에 v2.12.0 전면 figure 크롭 개선 항목 추가 계약 무변경이라 fig-engine.ts·fig-extract.d.ts 수정 불요. 출력 필드·좌표계· (num,page)·manifest 스키마 불변. typecheck·build 통과. Co-Authored-By: Claude Fable 5 --- docs/fig-extract-integration.md | 1 + src/core/fig-extract.js | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/fig-extract-integration.md b/docs/fig-extract-integration.md index 78a7e2b..42ca25d 100644 --- a/docs/fig-extract-integration.md +++ b/docs/fig-extract-integration.md @@ -77,6 +77,7 @@ const seeds = toFigureEntries(res, (p) => pageHeights[p]); - **번호 글리프에 ToUnicode 매핑이 없는 PDF는 원리상 미탐지**: 번호가 화면에는 정상으로 보이는데 텍스트 레이어에 문자가 없는 문서가 있다(Wiley 일부). 엔진이 아니라 PDF 쪽 문제라 사용자 눈에는 "번호가 멀쩡히 보이는데 안 잡힌다"로 보인다 — 문의가 오면 수동 크롭 안내가 맞다. - **영역 경계 정밀화 (v2.10.x)**: figure/table·나란한 컬럼 경계 판정을 개선했다 — table 캡션을 **경계로만** 인식해 인접 figure 크롭에서 table을 제외(v2.10.0, table 자체 방출은 없음), 좌우로 나란한 두 figure가 서로를 통째로 크롭하던 것을 각자 캡션 컬럼으로 분리(v2.10.1 같은 baseline, v2.10.2 baseline 어긋난 offset). 출력 필드·좌표계·(num,page) 식별자 불변 — bbox가 더 타이트해질 뿐이라 소비자 코드 변경은 불요. - **캡션 문법 확대 (v2.11.0)**: 보충·부록 캡션의 inline 표기를 새로 잡는다 — `Fig. S1.`·`Figure S1:`·`Figure A1.`(문자접두 번호), `Supplemental`/`Supporting Figure N`(접두), `FIG. 3 (color online).`·`Figure 1 (저자명).`(괄호 한정구). 전부 **점형 canonical**(`S.N`·`A.N`)으로 방출하므로 `num` 필드에 `"S.1"`·`"A.1"` 형태가 더 자주 등장한다(v2.6.0의 `ED.N`·prefix `S.N`과 동일한 표기 규약 — 새 값 형태 아님). 출력 필드·좌표계·(num,page) 식별자·manifest 스키마 불변, 소비자 코드 변경 불요. 주의: 한 물리 figure의 캡션에 다른 계열 라벨이 중첩된 오제출 문서(예: Extended Data 캡션 본문에 `Figure S1.`)는 같은 그림을 `ED.N`+`S.N` 두 번 방출할 수 있다(candidate suppression 미구현 — 엔진 repo 백로그, n=1 코너). +- **전면 figure 크롭 개선 (v2.12.0)**: Nature Extended Data류 **전면(full-page) figure**가 과대 패널티에 눌려 페이지 일부만 크롭되던 것을 해소했다 — 전면 figure의 크롭 영역이 더 정확(전체)해진다. 출력 필드·좌표계·(num,page)·manifest 스키마 불변, 소비자 코드 변경 불요(bbox가 truth에 더 가까워질 뿐). - 엔진은 백그라운드 탭에서 크롬 타이머 스로틀링의 영향을 받는다(분석이 수십 배 느려짐). 전체 문서 스캔은 사용자가 뷰어를 보고 있는 동안 idle로 돌리는 것을 권장. diff --git a/src/core/fig-extract.js b/src/core/fig-extract.js index cabaca9..ff13000 100644 --- a/src/core/fig-extract.js +++ b/src/core/fig-extract.js @@ -31,7 +31,16 @@ const FigExtract = (() => { -const VERSION = "2.11.0"; +const VERSION = "2.12.0"; +// 2.12.0: [계약 무변경] hugePenalty 전면 figure 오발 완화 — Nature Extended Data류 전면 figure(up 영역이 +// 페이지의 65~78% 차지)가 hugePenalty(-8)를 맞아 healthy(≥8) 문턱 아래로 눌리면, ⓐ up 점수 직접 +// 하락 + ⓑ detached-with-up side 거부(up≥8 조건)가 꺼져 작은 side 크롭에 짐 → clip. **up 방향이고 +// bodyStops=0(본문 stop 없음)이며 (farClosed || !raster)일 때 hugePenalty 면제**한다 — 진짜 전면 +// figure는 far 경계가 닫혔거나 벡터로 채워지고, `!farClosed && raster`는 경계 안 닫힌 영역이 raster +// 너머로 over-reach한 것이라 벌점 유지(Simões 4@6 칼럼폭 over-grab 회귀 방지). body>0·side는 무변경. +// 전수 diff 회귀 감사(v2.11.0↔): gate FIX 8 critical clip(Xue ED.1/2/6/9·Simões ED.9·Luques 3/ED.3· +// Paul ED.4) + Structural 13@14 보너스, gate REGRESS 0. measureCandidate가 metrics.direction을 실어 +// figureScore가 up 한정 판정. // 2.11.0: [계약 무변경] 캡션 문법 확장 (M1 점없는 문자+숫자 번호 · M2 괄호 한정구) — 보충/부록 캡션의 // 모든 표면표기를 탐지해 canonical(점형 S.N·A.N·ED.N)로 방출한다(EVAL §4.5 정체성 규약). 세 갈래: // ① inline 문자+숫자 — "FIG. S1." "Fig. S1:" "Figure S1" "Figure S.1" "Figure A1"(점 유무·구분자 @@ -673,7 +682,14 @@ function figureScore(m) { const bodyPenalty = Math.min(6, m.bodyStops * 1.5); const tinyPenalty = (m.areaRatio < 0.002 || m.heightRatio < 0.012) ? 8 : 0; const slenderPenalty = (m.widthRatio < 0.10 && m.heightRatio > 0.12) ? 5 : 0; - const hugePenalty = (m.areaRatio > 0.65 || m.heightRatio > 0.82) ? 8 : 0; + /* hugePenalty: 영역이 페이지를 통째로 삼키는 over-grab 방지. 단 up 방향이고 bodyStops=0이며 + (farClosed || !raster)일 때 면제한다(v2.12.0) — 본문을 문 흔적 없는 진짜 전면 figure(Nature + Extended Data류)는 far 경계가 닫혔거나(farClosed) 벡터로 영역을 채운다(raster=0). 반면 + `!farClosed && raster`는 경계가 안 닫힌(ink가 far 경계까지 이어지는) 영역 안에 raster figure가 + 든 형태 = raster 너머로 over-reach한 것이라 벌점 유지(Simões 4@6 회귀 방지). over-grab은 + 본문을 삼켜 bodyStops>0이므로 여전히 벌점, side 후보도 무변경(full-height 보호 유지). */ + const hugeExempt = m.direction === "up" && m.bodyStops === 0 && (m.farClosed || !m.raster); + const hugePenalty = (!hugeExempt && (m.areaRatio > 0.65 || m.heightRatio > 0.82)) ? 8 : 0; const otherCapPenalty = m.stopReason === "other-cap" ? 0.5 : 0; const total = area + width + height + density + proximity + boundary + raster - bodyPenalty - tinyPenalty - slenderPenalty - hugePenalty - otherCapPenalty; @@ -976,7 +992,8 @@ function detectPage(pg, lines, dom, grid, dbg, captionData) { farBlankPx, farClosed: farBlankPx >= Math.round(4.8 * S), raster, - stopReason + stopReason, + direction: dir }; }; const scoreText = (dir, candidate) => {