エスペラント辞書アプリをElectronで作って公開しました

エスペラント辞書アプリをElectronで作成し、リリースしました。
エスペラントto日本語の単語変換をします。とりあえずエスペラントの単語を引くことができます。
名前はlina_dictoです。
https://github.com/MichinariNukazawa/lina_dicto

なおエスペラント辞書データですが、すばらしい辞書データ が公開されており、これを使っています。
感謝。


ダウンロードはこちら。
https://github.com/MichinariNukazawa/lina_dicto/releases


本記事では辞書アプリ固有の話はしません。なぜなら今は2017年であり、辞書データをすべてメモリに置き、かつ動的言語を使って辞書データを頭から尻尾まで舐めるという超富豪コーディングをしても、ユーザ体験をまったく損ねず遅延もまったく体感しない辞書アプリケーションが作れるからです。IntelとJavaScriptエンジンのエンジニアには足を向けて寝られません。データサイズが小さかったのもあるかな。

事前に検索インデクスくらいは作る必要があるだろうと想像していたので、正直、拍子抜けの気持ちが無いといえば嘘になります。

# エスペラント固有の話

先にエスペラント固有の話をします。固有の話は2つあります。

## 語根分かち書き

語根とは、語尾の変化による現在形への変換などをされる前の単語です。詳しくはWikipedia。
特にエスペラントは、語根を組み合わせて単語を作ることで、話者の記憶リソースへの負担を軽減する設計になっています。エスペラントは語根がはっきり定義されており、なぜなら人工言語であり、そういう設計だからなのですが、単語が複数の語根から成る場合がかなりあります。詳しくはWikって略すな。
今回使用した辞書データには、単語が語根分かち書き形式で収録されています。この分割部データもいずれは有効に使いたい所存ですが、検索時は、普通のユーザがタイプするであろう分かち書きされていない単語文字列と、分かち書き済み単語データをマッチングしなければなりません。
なので、分かち書きは単純に取り除きます。
上で、動的言語で文字列のマッチング・ループなんて...って書いてありますが、実際にはもっとひどいことをしています。具体的には、分かち書き状態の単語文字列を、正規表現置換によって分かち書き除去を行っています。
(さらに踏み込むなら、大文字/小文字マッチのためのlowarCase()等、CPUリソースを暴虐無人に使っています。)
せめて起動時の、辞書データファイル読み込み・オンメモリ辞書データ生成の際にキャッシュを作っておけよという感じですが、キャッシュ管理はコードが複雑化するので避けたいというプログラマの怠惰な方針を今のところ支持しています。だって実際に問題ない速度が出てしまっていますし...。

## 代用表記

エスペラントが使用する文字には、ASCIIアルファベット以外の文字が含まれています。
具体的には下記のやつです。
``` Ĉ ĉ Ĝ ĝ Ĥ ĥ Ĵ ĵ Ŝ ŝ Ŭ ŭ Ŭ ŭ ```
現代的ブラウザなら、UTF-8かつ対応フォントで上記文字列が問題なく表示されます。

代用表記には4種類くらいあり、ぶっちゃけ初学者には"^-sistemo"(typoではない)以外はピンと来ません。ついでに言うと、他の代用表記は実装が難しいのでやりたくありません。
特に元祖本家のH-sistemoの変換ルールが最悪です。これってつまり代用表記か否かの判定に辞書が必要じゃねえかと。エスペラントはunicodeどころかコンピュータが影もカタチも存在しない時代の設計だから仕方がないねというところです。

 で、^-sistemoの実装ですが、 下記のコード。
```
str = str.replace(/C\^/g,"\u0108");
```
こういうのが12個くらい、ハードコートされて並んでいます。組み込みエンジニアは卒倒して良いと思う。
もし複数のsistemoj(?)に対応することになったら、その時ついでに書き直します。

# electronアプリの話

