トップ 追記

日々の破片

Subscribe with livedoor Reader
著作一覧

2018-09-11

_ TinyMCEの使い方

SimpleMDEをしばらく使っていたが色を付けたいというような要望があって、そりゃマークダウンにはないし、かといって直接spanを書かせるわけにもいかないし、というわけでいろいろWYSIWYG系のブラウザ用エディターを調べて、結局TinyMCEに落ち着いた。

が、ドキュメントがいまいちわかりにくくて、どのプラグインが追加有償なのかといったこともなかなかわかりにくい。でも、まあ、そのあたりは解決して(一番使いたいのはTextColorでこれはデフォルトプラグインだし、次に使いたいのはTableで、これもデフォルトプラグインだった)が、一番の問題点は、入力されたデータをどう扱えるか、だった。

それ以外の使い方はなんかおかしなドキュメント(懇切丁寧だが、同じことを何度も何度も繰り返して書いてあるコピペプログラミングみたいな感じ)に書いてあるし、日本語でもうすこしまともに整理してくれてあるサイトもある(今ググってみつけた)。

知りたいのに素直にわからないのは次の2点だ。

  • データの取り出しと設定
  • 変化の検知

前者は、AJAXでサーバーへ送信したり、保存したデータをサーバーで初期設定するときに必要だし、後者はサーバーへ送信するタイミングを得るために必須だ。

TinyMCE自身はtinymce.init({selector: '#ID'(とか.parent .classとか)})と、ラップするtextareaのセレクタを与えればすぐに使えるすぐれものではあるが、ドキュメントにはtextareaをフォームに入れればsubmitされるからOKみたいにしか書いてない。でも待て。ユーザーが長い文章を入力して一息つこうとした瞬間にWordはクラッシュしブラウザーはハングしたりクラッシュする。だから、Submitを待ってはならない道理だ。最初は単純に$('#textarea').val()とすれば取り出せるのではないかと思ったが、ラップさせるTEXTAREAそのものは本当に単なるダミーとしてしか利用していないらしくて入力はまったく反映されない(逆方向はサポートしていてTEXTAREAにあらかじめ設定した内容は初期値としてロードされる)。

あと、動的に作るのは新たにDOMに追加したtextareaをtinymce.iniに与えれば良いからOKとして、削除はどうするんだ? とかも知りたいところ。で、そのあたりのJS用のAPIがいまひとつわかりにくかったので以下にまとめる。

TinyMCEのエディタオブジェクトの取得方法

  • tinymce.initで指定できるinit_instance_callbackの引数で与えられたオブジェクトを使う
      tinymce.init({selector: '#textarea', 
                    init_instance_callback: (editor) => {
                       texteditor = editor; // 後で使う
                     }
                    })
    
  • IDをtinymceに与えて取得する。
      let editor = tinymce.get('textarea'); // セレクタではなくIDなので#を付けてはだめ。はまった。
    
  • tinymce.editors配列から探す。

エディタオブジェクトの破壊方法(textareaの破壊前に行う。そうでないとおかしなことが起きる)

  • IDを指定する。
     tinymce.remove('#textarea'); // getと違ってこちらはセレクタとしてIDを指定する
      
  • tinymce.removeにエディタのインスタンスを直接与える
     let editor = tinymce.get('textarea');
     tinymce.remove(editor);  // この例は意味ない
     

入力内容の取り出し

DOMとして取得できるが、ここではサーバーへ送信したりするための方法なので文字列(つまりパーシャルHTML)の取得方法。

  let html = tinymce.get('textarea').getContent();  // これで<p>入力したよ。</p>みたいなのが取得できる。

内容設定

  • textareaにあらかじめgetContent()で取り出したパーシャルHTMLを埋め込む。
  • エディタのsetContent(パーシャルHTML)メソッドを呼ぶ。

ここまでわかると、後は、取り出しタイミングさえ得られればAJAXでサーバーへ入力内容を随時送信できる。

取り出しタイミングは、サーバーとの通信が遅ければblur一択だろうが、そうでなければ、エディターのchangeイベント(エディターがアンドゥポイント生成後に発火)、undoイベント(ユーザーがアンドゥを呼んだ後に発火)、redoイベント(ユーザーがリドゥした後に発火)の3イベントを見張るのが良いと思う。

