niszetの日記

アナログCMOS系雑用エンジニアが頑張る備忘録系日記

(Pandoc) docx -> md への逆変換のメモ(1回目)

可逆にしたい。

さて、塩漬けにしていた課題、PandocでMarkdownからdocxを生成した後、docxからMarkdownに再変換をする話です。

準備

ひとまずRMarkdownから生成することにします。rmarkdownでデフォルトで生成されるテンプレートからとりあえずdocxに変換して逆変換をします。keep_md:trueを指定して、Rmdから生成されたmdは下記のようになります。\ははてな上でコードブロックを書くために必要なので、手元で試すときは消してください。

---
title: "word"
author: "niszet"
date: "2020/5/20"
output: 
  word_document:
    keep_md: true
---



## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:


\```r
summary(cars)
\```

\```
##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00
\```

## Including Plots

You can also embed plots, for example:

![](word_files/figure-docx/pressure-1.png)<!-- -->

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.

この時、実行されているコマンドは下記のとおり。

"C:/Users/niszet/AppData/Local/Pandoc/pandoc" +RTS -K512m -RTS word.utf8.md --to docx --from markdown+autolink_bare_uris+tex_math_single_backslash+smart --output word.docx --highlight-style tango --lua-filter "C:/Users/niszet/Documents/R/win-library/4.0/rmarkdown/rmd/lua/pagebreak.lua" 

さて、生成されたdocxファイルに対して下記のとおり逆変換をかけます。

pandoc word.docx -t markdown -o word_rev.md -f docx+styles -s --atx-headers --wrap=none --extract-media=hoge

結果は下記のとおりになります。

---
author: niszet
date: 2020/5/20
title: word
---

## R Markdown

::: {custom-style="First Paragraph"}
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see [[http://rmarkdown.rstudio.com]{custom-style="Hyperlink"}](http://rmarkdown.rstudio.com).
:::

::: {custom-style="Body Text"}
When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
:::

::: {custom-style="Source Code"}
    summary(cars)
:::

::: {custom-style="Source Code"}
    ##      speed           dist       
    ##  Min.   : 4.0   Min.   :  2.00  
    ##  1st Qu.:12.0   1st Qu.: 26.00  
    ##  Median :15.0   Median : 36.00  
    ##  Mean   :15.4   Mean   : 42.98  
    ##  3rd Qu.:19.0   3rd Qu.: 56.00  
    ##  Max.   :25.0   Max.   :120.00
:::

## Including Plots

::: {custom-style="First Paragraph"}
You can also embed plots, for example:
:::

::: {custom-style="Body Text"}
![](hoge/media/image1.png){width="5.0526312335958in" height="4.0421052055993in"}
:::

::: {custom-style="Body Text"}
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
:::

色々課題が見えてきますね。ひとつひとつ見ていきます。まずは簡単なモノから。

--atx-headers

Markdownの章や節を示す###ですが、何も指定しない場合は「Setext-style headings」の記法で出力されます。いつもの記法にする場合は --atx-headersをつけます。Markdown Extensionではないだなぁ。あと、-t markdownではなくて-t gfmにするとATXの方になります。これはまたいつか。gfmの場合はdivとspanがhtmlタグになり、-sによるメタデータのとりこみ(後述)が抜けます(要確認)

pandoc.org

-s

-s あるいは --standalone をオプションで付けることで、メタデータ、今回はauthor、date、titleが復活します。生成したdocxを編集して保存すると内部でスタイルidが割り振られなおしますが、これの影響は受けていないようです(色々やって要確認ではあるけども)

pandoc.org

--wrap=none

どこまでもとに戻すか?は考えるべき点ですが、明示的にwrapオプションを指定しない場合は適当なところで折り返しのために改行されます。これを抑制するためには--wrap=noneの指定が必要です。diffを取って確認したい場合は必要ですが、元のmdが改行されていた場合は…?など課題がありそう(未確認)ですね。

pandoc.org

-f docx+styles

docx上で与えられているスタイルの情報を保持するためには +stylesが必須です。これについて考えていきたいです。次回以降。とりあえず思うところは「とても見づらい」ですね…。

また、気づくかと思いますが、summary(cars)については言語情報(r)が消えていて、かつ文字スタイルについては残っていないこともわかります。これは再度docxに変換した際にdocx間で差異が出ることが見て取れますね。また、下記の何も指定しない例を見ればわかる通り、コードブロックに再生されません。これはextensionのbacktick_code_blocksを与えても挙動に変化がないのでdocx Readerとしては「Source Code」スタイルはCodeBlockに割り当てないという挙動なのかもしれません。これも要確認です。

追記と訂正

上記は勘違いでした。これは、インデントされたブロックはCodeBlockになるというPandocの仕様を満たした、れっきとしたコードブロックです。

pandoc.org

これは-t native等で変換すれば確認できます(確認しました)。

ではなぜbacktick_code_blocksを与えても挙動に変化がないのか…?は次回改めて書きます。

--extract-media=hoge

デフォルトではdocxファイル中の画像ファイルが抜き出されません。--extract-media=hogeと指定すると、hogeというディレクトリの下に画像ファイル(正確にはこの中にmediaというディレクトリがつくられ、さらにその下に作られる)が作成されます。

このオプションを知っているだけでも、docxから画像ファイルを抜き出せるのは便利かもしれません。今回、Word上で特にいじっていない状態では作成時のpngファイルと抜き出したpngファイルのMD5チェックサムの値は一致したので、正しくデータが取り出せると思います。

ちなみに、上記の拡張、オプションを何も設定しない場合は下記のようになります。

pandoc word.docx -t markdown -o word_rev0.md -f docx
R Markdown
----------

This is an R Markdown document. Markdown is a simple formatting syntax
for authoring HTML, PDF, and MS Word documents. For more details on
using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that
includes both content as well as the output of any embedded R code
chunks within the document. You can embed an R code chunk like this:

    summary(cars)
    ##      speed           dist       
    ##  Min.   : 4.0   Min.   :  2.00  
    ##  1st Qu.:12.0   1st Qu.: 26.00  
    ##  Median :15.0   Median : 36.00  
    ##  Mean   :15.4   Mean   : 42.98  
    ##  3rd Qu.:19.0   3rd Qu.: 56.00  
    ##  Max.   :25.0   Max.   :120.00

Including Plots
---------------

You can also embed plots, for example:

![](media/rId23.png){width="5.0526312335958in"
height="4.0421052055993in"}

Note that the `echo = FALSE` parameter was added to the code chunk to
prevent printing of the R code that generated the plot.

さて、前途多難感がすでに出てきましたが、やっていきましょう…。