Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

テキスト形式のEPSを出力する機能 #52

Closed
doraTeX opened this issue Oct 16, 2015 · 37 comments
Closed

テキスト形式のEPSを出力する機能 #52

doraTeX opened this issue Oct 16, 2015 · 37 comments

Comments

@doraTeX
Copy link
Owner

doraTeX commented Oct 16, 2015

テキスト形式のEPSでなければ問題が起こるケースに対処するために,eps2write デバイスによってEPS出力する場合に,pdftops を用いてテキスト形式のEPSに変換する機能を付けるとよいのでは。

仕様案

  • TeX2img.app 内に pdftops とその依存ライブラリ(サイズは全2.6MB)を抱え込む。
  • GUIに「テキスト形式で出力する (EPS)」というオプションを追加。
  • CUI版には --[no-]plain-text あるいは --[no-]text-format といった名前のオプションを追加する。
  • CUI版利用時は,mudraw 同様に,既に pdftops がインストールされていればそれを,インストールされていなければGUI版同梱の pdftops をサーチして用いる。

変換経路

EPS出力かつ gs>=9.15 かつこのオプションがONの場合には,次の変換経路で変換する。

TeX (→ DVI ) → PDF →[gs(eps2write)でアウトライン化+クロップ] → EPS →[epstopdf(gs)]→ PDF →[pdftops] → EPS (→[BB情報を編集して余白付与] → EPS)

pdftops のオプション

pdftops -eps in.pdf out.eps
@aminophen
Copy link

そういえばそんな調査していました… まだ pdftops が本当にテキスト形式の EPS しか出さないのかどうか自信がありませんので、もう少し検証させてください。

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 17, 2015

少し試してみたところ,gsでビットマップ化されてしまう🍣の例「理」の例もテキスト化されていたので,常にテキスト形式で出力できるものと考えてよさそうです。
そちらでもぜひ色々な例で検証してみてください。

@aminophen
Copy link

気になる点を挙げておくと:

  • 「テキスト形式の EPS を出力」という表現から「(PDF のように)テキストを保持した EPS だろうか」という誤解が生じないように配慮する必要があります。EPS の中身がバイナリかテキストかということを意識しているユーザは少ないはずですので、選択させるメリットはあるのだろうか(一方に固定するか、あるいは高度なオプションとして隠すかでも良いのでは)とも思います。
  • eps2write で吐いた EPS と、その後 epstopdf → pdftops を経た EPS では HiRes の桁数や原点の位置が違います。

たとえば元の eps2write が出した EPS が

%%BoundingBox: 289 104 523 758
%%HiResBoundingBox: 289.983991 104.781997 522.031984 757.903977

の場合、そこから epstopdf と pdftops を経た EPS では

%%BoundingBox: 0 0 233 654
%%HiResBoundingBox: 0 0 232.05 653.12

という値になりました。どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。この影響がどの程度生じるのか、まだわかっていません。

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 17, 2015

「テキスト形式の EPS を出力」という表現から「(PDF のように)テキストを保持した EPS だろうか」という誤解が生じないように配慮する必要があります。