どのイベントでも同じサーバーへの内容送信を行うのだから、tinymce.initの引数で与えれば良い。

tinymce.init({selector: 'textarea',
              init_instance_callback: (editor) => {
                editor.on('change', (e) => {  // ドキュメントではChangeのように大文字始まりで書いてあるが、小文字始まりでOK。大文字始まりでどうかは試していない。以下同様。
                  sendContent(editor.getContent()); // sendContentは自前の送信メソッド
                });
                editor.on('undo', (e) => {
                  sendContent(editor.getContent());
                });
                editor.on('redo', (e) => {
                  sendContent(editor.getContent());
                });
               }
              });

2018-09-09

_ ドイツマイスターの眼鏡を購入

数年前からキラー通りを歩く都度、木のフレームというものを飾っている眼鏡屋が気になって気になってしかたがなかった。

それで、使っていた眼鏡のレンズが相当はげて汚れてきたのもあって、そこで眼鏡を作ろうと思い立った。とはいっても値段が全然見当がつかない。木という素材はそこら中にあるけれど、木の眼鏡フレームがそこら中に売っているわけではないから大量生産とは思えない。ということは相当価格は高そうだ。というわけで、一応予算は10万とレンズで12~3万くらいかなぁ、高いけどまあいいや、とあたりをつけて出かけたのが先々週。

店入ると誰もいないからショーケースを見たら、ぱっと見で木のフレームは20万とかする。予算の2倍じゃん。とびびったが、5年使えば年4万、月当たりで4000円弱、なんだ通信費よりも安いじゃん、と腹を括ったところに店員が出てきた。ら、いきなり予約か? と聞かれるが、眼鏡屋さんで予約が必要だなんて考えてもいなかったのでもちろんフリだ。

暑くて客が誰もいないから問題ないということで、最初に、検眼しろと言われる。もちろんそのつもりだったので検眼が始まるのだが、やたらたくさん検査があって驚いた。

最初に趣味を聞かれて、なんだそれ? と思ったら、要するに眼鏡で何を見るかのユースケースを知るためだったと後でわかったが、なるほど、そういうことか。

アルファベットが5つ並べたのを片目ずつというのはわかるが、分度器みたいなのが出て来ておそらく乱視系の検査も入る。驚いたのは右目では120度あたりの軸の数値が朧状というか鱗上で読めないことだ。鱗状に見える部分があって、伊賀の影丸かなにかで徐々に姿が消えていくような見た目なのだ。

なんか左上のほうの数字が読めないと言うと、それが右目の視野欠落だ(があるというのは説明済み)でしょ? と言われる。続けて眼鏡屋さんは、それが中心にある人もいるんですよ、と慰めなんだかなんだかよくわからないことを言うが、そうか、視野の欠落というのはこういうことなのか。と人体の不思議に感動した。

それにしても眼科では明滅する点の分布で調べるので、このような形で欠落が視覚化されるとは思わなかった。というか、影になっているのだろうくらいにしか考えていなかったのだが(日常生活では左目が勝手に見て脳内で合成するし、そこを見たいときは視線がそこへ動くので欠落部そのもので意識的に何かを見ることはできない)鱗状に見えるのか。おもしろい。

さらに検査が続く。右目で縦棒、左目で横棒(逆かも知れないけど)の十字が十字に見えるか? というのをやって、全然ずれていることがわかった。

なるほど、確かにオペラを見ると舞台にドッペルゲンガーが見えるのはこういう原理かと感心するが、それを直すのが眼鏡屋の使命だから、無理に焦点を合わせずに自然に見て十字が中央で交差するように、と説明されながらレンズを変えて調整していく。へー、なるほど。

なんだかんだで1時間以上検査をして、さてフレームの選択になる。

もう腹を括っているので木のやつ一択だ。

それでもいくつか種類があって、色が黒と茶と灰色で灰色がお勧めとか言われる。黒も渋いかなと思ったがあまりおもしろくない(悪くはない)ので、お勧めの灰色を選んだ。さらに四角いのや楕円のがあるが、今使っているのが四角なので楕円にしてみた。

レンズもこれまで購入していたのと3倍くらい違ってここでもびびったが、もう開き直っているのでOK。むしろ先払いすると、ここまで客がいないと(予約入ってなかったのか、誰も客が来ないのでおれの貸し切り状態)夜逃げされたら怖いなとか考えるが、クレジットだから引き落とし前に物を受け取れそうだしまあどうにかなるだろうとサインする。

