概要
とにかく、wordが嫌いだ。知らないうちにfontが違うだの、インデントが違うのだの、めんどくさいことこの上ない。
だったら、いっそtextだけでコンバートできないか?と考えてpython-docxを使ってみた。
結論
もう少し、時間があればなんとかできるかもしれない。
問題は「相互参照」で図番号等をかってに挿入する仕組みである。
wordは内部で勝手に「_Refxxxx」というようなbookmarkを作ってこれを実現しているのだが、これをプログラム側で代行する必要がある。python-docxの開発者はこの辺を追加しているような気もするがまだよくわからない。もう少し調べてみよう。
あとは、数式の挿入ができそうもないなあ・・やっぱり、markdownから攻めるのがいいのかなあ?
SAMPLE
python-docxはインストール済みとする。
最初に、tmp.docxというwordを作っておく。
ここには、見出し1が1,見出し2が1.1というように長文用のstyleを設定して、saveしておく。
以下のプログラムを走らせると、図番号の表示が
図ー 図の名称
とかになっているが、fieldの更新をすると、無事
図1.1-1 図の名称
になってくれる。
test.py
# coding:utf-8
from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Inches
from attrdict import AttrDict
'''
図番号を挿入する
'''
def Figure(elm,paragraph):
run = paragraph.add_run()
r = run._r
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
r.append(fldChar)
instrText = OxmlElement('w:instrText')
instrText.text = u' STYLEREF 2 \s'
r.append(instrText)
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'end')
r.append(fldChar)
run = paragraph.add_run(u'-')
run = paragraph.add_run()
r = run._r
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
r.append(fldChar)
instrText = OxmlElement('w:instrText')
instrText.text = u' SEQ 図 \* DBCHAR'
r.append(instrText)
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'end')
r.append(fldChar)
run = paragraph.add_run(u' '+elm)
document = Document('tmp.docx')
# document.add_heading(u'ドキュメント', 0)
p = document.add_paragraph(u'文の挿入 ')
p.add_run(u'太字').bold = True
p.add_run(' and some ')
p.add_run(u'斜線.').italic = True
document.add_heading(u'見出し1', level=1)
document.add_paragraph(u'本文1で長い文章をかいてもらいたいということなんで書いた。改行も試験したいのでこんなに長い文になってしまった。')
document.add_heading(u'見出し2', level=2)
document.add_paragraph(u'本文2')
document.add_heading(u'見出し3', level=3)
document.add_paragraph(u'本文3')
# document.add_picture('monty-truth.png', width=Inches(1.25))
pg = document.add_paragraph(u'図',style='Caption')
Figure(u'図の名称',pg)
document.add_page_break()
document.save('demo3.docx')