それはUIの表現次第で何とかなるのではないでしょうか。
プレーンテキストで出力する (EPS)」(英語版:Output as plain text (EPS) とかはいかがでしょう。

EPS の中身がバイナリかテキストかということを意識しているユーザは少ないはずですので、選択させるメリットはあるのだろうか(一方に固定するか、あるいは高度なオプションとして隠すかでも良いのでは)

  • バイナリEPSに固定すると,テキストEPSが要求されるケースで困る。
  • テキストEPSに固定すると,「GUI版TeXimg も pdftops もインストールされていない状況下ではCUI版TeX2imgでのEPS出力が利用できない」となってしまう。

という問題が生じます。
(後者の場合,自動的にバイナリEPS出力にフォールバックさせるという手もありますが。)

どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。

確かにBBの原点の変化はちょっと怖いですね。
#37 のような例についても検証が必要です。
余白付与については,pdftops 後に実行するようにしておけば問題ないでしょうね。

@aminophen
Copy link

「プレーンテキストで出力する (EPS)」なら伝わりそうです。いずれにせよその意義を FAQ に書いておかないと、Forum の質問のような場合に気づいてもらえない可能性が高いですね。(「○○というソフトで EPS を作ったら貼りつくのに TeX2img で作ったら貼りつかない」というときに、「EPS は PostScript 言語で書かれたテキストだったはずだ」という知識がないと「EPS の中身に違いがあるのでは」のような発想にそもそも至らないので)

BB の変化についてはもう少し慎重に調べる必要がありますね。従来の EPS に epstopdf + pdftops を通すと余白の付き方が微妙に変わってしまうことは確認できました。

EPS の左下が epstopdf + pdftops では常に 0 0 なので、ここに余白を付けると必ず BB がマイナスになる…けれど従来の場合も余白が大きければマイナスになりえたので同じですかね?

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 17, 2015

どうやら epstopdf + pdftops 全体としては「元の EPS の HiRes の値を演算して左下が 0 0 になるように描画しなおし、新しい HiRes を小数点以下2桁まで求め、それを包含するように非 HiRes の値も書き込む」ように見えます。この影響がどの程度生じるのか、まだわかっていません。

これは,epstopdf でPDFに直したときに,PDFのMediaBoxの左下が(0,0)になるようにボックスが再調整されるためにおこるもので,pdftops はそれを引き継いでいるに過ぎないようです。

@aminophen
Copy link

これは,epstopdf でPDFに直したときに,PDFのMediaBoxの左下が(0,0)になるようにボックスが再調整されるためにおこるもので,pdftops はそれを引き継いでいるに過ぎないようです。

ということは、BB の値が変わることは問題なさそうですね。

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 18, 2015

余白付与については,pdftops 後に実行するようにしておけば問題ないでしょうね。

余白付与と pdftops の順序を逆にしました。
この方が,余白付与後の epstopdf + pdftops コンボによってBBの原点が (0,0) にリセットされるので,最終生成物に負のBB値が出てこなくて済みます。

それに何より,epstopdf はゼロサイズのEPSに弱いという問題に対する対処という点が挙げられます。
「EPSを epstopdf + pdftops でプレーンテキスト化する」という処理を行うとき,余白付与によって最終的に白紙ページになるはずのゼロサイズのEPSをこの経路にかけるとエラーになってしまいます。事前に余白付与を済ませておけばゼロサイズでなくなるのでこの問題が回避できます。

整理すると,経路は以下の7通りとなります。

gsを通さない経路

  1. 速度優先モードでのビットマップ生成 (PDF →[pdfcrop類似処理でクロップ]→ PDF →[Quartz API でビットマップ化+余白付与]→ JPEG/PNG/GIF/TIFF/BMP)
  2. テキスト情報を残したPDF生成 (PDF →[pdfcrop類似処理でクロップ+余白付与]→ PDF)
  3. テキスト情報を残したSVG生成 (PDF →[pdfcrop類似処理でクロップ+余白付与]→ PDF →[mudraw]→ SVG)

gsを通す経路

  1. 画質優先モードでのビットマップ生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ]→ EPS →[epstopdf(gs)]→ PDF →[Quartz API でビットマップ化+余白付与]→ JEPG/PNG/GIF/TIFF/BMP)
  2. アウトライン化PDF生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[epstopdf(gs)]→ PDF →[pdfcrop類似処理で余白付与]→ PDF)
  3. アウトライン化EPS(バイナリ形式)生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[BB情報を編集して余白付与] → EPS)
  4. アウトライン化EPS(テキスト形式)生成 (PDF →[gs(eps(2)write)でアウトライン化[*1]+クロップ] → EPS →[BB情報を編集して余白付与] → EPS →[epstopdf(gs)]→ PDF →[pdftops])

[*1] このgsによるアウトライン化は,画質優先モードの場合は -r20016 固定,速度優先モードの場合は解像度レベル設定に従う

doraTeX added a commit that referenced this issue Oct 18, 2015
@doraTeX
Copy link
Owner Author

doraTeX commented Oct 18, 2015

Ver. 2.0.6 beta 1 が完成しました。

Ver. 2.0.6 beta 1 での改良点

@aminophen
Copy link

Ver. 2.0.6 beta 1 の TeX2img.app が正しく梱包されていない…?

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 19, 2015

確かにアーカイブが壊れていましたので差し替えました

@aminophen
Copy link

