( textBody: TextBody, placeholder: PlaceholderInfo | undefined, ctx: RenderContext, container: HTMLElement, options?: RenderTextBodyOptions )
| 497 | } |
| 498 | |
| 499 | export function renderTextBody( |
| 500 | textBody: TextBody, |
| 501 | placeholder: PlaceholderInfo | undefined, |
| 502 | ctx: RenderContext, |
| 503 | container: HTMLElement, |
| 504 | options?: RenderTextBodyOptions |
| 505 | ): void { |
| 506 | const category = getPlaceholderCategory(placeholder) |
| 507 | let bulletCounter = 0 |
| 508 | |
| 509 | // Parse normAutofit from bodyPr (font scaling + line spacing reduction) |
| 510 | let fontScale = 1 |
| 511 | let lnSpcReduction = 0 |
| 512 | if (textBody.bodyProperties) { |
| 513 | const normAutofit = textBody.bodyProperties.child('normAutofit') |
| 514 | if (normAutofit.exists()) { |
| 515 | const fs = normAutofit.numAttr('fontScale') |
| 516 | if (fs !== undefined) fontScale = fs / 100000 // 100000 = 100% |
| 517 | const lsr = normAutofit.numAttr('lnSpcReduction') |
| 518 | if (lsr !== undefined) lnSpcReduction = lsr / 100000 // e.g., 20000 = 20% |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | for (const paragraph of textBody.paragraphs) { |
| 523 | const paraDiv = document.createElement('div') |
| 524 | const level = paragraph.level |
| 525 | |
| 526 | // ---- Build merged paragraph style (7-level inheritance) ---- |
| 527 | const merged: MergedParagraphStyle = {} |
| 528 | |
| 529 | // Level 1: master defaultTextStyle |
| 530 | mergeParagraphProps(merged, findStyleAtLevel(ctx.master.defaultTextStyle, level)) |
| 531 | |
| 532 | // Level 2: master text styles by category |
| 533 | const masterTextStyle = |
| 534 | category === 'title' |
| 535 | ? ctx.master.textStyles.titleStyle |
| 536 | : category === 'body' |
| 537 | ? ctx.master.textStyles.bodyStyle |
| 538 | : ctx.master.textStyles.otherStyle |
| 539 | mergeParagraphProps(merged, findStyleAtLevel(masterTextStyle, level)) |
| 540 | |
| 541 | // Level 3: master placeholder lstStyle |
| 542 | if (placeholder) { |
| 543 | const masterPh = findPlaceholderNode(ctx.master.placeholders, placeholder) |
| 544 | if (masterPh) { |
| 545 | const lstStyle = getPlaceholderLstStyle(masterPh) |
| 546 | mergeParagraphProps(merged, findStyleAtLevel(lstStyle, level)) |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | // Level 4: layout placeholder lstStyle |
| 551 | if (placeholder) { |
| 552 | const layoutPh = findPlaceholderNode( |
| 553 | ctx.layout.placeholders.map((e) => e.node), |
| 554 | placeholder |
| 555 | ) |
| 556 | if (layoutPh) { |
no test coverage detected