で、できあがったのをかけて、おお、確かに木だ。ちょっとざらつく触感がおもしろい。意外と弾力性があるな、とか、鼻当ての部分は木だからプラスティックと違って溶けなさそうで良いな、とかいろいろ考えながら、家に帰ってから屋上で横になってオリーブの木を眺めていたら、すごく違和感がある。

妙に立体感があるのだ。ふと、遠くのクレーンを眺めるといつもは2つ見えるランプが1つに見える。わ、ふつうに焦点があっていると、いちいち注視点で左右の焦点合わせ(といっても無意識にしているわけだろうが)をしないので、ディープフォーカスなんだ、と驚いた。

あの十字の検査の結果がこれか。と驚く。なるほど、これは良いものだ、とレンズのほうにもあらためて感心した。

というわけで眼鏡を作って何十年、初めてコンタクトレンズをして、耳と鼻が解放されて、視野すべてがくっきり見えたときに劣らない感動があって驚いた(子供の頃にはっきりと見えたときにも感動はあったかも知れないが、覚えていないと、書いた瞬間に思い出した。新宿の百貨店に親に連れられて作ったのだった。床のリノリウムの四角がはっきりタイル状になっているのを知って仰天したのを思い出した。記憶というのはおもしろい)。

というわけで、オペラ用に遠くを見る用の眼鏡も作ろうという気分になった(が、さすがに金が続かないので今度は木はなしだな)。


2018-08-31

_ 千葉旅行

千葉は埼玉(秩父困民党など民主主義発祥の地だったり北条生き残りの山城が大量にあったり猪俣党の町があったり百穴があったりむちゃくちゃ)や群馬(古墳の数は日本一)とならんで近くて遠い歴史的な秘境なので、会社を休んで妻と旅行。

今回は、佐倉へ行く。

頭の中ではなんとなく安房と下総の間と認識していたが、実際にナビゲーターにしたがって進むとびっくり、千葉市より少し内陸に入ったところ(四街道の先)で日本から距離にしてたかだか70km弱しかない。そんな近かったのか。

というわけで、日本のロビンフッド、義民佐倉惣五郎(宗吾)くらいしか知識を持たないまま佐倉へ向かった。

そんな近いと知らなかったので朝8:30くらいに出発したら9:30過ぎには着いてしまった。

_ 国立歴史民俗博物館

お目当ては城址にある国立歴史民俗博物館で、幸い9:30開館なのでちょうど良かった。

でかい。なんか故宮なみにでっかな建物で驚いた。銚子の新国立劇場の倉庫兼博物館みたいなもので、千葉だけにでっかな場所に倉庫を兼ねた博物館を作ったのかなとか考えながら長い石段を登って正面から入り、なぜかJAFの割引がある入場券を買う。特設展でおみやげというのをやっていたのでよくわからんが、それも付いた入場料を払う。