「gs9.15 以上の eps2write 経由時に、Xpdf の pdftops を使ってテキスト形式の EPS を出力する」は成功しているようです。

「あいうえお」を EPS 化していて気づいたのですが、eps2write は epswrite に比べて書き込む量が膨大に増えていて、それを隠すためにバイナリ化圧縮しているようですね。pdftops でそれをプレーンテキストにするとかなり量が減るので、バイナリより軽くなっています。サイズとしては「gs9.14 以前の epswrite < Xpdf の pdftops < gs9.15 以降の eps2write」になる傾向があります。

@aminophen
Copy link

#54, #55 のバグも直っていました。いままで全然気づきませんでした…

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 19, 2015

eps2write は epswrite に比べて書き込む量が膨大に増えていて、それを隠すためにバイナリ化圧縮しているようですね。pdftops でそれをプレーンテキストにするとかなり量が減るので、バイナリより軽くなっています。サイズとしては「gs9.14 以前の epswrite < Xpdf の pdftops < gs9.15 以降の eps2write」になる傾向があります。

つくづく,なぜ epswrite を廃止する必要があったのかと残念に思います……。

@doraTeX doraTeX closed this as completed Oct 19, 2015
@abenori
Copy link

abenori commented Oct 19, 2015

Ghostscriptで何とかならないかと,なんとなくググってみたら,気になるものを見つけました.
http://d.hatena.ne.jp/yshl/20070515/1179199949
全然わからないので使えるかさっぱりですが……

@aminophen
Copy link

Ghostscriptで何とかならないかと,なんとなくググってみたら,気になるものを見つけました.

/LZWDecode をデコードできないと書いてあるようで、ちょっと厳しそうです… gs9.05 の epswrite が吐いたプレーンテキストな EPS を食わせると「コメント行以外をそっくりそのまま stdout に吐く」ことはわかったのですが

  • 懸案の gs9.16 の eps2write のバイナリ EPS(最初に currentfile /ASCII85Decode filter /LZWDecode filter がある)を食わせるとバイナリの始まりをバイナリと認識できず /syntax error になる
  • 昔調べた -dCompressPages=false を付けて一部のバイナリをほどいた EPS を食わせると Error: /undefined in this とかいうよくわからないエラーが出る

ようです… まあ 2007 年のスクリプトだから無理はないですが、もっと調べるとスクリプトで Decode する方法があるのかもしれません。

@abenori
Copy link

abenori commented Oct 20, 2015

そもそもだめなのはLZWそのものなんですね……
# 一応全部テキストなepsをWordに食わせても読めないと悩んでいました……

WordはPostScript 3.0(とそれ以前)をサポートしているようですが,LZWが入れられるようになったのはその後,という理解でいいんでしょうか?それとpdftopsがLZWを入れないかどうかはよくわからない(一応なっているみたいだが)ということでOK?

@aminophen
Copy link

pdftops が LZW を入れないかどうかはソースを見れば分かるかもしれません😏

Windows の場合は pdftops が TeX Live (win32) でも W32TeX でも入っていると仮定してよいはずですので、直接これを呼べば良いでしょうね。

@abenori
Copy link

abenori commented Oct 20, 2015

正直なんかやる気が出ないです.なんか繰り返しもありますが.

  • Wordでだめな理由が僕には見つかっていない
  • だめな理由が「LZWがだめ」としてpdftopsがLZWを入れないかわかっていない.(まさか本当にソースを読めといっているわけではないと思いますが…….しかもソースは「説明書」じゃないし.)
  • 「LZWを入れない」というのと「テキスト出力」とは同値ではない.
  • W32TeX / TeXLiveともにpdftopsにはインストール作業が必要

@aminophen
Copy link

「LZWを入れない」というのと「テキスト出力」とは同値ではない.

まさにおっしゃるとおりです。フォーラムに「LZW バイナリがあるから」と回答したのは“無難な正解”で、LZW が原因なのかバイナリが原因なのか当時よくわかっていなかったのです。今も私は手元で「LZW もバイナリも存在しない EPS」と「LZW もバイナリもともに存在する EPS」しか試していないため、はっきりしたことはわかっていません(数か月前の検証段階で pdftops を結論とするのは短絡的だと思ったのもこれが理由だった気がする)。ただ、pdftops がテキスト形式の読める EPS を出すのは確かなので、Mac 版にとりあえずその機能を付けたのは悪くないと思っています。

