\n"); exit(2); } $path = $argv[1]; $wordNs = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'; $zip = new ZipArchive(); if ($zip->open($path) !== true) { throw new RuntimeException("Cannot open DOCX: {$path}"); } $documentXml = $zip->getFromName('word/document.xml'); if ($documentXml === false) { throw new RuntimeException('word/document.xml is missing'); } $doc = new DOMDocument('1.0', 'UTF-8'); $doc->preserveWhiteSpace = false; $doc->formatOutput = false; if (!$doc->loadXML($documentXml)) { throw new RuntimeException('word/document.xml is invalid'); } $xpath = new DOMXPath($doc); $xpath->registerNamespace('w', $wordNs); function attr(DOMElement $element, string $name, string $value, string $ns): void { $element->setAttributeNS($ns, 'w:' . $name, $value); } function child(DOMDocument $doc, DOMElement $parent, string $localName, string $ns): DOMElement { foreach ($parent->childNodes as $node) { if ($node instanceof DOMElement && $node->namespaceURI === $ns && $node->localName === $localName) { return $node; } } $element = $doc->createElementNS($ns, 'w:' . $localName); $parent->appendChild($element); return $element; } foreach ($xpath->query('//w:body/w:p | //w:body/w:tbl//w:p') as $paragraph) { if (!$paragraph instanceof DOMElement) { continue; } $text = ''; foreach ($xpath->query('.//w:t', $paragraph) as $textNode) { $text .= $textNode->textContent; } $text = trim(preg_replace('/\s+/u', ' ', $text) ?? ''); $pPrNode = $xpath->query('./w:pPr', $paragraph)->item(0); if (!$pPrNode instanceof DOMElement) { $pPrNode = $doc->createElementNS($wordNs, 'w:pPr'); $paragraph->insertBefore($pPrNode, $paragraph->firstChild); } $spacing = child($doc, $pPrNode, 'spacing', $wordNs); $before = '0'; $after = '30'; $line = '320'; if ($text === '') { $after = '20'; $line = '120'; } elseif (preg_match('/^[1-7]\.\s/u', $text)) { $before = '120'; $after = '45'; $line = '330'; } elseif (preg_match('/^[1-7]\.\d\s/u', $text)) { $before = '70'; $after = '30'; $line = '320'; } elseif (str_starts_with($text, '•')) { $after = '15'; $line = '310'; } elseif (str_starts_with($text, 'วันที่ 5 มกราคม')) { $before = '40'; $after = '100'; $line = '330'; } elseif (str_starts_with($text, 'เรื่อง') || str_starts_with($text, 'เรียน')) { $after = '55'; $line = '330'; } elseif (str_starts_with($text, 'ลงชื่อ')) { $before = '160'; $after = '10'; $line = '310'; } elseif (str_starts_with($text, '(') || str_starts_with($text, 'ตำแหน่ง') || str_starts_with($text, 'วันที่ _') || str_starts_with($text, 'ผู้มีอำนาจ')) { $after = '10'; $line = '310'; } elseif (str_starts_with($text, 'บริษัท บี.อาร์.เอ็น.') || str_starts_with($text, 'เอกสารฉบับนี้') || str_starts_with($text, 'ผลส่งมอบประกอบ') || str_starts_with($text, 'การเปลี่ยนแปลง') || str_starts_with($text, 'จึงจัดทำ')) { $after = '55'; $line = '330'; } attr($spacing, 'before', $before, $wordNs); attr($spacing, 'after', $after, $wordNs); attr($spacing, 'line', $line, $wordNs); attr($spacing, 'lineRule', 'auto', $wordNs); } foreach ($xpath->query('//w:sectPr/w:pgMar') as $margin) { if (!$margin instanceof DOMElement) { continue; } attr($margin, 'top', '850', $wordNs); attr($margin, 'bottom', '850', $wordNs); attr($margin, 'left', '1080', $wordNs); attr($margin, 'right', '1080', $wordNs); attr($margin, 'header', '400', $wordNs); attr($margin, 'footer', '400', $wordNs); } foreach ($xpath->query('//w:tbl/w:tblPr') as $tableProperties) { if (!$tableProperties instanceof DOMElement) { continue; } $margins = child($doc, $tableProperties, 'tblCellMar', $wordNs); foreach (['top' => '45', 'left' => '70', 'bottom' => '45', 'right' => '70'] as $side => $width) { $edge = child($doc, $margins, $side, $wordNs); attr($edge, 'w', $width, $wordNs); attr($edge, 'type', 'dxa', $wordNs); } } $updatedXml = $doc->saveXML(); if ($updatedXml === false) { throw new RuntimeException('Cannot serialize adjusted document XML'); } if (!$zip->addFromString('word/document.xml', $updatedXml)) { throw new RuntimeException('Cannot update word/document.xml'); } $zip->close(); echo $path . PHP_EOL;