エスペラントに興味があって読んでくださった方は、ここから先はelectronという退屈な実装技術の話しかしないのでこの下は読まなくてよいです。実装技術に対する初心者の泥臭いトライアンドエラーで脳内物質が出てくる系の方はこんにちわ。エスペラント富豪コーディングの話は楽しんでくれましたか。

なおインストールからサンプルアプリ動作までの前半戦はこちら。
https://srad.jp/~m_nukazawa/journal/614745/

## リリースパッケージディレクトリの展開先について

リリースに使っている設定JSONファイルに書いた書き出し先パスがひとつ上になっているだけでした。そして、実はもっと深刻な問題を持っています。
設定しないと、electron-releasesはリリースディレクトリを、プロジェクトのroot的なソースパスに展開します。
そして、このディレクトリに置かれたファイルは、基本的にすべてがリリースに含まれます。
なので何も考えずに
```
node_modules/.bin/electron-packager . lina_dicto --platform=all --arch=x64
```
とかやると、初回はともかく、2回目以降はすべてのプラットフォームのリリースディレクトリ(バイナリとelectron付属物)がすべてのプラットフォームのリリースに含まれるというマトリョーシカを作ってしまいます。(私は途中で圧縮が長すぎるのに気づいてkillした)


ここらへん、本当はjavascriptのトランスパイラとかMakefileオルタネイティヴスが呼び出して使う想定で単純な作りになっていて、直接使うことはあまり考えてないとかじゃないかなぁと妄想をたくましくする次第ですが、ともかくelectron初心者なので複雑なことはしたくない一心、jQueryすら使っていないこの単純プロジェクトにそんなものを入れたくはないので、成果物はとりあえずwin版だけzipできればいいやの精神で、vecterion_vgeの成果を転用したbashスクリプトをビルド&パッケージングスクリプトとして採用した次第です。

## MacOSXビルドについて

electronのバイナリ配布物、ようは『electron共通ブラウザコア(プラットフォーム固有) + Webページ的なもの(プラットフォーム非依存)』のセットでしかないので、インターネットから降ってきたプリコンパイル済みコアさえあればxcodeが無くともLinuxであってもOSXのバイナリ配布物が用意できるという理屈は納得できるのですが、それはそれとして起動するかどうかくらいは確認しないとリリースはしたくないので、動作検証してくださる方を募集しております。

## (ブラウザの)開発者モードON/OFFについて

一応、開発者モードをユーザがONにできてしまうことについては悩んではいます。 ユーザはOFFにできないからアプリを落としてもらうしか無いなー、という程度ですが。
オープンソースだから中身を見られてもOKということで、私はデバッグモードが開ける状態でリリースしています。リリース候補のデバッグも楽です。問題無ければデバッグモードを殺す手間無しに、そのままリリースできるからです。
デバッグビルド/リリースビルドで開発者モード有効フラグを切り替えると上記の手間が発生してしまいます。
隠れショートカットで開発者モードを出せる、という方法は、万が一にユーザが隠しショーカットを押してしまったらシッチャカメッチャカになるのが目に見えています。

## Windows版インストーラについて

本当はLinux上でWindows版インストーラが作りたいのですが、必須機能ではありませんし、できるかどうか調べることもせず、vecterionで使っているスクリプトを改造して配布用zipを作りました。

# まとめ

エスペラントについて。
すばらしい辞書データ を公開してくださっていることに感謝。

Electronについて。
Webで何かやったことのある人がPCアプリケーションを作る羽目に陥ったなら、electronは良いと思います。なにしろWebKitブラウザなので、ハマった時にWeb上にQAや対処法がたくさんあります。
少なくとも私は3日程度でクロスプラットフォームPC辞書アプリが構築できたので、electronすごく良かったです。


以上です。

vecterion_vge 17.07 release works



GladeとGtkバージョン

gladeによるポトペタなGUI作成を導入したのですが、これにWindows版公式ビルド最新版より新しいバージョンのGTKが必要とのこと。

===
 debug: et_etaion_set_application_base_dir_from_execute_path()[126]: dir:'..'
