一键导入
markdown-to-branded-doc
Convert markdown files to branded documents using pre-composed branded templates. Supports .docx and Google Docs (via gws CLI).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Convert markdown files to branded documents using pre-composed branded templates. Supports .docx and Google Docs (via gws CLI).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
End-of-session procedure that captures learnings into memory topic files, verifies index consistency, updates current-state.md, and syncs changes to team-lib.
Send an on-demand manual pulse to the ClickUp Pulse channel and optionally register thread-to-task mappings.
Graduated to team-lib — see team-lib/skills/session-debrief/. This stub demonstrates the my-lib → team-lib graduation pattern.
Add aliases, functions, or env vars to ~/.bashrc with section-aware placement
Check and upgrade local workspace files against latest team-lib templates
Compose base + type-override templates with brand tokens to produce fully resolved branded templates. Deep merges base+override, resolves tokenRef dot-paths against brand-tokens.json, and applies brand preference fan-out.
| name | markdown-to-branded-doc |
| description | Convert markdown files to branded documents using pre-composed branded templates. Supports .docx and Google Docs (via gws CLI). |
| summary | Renders markdown to branded documents using branded-template-v2 schema. Loads pre-composed templates from companies/{name}/brand/templates/{type}.json. Supports 7 document types across all brands. |
| version | 4.0.0 |
| last_updated | "2026-03-19T00:00:00.000Z" |
| dependencies | ["/_external/anthropics/skills/docx"] |
Convert Markdown documents to professionally formatted, branded documents. All styling comes from pre-composed branded templates — the renderer does no composition, no token resolution, no fallback chains.
Markdown → parser.js → DocumentIR → render-branded-docx.js → .docx file
→ render-branded-gdoc.js → JSON plan → execute-gdoc-api.js → Google Doc
lib/parser.js): Parses markdown via marked.lexer() into a format-agnostic IRlib/brand-loader.js): Loads pre-composed template from context/indexed/companies/{brand}/brand/templates/{type}.jsonrender-branded-docx.js): Maps IR to docx library objects using template valuesrender-branded-gdoc.js): Maps IR to a JSON render plan (v2.4)execute-gdoc-api.js): Executes render plan via gws CLINode dependencies:
cd skills/markdown-to-branded-doc/scripts
npm install
System dependencies:
gws CLI — Required for Google Docs output (--format gdoc). Handles OAuth and all Google API calls.
npm install -g @anthropic/gws (or follow gws setup docs)gws auth login once to configure Google credentials for your workspace accountgws docs list --limit 1 should return a document without errors.docx output — only required when using --format gdoc or running execute-gdoc-api.jspdftotext — Required for PDF-based orphan detection (heading placement optimization). Silently skipped if not installed — documents render correctly but orphan headings won't be detected.
sudo apt install poppler-utilsbrew install popplerpdftotext -v should print version infonode scripts/md-to-branded-doc.js <input.md> <output> [--brand <brand>] [--type <type>] [--format docx|gdoc]
Options:
--brand — Company slug: pvragon, acme-corp, globex (default: pvragon)--type — Document type (default: doc-report)--format — Output format: docx or gdoc (default: docx)--list-brands — List available brands--list-types — List available document types for a brandDocument types:
doc-report — Standard branded report with TOCdoc-report-cover — Report with dedicated cover pagedoc-letterhead — Formal correspondence, no page numbersdoc-legal — Contracts, MSAs, SOWs — suppressed branding, 10pt, legal conventionsslides-informational — Content-dense slides (read-oriented)slides-formal — Presentation slides (present-oriented)html-presentation — Standalone HTML presentation# Pvragon legal document
node scripts/md-to-branded-doc.js ./msa.md ./msa.docx --brand pvragon --type doc-legal
# Acme Corp report as Google Doc
node scripts/md-to-branded-doc.js ./report.md ./plan.json --brand acme-corp --type doc-report --format gdoc
node scripts/execute-gdoc-api.js plan.json [--folder <driveFolder>]
The executor handles everything automatically:
batchUpdate calls[TABLE_N] placeholders), optimizes column widthsPage numbers use a template-based approach. A Google Doc template (_pvragon-doc-template-pagenums) has pre-configured footer with auto-updating page numbers and "different first page" enabled. The executor copies this template via files.copy instead of creating a blank doc.
1ece9BQ7ouVm0Zg-YCxGaM0REjPuz_yl4q8f1oYLH2i4Page numbers are enabled per template type via headerFooter.footer.pageNumbers. Legal and report types have page numbers; letterhead does not.
The Google Docs API doesn't support creating first-page-only headers. Workaround:
useFirstPageHeaderFooter which hides it on page 1)Keyword-triggered (all doc types): Visible insertPageBreak before headings starting with Appendix, Exhibit, Schedule, or Signature Block.
Orphan detection (when enabled): After all content is finalized, exports the document as PDF and cross-references page boundaries with the Docs API heading list. Headings near the bottom of a page with insufficient content after them get a visible page break inserted before them. Runs iteratively until no orphans remain.
pdftotext for page boundary extraction (accurate positions)namedStyleType for heading identification (accurate semantics)Paragraphs between the title and first section heading can be treated as subtitle/metadata (brand-colored, styled). This is controlled per template type via renderOptions.subtitleDetection:
The renderer reads a single pre-composed JSON file per brand × type. Key sections:
| Section | What it controls |
|---|---|
documentSettings | Page mode, margins, font, font size, line spacing |
headings | h1–h6 styling (color, size, spacing, bold, italic) |
bodyText | Normal paragraph styling |
inlineStyles | Bold labels, links, code font |
tables | Header row, alternating rows, borders |
headerFooter | Logo, page numbers, alignment |
renderOptions | subtitleDetection |
pageBreaks | orphanDetection |
themeColors | Document theme palette |
titleBlock | Title, subtitle, metadata styling |
Templates are generated by the compose-branded-template skill and stored at context/indexed/companies/{brand}/brand/templates/{type}.json.
scripts/
├── md-to-branded-doc.js # CLI entry point
├── render-branded-gdoc.js # Google Docs renderer (plan generation)
├── render-branded-docx.js # DOCX renderer
├── execute-gdoc-api.js # Google Docs plan executor (gws CLI)
├── lib/
│ ├── parser.js # Markdown → DocumentIR
│ └── brand-loader.js # Loads composed templates from company context
├── package.json
└── node_modules/
The Google Docs pipeline uses pre-configured template documents to work around API limitations (page numbers, first-page headers). Template IDs are stored in each brand's composed templates under googleDocTemplates.
| Template | ID | Shared? | Notes |
|---|---|---|---|
| Page numbers | 1ece9BQ7ouVm0Zg-YCxGaM0REjPuz_yl4q8f1oYLH2i4 | Yes — all brands | Footer with auto-updating page numbers + "different first page" enabled |
| Pvragon letterhead | 1R_mBGvrZfOdAz8bkFWtr4Rn_rsfJqU0q0VClf7YDV-A | No — Pvragon only | Brand-specific header (logo, address, contact info) |
Letterhead templates are created automatically by compose-branded-template.js when clasp is available. If clasp is not installed:
--google-doc-templates '{"letterhead":"<new-id>"}'The page-number template is brand-independent and shared — no per-brand creation needed.
| Feature | Status | Workaround |
|---|---|---|
| First-page header | Not supported by API | Full logo in body, favicon in DEFAULT header with useFirstPageHeaderFooter |
| Page numbers | No insertAutoText API | Template-based approach (copy from pre-configured template) |
| Named style definitions | No updateNamedStyles API | Could set via template doc or Apps Script (future) |
| Table alignment (centering) | No table-level alignment property | Left-aligned only via API. Apps Script can set alignment (future) |
| Page break elements | insertPageBreak ✓ | Working — visible, editable page breaks |