Create and read Microsoft Word (.docx) documents. Use this skill when you need to generate reports/letters/templates as .docx or extract readable text from existing .docx files.
62
73%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./scientific-skills/Other/word-read-write/SKILL.md.docx files for indexing, review, or conversion to Markdown..docx documents using the docx (docx-js) library..docx content via Pandoc conversion.^9.0.0>= 2.0 (CLI tool for extracting/converting .docx content).docx (Node.js)Install
npm i docxcreate-doc.js
const fs = require("fs");
const {
Document,
Packer,
Paragraph,
TextRun,
Table,
TableRow,
TableCell,
ImageRun,
Header,
Footer,
AlignmentType,
BorderStyle,
WidthType,
ShadingType,
PageOrientation,
PageNumber,
PageBreak,
TableOfContents,
HeadingLevel,
LevelFormat,
} = require("docx");
const US_LETTER = { width: 12240, height: 15840 }; // DXA (1440 = 1 inch)
const MARGINS_1IN = { top: 1440, right: 1440, bottom: 1440, left: 1440 };
const CONTENT_WIDTH = US_LETTER.width - MARGINS_1IN.left - MARGINS_1IN.right; // 9360
const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
const borders = { top: border, bottom: border, left: border, right: border };
const doc = new Document({
styles: {
default: {
document: {
run: { font: "Arial", size: 24 }, // 12pt
},
},
paragraphStyles: [
// Use exact IDs to override built-in Word heading styles
{
id: "Heading1",
name: "Heading 1",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: { size: 32, bold: true, font: "Arial" },
paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 },
},
{
id: "Heading2",
name: "Heading 2",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: { size: 28, bold: true, font: "Arial" },
paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 },
},
],
},
numbering: {
config: [
{
reference: "bullets",
levels: [
{
level: 0,
format: LevelFormat.BULLET,
text: "•",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } },
},
],
},
{
reference: "numbers",
levels: [
{
level: 0,
format: LevelFormat.DECIMAL,
text: "%1.",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } },
},
],
},
],
},
sections: [
{
properties: {
page: {
size: {
width: US_LETTER.width,
height: US_LETTER.height,
// For landscape: pass portrait dimensions and set orientation; docx swaps internally.
// orientation: PageOrientation.LANDSCAPE,
},
margin: MARGINS_1IN,
},
},
headers: {
default: new Header({
children: [new Paragraph({ children: [new TextRun("Sample Header")] })],
}),
},
footers: {
default: new Footer({
children: [
new Paragraph({
children: [
new TextRun("Page "),
new TextRun({ children: [PageNumber.CURRENT] }),
],
}),
],
}),
},
children: [
new Paragraph({
heading: HeadingLevel.HEADING_1,
children: [new TextRun("DOCX Creation Example")],
}),
new TableOfContents("Table of Contents", {
hyperlink: true,
headingStyleRange: "1-3",
}),
new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun("Lists")],
}),
new Paragraph({
numbering: { reference: "bullets", level: 0 },
children: [new TextRun("Bullet item")],
}),
new Paragraph({
numbering: { reference: "numbers", level: 0 },
children: [new TextRun("Numbered item")],
}),
new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun("Table")],
}),
new Table({
width: { size: CONTENT_WIDTH, type: WidthType.DXA },
columnWidths: [CONTENT_WIDTH / 2, CONTENT_WIDTH / 2],
rows: [
new TableRow({
children: [
new TableCell({
borders,
width: { size: CONTENT_WIDTH / 2, type: WidthType.DXA },
shading: { fill: "D5E8F0", type: ShadingType.CLEAR },
margins: { top: 80, bottom: 80, left: 120, right: 120 },
children: [new Paragraph("Left cell")],
}),
new TableCell({
borders,
width: { size: CONTENT_WIDTH / 2, type: WidthType.DXA },
shading: { fill: "FFFFFF", type: ShadingType.CLEAR },
margins: { top: 80, bottom: 80, left: 120, right: 120 },
children: [new Paragraph("Right cell")],
}),
],
}),
],
}),
new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun("Image")],
}),
new Paragraph({
children: [
new ImageRun({
type: "png",
data: fs.readFileSync("./image.png"),
transformation: { width: 200, height: 150 },
altText: { title: "Title", description: "Desc", name: "Name" },
}),
],
}),
new Paragraph({ children: [new PageBreak()] }),
new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun("New Page Section")],
}),
// Do not use "\n" inside TextRun; create separate Paragraphs instead.
new Paragraph({ children: [new TextRun("This is on a new page.")] }),
],
},
],
});
(async () => {
const buffer = await Packer.toBuffer(doc);
fs.writeFileSync("output.docx", buffer);
console.log("Wrote output.docx");
})();Run
node create-doc.js.docx text with Pandocpandoc document.docx -o output.md.docx is a ZIP archive containing XML parts; libraries generate the required XML and package it.12240 x 15840.12240 - 1440 - 1440 = 9360 DXA.orientation: PageOrientation.LANDSCAPE.HeadingLevel.*."Heading1", "Heading2", etc.outlineLevel (H1 = 0, H2 = 1, ...), otherwise TOC may not pick up headings.\n in runs to simulate line breaks; create separate Paragraph elements.numbering.config with LevelFormat.BULLET / LevelFormat.DECIMAL.reference: same reference continues; different reference restarts.WidthType.DXA (percent widths can break in Google Docs).width and columnWidths; the sum of columnWidths must equal table width.width to match its corresponding column width (required for consistent rendering).margins are internal padding and do not add to width; they reduce usable content area.ShadingType.CLEAR to avoid unexpected black backgrounds.ImageRun requires a valid type (e.g., png, jpg) and altText fields.PageBreak must be inside a Paragraph (or use pageBreakBefore: true).| Field | Required | Format/Source | Example | If Missing |
|---|---|---|---|---|
| User task description | Yes | Text | Research question, writing goal, analysis objective | Stop and ask user to provide |
| Primary input material | Depends on task | Text, file path, ID, table, or literature | PMID, PDF, CSV, DOCX, keywords, etc. | Specify which material type is missing |
| Output preference | No | Text | Language, format, target journal, template | Use skill default format |
This skill accepts requests that match the documented purpose of word-read-write and include enough context to complete the workflow safely.
Do not continue the workflow when the request is out of scope, missing a critical input, or would require unsupported assumptions. Instead respond:
word-read-writeonly handles its documented workflow. Please provide the missing required inputs or switch to a more suitable skill.
63c61d3
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.