發(fā)規(guī)范實(shí)戰(zhàn):PPTX 解析還原質(zhì)量迭代與 OOXML 陷阱排查指南)
OpenMAIC maic-importer 開(kāi)發(fā)規(guī)范實(shí)戰(zhàn)PPTX 解析還原質(zhì)量迭代與 OOXML 陷阱排查指南【免費(fèi)下載鏈接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click項(xiàng)目地址: https://gitcode.com/GitHub_Trending/op/OpenMAICmaic-importer是 OpenMAIC 中負(fù)責(zé)將.pptx文件解析為結(jié)構(gòu)化 JSON、進(jìn)而還原成畫(huà)布可渲染Slide[]的核心包。本文以本包開(kāi)發(fā)規(guī)范SKILL.md為骨架結(jié)合DESIGN.md的架構(gòu)設(shè)計(jì)與src/下的實(shí)際源碼實(shí)現(xiàn)完整講解還原質(zhì)量迭代流程、標(biāo)準(zhǔn)修 bug 流程、OOXML 陷阱、分層紅線與高風(fēng)險(xiǎn)文件供開(kāi)發(fā)者含 Agent在修改解析側(cè)代碼前快速建立正確的排查心智模型。maic-importer 是什么一條從 .pptx 到 JSON 的解析管線maic-importer的前身是瀏覽器端運(yùn)行的 pptxtojsonOpenMAIC 在其parse()之上擴(kuò)展了完整的 import pipelineimportPptx()→ 直接產(chǎn)出畫(huà)布Slide[]。包內(nèi)開(kāi)發(fā)規(guī)范 SKILL.md 開(kāi)宗明義先讀 DESIGN.md 了解架構(gòu)再做任何改動(dòng)。按 DESIGN.md 的記載整條解析管線為.pptx (ArrayBuffer) ↓ parser/ZipParser ── 解壓 zip按用途分類 PptxFiles ↓ model/* ── XML → 結(jié)構(gòu)化模型位置、大小、層級(jí) PresentationData ↓ serializer/* ── 模型 主題/模板上下文 → JSON 元素 Element[] ↓ adapter/toPptxtojson ── 組裝最終輸出 Output { slides, themeColors, size }入口是src/index.ts的parse(buffer, options?)。包內(nèi)有兩個(gè)易混目錄src/是 TypeScript 主實(shí)現(xiàn)參與構(gòu)建src1/是原版 JS 參考實(shí)現(xiàn)只讀不改不構(gòu)建。理解本包時(shí)先記住三個(gè)核心設(shè)計(jì)點(diǎn)詳見(jiàn) DESIGN.md模型層不感知樣式model/*只解析是什么、在哪里、多大顏色、字體、填充等視覺(jué)樣式留給 serializer 層做 theme/master/layout 級(jí)聯(lián)解析Serializer 是純映射*ToElement(node, ctx, order)輸入模型 上下文、輸出 JSON 元素、無(wú)副作用因此定位 bug 時(shí)只需懷疑對(duì)應(yīng)的 serializer 文件單位約定對(duì)外 JSON 一律ptleft/top/width/height顏色一律#RRGGBB角度一律deg內(nèi)部 EMU 在 model 層轉(zhuǎn) pxadapter 層 px → pt。單位換算集中在 parser/units.ts其中定義了 EMU→px、EMU→pt、OOXML 角度60000 分之一度→deg、百分比100000 分之一→小數(shù)等全套換算函數(shù)。還原質(zhì)量迭代從低分樣本到修復(fù)交付必讀解析還原不可能一版到位規(guī)范要求以批次迭代的方式持續(xù)逼近真實(shí)還原效果。倉(cāng)庫(kù)根目錄的iterate-prompt.md規(guī)定了如何從comparison_run中拉取低分樣本、聚類問(wèn)題、撰寫(xiě)報(bào)告。每批迭代需要交付兩樣?xùn)|西iteration-version-report.md倉(cāng)庫(kù)根目錄——批次迭代報(bào)告針對(duì)本包的解析側(cè)修復(fù)——注意渲染問(wèn)題應(yīng)修在packages/openmaic/renderer不要在本包越界處理。SKILL.md 以test-0601-002deck第一節(jié) 養(yǎng)老服務(wù)管理概述為樣例列出了四類典型問(wèn)題及其排查入口現(xiàn)象側(cè)查哪里L(fēng)ogo 上多 5 個(gè)空心圓解析layoutElements里 master 組「組合 7」子橢圓grpFill勿把父組 fill 攤到每個(gè) child → shapeSerializer.ts照片應(yīng)是圓卻變方解析p:piccustGeom→ imageSerializer.resolvePresetGeom畫(huà)布四周邊框渲染SlideCanvaschrome截圖須false文字整體偏上解析渲染bodyPranchor→vAlign→ transformParsedToSlides BaseTextElement正文偏粗、換行少解析渲染replaceFontFamilyInHtml/ 文本框width調(diào)試時(shí)有一條鐵律一定要看layoutElements。Logo、頁(yè)腳、master 裝飾元素幾乎都在layoutElements里而不是elements里只盯著elements會(huì)漏掉大量母版?zhèn)葐?wèn)題。對(duì)應(yīng)的調(diào)試命令均在倉(cāng)庫(kù)根執(zhí)行# 倉(cāng)庫(kù)根拉低分 node --env-file.env.development scripts/inspect-low-scores.mjs test-0601-002 # 本包JSON含 layoutElements npx tsx scripts/transvert.ts /path/to.pptx ./out.json node -e const srequire(./out.json).slides[1]; console.log(s.layoutElements?.length, s.elements?.length)transvert.ts是開(kāi)發(fā)主力腳本直接 importsrc源碼、無(wú)需構(gòu)建即可出 JSON源碼 內(nèi)部就是parseZip → buildPresentation → toPptxtojsonFormat三步。用node -e一行即可快速核對(duì)第 2 頁(yè)的layoutElements與elements數(shù)量是否與預(yù)期一致。修 bug 的標(biāo)準(zhǔn)流程解壓 → 轉(zhuǎn)換 → 改碼 → diff規(guī)范給出了任何 bug 修復(fù)都必須遵守的四步流程# 1. 解壓 pptx 看源 XML node scripts/extract-pptx-structure.js ./xxx.pptx ./out # 2. 生成修改前的 JSON npx tsx scripts/transvert.ts ./xxx.pptx ./before.json # 3. 改代碼 # 4. 生成修改后的 JSONdiff 對(duì)比 npx tsx scripts/transvert.ts ./xxx.pptx ./after.json第一步的 extract-pptx-structure.js 會(huì)把.pptx本質(zhì)是 zip解壓并以樹(shù)形打印內(nèi)部結(jié)構(gòu)方便直接查看ppt/slides/slideN.xml、ppt/slideMasters/、ppt/media/等原始 XML第二步與第四步的before/after.json對(duì)比則是驗(yàn)證修復(fù)是否生效的客觀依據(jù)。規(guī)范還給出了按數(shù)值/結(jié)構(gòu)/顏色/模板/裝飾分類的定位思路JSON 數(shù)值錯(cuò) → serializer節(jié)點(diǎn)類型錯(cuò) → model/Slide.ts顏色錯(cuò) → StyleResolver.ts utils/color.ts模板繼承錯(cuò) → RenderContext.tsmaster/layout 裝飾→ slideSerializer.ts 的layoutElements shapeSerializer.ts 的grpFill/lnnoFillvslnRef。OOXML 陷阱清單本 deck 已踩規(guī)范將真實(shí)踩過(guò)的 OOXML 陷阱固化為四條經(jīng)驗(yàn)每條都能在源碼中找到對(duì)應(yīng)實(shí)現(xiàn)1.a:grpFill/子形狀由組級(jí)合成禁止把父組 fill 攤給每個(gè) childgrpFill表示子形狀的填充由父組grpSpPr合成因此 JSON 里每個(gè) child 的fill應(yīng)為transparent。既不能把父組 solidFill 抄到每個(gè)橢圓上也不能用fillRef補(bǔ)色——test-0601-002 的 5 個(gè) Logo 圓點(diǎn)正是此類問(wèn)題。源碼 shapeSerializer.ts 在檢測(cè)到grpFill時(shí)依賴ctx.groupFillNode見(jiàn) RenderContext.ts繼承組填充同時(shí) StyleResolver.ts 也實(shí)現(xiàn)了 grpFill 從父組繼承填充的邏輯。對(duì)應(yīng)回歸測(cè)試見(jiàn) shapeSerializer.grpFill.test.ts。2.a:lna:noFill//a:ln顯式無(wú)描邊優(yōu)先于lnRef當(dāng)形狀顯式聲明a:noFill/作者意圖是無(wú)線條時(shí)即使p:style里帶有l(wèi)nRef也應(yīng)以noFill為準(zhǔn)。源碼中通過(guò)noFillSuppressed處理這一優(yōu)先級(jí)避免像 WPS 風(fēng)格的兼容邏輯那樣錯(cuò)誤地繼承一個(gè)綠色lnRef。3.p:pic圓形裁剪常為custGeom而非prstGeom prstellipse許多 deck 的圓形照片裁剪用的是自定義幾何custGeom而不是預(yù)設(shè)幾何prstGeom。若只讀prstGeom會(huì)得到rect方形。imageSerializer.resolvePresetGeom 的注釋明確寫(xiě)著Many decks use custGeom circles on p:pic instead of prstellipse實(shí)現(xiàn)上先查prstGeom、再查custGeom的pathLst/path兩個(gè)分支都必須覆蓋因?yàn)樵摵瘮?shù)的結(jié)果直接影響下游的clip。4. 分層順序layoutElementsmasterlayout先畫(huà)elementsslide后畫(huà)元素的分層必須與 transformParsedToSlides 的輸出順序一致masterlayout 裝飾墊底slide 內(nèi)容在上。這也再次印證了調(diào)試先看layoutElements的必要性——master 裝飾一旦畫(huà)錯(cuò)會(huì)疊在每一頁(yè)內(nèi)容之下。代碼規(guī)范與提交約定SKILL.md對(duì)本包代碼質(zhì)量提出了明確約束TypeScript strict不用ts-ignoreany僅在必要時(shí)局部使用并加注釋說(shuō)明注釋解釋為什么不解釋做了什么描述意圖而非流水賬用已有工具單位換算用 parser/units.tsXML 操作用 SafeXmlNode顏色變換用 utils/color.ts避免重復(fù)造輪子引入不一致commit message 用中文、動(dòng)詞起頭、點(diǎn)明修了什么好fix(text): 修復(fù) solidFill/gradFill 互斥覆蓋導(dǎo)致漸變遮蓋文字顏色壞fix bug/update一個(gè) commit 只做一件事重構(gòu)與 bug 修復(fù)分開(kāi)提。類型協(xié)議adapter/types.ts對(duì)外 JSON 的契約src/adapter/types.ts 是與下游的協(xié)議修改必須極其謹(jǐn)慎四條紅線不改已有字段的名字或類型不把可選字段改為必選新增字段一律?:可選并附 JSDoc 說(shuō)明其含義遵守單位約定長(zhǎng)度單位 pt、顏色#RRGGBB、角度 deg。從 types.ts 源碼可以看到Element是Shape | Text | Image | Table | Chart | Video | Audio | Diagram | Math與Group的聯(lián)合Slide同時(shí)輸出elements與layoutElements兩個(gè)數(shù)組Output頂層為{ slides, themeColors, size }。這些結(jié)構(gòu)一旦改變所有下游消費(fèi)方渲染器、畫(huà)布都會(huì)受影響。與之相對(duì)model/*的內(nèi)部類型可以自由重構(gòu)但必須保持模型層不感知樣式的原則——視覺(jué)樣式解析的復(fù)雜級(jí)聯(lián)邏輯不應(yīng)下放到 model 層。分層紅線單向依賴規(guī)范用一張表劃定了各層的職責(zé)邊界層該做不該做parser解壓、XML 解析、單位換算解析 OOXML 業(yè)務(wù)語(yǔ)義model解析幾何與結(jié)構(gòu)解析視覺(jué)樣式serializer模型 上下文 → JSON 元素直接讀 zipadapter定義類型、組裝輸出寫(xiě)業(yè)務(wù)邏輯shapes輸出 SVG path決定填充/邊框utils通用工具引用業(yè)務(wù)類型依賴方向?yàn)閍dapter → serializer → model → parser禁止反向shapes與utils是底層工具。這條紅線保證了每一層都可以獨(dú)立測(cè)試與替換也是定位問(wèn)題只需懷疑對(duì)應(yīng) serializer的架構(gòu)前提。高風(fēng)險(xiǎn)文件清單改動(dòng)以下文件前需要格外謹(jǐn)慎規(guī)范原文標(biāo)注為高風(fēng)險(xiǎn)groupSerializer.ts承擔(dān)chOff/chExt縮放與 flip/rotation 烘焙。改前想清楚flipH flipV → 180°的等價(jià)規(guī)則新增 child 特殊縮放規(guī)則時(shí)要做 fast-path 短路避免性能回退。shapeSerializer.ts800 行承擔(dān) Shape/Text 判定、preset 路徑、自適應(yīng)、grpFill/fillRef/lnRef互斥等核心邏輯。調(diào)整 Shape vs Text 判定前先用src1跑同樣的.pptx對(duì)比以原版參考實(shí)現(xiàn)校準(zhǔn)行為。imageSerializer.tsresolvePresetGeom影響下游clipcustGeom與prstGeom兩個(gè)分支都要覆蓋。presets.ts200 preset 共享輔助函數(shù)修一個(gè)前先看調(diào)用方避免誤傷其他幾何。parser/units.ts被廣泛依賴不要改現(xiàn)有函數(shù)簽名需要新單位就新增函數(shù)。開(kāi)發(fā)注意事項(xiàng)最后是規(guī)范強(qiáng)調(diào)的幾條提交紀(jì)律*.pptx、slides.json、out/、dist/已在.gitignore中提交前用git status確認(rèn)不要把調(diào)試產(chǎn)物帶進(jìn)倉(cāng)庫(kù)src1/是原版參考實(shí)現(xiàn)只讀不改不構(gòu)建改了 adapter/types.ts 必須在 commit body 寫(xiě)明協(xié)議變更改完解析邏輯后用新 version重跑 compare避免與舊批次 reply 混淆保證迭代報(bào)告的數(shù)據(jù)可追蹤。整套規(guī)范的精髓可以濃縮為一句話先看layoutElements懷疑對(duì)應(yīng) serializer用before/after.jsondiff 驗(yàn)證提交時(shí)守住協(xié)議與分層紅線。按這個(gè)流程走無(wú)論面對(duì)的是 Logo 空心圓、圓形照片還是文字偏移都能在幾分鐘內(nèi)定位到具體的解析或渲染環(huán)節(jié)。【免費(fèi)下載鏈接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click項(xiàng)目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考