critical: init_gtk_builder_()[2740]: Couldn't load document_new_dialog_builder file: ./resource/ui/document_new_dialog.glade: required gtk+ version 3.12, current version is 3.10

===


ビルド済みGTKライブラリの取得

officialの最新版は 3.10.4-20131202 までしか提供されていないので、unofficialなバイナリを使用することに。
使い勝手の問題からofficialに近いパッケージを探して、https://twitter.com/niloufarjp/ 氏の配布してくださっている配布パッケージを、下記スクリプトで全解凍&フォルダ統合済みに再パッケージ。
https://github.com/MichinariNukazawa/vecterion_vge/blob/master/deploy/win/gtk_library/gtk_library_repackage.sh

loaders.cache, libpixbufloader-svg.dll

libpixbufloader-svg.dll を使うにあたって loaders.cache が無いから gdk-pixbuf-query-loaders.exeを呼び出して作れ、と親切なエラーメッセージなのでそれに従いファイルを作成。
===
(vecterion_vge.exe:8124): GdkPixbuf-WARNING **: Cannot open pixbuf loader module file 'C:\Users\nuka\Documents\vecterion_vge-win64-17.07develop-11c2ada\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache': No such file or directory

This likely means that your installation is broken.
Try running the command
  gdk-pixbuf-query-loaders > C:\Users\nuka\Documents\vecterion_vge-win64-17.07develop-11c2ada\lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
to make things work again for the time being.
===

下の、古い設定ファイルをコピーしてきても動いたけれど、念のため生成版に置き換え。
===古い版
# GdkPixbuf Image Loader Modules file
# Automatically generated file, do not edit
# Created by gdk-pixbuf-query-loaders.exe from gdk-pixbuf-2.30.1
#
# LoaderDir = Z:\srv\win32builder\fixed_3104\build\win32/lib/gdk-pixbuf-2.0/2.10.0/loaders
#
"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll"
"svg" 2 "gdk-pixbuf" "Scalable Vector Graphics" "LGPL"
"image/svg+xml" "image/svg" "image/svg-xml" "image/vnd.adobe.svg+xml" "text/xml-svg" "image/svg+xml-compressed" ""
"svg" "svgz" "svg.gz" ""
" <svg" "*    " 100
" <!DOCTYPE svg" "*             " 100
 

 
===

===生成版
# GdkPixbuf Image Loader Modules file
# Automatically generated file, do not edit
# Created by gdk-pixbuf-query-loaders.exe from gdk-pixbuf-2.36.6
#
# LoaderDir = C:\Users\nuka\Documents\vecterion_vge-win64-17.07develop-11c2ada/lib/gdk-pixbuf-2.0/2.10.0/loaders
#
"GDK_PIXBUF_TOPLEVEL/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll"
"svg" 6 "gdk-pixbuf" "Scalable Vector Graphics" "LGPL"
"image/svg+xml" "image/svg" "image/svg-xml" "image/vnd.adobe.svg+xml" "text/xml-svg" "image/svg+xml-compressed" ""
"svg" "svgz" "svg.gz" ""
" <svg" "*    " 100
" <!DOCTYPE svg" "*             " 100
 

===

足りないアイコンファイルの追加

===
 (vecterion_vge.exe:8156): Gtk-WARNING **: Could not find the icon 'window-minimize-symbolic-ltr'. The 'hicolor' theme
was not found either, perhaps you need to install it.
You can get a copy from:
    http://icon-theme.freedesktop.org/releases

===
===
(vecterion_vge.exe:8156): Gtk-WARNING **: Could not load a pixbuf from /org/gtk/libgtk/icons/16x16/status/image-missing.png.
This may indicate that pixbuf loaders or the mime database could not be found. 

===

今回の場合、 https://github.com/Beep6581/RawTherapee/issues/3046 に書いてあるキャッシュの更新はしなくても、上記警告まではとりあえず解決して消える。