なんかヒグマの爪のお守りが売っている売店を横目に特設展の会場へ向かう(あとになって、常設展と同じ建物の地下とわかるのだが、入り口がまったく異なるのでどういう構造になっているのか思い返してもよくわからない。

_ おみやげ

おみやげは、近世、旅行に行った思い出のためというよりも、いろいろなところへ行ったということを周囲に誇ったり、センスの良いものを持ち帰ることで誇ったりするための、承認要求を満たすための仕組みである(という意味)の説明が最初にされている。

したがって、この展示は、そういった旅行者の自己顕示欲を満たすと同時に、そのような自己顕示欲をくすぐり、収集本能をくすぐりまくることで本来価値のないものを売りつけるための経済的メディアとしての役割を持つ観光地経済の中核となる機械の成立と発展、いかに持続させるかといった視点で作られている。さらにはいかに収集本能をくすぐるために同工異曲のおみやげが各地でなぜか作られる(ペナントとか、そういえば展示されていなかったが太い名所名をペイントした鉛筆とか昔買った覚えがあるとか、通行手形とか、絵葉書とか)。

と同時に、おみやげが個人収蔵される場合は旅行という非日常と生活という日常の間の呪術的空間を現出せしめるための霊物としての役割があり、それはおみやげ展示棚(そういえば、爺さん(2人いる)の家にはどちらもそういう棚があり、アフリカ土産やら中国土産やら東北土産やらが展示されていた)は、家族に対しての小博物館としての役割を果たす(なるほど、確かにおれはそれを観てカンプチアのアンコールトムのおもしろさや、ニューギニアの首狩り族などについて知ったのだった)ということが示される。

むちゃくちゃおもしろい!

これぞ国立の研究ですな。

と、展示場に足を踏み入れてたったの2m足らずの間にえらく脳みそが刺激されまくった。

とにかく、この博物館はふつうではない。結局、全体の2/3(そのうち2/3は早回し再生)しか見なかったが、5年分くらいの思考を使ったように思える。どえらく疲れたがおもしろかった。

(とりあえず何十回目かの反芻するのでまずはここまで)

_ 喫茶店の町としての佐倉

市役所のホームページ。

茶畑を作ることで地域経済を支えようとした人。

_ 城址

山の上に国立民族学博物館があり、そこが城址ということは位置的に山城に近い(が、江戸時代なのでふつうに天守閣を持つものだろう)のが不思議で、佐倉藩が官軍側だと書いた展示があったことから、外様だったので守りを重視したのかな? と思った。あとで調べたら、逆に東北から江戸へ攻めて来られた場合の要害としての機能が与えられた(むしろ老中輩出の藩というか堀田だし)からだとわかった。あと、天守閣は持たずに櫓を置いたとあって、どちらかというと機能的にも山城そのものに近かったようだ。

_ 武家屋敷

二つの薄暗い坂。

作りは意外なほど昭和の家屋と同じ(というか、昭和の家屋は武家屋敷がベースなのではないか)。廊下、障子、和室。廊下の突き当りに厠。風呂場と台所は近い。

_ 八幡の藪知らず

新八幡で停めてサンサールで飯を食うことにした。

八幡の藪知らずの本物(筒井康隆の小説の中のラップみたいな言葉の流れの中に出てきて子供のころから興味があった)を見物。びっくりするほど狭い。今はほとんど竹藪。というか、千葉街道はこれまで何度も往復していてすぐ脇を通っていたのに、これが八幡の藪知らずとは意識すらしていなかった。というくらいに小さな藪に過ぎない。

現在も立ち入り禁止。なぜ藪知らずなのかは諸説あるとか説明板がある。

ふつうに考えれば、ツツガムシの群生地なんじゃないかとか日本住血吸虫症持ちのタニシでもいるんじゃないか? と思うのだが。中は湿地帯だか沼だかだそうだし。いずれにしても謎のままに残しておくのはそれはそれでおもしろい。


2018-08-30

_ HIGH & LOW the movie

子供が、ズートピアを観て4DXに見切りをつけるには早過ぎる、HIGH & LOWを観ろと勧めるので豊洲に観に行った。

なんか乱闘シーンで背中がポコポコ子供の肩叩きみたいにされるのが心地よいのだが、そうではなく乱闘シーンやバイクで動き回るのに合わせて椅子がグイングインするのがミソっぽい。

やたらと登場人物がいるので(子供が予習しておけといってプログラムを渡したが、味方側が5グループで20人近く主要人物がいて、敵側が4~5グループで主要人物がこれまた20人近くいて、さらに別枠に2人と2人、とにかくやたらと人数が多くて面倒になってろくに読まないまま映画に突入したのだが、最初にえらくテンポが良い紙芝居で背景説明を数分でやられたのだが、色分けとスタイルできれいに分かれているので、敵側の外国人以外はほぼ把握できたので観ていてわけがわからなくなる(ほど人数ほどには物語は複雑ではない)ことはなかった。

映画としてはバストショット、顔アップ、ひいてバイクが勢ぞろい、乱闘始まりひいて背後から敵がうじゃうじゃわいてきて、またバストショット、ひいて殴り合い、顔アップ、引いて敵がうじゃうじゃの乱闘、またバストショットといった具合で別段おもしろくもなんともないのだが、テンポの良さと次々と出てくる顔が変わるので退屈することはほとんどなかった。アイドル映画というジャンルとしては割と良いものだったかもしれない。

映画のできがいまいちなのは、最後の少しずつ勢ぞろいしながら決戦の場に臨むまさに映画向けのシーンがテンポが悪くてまったくおもしろくない(高校生の村上くんのところにお笑いを入れているのは悪い趣向ではないとは思ったが)のが致命的な感じで、主要人物の頭数が多過ぎる弊害なのかな。もう少しどうにかならんものかとは思った(代わりに、特別枠の2人がバイクで乱入してくるところは横広画面をうまく使っていてなかなか良い感じだった)。

動きでは、なんかデスノートの探偵みたいな気持ち悪い目つきのやつ(というか、スモーキーと名前は覚えた)が圧倒的におもしろいのだが、途中で怪我して退場してしまった。

たまにはこういうのも悪くはないかも知れない。

・なんか色分けのうまさとやたらめったらと強いやつが敵になったり味方になったり入れ替わったりが、新宿スワンみたいだなとか感じた。


2018-08-28

_ BingスペルチェックAPIを試しているんだが……

Bing Spell Check APIで日本語もチェックできる(ただし、mode=spellのみ)というので試しているのだが、全然、わけがわからなくて閉口している。

次のようなクラスでテストしてみる。

# coding: utf-8
require 'net/http'
require 'uri'
require 'json'
  
class BingSpellChecker
  KEY1 = '登録して得られたキー'.freeze
  # マーケットはja-JP、言語はja、モードはspell(proofモードは対応していないので英語チェックになるらしい)
  URL = 'https://api.cognitive.microsoft.com/bing/v7.0/spellcheck?mkt=ja-JP&setLang=ja&mode=spell'.freeze
 
  @@uri = nil
 
  def initialize(logger = Rails.logger)
    @logger = logger
    unless @@uri
      @@uri = URI.parse(URL)
    end
  end
 
  def check(text)
@logger.debug @@uri.request_uri
    req = Net::HTTP::Post.new(@@uri.request_uri,
                              'Content-Type' => 'application/x-www-form-urlencoded',
                              'Ocp-Apim-Subscription-Key' => KEY1)
    req.set_form_data('text' => text)
    resp = Net::HTTP.start(@@uri.host, @@uri.port, use_ssl: @@uri.scheme == 'https') do |h|
      h.request(req)
    end
    # 最初mode=proofで試していたがまったく日本語は無視されているのでマーケットとして
    # 何を認識しているのか確認するためにレスポンスヘッダをログした名残
    resp.each_header do |nm, val|
      @logger.debug "#{nm}=#{val}"
    end
    r = JSON.parse(resp.body)
    @logger.debug JSON.pretty_generate(r)
    if resp.code == '200'
      []   # 実際は応答データを元に都合が良いStructのインスタンス配列にしているが省略
    else
      return resp.code
    end
  end
end

たとえば、次の文を送ると、まあ検出されるのだが嬉しくない。

にぽんごが間違えている。
結果のJSON:
{
  "_type": "SpellCheck",
  "flaggedTokens": [
    {
      "offset": 4,
      "token": "が間違えて",
      "type": "UnknownToken",
      "suggestions": [
        {
          "suggestion": "が 間違えて",
          "score": 1
        }
      ]
    }
  ],
  "correctionType": "High"
}

分かち書きしろと? というか「にぽんご」はOKなのかなぁ。

で、気を取り直して、もう少し長い文章にしてみる。

にぽんごむずかしい。そもそもにぽんごむつかしいから、にぽんごが間違えている。
結果のJSON:
{
  "_type": "SpellCheck",
  "flaggedTokens": [
  ]
}

OKになってしまった……というか試していると複文は何をしても(と言っても限界はあるが)OKとなる。そういうものなのか? 確かにサンプルは1文だしなぁ。

追記:どうも本当に1単語のスペルチェックみたいだ。「グローパル」でかけたら「グローバル」と出てきた……。カンマで区切ると複数単語も行ける(「デシプリン,風鈴火山」→「ディシプリン,風林火山」)が、使形態素解析して名詞だけ拾ってとかしないと使えないのか……

だんだん嫌になってきたが、「問題は、グローパル基準です。」は文だけどグローパルを正しく指摘するが、「問題は、グローパル基準にあります。」だと指摘されないとか、結局mode=proofがサポートされていない以上、正しく単語を抽出してチェックできない、ということみたいだ。将来に期待、かな(APIは使いやすいのでとても良いのだが残念)


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|

ジェズイットを見習え