2020/11/28
2019/04/12に公開してから、しばらくぶりに更新しました。
まず、WordRemake というオプション名を RemakeAfter に変更しました。
pandocでdocxファイルを生成した後で、python-docxで更に調整を加えるかどうかを指定するものです。
それから、こちらが主な更新点ですが、docxファイルへの変換において 下線・傍点・フリガナに対応しました。
拙作 makeDOCX と同じ記述方法で下線・傍点・フリガナを付加できます。
#u3{Hello}
#e1{Hello}
#r{晴天:セイテン}
詳細は 8. 下線・傍点・フリガナの付加 を参照。
また、下線・傍点・フリガナのテクニカルな情報については
python-docxにおける下線・傍点・フリガナの処理 を参照。
pandocでWord文書(docxファイル)を生成した後で、
それに修正を加えたいことがしばしばあります。
Wordを起動してその修正を行うとなると、
当然ながらWindows&Wordの環境が必要になります。
それがどうにも気に入らない。なるべくOfficeソフトを使いたくない派なので。
ということで、python-docxを利用してdocxファイルの修正をしようと考えました。
そこで作成したのが usepandoc.py です。
以下では pandoc, python がインストール済みであり、
どのディレクトリからでも実行可能であることを前提にします。
処理する markdown原稿の書き方は、拙作 makeDOCX の場合と同じです。
pandoc用オプション、Word修正用オプションをmarkdown原稿中に書き入れます。
用いたpandocは ver 2.11.1.1 です。
python ver 3.7.6 で動作確認しました。
インストールが必要なpythonライブラリは次の二つ。
python -m pip install --upgrade python-docx [enter]
python -m pip install --upgrade chardet [enter]
上のようにするとライブラリをインストールできます。
付随して必要になるライブラリ(lxmlなど)もインストールされます。
usepandoc.zipをダウンロードしてから解凍します。
すると usepandoc.py, test.txt などが出てくるので次のように実行します。
python usepandoc.py test.txt [enter]
実行すると test.docx が作成されるはずです。
処理するファイルの名前にはワイルドカードも使えます。
markdown原稿の test.txt は、utf-8 で書かれていますが、
別のエンコードでも大丈夫だとおもいます。
日本語版Windowsの下では cp932(Shift_JIS)、
他の環境なら utf-8 で書いておくのが無難ではあります。
usepandoc.py に指定するコマンドラインオプションは
--ext
の一つだけです。
--ext=html
とすれば htmlファイルを生成します。
--ext=pptx
なら pptxファイルの生成。
省略時は --ext=docx
とみなされます。
html, pptx の場合は、pandoc でファイルを生成したらそれで終了です。
usepandoc.py が独自の修正を加えることはありません。
なお、--ext
以外のマイナス記号で始まるオプションは、
pandocにそのまま引き渡されます。
*例: python usepandoc.py --ext=html --toc --mathml test.txt [enter]
usepandoc.zipを解凍すると pandoc というサブディレクトリが出てきます。
その下には reference.docx, reference_pn.docx というファイル、
それから templates というディレクトリがあります。
reference.docx は、Wordファイルを作成するときに
pandocが参照するスタイル定義ファイルです。
これは、デフォルト版に少し変更を加えたものです。
見出しが青色に設定されているのを色なしにするなどの変更です。
reference_pn.docx は、フッターにページ番号を付加したもので
それ以外は reference.docx と同じです。
必要に応じて好みの形に修正してください。
templates というサブディレクトリには template01.html があります。
これはデフォルトのテンプレートに次の手を加えたものです。
template01.html を利用するときは、markdownの原稿に下の行を書き加えます。
<!-- pandoc --template=template01.html -->
pandocにはデータディレクトリというのがあり、そこに reference.docx などがあるものと仮定されます。
usepandoc.py ではそのデータディレクトリを直下の pandoc というサブディレクトリに変更しています(--data-dir
オプションで変更)。
もし pandocというサブディレクトリが存在しなければ
データディレクトリを変更はしませんが、
usepandoc.py をちゃんと機能させるためには残すことをお勧めします。
usepandoc.py が存在するのと同じディレクトリに
pandoc というサブディレクトリを置くようにします。
pandoc用のmarkdownの原稿では下の行が覚書のメモとして無視されます(返還後の文書には表面に出てきません)。
<!-- ……… -->
これは html のコメントの書き方です。
このコメントの形で pandoc用のオプションを書き入れることができます。
<!-- pandoc --toc --mathml -->
上のように書いておくと --toc
および --mathml
を指定することになります。
<!--
は、前に空白を置かず必ず行頭から書いてください。
tocは目次の生成、mathmlは数式の記述を有効にするオプションです。
このコメント形式のオプションは、ファイル中のどこに書いてもかまいません。
ただし、%
で始まる冒頭のタイトルブロックよりは後ろに書きます。
このコメントを利用したオプション指定は usepandoc.py に特有の書き方です。
より一般的には yamlブロックを使ってオプションを指定する方法があります。
それについては pandocのマニュアルなどを参照してください。
usepandoc.pyは、pandocで変換した後に python-docxを利用して変更を加えます。
どんな変更を加えるかを示しつつ、変更の在り方をコントロールする方法を記します。
なお、拙作 makeDOCX で行っている CharsLine(1行あたりの文字数)、LinesPage(1ページあたりの行数)には対応していません。
また、箇条書きの行頭文字について、小文字ローマ数字の ‘i.’ を①, ②などの丸囲み数字に変更するという処理も行いません。
pandocが生成するのは letterサイズですが、それをA4サイズに変更します。
<!-- PageSize=A5 -->
という 1行を書いておけば
A5サイズに変更できます。
指定できるサイズは次のとおり。
B4, A4, B5, A5, HG(ハガキのサイズ)
横長にしたいときは A4L
のようにアルファベットのエルを付けます。
横長を意味する landscape の頭文字のつもり。
例: <!-- PageSize=B5L -->
各ページのフッターに 1/5
とか 4/5
のようなページ番号をつけます。
「該当ページの番号、スラッシュ記号、総ページ数」の形式で
中央揃えでページ番号が付けられます。
つけない場合は PageNumber=no
を指定します。
PageNumber=yes
だとページ番号が付きます。
yes, no は小文字で書いてください。
ハガキ印刷用文書だとページ番号が不要です。
また、後で自分なりにページ番号をデザインしたいときも番号がない方がやりやすいとおもいます。
例: <!-- PageNumber=no PageSize=HG -->
上のように複数のWord用オプションを 1行にまとめて書くことができます。
ただし、pandoc用のオプションとは混在させないでください。
数値を指定するオプションには次の二つがあります。
FontSize=10.5
のように指定。TextColumns=2
とすれば2段組みになる。 以下に掲げる表の調整は、文書中に複数の表がある場合、
すべての表に一括して適用されます。
pandocで生成される表では、1行目と 2行目の間に罫線が引かれます。
でも、それ以外の罫線はありません。
そこで、外枠を二重線、内側を普通の実線にします。
<!-- TableBorder=no -->
上の行がファイル中にあると、罫線は引かれません。
表がページ内の左右バランスにおいて中央に位置するよう調整します。
表にキャプションがあるときは、それも中央揃えにします。
<!-- TableCenter=no -->
上の行があると、中央揃えにはなりません。
表の 1行目の各セルの文字配置を均等割り付けにします。
TableRow1=no
を書いておくと、均等割り付けになりません。
画像をページ内の左右バランスにおいて中央揃えにします。
画像のキャプションがあるときは、それも中央揃えにします。
ただし、画像が独立した段落(パラグラフ)でない場合、
たとえば、文章と一緒になって段落を構成している場合は
中央揃えになりません。
ImageCenter=no
を指定すると、画像を中央揃えにしません。
pandocの処理結果そのままを得たいときは RemakeAfter=no
を指定します。
これがあると python-docxによる変更は行われません。
pandocでdocxを生成したらそれで終了です。
結果として、Wordに関するオプションが書かれていても、それらは生かされません。
Word用オプションをそのデフォルト値とともに記します。
PageSize=A4
ページサイズ。PageNumber=yes
ページ番号の付加。FontSize=12.0
標準フォントサイズ。TextColumns=1
段組みの数。TableBorder=yes
表の罫線付け。TableCenter=yes
表の中央そろえ。TableRow1=yes
表の1行目を均等割り付け。ImageCenter=yes
画像の中央そろえ。RemakeAfter=yes
事後のdocxファイルの調整の有無。
コマンドラインオプションの --ext=html
を指定して
htmlファイルを生成する場合、見出しにID属性を付加します。
# 更新情報
上のmarkdownの見出しの記述が pandocでは下の html記述に変換されます。
<h1 ID="更新情報">更新情報</h1>
要するに ID属性がマルチバイト文字になります。
最近のブラウザではマルチバイト文字でも問題なさそうですが、
半角英数文字の方が無難そうです。
# 更新情報 {#update}
上のmarkdown記述であれば ID属性が update になります。
usepandoc.py では ID属性の記述がない見出しに、機械的にIDを付加します。
{#session-ex1}
のような記述を付け加えます。
見出しのレベルに関係なく、見出しの出現順に通し番号を割り当てます。
ただし、次の二つのケースでは ID属性を付加しません。
{#update}
のようなID属性の記述がある場合。 なお、属性の記述の {-}
は {#session-ex1 .unnumbered}
のようになります。
docxファイルへの変換において 下線・傍点・フリガナに対応させました。
#u{Hello}
の記述があると Hello に下線が付きます。#e{Hello}
の場合は Hello に傍点が付きます。#p{晴天:セイテン}
とすれば「晴天」にフリガナがつきます。#p{
のp(PhoneticGuide)の代わりに r(ルビ)の1文字を書いてもいいです。 下線または傍点の場合、‘{’ の前に半角数字を1文字書くと、その値が
VBAでいうところの下線プロパティ、傍点プロパティにセットされます。
#u3{Hello}
のように3を書くと、二重下線になり、
#u4{Hello}
のように4を書くと、点線の下線になります。
数字がないときは、下線でも傍点でも 1 が指定されたものとみなされます。
また、プロパティとして該当しない数字が指定されたときも
1 が指定されたものとみなされます。
どの数字がどの下線・傍点に対応するのかは
下の定数を参考にしてください。
#u{ …… }
などの記述の { …… }
の中に
半角の {
と }
を書くことはできないのでご注意ください。
#e{#u{ …… }}
のように二重に指定することは可能です。
処理の順番として、下線・傍点の後にフリガナを処理します。
なので、下線・傍点とフリガナを併用するときは
#r{#u{山内}:ヤマノウチ}
のように下線・傍点の記述を内側にして下さい。
フリガナを斜体にしようとして #r{山内:*ヤマノウチ*}
のように書いても
残念ながら斜体にはなりません。フリガナのプロパティは指定不可です。
フリガナのところに半角の記号類は書かないようにして下さい。
なお、下線・傍点・フリガナのテクニカルな情報については python-docxにおける下線・傍点・フリガナの処理 を参照してください。
python-docxを利用していて少々手こずった点などを記します。
usepandoc.py の中に set_cell_border() という関数があります。
表(table)の各セルに罫線を付加するための関数です。
これは、下のサイトに掲げられていたものを使わせてもらいました。
How to setup cell borders with python-docx - Stack Overflow
使い方については上記サイトか usepandoc.py の中身を参照してください。
罫線の種類には single, double, dotDotDash を指定可能なようです。
usepandoc.py では、外枠をdouble、内線をsingleにしてあります。
pandocが生成するtableを確認すると、ちょっと変則的です。
tableオブジェクトが変数 table に代入されている場合
row_count = len(table.rows)
column_count = len(table.columns)
上のようにして行数と列数を得られるはずですが、column_count が 0 になります。
行数の方は適切な値が得られるのですが……
table.cell(0, 0)
が左上端のセルを示し、
table.cell(row_count-1, column_count-1)
が右下端を示すはずなのに
そうは問屋がおろさない。
table.cell(0, 0), table.cell(0, 1), table.cell(0, 2), ……
上のように行番号を0に固定し、列番号を徐々に挙げていって
どこでエラーが発生するかをチェックします。
そうすると table に含まれるセルの個数を知ることができます。
個数が分かれば何とか処理可能です。
こういう表(table)でも Wordで問題なく表として扱えるんですね。
python-docxを利用してフッターにページ番号を付加する方法を調べましたが、
結局、わかりませんでした。
docxファイルを展開したとき、document.xml のほかに
footer1.xml のようなファイルが必要になるようですが、
それを生成する機能が python-docx にはまだないのでは?とおもいます。
ということで、ページ番号を付加したテンプレート reference_pn.docx を用意して、それを使うことにしました。
デフォルトの PageNumber=yes
だと reference_pn.docx を参照し、
PageNumber=no
なら reference.docx を参照します。
パラグラフに、画像だけでなく文章等もある場合と
画像だけの場合とがあります。
ImageCenter=yes
が指定されたとき、画像だけなら中央揃えにしますが
そうでなければ中央揃えにしません。
この画像の中央揃えの処理は次のようにしました。
inline_tag = './w:drawing/wp:inline'
for para in document.paragraphs:
if para.text == "" and len(para.runs) == 1 and \
len(para.runs[0].element.xpath(inline_tag)) > 0:
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
段組みを設定するためのメソッドが特に用意されているわけではないので
xmlに手を加える方法をとりました。
該当の処理は次のとおり。
section = document.sections[0]
sectPr = section._sectPr
cols = sectPr.xpath('./w:cols')[0]
cols.set(qn('w:num'), '{}'.format(optdct['TextColumns']))
cols.set(qn('w:sep'), '1') # separate line: 0 or 1
cols.set(qn('w:equalWidth'), '1') # equal width: 0 or 1
段組みの境界線をつけ、均等幅にするようにしてありますが、
そうしたくない場合は該当箇所を書き換えてください。
~ 以上 ~
Copyright (C) T. Yoshiizumi, 2019-2020 All rights reserved.