まだ分かっていない多い状態ですので、もう少し慎重に調べてみます。

@abenori
Copy link

abenori commented Oct 20, 2015

何かわかったらよろしくお願いします……が,いずれにせよインストール作業が必要なものを使うのは気が引けます.

pdftops がテキスト形式の読める EPS を出すのは確か

そういう例しか観測されていない,が正しい?(「説明書」にあるのかという質問です.)

@aminophen
Copy link

そういう例しか観測されていない,が正しい?

はい。説明書にその手のコメントがないので例で観測するほかなく、そういうことになっています。

…といったところで、doraTeX さんの実験で登場した sushi.pdf を試したところ、gs9.16 の場合のみバイナリが入っています。~~これは手元では Word 2010 に貼りつけることに成功していません…~~訂正:かなり動作が重いだけで、貼り付けはできていました。Windows 版 TeX2img で「アウトライン化 PDF」を出力した後、pdftops で変換するという実験を行うと

  • 「gs9.10 の epswrite + pdfwrite」のあと「pdftops」で作った EPS : Word 貼り付け成功
  • 「gs9.16 の eps2write + pdfwrite」のあと「pdftops」で作った EPS : Word 貼り付け~~失敗(このイメージは現在表示できません)~~成功

とりあえずここに置きます。

gs9.16 のあとに pdftops が吐いた EPS は「LZW はないが、バイナリはある」っぽいです。ということは、LZW があることが Office 貼り付け不能の原因なのかもしれません。

追記:「gs9.16 の eps2write + pdfwrite のあと pdftops を通した EPS」は、Word への貼り付けと表示は成功しましたが、保存時に PDF 形式を指定すると PDF には図が出てきませんでした。

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 20, 2015

「LZW はないが、バイナリはある」

equation-916.eps は,モノとしてはテキストファイルに見えますが。

ちなみに,Mac版Wordでは,epsが貼り付けられると内部的にPDFへ変換してから貼り付けているように見えます。そのため,gs 9.16 の eps2write で出力したEPSも貼り付け可能です。
ですから,今回増設した「プレーンテキストEPS出力」機能は,Mac版では特に目に見えるメリットはありません。EPSがプレーンテキストである方が何かと扱いやすい場面もあるだろうと思って付けました。(テキストエディタで中身を簡単に覗ける安心感とか……)

@aminophen
Copy link

equation-916.eps をテキストエディタである Emacs で開いているのですが、一万行目付近にテキストとは思えないものが多発しますが…

equation-916-emacs

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 20, 2015

そのあたりも一応ASCII文字っぽいですよ。

2015-10-20 23 44 58

↑ A → U+0041

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 20, 2015

この部分は,PostScript Language Reference の3.2.2節に規定された ASCII base-85 filterに従ってバイナリをテキストへエンコードした部分で,3.13.3節に規定された ASCII85Decode filter でこれをバイナリにデコードする処理が equation-916.eps の457行目に /ASCII85Decode filter として書かれていますね。

参考:PostScript言語 / ファイルとフィルタ

@doraTeX doraTeX reopened this Oct 20, 2015
@aminophen
Copy link

この部分は,PostScript Language Reference の3.2.2節に規定された ASCII base-85 filterに従ってバイナリをテキストへエンコードした部分で

ああ、本当ですね。だいぶ上の方に /ASCII85Decode filter とあるのも見落としていました。こういうのだったら Windows の Office でも解釈できるのですね。

@aminophen
Copy link

…ということは、gs9.16 の eps2write で「LZW バイナリ」と呼んでいたものは
/ASCII85Decode filter /LZWDecode filter
とあることを加味すると、正確には「LZW バイナリを ASCII base-85 filter に従ってテキストへエンコードした部分」ということですね(ということは結局これもテキスト…?)。

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 20, 2015

その部分はテキストですが,その後に,/ASCII85Decode filter を伴わない /Filter/LZWDecode が現れ,本物のバイナリが登場し始めます。よって,eps2write を通したものは,EPSファイル全体としてはバイナリファイルとなっています。

2015-10-21 0 12 17

