Creación, edición y análisis de DOCX
Un .docx es un archivo ZIP que contiene archivos XML. Elige tu enfoque según la tarea:
| Tarea | Enfoque |
|---|---|
| Crear un documento nuevo | Escribe un script con docx (npm) — consulta las trampas a continuación |
| Editar un documento existente | unzip → editar word/document.xml → zip (docx-js no puede abrir archivos existentes) |
| Leer contenido | pandoc -t markdown file.docx |
Las rutas de los scripts a continuación son relativas al directorio de esta habilidad.
Crear con docx-js — trampas
docx está preinstalado — no ejecutes npm install primero; escribe el script y usa require('docx') directamente. Solo si ese require falla: npm install docx. El modelo conoce la API; estos son los puntos problemáticos:
- El tamaño de página predeterminado es A4. Para Carta EE. UU., establece
page: { size: { width: 12240, height: 15840 } }(DXA; 1440 = 1″). - Paisaje: pasa las dimensiones de retrato y
orientation: PageOrientation.LANDSCAPE— docx-js intercambia ancho/alto internamente. - Las tablas necesitan anchos dobles: establece
columnWidthsen la tabla Ywidthen cada celda, ambos enWidthType.DXA(PERCENTAGE no funciona en Google Docs). Los anchos de las columnas deben sumar el ancho de la tabla. - Sombreado de tabla: usa
ShadingType.CLEAR, nuncaSOLID(se renderiza negro). - Listas: nunca insertes
•literalmente; usa una configuraciónnumberingconLevelFormat.BULLET. ImageRunrequieretype:("png","jpg", …).PageBreakdebe estar dentro de unParagraph.- Nunca uses
\n— usa elementosParagraphseparados. - TDC (Tabla de Contenido): los encabezados deben usar
HeadingLevel.*integrados; los estilos de encabezado personalizados necesitanoutlineLevelconfigurado o no aparecerán. - No uses una tabla como una regla horizontal — usa un borde inferior de párrafo en su lugar.
- Guía de puntos / alineado a la derecha en la misma línea: usa
PositionalTab(alignment: PositionalTabAlignment.RIGHT,leader: PositionalTabLeader.DOT) dentro de unTextRun, no puntos literales ni espacios de relleno.
Verificar la salida
Después de escribir un .docx, conviértelo a PDF y revísalo:
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # luego lee las imágenes
pdftoppm rellena con ceros los números de página hasta el ancho del total de páginas (page-01.jpg…page-12.jpg).
Editar documentos existentes
Los archivos .doc legacy deben convertirse primero: python scripts/office/soffice.py --headless --convert-to docx file.doc.
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete # elimina entradas de enlaces simbólicos — los docx de terceros no son confiables
python scripts/merge_runs.py unpacked/ # fusiona ejecuciones fragmentadas para que el texto sea localizable
# edita unpacked/word/document.xml en su lugar — NO reformatees ni embellezcas
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # verificaciones XSD; --auto-repair corrige problemas comunes
# ¿cambios controlados? añade --author "<el nombre bajo el que hiciste el cambio>" para verificar que cada edición esté registrada
Word divide el texto en muchas ejecuciones <w:r> (identificadores de revisión, marcadores de corrección ortográfica), por lo que una frase que ves en el documento a menudo no existe como una cadena contigua en el XML. merge_runs.py fusiona ejecuciones adyacentes con el mismo formato en word/document.xml sin cambiar el contenido ni la representación; también acepta un .docx directamente (python scripts/merge_runs.py doc.docx -o merged.docx).
Cambios controlados: al marcar cambios, valida con --author "<el nombre bajo el que hiciste el cambio>" (necesita --original) — reporta cualquier texto que hayas cambiado sin un <w:ins>/<w:del> alrededor, lo cual es fácil de hacer accidentalmente e invisible en la vista aceptada. Envuelve las ejecuciones en <w:ins>/<w:del> con atributos w:id, w:author, w:date. Dentro de <w:del>, el elemento de texto es <w:delText>, no <w:t>. Una marca de párrafo eliminada (<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>) significa "fusionar este párrafo con el siguiente" — por lo tanto, eliminar un párrafo por completo es eso más un <w:del> alrededor de cada ejecución. <w:del/> debe ir antes de los demás hijos de rPr; su orden está impuesto por el esquema.
Para producir una copia limpia con todos los cambios controlados aceptados: python scripts/accept_changes.py in.docx out.docx.
Aceptar una marca de párrafo eliminada debería unir ese párrafo con el siguiente, de modo que un párrafo cuyas ejecuciones todas están eliminadas desaparezca. Word hace esto; accept_changes.py y pandoc --track-changes=accept no siempre lo hacen. Ambos fallan de la misma manera: eliminan el texto eliminado pero dejan atrás el párrafo vacío, que aparece como un viñeta vacía errante cuando estaba numerado automáticamente:
pandoc --track-changes=acceptnunca une los párrafos.accept_changes.py(LibreOffice) los une correctamente, excepto cuando el párrafo eliminado va seguido de un párrafo espaciador vacío.
Una viñeta vacía en cualquier vista es un artefacto de esa vista, no un defecto en el documento. Verifica las eliminaciones de párrafos en el XML.
Comentarios
Los comentarios requieren seis archivos vinculados entre sí. Usa el asistente — modo directorio cuando también edites document.xml (ahorra un ciclo de descompresión/recompresión), modo .docx directo en caso contrario:
# Contra un directorio ya descomprimido (preferido cuando también se colocan marcadores)
python scripts/comment.py unpacked/ "El tope de tarifas y gastos es demasiado bajo"
python scripts/comment.py unpacked/ "De acuerdo" --parent 0
# Contra un .docx directamente
python scripts/comment.py contract.docx "Este tope es demasiado bajo" -o annotated.docx
El script escribe comments.xml, commentsExtended.xml, commentsIds.xml, commentsExtensible.xml, las relaciones y las anulaciones de tipo de contenido. Los IDs de comentarios se asignan automáticamente. Luego imprime el fragmento <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> para añadir a word/document.xml para que el comentario se ancle a un texto específico — hasta que coloques esos marcadores, el comentario existe pero no es visible.
Dependencias
docx (npm, preinstalado — instala solo si require('docx') falla) · pandoc · LibreOffice (soffice) · pdftoppm (Poppler)
Esta habilidad es creada y mantenida por Anthropic. Incluida aquí sin modificaciones, excepto los metadatos del frontmatter; consulta LICENSE.txt para los términos.