「Word docxファイルはzipファイルとして展開できる」って、知ってましたか?
シナリオ
あなたは、ドキュメント変換ツール「Pandoc」で、Markdownファイルからdocxファイルを生成したい、と考えます。
しかし、いろいろな都合で、docxファイルのフォーマットにかなり手を加える必要がある、とわかりました。
(たとえば、ルビ・脚注・図表など、単純なMarkdownの知識ではどうしようもないようなフォーマットを想定しましょう)
調べた結果、「Pandocフィルタを書いて、docxファイルをいじればよい」とひとまず結論を出します。
さて……
- docxの中身ってどうなっているのでしょうか?
- どうやって、MS Word本体なしで、docxファイルをいじればよいのでしょうか?
下記では、前者の「docxの中身」についてざっくり話します。後者は割愛します。
Office Open XMLとは
Office Open XML (OOXML)は、MS Officeのファイル(Office2007以降)の形式を定めている規格です。
雑に言えば「zip圧縮されたxmlファイル群+アセットファイル(画像など)」という構成です。
厳密には、次の規格群によって定められています:
-
Open Packaging Conventions (OPC)
- XMLを用いたパッケージの方法について定義
- Officeファイルの他にも、Microsoft系の各ファイル形式(appx/cspkg/xps/nupkgなど)で採用されているようです。
- Office Open XML (OOXML)
- MS Officeに限らず、一般的でオープンなオフィスファイルの仕様を定義
- (ただしLibreOfficeと比べると、Microsoftの意向がだいぶ入るので、本当の意味での「オープン」性は懐疑的?)
- ECMA-376, Second Edition および ISO/IEC 29500
- MS Officeに限らず、一般的でオープンなオフィスファイルの仕様を定義
さらに、MS Officeの各ソフト(Word、Excel、PowerPoint)によって、それぞれ具体的な規格が定められています:
- WordprocessingML (Word docxに対応)
- SpreadsheetML (Excel xlsxに対応)
- PresentationML (PowerPoint pptxに対応)
docxファイルの中身
とにかく、docxファイルを調達しましょう。
便宜上、ここではPandocがデフォルトで利用する reference.docx
というファイルを使います。
$ pandoc --print-default-data-file=reference.docx > reference.docx
まず、docxファイルはzipアーカイブです。
docxファイルをzipファイルと見なせば、展開ができます。
ひとまず、中身をざっくり見てみましょう。
$ unzip -l reference.docx
Archive: reference.docx
Length Date Time Name
--------- ---------- ----- ----
1830 02-22-2019 07:00 [Content_Types].xml
724 02-22-2019 07:00 _rels/.rels
724 02-22-2019 07:00 docProps/app.xml
595 02-22-2019 07:00 docProps/core.xml
242 02-22-2019 07:00 docProps/custom.xml
8125 02-22-2019 07:00 word/document.xml
2494 02-22-2019 07:00 word/fontTable.xml
1135 02-22-2019 07:00 word/footnotes.xml
626 02-22-2019 07:00 word/comments.xml
2157 02-22-2019 07:00 word/numbering.xml
2126 02-22-2019 07:00 word/settings.xml
199 02-22-2019 07:00 word/webSettings.xml
14247 02-22-2019 07:00 word/styles.xml
1367 02-22-2019 07:00 word/_rels/document.xml.rels
301 02-22-2019 07:00 word/_rels/footnotes.xml.rels
7674 02-22-2019 07:00 word/theme/theme1.xml
--------- -------
44566 16 files
実際にzipファイルとして展開してみましょう。
$ unzip reference.docx -d reference_docx
Archive: reference.docx
inflating: reference_docx/[Content_Types].xml
inflating: reference_docx/_rels/.rels
inflating: reference_docx/docProps/app.xml
inflating: reference_docx/docProps/core.xml
inflating: reference_docx/docProps/custom.xml
inflating: reference_docx/word/document.xml
inflating: reference_docx/word/fontTable.xml
inflating: reference_docx/word/footnotes.xml
inflating: reference_docx/word/comments.xml
inflating: reference_docx/word/numbering.xml
inflating: reference_docx/word/settings.xml
inflating: reference_docx/word/webSettings.xml
inflating: reference_docx/word/styles.xml
inflating: reference_docx/word/_rels/document.xml.rels
inflating: reference_docx/word/_rels/footnotes.xml.rels
inflating: reference_docx/word/theme/theme1.xml
ディレクトリ構造を tree
コマンドで見てみます。
$ tree reference_docx
reference_docx
├── [Content_Types].xml
├── _rels
├── docProps
│ ├── app.xml
│ ├── core.xml
│ └── custom.xml
└── word
├── _rels
│ ├── document.xml.rels
│ └── footnotes.xml.rels
├── comments.xml
├── document.xml
├── fontTable.xml
├── footnotes.xml
├── numbering.xml
├── settings.xml
├── styles.xml
├── theme
│ └── theme1.xml
└── webSettings.xml
中身の雰囲気のみをつかむ
ここからかなり割愛して、ディレクトリ内の雰囲気をつかんでいきます。
まず注目してほしいのは word
ディレクトリです。
Wordファイルのコンテンツが、大体ここに入っていると思ってください。
_rels
ディレクトリなどは、いったん無視して大丈夫です。(ざっくり言えば、OPCに基づき、各ファイル間の関係(relation)を定義しています)
試しに word/documents.xml
の中身を見てみます。
$ cd reference_docx/word
$ cat document.xml
<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing">
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="Title" />
</w:pPr>
<w:r>
<w:t xml:space="preserve">
Title
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Subtitle" />
</w:pPr>
<w:r>
<w:t xml:space="preserve">
Subtitle
</w:t>
</w:r>
</w:p>
(中略)
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1" />
</w:pPr>
<w:bookmarkStart w:id="21" w:name="heading-1" />
<w:r>
<w:t xml:space="preserve">
Heading 1
</w:t>
</w:r>
<w:bookmarkEnd w:id="21" />
</w:p>
(中略)
<w:sectPr />
</w:body>
</w:document>
ひとまず、ここではWord文書らしきものが、XMLで定義されているということをつかめばOKです。
詳細については、ここでは割愛します。
もっと中身を覗きたい場合は、テキストエディタを使って中身を見てみましょう。
ただし、XMLファイルがminifyされている場合も多いため、XMLの整形ができるエディタ(もしくは拡張機能)を使いましょう。
まとめ
今の段階では、次のことがわかれば十分です。
- docxファイルはzipアーカイブ(zipとして展開ができる)
- その中身はXMLファイル
- 上記は、主にOffice Open XML (OOXML) という規格で定められている
- パッケージ構成自体の規格: Open Packaging Convention (OPC)
- Word docxの詳細な規格: WordprocessingML
さらに知りたい人へ
- 日本語の資料
- Office Open XML - Anatomy of an OOXML WordProcessingML File
- Eric White氏の資料(OOXML関係の解説記事やチュートリアル動画をたくさん出している)
- YouTube: Eric White - YouTube
- ブログ: Eric White | Open XML
今回は以上です。
and more...(勝手に宣伝)
(2020-05-30:技術書典6版から商業版に案内を変更)
Office Open XMLのディープな入口を案内してくれる本が商業化されました!
理音伊織さんが技術書典6で頒布された同人誌(通称「茨本」)が底本となっています。
Kindleなど電子書籍、紙の本で読めます。
本気でOpen Office XMLを学びたい人はこの本を読みましょう。
あと一歩深い情報を得るためのロードマップ~Office Open XMLフォーマットガイド (技術の泉シリーズ(NextPublishing))
#技術書典 6で頒布したOOXML本がインプレスR&Dさんから11/1に発売になります!
— 理音伊織 (@IoriAYANE) October 30, 2019
同人版では書き切れなかった図形関係あたりが増量されています。
ぜひに!
あと一歩深い情報を得るためのロードマップ~Office Open XMLフォーマットガイド https://t.co/ZVgLNlFNtS