↑sushi.pdf を eps2write で処理した結果のeps

@aminophen
Copy link

その後に, /ASCII85Decode filter を伴わない /Filter/LZWDecode が現れ,本物のバイナリが登場し始めます。

ああ、そこはまさに -dCompressPages=false をもってしても decode できなかった部分です。/ASCII85Decode された /LZWDecode の部分は -dCompressPages=false を使えば圧縮されないのですが、その後に来る“本物のバイナリ”を gs のみで Decode する方法をいまだに見いだせていないのです。

@abenori
Copy link

abenori commented Oct 20, 2015

そのため,gs 9.16 の eps2write で出力したEPSも貼り付け可能です。

Macずるい…….

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが,Windowsの方はWordに張り込めるのをやはり目的とした方がよいですよね…….

現れた/LZWDecodeをすべてデコードしたものに置き換える,というのはさすがに面倒だろうか.

@doraTeX
Copy link
Owner Author

doraTeX commented Oct 20, 2015

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが,

そんなオプションがありましたか……!

まあ,-dASCII85EncodePages=true で出力したテキストEPSは,「実質全体が ASCII base-85 でエンコードされた意味不明な文字列からなるテキスト」になるのに対し,pdftops で出力したテキストEPSは「読めるテキスト」になるという違いがありますので,Mac版に pdftops を内蔵した意義は一応あったということにしておきましょう。
(sushi.pdf の場合は,埋め込み画像の部分があるので pdftops した後にも ASCII85 の部分が現れますが,普通の文字だけの書類を pdftops にかけた場合,ASCII85 部を含まない「完全に読める」EPSを出力してくれるようです。)

@abenori
Copy link

abenori commented Oct 20, 2015

上で出ている-dCompressionPage=falseと組み合わせるとかなりの部分がEncodeされていないファイルにはなるのですが,なんだか長ったらしくてよくわかりません……上でも話になっていましたが,pdftopsで出した方が素直には見えますね.(といってもEPSを読もうとする変態がどのくらいいるかは謎ですが…….)

eps2writeがはき出したファイルはPDFみたいです.

@abenori
Copy link

abenori commented Oct 20, 2015

ふとGhostscriptを9.18にあげてみたら,次のtest_gs.epsができました.どうも見たところLZW圧縮はないように見えますが,やはりWordへははりこめません.

https://onedrive.live.com/redir?resid=4FABCB4EC4FA1E70!16825&authkey=!ANYoMX5Yq7PLXU4&ithint=folder%2cexe

@aminophen
Copy link

テキストにしたいだけならば-dASCII85EncodePages=trueでエンコードしてしまえばよいのですが

それも昔試した記憶が… でもバイナリをエンコードしたにすぎないので読めないと判断し、やめたと思います。フィルタに関係ありそうなオプションは私なりにいったんは試したような状態です。

ふとGhostscriptを9.18にあげてみたら

私も gs9.19 git prerelease をたまたま数日前に Windows で git clone していたので試したところ、-dCompressPages=false の有無によらず「ほぼ」圧縮なしの EPS になりました(最後の方にちょっとだけ意味不明な文字列がある)。LZW はないようですが、やはり Word へはりこめませんね。

評判が悪くてデフォルトを -dCompressPages=true ではなく false に変更したのだろうか。

@abenori
Copy link

abenori commented Oct 21, 2015

ともかく小手先ではWordには対応させられなさそうなので,この件は忘れることにします.ご迷惑をおかけしました.

@aminophen
Copy link

そろそろ「TeX2img でどの画像まで対応するか」をはっきりさせたほうがよいということですね。依存ツールを抱え込むのも、mudraw くらいなら軽いですし Win 版の pdfiumdraw は他で難しい EMF のための需要があるのであって欲しいですが、これ以上増やすのはあまり乗り気がしないです。万能神話はあくまで神話ですし、私もそれは求めていません。

pdftops も結局どんな場合でもプレーンテキストを出せる保証がないので、どうなんでしょうかね。「テキスト形式の EPS が必要なら、pdftops をインストールすればできるかもしれません」程度の情報を FAQ に書いておくほうが無理がないのかもしれません。依存ツールが増えないならまだしも、「増やしても完全なテキストになるとは保証できない」だとモチベーションが起きないのもわかります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants