From 50096ae275d5a99308ff3dc8eb83ecfdf934cc10 Mon Sep 17 00:00:00 2001 From: Gutierrez Soto Jhosepmyr Orlando Date: Thu, 9 Jul 2026 23:21:55 -0500 Subject: [PATCH 1/3] fix: convert rendered HTML instead of raw Markdown for Word output README.md relies heavily on inline HTML (tables, images, line breaks) that pandoc's Markdown reader drops or mangles when writing to docx. Rendering full HTML first with the same engine used for the PDF, then converting that HTML to docx, preserves tables and images that were previously lost. --- .github/workflows/generate-pdf.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/generate-pdf.yml b/.github/workflows/generate-pdf.yml index e43d47d..b9113ef 100644 --- a/.github/workflows/generate-pdf.yml +++ b/.github/workflows/generate-pdf.yml @@ -55,8 +55,13 @@ jobs: - name: Install pandoc run: sudo apt-get install -y -qq pandoc + - name: Render full HTML for Word conversion + run: | + md-to-pdf README.md --as-html --basedir . + mv README.html report-source.html + - name: Generate Word document - run: pandoc README.md -o "${REPORT_NAME}.docx" + run: pandoc report-source.html -o "${REPORT_NAME}.docx" - name: Upload Word artifact id: upload-docx From aac742c1f21b54e72b71a2586150fa1bfd53da75 Mon Sep 17 00:00:00 2001 From: Gutierrez Soto Jhosepmyr Orlando Date: Thu, 9 Jul 2026 23:38:33 -0500 Subject: [PATCH 2/3] feat: add professional Word style template for report generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defines branded heading styles (Title/H1-H4), a header, and a footer with page numbering (Página X de Y), matching the PDF's A4 layout and margins. Used as pandoc's --reference-doc when generating the Word document. --- .github/templates/word-reference-template.docx | Bin 0 -> 10593 bytes .gitignore | 3 +++ 2 files changed, 3 insertions(+) create mode 100644 .github/templates/word-reference-template.docx diff --git a/.github/templates/word-reference-template.docx b/.github/templates/word-reference-template.docx new file mode 100644 index 0000000000000000000000000000000000000000..b586f7b9b997fa84c0d09dd91d12e5f4eb47b4a7 GIT binary patch literal 10593 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 aPyVp-w<`!g5)lc21P}oI)&K Date: Thu, 9 Jul 2026 23:40:09 -0500 Subject: [PATCH 3/3] feat: apply Word style template, real TOC and auto-updating fields Wires the branded reference-doc into the pandoc conversion, generates a native Word table of contents (--toc), and post-processes the docx to set updateFields so Word refreshes the TOC and populates it automatically when the file is opened, since pandoc does not set this by default. --- .github/workflows/generate-pdf.yml | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.github/workflows/generate-pdf.yml b/.github/workflows/generate-pdf.yml index b9113ef..cee0149 100644 --- a/.github/workflows/generate-pdf.yml +++ b/.github/workflows/generate-pdf.yml @@ -61,7 +61,40 @@ jobs: mv README.html report-source.html - name: Generate Word document - run: pandoc report-source.html -o "${REPORT_NAME}.docx" + run: | + pandoc report-source.html \ + --reference-doc=.github/templates/word-reference-template.docx \ + --toc --toc-depth=3 \ + --metadata title="${REPORT_NAME}" --metadata lang=es-PE \ + -o "${REPORT_NAME}.docx" + + - name: Enable auto-update of the Word table of contents + run: | + python3 - "${REPORT_NAME}.docx" <<'PY' + import re + import sys + import zipfile + + path = sys.argv[1] + with zipfile.ZipFile(path, "r") as zin: + items = zin.infolist() + data = {item.filename: zin.read(item.filename) for item in items} + + settings = data["word/settings.xml"].decode("utf-8") + if "' + + settings[insert_at:] + ) + data["word/settings.xml"] = settings.encode("utf-8") + + with zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED) as zout: + for item in items: + zout.writestr(item, data[item.filename]) + PY - name: Upload Word artifact id: upload-docx