===
(vecterion_vge.exe:6744): Gtk-WARNING **: Could not load a pixbuf from icon theme.
This may indicate that pixbuf loaders or the mime database could not be found.
**

===

===
**
Gtk:ERROR:gtkiconhelper.c:493:ensure_surface_for_gicon: assertion failed: (destination)
===

share/icons 以下のアイコンファイルが足りないだけなので、これをすべて配布パッケージに追加。

CSS font: monotype; の警告

===
(vecterion_vge.exe:3652): Gtk-WARNING **: Theme parsing error: <data>:23:9: not a number

(vecterion_vge.exe:3652): Gtk-WARNING **: Theme parsing error: <data>:23:18: Using Pango syntax for the font: style property is deprecated; please use CSS syntax
===
CSS syntaxに合わせろとのことなので、font-familyに書き換えて解決。
===
 626 >------->------->-------"GtkStatusbar {\n"¬
 627 >------->------->-------"   font-family: monospace;\n"¬
 628 >------->------->-------"}\n"¬

===


CSS 'px'の警告


===
(vecterion_vge.exe:3652): Gtk-WARNING **: Theme parsing error: <data>:20:16: Not using units is deprecated. Assuming 'px'.
===

単位のつけ忘れだった。

===
 629 >------->------->-------"GtkTextView {\n"¬
 630 >------->------->-------"   font-family: monospace;\n"¬
 631 >------->------->-------"   font-size: 12px;\n"¬
 632 >------->------->-------"}\n"¬

===

.glade ダイアログ -rdynamic の警告

 .gladeファイルによるUIを使用していると出る。
===
(vecterion_vge.exe:7444): Gtk-WARNING **: Could not find signal handler 'cb_clicked_button_cancel_'.  Did you compile with -rdynamic?

(vecterion_vge.exe:7444): Gtk-WARNING **: Could not find signal handler 'cb_clicked_button_ok_'.  Did you compile with -rdynamic?

===
.gladeファイル読み込みの際に、 gtk_builder_connect_signals(); を呼んでいたが、OK,Cancelボタンの標準的なコールバック(gtk_dialog_run()から戻り値でACCEPT/その他が返ってくる)には必要なかったので、これを除去すると消えた。

ビルドオプションは今は追う必要がないので、追っていない。以下はメモ。
警告メッセージは `-dynamic`を付けろと言っているが、 実際は` -Wl,--export-dynamic`かもしれない。
ただし、これも、Windows版(mingw)では以下の警告が出た。
===
/usr/bin/x86_64-w64-mingw32-ld: warning: --export-dynamic is not supported for PE+ targets, did you mean --export-all-symbols?
===

gtk_file_chooser_dialog 呼び出し時のクラッシュ

gschemas.compiled が必要だった模様。



dev版パッケージの内で、下記のような感じでコマンドを実行すると生成することができる。
(たぶん、 環境変数 GSETTINGS_SCHEMA_DIR の指定はいらない。)
```
bin\glib-compile-schemas.exe share\glib-2.0\schemas 
```
同じパスに、この gschemas.compiled ファイルを配置すると解決。

Centaring GtkScrolledWindow

GtkScrolledWindowのスクロール位置をアプリケーション側から変更して中央寄せするコードです。



===
 static void et_scrolled_window_centering_(GtkScrolledWindow *scrolled_window)
{
    {
        GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment (scrolled_window);
        double v = (gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj)) / 2.0;
        gtk_adjustment_set_value (vadj, v);
    }

    {
        GtkAdjustment *hadj = gtk_scrolled_window_get_hadjustment (scrolled_window);
        double h = (gtk_adjustment_get_upper(hadj) - gtk_adjustment_get_page_size(hadj)) / 2.0;
        gtk_adjustment_set_value (hadj, h);
    }
}

===

問題はこのスクロール位置指定の実行タイミングで、スクロール位置を変更するにはScrolledWindowの中でスクロールされる内側Widgetが再描画済みでサイズが確定していなければならないのですが、Widgetコールバックの設計によっては、スクロール位置の変更コードを呼び出すタイミングがその内側Widgetの再描画コールバック("draw"イベント)内しかない場合があって。
仕方がないので最初の再描画コールバック内でフラグをカウントアップして"draw"イベントを再度コールするようにしたのですが、作成中のアプリケーションはそうしなくても都合により外部からすぐ再描画コールバックが呼ばれるので、これで本当に正しいのか正直不明です。

===

 
static gboolean _cb_expose_event (GtkWidget *widget, cairo_t *cr, gpointer data)
{

(中略)

        switch(self->centering_control){
            case 0:
                self->centering_control++;
                // kick to re draw event, because only need centering.
                gtk_widget_queue_draw(self->canvas);
                break;
            case 1:
                self->centering_control++;
                debug_print_adjustment_(self);
                et_scrolled_window_centering_(GTK_SCROLLED_WINDOW(self->scroll));
                break;
            default:
                break;
        }
    }


    return FALSE;
}

===

以上です。

Install Android Studio 2.3.1 to Ubuntu16.04LTS

今回特に、エラーメッセージをメモしていないので、これは記憶で書いているメモです。







基本的には公式サイトに書いてある手順でOKです。
ただ、事前に32bitライブラリをインストールする指示がありますが、それらのパッケージはかなり前のUbuntuから廃止されているようで、かつ、無くてもInstallおよび実行できました。




インストール中、アドオンのProxyが設定されていない(だったか)旨のエラーが出ますが、Cancelすればインストールが続行します。
インストール中、わたしのマシンではブラウザのインターネット接続が切れました。インストーラがパッケージをダウンロードしてくるので、その時に帯域を使い切る等があったのかもしれません。
また、インストール中にパッケージが見つからなかった的な旨のメッセージが出ましたが、 これは2回ほどRetryを選択したところ、続行できました。ネットワークの問題かと思われます。

Android公式のチュートリアルにまあまあ従って(Android6.0ターゲットに変更。ユーザカバー率が10%を切ると表示されていてすごい。)プロジェクトを作ると、 エラーメッセージ。




http://amaebi.jp/?p=318
に従い、Proxy設定をAuto-Detectにして、いったんプロジェクトを閉じ、再度開いたところ、幾つもエラーは出るものの、進行はしました。

一覧にそれらしき端末は出るし(とはいえudev設定する前から出ていた)、ビルド成功のメッセージは出てエラーは出ないものの、そこから先、アプリケーションが実機で実行されない。

http://kntmr.hatenablog.com/entry/2015/12/02/113533
を参考にUSB接続をMTPにすると、「USBデバッグを許可しますか?」というダイアログと共に、公式ドキュメントのフィンガープリントの許可ダイアログが出ました。
わたしのLTE/Blade V7 Liteでは、「充電のみ」モードではUSBデバッグが出ませんでした。

認識されるようになると、名前が「null」ではなく、きちんとデバイス名が表示される。





一度目はAndroid23SDKが無いとかで失敗しますが、再度Runすると、これが自動でインストールされます。

で、何度か繰り返したら実機にアプリケーションが表示されました。

雑感

- 必要になった都度インストールがあって、新しことをする度に待ち時間がありそう。
- IDEからWebのドキュメントへ飛ぶリンクが多数あるので、都度インストールと合わせて、インターネット必須。
- インストール・ネットワーク関連は、再度実行すると上手く行くこと多し。ネットワーク周り、不安定すぎやしないか。

以上です。

ComfyUIでXYZ-PlotするワークフローのサンプルとTips(ComfyUI-XYZ-Stitch)

 ComfyUIでAutomatic1111的なXY-Plotをしたいのだが、ComfyUIデフォルト機能には用意されていない。     カスタムノードが必要となるのだが、Webには古いとか何故か動かないとかなXY-Plotパッケージの使ってみた系記事か、githubに上げられた...